//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MainForm.h"
//---------------------------------------------------------------------------
#include <stdio.h>
#include "ConfigForm.h"
#include "AboutForm.h"
#include <fstream>
#include <string>
#include <IniFiles.hpp>
#pragma package(smart_init)
#pragma resource "*.dfm"
//******************************************************************************
//******************************************************************************
//******************************************************************************
// Global stuff
//******************************************************************************
TfrmMain *frmMain;
// Set up some colors
TColor MapColors[] = {clAqua, // empty
clWhite, // obstacle
clBlue, // character
clRed, // enemy
clYellow // prize
};
ColorID ColorMap[] = {{ctEMPTY, MapColors[ctEMPTY]},
{ctOBSTACLE, MapColors[ctOBSTACLE]},
{ctCHARACTER, MapColors[ctCHARACTER]},
{ctENEMY, MapColors[ctENEMY]},
{ctPRIZE, MapColors[ctPRIZE]}
};
/*
Constructor.
*/
__fastcall TfrmMain::TfrmMain(TComponent* Owner) : TForm(Owner)
{
pnlWorld->DoubleBuffered = true; // prevent flicker
gridWorld->DoubleBuffered = true; // prevent flicker
// Some defaults
FShowGrid = true;
FGridColor = clBlack;
FCurrColorID = ColorMap[ctOBSTACLE];
FColumns = 20;
FRows = 20;
FCurrFileName = "Exported.txt"; // for compatibility with CS230 game .exe
IsUndo = false;
// Reset the internal data
InitializeApp();
}
//---------------------------------------------------------------------------
/*
Initializes the internal state of the UI
*/
void TfrmMain::InitializeApp(void)
{
// Clear undo history
while (!UndoData.empty())
UndoData.pop();
// Clear undo history
while (!RedoData.empty())
RedoData.pop();
// Set all cells to empty
for (int i = 0; i < FMaxRows; i++)
for (int j = 0; j < FMaxColumns; j++)
FDataMap[i][j] = ctEMPTY;
// Initialize the size of the grid
spnRows->Position = FRows;
spnColumns->Position = FColumns;
// Assume the mouse is off of the grid
FCurrRow = -1;
FCurrColumn = -1;
FPrevRow = -1;
FPrevColumn = -1;
AdjustGrid();
DisplayCurrentCellInStatusBar();
}
/*
Add information to the undo stack. The information is the previous
state so that it can be un-done later.
*/
void TfrmMain::PushUndo(void)
{
CellData cd;
// All we need is the previous color and the row/column
cd.row = FCurrRow;
cd.col = FCurrColumn;
cd.ctype = (CELL_TYPE) FDataMap[FCurrRow][FCurrColumn];
UndoData.push(cd);
}
/*
Add information to the redo stack. The information is the previous
state so that it can be re-done later.
*/
void TfrmMain::PushRedo(void)
{
CellData cd;
// All we need is the previous color and the row/column
cd.row = FCurrRow;
cd.col = FCurrColumn;
cd.ctype = (CELL_TYPE) FDataMap[FCurrRow][FCurrColumn];
RedoData.push(cd);
}
/*
Remove information from the undo stack. The removed information
tells the application "how" to undo the last step.
*/
void TfrmMain::PopUndo(void)
{
// Nothing to do
if (UndoData.empty())
return;
// Get/remove undo info
CellData cd = UndoData.top();
UndoData.pop();
// Set the state to what was popped off
FCurrRow = cd.row;
FCurrColumn = cd.col;
PushRedo();
FDataMap[FCurrRow][FCurrColumn] = cd.ctype;
// A little tricky. Since we don't want to highlight (a thick border)
// the cell, we need to communicate this to the HighlightCell method.
// It won't highlight a cell if it is during an undo operation. Are there
// other/better ways to handle this? Probably, but this will do here.
IsUndo = true;
HighlightCell(true);
IsUndo = false;
DisplayCurrentCellInStatusBar();
}
/*
Remove information from the redo stack. The removed information
tells the application "how" to redo the last step.
*/
void TfrmMain::PopRedo(void)
{
// Nothing to do
if (RedoData.empty())
return;
// Get/remove redo info
CellData cd = RedoData.top();
RedoData.pop();
// Set the state to what was popped off
FCurrRow = cd.row;
FCurrColumn = cd.col;
PushUndo();
FDataMap[FCurrRow][FCurrColumn] = cd.ctype;
// A little tricky. Since we don't want to highlight (a thick border)
// the cell, we need to communicate this to the HighlightCell method.
// It won't highlight a cell if it is during an undo operation. Are there
// other/better ways to handle this? Probably, but this will do here.
IsUndo = true;
HighlightCell(true);
IsUndo = false;
DisplayCurrentCellInStatusBar();
}
/*
Displays current row/column in the status bar
*/
void TfrmMain::DisplayCurrentCellInStatusBar(void)
{
// Invalid location, erase the display
if (FOffGrid || FCurrColumn == -1 || FCurrRow == -1)
barStatus->Panels->Items[0]->Text = "";
else
barStatus->Panels->Items[0]->Text = Format(" Row: %d, Col: %d", ARRAYOFCONST((FCurrRow + 1, FCurrColumn + 1)));
}
/*
If the grid is resized, need to update variables with the new sizes
*/
void TfrmMain::AdjustGrid(void)
{
gridWorld->ColCount = FColumns;
gridWorld->RowCount = FRows;
// The size of the cells, including the borders
FCellWidth = gridWorld->Width / FColumns;
FCellHeight = gridWorld->Height / FRows;
// The size of the cells without the borders
if (gridWorld->GridLineWidth)
{
FCellWidth -= gridWorld->GridLineWidth;
FCellHeight -= gridWorld->GridLineWidth;
}
// Make this the default now
gridWorld->DefaultColWidth = FCellWidth;
gridWorld->DefaultRowHeight = FCellHeight;
// Keep the currently selected cell as selected
TGridRect rect = {{FCurrColumn, FCurrRow}, {FCurrColumn, FCurrRow}};
gridWorld->Selection = rect;
}
/*
Displays text in the bottom of the app. Used for debugging.
*/
void TfrmMain::AddStatus(const char *text)
{
mmoStatus->Lines->Insert(0, text);
}
/*
The mouse movement is tracked on the grid by highlighting the border of
the cell that is under the mouse cursor.
*/
void TfrmMain::HighlightCell(bool Force)
{
// If we are in the same cell, do nothing
if ( (!Force) && (FPrevRow == FCurrRow && FPrevColumn == FCurrColumn) )
return;
// Otherwise, we've moved from one cell to the next.
// Un-highlight (lowlight?) the previous cell.
TRect rect = gridWorld->CellRect(FPrevColumn, FPrevRow);
DrawCell(FPrevColumn, FPrevRow, rect);
// Off the board, do nothing
if (FCurrRow < 0 || FCurrRow >= FRows || FCurrColumn < 0 || FCurrColumn >= FColumns)
return;
// Highlight the new cell
rect = gridWorld->CellRect(FCurrColumn, FCurrRow);
DrawCell(FCurrColumn, FCurrRow, rect);
}
/*
This does the actual drawing of each cell
*/
void TfrmMain::DrawCell(int ACol, int ARow, TRect &Rect)
{
// Rectangle of cell to draw
Rect.Left = Rect.Left - 1;
Rect.Right = Rect.Right;
Rect.Top = Rect.Top - 1;
Rect.Bottom = Rect.Bottom;
// Default
gridWorld->Canvas->Pen->Width = 1;
gridWorld->Canvas->Pen->Color = FGridColor;
//bool highlight = false;
// Draw a 3 pixel wide black border on the highlighted cell
if ((ACol == FCurrColumn && ARow == FCurrRow && !FOffGrid && (ACol != -1 && ARow != -1)) )
{
if (!IsUndo)
{
gridWorld->Canvas->Pen->Width = 3;
gridWorld->Canvas->Pen->Color = clBlack;
Rect.left += gridWorld->Canvas->Pen->Width - 1;
Rect.Top += gridWorld->Canvas->Pen->Width - 1;
Rect.right -= gridWorld->Canvas->Pen->Width - 1;
Rect.Bottom -= gridWorld->Canvas->Pen->Width - 1;
//highlight = true;
}
}
// BUG FIX (from WarBoats!)
if ((ACol == -1) || (ARow == -1))
return;
// The cell is empty
if (FDataMap[ARow][ACol] == ctEMPTY)
{
gridWorld->Canvas->Brush->Color = MapColors[ctEMPTY];
gridWorld->Canvas->Rectangle(Rect);
}
// The cell is an obstacle (collision)
else if (FDataMap[ARow][ACol] == ctOBSTACLE)
{
gridWorld->Canvas->Brush->Color = MapColors[ctOBSTACLE];
gridWorld->Canvas->Rectangle(Rect);
}
// The cell is the character in the game
else if (FDataMap[ARow][ACol] == ctCHARACTER)
{
gridWorld->Canvas->Brush->Color = MapColors[ctCHARACTER];
gridWorld->Canvas->Rectangle(Rect);
}
// The cell is an enemy
else if (FDataMap[ARow][ACol] == ctENEMY)
{
gridWorld->Canvas->Brush->Color = MapColors[ctENEMY];
gridWorld->Canvas->Rectangle(Rect);
}
// The cell is a prize (coin)
else if (FDataMap[ARow][ACol] == ctPRIZE)
{
#if 1
gridWorld->Canvas->Brush->Color = MapColors[ctPRIZE];
gridWorld->Canvas->Rectangle(Rect);
#else
/***** EXPERIMENTAL CODE *****/
gridWorld->Canvas->Brush->Color = MapColors[ctEMPTY];
TRect r = Rect;
/*
r.Top++;
r.Bottom -= 2;
r.Left++;
r.Right -= 2;
*/
gridWorld->Canvas->StretchDraw(r, imgPrize->Picture->Bitmap);
TPoint pts[4];
pts[0].x = Rect.Left;
pts[0].y = Rect.Top;
pts[1].x = Rect.Left;
pts[1].y = Rect.Bottom;
pts[2].x = Rect.Right;
pts[2].y = Rect.Bottom;
pts[3].x = Rect.Right;
pts[3].y = Rect.Top;
if (highlight)
gridWorld->Canvas->Polyline(pts, 4);
#endif
}
}
/*
Enables/disables the grid lines
*/
void TfrmMain::ChangeGrid(bool Show)
{
if (Show)
FGridColor = clBlack;
else
FGridColor = MapColors[ctEMPTY];
gridWorld->Refresh(); // repaint grid
}
//******************************************************************************
//******************************************************************************
//******************************************************************************
// Event Handlers
//******************************************************************************
//******************************************************************************
// Form Event Handlers
//******************************************************************************
void __fastcall TfrmMain::FormCreate(TObject *Sender)
{
// The 'usual' visual modifications at runtime
pgeWorld->Align = alClient;
pnlWorld->Align = alClient;
gridWorld->Align = alClient;
pnlBottom->BevelOuter = bvNone;
// Seamless grid
//pnlBottom->Color = MapColors[ctEMPTY];
//gridWorld->Color = MapColors[ctEMPTY];
// Size of the main window
Width = 700;
Height = 700;
// Default size
spnColumns->Position = FColumns;
spnRows->Position = FRows;
// Hide the memo for now
mmoStatus->Height = 0;
// Register this application with the OS as a drop target.
DragAcceptFiles(this->Handle, true);
// Put some values into the combo boxes
lstGravity->Items->Add("-5.0");
lstGravity->Items->Add("-8.0");
lstGravity->Items->Add("-10.0");
lstGravity->Items->Add("-12.0");
lstGravity->Items->Add("-15.0");
lstGravity->Items->Add("-18.0");
lstGravity->Items->Add("-20.0");
lstGravity->Items->Add("-25.0");
lstGravity->Items->Add("-30.0");
lstGravity->Items->Add("-40.0");
lstGravity->ItemIndex = 6;
lstJumpVelocity->Items->Add("5.0");
lstJumpVelocity->Items->Add("8.0");
lstJumpVelocity->Items->Add("11.0");
lstJumpVelocity->Items->Add("15.0");
lstJumpVelocity->Items->Add("20.0");
lstJumpVelocity->ItemIndex = 3;
lstMoveVelocityHero->Items->Add("2.0");
lstMoveVelocityHero->Items->Add("3.0");
lstMoveVelocityHero->Items->Add("4.0");
lstMoveVelocityHero->Items->Add("5.0");
lstMoveVelocityHero->Items->Add("7.0");
lstMoveVelocityHero->Items->Add("10.0");
lstMoveVelocityHero->ItemIndex = 2;
lstMoveVelocityEnemy->Items->Add("2.0");
lstMoveVelocityEnemy->Items->Add("3.0");
lstMoveVelocityEnemy->Items->Add("4.0");
lstMoveVelocityEnemy->Items->Add("5.0");
lstMoveVelocityEnemy->Items->Add("7.0");
lstMoveVelocityEnemy->Items->Add("10.0");
lstMoveVelocityEnemy->ItemIndex = 4;
lstEnemyIdleTime->Items->Add("0.0");
lstEnemyIdleTime->Items->Add("0.25");
lstEnemyIdleTime->Items->Add("0.50");
lstEnemyIdleTime->Items->Add("1.0");
lstEnemyIdleTime->Items->Add("2.0");
lstEnemyIdleTime->Items->Add("3.0");
lstEnemyIdleTime->Items->Add("5.0");
lstEnemyIdleTime->ItemIndex = 3;
spnHeroLives->Position = 5;
chkMultiJump->Checked = true;
// We need to guarantee that this has been created before
// calling any of its methods (e.g. LoadSettings). We take
// ownership, so it will be deleted when this class is deleted.
frmConfig = new TfrmConfig(this);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
{
frmConfig->SaveSettings();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormShow(TObject *Sender)
{
frmConfig->LoadSettings();
FShowGrid = frmConfig->GridEnabled;
btnGrid->Down = FShowGrid;
ChangeGrid(FShowGrid);
spnRows->Position = frmConfig->DefaultRowCount;
spnColumns->Position = frmConfig->DefaultColCount;
ReadCS230ConfigFile(frmConfig->GameConfigFile);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormDestroy(TObject *Sender)
{
// Unregister this application with the OS as a drop target.
DragAcceptFiles(this->Handle, false);
}
//---------------------------------------------------------------------------
//******************************************************************************
// TDrawGrid Event Handlers
//******************************************************************************
/*
Called each time a cell needs to be repainted.
*/
void __fastcall TfrmMain::gridWorldDrawCell(TObject *, int ACol, int ARow, TRect &Rect, TGridDrawState)
{
DrawCell(ACol, ARow, Rect);
}
//---------------------------------------------------------------------------
/*
Called when a cell is selected (with the mouse or keyboard).
*/
void __fastcall TfrmMain::gridWorldSelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect)
{
FCurrRow = ARow;
FCurrColumn = ACol;
PushUndo();
FDataMap[ARow][ACol] = FCurrColorID.type;
DisplayCurrentCellInStatusBar();
}
//---------------------------------------------------------------------------
/*
Handles the OnMouseDown event. If the user holds the right mouse button
down, we will erase (paint in the background color) the cell.
*/
void __fastcall TfrmMain::gridWorldMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (Button == mbRight)
{
// Map mouse position (pixels) to row/col
TGridCoord coord = gridWorld->MouseCoord(X, Y);
FCurrRow = coord.Y;
FCurrColumn = coord.X;
PushUndo();
FDataMap[FCurrRow][FCurrColumn] = ctEMPTY;
DisplayCurrentCellInStatusBar();
HighlightCell(true);
}
}
//---------------------------------------------------------------------------
/*
Tracks the mouse movement across the grid so the cell under the mouse
can be highlighted.
*/
void __fastcall TfrmMain::gridWorldMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
TGridCoord coord = gridWorld->MouseCoord(X, Y);
FPrevRow = FCurrRow;
FPrevColumn = FCurrColumn;
FCurrRow = coord.Y;
FCurrColumn = coord.X;
if (Shift.Contains(ssRight))
{
if (FPrevRow == FCurrRow && FPrevColumn == FCurrColumn)
return;
FDataMap[FCurrRow][FCurrColumn] = ctEMPTY;
}
DisplayCurrentCellInStatusBar();
HighlightCell();
}
//---------------------------------------------------------------------------
/*
When the mouse leaves the grid, we need to update the display.
*/
void __fastcall TfrmMain::gridWorldMouseLeave(TObject *Sender)
{
FOffGrid = true;
TRect rect = gridWorld->CellRect(FCurrColumn, FCurrRow);
DrawCell(FCurrColumn, FCurrRow, rect);
DisplayCurrentCellInStatusBar();
}
//---------------------------------------------------------------------------
/*
When the mouse moves onto the grid, we need to start tracking it and update
the display.
*/
void __fastcall TfrmMain::gridWorldMouseEnter(TObject *Sender)
{
FOffGrid = false;
TRect rect = gridWorld->CellRect(FCurrColumn, FCurrRow);
TGridDrawState state;
gridWorldDrawCell(this, FCurrColumn, FCurrRow, rect, state);
}
//---------------------------------------------------------------------------
//******************************************************************************
// Action Event Handlers
//******************************************************************************
/*
Handler for File Open
*/
void __fastcall TfrmMain::actFileOpenExecute(TObject *Sender)
{
if (dlgFileOpen->Execute())
{
InitializeApp();
if (ImportMapData(dlgFileOpen->FileName.c_str()))
{
short r = FRows;
short c = FColumns;
spnRows->Position = r;
spnColumns->Position = c;
}
}
}
//---------------------------------------------------------------------------
/*
Handler for File save
*/
void __fastcall TfrmMain::actFileSaveExecute(TObject *Sender)
{
if (dlgFileSaveText->Execute())
ExportMapData(dlgFileSaveText->FileName.c_str());
}
//---------------------------------------------------------------------------
/*
Handler for testing the level in the game
*/
void __fastcall TfrmMain::actTestExecute(TObject *Sender)
{
// Export the current level
ExportMapData(FCurrFileName.c_str());
WriteCS230ConfigFile(frmConfig->GameConfigFile);
// Launch the game. The name of the game executable is now stored
// in the .ini file (config file).
int result = WinExec(frmConfig->GameExecutable.c_str(), SW_NORMAL);
// If it failed to launch for some reason, show the error code.
// TODO: Add a better message regarding the reason it failed.
if (result < 32)
ShowMessage(IntToStr(result));
}
//---------------------------------------------------------------------------
/*
Handler for File New
*/
void __fastcall TfrmMain::actFileNewExecute(TObject *Sender)
{
InitializeApp();
}
//---------------------------------------------------------------------------
/*
Handler for toggling the grid on/off
*/
void __fastcall TfrmMain::actShowGridExecute(TObject *Sender)
{
FShowGrid = !FShowGrid; // toggle
ChangeGrid(FShowGrid);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::actHelpAboutExecute(TObject *Sender)
{
frmAbout->ShowModal();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::actEditConfigurationExecute(TObject *Sender)
{
frmConfig->ShowModal();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::actEditUndoExecute(TObject *Sender)
{
PopUndo();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::actEditUndoUpdate(TObject *Sender)
{
actEditUndo->Enabled = !UndoData.empty();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::actEditRedoExecute(TObject *Sender)
{
PopRedo();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::actEditRedoUpdate(TObject *Sender)
{
actEditRedo->Enabled = !RedoData.empty();
}
//---------------------------------------------------------------------------
//******************************************************************************
// Other event handlers
//******************************************************************************
/*
When the user changes the number of rows/columns, need to update the
display.
*/
void __fastcall TfrmMain::OnCellCountChange(TObject *Sender)
{
FRows = spnRows->Position;
FColumns = spnColumns->Position;
AdjustGrid();
}
//---------------------------------------------------------------------------
/*
Handles the event when the sheet (in the PageControl) is resized.
*/
void __fastcall TfrmMain::shtDesignResize(TObject *Sender)
{
AdjustGrid();
}
//---------------------------------------------------------------------------
/*
If the splitter bar is moved, the board will be resized and needs to be
updated. (The cell width/height has changed.)
*/
void __fastcall TfrmMain::splitHorizontalMoved(TObject *Sender)
{
AdjustGrid();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::ColorChange(TObject *Sender)
{
TButton *b = (TButton *)Sender;
FCurrColorID = ColorMap[b->Tag];
}
//---------------------------------------------------------------------------
/*
If the user drops files from Windows Explorer onto the window, this
message (WM_DROPFILES) will be sent and handled here.
*/
void __fastcall TfrmMain::WMDropFiles(TWMDropFiles &Message)
{
int num_files, filename_length;
char file_name[MAX_PATH + 1];
// Refer to the Win SDK documentation about the details
// of DragQueryFile and the HDROP structure
// Get the number of files that are being dropped on the app
num_files = DragQueryFile((HDROP)Message.Drop, -1, NULL, 0);
if (num_files < 1)
return;
// Retrieve each filename
for(int i = 0; i < num_files; i++)
{
// Get the length of the i'th filename
filename_length = DragQueryFile((HDROP)Message.Drop, i, NULL, 0);
// Retrieve the filename from the HDROP structure
DragQueryFile((HDROP)Message.Drop, i, file_name, filename_length + 1);
// We can only deal with one at this point
InitializeApp();
ImportMapData(file_name);
short r = FRows;
short c = FColumns;
spnRows->Position = r;
spnColumns->Position = c;
return;
}
}
/*
Sample data file:
Width 10
Height 10
1 1 1 1 1 1 1 1 1 1
1 0 3 0 0 4 0 4 0 1
1 0 0 0 1 1 1 0 0 1
1 0 0 1 0 4 0 0 0 1
1 0 1 0 0 0 0 0 0 1
1 0 4 0 1 0 0 0 0 1
1 0 0 0 0 1 1 1 1 1
1 0 0 2 0 0 0 4 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1
*/
bool TfrmMain::ImportMapData(const AnsiString &FileName)
{
std::ifstream infile(FileName.c_str());
if (!infile.is_open())
return false;
std::string str;
// e.g. Width 20
infile >> str; // skip "Width"
infile >> FColumns; // read width
// e.g. Height 20
infile >> str; // skip "Height"
infile >> FRows; // read height
for(int r = 0; r < FRows; r++)
for(int c = 0; c < FColumns; c++)
infile >> FDataMap[FRows - r - 1][c];
return true;
}
bool TfrmMain::ExportMapData(const AnsiString &FileName)
{
std::ofstream outfile(FileName.c_str());
if (!outfile.is_open())
return false;
// e.g. 'Width 20'
outfile << "Width ";
outfile << FColumns;
outfile << std::endl;
// e.g. 'Height 20'
outfile << "Height ";
outfile << FRows;
outfile << std::endl;
for(int r = 0; r < FRows; r++)
{
for(int c = 0; c < FColumns; c++)
outfile << FDataMap[FRows - r - 1][c] << " ";
outfile << std::endl;
}
return true;
}
/*
GRAVITY=-20.0
JUMP_VELOCITY=22.0
MOVE_VELOCITY_HERO=4.0
MOVE_VELOCITY_ENEMY=5.5
ENEMY_IDLE_TIME=0.25
HERO_LIVES=7
MULTI_JUMP=1
*/
void TfrmMain::WriteCS230ConfigFile(const AnsiString &FileName)
{
// TMemIniFile is a buffered ini file
TMemIniFile *inifile = new TMemIniFile(FileName);
try
{
inifile->WriteFloat("Platform", "Gravity", (float)StrToFloat(lstGravity->Text));
inifile->WriteFloat("Platform", "Jump_Velocity", (float)StrToFloat(lstJumpVelocity->Text));
inifile->WriteFloat("Platform", "Move_Velocity_Hero", (float)StrToFloat(lstMoveVelocityHero->Text));
inifile->WriteFloat("Platform", "Move_Velocity_Enemy", (float)StrToFloat(lstMoveVelocityEnemy->Text));
inifile->WriteFloat("Platform", "Enemy_Idle_Time", (float)StrToFloat(lstEnemyIdleTime->Text));
inifile->WriteBool("Platform", "Multi_Jump", chkMultiJump->Checked);
inifile->WriteInteger("Platform", "Hero_Lives", spnHeroLives->Position);
}
__finally
{
inifile->UpdateFile(); // Flush the buffer to disk before deleting!!!
delete inifile;
}
}
void TfrmMain::ReadCS230ConfigFile(const AnsiString &FileName)
{
// TMemIniFile is a buffered ini file
TMemIniFile *inifile = new TMemIniFile(FileName);
try
{
lstGravity->Text = inifile->ReadString("Platform", "Gravity", "0.0");
lstJumpVelocity->Text = inifile->ReadString("Platform", "Jump_Velocity", "0.0");
lstMoveVelocityHero->Text = inifile->ReadString("Platform", "Move_Velocity_Hero", "0.0");
lstMoveVelocityEnemy->Text = inifile->ReadString("Platform", "Move_Velocity_Enemy", "0.0");
lstEnemyIdleTime->Text = inifile->ReadString("Platform", "Enemy_Idle_Time", "0.0");
chkMultiJump->Checked = inifile->ReadBool("Platform", "Multi_Jump", false);
spnHeroLives->Position = (short)inifile->ReadInteger("Platform", "Hero_Lives", 1);
}
__finally
{
inifile->UpdateFile(); // Flush the buffer to disk before deleting!!!
delete inifile;
}
}