Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef HODJNPODJ_LIFE_GAME_H
#define HODJNPODJ_LIFE_GAME_H
#include "bagel/boflib/sound.h"
#include "bagel/hodjnpodj/hnplibs/gamedll.h"
namespace Bagel {
namespace HodjNPodj {
namespace Life {
#define SPLASHSPEC ".\\art\\backgrnd.BMP"
#define CURLY_X 25 // Colony dimensions
#define CURLY_Y 24
#define VILLAGES_PLACED 10 // Number of colonies pre-placed in meta-game mode
#define PLACE_COLS 10
#define PLACE_ROWS 10
#define OFFSET_X 6
#define OFFSET_Y 4
#define SCROLL_BUTTON ".\\art\\SCROLBTN.BMP" // scroll commands button bmp
#define CALENDAR_BMP ".\\ART\\CALENDAR.BMP" // the blank calendar artwork
// stat info
#define STATS_COLOR RGB(255, 255, 0) // color of visual game stats
#define STATS_FONT_SIZE 15
#define MONTH_COL_POS 17 // sprite calendar pos
#define MONTH_ROW_POS 140
#define SCORE_LEFT_COL 459 // score pos
#define SCORE_LEFT_ROW 30
#define SCORE_RIGHT_COL 574
#define SCORE_RIGHT_ROW 52
#define CURRENT_LEFT_COL 44 // current villages pos
#define CURRENT_LEFT_ROW 30
#define CURRENT_RIGHT_COL 220
#define CURRENT_RIGHT_ROW 52
#define ROUND_LEFT_COL 15 // years past pos
#define ROUND_LEFT_ROW 315
#define ROUND_RIGHT_COL 62
#define ROUND_RIGHT_ROW 331
#define ROUND_TEXT1_LEFT_COL 15
#define ROUND_TEXT1_LEFT_ROW 330
#define ROUND_TEXT1_RIGHT_COL 62
#define ROUND_TEXT1_RIGHT_ROW 352
#define ROUND_TEXT2_LEFT_COL 15
#define ROUND_TEXT2_LEFT_ROW 351
#define ROUND_TEXT2_RIGHT_COL 62
#define ROUND_TEXT2_RIGHT_ROW 373
#define VILLAGE_LEFT_COL 15 // villages left pos
#define VILLAGE_LEFT_ROW 423
#define VILLAGE_RIGHT_COL 62
#define VILLAGE_RIGHT_ROW 441
#define VILLAGE_TEXT1_LEFT_COL 15
#define VILLAGE_TEXT1_LEFT_ROW 438
#define VILLAGE_TEXT1_RIGHT_COL 62
#define VILLAGE_TEXT1_RIGHT_ROW 459
// Button Identifier codes (BIDs)
#define IDC_EVOLVE 101
#define IDC_COMMAND 102
// Button positioning constants
#define QUIT_BUTTON_WIDTH 50
#define QUIT_BUTTON_HEIGHT 20
#define QUIT_BUTTON_OFFSET_X 10
#define QUIT_BUTTON_OFFSET_Y 10
#define COMMAND_BUTTON_WIDTH 80
#define COMMAND_BUTTON_HEIGHT 18
#define COMMAND_OFFSET_X 0
#define COMMAND_OFFSET_Y 0
#define EVOLVE_BUTTON_WIDTH 94
#define EVOLVE_BUTTON_HEIGHT 20
#define EVOLVE_BUTTON_OFFSET_X 0
#define EVOLVE_BUTTON_OFFSET_Y 30
// Timer ID's
#define EVOLVE_TIMER_ID 10001
#define EVOLVE_INTERVAL 100 // decaseconds
/////////////////////////////////////////////////////////////////////////////
// CMainWindow:
// See game.cpp for the code to the member functions and the message map.
class CLife;
class CMainWindow : public CFrameWnd {
private:
CLife *m_cLife = nullptr;
LPGAMESTRUCT m_lpGameStruct = nullptr;
HWND m_hCallAppWnd = nullptr;
bool m_bGameActive = false;
CSound *m_pSound = nullptr;
CRect m_rNewGameButton;
public:
CMainWindow(HWND, LPGAMESTRUCT);
~CMainWindow();
void initStatics();
void SplashScreen();
void DisplayStats();
void RefreshStats();
void NewGame();
void GamePause();
void GameResume();
protected:
virtual bool OnCommand(WPARAM wParam, LPARAM lParam) override;
//{{AFX_MSG( CMainWindow )
afx_msg void OnPaint();
afx_msg void OnLButtonDown(unsigned int, CPoint);
afx_msg void OnLButtonDblClk(unsigned int, CPoint);
afx_msg void OnSysKeyDown(unsigned int, unsigned int, unsigned int);
afx_msg void OnSysChar(unsigned int, unsigned int, unsigned int);
afx_msg void OnKeyDown(unsigned int, unsigned int, unsigned int);
afx_msg void OnTimer(uintptr);
afx_msg void OnClose();
afx_msg void OnDestroy();
afx_msg LRESULT OnMCINotify(WPARAM, LPARAM);
afx_msg LRESULT OnMMIONotify(WPARAM, LPARAM);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// CTheApp:
// See game.cpp for the code to the InitInstance member function.
//
class CTheApp : public CWinApp {
public:
bool InitInstance();
};
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CWindowMain frame
class CWindowMain : public CFrameWnd {
DECLARE_DYNCREATE(CWindowMain)
protected:
CWindowMain(); // protected constructor used by dynamic creation
virtual ~CWindowMain();
// Generated message map functions
//{{AFX_MSG(CWindowMain)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel
#endif

View File

@@ -0,0 +1,44 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef HODJNPODJ_LIFE_GLOBALS_H
#define HODJNPODJ_LIFE_GLOBALS_H
namespace Bagel {
namespace HodjNPodj {
namespace Life {
// Main Window positioning constants
#define GAME_WIDTH 640
#define GAME_HEIGHT 480
// Scroll button size and positioning information
#define SCROLL_BUTTON_X 250
#define SCROLL_BUTTON_Y 0
#define SCROLL_BUTTON_DX 140
#define SCROLL_BUTTON_DY 23
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel
#endif

View File

@@ -0,0 +1,134 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/hodjnpodj/hnplibs/stdafx.h"
#include "bagel/hodjnpodj/life/grid.h"
namespace Bagel {
namespace HodjNPodj {
namespace Life {
colony::colony(int r, int c) {
int i, j; // indicies
rows = r;
cols = c;
m_nColony_count = 0;
/*
* Set up initial city. All cells on the
* grid are set to NO_LIFE
*/
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
grid[i][j] = NO_LIFE;
}
colony::~colony() {
}
colony &colony::operator=(const colony& c) {
int i, j;
for (i = 0; i < this->rows; i++)
for (j = 0; j < this->cols; j++)
this->grid[i][j] = c.grid[i][j];
this->m_nColony_count = c.m_nColony_count;
return *this;
}
bool colony::operator==(const colony& c) {
int i, j;
if (this->m_nColony_count != c.m_nColony_count)
return 0;
for (i = 0; i < this->rows; i++)
for (j = 0; j < this->cols; j++)
if (this->grid[i][j] != c.grid[i][j])
return 0;
return 1;
}
bool colony::operator!=(const colony& c) {
return !(*this == c);
}
void colony::evolve(const colony &clny) {
int r, c; // for local cell check
int neighbors; // # of neighbors in local area
int pos_r, pos_c; // will step across every part of board
/*
* apply evolve conditions centered at pos_r, pos_c
*/
for (pos_r = 0; pos_r < rows; pos_r++)
for (pos_c = 0; pos_c < cols; pos_c++) {
neighbors = 0;
for (r = pos_r - 1; r <= pos_r + 1; r++) {
/*
* make sure it's not out of bounds of grid
*/
if (r < 0)
continue;
if (r >= rows)
break;
for (c = pos_c - 1; c <= pos_c + 1; c++) {
if (c < 0)
continue;
if (c >= cols)
break;
/* don't count center as neighbor */
if ((r == pos_r) && (c == pos_c))
continue;
if (clny.grid[r][c] == LIFE)
neighbors++;
}
}
/* game of life conditions! */
if ((neighbors < 2 || neighbors > 3) &&
clny.grid[pos_r][pos_c] == LIFE)
flip(pos_r, pos_c);
else if (neighbors == 3 &&
clny.grid[pos_r][pos_c] == NO_LIFE)
flip(pos_r, pos_c);
}
}
void colony::flip(int r, int c) {
if (grid[r][c] == LIFE) {
grid[r][c] = NO_LIFE;
m_nColony_count--;
} else {
grid[r][c] = LIFE;
m_nColony_count++;
}
}
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel

View File

@@ -0,0 +1,78 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef HODJNPODJ_LIFE_GRID_H
#define HODJNPODJ_LIFE_GRID_H
namespace Bagel {
namespace HodjNPodj {
namespace Life {
// For colony class
#define LIFE 1 // '+'
#define NO_LIFE 0 // '-'
#define BOARD_START_ROW 58
#define BOARD_START_COL 63
//#define BOARD_SPACING 1.5
#define BOARD_SPACING_TIMES_TWO 3
#define ROWS 15
#define COLS 20
class colony {
int grid[ROWS][COLS] = {};
int rows = 0, cols = 0;
public:
//creator
colony(int r, int c);
colony(const colony &) = default;
//destroy construct
~colony();
//copy operator
colony &operator=(const colony &c);
//equality operators: assuming equal dims
bool operator==(const colony &c);
bool operator!=(const colony &c);
//accessors
int row() const {
return rows;
};
int col() const {
return cols;
};
int islife(int r, int c) const {
return grid[r][c];
};
void evolve(const colony &c);
void flip(int r, int c);
//void print();
public:
int m_nColony_count = 0;
};
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel
#endif

View File

@@ -0,0 +1,86 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/afxwin.h"
#include "bagel/hodjnpodj/life/resource.h"
#include "bagel/hodjnpodj/life/game.h"
namespace Bagel {
namespace HodjNPodj {
namespace Life {
HINSTANCE hDLLInst;
HINSTANCE hExeInst;
CMainWindow *gMainWnd = nullptr; // pointer to the poker's main window
CPalette *pTestPalette = nullptr;
HCURSOR hGameCursor;
/////////////////////////////////////////////////////////////////////////////
// Public C interface
/*****************************************************************
*
* RunLife
*
* FUNCTIONAL DESCRIPTION:
*
* This is the API function for the DLL. It is what the calling app
* calls to invoke poker
*
* FORMAL PARAMETERS:
*
* hParentWnd, lpGameInfo
*
* IMPLICIT INPUT PARAMETERS:
*
* n/a
*
* IMPLICIT OUTPUT PARAMETERS:
*
* n/a
*
* RETURN VALUE:
*
* n/a
*
****************************************************************/
HWND FAR PASCAL RunLife(HWND hParentWnd, LPGAMESTRUCT lpGameInfo) {
// create a my poker window and show it
gMainWnd = new CMainWindow(hParentWnd, lpGameInfo);
gMainWnd->ShowWindow(SW_SHOWNORMAL);
gMainWnd->SplashScreen(); // Force immediate display to minimize repaint delay
gMainWnd->DisplayStats(); // Initializes the stats
gMainWnd->UpdateWindow();
gMainWnd->SetActiveWindow();
// return the handle to this window
hDLLInst = (HINSTANCE)GetWindowWord(gMainWnd->m_hWnd, GWW_HINSTANCE);
hExeInst = (HINSTANCE)GetWindowWord(hParentWnd, GWW_HINSTANCE);
// MFC::PostMessage( pMainGameWnd->m_hWnd, WM_COMMAND, IDC_COMMAND, BN_CLICKED );
return gMainWnd->m_hWnd;
}
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel

View File

@@ -0,0 +1,37 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef HODJNPODJ_LIFE_DLLINIT_H
#define HODJNPODJ_LIFE_DLLINIT_H
#include "bagel/hodjnpodj/hnplibs/gamedll.h"
namespace Bagel {
namespace HodjNPodj {
namespace Life {
extern HWND FAR PASCAL RunLife(HWND hParentWnd, LPGAMESTRUCT lpGameInfo);
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel
#endif

View File

@@ -0,0 +1,554 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/hodjnpodj/hnplibs/stdafx.h"
#include "bagel/hodjnpodj/globals.h"
#include "bagel/hodjnpodj/hnplibs/sprite.h"
#include "bagel/hodjnpodj/hnplibs/text.h"
#include "bagel/hodjnpodj/life/life.h"
#include "bagel/hodjnpodj/life/game.h"
#include "bagel/hodjnpodj/hodjnpodj.h"
namespace Bagel {
namespace HodjNPodj {
namespace Life {
static const char *curly[5] = {
".\\art\\Colony1.BMP",
".\\art\\Colony2.BMP",
".\\art\\Colony3.BMP",
".\\art\\Colony4.BMP",
".\\art\\Colony5.BMP"
};
static const char *months[12] = {
".\\art\\jan.BMP",
".\\art\\feb.BMP",
".\\art\\mar.BMP",
".\\art\\apr.BMP",
".\\art\\may.BMP",
".\\art\\jun.BMP",
".\\art\\jul.BMP",
".\\art\\aug.BMP",
".\\art\\sep.BMP",
".\\art\\oct.BMP",
".\\art\\nov.BMP",
".\\art\\dec.BMP"
};
// Globals!
extern int nSpeed, nCountDown, nLife;
extern int nTurnCounter, nLifeCounter;
extern bool bIsInfiniteLife, bIsInfiniteTurns;
extern CMainWindow *gMainWnd;
extern CPalette *pGamePalette;
extern CSprite *pScrollSprite;
/*****************************************************************
*
* CLife
*
* FUNCTIONAL DESCRIPTION:
*
* [Description of function]
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
CLife::CLife(CDC *pDC) {
int i;
bool bCheck;
m_dScore = 0.0;
m_nYears = 0;
m_nCumLife = 0;
m_bIsEvolving = false;
m_bPrePlace = false;
pColony = new colony(ROWS, COLS);
// Because this change came bout later
for (i = 0 ; i < VILLAGES ; i++) {
pBaseSprite[i] = new CSprite();
(*pBaseSprite[i]).SharePalette(pGamePalette);
bCheck = (*pBaseSprite[i]).LoadSprite(pDC, curly[i]);
ASSERT(bCheck);
(*pBaseSprite[i]).SetMobile(true);
(*pBaseSprite[i]).SetMasked(true);
(*pBaseSprite[i]).SetOptimizeSpeed(true);
}
for (i = 0 ; i < MONTHS ; i++) {
m_cCalendar.pMonthSprite[i] = new CSprite();
m_cCalendar.bIsOn[i] = false;
m_cCalendar.pMonthSprite[i]->SharePalette(pGamePalette);
bCheck = m_cCalendar.pMonthSprite[i]->LoadSprite(pDC, months[i]);
ASSERT(bCheck);
m_cCalendar.pMonthSprite[i]->SetMobile(true);
m_cCalendar.pMonthSprite[i]->SetMasked(true);
}
//srand((unsigned) time(nullptr)); // seed the random number generator
}
/*****************************************************************
*
* ~CLife
*
* FUNCTIONAL DESCRIPTION:
*
* [Description of function]
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
CLife::~CLife() {
int i;
for (i = 0 ; i < VILLAGES ; i++)
delete pBaseSprite[i];
for (i = 0 ; i < MONTHS ; i++)
delete m_cCalendar.pMonthSprite[i];
CSprite::FlushSpriteChain();
delete pColony;
delete pYears;
delete pYearsText1;
delete pYearsText2;
delete pColonyStat;
delete pColonyStatText1;
delete pScore;
delete pColonyPlaced;
}
/*****************************************************************
*
* change_board
*
* FUNCTIONAL DESCRIPTION:
*
* [Description of function]
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
void CLife::change_board(unsigned int nFlags, CPoint point, CDC *pDC, bool bPlayingMeta) {
int i;
CSprite *pSprite;
CRect myArea;
CSize mySize;
CPoint sprite_loc; // center location of sprite on board
int row, col; // indices help find board cell
char buf[10];
bool bAssertCheck; // used to check for assertion failures
// added routines to capture if button click was inside
// legal board area
if (point.x <= BOARD_START_COL || // Is pnt outside of range?
point.x >= BOARD_START_COL + COLS * BOARD_SPACING_TIMES_TWO + COLS * CURLY_X ||
point.y <= BOARD_START_ROW ||
point.y >= BOARD_START_ROW + ROWS * BOARD_SPACING_TIMES_TWO + ROWS * CURLY_Y) {
// MessageBeep(-1);
sndPlaySound(WAV_CANTDO, SND_SYNC);
return;
}
// track down cell of board that was clicked
row = (point.y - BOARD_START_ROW) / (BOARD_SPACING_TIMES_TWO + CURLY_Y);
col = (point.x - BOARD_START_COL) / (BOARD_SPACING_TIMES_TWO + CURLY_X);
if (!(*pColony).islife(row, col)) { //life at this cell now?
// No - so do we have colonies left to place?
if (!nLifeCounter && !bIsInfiniteLife) {
// No - so indicate this to user
// MessageBeep(-1);
sndPlaySound(WAV_CANTDO, SND_SYNC);
return;
}
} else if (
bPlayingMeta == true || // can't remove life in meta OR
m_bIsEvolving == true // if evolve was clicked.
) {
// MessageBeep(-1);
sndPlaySound(WAV_CANTDO, SND_SYNC);
return;
} // end if
// flip it on/off
(*pColony).flip(row, col);
// Update colony placed count on the board
gMainWnd->RefreshStats();
//set it up to be centered
sprite_loc.y = BOARD_START_ROW + (CURLY_Y + BOARD_SPACING_TIMES_TWO) * row;
sprite_loc.x = BOARD_START_COL + (CURLY_X + BOARD_SPACING_TIMES_TWO) * col;
pSprite = CSprite::GetSpriteChain();
// User want to turn life off?
if ((*pColony).islife(row, col)) {
if (bIsInfiniteLife != true) {
//decrement colony counter if not infinite
nLifeCounter--;
Common::sprintf_s(buf, "%d", nLifeCounter);
bAssertCheck = pColonyStat->DisplayString(pDC, buf, STATS_FONT_SIZE, FW_BOLD, STATS_COLOR);
ASSERT(bAssertCheck); // paint the text
}
i = brand() % VILLAGES;
pSprite = (*pBaseSprite[i]).DuplicateSprite(pDC);
mySize = (*pSprite).GetSize();
(*pSprite).LinkSprite();
// paint the sprite in its new location
(*pSprite).PaintSprite(pDC,
sprite_loc.x, // finding center of cell
sprite_loc.y);
sndPlaySound(WAV_NEWVILLAGE, SND_ASYNC);
} else {
CRect testRect; // sprite area to be tested
if (bIsInfiniteLife != true) {
//Add life back to colony counter if finite
nLifeCounter++;
Common::sprintf_s(buf, "%d", nLifeCounter);
bAssertCheck = pColonyStat->DisplayString(pDC, buf, STATS_FONT_SIZE, FW_BOLD, STATS_COLOR);
ASSERT(bAssertCheck); // paint the text
}
pSprite = CSprite::Touched(sprite_loc);
if (pSprite != nullptr) { // See if the point is in the sprite's rectangle
(*pSprite).RefreshBackground(pDC); // ... simply repaint background
(*pSprite).UnlinkSprite(); // ... and if so, unlink it from chain
delete pSprite;
}
}
}
/*****************************************************************
*
* evolution
*
* FUNCTIONAL DESCRIPTION:
*
* [Description of function]
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
void CLife::evolution(CDC *pDC) {
CSprite *pSprite;
CSize mySize;
CRect myArea;
CPoint sprite_loc; // center location of sprite on board
int i; // used to gen random village
int row, col; // indexs help find board cell
colony pColonyCopy((*pColony).row(), (*pColony).col());
// make copy of original pColony for later ref
pColonyCopy = (*pColony);
// Update stats
if (m_nYears == 0) //just starting evolution?
m_nCumLife = (*pColony).m_nColony_count;
else
m_nCumLife += (*pColony).m_nColony_count;
m_nYears++;
m_dScore = ((double) m_nCumLife) / ((double) m_nYears);
//Evolve internal board
(*pColony).evolve(*pColony);
// update score
if (m_nCumLife > LARGE && bIsInfiniteTurns) { // This prevents int overflow
// reset it
m_nCumLife = (int) m_dScore;
m_nYears = 1;
}
// update stats visually
gMainWnd->RefreshStats();
//Update visual board
if (pColonyCopy != (*pColony))
for (row = 0; row < (*pColony).row(); row++)
for (col = 0; col < (*pColony).col(); col++) {
pSprite = CSprite::GetSpriteChain();
// Any change for this particular cell?
if (pColonyCopy.islife(row, col) == (*pColony).islife(row, col))
continue; // no change -- loop
if ((*pColony).islife(row, col)) { //Need to put a sprite there?
// Yes, paint new sprite in cell
i = brand() % VILLAGES;
pSprite = (*pBaseSprite[i]).DuplicateSprite(pDC);
mySize = (*pSprite).GetSize();
//set it up to be centered
sprite_loc.y = BOARD_START_ROW + (CURLY_Y + BOARD_SPACING_TIMES_TWO) * row;
sprite_loc.x = BOARD_START_COL + (CURLY_X + BOARD_SPACING_TIMES_TWO) * col;
(*pSprite).LinkSprite();
// paint the sprite in its new location
(*pSprite).PaintSprite(pDC,
sprite_loc.x, // finding center of cell
sprite_loc.y);
} else {
CRect testRect; // sprite area to be tested
sprite_loc.y = BOARD_START_ROW + (CURLY_Y + BOARD_SPACING_TIMES_TWO) * row;
sprite_loc.x = BOARD_START_COL + (CURLY_X + BOARD_SPACING_TIMES_TWO) * col;
pSprite = CSprite::Touched(sprite_loc);
if (pSprite != nullptr) { // See if the point is in the sprite's rectangle
(*pSprite).RefreshBackground(pDC); // ... simply repaint background
(*pSprite).UnlinkSprite(); // ... and if so, unlink it from chain
delete pSprite;
}
}
}
}
/*****************************************************************
*
* NewGame
*
* FUNCTIONAL DESCRIPTION:
*
* [Description of function]
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
void CLife::NewGame(CDC *pDC) {
colony pColonyCopy((*pColony).row(), (*pColony).col());
// Reset internal grid
(*pColony) = pColonyCopy;
// Reset Stats
m_nYears = 0;
m_dScore = 0.0;
m_nCumLife = 0;
nCountDown = nSpeed * MONTHS;
nLifeCounter = nLife;
// Refresh Calendar
ResetMonths(pDC);
DisplayMonth(nCountDown, pDC);
// Update visual stats
gMainWnd->RefreshStats();
//Reset visual board
CSprite::EraseSprites(pDC);
CSprite::FlushSpriteChain();
}
/*****************************************************************
*
* DisplayMonth
*
* FUNCTIONAL DESCRIPTION:
*
* [Description of function]
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
void CLife::DisplayMonth(int nMonth, CDC *pDC) {
int i, j;
/************************************************************************************
* In order to get the visual calendar to change exactly 12 times, regardless *
* of the how nSpeed was set, I could achieve this in at least two different ways. *
* First way was to modify how the WM_TIMER messages are passed around, but this *
* would introduce many more changes that I wanted to make. Second way was *
* to watch the nMonth (equivalent to the nCountDown global) and change the *
* calendar only when it hit specific values defined by nSpeed (speed of clock). *
* I am doing this second way here. *
************************************************************************************/
if (nSpeed != FASTEST) { // don't want divide by 0 errors if FASTEST = 0
/*
* nMonths counts down, i.e. 24, 23, 22, 21....
* j is a number between 0 and 11 counting as follows:
* 0, 1, 2, 3, 4....
* j is indexing the current month
*/
j = (MONTHS - ((int) nMonth / nSpeed) - 1);
if (j < 0)
j = 0;
if (j == 0)
i = MONTHS - 1; // i indexes previous month
else
i = j - 1;
if (m_cCalendar.bIsOn[i] == true) {
m_cCalendar.pMonthSprite[i]->EraseSprite(pDC);
m_cCalendar.bIsOn[i] = false;
}
} else
j = 0;
//b
m_cCalendar.pMonthSprite[j]->PaintSprite(pDC, MONTH_COL_POS + 1, MONTH_ROW_POS + 1);
m_cCalendar.bIsOn[j] = true;
}
/*****************************************************************
*
* ResetMonths
*
* FUNCTIONAL DESCRIPTION:
*
* [Description of function]
*
* FORMAL PARAMETERS:
*
* [Show arguments]
*
* IMPLICIT INPUT PARAMETERS:
*
* [External data read]
*
* IMPLICIT OUTPUT PARAMETERS:
*
* [External data modified]
*
* RETURN VALUE:
*
* [Discuss return value]
*
****************************************************************/
void CLife::ResetMonths(CDC *pDC) {
int i;
// reset all calendars
for (i = 0 ; i < MONTHS ; i++) {
if (m_cCalendar.bIsOn[i] == true) {
m_cCalendar.pMonthSprite[i]->EraseSprite(pDC);
m_cCalendar.bIsOn[i] = false;
break;
}
}
// repaint current calendar
//DisplayMonth(nMonth, pDC);
}
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel

View File

@@ -0,0 +1,88 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef HODJNPODJ_LIFE_LIFE_H
#define HODJNPODJ_LIFE_LIFE_H
#include "bagel/hodjnpodj/hnplibs/stdafx.h"
#include "bagel/hodjnpodj/hnplibs/sprite.h"
#include "bagel/hodjnpodj/hnplibs/text.h"
#include "bagel/hodjnpodj/life/grid.h"
namespace Bagel {
namespace HodjNPodj {
namespace Life {
#define VILLAGES 5 // Constants
#define MONTHS 12
#define FASTEST 0 // Changing this doesn't effectly change it
// everywhere. speed of evolution.
#define LARGE 32468 //= 2^15 - 300
// when to reset counter increments
#define WAV_EVOLVE ".\\sound\\sound178.wav" // Wave sounds
#define WAV_GAMEOVER ".\\sound\\sound283.wav"
#define WAV_NEWVILLAGE ".\\sound\\colony.wav"
#define WAV_DEATH ".\\sound\\sound259.wav"
#define WAV_CANTDO ".\\sound\\sorry.wav"
class CCalendar {
public:
CSprite *pMonthSprite[MONTHS] = {};
bool bIsOn[MONTHS] = {};
};
class CLife {
public:
// Constructor
CLife(CDC *pDC);
// Destructor
~CLife();
void change_board(unsigned int, CPoint, CDC*, bool);
void evolution(CDC *pDC);
void NewGame(CDC *pDC);
void DisplayMonth(int nMonth, CDC *pDC);
void ResetMonths(CDC *pDC);
int ColonyPlaced() {
return (*pColony).m_nColony_count;
}
public:
colony *pColony = nullptr;
double m_dScore = 0.0;
int m_nCumLife = 0;
int m_nYears = 0;
bool m_bIsEvolving = false;
bool m_bPrePlace = false;
CText *pYears = nullptr, *pYearsText1 = nullptr, *pYearsText2 = nullptr,
*pColonyStat = nullptr, *pColonyStatText1 = nullptr,
*pScore = nullptr, *pColonyPlaced = nullptr, *pTime = nullptr;
CSprite *pBaseSprite[VILLAGES] = {};
CCalendar m_cCalendar;
};
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel
#endif

View File

@@ -0,0 +1,66 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef HODJNPODJ_LIFE_RESOURCE_H
#define HODJNPODJ_LIFE_RESOURCE_H
namespace Bagel {
namespace HodjNPodj {
namespace Life {
#define LIFE_ICON 2
//#define IDD_COMMANDS 5
//#define IDD_RULES 111
//#define IDD_STATS 114
//#define IDD_NEWSETTING 118
//#define IDI_LIFE 123
//#define IDD_RULES_DIALOG 900
//#define IDC_RULES_OKAY 900
//#define IDC_RULES_ARROWDN 910
//#define IDC_RULES_ARROWUP 911
//#define IDC_RULES_INVALID 912
//#define IDC_RULES 1001
//#define IDC_NEWGAME 1004
//#define IDC_OPTIONS 1005
//#define IDC_QUIT 1007
#define IDD_USERCFG 110 // user config dialog id
#define IDC_STARTVILLAGES 1010 // scroll bar
#define IDC_EVOLVESPEED 1011 // scroll bar
#define IDC_SCORE 1013
#define IDC_YEAR 1014
#define IDC_COL_LEFT 1015
#define IDE_SCORE 1016
#define IDE_YEAR 1017
#define IDE_TIMER 1018
#define IDE_COL_LEFT 1022
#define IDC_EVOLVEROUNDS 1019
#define IDC_RETURN_LIFE 1020
#define IDC_ROUNDS 1025
#define IDC_PREPLACE 1027
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel
#endif

View File

@@ -0,0 +1,513 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "bagel/hodjnpodj/hnplibs/stdafx.h"
#include "bagel/hodjnpodj/hnplibs/text.h"
#include "bagel/hodjnpodj/hnplibs/menures.h"
#include "bagel/hodjnpodj/life/usercfg.h"
#include "bagel/hodjnpodj/life/life.h"
namespace Bagel {
namespace HodjNPodj {
namespace Life {
extern int nSpeed, // Speed between evolutions
nCountDown, // Counts before an evolution
nLife, // Num of lives given at game start
nPlace;
extern int nTurnCounter, // Counts num of years before end of game
nLifeCounter; // Counts num of lives left to place
extern bool bPrePlaceColonies, // Whether they want to pre-place some
bIsInfiniteLife, // Tells if num of lives is set to infi
bIsInfiniteTurns; // Tells if num of turns is set to infi
extern CPalette *pGamePalette; // Used everywhere for ref
CUserCfgDlg::CUserCfgDlg(CWnd *pParent, CPalette *pPalette, unsigned int nID)
: CBmpDialog(pParent, pPalette, nID, ".\\ART\\SSCROLL.BMP") {
m_DisplayRounds = "";
m_DisplaySpeed = "";
m_DisplayVillages = "";
}
void CUserCfgDlg::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STARTVILLAGES, m_ScrollVillages);
DDX_Control(pDX, IDC_ROUNDS, m_ScrollRounds);
DDX_Control(pDX, IDC_EVOLVESPEED, m_ScrollSpeed);
}
bool CUserCfgDlg::OnInitDialog() {
int i;
CRect statsRect; // game stats displays
int nStat_col_offset; // game stats placement
int nStat_row_offset;
int nStatWidth, nStatHeight;
bool bAssertCheck;
CDC *pDC;
CBmpDialog::OnInitDialog();
mSpeedTable[0] = "Time Flies";
mSpeedTable[1] = "1.2 Seconds";
mSpeedTable[2] = "2.4 Seconds";
mSpeedTable[3] = "3.6 Seconds";
mSpeedTable[4] = "4.8 Seconds";
mSpeedTable[5] = "6.0 Seconds";
mSpeedTable[6] = "7.2 Seconds";
mSpeedTable[7] = "8.4 Seconds";
mSpeedTable[8] = "Time Crawls";
m_nLife[0] = 5;
m_nLife[1] = 10;
m_nLife[2] = 15;
m_nLife[3] = 20;
m_nLife[4] = 25;
m_nLife[5] = 30;
m_nLife[6] = 40;
m_nLife[7] = 50;
m_nLife[8] = 60;
m_nLife[9] = 80;
m_nLife[10] = 100;
m_nLife[11] = 125;
m_nLife[12] = 150;
m_nLife[13] = 175;
m_nLife[14] = 200;
m_nLife[15] = 201;
for (i = 0; i < TURNS_SETTINGS; i++)
m_nTurns[i] = m_nLife[i];
// Convert preferences
nSpeedTemp = nSpeed;
nLifeTemp = -1;
for (i = 0; i < LIFE_SETTINGS; i++)
if (m_nLife[i] == nLife) {
nLifeTemp = i;
break;
}
if (nLifeTemp == -1)
nLifeTemp = 7; // MAgIC NUmbER!!! (bec m_nLife[7] = VILLAGES_DEF)
nTurnCounterTemp = -1;
for (i = 0; i < TURNS_SETTINGS; i++)
if (m_nTurns[i] == nTurnCounter) {
nTurnCounterTemp = i;
break;
}
if (nTurnCounterTemp == -1)
nTurnCounterTemp = 10; // MAgIC NUmbER!!! (bec m_nLife[10] = ROUNDS_DEF)
pDC = GetDC();
// setup the Starting Villages stat display box
nStat_col_offset = 25; //20
nStat_row_offset = 25;
nStatWidth = 120;
nStatHeight = 15;
statsRect.SetRect(
nStat_col_offset,
nStat_row_offset,
nStat_col_offset + nStatWidth,
nStat_row_offset + nStatHeight
);
if ((m_pVillages = new CText) != nullptr) {
bAssertCheck = (*m_pVillages).SetupText(pDC, pGamePalette, &statsRect, JUSTIFY_LEFT);
ASSERT(bAssertCheck); // initialize the text objext
} // end if
// setup the starting villages scroll bar
m_ScrollVillages.SetScrollRange(MIN_LIFE, MAX_LIFE, false);
m_ScrollVillages.SetScrollPos(nLifeTemp, true);
// set up the Speed stat display box
nStat_row_offset += 35; //48;
statsRect.SetRect(
nStat_col_offset,
nStat_row_offset,
nStat_col_offset + nStatWidth,
nStat_row_offset + nStatHeight
);
if ((m_pSpeed = new CText) != nullptr) {
bAssertCheck = (*m_pSpeed).SetupText(pDC, pGamePalette, &statsRect, JUSTIFY_LEFT);
ASSERT(bAssertCheck); // initialize the text objext
} // end if
// setup the speed scroll bar
m_ScrollSpeed.SetScrollRange(MIN_SPEED, MAX_SPEED, false);
m_ScrollSpeed.SetScrollPos(nSpeedTemp, true);
// set up the rounds stat display box
nStat_row_offset += 38; //48;
statsRect.SetRect(
nStat_col_offset,
nStat_row_offset,
nStat_col_offset + nStatWidth,
nStat_row_offset + nStatHeight
);
if ((m_pRounds = new CText) != nullptr) {
bAssertCheck = (*m_pRounds).SetupText(pDC, pGamePalette, &statsRect, JUSTIFY_LEFT);
ASSERT(bAssertCheck); // initialize the text objext
} // end if
ReleaseDC(pDC);
// setup the speed scroll bar
m_ScrollRounds.SetScrollRange(MIN_TURNS, MAX_TURNS, false);
m_ScrollRounds.SetScrollPos(nTurnCounterTemp, true);
/************************
* Set up color buttons. *
************************/
if ((m_pPrePlaceButton = new CCheckButton) != nullptr) { // build a color QUIT button to let us exit
(*m_pPrePlaceButton).SetPalette(pGamePalette); // set the palette to use
(*m_pPrePlaceButton).SetControl(IDC_PREPLACE, this); // tie to the dialog control
}
((CWnd *)this)->CheckDlgButton(IDC_PREPLACE, bPrePlaceColonies); // Set the frame option box
if ((m_pOKButton = new CColorButton) != nullptr) { // build a color OK button
(*m_pOKButton).SetPalette(pGamePalette); // set the palette to use
(*m_pOKButton).SetControl(IDOK, this); // tie to the dialog control
} // end if
if ((m_pCancelButton = new CColorButton) != nullptr) { // build a color CANCEL button
(*m_pCancelButton).SetPalette(pGamePalette);
(*m_pCancelButton).SetControl(IDCANCEL, this);
} // end if
return true; // return true unless you set the focus to a control
}
void CUserCfgDlg::OnHScroll(unsigned int nSBCode, unsigned int nPos, CScrollBar* pScrollBar) {
// TODO: Add your message handler code here and/or call default
CDC *pDC;
bool bAssertCheck;
char msg[64];
pDC = GetDC();
if (pScrollBar->GetDlgCtrlID() == IDC_EVOLVESPEED) {
int nOldSpeed = nSpeedTemp;
switch (nSBCode) {
case SB_LINERIGHT:
nSpeedTemp++;
break;
case SB_PAGERIGHT:
nSpeedTemp += 2; //SPEED/5;
break;
case SB_RIGHT:
nSpeedTemp = MAX_SPEED;
break;
case SB_LINELEFT:
nSpeedTemp--;
break;
case SB_PAGELEFT:
nSpeedTemp -= 2; //SPEED/5;
break;
case SB_LEFT:
nSpeedTemp = MIN_SPEED;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
nSpeedTemp = (int) nPos;
break;
}
if (nSpeedTemp < MIN_SPEED)
nSpeedTemp = MIN_SPEED;
if (nSpeedTemp > MAX_SPEED)
nSpeedTemp = MAX_SPEED;
if (nSpeedTemp != nOldSpeed) { //To prevent "flicker"
Common::sprintf_s(msg, "Speed: %s", mSpeedTable[nSpeedTemp].c_str()); // only redraw if
// m_nSpeedTemp has changed
bAssertCheck = (*m_pSpeed).DisplayString(pDC, msg, FONT_SIZE, FW_BOLD, OPTIONS_COLOR);
ASSERT(bAssertCheck);
pScrollBar->SetScrollPos(nSpeedTemp, true);
}
} else if (pScrollBar->GetDlgCtrlID() == IDC_STARTVILLAGES) {
int nOldCounter = nLifeTemp;
switch (nSBCode) {
case SB_LINERIGHT:
nLifeTemp++;
break;
case SB_PAGERIGHT:
nLifeTemp += LIFE_SETTINGS / 5; // want 5 pagerights end to end
break;
case SB_RIGHT:
nLifeTemp = MAX_LIFE;
break;
case SB_LINELEFT:
nLifeTemp--;
break;
case SB_PAGELEFT:
nLifeTemp -= LIFE_SETTINGS / 5; // want 5 pagerights end to end
break;
case SB_LEFT:
nLifeTemp = MIN_LIFE;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
nLifeTemp = (int) nPos;
break;
}
if (nLifeTemp < MIN_LIFE)
nLifeTemp = MIN_LIFE;
if (nLifeTemp > MAX_LIFE)
nLifeTemp = MAX_LIFE;
if (nLifeTemp != nOldCounter) { //To prevent "flicker"
// only redraw if counter has changed
if (nLifeTemp == MAX_LIFE)
Common::sprintf_s(msg, "Villages: Unlimited");
else
Common::sprintf_s(msg, "Villages: %d", m_nLife[nLifeTemp]);
bAssertCheck = (*m_pVillages).DisplayString(pDC, msg, FONT_SIZE, FW_BOLD, OPTIONS_COLOR);
ASSERT(bAssertCheck); // paint the text
pScrollBar->SetScrollPos(nLifeTemp, true);
}
} else if (pScrollBar->GetDlgCtrlID() == IDC_ROUNDS) {
int nOldCounter = nTurnCounterTemp;
switch (nSBCode) {
case SB_LINERIGHT:
nTurnCounterTemp++;
break;
case SB_PAGERIGHT:
nTurnCounterTemp += (MAX_TURNS - MIN_TURNS + 1) / 5; // want 5 pagerights end to end
break;
case SB_RIGHT:
nTurnCounterTemp = MAX_TURNS;
break;
case SB_LINELEFT:
nTurnCounterTemp--;
break;
case SB_PAGELEFT:
nTurnCounterTemp -= (MAX_TURNS - MIN_TURNS + 1) / 5; // want 5 pagerights end to end
break;
case SB_LEFT:
nTurnCounterTemp = MIN_TURNS;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
nTurnCounterTemp = (int) nPos;
break;
}
if (nTurnCounterTemp < MIN_TURNS)
nTurnCounterTemp = MIN_TURNS;
if (nTurnCounterTemp > MAX_TURNS)
nTurnCounterTemp = MAX_TURNS;
// only redraw if changed to prevent "flicker"
if (nTurnCounterTemp != nOldCounter) {
if (nTurnCounterTemp == MAX_TURNS)
Common::sprintf_s(msg, "Years: Unlimited");
else
Common::sprintf_s(msg, "Years: %d", m_nTurns[nTurnCounterTemp]);
bAssertCheck = (*m_pRounds).DisplayString(pDC, msg, FONT_SIZE, FW_BOLD, OPTIONS_COLOR);
ASSERT(bAssertCheck); // paint the text
pScrollBar->SetScrollPos(nTurnCounterTemp, true);
}
}
ReleaseDC(pDC);
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CUserCfgDlg::OnPrePlace() {
bPrePlaceColonies = !bPrePlaceColonies;
((CWnd *)this)->CheckDlgButton(IDC_PREPLACE, bPrePlaceColonies);
}
void CUserCfgDlg::OnOK() {
ClearDialogImage();
if (m_nLife[nLifeTemp] == nLife && // Starting Lives or Rounds option changed?
m_nTurns[nTurnCounterTemp] == nTurnCounter) {
nSpeed = nSpeedTemp; // No - so just update speed counter
nCountDown = nSpeed * MONTHS;
EndDialog(false); // and don't start new game
return;
} // end if
if (nLifeTemp == MAX_LIFE) { // infinite life?
bIsInfiniteLife = true; // yes
} else {
bIsInfiniteLife = false;
nLifeCounter = m_nLife[nLifeTemp];
} // end if
nLife = m_nLife[nLifeTemp];
nSpeed = nSpeedTemp; // save speed counter
nCountDown = nSpeed * MONTHS;
if (nTurnCounterTemp == MAX_TURNS) { // fastest turn counter?
bIsInfiniteTurns = true;
} else {
bIsInfiniteTurns = false;
} // end if
nTurnCounter = m_nTurns[nTurnCounterTemp];
/******************************************
* Save new game settings to the INI file. *
******************************************/
WritePrivateProfileString(INI_SECTION, "Speed",
Common::String::format("%d", nSpeedTemp).c_str(),
INI_FNAME);
WritePrivateProfileString(INI_SECTION, "Rounds",
Common::String::format("%d", m_nTurns[nTurnCounterTemp]).c_str(),
INI_FNAME);
WritePrivateProfileString(INI_SECTION, "Villages",
Common::String::format("%d", m_nLife[nLifeTemp]).c_str(),
INI_FNAME);
if (bPrePlaceColonies)
nPlace = 1;
else
nPlace = 0;
WritePrivateProfileString(INI_SECTION, "PrePlace",
Common::String::format("%d", nPlace).c_str(),
INI_FNAME);
EndDialog(IDOK);
}
void CUserCfgDlg::OnCancel() {
ClearDialogImage();
EndDialog(false);
}
void CUserCfgDlg::OnPaint() {
// TODO: Add your message handler code here
CDC *pDC;
bool bAssertCheck;
char msg[64];
CBmpDialog::OnPaint();
pDC = GetDC();
// Display Starting Villages stats
if (bIsInfiniteLife == true)
Common::sprintf_s(msg, "Villages: Unlimited");
else
Common::sprintf_s(msg, "Villages: %d", m_nLife[nLifeTemp]);
bAssertCheck = (*m_pVillages).DisplayString(pDC, msg, FONT_SIZE, FW_BOLD, OPTIONS_COLOR);
ASSERT(bAssertCheck);
// Display Speed stats
Common::sprintf_s(msg, "Speed: %s", mSpeedTable[nSpeedTemp].c_str());
bAssertCheck = (*m_pSpeed).DisplayString(pDC, msg, FONT_SIZE, FW_BOLD, OPTIONS_COLOR);
ASSERT(bAssertCheck); // paint the text
// set up the rounds stat display box
if (bIsInfiniteTurns == true)
Common::sprintf_s(msg, "Years: Unlimited");
else
Common::sprintf_s(msg, "Years: %d", m_nTurns[nTurnCounterTemp]);
bAssertCheck = (*m_pRounds).DisplayString(pDC, msg, FONT_SIZE, FW_BOLD, OPTIONS_COLOR);
ASSERT(bAssertCheck); // paint the text
ReleaseDC(pDC);
}
void CUserCfgDlg::ClearDialogImage() {
if (m_pOKButton != nullptr) { // release button
delete m_pOKButton;
m_pOKButton = nullptr;
}
if (m_pCancelButton != nullptr) {
delete m_pCancelButton;
m_pCancelButton = nullptr;
}
if (m_pPrePlaceButton != nullptr) { // release the button
delete m_pPrePlaceButton;
m_pPrePlaceButton = nullptr;
}
ValidateRect(nullptr);
}
void CUserCfgDlg::OnClose() {
CBmpDialog::OnClose();
}
void CUserCfgDlg::OnDestroy() {
CDC *pDC = GetDC();
if (m_pVillages != nullptr) {
delete m_pVillages;
m_pVillages = nullptr;
}
if (m_pSpeed != nullptr) {
delete m_pSpeed;
m_pSpeed = nullptr;
}
if (m_pRounds != nullptr) {
delete m_pRounds;
m_pRounds = nullptr;
}
ReleaseDC(pDC);
CBmpDialog::OnDestroy();
}
BEGIN_MESSAGE_MAP(CUserCfgDlg, CBmpDialog)
ON_WM_PAINT()
ON_WM_HSCROLL()
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_PREPLACE, CUserCfgDlg::OnPrePlace)
ON_WM_DESTROY()
END_MESSAGE_MAP()
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel

View File

@@ -0,0 +1,110 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef HODJNPODJ_LIFE_USERCFG_H
#define HODJNPODJ_LIFE_USERCFG_H
#include "bagel/hodjnpodj/hnplibs/text.h"
#include "bagel/hodjnpodj/hnplibs/button.h"
#include "bagel/hodjnpodj/hnplibs/cbofdlg.h"
#include "bagel/hodjnpodj/life/resource.h"
namespace Bagel {
namespace HodjNPodj {
namespace Life {
#define LIFE_SETTINGS 16
#define MIN_LIFE 0
#define MAX_LIFE 15
#define LIFE_HI_BOUND 201
#define SPEED 9
#define MIN_SPEED 0
#define MAX_SPEED 8
#define TURNS_SETTINGS 16
#define MIN_TURNS 0
#define MAX_TURNS 15
#define TURN_HI_BOUND 201
#define OPTIONS_COLOR RGB(0, 0, 0) // Color of the stats info CText
#define FONT_SIZE 14
#define INI_FNAME "HODJPODJ.INI" // INI saved Life settings
#define INI_SECTION "Life"
#define ROUNDS_DEF 100 // default skill levels
#define VILLAGES_DEF 50
#define SPEED_DEF 1
#define PLACE_DEF 0
#define VILLAGES_LOW 30 // meta game skill levels
#define VILLAGES_MED 25
#define VILLAGES_HI 20
#define ROUNDS_META 20
class CUserCfgDlg : public CBmpDialog {
private:
CString mSpeedTable[SPEED];
int m_nLife[LIFE_SETTINGS] = {};
int m_nTurns[TURNS_SETTINGS] = {};
CText *m_pVillages = nullptr, *m_pSpeed = nullptr,
*m_pRounds = nullptr;
public:
int nSpeedTemp = 0, // remembers cur settings
nTurnCounterTemp = 0,
nLifeTemp = 0;
bool bPrePlaceTemp = false;
CUserCfgDlg(CWnd *pParent = nullptr, CPalette *pPalette = nullptr, unsigned int = IDD_USERCFG);
enum { IDD = IDD_USERCFG };
CScrollBar m_ScrollVillages;
CScrollBar m_ScrollRounds;
CScrollBar m_ScrollSpeed;
CString m_DisplayRounds;
CString m_DisplaySpeed;
CString m_DisplayVillages;
CCheckButton *m_pPrePlaceButton = nullptr; // PrePlace check box
CColorButton *m_pOKButton = nullptr; // OKAY button on scroll
CColorButton *m_pCancelButton = nullptr; // Cancel button on scroll
protected:
void ClearDialogImage();
virtual void DoDataExchange(CDataExchange*) override; // DDX/DDV support
virtual bool OnInitDialog() override;
virtual void OnOK() override;
virtual void OnCancel() override;
afx_msg void OnPrePlace();
afx_msg void OnPaint();
afx_msg bool OnEraseBkgnd(CDC *pDC);
afx_msg void OnHScroll(unsigned int nSBCode, unsigned int nPos, CScrollBar* pScrollBar);
afx_msg void OnClose();
afx_msg void OnDestroy();
DECLARE_MESSAGE_MAP()
};
} // namespace Life
} // namespace HodjNPodj
} // namespace Bagel
#endif