From f49200a4a270a15f374b36e97fda19ae7a582eb4 Mon Sep 17 00:00:00 2001 From: Jon Thysell Date: Wed, 20 Oct 2021 16:13:31 -0700 Subject: [PATCH] Fixed rendering flicker and more * No more flicker when updating lights * Lights now toggled on mouseUp instead of mouseDown * Added playfield and hud areas --- src/GameWindow.c | 71 ++++++++++++++++++++++++++++++------------------ src/GameWindow.h | 18 +++++++++--- src/MacLO.c | 19 ++++++++++++- 3 files changed, 77 insertions(+), 31 deletions(-) diff --git a/src/GameWindow.c b/src/GameWindow.c index 7e599f1..5d76466 100644 --- a/src/GameWindow.c +++ b/src/GameWindow.c @@ -3,7 +3,9 @@ #include "GameWindow.h" -void GameWindow_DrawPlayfield(const GameWindow *pGameWindow); +void GameWindow_SetLightRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t c, const int8_t r); +void GameWindow_DrawPlayfield(const GameWindow *pGameWindow, Boolean fullRefresh); +void GameWindow_DrawHUD(const GameWindow *pGameWindow, Boolean fullRefresh); void GameWindow_Init(GameWindow *pGameWindow) { @@ -20,14 +22,18 @@ void GameWindow_Init(GameWindow *pGameWindow) } // Setup rects - pGameWindow->PlayfieldRect.left = PlayfieldMargin; pGameWindow->PlayfieldRect.top = PlayfieldMargin; - pGameWindow->PlayfieldRect.right = (2 * PlayfieldMargin) + (PuzzleSize * (LightSize + LightMargin)) - LightMargin; - pGameWindow->PlayfieldRect.bottom = (2 * PlayfieldMargin) + (PuzzleSize * (LightSize + LightMargin)) - LightMargin;; + pGameWindow->PlayfieldRect.bottom = pGameWindow->Window->portRect.bottom - PlayfieldMargin; + pGameWindow->PlayfieldRect.left = pGameWindow->PlayfieldRect.top; + pGameWindow->PlayfieldRect.right = pGameWindow->PlayfieldRect.bottom; + pGameWindow->HUDRect.top = HUDMargin; + pGameWindow->HUDRect.bottom = pGameWindow->Window->portRect.bottom - HUDMargin; + pGameWindow->HUDRect.left = pGameWindow->PlayfieldRect.right + HUDMargin; + pGameWindow->HUDRect.right = pGameWindow->Window->portRect.right - HUDMargin; + // Load first level GameEngine_LoadLevel(&(pGameWindow->Engine), 0, false); - } void GameWindow_Draw(const GameWindow *pGameWindow, Boolean fullRefresh) @@ -39,49 +45,66 @@ void GameWindow_Draw(const GameWindow *pGameWindow, Boolean fullRefresh) if (fullRefresh) { // Fill background - ForeColor(blackColor); - PaintRect(pContentRect); + FillRect(pContentRect, WindowPattern); } - GameWindow_DrawPlayfield(pGameWindow); + GameWindow_DrawPlayfield(pGameWindow, fullRefresh); + GameWindow_DrawHUD(pGameWindow, fullRefresh); } -void GameWindow_DrawPlayfield(const GameWindow *pGameWindow) +void GameWindow_SetLightRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t c, const int8_t r) +{ + pRect->top = pGameWindow->PlayfieldRect.top + PlayfieldPadding + LightMargin + (r * (LightMargin + LightSize)); + pRect->bottom = pRect->top + LightSize; + pRect->left = pGameWindow->PlayfieldRect.left + PlayfieldPadding + LightMargin + (c * (LightMargin + LightSize)); + pRect->right = pRect->left + LightSize; +} + +void GameWindow_DrawPlayfield(const GameWindow *pGameWindow, Boolean fullRefresh) { int8_t r, c; Rect lightRect; SetPort(pGameWindow->Window); + if (fullRefresh) + { + // Fill background + FillRoundRect(&(pGameWindow->PlayfieldRect), PlayfieldCornerSize, PlayfieldCornerSize, PlayfieldPattern); + } + // Draw lights for (r = 0; r < PuzzleSize; r++) { - lightRect.top = PlayfieldMargin + (r * (LightMargin + LightSize)); - lightRect.bottom = lightRect.top + LightSize; - for (c = 0; c < PuzzleSize; c++) { - lightRect.left = PlayfieldMargin + (c * (LightMargin + LightSize)); - lightRect.right = lightRect.left + LightSize; + GameWindow_SetLightRect(pGameWindow, &lightRect, c, r); if (GameEngine_GetLight(&(pGameWindow->Engine), c, r)) { // Draw ON light - ForeColor(whiteColor); - PaintRoundRect(&lightRect, LightCornerSize, LightCornerSize); + FillRoundRect(&lightRect, LightCornerSize, LightCornerSize, white); } else { // Draw OFF light - ForeColor(blackColor); - PaintRoundRect(&lightRect, LightCornerSize, LightCornerSize); - ForeColor(whiteColor); - FrameRoundRect(&lightRect, LightCornerSize, LightCornerSize); + FillRoundRect(&lightRect, LightCornerSize, LightCornerSize, black); } } } } +void GameWindow_DrawHUD(const GameWindow *pGameWindow, Boolean fullRefresh) +{ + SetPort(pGameWindow->Window); + + if (fullRefresh) + { + // Fill background + FillRoundRect(&(pGameWindow->HUDRect), HUDCornerSize, HUDCornerSize, HUDPattern); + } +} + void GameWindow_Show(const GameWindow *pGameWindow) { ShowWindow(pGameWindow->Window); @@ -96,18 +119,14 @@ void GameWindow_Click(GameWindow *pGameWindow, const Point *pPosition) { for (r = 0; r < PuzzleSize; r++) { - lightRect.top = PlayfieldMargin + (r * (LightMargin + LightSize)); - lightRect.bottom = lightRect.top + LightSize; - for (c = 0; c < PuzzleSize; c++) { - lightRect.left = PlayfieldMargin + (c * (LightMargin + LightSize)); - lightRect.right = lightRect.left + LightSize; + GameWindow_SetLightRect(pGameWindow, &lightRect, c, r); if (PtInRect(*pPosition, &lightRect)) { GameEngine_ToggleLights(&(pGameWindow->Engine), c, r); - GameWindow_DrawPlayfield(pGameWindow); + GameWindow_Draw(pGameWindow, false); break; } } diff --git a/src/GameWindow.h b/src/GameWindow.h index 7679f64..64ef5f0 100644 --- a/src/GameWindow.h +++ b/src/GameWindow.h @@ -7,16 +7,26 @@ #include "MacCommon.h" #include "GameEngine.h" -#define PlayfieldMargin 5 -#define LightMargin 10 -#define LightSize 50 -#define LightCornerSize 10 +#define WindowPattern black + +#define PlayfieldMargin 4 +#define PlayfieldPadding 2 +#define PlayfieldCornerSize 12 +#define LightMargin 6 +#define LightSize 50 +#define LightCornerSize 8 +#define PlayfieldPattern ltGray + +#define HUDMargin PlayfieldMargin +#define HUDCornerSize PlayfieldCornerSize +#define HUDPattern PlayfieldPattern typedef struct GameWindow { WindowPtr Window; GameEngine Engine; Rect PlayfieldRect; + Rect HUDRect; } GameWindow; void GameWindow_Init(GameWindow *pGameWindow); diff --git a/src/MacLO.c b/src/MacLO.c index 4b5cf62..053bb62 100644 --- a/src/MacLO.c +++ b/src/MacLO.c @@ -18,6 +18,7 @@ Boolean gExitApp; void MacLO_HandleUpdate(const EventRecord *pEvent); void MacLO_HandleMouseDown(const EventRecord *pEvent); +void MacLO_HandleMouseUp(const EventRecord *pEvent); void MacLO_HandleMenuChoice(const long menuChoice); void MacLO_HandleAppleMenuChoice(const short item); @@ -58,7 +59,6 @@ void MacLO_AppInit() // Setup the game window GameWindow_Init(&gGameWindow); - GameWindow_Draw(&gGameWindow, true); GameWindow_Show(&gGameWindow); } @@ -79,6 +79,9 @@ void MacLO_MainLoop() case mouseDown: MacLO_HandleMouseDown(&event); break; + case mouseUp: + MacLO_HandleMouseUp(&event); + break; case keyDown: case autoKey: // Translate command key combos to menu items @@ -130,6 +133,20 @@ void MacLO_HandleMouseDown(const EventRecord *pEvent) case inDrag: DragWindow(window, mousePosition, &((*GetGrayRgn())->rgnBBox)); break; + } +} + +void MacLO_HandleMouseUp(const EventRecord *pEvent) +{ + WindowPtr window; + long windowPart; + Point mousePosition; + + windowPart = FindWindow(pEvent->where, &window); + mousePosition = pEvent->where; + + switch (windowPart) + { case inContent: GlobalToLocal(&mousePosition); GameWindow_Click(&gGameWindow, &mousePosition);