Proper event loop, menus, and more

* Added a proper event loop
* Added minimal menu bars
* Added about menu
* GameWindow initializes a GameEngine (even if you can't play it yet)
* Updated variable naming conventions
This commit is contained in:
Jon Thysell 2021-10-15 17:29:07 -07:00
parent 6184d31e6a
commit 2ce4236ea7
11 changed files with 251 additions and 65 deletions

View File

@ -12,53 +12,55 @@ const uint8_t MinHalfStars = 1;
const uint16_t PerfectScore = 300; // LevelCount * MaxHalfStars
void GameEngine_LoadLevel(GameEngine *engine, const int8_t level, const bool setB)
void GameEngine_ToggleSingleLight(GameEngine *pGameEngine, const int8_t x, const int8_t y);
void GameEngine_LoadLevel(GameEngine *pGameEngine, const int8_t level, const bool setB)
{
engine->Level = Levels_BoundLevel(level);
engine->Lights = Levels_GetLightsForLevel(engine->Level, setB);
engine->Par = Levels_GetParForLevel(engine->Level);
engine->Moves = 0;
pGameEngine->Level = Levels_BoundLevel(level);
pGameEngine->Lights = Levels_GetLightsForLevel(pGameEngine->Level, setB);
pGameEngine->Par = Levels_GetParForLevel(pGameEngine->Level);
pGameEngine->Moves = 0;
}
bool GameEngine_GetLight(const GameEngine *engine, const int8_t x, const int8_t y)
bool GameEngine_GetLight(const GameEngine *pGameEngine, const int8_t x, const int8_t y)
{
if (x >= 0 && x < PuzzleSize && y >= 0 && y < PuzzleSize)
{
return bitRead(engine->Lights, y * PuzzleSize + x);
return bitRead(pGameEngine->Lights, y * PuzzleSize + x);
}
return false;
}
bool GameEngine_IsCompleted(const GameEngine *engine)
bool GameEngine_IsCompleted(const GameEngine *pGameEngine)
{
return engine->Lights == 0;
return pGameEngine->Lights == 0;
}
uint8_t GameEngine_GetHalfStars(const GameEngine *engine)
uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine)
{
uint8_t halfStarsLost = engine->Moves <= engine->Par ? 0 : max(0, (1 + engine->Moves - engine->Par) / 2);
uint8_t halfStarsLost = pGameEngine->Moves <= pGameEngine->Par ? 0 : max(0, (1 + pGameEngine->Moves - pGameEngine->Par) / 2);
return max(MinHalfStars, MaxHalfStars - halfStarsLost);
}
void GameEngine_ToggleSingleLight(GameEngine *engine, const int8_t x, const int8_t y)
{
if (x >= 0 && x < PuzzleSize && y >= 0 && y < PuzzleSize)
{
bitToggle(engine->Lights, y * PuzzleSize + x);
}
}
void GameEngine_ToggleLights(GameEngine *engine, const int8_t x, const int8_t y)
void GameEngine_ToggleLights(GameEngine *pGameEngine, const int8_t x, const int8_t y)
{
int8_t targetX = max(0, min(x, PuzzleSize - 1));
int8_t targetY = max(0, min(y, PuzzleSize - 1));
GameEngine_ToggleSingleLight(engine, targetX, targetY);
GameEngine_ToggleSingleLight(engine, targetX + 1, targetY);
GameEngine_ToggleSingleLight(engine, targetX, targetY + 1);
GameEngine_ToggleSingleLight(engine, targetX - 1, targetY);
GameEngine_ToggleSingleLight(engine, targetX, targetY - 1);
GameEngine_ToggleSingleLight(pGameEngine, targetX, targetY);
GameEngine_ToggleSingleLight(pGameEngine, targetX + 1, targetY);
GameEngine_ToggleSingleLight(pGameEngine, targetX, targetY + 1);
GameEngine_ToggleSingleLight(pGameEngine, targetX - 1, targetY);
GameEngine_ToggleSingleLight(pGameEngine, targetX, targetY - 1);
engine->Moves++;
pGameEngine->Moves++;
}
void GameEngine_ToggleSingleLight(GameEngine *pGameEngine, const int8_t x, const int8_t y)
{
if (x >= 0 && x < PuzzleSize && y >= 0 && y < PuzzleSize)
{
bitToggle(pGameEngine->Lights, y * PuzzleSize + x);
}
}

View File

