yeti3dpro-sdl3/editor/UnitMain.cpp

790 lines
22 KiB
C++

/*
** Name: Yeti3D PRO
** Desc: Portable GameBoy Advanced 3D Engine
** Auth: Derek J. Evans <derek@theteahouse.com.au>
**
** Copyright (C) 2003-2004 Derek J. Evans. All Rights Reserved.
**
** YY YY EEEEEE TTTTTT IIIIII 33333 DDDDD
** YY YY EE TT II 33 DD DD
** YYYY EEEE TT II 333 DD DD
** YY EE TT II 33 DD DD
** YY EEEEEE TT IIIIII 33333 DDDDD
*/
#include <vcl.h>
#pragma hdrstop
#include "UnitMain.h"
#include "UnitPreview.h"
#include "UnitSplash.h"
#include "map.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormMain *FormMain;
//---------------------------------------------------------------------------
__fastcall TFormMain::TFormMain(TComponent* Owner) : TForm(Owner) {}
//---------------------------------------------------------------------------
void __fastcall TFormMain::FormCreate(TObject *Sender)
{
TmpBitmap = new Graphics::TBitmap;
SelectionStatus = Rect(-1, -1, -1, -1);
SetFileName("");
PaintBox->ControlStyle = PaintBox->ControlStyle << csOpaque;
SetZoom(11);
UpdateTextureList();
}
//---------------------------------------------------------------------------
void TFormMain::UpdateTextureList()
{
ListView->Items->BeginUpdate();
ListView->Clear();
ILTextures->Clear();
TmpBitmap->PixelFormat = pf32bit;
TmpBitmap->Width = TEXTURE_WIDTH;
TmpBitmap->Height = TEXTURE_HEIGHT;
for (int i = 0; i < TEXTURE_MAX; i++)
{
for (int y = 0; y < TEXTURE_HEIGHT; y++)
{
for (int x = 0; x < TEXTURE_WIDTH; x++)
{
int c = textures[i][TEXTURE_HEIGHT - y - 1][x];
((DWORD*)TmpBitmap->ScanLine[y*64/TEXTURE_HEIGHT])[x*64/TEXTURE_WIDTH] =
RGB(palette[c][2], palette[c][1], palette[c][0]);
}
}
TListItem* LListItem = ListView->Items->Add();
LListItem->Caption = String("#") + i;
LListItem->ImageIndex = ILTextures->Add(TmpBitmap, NULL);
}
ListView->ItemIndex = 0;
ListView->Items->EndUpdate();
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::FormPaint(TObject *Sender)
{
OnPaint = NULL;
//FormPreview->SetFocus();
FormSplash->Execute();
}
//---------------------------------------------------------------------------
void TFormMain::SetZoom(int AZoom)
{
Zoom = EnsureRange(AZoom, 6, 24);
ScrollBox->OnResize(ScrollBox);
}
//---------------------------------------------------------------------------
TRect TFormMain::CellRect(int x, int y)
{
return Bounds(x * Zoom, (MAP_HEIGHT - y - 1) * Zoom, Zoom, Zoom);
}
//---------------------------------------------------------------------------
void TFormMain::CellDraw(int x, int y)
{
TCanvas* LCanvas = PaintBox->Canvas;
cell_t* cell = &yeti->map.item[y][x];
TRect r = CellRect(x, y);
if (CELL_IS_SOLID(cell))
{
LCanvas->Brush->Color = (TColor) RGB(0, 0, 150);
}
else
{
int s = ((cell->top - cell->bot) >> 4);
LCanvas->Brush->Color = (TColor) RGB(s, s, s);
}
TRect s = RectNormalize(&Selection);
if (x >= s.Left && y >= s.Top && x <= s.Right && y <= s.Bottom)
{
cell->swi |= CELL_SWI_SELECTED;
if (cell->swi & CELL_SWI_TERRAIN || cell->swi & CELL_SWI_CAVE)
{
LCanvas->Pen->Color = clLime;
}
else
{
LCanvas->Pen->Color = clGreen;
}
LCanvas->Rectangle(r);
if (x == Selection.left && y == Selection.top)
{
LCanvas->Pen->Color = clRed;
LCanvas->Rectangle(RectInflate(&r, -2, -2));
}
}
else
{
cell->swi &= ~CELL_SWI_SELECTED;
if (CELL_IS_SOLID(cell))
{
LCanvas->FillRect(r);
TRect tmp = r; // Frame3D modifies the rectangle.
Frame3D(LCanvas, tmp, (TColor) RGB(0, 0, 200), (TColor) RGB(0, 0, 100), 1);
//Frame3D(PaintBox->Canvas, tmp, (TColor) RGB(0, 0, 100), (TColor) RGB(0, 0, 200), 1);
}
else
{
LCanvas->Pen->Color = clBlack;
LCanvas->Rectangle(r);
}
}
if (cell->swi & CELL_SWI_LIGHT)
{
LCanvas->Pen->Color = clWhite;
LCanvas->Rectangle(RectInflate(&r, -4, -4));
}
if (cell->ent)
{
if (cell->ent == 1)
{
LCanvas->Pen->Color = clYellow;
}
else
{
LCanvas->Pen->Color = clLime;
}
LCanvas->Brush->Style = bsClear;
LCanvas->Ellipse(RectInflate(&r, -1, -1));
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::PaintBoxPaint(TObject *Sender)
{
TRect LClipRect = PaintBox->Canvas->ClipRect;
for (int y = MAP_HEIGHT; y--;)
{
for (int x = MAP_WIDTH; x--;)
{
TRect LTempRect;
if (IntersectRect(LTempRect, LClipRect, CellRect(x, y)))
{
CellDraw(x, y);
}
}
}
if (Selection != SelectionStatus)
{
SelectionStatus = Selection;
StatusBar->Panels->Items[0]->Text = Format("Selected Cell: (%d, %d)", ARRAYOFCONST((
(int)Selection.left,
(int)Selection.top,
(int)Selection.Width(),
(int)Selection.Height())));
StatusBar->Update();
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::ScrollBoxResize(TObject *Sender)
{
int LWidth = MAP_WIDTH * Zoom;
int LHeight = MAP_HEIGHT * Zoom;
PanelScene->SetBounds(
Max((ScrollBox->ClientWidth - LWidth) / 2, 0) - ScrollBox->HorzScrollBar->Position,
Max((ScrollBox->ClientHeight - LHeight) / 2, 0) - ScrollBox->VertScrollBar->Position,
LWidth, LHeight);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MIExitClick(TObject *Sender)
{
Close();
}
void cell_solid_switch(cell_t* cell, int issolid)
{
if (issolid)
{
if (!CELL_IS_SOLID(cell))
{
cell->tsa = cell->top;
cell->bsa = cell->bot;
cell->top = cell->bot = 0;
}
}
else
{
if (CELL_IS_SOLID(cell))
{
cell->top = cell->tsa;
cell->bot = cell->bsa;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::PaintBoxMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
if (LButton || RButton)
{
PBMouse->SetBounds(X, Y, 0, 0);
ScrollBox->ScrollInView(PBMouse);
}
X = X / Zoom;
Y = MAP_HEIGHT - (Y / Zoom) - 1;
//X = EnsureRange(X, 0, YETI_MAP_WIDTH - 1);
//Y = EnsureRange(Y, 0, YETI_MAP_HEIGHT - 1);
if (TBDraw->Down)
{
if (LButton || RButton)
{
cell_solid_switch(&yeti->map.item[Y][X], LButton);
map_precalc_data(&yeti->map, yeti->visual.map_lod);
CellDraw(X, Y);
Modified = True;
}
}
if (TBArrow->Down && LButton)
{
Selection.Right = X;
Selection.Bottom = Y;
PaintBox->Repaint();
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::PaintBoxMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (Button == mbLeft ) LButton = True;
if (Button == mbRight) RButton = True;
if (TBArrow->Down)
{
Selection = Bounds(X / Zoom, MAP_HEIGHT - (Y / Zoom) - 1, 0, 0);
}
PaintBoxMouseMove(Sender, Shift, X, Y);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::PaintBoxMouseUp(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (Button == mbLeft ) LButton = False;
if (Button == mbRight) RButton = False;
PaintBox->Repaint();
}
//---------------------------------------------------------------------------
void yeti_lua_init(lua_t lua, palette_t palette,
float LR, float LG, float LB,
float pgamma, float sgamma)
{
int x, y;
float r, g, b;
for (y = 0; y < 64; y++)
{
for (x = 0; x < 256; x++)
{
r = palette[x][0];
g = palette[x][1];
b = palette[x][2];
r = pow(r / 255.0, pgamma) * 255.0;
g = pow(g / 255.0, pgamma) * 255.0;
b = pow(b / 255.0, pgamma) * 255.0;
r = r * LR;
g = g * LG;
b = b * LB;
r = r * y / 32;
g = g * y / 32;
b = b * y / 32;
r = pow(r / 255.0, sgamma) * 255.0;
g = pow(g / 255.0, sgamma) * 255.0;
b = pow(b / 255.0, sgamma) * 255.0;
r = r / 255.0 * 31.0;
g = g / 255.0 * 31.0;
b = b / 255.0 * 31.0;
lua[y][x] = RGB_SET((int)r, (int)g, (int)b);
}
}
}
#define APPLY(A) \
for (int y = R.top; y <= R.bottom; y++) for (int x = R.left; x <= R.right; x++) \
{cell_t* cell = &yeti->map.item[y][x]; A;}
void __fastcall TFormMain::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
TRect R = RectNormalize(&Selection);
unsigned tx = Max(ListView->ItemIndex, 0);
bool sft = Shift.Contains(ssShift);
bool ctl = Shift.Contains(ssCtrl );
cell_t* selc = &yeti->map.item[R.top][R.left];
switch (Key)
{
case 221: {APPLY(cell->bot += 64) Key = 1; break;}
case 219: {APPLY(cell->bot -= 64) Key = 1; break;}
case 'P': {APPLY(cell->top += 64) Key = 1; break;}
case 'O': {APPLY(cell->top -= 64) Key = 1; break;}
case 'L':
{
if (ctl)
APPLY(cell->sw2=((selc->sw2+CELL_SW2_LIGHT1)&CELL_SW2_LIGHT_MASK))
else
APPLY(cell->swi ^= CELL_SWI_LIGHT);
Key = 1;
break;
}
case 'T': {APPLY(cell->swi ^= CELL_SWI_TERRAIN ) Key = 1; break;}
case 'C': {APPLY(cell->swi ^= CELL_SWI_CAVE ) Key = 1; break;}
case 'H': {APPLY(cell->sw2 ^= CELL_SW2_HALFBRIGHT ) Key = 1; break;}
case 'Q': {APPLY(cell->sw2 ^= CELL_SW2_OVERPASS ) Key = 1; break;}
case 'K': {APPLY(if (++cell->wwi>8)cell->wwi=0) Key = 1; break;}
case 'S': {map_smooth_slopes(&yeti->map, R.left, R.top, R.right, R.bottom); Key = 1; break;}
case '6': {APPLY(cell->tos -= 2;) Key = 1; break;}
case '7': {APPLY(cell->tos += 2;) Key = 1; break;}
case '8': {APPLY(cell->bos -= 2;) Key = 1; break;}
case '9': {APPLY(cell->bos += 2;) Key = 1; break;}
#define WALLTX if(!sft)cell->wtb=tx;if(!ctl)cell->wtt=tx;
case 45: {if(tc)tx=(tx-1)%TEXTURE_MAX;APPLY(cell->btx=tx);Key=1;break;}
case 46: {if(tc)tx=(tx+1)%TEXTURE_MAX;APPLY(cell->btx=tx);Key=1;break;}
case 36: {if(tc)tx=(tx-1)%TEXTURE_MAX;APPLY(WALLTX);Key=1;break;}
case 35: {if(tc)tx=(tx+1)%TEXTURE_MAX;APPLY(WALLTX);Key=1;break;}
case 33: {if(tc)tx=(tx-1)%TEXTURE_MAX;APPLY(cell->ttx=tx);Key=1;break;}
case 34: {if(tc)tx=(tx+1)%TEXTURE_MAX;APPLY(cell->ttx=tx);Key=1;break;}
case 'F': {APPLY(cell_solid_switch(cell, true )); Key = 1; break;}
case 'G': {APPLY(cell_solid_switch(cell, false)); Key = 1; break;}
case '1': {APPLY(cell->swi=cell->swi&~CELL_SWI_LUA_MASK|CELL_SWI_LUA_0);Key=1;break;}
case '2': {APPLY(cell->swi=cell->swi&~CELL_SWI_LUA_MASK|CELL_SWI_LUA_1);Key=1;break;}
case '3': {APPLY(cell->swi=cell->swi&~CELL_SWI_LUA_MASK|CELL_SWI_LUA_2);Key=1;break;}
case '4': {APPLY(cell->swi=cell->swi&~CELL_SWI_LUA_MASK|CELL_SWI_LUA_3);Key=1;break;}
case 'E':
{
String Value = yeti->map.item[R.top][R.left].ent;
if (InputQuery("", "Enter Entity ID (0..255):", Value))
{
int ent = Value.ToIntDef(0);
APPLY(cell->ent = ent);
game_spawn_entities(yeti);
Key = 1;
}
break;
}
case VK_LEFT : {Key = 0; break;}
case VK_UP : {Key = 0; break;}
case VK_RIGHT : {Key = 0; break;}
case VK_DOWN : {Key = 0; break;}
//case VK_CONTROL : {Key = 0; break;}
case ' ' : {Key = 0; break;}
case 'A' : {Key = 0; break;}
case 'Z' : {Key = 0; break;}
default:
{
//ShowMessage(Key);
}
}
if (Key == 1)
{
Key = 0;
map_precalc_data(&yeti->map, yeti->visual.map_lod);
PaintBox->Repaint();
FormPreview->TimerTimer(FormPreview->Timer);
Modified = true;
ListView->ItemIndex = tx;
ListView->Selected->MakeVisible(False);
tc = true;
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
{
switch(Key)
{
case VK_LEFT : {Key = 0; break;}
case VK_UP : {Key = 0; break;}
case VK_RIGHT : {Key = 0; break;}
case VK_DOWN : {Key = 0; break;}
//case VK_CONTROL: {Key = 0; break;}
case ' ' : {Key = 0; break;}
case 'A' : {Key = 0; break;}
case 'Z' : {Key = 0; break;}
}
}
//---------------------------------------------------------------------------
void TFormMain::ExportToFile(String AFileName)
{
yeti_save_map(yeti, &rommap);
TStringList* SL = new TStringList;
__try
{
String LName = ChangeFileExt(ExtractFileName(AFileName), "");
LName = AnsiReplaceStr(LName, " ", "_");
SL->Add(Format("YETI_ROM rom_map_t map_%s = {", ARRAYOFCONST((LName))));
SL->Add(Format("\"%s\",\"%s\",\"%s\",{", ARRAYOFCONST((
rommap.name,
rommap.auth,
rommap.desc))));
for (int y = 0; y < MAP_HEIGHT; y++)
{
SL->Add("{");
for (int x = 0; x < MAP_WIDTH; x++)
{
rom_cell_t* cell = &rommap.cells[y][x];
SL->Add(Format("{%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d},", ARRAYOFCONST((
cell->swi,
cell->ent,
cell->top,
cell->wtb,
cell->sw2,
cell->bot,
cell->lit,
cell->wtt,
cell->ttx,
cell->wwi,
cell->btx,
cell->tos,
cell->bos
))));
}
String S = SL->Strings[SL->Count - 1];
SL->Strings[SL->Count - 1] = S.SubString(1, S.Length() - 1);
SL->Add("},");
}
String S = SL->Strings[SL->Count - 1];
SL->Strings[SL->Count - 1] = S.SubString(1, S.Length() - 1);
SL->Add("}};");
SL->SaveToFile(AFileName);
}
__finally
{
SL->Free();
}
}
//---------------------------------------------------------------------------
void TFormMain::SetFileName(String AFileName)
{
FileName = AFileName;
if (!AFileName.Length()) AFileName = "untitled";
Caption = Application->Title + " | " + __DATE__ + " | [" + AFileName + "]";
Modified = false;
PaintBox->Repaint();
}
//---------------------------------------------------------------------------
void TFormMain::LoadFromFile(String AFileName)
{
TFileStream* FS = new TFileStream(AFileName, fmOpenRead);
try
{
FS->ReadBuffer(&rommap, sizeof(rommap));
game_load_map(yeti, &rommap);
}
__finally
{
FS->Free();
}
SetFileName(AFileName);
}
//---------------------------------------------------------------------------
void TFormMain::SaveToFile(String AFileName)
{
AFileName = ChangeFileExt(AFileName, ".y3d");
TFileStream* FS = new TFileStream(AFileName, fmCreate);
try
{
yeti_save_map(yeti, &rommap);
FS->WriteBuffer(&rommap, sizeof(rommap));
}
__finally
{
FS->Free();
}
ExportToFile(ChangeFileExt(AFileName, ".c"));
SetFileName(AFileName);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MISaveClick(TObject *Sender)
{
if (FileExists(FileName) && !FileIsReadOnly(FileName))
{
SaveToFile(FileName);
}
else
{
MISaveAs->Click();
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MISaveAsClick(TObject *Sender)
{
SaveDialog->FileName = FileName;
if (SaveDialog->Execute()) SaveToFile(SaveDialog->FileName);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::ExportCFileClick(TObject *Sender)
{
if (FileExists(FileName))
{
ExportDialog->FileName = ChangeFileExt(FileName, ".c");
}
if (ExportDialog->Execute()) ExportToFile(ExportDialog->FileName);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MIOpenClick(TObject *Sender)
{
OpenDialog->FileName = FileName;
if (OpenDialog->Execute() && CanClose())
{
LoadFromFile(OpenDialog->FileName);
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MINewClick(TObject *Sender)
{
if (CanClose())
{
map_init(&yeti->map, yeti->visual.map_lod);
game_spawn_entities(yeti);
SetFileName("");
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::TBNewClick(TObject *Sender)
{
MINew->Click();
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::TBOpenClick(TObject *Sender)
{
MIOpen->Click();
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::TBSaveClick(TObject *Sender)
{
MISave->Click();
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MIAboutClick(TObject *Sender)
{
ShowMessage(YETI_STR_CAPTION);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::FormCloseQuery(TObject *Sender, bool &CanClose)
{
CanClose = True;
if (Modified)
{
switch (Application->MessageBox(
"Current project has been modified. Do you want to save now?",
Application->Title.c_str(), MB_YESNOCANCEL))
{
case IDYES:
{
MISaveAs->Click(); // << This should be Save, but SaveAs is safer.
CanClose = !Modified;
break;
}
case IDNO:
{
CanClose = True;
break;
}
case IDCANCEL:
{
CanClose = False;
break;
}
}
}
}
//---------------------------------------------------------------------------
bool TFormMain::CanClose()
{
bool LCanClose = True;
FormCloseQuery(this, LCanClose);
return LCanClose;
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::ToolButton2Click(TObject *Sender)
{
SetZoom(Zoom + 1);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::ToolButton3Click(TObject *Sender)
{
SetZoom(Zoom - 1);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::ListViewChange(TObject *Sender, TListItem *Item, TItemChange Change)
{
tc = false;
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MISelectAllClick(TObject *Sender)
{
Selection = Rect(0, 0, MAP_WIDTH - 1, MAP_HEIGHT - 1);
PaintBox->Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::ListViewMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
ListView->Cursor = ListView->GetItemAt(X, Y) ? crHandPoint : crDefault;
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MICopyClick(TObject *Sender)
{
TRect R = RectNormalize(&Selection);
MapClip.Length = R.Height() + 1;
for (int i = 0; i < MapClip.Length; i++)
{
MapClip[i].Length = R.Width() + 1;
}
for (int y = R.top; y <= R.bottom; y++)
{
for (int x = R.left; x <= R.right; x++)
{
yeti_save_cell(&yeti->map.item[y][x], &MapClip[y - R.top][x - R.left]);
}
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MIDeleteClick(TObject *Sender)
{
TRect R = RectNormalize(&Selection);
// TODO: Need a range init function.
map_precalc_data(&yeti->map, yeti->visual.map_lod);
Modified = True;
PaintBox->Refresh();
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MICutClick(TObject *Sender)
{
MICopy->Click();
MIDelete->Click();
}
//---------------------------------------------------------------------------
void SurfaceLoadFromIniFile(surface_t* surface, TIniFile* AIniFile, String ASection)
{
surface_init(surface);
surface->xsize += AIniFile->ReadInteger(ASection, "xsize", 0);
surface->ysize += AIniFile->ReadInteger(ASection, "ysize", 0);
surface->mode = AIniFile->ReadInteger(ASection, "mode" , surface->mode);
surface->xpan = AIniFile->ReadInteger(ASection, "xpan" , surface->xpan);
surface->ypan = AIniFile->ReadInteger(ASection, "ypan" , surface->ypan);
}
void __fastcall TFormMain::MIImportTexturesClick(TObject *Sender)
{
if (OpenPictureDialog->Execute())
{
BitmapLoadFromFile(TmpBitmap, OpenPictureDialog->FileName);
if (TmpBitmap->Width != 64)
{
throw Exception("Texture set bitmap must be 64 pixels wide.");
}
if (TmpBitmap->Height >= (64 * 128))
{
throw Exception("Texture contains more than 128 textures.");
}
TmpBitmap->PixelFormat = pf32bit;
TmpBitmap->PixelFormat = pf8bit;
memset(textures, 0, sizeof(textures));
TMaxLogPalette Palette;
Palette.palVersion = 0x300;
Palette.palNumEntries = 256;
GetPaletteEntries(TmpBitmap->Palette, 0, Palette.palNumEntries, Palette.palPalEntry);
for (int i = Palette.palNumEntries; i--;)
{
palette[i][0] = Palette.palPalEntry[i].peRed;
palette[i][1] = Palette.palPalEntry[i].peGreen;
palette[i][2] = Palette.palPalEntry[i].peBlue;
}
yeti_init_lua(yeti, YETI_GAMMA);
for (int y = 0; y < TmpBitmap->Height; y++)
{
for (int x = 0; x < TmpBitmap->Width; x++)
{
textures[y >> 6][63 - (y & 63)][x & 63] = ((Byte*)TmpBitmap->ScanLine[y])[x];
}
}
TIniFile* LIniFile = new TIniFile(ChangeFileExt(OpenPictureDialog->FileName, ".ini"));
try
{
for (int i = 0; i < yeti->surfaces.length; i++)
{
SurfaceLoadFromIniFile(&yeti->surfaces.item[i], LIniFile, i);
}
}
catch (...)
{
LIniFile->Free();
}
UpdateTextureList();
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::TimerTimer(TObject *Sender)
{
PanelCamera->Color = PanelCamera->Color != clWhite ? clWhite : clRed;
}
//---------------------------------------------------------------------------