hostile-takeover/game/GameOptions.cpp
2016-08-24 21:34:48 -04:00

1719 lines
40 KiB
C++

#include "ht.h"
#include "mpshared/netmessage.h"
namespace wi {
// Handy dandy global flags used for enabling various test features
#ifdef DRAW_PATHS
bool gfDrawPaths = false;
#endif
#ifdef DRAW_LINES
bool gfDrawLines = false;
#endif
#ifdef STATS_DISPLAY
bool gfShowStats = false;
#endif
bool gfOvermindEnabled = true;
bool gfSoundEnabled = true;
#ifdef DEV_BUILD
bool gfShowFPS = true;
#else
bool gfShowFPS = false;
#endif
bool gfLockStep = false;
bool gfSuspendUpdates = false;
bool gfSingleStep = false;
bool gfGodMode = false;
bool gfAutosave = false;
bool gfStylusUI = false;
#define SetControlChecked(id, f) ((CheckBoxControl *)GetControlPtr(id))->SetChecked(f)
#define GetControlChecked(id) ((CheckBoxControl *)GetControlPtr(id))->IsChecked()
// GameOptions
class GameOptionsForm : public ShellForm
{
public:
virtual bool Init(FormMgr *pfrmm, IniReader *pini, word idf) secGameOptionsForm;
virtual void OnControlSelected(word idc) secGameOptionsForm;
};
// SoundOptions
class SoundOptionsForm : public ShellForm
{
public:
virtual bool Init(FormMgr *pfrmm, IniReader *pini, word idf) secGameOptionsForm;
virtual void OnControlSelected(word idc) secGameOptionsForm;
private:
void InitResettableControls() secGameOptionsForm;
void UpdateLabels() secGameOptionsForm;
int m_nVolume;
bool m_fEnabled;
};
// ColorOptions
class ColorOptionsForm : public Form
{
public:
ColorOptionsForm(Palette *ppal) secGameOptionsForm;
virtual bool Init(FormMgr *pfrmm, IniReader *pini, word idf) secGameOptionsForm;
virtual void OnPaintBackground(DibBitmap *pbm, UpdateMap *pupd) secGameOptionsForm;
virtual void OnControlSelected(word idc) secGameOptionsForm;
private:
void InitResettableControls() secGameOptionsForm;
void UpdateLabels() secGameOptionsForm;
Palette *m_ppal;
int m_nHueOffset;
int m_nSatMultiplier;
int m_nLumOffset;
};
// DisplayOptions
class DisplayOptionsForm : public ShellForm
{
public:
virtual bool Init(FormMgr *pfrmm, IniReader *pini, word idf) secGameOptionsForm;
virtual void OnControlSelected(word idc) secGameOptionsForm;
private:
void InitResettableControls() secGameOptionsForm;
};
// PerformanceOptions
class PerformanceOptionsForm : public ShellForm
{
public:
virtual bool Init(FormMgr *pfrmm, IniReader *pini, word idf) secGameOptionsForm;
virtual void OnControlSelected(word idc) secGameOptionsForm;
private:
void InitResettableControls() secGameOptionsForm;
word m_wfPerfOptions;
};
// DeleteMissionPackForm
class DeleteMissionPackForm : public ShellForm
{
public:
virtual bool Init(FormMgr *pfrmm, IniReader *pini, word idf) secGameOptionsForm;
virtual void OnControlSelected(word idc) secGameOptionsForm;
virtual void OnControlNotify(word idc, int nNotify) secGameOptionsForm;
private:
void PopulateList() secGameOptionsForm;
};
// GobCountForm
class GobCountForm : public Form
{
public:
virtual void OnPaint(DibBitmap *pbm) secGameOptionsForm;
virtual void OnUpdateMapInvalidate(UpdateMap *pupd, Rect *prcOpaque) secGameOptionsForm;
virtual bool OnPenEvent(Event *pevt) secGameOptionsForm;
private:
void OutputString(DibBitmap *pbm, char *psz, int *px, int *py) secGameOptionsForm;
void FormatSideString(char *pszIn, int *acPerSide, char *pszOut) secGameOptionsForm;
};
// +++
bool DoModalGameOptionsForm(Palette *ppal, bool fInGame)
{
#if !defined(IPHONE) && !defined(SDL)
ShellForm *pfrm = (ShellForm *)gpmfrmm->LoadForm(gpiniForms, kidfGameOptions, new GameOptionsForm());
if (pfrm == NULL)
return false;
int nResult;
pfrm->DoModal(&nResult);
if (!fInGame)
pfrm->Show(true);
if (nResult == kidcColorOptions) {
gpmfrmm->InvalidateRect(NULL);
Form *pfrmT = gpmfrmm->LoadForm(gpiniForms, kidfColorOptions, new ColorOptionsForm(ppal));
if (pfrmT != NULL) {
pfrmT->DoModal();
delete pfrmT;
}
}
pfrm->Show(false);
delete pfrm;
#else
// iPhone and SDL builds only have InGameOptions
ShellForm *pfrm = (ShellForm *)gpmfrmm->LoadForm(gpiniForms,
kidfInGameOptions, new InGameOptionsForm());
if (pfrm == NULL) {
return false;
}
pfrm->DoModal();
delete pfrm;
#endif
return true;
}
//
// Format option buttons sequentially, based on visibility
//
void FormatButtons(Form *pfrm, word *aidc, int cidc, int idcRef, int idcRefNext)
{
Control *pctlRef = pfrm->GetControlPtr(idcRef);
Rect rcRef;
pctlRef->GetRect(&rcRef);
Control *pctlRefNext = pfrm->GetControlPtr(idcRefNext);
Rect rcRefNext;
pctlRefNext->GetRect(&rcRefNext);
int x = rcRef.left;
int y = rcRef.top;
int cySpacing = rcRefNext.top - rcRef.top;
for (int n = 0; n < cidc; n++) {
Control *pctl = pfrm->GetControlPtr(aidc[n]);
if (!(pctl->GetFlags() & kfCtlVisible))
continue;
Rect rc;
pctl->GetRect(&rc);
rc.left = x;
rc.bottom = y + rc.bottom - rc.top;
rc.top = y;
pctl->SetRect(&rc);
y += cySpacing;
}
}
//
// GameOptions implementation
//
bool GameOptionsForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!ShellForm::Init(pfrmm, pini, idf))
return false;
// No color options when screen depth is 4
ModeInfo mode;
gpdisp->GetMode(&mode);
if (mode.nDepth == 4)
GetControlPtr(kidcColorOptions)->Show(false);
// No display options when there is only one choice
if (ggame.GetModeMatchCount() == 1)
GetControlPtr(kidcDisplayOptions)->Show(false);
// Multiplayer changes
if (gfMultiplayer) {
GetControlPtr(kidcInGameOptions)->Show(false);
GetControlPtr(kidcPerformanceOptions)->Show(false);
GetControlPtr(kidcDisplayOptions)->Show(false);
}
// Can't delete mission packs from here on Palm because they may have been bundle-bit copied
// from card to internal ram; deleting them here and then exiting causes the launcher to crash
// because it expects them still to be there. For Palm we have an external application that does
// mission pack management
#ifdef PIL
GetControlPtr(kidcDeleteMissionPack)->Show(false);
#endif
// Format the remaining visible buttons
word aidcFormat[] = { kidcInGameOptions, kidcSoundOptions, kidcPerformanceOptions, kidcColorOptions, kidcDisplayOptions, kidcDeleteMissionPack };
FormatButtons(this, aidcFormat, ARRAYSIZE(aidcFormat), kidcInGameOptions, kidcSoundOptions);
return true;
}
void GameOptionsForm::OnControlSelected(word idc)
{
// Remember what button was pressed - the caller will want this
switch (idc) {
case kidcDeleteMissionPack:
{
ShellForm *pfrm = (ShellForm *)gpmfrmm->LoadForm(gpiniForms, kidfDeleteMissionPack, new DeleteMissionPackForm());
if (pfrm != NULL) {
pfrm->DoModal();
delete pfrm;
return;
}
}
break;
case kidcInGameOptions:
{
ShellForm *pfrm = (ShellForm *)gpmfrmm->LoadForm(gpiniForms, kidfInGameOptions, new InGameOptionsForm());
if (pfrm != NULL) {
pfrm->DoModal();
delete pfrm;
return;
}
}
break;
case kidcSoundOptions:
{
ShellForm *pfrm = (ShellForm *)gpmfrmm->LoadForm(gpiniForms, kidfSoundOptions, new SoundOptionsForm());
if (pfrm != NULL) {
pfrm->DoModal();
delete pfrm;
return;
}
}
break;
case kidcColorOptions:
// This'll get executed after return
break;
case kidcDisplayOptions:
{
ShellForm *pfrm = (ShellForm *)gpmfrmm->LoadForm(gpiniForms, kidfDisplayOptions, new DisplayOptionsForm());
if (pfrm != NULL) {
pfrm->DoModal();
delete pfrm;
return;
}
}
break;
case kidcPerformanceOptions:
{
ShellForm *pfrm = (ShellForm *)gpmfrmm->LoadForm(gpiniForms, kidfPerformanceOptions, new PerformanceOptionsForm());
if (pfrm != NULL) {
pfrm->DoModal();
delete pfrm;
return;
}
}
break;
}
Form::OnControlSelected(idc);
}
//
// InGameOptionsForm implementation
//
bool InGameOptionsForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!ShellForm::Init(pfrmm, pini, idf))
return false;
m_fLassoSelection = gfLassoSelection;
m_tGameSpeed = gtGameSpeed;
m_wfHandicap = gwfHandicap;
m_nScrollSpeed = gnScrollSpeed;
#if defined(IPHONE) || defined(SDL)
GetControlPtr(kidcLassoSelection)->Show(false);
#endif
InitResettableControls();
return true;
}
// Transplate game update rate into a 'multiplier from normal' string
void GetSpeedMultiplierString(char *psz, long tGameSpeed)
{
int n = 0;
if (tGameSpeed != 0) {
n = (8 * 100) / tGameSpeed;
}
int cWhole = n / 100;
int cFrac = n % 100;
sprintf(psz, "%d.%dx", cWhole, cFrac);
}
void InGameOptionsForm::InitResettableControls()
{
// Lasso
SetControlChecked(kidcLassoSelection, m_fLassoSelection);
// Game Speed
SliderControl *psldr = (SliderControl *)GetControlPtr(kidcGameSpeed);
psldr->SetRange(0, ARRAYSIZE(gatGameSpeeds) - 1);
psldr->SetValue(8);
for (int i = 0; i < ARRAYSIZE(gatGameSpeeds); i++) {
if (gatGameSpeeds[i] == m_tGameSpeed) {
psldr->SetValue(i);
break;
}
}
// Scroll Speed 1x to 5x, in .25 increments
#define knScrollSpeedMax 5
psldr = (SliderControl *)GetControlPtr(kidcScrollSpeed);
psldr->SetRange(0, (knScrollSpeedMax - 1) * 4);
psldr->SetValue((m_nScrollSpeed - 1.0) / 0.25);
// Difficulty
SetControlChecked(kidcEasy, m_wfHandicap == kfHcapEasy);
SetControlChecked(kidcNormal, m_wfHandicap == kfHcapNormal);
SetControlChecked(kidcHard, m_wfHandicap == kfHcapHard);
UpdateLabels();
}
void InGameOptionsForm::UpdateLabels()
{
char szT[80];
GetSpeedMultiplierString(szT, m_tGameSpeed);
LabelControl *plbl = (LabelControl *)GetControlPtr(kidcGameSpeedLabel);
plbl->SetText(szT);
plbl = (LabelControl *)GetControlPtr(kidcScrollSpeedLabel);
int cWhole = (int)m_nScrollSpeed;
int cFrac = (m_nScrollSpeed - (int)m_nScrollSpeed) * 100;
sprintf(szT, "%d.%dx", cWhole, cFrac);
plbl->SetText(szT);
}
void InGameOptionsForm::OnControlSelected(word idc)
{
switch (idc) {
case kidcGameSpeed:
{
SliderControl *psldr =
(SliderControl *)GetControlPtr(kidcGameSpeed);
m_tGameSpeed = gatGameSpeeds[psldr->GetValue()];
UpdateLabels();
}
break;
case kidcScrollSpeed:
{
SliderControl *psldr =
(SliderControl *)GetControlPtr(kidcScrollSpeed);
m_nScrollSpeed = 1.0 + psldr->GetValue() * 0.25;
UpdateLabels();
}
break;
case kidcEasy:
case kidcNormal:
case kidcHard:
{
SetControlChecked(kidcEasy, idc == kidcEasy);
SetControlChecked(kidcNormal, idc == kidcNormal);
SetControlChecked(kidcHard, idc == kidcHard);
}
break;
case kidcOk:
{
// Lasso and game speed, other
gfLassoSelection = GetControlChecked(kidcLassoSelection);
SliderControl *psldr = (SliderControl *)GetControlPtr(kidcGameSpeed);
ggame.SetGameSpeed(gatGameSpeeds[psldr->GetValue()]);
psldr = (SliderControl *)GetControlPtr(kidcScrollSpeed);
gnScrollSpeed = 1.0 + psldr->GetValue() * 0.25;
// Difficulty
if (GetControlChecked(kidcEasy))
gwfHandicap = kfHcapEasy;
else if (GetControlChecked(kidcNormal))
gwfHandicap = kfHcapNormal;
else if (GetControlChecked(kidcHard))
gwfHandicap = kfHcapHard;
if (gpplrLocal != NULL)
gpplrLocal->SetHandicap(gwfHandicap);
// Save prefs now in case the game crashes before exiting!
ggame.SavePreferences();
}
EndForm(idc);
break;
case kidcCancel:
EndForm(idc);
break;
case kidcDefault:
m_fLassoSelection = false;
m_tGameSpeed = kcmsUpdate / 20;
m_nScrollSpeed = 1.0;
m_wfHandicap = kfHcapDefault;
InitResettableControls();
break;
}
}
//
// SoundOptionsForm
//
bool SoundOptionsForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!ShellForm::Init(pfrmm, pini, idf))
return false;
// Save away values to restore in case of cancel
m_nVolume = gsndm.GetVolume();
m_fEnabled = gsndm.IsEnabled();
InitResettableControls();
return true;
}
void SoundOptionsForm::InitResettableControls()
{
SetControlChecked(kidcMute, !gsndm.IsEnabled());
SliderControl *psldr = (SliderControl *)GetControlPtr(kidcVol);
psldr->SetRange(0, 255);
int nVolume = gsndm.GetVolume();
if (nVolume < 0) {
psldr->Show(false);
GetControlPtr(kidcVolLabel)->Show(false);
GetControlPtr(kidcVolumeString)->Show(false);
} else {
psldr->SetValue(nVolume);
}
UpdateLabels();
}
void SoundOptionsForm::UpdateLabels()
{
char szT[80];
LabelControl *plbl = (LabelControl *)GetControlPtr(kidcVolLabel);
itoa((gsndm.GetVolume() * 100) / 255, szT, 10);
plbl->SetText(szT);
}
void SoundOptionsForm::OnControlSelected(word idc)
{
switch (idc) {
case kidcVol:
{
SliderControl *psldr = (SliderControl *)GetControlPtr(kidcVol);
gsndm.SetVolume(psldr->GetValue());
UpdateLabels();
}
break;
case kidcMute:
{
gsndm.Enable(!GetControlChecked(kidcMute));
InitResettableControls();
}
break;
case kidcCancel:
gsndm.Enable(m_fEnabled);
gsndm.SetVolume(m_nVolume);
EndForm(idc);
break;
case kidcOk:
ggame.SavePreferences();
EndForm(idc);
break;
}
}
//
// Color Options Form
//
ColorOptionsForm::ColorOptionsForm(Palette *ppal)
{
m_ppal = ppal;
}
bool ColorOptionsForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!Form::Init(pfrmm, pini, idf))
return false;
// Save away values to restore in case of cancel
m_nHueOffset = gnHueOffset;
m_nSatMultiplier = gnSatMultiplier;
m_nLumOffset = gnLumOffset;
InitResettableControls();
// Position the form middle of screen, bottom
Size sizDib;
m_pfrmm->GetDib()->GetSize(&sizDib);
Rect rc;
rc.left = ((sizDib.cx - m_rc.Width()) / 2) & ~1;
rc.top = sizDib.cy - m_rc.Height();
rc.right = rc.left + m_rc.Width();
rc.bottom = rc.top + m_rc.Height();
SetRect(&rc);
return true;
}
void ColorOptionsForm::InitResettableControls()
{
SliderControl *psldr = (SliderControl *)GetControlPtr(kidcLum);
psldr->SetRange(-100, 100);
psldr->SetValue(gnLumOffset);
psldr = (SliderControl *)GetControlPtr(kidcSat);
psldr->SetRange(-100, 100);
psldr->SetValue(gnSatMultiplier);
psldr = (SliderControl *)GetControlPtr(kidcHue);
psldr->SetRange(-100, 100);
psldr->SetValue(gnHueOffset);
UpdateLabels();
}
void ColorOptionsForm::UpdateLabels()
{
char szT[80];
LabelControl *plbl = (LabelControl *)GetControlPtr(kidcHueLabel);
itoa(gnHueOffset, szT, 10);
plbl->SetText(szT);
plbl = (LabelControl *)GetControlPtr(kidcSatLabel);
itoa(gnSatMultiplier, szT, 10);
plbl->SetText(szT);
plbl = (LabelControl *)GetControlPtr(kidcLumLabel);
itoa(gnLumOffset, szT, 10);
plbl->SetText(szT);
}
void ColorOptionsForm::OnControlSelected(word idc)
{
switch (idc) {
case kidcHue:
case kidcSat:
case kidcLum:
{
SliderControl *psldr = (SliderControl *)GetControlPtr(kidcHue);
gnHueOffset = (short)psldr->GetValue();
psldr = (SliderControl *)GetControlPtr(kidcSat);
gnSatMultiplier = (short)psldr->GetValue();
psldr = (SliderControl *)GetControlPtr(kidcLum);
gnLumOffset = (short)psldr->GetValue();
UpdateLabels();
SetHslAdjustedPalette(m_ppal, gnHueOffset, gnSatMultiplier, gnLumOffset);
// Some devices such as the PocketPC need the form redrawn because setting the palette
// is only setting an 8->16 bit translation table, and only the controls are redrawing.
#ifdef CE
gpmfrmm->InvalidateRect(NULL);
#endif
}
break;
case kidcCancel:
if (m_nHueOffset != gnHueOffset || m_nSatMultiplier != gnSatMultiplier || m_nLumOffset != gnLumOffset) {
gnHueOffset = m_nHueOffset;
gnSatMultiplier = m_nSatMultiplier;
gnLumOffset = m_nLumOffset;
SetHslAdjustedPalette(m_ppal, gnHueOffset, gnSatMultiplier, gnLumOffset);
}
EndForm(idc);
break;
case kidcOk:
// Save prefs now in case the game crashes before exiting!
ggame.SavePreferences();
EndForm(idc);
break;
case kidcDefault:
if (gnHueOffset != 0 || gnSatMultiplier != 0|| gnLumOffset != 0) {
gnHueOffset = 0;
gnSatMultiplier = 0;
gnLumOffset = 0;
SetHslAdjustedPalette(m_ppal, gnHueOffset, gnSatMultiplier, gnLumOffset);
}
InitResettableControls();
// Some devices such as the PocketPC need the form redrawn because setting the palette
// is only setting an 8->16 bit translation table, and only the controls are redrawing.
#ifdef CE
gpmfrmm->InvalidateRect(NULL);
#endif
break;
}
}
void ColorOptionsForm::OnPaintBackground(DibBitmap *pbm, UpdateMap *pupd)
{
// Draw the fancy background bitmap
RawBitmap *prbm = LoadRawBitmap("titlescreenbkgd.rbm");
BltHelper(pbm, prbm, pupd, m_rc.left, m_rc.top);
delete prbm;
}
//
// Display options form
//
bool DisplayOptionsForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!ShellForm::Init(pfrmm, pini, idf))
return false;
InitResettableControls();
// Initialize display mode list
ListControl *plstc = (ListControl *)GetControlPtr(kidcModesList);
plstc->SetFlags(plstc->GetFlags() | kfLstcBorder);
int immCur = ggame.GetModeMatchCurrent();
int cmm = ggame.GetModeMatchCount();
// Make resolution list
for (int imm = 0; imm < cmm; imm++) {
ModeMatch mm;
ggame.GetModeMatch(imm, &mm);
// Art
char szArt[64];
if (mm.nDepthData < 8) {
strcpy(szArt, "gray");
} else {
strcpy(szArt, "color");
}
switch (mm.nSizeData) {
case 16:
strcat(szArt, " low-res art");
break;
case 20:
// Don't want to insult PPC users
#ifdef CE
strcat(szArt, " art");
#else
strcat(szArt, " med-res art");
#endif
break;
case 24:
strcat(szArt, " high-res art");
break;
}
// Orientation
ModeInfo mode;
gpdisp->GetModeInfo(mm.imode, &mode);
char szOrientation[64];
szOrientation[0] = 0;
if (mode.nDegreeOrientation != 0)
sprintf(szOrientation, ", %d deg", mode.nDegreeOrientation);
char szT[64];
#ifdef DEV_BUILD
sprintf(szT, "%dx%dx%d, %s%s", mode.cx, mode.cy, mode.nDepth, szArt, szOrientation);
#else
sprintf(szT, "%dx%d, %s%s", mode.cx, mode.cy, szArt, szOrientation);
#endif
plstc->Add(szT, (void *)(pword)imm);
}
plstc->Select(immCur);
return true;
}
void DisplayOptionsForm::InitResettableControls()
{
}
void DisplayOptionsForm::OnControlSelected(word idc)
{
switch (idc) {
case kidcOk:
{
ListControl *plstc = (ListControl *)GetControlPtr(kidcModesList);
if (plstc->GetFlags() & kfCtlVisible) {
int immNew = (int)(long)plstc->GetSelectedItemData();
ggame.RequestModeChange(immNew);
}
// Save prefs now in case the game crashes before exiting!
ggame.SavePreferences();
}
EndForm(idc);
break;
case kidcCancel:
EndForm(idc);
break;
case kidcDefault:
{
ListControl *plstc = (ListControl *)GetControlPtr(kidcModesList);
plstc->Select(ggame.GetModeMatchBest(), true);
InitResettableControls();
}
break;
}
}
//
// PerformanceOptionsForm implementation
//
bool PerformanceOptionsForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!ShellForm::Init(pfrmm, pini, idf))
return false;
m_wfPerfOptions = gwfPerfOptions;
InitResettableControls();
return true;
}
void PerformanceOptionsForm::InitResettableControls()
{
SetControlChecked(kidcRocketShots, (m_wfPerfOptions & kfPerfRocketShots) != 0);
SetControlChecked(kidcRocketTrails, (m_wfPerfOptions & kfPerfRocketTrails) != 0);
SetControlChecked(kidcRocketImpacts, (m_wfPerfOptions & kfPerfRocketImpacts) != 0);
SetControlChecked(kidcShots, (m_wfPerfOptions & kfPerfShots) != 0);
SetControlChecked(kidcShotImpacts, (m_wfPerfOptions & kfPerfShotImpacts) != 0);
SetControlChecked(kidcSelectionBrackets, (m_wfPerfOptions & kfPerfSelectionBrackets) != 0);
SetControlChecked(kidcSmoke, (m_wfPerfOptions & kfPerfSmoke) != 0);
SetControlChecked(kidcEnemyDamageIndicator, (m_wfPerfOptions & kfPerfEnemyDamageIndicator) != 0);
SetControlChecked(kidcScorchMarks, (m_wfPerfOptions & kfPerfScorchMarks) != 0);
SetControlChecked(kidcSymbolFlashing, (m_wfPerfOptions & kfPerfSymbolFlashing) != 0);
}
void PerformanceOptionsForm::OnControlSelected(word idc)
{
switch (idc) {
case kidcCancel:
EndForm(idc);
break;
case kidcOk:
{
word wfT = 0;
if (GetControlChecked(kidcRocketShots))
wfT |= kfPerfRocketShots;
if (GetControlChecked(kidcRocketTrails))
wfT |= kfPerfRocketTrails;
if (GetControlChecked(kidcRocketImpacts))
wfT |= kfPerfRocketImpacts;
if (GetControlChecked(kidcShots))
wfT |= kfPerfShots;
if (GetControlChecked(kidcShotImpacts))
wfT |= kfPerfShotImpacts;
if (GetControlChecked(kidcSelectionBrackets))
wfT |= kfPerfSelectionBrackets;
if (GetControlChecked(kidcSmoke))
wfT |= kfPerfSmoke;
if (GetControlChecked(kidcEnemyDamageIndicator))
wfT |= kfPerfEnemyDamageIndicator;
if (GetControlChecked(kidcScorchMarks))
wfT |= kfPerfScorchMarks;
if (GetControlChecked(kidcSymbolFlashing))
wfT |= kfPerfSymbolFlashing;
gwfPerfOptions = wfT;
ggame.SavePreferences();
EndForm(idc);
}
break;
case kidcDefault:
m_wfPerfOptions = kfPerfAll;
InitResettableControls();
break;
}
}
//
// TestOptionsForm implementation
//
bool TestOptionsForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!Form::Init(pfrmm, pini, idf))
return false;
CheckBoxControl *pcbox = (CheckBoxControl *)GetControlPtr(kidcDrawLines);
#ifdef DRAW_LINES
pcbox->SetChecked(gfDrawLines);
#else
pcbox->Show(false);
#endif
pcbox = (CheckBoxControl *)GetControlPtr(kidcDrawPaths);
#ifdef DRAW_PATHS
pcbox->SetChecked(gfDrawPaths);
#else
pcbox->Show(false);
#endif
pcbox = (CheckBoxControl *)GetControlPtr(kidcShowStats);
#ifdef STATS_DISPLAY
pcbox->SetChecked(gfShowStats);
#else
pcbox->Show(false);
#endif
pcbox = (CheckBoxControl *)GetControlPtr(kidcLockStep);
pcbox->SetChecked(gfLockStep);
SetControlChecked(kidcOvermind, gfOvermindEnabled);
SetControlChecked(kidcShowFPS, gfShowFPS);
SetControlChecked(kidcSuspendUpdates, gfSuspendUpdates);
SetControlChecked(kidcMaxRepaint, (gevm.GetRedrawFlags() & kfRedrawMax) != 0);
#ifdef DRAW_UPDATERECTS
SetControlChecked(kidcDrawUpdateRects, gfDrawUpdateRects);
#endif
SetControlChecked(kidcGodMode, gfGodMode);
SetControlChecked(kidcAutosave, gfAutosave);
SetControlChecked(kidcStylusUI, gfStylusUI);
dword ff = ggame.GetSimUIForm()->GetPenHandler()->GetFlags();
return true;
}
void TestOptionsForm::OnControlSelected(word idc)
{
switch (idc) {
case kidcBreak:
#if defined(PIL) && !defined(PNO)
DebugBreak();
#endif
break;
case kidcGobCount:
{
Form *pfrm = gpmfrmm->LoadForm(gpiniForms, kidfGobCount, new GobCountForm());
pfrm->DoModal();
delete pfrm;
}
break;
case kidcMemoryUse:
{
Form *pfrm = gpmfrmm->LoadForm(gpiniForms, kidfMemoryUse, new MemoryUseForm());
pfrm->DoModal();
delete pfrm;
}
break;
#ifdef DRAW_PATHS
case kidcDrawPaths:
gfDrawPaths = !gfDrawPaths;
break;
#endif
#ifdef DRAW_LINES
case kidcDrawLines:
gfDrawLines = !gfDrawLines;
break;
#endif
case kidcLockStep:
gfLockStep = !gfLockStep;
#ifdef MP_DEBUG_SHAREDMEM
extern bool gfMPServer;
if (gfMPServer)
gpsmw->fDetectSyncErrors = gfLockStep;
#endif
break;
case kidcStylusUI:
gfStylusUI = !gfStylusUI;
ggame.GetSimUIForm()->SetUIType(gfStylusUI == true ?
kuitStylus : kuitFinger);
break;
case kidcOvermind:
{
for (Gob *pgob = ggobm.GetFirstGob(); pgob != NULL; pgob = ggobm.GetNextGob(pgob)) {
if (pgob->GetType() == kgtOvermind)
((OvermindGob *)pgob)->Toggle();
}
gfOvermindEnabled = !gfOvermindEnabled;
}
break;
case kidcClearFog:
gsim.GetLevel()->GetFogMap()->RevealAll(gpupdSim);
break;
#ifdef STATS_DISPLAY
case kidcShowStats:
gfShowStats = !gfShowStats;
break;
#endif
case kidcShowFPS:
gfShowFPS = !gfShowFPS;
ggame.GetSimUIForm()->GetControlPtr(kidcFps)->Show(gfShowFPS);
break;
case kidcMaxRepaint:
if (gevm.GetRedrawFlags() & kfRedrawMax) {
gevm.ClearRedrawFlags(kfRedrawMax);
} else {
gevm.SetRedrawFlags(kfRedrawMax);
}
break;
case kidcSuspendUpdates:
gfSuspendUpdates = !gfSuspendUpdates;
break;
case kidcDrawUpdateRects:
#ifdef DRAW_UPDATERECTS
gfDrawUpdateRects = !gfDrawUpdateRects;
#endif
break;
case kidcGodMode:
gfGodMode = !gfGodMode;
break;
case kidcAutosave:
gfAutosave = !gfAutosave;
break;
case kidcHelp:
Help();
break;
default:
EndForm(idc);
}
}
//
// MemoryUseForm implementation
//
bool MemoryUseForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!Form::Init(pfrmm, pini, idf))
return false;
SetControlChecked(kidcLimitCache, gcam.GetLimit() != 0);
UpdateLabels();
SetBackgroundColorIndex(kiclrBlack);
return true;
}
void MemoryUseForm::OnControlSelected(word idc)
{
switch (idc) {
case kidcClearCache:
gcam.MakeSpace((dword)-1);
UpdateLabels();
break;
case kidcLimitCache:
if (gcam.GetLimit() == 0) {
gcam.SetLimit(10240);
} else {
gcam.SetLimit(0);
}
UpdateLabels();
break;
case kidcAdd10KCache:
gcam.SetLimit(gcam.GetLimit() + 10240);
UpdateLabels();
break;
case kidcSub10KCache:
gcam.SetLimit(gcam.GetLimit() - 10240);
UpdateLabels();
break;
default:
EndForm(idc);
}
}
extern dword gcbDynMemAtStart;
extern dword gcbDbMemAtStart;
void MemoryUseForm::UpdateLabels()
{
dword cbDyn, cbDb;
dword cbTotal = gmmgr.GetTotalSize(&cbDyn, &cbDb);
#ifdef PIL
dword cbFree;
dword cbMax;
MemHeapFreeBytes(0, (UInt32 *)&cbFree, (UInt32 *)&cbMax);
#else
dword cbFree = 0;
#endif
char szT[128];
sprintf(szT, "start dyn, db free: %u, %u", gcbDynMemAtStart, gcbDbMemAtStart);
((LabelControl *)GetControlPtr(kidcDynDbInitial))->SetText(szT);
sprintf(szT, "mmgr dyn, db reserve: %u, %u", cbDyn, cbDb);
((LabelControl *)GetControlPtr(kidcMmgrDynDbReserve))->SetText(szT);
sprintf(szT, "dyn use: %u / %u", gcbDynMemAtStart - cbFree, gcbDynMemAtStart);
((LabelControl *)GetControlPtr(kidcDynUse))->SetText(szT);
sprintf(szT, "mmgr use: %u / %u", cbTotal - gmmgr.GetFreeSize(), cbTotal);
((LabelControl *)GetControlPtr(kidcMmgrUse))->SetText(szT);
sprintf(szT, "cache use: %u", gcam.GetTotalSize());
((LabelControl *)GetControlPtr(kidcCacheUse))->SetText(szT);
bool fCacheLimit = (gcam.GetLimit() != 0);
GetControlPtr(kidcAdd10KCache)->Show(fCacheLimit);
GetControlPtr(kidcSub10KCache)->Show(fCacheLimit);
GetControlPtr(kidcCacheLimit)->Show(fCacheLimit);
sprintf(szT, "Cache Limit: %u", gcam.GetLimit());
((LabelControl *)GetControlPtr(kidcCacheLimit))->SetText(szT);
}
//
// GobCountForm
//
// Note: matches gob types (kgt*)
static char *s_aszGobs[] = {
"none", "guard", "trooper", "hrc", "decal", "scenery", "anim", "pwr gen",
"proc", "struc", "unit", "bullpup", "hq", "randc", "vts", "srv ctr",
"broadsw", "libertr", "eagle", "hydra",
"raider", "wareh", "domin", "overm", "tshot", "rockt", "gtower", "rtower", "scorch",
"smoke", "puff", "bullet", "cyclops", "cy shot", "andy", "repl", "actvtr", "fox"
};
void GobCountForm::OnPaint(DibBitmap *pbm)
{
int acbGob[ARRAYSIZE(s_aszGobs)];
memset(acbGob, 0, sizeof(acbGob));
int acGobs[ARRAYSIZE(s_aszGobs)];
memset(acGobs, 0, sizeof(acGobs));
int acGobsSide[ARRAYSIZE(s_aszGobs)][kcSides];
memset(acGobsSide, 0, sizeof(acGobsSide));
bool afUnit[ARRAYSIZE(s_aszGobs)];
memset(afUnit, 0, sizeof(afUnit));
bool afStructure[ARRAYSIZE(s_aszGobs)];
memset(afStructure, 0, sizeof(afStructure));
bool afMobileUnit[ARRAYSIZE(s_aszGobs)];
memset(afMobileUnit, 0, sizeof(afMobileUnit));
for (Gob *pgobT = ggobm.GetFirstGob(); pgobT != NULL; pgobT = ggobm.GetNextGob(pgobT)) {
GobType gt = pgobT->GetType();
acGobs[gt]++;
#if defined(PIL)
acbGob[gt] = MemPtrSize(pgobT);
#elif defined(IPHONE) || defined(SDL)
acbGob[gt] = 0;
#else
acbGob[gt] = _msize(pgobT);
#endif
if (pgobT->GetFlags() & kfGobUnit) {
afUnit[gt] = true;
UnitGob *punt = (UnitGob *)pgobT;
acGobsSide[gt][punt->GetSide()]++;
}
if (pgobT->GetFlags() & kfGobStructure)
afStructure[gt] = true;
if (pgobT->GetFlags() & kfGobMobileUnit)
afMobileUnit[gt] = true;
}
int y = m_rc.top;
int x = m_rc.left;
char szT[64];
int gt;
for (gt = 0; gt < ARRAYSIZE(s_aszGobs); gt++) {
if (acGobs[gt] == 0)
continue;
// Unit?
if (afUnit[gt]) {
char szT2[64];
sprintf(szT2, "%s=%d", s_aszGobs[gt], acbGob[gt]);
FormatSideString(szT2, acGobsSide[gt], szT);
} else {
sprintf(szT, "%s=%d:%d", s_aszGobs[gt], acbGob[gt], acGobs[gt]);
}
OutputString(pbm, szT, &x, &y);
}
// Units per side
int acUnitsPerSide[kcSides];
memset(acUnitsPerSide, 0, sizeof(acUnitsPerSide));
for (gt = 0; gt < ARRAYSIZE(s_aszGobs); gt++) {
if (!afUnit[gt])
continue;
for (Side side = ksideNeutral; side < kcSides; side++)
acUnitsPerSide[side] += acGobsSide[gt][side];
}
FormatSideString("Units", acUnitsPerSide, szT);
OutputString(pbm, szT, &x, &y);
// Structures per side
int acStructuresPerSide[kcSides];
memset(acStructuresPerSide, 0, sizeof(acStructuresPerSide));
for (gt = 0; gt < ARRAYSIZE(s_aszGobs); gt++) {
if (!afStructure[gt])
continue;
for (Side side = ksideNeutral; side < kcSides; side++)
acStructuresPerSide[side] += acGobsSide[gt][side];
}
FormatSideString("Structs", acStructuresPerSide, szT);
OutputString(pbm, szT, &x, &y);
// Mobile units per side
int acMobileUnitsPerSide[kcSides];
memset(acMobileUnitsPerSide, 0, sizeof(acMobileUnitsPerSide));
for (gt = 0; gt < ARRAYSIZE(s_aszGobs); gt++) {
if (!afMobileUnit[gt])
continue;
for (Side side = ksideNeutral; side < kcSides; side++)
acMobileUnitsPerSide[side] += acGobsSide[gt][side];
}
FormatSideString("Munts", acMobileUnitsPerSide, szT);
OutputString(pbm, szT, &x, &y);
// Total gobs
int cGobs = 0;
for (gt = 0; gt < ARRAYSIZE(s_aszGobs); gt++)
cGobs += acGobs[gt];
sprintf(szT, "total:%d", cGobs);
OutputString(pbm, szT, &x, &y);
// Total memory consumed
long cbGobs = 0;
for (gt = 0; gt < ARRAYSIZE(s_aszGobs); gt++)
cbGobs += (long)(acbGob[gt] + 8) * acGobs[gt];
sprintf(szT, "gob mem:%ld", cbGobs);
OutputString(pbm, szT, &x, &y);
#ifdef PIL
UInt32 cbFree, cbMax;
MemHeapFreeBytes(0, &cbFree, &cbMax);
sprintf(szT, "heap free:%ld", cbFree);
OutputString(pbm, szT, &x, &y);
sprintf(szT, "dyn use:%ld/%ld", gcbDynMemAtStart - cbFree, gcbDynMemAtStart);
OutputString(pbm, szT, &x, &y);
#endif
}
void GobCountForm::OutputString(DibBitmap *pbm, char *psz, int *px, int *py)
{
Font *pfnt = gapfnt[kifntDefault];
char *pszNext = ",";
int cxNext = pfnt->GetTextExtent(pszNext);
int x = *px;
int y = *py;
int cx = pfnt->GetTextExtent(psz);
if (x + cxNext + cx > m_rc.right) {
y += pfnt->GetHeight();
x = m_rc.left;
} else {
if (x != m_rc.left) {
pfnt->DrawText(pbm, pszNext, x, y);
x += cxNext;
}
}
pfnt->DrawText(pbm, psz, x, y);
x += cx;
*px = x;
*py = y;
}
void GobCountForm::FormatSideString(char *pszIn, int *acPerSide, char *pszOut)
{
int cTotal = 0;
Side sideLast = (Side)-1;
for (Side side = ksideNeutral; side < kcSides; side++) {
cTotal += acPerSide[side];
if (acPerSide[side] != 0)
sideLast = side;
}
sprintf(pszOut, "%s:", pszIn);
char szT[32];
for (Side sideT = ksideNeutral; sideLast != (Side)-1 && sideT <= sideLast; sideT++) {
sprintf(szT, sideT != sideLast ? "%d/" : "%d", acPerSide[sideT]);
strcat(pszOut, szT);
}
sprintf(szT, "(%d)", cTotal);
strcat(pszOut, szT);
}
void GobCountForm::OnUpdateMapInvalidate(UpdateMap *pupd, Rect *prcOpaque)
{
pupd->InvalidateRect();
Form::OnUpdateMapInvalidate(pupd, prcOpaque);
}
bool GobCountForm::OnPenEvent(Event *pevt)
{
if (pevt->eType == penDownEvent) {
EndForm(kidcOk);
return true;
}
return false;
}
//
// InputPanel form
//
class InputPanelForm : public ShellForm
{
public:
virtual void OnControlSelected(word idc) secInputPanelForm;
virtual void OnUpdateMapInvalidate(UpdateMap *pupd, Rect *prcOpaque) secInputPanelForm;
virtual void OnPaint(DibBitmap *pbm) secInputPanelForm;
virtual bool OnPenEvent(Event *pevt) secInputPanelForm;
virtual bool EventProc(Event *pevt) secInputPanelForm;
virtual bool Init(FormMgr *pfrmm, IniReader *pini, word idf) secInputPanelForm;
void SetLabel(const char *pszLabel) secInputPanelForm;
void SetEdit(const char *pszEdit) secInputPanelForm;
void GetEdit(char *psz, int cb) secInputPanelForm;
void SetChars(char **ppsz, int cRows) secInputPanelForm;
void SetValidateProc(bool (*pfnValidateInput)(const char *psz)) {
m_pfnValidateInput = pfnValidateInput;
}
private:
char TrackPen(int x, int y, bool fDown) secInputPanelForm;
void OnChar(char ch) secInputPanelForm;
void OnBackspace() secInputPanelForm;
int GetCharRect(int iCol, int iRow, char *pch, Rect *prcChar) secInputPanelForm;
char **m_ppszChars;
int m_cRows;
int m_iColLast;
int m_iRowLast;
bool m_fDown;
int m_xForm;
int m_yForm;
Font *m_pfnt;
bool (*m_pfnValidateInput)(const char *psz);
};
bool DoInputPanelForm(char **ppszChars, int cRows, const char *pszLabel,
const char *pszEdit, char *pszOut, int cbOut,
bool (*pfnValidateInput)(const char *psz))
{
InputPanelForm *pfrm = (InputPanelForm *)gpmfrmm->LoadForm(gpiniForms, kidfInputPanel, new InputPanelForm());
if (pfrm != NULL) {
pfrm->SetValidateProc(pfnValidateInput);
pfrm->SetLabel(pszLabel);
pfrm->SetEdit(pszEdit);
if (ppszChars != NULL)
pfrm->SetChars(ppszChars, cRows);
if (pfrm->DoModal()) {
pfrm->GetEdit(pszOut, cbOut);
delete pfrm;
return true;
} else {
strncpyz(pszOut, pszEdit, cbOut);
delete pfrm;
return false;
}
}
return false;
}
void DoInputPanelForm(Form *pfrm, word idcLabel, word idcEdit)
{
LabelControl *plbl = (LabelControl *)pfrm->GetControlPtr(idcLabel);
const char *pszLabel = plbl->GetText();
char szEdit[128];
EditControl *pedt = (EditControl *)pfrm->GetControlPtr(idcEdit);
pedt->GetText(szEdit, sizeof(szEdit));
DoInputPanelForm(NULL, 0, pszLabel, szEdit, szEdit, sizeof(szEdit));
pedt->SetText(szEdit);
}
bool InputPanelForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
// Get initial form dimensions before passing to ShellForm since it reformats
char szForm[32];
itoa(idf, szForm, 10);
int x, y, cx, cy;
pini->GetPropertyValue(szForm, "FORM", "(%d %d %d %d)", &x, &y, &cx, &cy);
Size siz;
pfrmm->GetDib()->GetSize(&siz);
m_xForm = (siz.cx - PcFromFc(cx)) / 2;
m_yForm = (siz.cy - PcFromFc(cy)) / 2;
m_pfnt = gapfnt[kifntShadow];
m_iColLast = -1;
m_iRowLast = -1;
m_fDown = false;
static char *s_apszChars[] = {
"ABCDEFGHIJKLM",
"NOPQRSTUVWXYZ",
"abcdefghijklm",
"nopqrstuvwxyz",
"1234567890?!*"
};
m_ppszChars = s_apszChars;
m_cRows = ARRAYSIZE(s_apszChars);
m_pfnValidateInput = NULL;
return ShellForm::Init(pfrmm, pini, idf);
}
const int kxBox = 5;
const int kyBox = 35;
const int kcxBox = (160 - (5 + 5));
const int kcyBox = (118 - kyBox - 5);
int InputPanelForm::GetCharRect(int iCol, int iRow, char *pch, Rect *prcChar)
{
int cRows = m_cRows;
int cCols = (int)strlen(m_ppszChars[0]);
prcChar->SetEmpty();
if (iRow < 0 || iRow >= cRows)
return 0;
if (iCol < 0 || iCol >= (int)strlen(m_ppszChars[iRow]))
return 0;
prcChar->left = PcFromFc(kxBox) + PcFromFc(kcxBox) * iCol / cCols;
prcChar->right = PcFromFc(kxBox) + PcFromFc(kcxBox) * (iCol + 1) / cCols;
prcChar->top = PcFromFc(kyBox) + PcFromFc(kcyBox) * iRow / cRows;
prcChar->bottom = PcFromFc(kyBox) + PcFromFc(kcyBox) * (iRow + 1) / cRows;
prcChar->Offset(m_xForm, m_yForm);
*pch = m_ppszChars[iRow][iCol];
return m_pfnt->GetTextExtent(pch, 1);
}
char InputPanelForm::TrackPen(int x, int y, bool fDown)
{
// Hittest
char ch = (char)-1;
Rect rcChar;
int iRow, iCol;
bool fFound = false;
for (iRow = 0; iRow < m_cRows; iRow++) {
int cCols = (int)strlen(m_ppszChars[iRow]);
for (iCol = 0; iCol < cCols; iCol++) {
GetCharRect(iCol, iRow, &ch, &rcChar);
if (rcChar.PtIn(x, y)) {
fFound = true;
break;
}
}
if (fFound)
break;
}
// Track
if (iRow != m_iRowLast || iCol != m_iColLast || fDown != m_fDown) {
char chT;
Rect rcT;
GetCharRect(iCol, iRow, &chT, &rcT);
InvalidateRect(&rcT);
GetCharRect(m_iColLast, m_iRowLast, &chT, &rcT);
InvalidateRect(&rcT);
m_iRowLast = iRow;
m_iColLast = iCol;
}
m_fDown = fDown;
return fFound ? ch : (char)-1;
}
bool InputPanelForm::OnPenEvent(Event *pevt)
{
switch (pevt->eType) {
case penDownEvent:
TrackPen(pevt->x, pevt->y, true);
break;
case penUpEvent:
{
char ch = TrackPen(pevt->x, pevt->y, false);
if (ch != (char)-1) {
gsndm.PlaySfx(ksfxGuiButtonTap);
OnChar(ch);
}
}
break;
case penMoveEvent:
TrackPen(pevt->x, pevt->y, m_fDown);
break;
}
return ShellForm::OnPenEvent(pevt);
}
bool InputPanelForm::EventProc(Event *pevt)
{
if (pevt->eType != keyDownEvent)
return ShellForm::EventProc(pevt);
// Keyboard interface
if (pevt->chr == chrBackspace || pevt->chr == chrDelete) {
OnBackspace();
} else {
for (int iRow = 0; iRow < m_cRows; iRow++) {
int cCols = (int)strlen(m_ppszChars[iRow]);
for (int iCol = 0; iCol < cCols; iCol++) {
if (pevt->chr == m_ppszChars[iRow][iCol])
OnChar(pevt->chr);
}
}
}
return false;
}
void InputPanelForm::OnUpdateMapInvalidate(UpdateMap *pupd, Rect *prcOpaque)
{
ShellForm::OnUpdateMapInvalidate(pupd, prcOpaque);
Rect rc;
rc.SetEmpty();
for (int iRow = 0; iRow < m_cRows; iRow++) {
int cCols = (int)strlen(m_ppszChars[iRow]);
for (int iCol = 0; iCol < cCols; iCol++) {
Rect rcChar;
char ch;
GetCharRect(iCol, iRow, &ch, &rcChar);
rc.Union(&rcChar);
}
}
pupd->InvalidateRect(&rc);
}
void InputPanelForm::OnPaint(DibBitmap *pbm)
{
ShellForm::OnPaint(pbm);
int cyChar = m_pfnt->GetHeight();
for (int iRow = 0; iRow < m_cRows; iRow++) {
int cCols = (int)strlen(m_ppszChars[iRow]);
for (int iCol = 0; iCol < cCols; iCol++) {
Rect rcChar;
char ch;
int cxChar = GetCharRect(iCol, iRow, &ch, &rcChar);
int xChar = rcChar.left + (rcChar.Width() - cxChar) / 2;
int yChar = rcChar.top + (rcChar.Height() - cyChar) / 2;
m_pfnt->DrawText(pbm, &ch, xChar, yChar, 1);
if (iCol == m_iColLast && iRow == m_iRowLast && m_fDown)
DrawBorder(pbm, &rcChar, 1, GetColor(kiclrWhite), NULL);
}
}
}
void InputPanelForm::OnChar(char ch)
{
char szT[128];
GetEdit(szT, sizeof(szT));
int cch = (int)strlen(szT);
if (cch < sizeof(szT) - 1) {
szT[cch] = ch;
szT[cch + 1] = 0;
SetEdit(szT);
}
}
void InputPanelForm::OnBackspace()
{
char szT[128];
GetEdit(szT, sizeof(szT));
int cch = (int)strlen(szT);
if (cch > 0) {
szT[cch - 1] = 0;
SetEdit(szT);
}
}
void InputPanelForm::OnControlSelected(word idc)
{
if (idc == kidcInputEdit)
return;
if (idc == kidcBackspace) {
OnBackspace();
return;
}
if (idc == kidcOk) {
if (m_pfnValidateInput != NULL) {
char szT[255];
GetEdit(szT, sizeof(szT));
if (!m_pfnValidateInput(szT))
return;
}
}
ShellForm::OnControlSelected(idc);
}
void InputPanelForm::SetLabel(const char *pszLabel)
{
LabelControl *plbl = (LabelControl *)GetControlPtr(kidcInputLabel);
plbl->SetText(pszLabel);
Rect rcLabel;
plbl->GetRect(&rcLabel);
EditControl *pedt = (EditControl *)GetControlPtr(kidcInputEdit);
Rect rcEdit;
pedt->GetRect(&rcEdit);
rcEdit.left = rcLabel.right + 3;
pedt->SetRect(&rcEdit);
}
void InputPanelForm::SetChars(char **ppsz, int cRows)
{
m_ppszChars = ppsz;
m_cRows = cRows;
}
void InputPanelForm::SetEdit(const char *pszEdit)
{
EditControl *pedt = (EditControl *)GetControlPtr(kidcInputEdit);
pedt->SetText(pszEdit);
}
void InputPanelForm::GetEdit(char *psz, int cb)
{
EditControl *pedt = (EditControl *)GetControlPtr(kidcInputEdit);
pedt->GetText(psz, cb);
}
// DeleteMissionPackForm
bool DeleteMissionPackForm::Init(FormMgr *pfrmm, IniReader *pini, word idf)
{
if (!ShellForm::Init(pfrmm, pini, idf))
return false;
PopulateList();
return true;
}
void DeleteMissionPackForm::PopulateList()
{
ListControl *plstc = (ListControl *)GetControlPtr(kidcMissionPackList);
plstc->Clear();
#if 0 // TODO:
Enum enm;
char szAddon[kcbFilename];
while (HostEnumAddonFiles(&enm, szAddon, sizeof(szAddon)))
plstc->Add(szAddon, NULL);
#endif
GetControlPtr(kidcOk)->Show(false);
}
void DeleteMissionPackForm::OnControlNotify(word idc, int nNotify)
{
if (idc != kidcMissionPackList)
return;
if (nNotify == knNotifySelectionChange || nNotify == knNotifySelectionTap) {
ListControl *plstc = (ListControl *)GetControlPtr(kidcMissionPackList);
ListItem *pli = plstc->GetSelectedItem();
GetControlPtr(kidcOk)->Show(pli != NULL);
}
}
void DeleteMissionPackForm::OnControlSelected(word idc)
{
switch (idc) {
case kidcMissionPackList:
return;
case kidcOk:
// Delete
{
ListControl *plstc = (ListControl *)GetControlPtr(kidcMissionPackList);
char szFn[64];
plstc->GetSelectedItemText(szFn, sizeof(szFn));
if (true) { // TODO: !gpakr.Delete(gpszDataDir, szFn)) {
HtMessageBox(kfMbWhiteBorder, "Error", "Mission Pack in use!");
} else {
PopulateList();
}
}
return;
case kidcCancel:
// Back
ShellForm::OnControlSelected(idc);
break;
}
}
} // namespace wi