@ -16,20 +16,20 @@ extern const uint16_t PerfectScore;
typedef struct GameEngine
{
int8_t Level;
int8_t Level;
uint32_t Lights;
uint16_t Par;
uint16_t Moves;
} GameEngine;
void GameEngine_LoadLevel(GameEngine *engine, const int8_t level, const bool setB);
void GameEngine_LoadLevel(GameEngine *pGameEngine, const int8_t level, const bool setB);
bool GameEngine_GetLight(const GameEngine *engine, const int8_t x, const int8_t y);
bool GameEngine_GetLight(const GameEngine *pGameEngine, const int8_t x, const int8_t y);
bool GameEngine_IsCompleted(const GameEngine *engine);
bool GameEngine_IsCompleted(const GameEngine *pGameEngine);
uint8_t GameEngine_GetHalfStars(const GameEngine *engine);
uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine);
void GameEngine_ToggleLights(GameEngine *engine, const int8_t x, const int8_t y);
void GameEngine_ToggleLights(GameEngine *pGameEngine, const int8_t x, const int8_t y);
#endif

View File

@ -3,27 +3,34 @@
#include "GameWindow.h"
void GameWindow_Init(GameWindow *gameWindow)
void GameWindow_Init(GameWindow *pGameWindow)
{
if (gameWindow->Window != nil)
if (pGameWindow->Window != nil)
{
ShowError("\pGameWindow already initialized!", false);
}
gameWindow->Window = GetNewWindow(kBaseResID, nil, kMoveToFront);
pGameWindow->Window = GetNewWindow(BaseResID, nil, MoveToFront);
if (gameWindow->Window == nil)
if (pGameWindow->Window == nil)
{
ShowError("\pGameWindow resource WIND kBaseResID missing!", true);
ShowError("\pGameWindow resource WIND BaseResID missing!", true);
}
CenterWindow(gameWindow->Window);
GameEngine_LoadLevel(&(pGameWindow->Engine), 0, false);
ShowWindow(gameWindow->Window);
SetPort(gameWindow->Window);
CenterWindow(pGameWindow->Window);
}
void GameWindow_Draw(GameWindow *pGameWindow)
{
SetPort(pGameWindow->Window);
MoveTo(10, 20);
DrawString("\pHello MacLO");
}
void GameWindow_Show(GameWindow *pGameWindow)
{
ShowWindow(pGameWindow->Window);
}

View File

@ -5,12 +5,16 @@
#define GAMEWINDOW_H
#include "MacCommon.h"
#include "GameEngine.h"
typedef struct GameWindow
{
WindowPtr Window;
WindowPtr Window;
GameEngine Engine;
} GameWindow;
void GameWindow_Init(GameWindow *gameWindow);
void GameWindow_Init(GameWindow *pGameWindow);
void GameWindow_Draw(GameWindow *pGameWindow);
void GameWindow_Show(GameWindow *pGameWindow);
#endif

View File

@ -5,19 +5,13 @@
void CenterWindow(WindowPtr window)
{
}
Boolean IsCompactDisplay()
{
return screenBits.bounds.right == 512
&& screenBits.bounds.bottom == 342;
// TODO
}
void ShowError(Str255 message, Boolean isFatal)
{
ParamText(message, kEmptyString, kEmptyString, kEmptyString);
StopAlert(kErrorAlertID, kNilFilterProc);
ParamText(message, EmptyString, EmptyString, EmptyString);
StopAlert(ErrorAlertResID, NilFilterProc);
if (isFatal)
{

View File

@ -4,13 +4,13 @@
#ifndef MACCOMMON_H
#define MACCOMMON_H
#define kBaseResID 128
#define kMoveToFront (WindowPtr)-1L
#define BaseResID 128
#define MoveToFront (WindowPtr)-1L
#define kEmptyString "\p"
#define kNilFilterProc nil
#define EmptyString "\p"
#define NilFilterProc nil
#define kErrorAlertID kBaseResID
#define ErrorAlertResID BaseResID
void CenterWindow(WindowPtr window);
Boolean IsCompactDisplay();

View File

@ -4,10 +4,33 @@
#include "GameWindow.h"
#include "MacLO.h"
GameWindow gGameWindow;
#define AppleMenuResID BaseResID
#define AboutMenuItemID 1
void MacLO_InitToolBox()
#define GameMenuResID BaseResID+1
#define QuitMenuItemID 1
#define AboutDialogResID BaseResID
#define AboutDialogOKID 1
GameWindow gGameWindow;
Boolean gExitApp;
void MacLO_HandleUpdate(const EventRecord *pEvent);
void MacLO_HandleMouseDown(const EventRecord *pEvent);
void MacLO_HandleMenuChoice(const long menuChoice);
void MacLO_HandleAppleMenuChoice(const short item);
void MacLO_ShowAboutDialog();
void MacLO_LaunchAppleMenuItem(const short item);
void MacLO_HandleGameMenuChoice(const short item);
void MacLO_ToolBoxInit()
{
MaxApplZone();
InitGraf(&thePort);
InitFonts();
InitWindows();
@ -18,13 +41,169 @@ void MacLO_InitToolBox()
InitCursor();
}
void MacLO_InitWindows()
void MacLO_AppInit()
{
Handle menuBar;
MenuHandle appleMenu;
// Add the menu bar
menuBar = GetNewMBar(BaseResID);
SetMenuBar(menuBar);
// Populate the apple menu
appleMenu = GetMHandle(AppleMenuResID);
AddResMenu(appleMenu, 'DRVR');
DrawMenuBar();
// Setup the game window
GameWindow_Init(&gGameWindow);
GameWindow_Draw(&gGameWindow);
GameWindow_Show(&gGameWindow);
}
void MacLO_MainLoop()
{
while (!Button()) { }
EventRecord event;
char cmdChar;
while (!gExitApp)
{
if (WaitNextEvent(everyEvent, &event, LONG_MAX, nil))
{
switch (event.what)
{
case updateEvt:
MacLO_HandleUpdate(&event);
break;
case mouseDown:
MacLO_HandleMouseDown(&event);
break;
case keyDown:
case autoKey:
// Translate command key combos to menu items
cmdChar = event.message & charCodeMask;
if ((event.modifiers & cmdKey) != 0)
{
MacLO_HandleMenuChoice(MenuKey(cmdChar));
}
break;
}
}
}
}
void MacLO_HandleUpdate(const EventRecord *pEvent)
{
WindowPtr window;
window = (WindowPtr)pEvent->message;
BeginUpdate(window);
if (window == gGameWindow.Window)
{
GameWindow_Draw(&gGameWindow);
}
EndUpdate(window);
}
void MacLO_HandleMouseDown(const EventRecord *pEvent)
{
WindowPtr window;
long windowPart;
long menuChoice;
windowPart = FindWindow(pEvent->where, &window);
switch (windowPart)
{
case inMenuBar:
menuChoice = MenuSelect(pEvent->where);
MacLO_HandleMenuChoice(menuChoice);
case inSysWindow:
SystemClick(pEvent, window);
break;
case inDrag:
DragWindow(window, pEvent->where, &((*GetGrayRgn())->rgnBBox));
break;
}
}
void MacLO_HandleMenuChoice(const long menuChoice)
{
short menu;
short item;
if (menuChoice != 0)
{
menu = HiWord(menuChoice);
item = LoWord(menuChoice);
switch (menu)
{
case AppleMenuResID:
MacLO_HandleAppleMenuChoice(item);
break;
case GameMenuResID:
MacLO_HandleGameMenuChoice(item);
break;
}
HiliteMenu(0);
}
}
void MacLO_HandleAppleMenuChoice(const short item)
{
MenuHandle appleMenu;
Str255 accName;
short accNumber;
switch (item)
{
case AboutMenuItemID:
MacLO_ShowAboutDialog();
break;
default:
MacLO_LaunchAppleMenuItem(item);
break;
}
}
void MacLO_ShowAboutDialog()
{
DialogPtr dialog;
int itemHit;
dialog = GetNewDialog(AboutDialogResID, nil, MoveToFront);
SetPort(dialog);
ShowWindow(dialog);
ModalDialog(nil, &itemHit);
DisposDialog(dialog);
}
void MacLO_LaunchAppleMenuItem(const short item)
{
MenuHandle appleMenu;
Str255 accName;
appleMenu = GetMHandle(AppleMenuResID);
GetItem(appleMenu, item, accName);
OpenDeskAcc(accName);
}
void MacLO_HandleGameMenuChoice(const short item)
{
switch (item)
{
case QuitMenuItemID:
gExitApp = true;
break;
}
}

View File

@ -4,8 +4,8 @@
#ifndef MACLO_H
#define MACLO_H
void MacLO_InitToolBox();
void MacLO_InitWindows();
void MacLO_ToolBoxInit();
void MacLO_AppInit();
void MacLO_MainLoop();
#endif

Binary file not shown.

Binary file not shown.

View File

@ -5,7 +5,7 @@
void main(void)
{
MacLO_InitToolBox();
MacLO_InitWindows();
MacLO_ToolBoxInit();
MacLO_AppInit();
MacLO_MainLoop();
}