[Scummvm-git-logs] scummvm master -> da713d15f8fbdb734877ebc6a409241429a198d0
dreammaster
noreply at scummvm.org
Sat Feb 15 06:37:20 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
da713d15f8 M4: RIDDLE: In progress adding save load menu, common base class with Burger
Commit: da713d15f8fbdb734877ebc6a409241429a198d0
https://github.com/scummvm/scummvm/commit/da713d15f8fbdb734877ebc6a409241429a198d0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2025-02-14T22:37:07-08:00
Commit Message:
M4: RIDDLE: In progress adding save load menu, common base class with Burger
Changed paths:
A engines/m4/gui/game_menu.cpp
A engines/m4/gui/game_menu.h
engines/m4/burger/gui/game_menu.cpp
engines/m4/burger/gui/game_menu.h
engines/m4/gui/gui_menu_items.cpp
engines/m4/gui/gui_menu_items.h
engines/m4/module.mk
engines/m4/riddle/gui/game_menu.cpp
engines/m4/riddle/gui/game_menu.h
engines/m4/riddle/riddle.cpp
engines/m4/riddle/riddle.h
diff --git a/engines/m4/burger/gui/game_menu.cpp b/engines/m4/burger/gui/game_menu.cpp
index d1b02b017e2..8c9f43b7ece 100644
--- a/engines/m4/burger/gui/game_menu.cpp
+++ b/engines/m4/burger/gui/game_menu.cpp
@@ -45,192 +45,6 @@ namespace M4 {
namespace Burger {
namespace GUI {
-Sprite *menu_CreateThumbnail(int32 *spriteSize) {
- Sprite *thumbNailSprite;
- GrBuff *thumbNail;
- Buffer *scrnBuff, *intrBuff, *destBuff, RLE8Buff;
- uint8 *srcPtr, *srcPtr2, *srcPtr3, *srcRowPtr, *destPtr;
- ScreenContext *gameScreen;
- int32 i, status;
- int32 currRow, beginRow, endRow;
-
- // Create a Sprite for the thumbNail
- if ((thumbNailSprite = (Sprite *)mem_alloc(sizeof(Sprite), "sprite")) == nullptr) {
- return nullptr;
- }
-
- thumbNail = new GrBuff((MAX_VIDEO_X + 1) / 3, (MAX_VIDEO_Y + 1) / 3);
- if (!thumbNail) {
- return nullptr;
- }
-
- destBuff = thumbNail->get_buffer();
- if (!destBuff) {
- return nullptr;
- }
-
- gameScreen = vmng_screen_find(_G(gameDrawBuff), &status);
- if ((!gameScreen) || (status != SCRN_ACTIVE)) {
- return nullptr;
- }
-
- scrnBuff = _G(gameDrawBuff)->get_buffer();
- if (!scrnBuff) {
- return nullptr;
- }
-
- // Grab the interface buffer
- intrBuff = _G(gameInterfaceBuff)->get_buffer();
-
- if (gameScreen->y1 > 0) {
- // Paint the top of the thumbnail black
- beginRow = gameScreen->y1;
- memset(destBuff->data, 21, (beginRow / 3) * destBuff->stride);
- srcRowPtr = (uint8 *)(scrnBuff->data + (-gameScreen->x1));
- destPtr = (uint8 *)(destBuff->data + ((beginRow / 3) * destBuff->stride));
- } else {
- srcRowPtr = (uint8 *)(scrnBuff->data + ((-gameScreen->y1) * scrnBuff->stride) + (-gameScreen->x1));
- beginRow = 0;
- destPtr = destBuff->data;
- }
- endRow = imath_min(MAX_VIDEO_Y, gameScreen->y2);
-
- for (currRow = beginRow; currRow <= endRow; currRow += 3) {
-
- // Set the src pointers
- srcPtr = srcRowPtr;
- srcPtr2 = srcRowPtr + scrnBuff->stride;
- srcPtr3 = srcRowPtr + (scrnBuff->stride << 1);
-
- for (i = 0; i < (MAX_VIDEO_X + 1) / 3; i++) {
-
- // Calculate the average - make sure not to extend past the end of the buffer
- if (endRow - currRow < 1) {
- *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2)) / 3));
- } else if (endRow - currRow < 2) {
- *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2) +
- *srcPtr2 + *(srcPtr2 + 1) + *(srcPtr2 + 2)) / 6));
- } else {
- *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2) +
- *srcPtr2 + *(srcPtr2 + 1) + *(srcPtr2 + 2) +
- *srcPtr3 + *(srcPtr3 + 1) + *(srcPtr3 + 2)) / 9));
- }
-
- if (*destPtr == 0) {
- *destPtr = 21;
- }
-
- // Increment the pointers
- srcPtr += 3;
- srcPtr2 += 3;
- srcPtr3 += 3;
- destPtr++;
- }
-
- // Update the row pointer
- srcRowPtr += scrnBuff->stride * 3;
- }
-
- // Reset the currRow
- beginRow = currRow;
-
- // Paint the interface section of the thumbnail
- if (currRow < MAX_VIDEO_Y) {
- // If the interface is visible, grab it
- if (intrBuff) {
- srcRowPtr = intrBuff->data;
- endRow = imath_min(MAX_VIDEO_Y, beginRow + intrBuff->h - 1);
- for (currRow = beginRow; currRow <= endRow; currRow += 3) {
- // Set the src pointers
- srcPtr = srcRowPtr;
- srcPtr2 = srcRowPtr + intrBuff->stride;
- srcPtr3 = srcRowPtr + (intrBuff->stride << 1);
-
- for (i = 0; i < (MAX_VIDEO_X + 1) / 3; i++) {
- // If the pix is outside of the inventory objects in the interface, set to black
- // If ((srcPtr - srcRowPtr < 180) || (srcPtr - srcRowPtr > 575)) {
- if (true) { // for now make everything in the interface black
- *destPtr = 21;
- }
-
- // Else calculate the average - make sure not to extend past the end of the buffer
- else {
- if (endRow - currRow < 1) {
- *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2)) / 3));
- } else if (endRow - currRow < 2) {
- *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2) +
- *srcPtr2 + *(srcPtr2 + 1) + *(srcPtr2 + 2)) / 6));
- } else {
- *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2) +
- *srcPtr2 + *(srcPtr2 + 1) + *(srcPtr2 + 2) +
- *srcPtr3 + *(srcPtr3 + 1) + *(srcPtr3 + 2)) / 9));
- }
- if (*destPtr == 0) {
- *destPtr = 21;
- }
- }
-
- // Increment the pointers
- srcPtr += 3;
- srcPtr2 += 3;
- srcPtr3 += 3;
- destPtr++;
- }
-
- // Update the row pointer
- srcRowPtr += intrBuff->stride * 3;
- }
- } else {
- // Else paint the bottom of the thumbnail black
- destPtr = (uint8 *)(destBuff->data + ((currRow / 3) * destBuff->stride));
- memset(destPtr, 21, (destBuff->h - (currRow / 3)) * destBuff->stride);
- }
- }
-
- // Reset the currRow
- beginRow = currRow;
-
- if (currRow < MAX_VIDEO_Y) {
- // Paint the bottom of the thumbnail black
- destPtr = (uint8 *)(destBuff->data + ((currRow / 3) * destBuff->stride));
- memset(destPtr, 21, (destBuff->h - (currRow / 3)) * destBuff->stride);
- }
-
- // Compress the thumbNail data into the RLE8Buff
- if ((*spriteSize = (int32)gr_sprite_RLE8_encode(destBuff, &RLE8Buff)) <= 0) {
- return nullptr;
- }
-
- // Fill in the Sprite structure
- thumbNailSprite->w = destBuff->w;
- thumbNailSprite->h = destBuff->h;
- thumbNailSprite->encoding = RLE8;
- thumbNailSprite->data = nullptr;
- if ((thumbNailSprite->sourceHandle = NewHandle(*spriteSize, "thumbNail source")) == nullptr) {
- return nullptr;
- }
- thumbNailSprite->sourceOffset = 0;
-
- // Now copy the RLE8Buff into the thumbNail source handle
- HLock(thumbNailSprite->sourceHandle);
- thumbNailSprite->data = (uint8 *)(*(thumbNailSprite->sourceHandle));
- memcpy(thumbNailSprite->data, RLE8Buff.data, *spriteSize);
- HUnLock(thumbNailSprite->sourceHandle);
-
- // Release all buffers
- _G(gameDrawBuff)->release();
- if (intrBuff) {
- _G(gameInterfaceBuff)->release();
- }
- thumbNail->release();
-
- // Free up both the thumbNail and the RLE8Buff
- delete thumbNail;
- mem_free((void *)RLE8Buff.data);
-
- return thumbNailSprite;
-}
-
//------------------------------------- GAME MENU -------------------------------------//
@@ -620,11 +434,188 @@ void CreateErrMenu(RGB8 *myPalette) {
//-------------------------------- SAVE / LOAD MENU -----------------------------------//
-void DestroySaveLoadMenu(bool saveMenu);
-void cb_SaveLoad_Slot(menuItemButton *theItem, guiMenu *myMenu);
-bool load_Handler(menuItemButton *theItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem);
+#define SAVE_LOAD_MENU_X 145
+#define SAVE_LOAD_MENU_Y 10
+#define SAVE_LOAD_MENU_W 344
+#define SAVE_LOAD_MENU_H 460
+
+#define SL_SAVE_X 214
+#define SL_SAVE_Y 384
+#define SL_SAVE_W 74
+#define SL_SAVE_H 43
+
+#define SL_LOAD_X 214
+#define SL_LOAD_Y 384
+#define SL_LOAD_W 74
+#define SL_LOAD_H 43
+
+#define SL_UP_X 292
+#define SL_UP_Y 255
+#define SL_UP_W 20
+#define SL_UP_H 17
+
+#define SL_DOWN_X 293
+#define SL_DOWN_Y 363
+#define SL_DOWN_W 20
+#define SL_DOWN_H 17
+
+#define SL_SLIDER_X 291
+#define SL_SLIDER_Y 255
+#define SL_SLIDER_W 23
+#define SL_SLIDER_H 127
+
+#define SL_CANCEL_X 139
+#define SL_CANCEL_Y 384
+#define SL_CANCEL_W 74
+#define SL_CANCEL_H 43
+
+#define SL_SAVE_LABEL_X 50
+#define SL_SAVE_LABEL_Y 241
+#define SL_SAVE_LABEL_W 70
+#define SL_SAVE_LABEL_H 16
+
+#define SL_LOAD_LABEL_X 50
+#define SL_LOAD_LABEL_Y 241
+#define SL_LOAD_LABEL_W 70
+#define SL_LOAD_LABEL_H 16
+
+#define SL_SCROLL_FIELD_X 50
+#define SL_SCROLL_FIELD_Y 256
+#define SL_SCROLL_FIELD_W 238
+#define SL_SCROLL_FIELD_H 121
+
+#define SL_SCROLL_LINE_W 238
+#define SL_SCROLL_LINE_H 15 //was 16
+
+#define SL_THUMBNAIL_X 66
+#define SL_THUMBNAIL_Y 28
+
+
+void SaveLoadMenu::show(RGB8 *myPalette, bool saveMenu) {
+ ItemHandlerFunction i_handler;
+ bool buttonGreyed;
+
+ if (!_G(menuSystemInitialized)) {
+ guiMenu::initialize(myPalette);
+ }
+
+ // Keep the memory tidy
+ PurgeMem();
+ CompactMem();
+
+ // Load in the game menu sprites
+ if (!guiMenu::loadSprites("slmenu", SL_TOTAL_SPRITES)) {
+ return;
+ }
+
+ // Initialize some global vars
+ _GM(firstSlotIndex) = 0;
+ _GM(slotSelected) = -1;
+ _GM(saveLoadThumbNail) = nullptr;
+ _GM(thumbIndex) = 100;
+ _GM(currMenuIsSave) = saveMenu;
+
+ _GM(slMenu) = guiMenu::create(_GM(menuSprites)[SL_DIALOG_BOX], SAVE_LOAD_MENU_X, SAVE_LOAD_MENU_Y,
+ MENU_DEPTH | SF_GET_ALL | SF_BLOCK_ALL | SF_IMMOVABLE);
+ if (!_GM(slMenu)) {
+ return;
+ }
+
+ if (_GM(currMenuIsSave)) {
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_SAVE_LABEL, SL_SAVE_LABEL_X, SL_SAVE_LABEL_Y, SL_SAVE_LABEL_W, SL_SAVE_LABEL_H);
+ menuItemButton::add(_GM(slMenu), SL_TAG_SAVE, SL_SAVE_X, SL_SAVE_Y, SL_SAVE_W, SL_SAVE_H,
+ (CALLBACK)cb_SaveLoad_Save, menuItemButton::BTN_TYPE_SL_SAVE, true);
+ } else {
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_LOAD_LABEL, SL_LOAD_LABEL_X, SL_LOAD_LABEL_Y, SL_LOAD_LABEL_W, SL_LOAD_LABEL_H);
+ menuItemButton::add(_GM(slMenu), SL_TAG_LOAD, SL_LOAD_X, SL_LOAD_Y, SL_LOAD_W, SL_LOAD_H,
+ (CALLBACK)cb_SaveLoad_Load, menuItemButton::BTN_TYPE_SL_LOAD, true);
+ }
+
+ menuItemButton::add(_GM(slMenu), SL_TAG_CANCEL, SL_CANCEL_X, SL_CANCEL_Y, SL_CANCEL_W, SL_CANCEL_H,
+ (CALLBACK)cb_SaveLoad_Cancel, menuItemButton::BTN_TYPE_SL_CANCEL);
+
+ menuItemVSlider::add(_GM(slMenu), SL_TAG_VSLIDER, SL_SLIDER_X, SL_SLIDER_Y, SL_SLIDER_W, SL_SLIDER_H,
+ 0, (CALLBACK)cb_SaveLoad_VSlider);
+
+ initializeSlotTables();
+
+ if (_GM(currMenuIsSave)) {
+ buttonGreyed = false;
+ i_handler = (ItemHandlerFunction)menuItemButton::handler;
+ } else {
+ buttonGreyed = true;
+ i_handler = (ItemHandlerFunction)load_Handler;
+ }
+
+ for (int32 i = 0; i < MAX_SLOTS_SHOWN; i++) {
+ menuItemButton::add(_GM(slMenu), 1001 + i,
+ SL_SCROLL_FIELD_X, SL_SCROLL_FIELD_Y + i * SL_SCROLL_LINE_H,
+ SL_SCROLL_LINE_W, SL_SCROLL_LINE_H,
+ (CALLBACK)cb_SaveLoad_Slot, menuItemButton::BTN_TYPE_SL_TEXT,
+ buttonGreyed && (!_GM(slotInUse)[i]), true, _GM(slotTitles)[i], i_handler);
+ }
-void cb_SaveLoad_VSlider(menuItemVSlider *myItem, guiMenu *myMenu) {
+ if (_GM(currMenuIsSave)) {
+ // Create thumbnails. One in the original game format for displaying,
+ // and the other in the ScummVM format for actually using in the save files
+ _GM(saveLoadThumbNail) = menu_CreateThumbnail(&_GM(sizeofThumbData));
+ _GM(_thumbnail).free();
+ Graphics::createThumbnail(_GM(_thumbnail));
+
+ } else {
+ updateThumbnails(0, _GM(slMenu));
+ _GM(saveLoadThumbNail) = _GM(menuSprites)[SL_EMPTY_THUMB];
+ }
+
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_THUMBNAIL, SL_THUMBNAIL_X, SL_THUMBNAIL_Y, SL_THUMBNAIL_W, SL_THUMBNAIL_H, false);
+
+ if (_GM(currMenuIsSave)) {
+ //<return> - if a slot has been selected, saves the game
+ //<esc> - cancels and returns to the game menu
+ guiMenu::configure(_GM(slMenu), (CALLBACK)cb_SaveLoad_Save, (CALLBACK)cb_SaveLoad_Cancel);
+ } else {
+ //<return> - if a slot has been selected, loads the selected game
+ //<esc> - cancels and returns to the game menu
+ guiMenu::configure(_GM(slMenu), (CALLBACK)cb_SaveLoad_Load, (CALLBACK)cb_SaveLoad_Cancel);
+ }
+
+ vmng_screen_show((void *)_GM(slMenu));
+ LockMouseSprite(0);
+}
+
+void SaveLoadMenu::destroyMenu(bool saveMenu) {
+ int32 i;
+
+ if (!_GM(slMenu)) {
+ return;
+ }
+
+ // Determine whether the screen was the SAVE or the LOAD menu
+ if (saveMenu) {
+
+ // If SAVE, there should be a thumbnail to unload
+ if (_GM(saveLoadThumbNail)) {
+ DisposeHandle(_GM(saveLoadThumbNail)->sourceHandle);
+ mem_free(_GM(saveLoadThumbNail));
+ _GM(saveLoadThumbNail) = nullptr;
+ }
+ } else {
+ // Else there may be up to 10 somewhere in the list to be unloaded
+ for (i = 0; i < MAX_SLOTS; i++) {
+ unloadThumbnail(i);
+ }
+ _GM(saveLoadThumbNail) = nullptr;
+ }
+
+ // Destroy the screen
+ vmng_screen_dispose(_GM(slMenu));
+ guiMenu::destroy(_GM(slMenu));
+
+ // Unload the save/load menu sprites
+ guiMenu::unloadSprites();
+}
+
+void SaveLoadMenu::cb_SaveLoad_VSlider(menuItemVSlider *myItem, guiMenu *myMenu) {
bool redraw;
if (!myMenu || !myItem)
@@ -664,7 +655,7 @@ void cb_SaveLoad_VSlider(menuItemVSlider *myItem, guiMenu *myMenu) {
// See if we were able to set a new first slot index
if (redraw) {
- SetFirstSlot(_GM(firstSlotIndex), myMenu);
+ setFirstSlot(_GM(firstSlotIndex), myMenu);
// Calculate the new percent
myItem->percent = (_GM(firstSlotIndex) * 100) / 89;
@@ -681,12 +672,11 @@ void cb_SaveLoad_VSlider(menuItemVSlider *myItem, guiMenu *myMenu) {
// Else the callback came from the thumb - set the _GM(firstSlotIndex) based on the slider percent
else {
_GM(firstSlotIndex) = (myItem->percent * 89) / 100;
- SetFirstSlot(_GM(firstSlotIndex), myMenu);
+ setFirstSlot(_GM(firstSlotIndex), myMenu);
}
}
-
-void cb_SaveLoad_Save(void *, guiMenu *myMenu) {
+void SaveLoadMenu::cb_SaveLoad_Save(void *, guiMenu *myMenu) {
menuItemTextField *myText;
bool saveGameFailed;
@@ -713,7 +703,7 @@ void cb_SaveLoad_Save(void *, guiMenu *myMenu) {
// If the save game failed, bring up the err menu
if (saveGameFailed) {
// Kill the save menu
- DestroySaveLoadMenu(true);
+ destroyMenu(true);
// Create the err menu
CreateErrMenu(nullptr);
@@ -723,14 +713,13 @@ void cb_SaveLoad_Save(void *, guiMenu *myMenu) {
}
// Kill the save menu
- DestroySaveLoadMenu(true);
+ destroyMenu(true);
// Shutdown the menu system
guiMenu::shutdown(true);
}
-
-void cb_SaveLoad_Load(menuItemButton *, guiMenu *) {
+void SaveLoadMenu::cb_SaveLoad_Load(menuItemButton *, guiMenu *) {
KernelTriggerType oldMode;
// If (slotSelected < 0) this callback is being executed by pressing return prematurely
@@ -739,7 +728,7 @@ void cb_SaveLoad_Load(menuItemButton *, guiMenu *) {
}
// Kill the menu
- DestroySaveLoadMenu(false);
+ destroyMenu(false);
// Shutdown the menu system
guiMenu::shutdown(false);
@@ -760,8 +749,7 @@ void cb_SaveLoad_Load(menuItemButton *, guiMenu *) {
_G(kernel).trigger_mode = oldMode;
}
-
-void cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu) {
+void SaveLoadMenu::cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu) {
menuItem *myItem;
int32 i, x, y, w, h;
@@ -796,11 +784,11 @@ void cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu) {
// Remove the thumbnail
if (_GM(saveLoadThumbNail)) {
- _GM(saveLoadThumbNail) = _GM(menuSprites)[Burger::GUI::SL_EMPTY_THUMB];
+ _GM(saveLoadThumbNail) = _GM(menuSprites)[SL_EMPTY_THUMB];
guiMenu::itemRefresh(nullptr, SL_TAG_THUMBNAIL, myMenu);
}
}
- SetFirstSlot(_GM(firstSlotIndex), myMenu);
+ setFirstSlot(_GM(firstSlotIndex), myMenu);
// Enable the slider
menuItemVSlider::enableVSlider(nullptr, SL_TAG_VSLIDER, myMenu);
@@ -822,7 +810,7 @@ void cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu) {
// Otherwise, back to the game menu
// Destroy the menu
- DestroySaveLoadMenu(_GM(currMenuIsSave));
+ destroyMenu(_GM(currMenuIsSave));
if (_GM(saveLoadFromHotkey)) {
// Shutdown the menu system
@@ -836,8 +824,7 @@ void cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu) {
_GM(buttonClosesDialog) = true;
}
-
-void cb_SaveLoad_Slot(menuItemButton *myButton, guiMenu *myMenu) {
+void SaveLoadMenu::cb_SaveLoad_Slot(menuItemButton *myButton, guiMenu *myMenu) {
int32 i, x, y, w, h;
char prompt[80];
int32 specialTag;
@@ -897,25 +884,7 @@ void cb_SaveLoad_Slot(menuItemButton *myButton, guiMenu *myMenu) {
}
}
-void InitializeSlotTables(void) {
- const SaveStateList saves = g_engine->listSaves();
-
- // First reset all the slots to empty
- for (int i = 0; i < MAX_SLOTS; ++i) {
- Common::strcpy_s(_GM(slotTitles)[i], 80, "<empty>");
- _GM(slotInUse)[i] = false;
- }
-
- for (const auto &save : saves) {
- if (save.getSaveSlot() != 0) {
- Common::String desc = save.getDescription();
- Common::strcpy_s(_GM(slotTitles)[save.getSaveSlot() - 1], 80, desc.c_str());
- _GM(slotInUse)[save.getSaveSlot() - 1] = true;
- }
- }
-}
-
-bool load_Handler(menuItemButton *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
+bool SaveLoadMenu::load_Handler(menuItemButton *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
bool handled;
// Handle the event just like any other button
@@ -956,7 +925,7 @@ bool load_Handler(menuItemButton *myItem, int32 eventType, int32 event, int32 x,
// Remove the thumbnail
if (_GM(saveLoadThumbNail)) {
- _GM(saveLoadThumbNail) = _GM(menuSprites)[Burger::GUI::SL_EMPTY_THUMB];
+ _GM(saveLoadThumbNail) = _GM(menuSprites)[SL_EMPTY_THUMB];
guiMenu::itemRefresh(nullptr, SL_TAG_THUMBNAIL, (guiMenu *)myItem->myMenu);
}
}
@@ -967,131 +936,6 @@ bool load_Handler(menuItemButton *myItem, int32 eventType, int32 event, int32 x,
}
-void DestroySaveLoadMenu(bool saveMenu) {
- int32 i;
-
- if (!_GM(slMenu)) {
- return;
- }
-
- // Determine whether the screen was the SAVE or the LOAD menu
- if (saveMenu) {
-
- // If SAVE, there should be a thumbnail to unload
- if (_GM(saveLoadThumbNail)) {
- DisposeHandle(_GM(saveLoadThumbNail)->sourceHandle);
- mem_free(_GM(saveLoadThumbNail));
- _GM(saveLoadThumbNail) = nullptr;
- }
- } else {
- // Else there may be up to 10 somewhere in the list to be unloaded
- for (i = 0; i < MAX_SLOTS; i++) {
- UnloadThumbNail(i);
- }
- _GM(saveLoadThumbNail) = nullptr;
- }
-
- // Destroy the screen
- vmng_screen_dispose(_GM(slMenu));
- guiMenu::destroy(_GM(slMenu));
-
- // Unload the save/load menu sprites
- guiMenu::unloadSprites();
-}
-
-
-void CreateSaveLoadMenu(RGB8 *myPalette, bool saveMenu) {
- ItemHandlerFunction i_handler;
- bool buttonGreyed;
-
- if (!_G(menuSystemInitialized)) {
- guiMenu::initialize(myPalette);
- }
-
- // Keep the memory tidy
- PurgeMem();
- CompactMem();
-
- // Load in the game menu sprites
- if (!guiMenu::loadSprites("slmenu", Burger::GUI::SL_TOTAL_SPRITES)) {
- return;
- }
-
- // Initialize some global vars
- _GM(firstSlotIndex) = 0;
- _GM(slotSelected) = -1;
- _GM(saveLoadThumbNail) = nullptr;
- _GM(thumbIndex) = 100;
- _GM(currMenuIsSave) = saveMenu;
-
- _GM(slMenu) = guiMenu::create(_GM(menuSprites)[Burger::GUI::SL_DIALOG_BOX], SAVE_LOAD_MENU_X, SAVE_LOAD_MENU_Y,
- MENU_DEPTH | SF_GET_ALL | SF_BLOCK_ALL | SF_IMMOVABLE);
- if (!_GM(slMenu)) {
- return;
- }
-
- if (_GM(currMenuIsSave)) {
- menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_SAVE_LABEL, SL_SAVE_LABEL_X, SL_SAVE_LABEL_Y, SL_SAVE_LABEL_W, SL_SAVE_LABEL_H);
- menuItemButton::add(_GM(slMenu), SL_TAG_SAVE, SL_SAVE_X, SL_SAVE_Y, SL_SAVE_W, SL_SAVE_H,
- (CALLBACK)cb_SaveLoad_Save, menuItemButton::BTN_TYPE_SL_SAVE, true);
- } else {
- menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_LOAD_LABEL, SL_LOAD_LABEL_X, SL_LOAD_LABEL_Y, SL_LOAD_LABEL_W, SL_LOAD_LABEL_H);
- menuItemButton::add(_GM(slMenu), SL_TAG_LOAD, SL_LOAD_X, SL_LOAD_Y, SL_LOAD_W, SL_LOAD_H,
- (CALLBACK)cb_SaveLoad_Load, menuItemButton::BTN_TYPE_SL_LOAD, true);
- }
-
- menuItemButton::add(_GM(slMenu), SL_TAG_CANCEL, SL_CANCEL_X, SL_CANCEL_Y, SL_CANCEL_W, SL_CANCEL_H,
- (CALLBACK)cb_SaveLoad_Cancel, menuItemButton::BTN_TYPE_SL_CANCEL);
-
- menuItemVSlider::add(_GM(slMenu), SL_TAG_VSLIDER, SL_SLIDER_X, SL_SLIDER_Y, SL_SLIDER_W, SL_SLIDER_H,
- 0, (CALLBACK)cb_SaveLoad_VSlider);
-
- InitializeSlotTables();
-
- if (_GM(currMenuIsSave)) {
- buttonGreyed = false;
- i_handler = (ItemHandlerFunction)menuItemButton::handler;
- } else {
- buttonGreyed = true;
- i_handler = (ItemHandlerFunction)load_Handler;
- }
-
- for (int32 i = 0; i < MAX_SLOTS_SHOWN; i++) {
- menuItemButton::add(_GM(slMenu), 1001 + i,
- SL_SCROLL_FIELD_X, SL_SCROLL_FIELD_Y + i * SL_SCROLL_LINE_H,
- SL_SCROLL_LINE_W, SL_SCROLL_LINE_H,
- (CALLBACK)cb_SaveLoad_Slot, menuItemButton::BTN_TYPE_SL_TEXT,
- buttonGreyed && (!_GM(slotInUse)[i]), true, _GM(slotTitles)[i], i_handler);
- }
-
- if (_GM(currMenuIsSave)) {
- // Create thumbnails. One in the original game format for displaying,
- // and the other in the ScummVM format for actually using in the save files
- _GM(saveLoadThumbNail) = menu_CreateThumbnail(&_GM(sizeofThumbData));
- _GM(_thumbnail).free();
- Graphics::createThumbnail(_GM(_thumbnail));
-
- } else {
- UpdateThumbNails(0, _GM(slMenu));
- _GM(saveLoadThumbNail) = _GM(menuSprites)[Burger::GUI::SL_EMPTY_THUMB];
- }
-
- menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_THUMBNAIL, SL_THUMBNAIL_X, SL_THUMBNAIL_Y, SL_THUMBNAIL_W, SL_THUMBNAIL_H, false);
-
- if (_GM(currMenuIsSave)) {
- //<return> - if a slot has been selected, saves the game
- //<esc> - cancels and returns to the game menu
- guiMenu::configure(_GM(slMenu), (CALLBACK)cb_SaveLoad_Save, (CALLBACK)cb_SaveLoad_Cancel);
- } else {
- //<return> - if a slot has been selected, loads the selected game
- //<esc> - cancels and returns to the game menu
- guiMenu::configure(_GM(slMenu), (CALLBACK)cb_SaveLoad_Load, (CALLBACK)cb_SaveLoad_Cancel);
- }
-
- vmng_screen_show((void *)_GM(slMenu));
- LockMouseSprite(0);
-}
-
void CreateGameMenu(RGB8 *myPalette) {
if ((!player_commands_allowed()) || (!INTERFACE_VISIBLE) ||
_G(pal_fade_in_progress) || _G(menuSystemInitialized)) {
@@ -1113,7 +957,7 @@ void CreateGameMenuFromMain(RGB8 *myPalette) {
void CreateSaveMenu(RGB8 *myPalette) {
_GM(saveLoadFromHotkey) = false;
- CreateSaveLoadMenu(myPalette, true);
+ SaveLoadMenu::show(myPalette, true);
}
void CreateF2SaveMenu(RGB8 *myPalette) {
@@ -1124,12 +968,12 @@ void CreateF2SaveMenu(RGB8 *myPalette) {
_GM(saveLoadFromHotkey) = true;
_GM(gameMenuFromMain) = false;
- CreateSaveLoadMenu(myPalette, true);
+ SaveLoadMenu::show(myPalette, true);
}
void CreateLoadMenu(RGB8 *myPalette) {
_GM(saveLoadFromHotkey) = false;
- CreateSaveLoadMenu(myPalette, false);
+ SaveLoadMenu::show(myPalette, false);
}
void CreateF3LoadMenu(RGB8 *myPalette) {
@@ -1140,7 +984,7 @@ void CreateF3LoadMenu(RGB8 *myPalette) {
_GM(saveLoadFromHotkey) = true;
_GM(gameMenuFromMain) = false;
- CreateSaveLoadMenu(myPalette, false);
+ SaveLoadMenu::show(myPalette, false);
}
void CreateLoadMenuFromMain(RGB8 *myPalette) {
@@ -1150,7 +994,7 @@ void CreateLoadMenuFromMain(RGB8 *myPalette) {
_GM(saveLoadFromHotkey) = true;
_GM(gameMenuFromMain) = true;
- CreateSaveLoadMenu(myPalette, false);
+ SaveLoadMenu::show(myPalette, false);
}
} // namespace GUI
diff --git a/engines/m4/burger/gui/game_menu.h b/engines/m4/burger/gui/game_menu.h
index b228eee5835..be5b781a56a 100644
--- a/engines/m4/burger/gui/game_menu.h
+++ b/engines/m4/burger/gui/game_menu.h
@@ -27,6 +27,7 @@
#include "m4/m4_types.h"
#include "m4/graphics/gr_buff.h"
#include "m4/gui/gui_menu_items.h"
+#include "m4/gui/game_menu.h"
#include "m4/gui/gui_univ.h"
namespace M4 {
@@ -43,6 +44,21 @@ using M4::GUI::Sprite;
using M4::GUI::CALLBACK;
using M4::GUI::ItemHandlerFunction;
+class SaveLoadMenu : public M4::GUI::SaveLoadMenuBase {
+private:
+ static void destroyMenu(bool saveMenu);
+ static bool load_Handler(menuItemButton *theItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem);
+
+ static void cb_SaveLoad_Save(void *, guiMenu *myMenu);
+ static void cb_SaveLoad_Load(menuItemButton *, guiMenu *);
+ static void cb_SaveLoad_Cancel(menuItemButton *, guiMenu *myMenu);
+ static void cb_SaveLoad_Slot(menuItemButton *myButton, guiMenu *myMenu);
+ static void cb_SaveLoad_VSlider(menuItemVSlider *myItem, guiMenu *myMenu);
+
+public:
+ static void show(RGB8 *myPalette, bool saveMenu);
+};
+
//GAME MENU FUNCTIONS
extern void CreateGameMenu(RGB8 *myPalette);
extern void CreateOptionsMenu(RGB8 *myPalette);
@@ -68,66 +84,6 @@ enum game_menu_button_tags {
GM_TAG_MAIN = 6
};
-//======================================
-//
-// Save/Load menu enums and defines
-//
-#define SAVE_LOAD_MENU_X 145
-#define SAVE_LOAD_MENU_Y 10
-#define SAVE_LOAD_MENU_W 344
-#define SAVE_LOAD_MENU_H 460
-
-#define SL_SAVE_X 214
-#define SL_SAVE_Y 384
-#define SL_SAVE_W 74
-#define SL_SAVE_H 43
-
-#define SL_LOAD_X 214
-#define SL_LOAD_Y 384
-#define SL_LOAD_W 74
-#define SL_LOAD_H 43
-
-#define SL_UP_X 292
-#define SL_UP_Y 255
-#define SL_UP_W 20
-#define SL_UP_H 17
-
-#define SL_DOWN_X 293
-#define SL_DOWN_Y 363
-#define SL_DOWN_W 20
-#define SL_DOWN_H 17
-
-#define SL_SLIDER_X 291
-#define SL_SLIDER_Y 255
-#define SL_SLIDER_W 23
-#define SL_SLIDER_H 127
-
-#define SL_CANCEL_X 139
-#define SL_CANCEL_Y 384
-#define SL_CANCEL_W 74
-#define SL_CANCEL_H 43
-
-#define SL_SAVE_LABEL_X 50
-#define SL_SAVE_LABEL_Y 241
-#define SL_SAVE_LABEL_W 70
-#define SL_SAVE_LABEL_H 16
-
-#define SL_LOAD_LABEL_X 50
-#define SL_LOAD_LABEL_Y 241
-#define SL_LOAD_LABEL_W 70
-#define SL_LOAD_LABEL_H 16
-
-#define SL_SCROLL_FIELD_X 50
-#define SL_SCROLL_FIELD_Y 256
-#define SL_SCROLL_FIELD_W 238
-#define SL_SCROLL_FIELD_H 121
-
-#define SL_SCROLL_LINE_W 238
-#define SL_SCROLL_LINE_H 15 //was 16
-
-#define SL_THUMBNAIL_X 66
-#define SL_THUMBNAIL_Y 28
-
/**
* Error menu enums and defines
*/
diff --git a/engines/m4/gui/game_menu.cpp b/engines/m4/gui/game_menu.cpp
new file mode 100644
index 00000000000..15caeff3b3f
--- /dev/null
+++ b/engines/m4/gui/game_menu.cpp
@@ -0,0 +1,334 @@
+/* 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 "m4/core/imath.h"
+#include "m4/graphics/gr_sprite.h"
+#include "m4/gui/game_menu.h"
+#include "m4/gui/gui_vmng.h"
+#include "m4/m4.h"
+
+namespace M4 {
+namespace GUI {
+
+void SaveLoadMenuBase::initializeSlotTables(void) {
+ const SaveStateList saves = g_engine->listSaves();
+
+ // First reset all the slots to empty
+ for (int i = 0; i < MAX_SLOTS; ++i) {
+ Common::strcpy_s(_GM(slotTitles)[i], 80, "<empty>");
+ _GM(slotInUse)[i] = false;
+ }
+
+ for (const auto &save : saves) {
+ if (save.getSaveSlot() != 0) {
+ Common::String desc = save.getDescription();
+ Common::strcpy_s(_GM(slotTitles)[save.getSaveSlot() - 1], 80, desc.c_str());
+ _GM(slotInUse)[save.getSaveSlot() - 1] = true;
+ }
+ }
+}
+
+Sprite *SaveLoadMenuBase::menu_CreateThumbnail(int32 *spriteSize) {
+ Sprite *thumbNailSprite;
+ GrBuff *thumbNail;
+ Buffer *scrnBuff, *intrBuff, *destBuff, RLE8Buff;
+ uint8 *srcPtr, *srcPtr2, *srcPtr3, *srcRowPtr, *destPtr;
+ ScreenContext *gameScreen;
+ int32 i, status;
+ int32 currRow, beginRow, endRow;
+
+ // Create a Sprite for the thumbNail
+ if ((thumbNailSprite = (Sprite *)mem_alloc(sizeof(Sprite), "sprite")) == nullptr) {
+ return nullptr;
+ }
+
+ thumbNail = new GrBuff((MAX_VIDEO_X + 1) / 3, (MAX_VIDEO_Y + 1) / 3);
+ if (!thumbNail) {
+ return nullptr;
+ }
+
+ destBuff = thumbNail->get_buffer();
+ if (!destBuff) {
+ return nullptr;
+ }
+
+ gameScreen = vmng_screen_find(_G(gameDrawBuff), &status);
+ if ((!gameScreen) || (status != SCRN_ACTIVE)) {
+ return nullptr;
+ }
+
+ scrnBuff = _G(gameDrawBuff)->get_buffer();
+ if (!scrnBuff) {
+ return nullptr;
+ }
+
+ // Grab the interface buffer
+ intrBuff = _G(gameInterfaceBuff)->get_buffer();
+
+ if (gameScreen->y1 > 0) {
+ // Paint the top of the thumbnail black
+ beginRow = gameScreen->y1;
+ memset(destBuff->data, 21, (beginRow / 3) * destBuff->stride);
+ srcRowPtr = (uint8 *)(scrnBuff->data + (-gameScreen->x1));
+ destPtr = (uint8 *)(destBuff->data + ((beginRow / 3) * destBuff->stride));
+ } else {
+ srcRowPtr = (uint8 *)(scrnBuff->data + ((-gameScreen->y1) * scrnBuff->stride) + (-gameScreen->x1));
+ beginRow = 0;
+ destPtr = destBuff->data;
+ }
+ endRow = imath_min(MAX_VIDEO_Y, gameScreen->y2);
+
+ for (currRow = beginRow; currRow <= endRow; currRow += 3) {
+
+ // Set the src pointers
+ srcPtr = srcRowPtr;
+ srcPtr2 = srcRowPtr + scrnBuff->stride;
+ srcPtr3 = srcRowPtr + (scrnBuff->stride << 1);
+
+ for (i = 0; i < (MAX_VIDEO_X + 1) / 3; i++) {
+
+ // Calculate the average - make sure not to extend past the end of the buffer
+ if (endRow - currRow < 1) {
+ *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2)) / 3));
+ } else if (endRow - currRow < 2) {
+ *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2) +
+ *srcPtr2 + *(srcPtr2 + 1) + *(srcPtr2 + 2)) / 6));
+ } else {
+ *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2) +
+ *srcPtr2 + *(srcPtr2 + 1) + *(srcPtr2 + 2) +
+ *srcPtr3 + *(srcPtr3 + 1) + *(srcPtr3 + 2)) / 9));
+ }
+
+ if (*destPtr == 0) {
+ *destPtr = 21;
+ }
+
+ // Increment the pointers
+ srcPtr += 3;
+ srcPtr2 += 3;
+ srcPtr3 += 3;
+ destPtr++;
+ }
+
+ // Update the row pointer
+ srcRowPtr += scrnBuff->stride * 3;
+ }
+
+ // Reset the currRow
+ beginRow = currRow;
+
+ // Paint the interface section of the thumbnail
+ if (currRow < MAX_VIDEO_Y) {
+ // If the interface is visible, grab it
+ if (intrBuff) {
+ srcRowPtr = intrBuff->data;
+ endRow = imath_min(MAX_VIDEO_Y, beginRow + intrBuff->h - 1);
+ for (currRow = beginRow; currRow <= endRow; currRow += 3) {
+ // Set the src pointers
+ srcPtr = srcRowPtr;
+ srcPtr2 = srcRowPtr + intrBuff->stride;
+ srcPtr3 = srcRowPtr + (intrBuff->stride << 1);
+
+ for (i = 0; i < (MAX_VIDEO_X + 1) / 3; i++) {
+ // If the pix is outside of the inventory objects in the interface, set to black
+ // If ((srcPtr - srcRowPtr < 180) || (srcPtr - srcRowPtr > 575)) {
+ if (true) { // for now make everything in the interface black
+ *destPtr = 21;
+ }
+
+ // Else calculate the average - make sure not to extend past the end of the buffer
+ else {
+ if (endRow - currRow < 1) {
+ *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2)) / 3));
+ } else if (endRow - currRow < 2) {
+ *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2) +
+ *srcPtr2 + *(srcPtr2 + 1) + *(srcPtr2 + 2)) / 6));
+ } else {
+ *destPtr = (uint8)((uint32)((*srcPtr + *(srcPtr + 1) + *(srcPtr + 2) +
+ *srcPtr2 + *(srcPtr2 + 1) + *(srcPtr2 + 2) +
+ *srcPtr3 + *(srcPtr3 + 1) + *(srcPtr3 + 2)) / 9));
+ }
+ if (*destPtr == 0) {
+ *destPtr = 21;
+ }
+ }
+
+ // Increment the pointers
+ srcPtr += 3;
+ srcPtr2 += 3;
+ srcPtr3 += 3;
+ destPtr++;
+ }
+
+ // Update the row pointer
+ srcRowPtr += intrBuff->stride * 3;
+ }
+ } else {
+ // Else paint the bottom of the thumbnail black
+ destPtr = (uint8 *)(destBuff->data + ((currRow / 3) * destBuff->stride));
+ memset(destPtr, 21, (destBuff->h - (currRow / 3)) * destBuff->stride);
+ }
+ }
+
+ // Reset the currRow
+ beginRow = currRow;
+
+ if (currRow < MAX_VIDEO_Y) {
+ // Paint the bottom of the thumbnail black
+ destPtr = (uint8 *)(destBuff->data + ((currRow / 3) * destBuff->stride));
+ memset(destPtr, 21, (destBuff->h - (currRow / 3)) * destBuff->stride);
+ }
+
+ // Compress the thumbNail data into the RLE8Buff
+ if ((*spriteSize = (int32)gr_sprite_RLE8_encode(destBuff, &RLE8Buff)) <= 0) {
+ return nullptr;
+ }
+
+ // Fill in the Sprite structure
+ thumbNailSprite->w = destBuff->w;
+ thumbNailSprite->h = destBuff->h;
+ thumbNailSprite->encoding = RLE8;
+ thumbNailSprite->data = nullptr;
+ if ((thumbNailSprite->sourceHandle = NewHandle(*spriteSize, "thumbNail source")) == nullptr) {
+ return nullptr;
+ }
+ thumbNailSprite->sourceOffset = 0;
+
+ // Now copy the RLE8Buff into the thumbNail source handle
+ HLock(thumbNailSprite->sourceHandle);
+ thumbNailSprite->data = (uint8 *)(*(thumbNailSprite->sourceHandle));
+ memcpy(thumbNailSprite->data, RLE8Buff.data, *spriteSize);
+ HUnLock(thumbNailSprite->sourceHandle);
+
+ // Release all buffers
+ _G(gameDrawBuff)->release();
+ if (intrBuff) {
+ _G(gameInterfaceBuff)->release();
+ }
+ thumbNail->release();
+
+ // Free up both the thumbNail and the RLE8Buff
+ delete thumbNail;
+ mem_free((void *)RLE8Buff.data);
+
+ return thumbNailSprite;
+}
+
+bool SaveLoadMenuBase::loadThumbnail(int32 slotNum) {
+ Sprite *&thumbNailSprite = _GM(thumbNails)[slotNum];
+ return g_engine->loadSaveThumbnail(slotNum + 1, thumbNailSprite);
+}
+
+void SaveLoadMenuBase::unloadThumbnail(int32 slotNum) {
+ if (_GM(thumbNails)[slotNum]->sourceHandle) {
+ HUnLock(_GM(thumbNails)[slotNum]->sourceHandle);
+ DisposeHandle(_GM(thumbNails)[slotNum]->sourceHandle);
+ _GM(thumbNails)[slotNum]->sourceHandle = nullptr;
+ }
+}
+
+void SaveLoadMenuBase::updateThumbnails(int32 firstSlot, guiMenu *myMenu) {
+ int32 i, startIndex, endIndex;
+
+ // Make sure there is something to update
+ if (firstSlot == _GM(thumbIndex)) {
+ return;
+ }
+
+ // Ensure firstSlot is in a valid range
+ firstSlot = imath_max(imath_min(firstSlot, 89), 0);
+
+ if (firstSlot > _GM(thumbIndex)) {
+ // Dump Out all thumbnails in slots which don't overlap
+ startIndex = _GM(thumbIndex);
+ endIndex = imath_min(_GM(thumbIndex) + 9, firstSlot - 1);
+ for (i = startIndex; i <= endIndex; i++) {
+ unloadThumbnail(i);
+ }
+
+ // Load in all thumbnails missing thumbnails
+ startIndex = imath_max(_GM(thumbIndex) + 10, firstSlot);
+ endIndex = imath_min(firstSlot + 9, 98);
+ for (i = startIndex; i <= endIndex; i++) {
+ if (_GM(slotInUse)[i]) {
+ if (!loadThumbnail(i)) {
+ _GM(slotInUse)[i] = false;
+ menuItemButton::disableButton(nullptr, 1001 + i - firstSlot, myMenu);
+ guiMenu::itemRefresh(nullptr, 1001 + i - firstSlot, myMenu);
+ }
+ }
+ }
+ } else {
+ // Else firstSlot < _GM(thumbIndex)
+ // Dump Out all thumbnails in slots which don't overlap
+ startIndex = imath_max(firstSlot + 10, _GM(thumbIndex));
+ endIndex = imath_min(_GM(thumbIndex) + 9, 98);
+ for (i = startIndex; i <= endIndex; i++) {
+ unloadThumbnail(i);
+ }
+
+ // Load in all thumbnails missing thumbnails
+ startIndex = firstSlot;
+ endIndex = imath_min(firstSlot + 9, _GM(thumbIndex) - 1);
+ for (i = startIndex; i <= endIndex; i++) {
+ if (_GM(slotInUse)[i]) {
+ if (!loadThumbnail(i)) {
+ _GM(slotInUse)[i] = false;
+ menuItemButton::disableButton(nullptr, 1001 + i - firstSlot, myMenu);
+ guiMenu::itemRefresh(nullptr, 1001 + i - firstSlot, myMenu);
+ }
+ }
+ }
+ }
+
+ // Set the var
+ _GM(thumbIndex) = firstSlot;
+}
+
+void SaveLoadMenuBase::setFirstSlot(int32 firstSlot, guiMenu *myMenu) {
+ menuItemButton *myButton;
+ int32 i;
+
+ if (!myMenu) {
+ return;
+ }
+
+ // Ensure firstSlot is in a valid range
+ firstSlot = imath_max(imath_min(firstSlot, 89), 0);
+
+ // Change the prompt and special tag of each of the slot buttons
+ for (i = 0; i < MAX_SLOTS_SHOWN; i++) {
+ myButton = (menuItemButton *)guiMenu::getItem(i + 1001, myMenu);
+
+ myButton->prompt = _GM(slotTitles)[firstSlot + i];
+ if (_GM(currMenuIsSave) || _GM(slotInUse)[firstSlot + i]) {
+ myButton->itemFlags = menuItemButton::BTN_STATE_NORM;
+ } else {
+ myButton->itemFlags = menuItemButton::BTN_STATE_GREY;
+ }
+
+ myButton->specialTag = firstSlot + i + 1;
+ guiMenu::itemRefresh(myButton, i + 1001, myMenu);
+ }
+}
+
+} // namespace GUI
+} // namespace M4
diff --git a/engines/m4/gui/game_menu.h b/engines/m4/gui/game_menu.h
new file mode 100644
index 00000000000..e33b1251d3c
--- /dev/null
+++ b/engines/m4/gui/game_menu.h
@@ -0,0 +1,47 @@
+
+/* 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 M4_GUI_GUI_GAME_MENU_H
+#define M4_GUI_GUI_GAME_MENU_H
+
+#include "m4/m4_types.h"
+#include "m4/gui/gui_menu_items.h"
+
+namespace M4 {
+namespace GUI {
+
+class SaveLoadMenuBase {
+protected:
+ static void initializeSlotTables();
+ static Sprite *menu_CreateThumbnail(int32 *spriteSize);
+ static bool loadThumbnail(int32 slotNum);
+ static void unloadThumbnail(int32 slotNum);
+ static void setFirstSlot(int32 firstSlot, guiMenu *myMenu);
+
+public:
+ static void updateThumbnails(int32 firstSlot, guiMenu *myMenu);
+};
+
+} // namespace GUI
+} // namespace M4
+
+#endif
diff --git a/engines/m4/gui/gui_menu_items.cpp b/engines/m4/gui/gui_menu_items.cpp
index 49c0afe744c..ac737f02dca 100644
--- a/engines/m4/gui/gui_menu_items.cpp
+++ b/engines/m4/gui/gui_menu_items.cpp
@@ -27,6 +27,7 @@
#include "m4/adv_r/adv_player.h"
#include "m4/core/errors.h"
#include "m4/core/imath.h"
+#include "m4/gui/game_menu.h"
#include "m4/gui/gui_event.h"
#include "m4/gui/hotkeys.h"
#include "m4/graphics/gr_line.h"
@@ -78,104 +79,6 @@ void gui_DrawSprite(Sprite *mySprite, Buffer *myBuff, int32 x, int32 y) {
}
}
-bool LoadThumbNail(int32 slotNum) {
- Sprite *&thumbNailSprite = _GM(thumbNails)[slotNum];
- return g_engine->loadSaveThumbnail(slotNum + 1, thumbNailSprite);
-}
-
-void UnloadThumbNail(int32 slotNum) {
- if (_GM(thumbNails)[slotNum]->sourceHandle) {
- HUnLock(_GM(thumbNails)[slotNum]->sourceHandle);
- DisposeHandle(_GM(thumbNails)[slotNum]->sourceHandle);
- _GM(thumbNails)[slotNum]->sourceHandle = nullptr;
- }
-}
-
-void UpdateThumbNails(int32 firstSlot, guiMenu *myMenu) {
- int32 i, startIndex, endIndex;
-
- // Make sure there is something to update
- if (firstSlot == _GM(thumbIndex)) {
- return;
- }
-
- // Ensure firstSlot is in a valid range
- firstSlot = imath_max(imath_min(firstSlot, 89), 0);
-
- if (firstSlot > _GM(thumbIndex)) {
- // Dump Out all thumbnails in slots which don't overlap
- startIndex = _GM(thumbIndex);
- endIndex = imath_min(_GM(thumbIndex) + 9, firstSlot - 1);
- for (i = startIndex; i <= endIndex; i++) {
- UnloadThumbNail(i);
- }
-
- // Load in all thumbnails missing thumbnails
- startIndex = imath_max(_GM(thumbIndex) + 10, firstSlot);
- endIndex = imath_min(firstSlot + 9, 98);
- for (i = startIndex; i <= endIndex; i++) {
- if (_GM(slotInUse)[i]) {
- if (!LoadThumbNail(i)) {
- _GM(slotInUse)[i] = false;
- menuItemButton::disableButton(nullptr, 1001 + i - firstSlot, myMenu);
- guiMenu::itemRefresh(nullptr, 1001 + i - firstSlot, myMenu);
- }
- }
- }
- } else {
- // Else firstSlot < _GM(thumbIndex)
- // Dump Out all thumbnails in slots which don't overlap
- startIndex = imath_max(firstSlot + 10, _GM(thumbIndex));
- endIndex = imath_min(_GM(thumbIndex) + 9, 98);
- for (i = startIndex; i <= endIndex; i++) {
- UnloadThumbNail(i);
- }
-
- // Load in all thumbnails missing thumbnails
- startIndex = firstSlot;
- endIndex = imath_min(firstSlot + 9, _GM(thumbIndex) - 1);
- for (i = startIndex; i <= endIndex; i++) {
- if (_GM(slotInUse)[i]) {
- if (!LoadThumbNail(i)) {
- _GM(slotInUse)[i] = false;
- menuItemButton::disableButton(nullptr, 1001 + i - firstSlot, myMenu);
- guiMenu::itemRefresh(nullptr, 1001 + i - firstSlot, myMenu);
- }
- }
- }
- }
-
- // Set the var
- _GM(thumbIndex) = firstSlot;
-}
-
-void SetFirstSlot(int32 firstSlot, guiMenu *myMenu) {
- menuItemButton *myButton;
- int32 i;
-
- if (!myMenu) {
- return;
- }
-
- // Ensure firstSlot is in a valid range
- firstSlot = imath_max(imath_min(firstSlot, 89), 0);
-
- // Change the prompt and special tag of each of the slot buttons
- for (i = 0; i < MAX_SLOTS_SHOWN; i++) {
- myButton = (menuItemButton *)guiMenu::getItem(i + 1001, myMenu);
-
- myButton->prompt = _GM(slotTitles)[firstSlot + i];
- if (_GM(currMenuIsSave) || _GM(slotInUse)[firstSlot + i]) {
- myButton->itemFlags = menuItemButton::BTN_STATE_NORM;
- } else {
- myButton->itemFlags = menuItemButton::BTN_STATE_GREY;
- }
-
- myButton->specialTag = firstSlot + i + 1;
- guiMenu::itemRefresh(myButton, i + 1001, myMenu);
- }
-}
-
//----------------------------- MENU DIALOG FUNCTIONS ---------------------------------//
bool guiMenu::initialize(RGB8 *myPalette) {
@@ -1891,7 +1794,7 @@ bool menuItemVSlider::handler(menuItemVSlider *myItem, int32 eventType, int32 ev
}
redrawItem = true;
if (!_GM(currMenuIsSave)) {
- UpdateThumbNails(_GM(firstSlotIndex), (guiMenu *)myItem->myMenu);
+ SaveLoadMenuBase::updateThumbnails(_GM(firstSlotIndex), (guiMenu *)myItem->myMenu);
}
break;
diff --git a/engines/m4/gui/gui_menu_items.h b/engines/m4/gui/gui_menu_items.h
index 1c7fc33bed4..8d2917ca2f4 100644
--- a/engines/m4/gui/gui_menu_items.h
+++ b/engines/m4/gui/gui_menu_items.h
@@ -131,23 +131,54 @@ enum options_menu_sprites {
OM_SCROLLING_OFF_BTN_NORM = 11,
OM_SCROLLING_OFF_BTN_OVER = 12,
OM_SCROLLING_OFF_BTN_PRESS = 10,
-#if 0
- OM_SLIDER_BTN_NORM,
- OM_SLIDER_BTN_OVER,
- OM_SLIDER_BTN_PRESS,
- OM_SLIDER_BAR,
+ OM_TOTAL_SPRITES = 14
+};
- OM_DONE_BTN_GREY,
- OM_DONE_BTN_NORM,
- OM_DONE_BTN_OVER,
- OM_DONE_BTN_PRESS,
+enum save_load_menu_sprites {
+ SL_DIALOG_BOX,
- OM_CANCEL_BTN_NORM,
- OM_CANCEL_BTN_OVER,
- OM_CANCEL_BTN_PRESS,
+#ifdef TODO
+ SL_SAVE_BTN_GREY,
+ SL_SAVE_BTN_NORM,
+ SL_SAVE_BTN_OVER,
+ SL_SAVE_BTN_PRESS,
+
+ SL_LOAD_BTN_GREY,
+ SL_LOAD_BTN_NORM,
+ SL_LOAD_BTN_OVER,
+ SL_LOAD_BTN_PRESS,
+
+ SL_CANCEL_BTN_NORM,
+ SL_CANCEL_BTN_OVER,
+ SL_CANCEL_BTN_PRESS,
+
+ SL_UP_BTN_GREY,
+ SL_UP_BTN_NORM,
+ SL_UP_BTN_OVER,
+ SL_UP_BTN_PRESS,
+
+ SL_DOWN_BTN_GREY,
+ SL_DOWN_BTN_NORM,
+ SL_DOWN_BTN_OVER,
+ SL_DOWN_BTN_PRESS,
+
+ SL_SAVE_LABEL,
+ SL_LOAD_LABEL,
+
+ SL_SLIDER_BTN_NORM,
+ SL_SLIDER_BTN_OVER,
+ SL_SLIDER_BTN_PRESS,
+
+ SL_LINE_NORM,
+ SL_LINE_OVER,
+ SL_LINE_PRESS,
+
+ SL_SCROLL_BAR,
#endif
- OM_TOTAL_SPRITES = 14
+ SL_EMPTY_THUMB = 25,
+
+ SL_TOTAL_SPRITES = 26
};
} // namespace GUI
@@ -439,10 +470,6 @@ struct MenuGlobals {
};
extern void gui_DrawSprite(Sprite *mySprite, Buffer *myBuff, int32 x, int32 y);
-extern bool LoadThumbNail(int32 slotNum);
-extern void UnloadThumbNail(int32 slotNum);
-extern void UpdateThumbNails(int32 firstSlot, guiMenu *myMenu);
-extern void SetFirstSlot(int32 firstSlot, guiMenu *myMenu);
//======================================
//
diff --git a/engines/m4/module.mk b/engines/m4/module.mk
index 1a2e482cd78..8a79b3545c5 100644
--- a/engines/m4/module.mk
+++ b/engines/m4/module.mk
@@ -48,6 +48,7 @@ MODULE_OBJS = \
graphics/gr_surface.o \
graphics/krn_pal.o \
graphics/rend.o \
+ gui/game_menu.o \
gui/gui_buffer.o \
gui/gui_cheapo.o \
gui/gui_dialog.o \
diff --git a/engines/m4/riddle/gui/game_menu.cpp b/engines/m4/riddle/gui/game_menu.cpp
index 54519378947..b369a474965 100644
--- a/engines/m4/riddle/gui/game_menu.cpp
+++ b/engines/m4/riddle/gui/game_menu.cpp
@@ -197,11 +197,21 @@ void GameMenu::cbOptions(void *, void *) {
}
void GameMenu::cbSave(void *, void *) {
- // TODO
+ destroyGameMenu();
+ guiMenu::shutdown(true);
+ _GM(buttonClosesDialog) = true;
+
+ // Create the save game menu
+ g_engine->showSaveScreen();
}
void GameMenu::cbLoad(void *, void *) {
- // TODO
+ destroyGameMenu();
+ guiMenu::shutdown(true);
+ _GM(buttonClosesDialog) = true;
+
+ // Create the save game menu
+ g_engine->showLoadScreen(M4Engine::kLoadFromGameDialog);
}
/*-------------------- OPTIONS MENU --------------------*/
@@ -294,6 +304,248 @@ void OptionsMenu::cbSetMidi(M4::GUI::menuItemHSlider *myItem, M4::GUI::guiMenu *
midi_set_overall_volume(myItem->percent);
}
+/*------------------- SAVE/LOAD METHODS ------------------*/
+
+#define SAVE_LOAD_MENU_X 42
+#define SAVE_LOAD_MENU_Y 155
+
+#define SL_TAG_SAVE_LABEL 1
+#define SL_TAG_LOAD_LABEL 2
+#define SL_LABEL_X 111
+#define SL_LABEL_Y 2
+#define SL_LABEL_W 110
+#define SL_LABEL_H 17
+
+#define SL_TAG_THUMBNAIL 5
+#define SL_THUMBNAIL_X 333
+#define SL_THUMBNAIL_Y 5
+#define SL_THUMBNAIL_W 213
+#define SL_THUMBNAIL_H 160
+
+#define SL_TAG_SAVE 100
+#define SL_TAG_LOAD 101
+#define SL_SAVELOAD_X 10
+#define SL_SAVELOAD_Y 74
+#define SL_SAVELOAD_W 26
+#define SL_SAVELOAD_H 26
+
+#define SL_TAG_CANCEL 102
+#define SL_CANCEL_X 10
+#define SL_CANCEL_Y 122
+#define SL_CANCEL_W 26
+#define SL_CANCEL_H 26
+
+#define SL_TAG_VSLIDER 103
+#define SL_SLIDER_X 305
+#define SL_SLIDER_Y 21
+#define SL_SLIDER_W 20
+#define SL_SLIDER_H 140
+
+#define SL_SCROLL_FIELD_X 46
+#define SL_SCROLL_FIELD_Y 21
+#define SL_SCROLL_LINE_W 258
+#define SL_SCROLL_LINE_H 14
+#define SL_SCROLL_FIELD_W 257
+#define SL_SCROLL_FIELD_H 139
+
+void SaveLoadMenu::show(RGB8 *myPalette, bool saveMenu) {
+ ItemHandlerFunction i_handler;
+ bool buttonGreyed;
+
+ if (!_G(menuSystemInitialized))
+ guiMenu::initialize(myPalette);
+
+ // Keep the memory tidy
+ PurgeMem();
+ CompactMem();
+
+ // Load in the game menu sprites
+ if (!guiMenu::loadSprites("slmenu", SL_TOTAL_SPRITES)) {
+ return;
+ }
+
+ // Initialize some global vars
+ _GM(firstSlotIndex) = 0;
+ _GM(slotSelected) = -1;
+ _GM(saveLoadThumbNail) = nullptr;
+ _GM(thumbIndex) = 100;
+ _GM(currMenuIsSave) = saveMenu;
+
+ _GM(slMenu) = guiMenu::create(_GM(menuSprites)[SL_DIALOG_BOX], SAVE_LOAD_MENU_X, SAVE_LOAD_MENU_Y,
+ MENU_DEPTH | SF_GET_ALL | SF_BLOCK_ALL | SF_IMMOVABLE);
+ if (!_GM(slMenu)) {
+ return;
+ }
+
+ if (_GM(currMenuIsSave)) {
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_SAVE_LABEL, SL_LABEL_X, SL_LABEL_Y,
+ SL_LABEL_W, SL_LABEL_H);
+ menuItemButton::add(_GM(slMenu), SL_TAG_SAVE, SL_SAVELOAD_X, SL_SAVELOAD_Y,
+ SL_SAVELOAD_W, SL_SAVELOAD_H, (CALLBACK)cbSave,
+ menuItemButton::BTN_TYPE_SL_SAVE, true);
+ } else {
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_LOAD_LABEL, SL_LABEL_X, SL_LABEL_Y,
+ SL_LABEL_W, SL_LABEL_H);
+ menuItemButton::add(_GM(slMenu), SL_TAG_LOAD, SL_SAVELOAD_X, SL_SAVELOAD_Y,
+ SL_SAVELOAD_W, SL_SAVELOAD_H, (CALLBACK)cbSave,
+ menuItemButton::BTN_TYPE_SL_SAVE, true);
+ }
+
+ menuItemButton::add(_GM(slMenu), SL_TAG_CANCEL, SL_CANCEL_X, SL_CANCEL_Y, SL_CANCEL_W, SL_CANCEL_H,
+ (CALLBACK)cbCancel, menuItemButton::BTN_TYPE_SL_CANCEL);
+
+ menuItemVSlider::add(_GM(slMenu), SL_TAG_VSLIDER, SL_SLIDER_X, SL_SLIDER_Y, SL_SLIDER_W, SL_SLIDER_H,
+ 0, (CALLBACK)cbVSlider);
+
+ initializeSlotTables();
+
+ if (_GM(currMenuIsSave)) {
+ buttonGreyed = false;
+ i_handler = (ItemHandlerFunction)menuItemButton::handler;
+ } else {
+ buttonGreyed = true;
+ i_handler = (ItemHandlerFunction)load_Handler;
+ }
+
+ for (int32 i = 0; i < MAX_SLOTS_SHOWN; i++) {
+ menuItemButton::add(_GM(slMenu), 1001 + i,
+ SL_SCROLL_FIELD_X, SL_SCROLL_FIELD_Y + i * SL_SCROLL_LINE_H,
+ SL_SCROLL_LINE_W, SL_SCROLL_LINE_H,
+ (CALLBACK)cbSlot, menuItemButton::BTN_TYPE_SL_TEXT,
+ buttonGreyed && (!_GM(slotInUse)[i]), true,
+ _GM(slotTitles)[i], i_handler);
+ }
+
+ if (_GM(currMenuIsSave)) {
+ // Create thumbnails. One in the original game format for displaying,
+ // and the other in the ScummVM format for actually using in the save files
+ _GM(saveLoadThumbNail) = menu_CreateThumbnail(&_GM(sizeofThumbData));
+ _GM(_thumbnail).free();
+ Graphics::createThumbnail(_GM(_thumbnail));
+
+ } else {
+ updateThumbnails(0, _GM(slMenu));
+ _GM(saveLoadThumbNail) = _GM(menuSprites)[SL_EMPTY_THUMB];
+ }
+
+ menuItemMsg::msgAdd(_GM(slMenu), SL_TAG_THUMBNAIL, SL_THUMBNAIL_X, SL_THUMBNAIL_Y, SL_THUMBNAIL_W, SL_THUMBNAIL_H, false);
+
+ if (_GM(currMenuIsSave)) {
+ //<return> - if a slot has been selected, saves the game
+ //<esc> - cancels and returns to the game menu
+ guiMenu::configure(_GM(slMenu), (CALLBACK)cbSave, (CALLBACK)cbCancel);
+ } else {
+ //<return> - if a slot has been selected, loads the selected game
+ //<esc> - cancels and returns to the game menu
+ guiMenu::configure(_GM(slMenu), (CALLBACK)cbLoad, (CALLBACK)cbCancel);
+ }
+
+ vmng_screen_show((void *)_GM(slMenu));
+ LockMouseSprite(0);
+}
+
+void SaveLoadMenu::destroyMenu(bool saveMenu) {
+ int32 i;
+
+ if (!_GM(slMenu)) {
+ return;
+ }
+
+ // Determine whether the screen was the SAVE or the LOAD menu
+ if (saveMenu) {
+ // If SAVE, there should be a thumbnail to unload
+ if (_GM(saveLoadThumbNail)) {
+ DisposeHandle(_GM(saveLoadThumbNail)->sourceHandle);
+ mem_free(_GM(saveLoadThumbNail));
+ _GM(saveLoadThumbNail) = nullptr;
+ }
+ } else {
+ // Else there may be up to 10 somewhere in the list to be unloaded
+ for (i = 0; i < MAX_SLOTS; i++) {
+ unloadThumbnail(i);
+ }
+ _GM(saveLoadThumbNail) = nullptr;
+ }
+
+ // Destroy the screen
+ vmng_screen_dispose(_GM(slMenu));
+ guiMenu::destroy(_GM(slMenu));
+
+ // Unload the save/load menu sprites
+ guiMenu::unloadSprites();
+}
+
+bool SaveLoadMenu::load_Handler(M4::GUI::menuItemButton *myItem, int32 eventType, int32 event, int32 x, int32 y, void **currItem) {
+ bool handled;
+
+ // Handle the event just like any other button
+ handled = menuItemButton::handler(myItem, eventType, event, x, y, currItem);
+
+ // If we've selected a slot, we want the thumbNail to remain on the menu permanently
+ if (_GM(slotSelected) >= 0) {
+ return handled;
+ }
+
+ // But if the event moved the mouse, we want to display the correct thumbNail;
+ if ((eventType == EVENT_MOUSE) && ((event == _ME_move) || (event == _ME_L_drag) || (event == _ME_L_release) ||
+ (event == _ME_doubleclick_drag) || (event == _ME_doubleclick_release))) {
+
+ // Get the button
+ if (!myItem)
+ return handled;
+
+ // This determines that we are over the button
+ if ((myItem->itemFlags == menuItemButton::BTN_STATE_OVER) || (myItem->itemFlags == menuItemButton::BTN_STATE_PRESS)) {
+ // See if the current _GM(saveLoadThumbNail) is pointing to the correct sprite
+ if (_GM(saveLoadThumbNail) != _GM(thumbNails)[myItem->specialTag - 1]) {
+ _GM(saveLoadThumbNail) = _GM(thumbNails)[myItem->specialTag - 1];
+ guiMenu::itemRefresh(nullptr, SL_TAG_THUMBNAIL, (guiMenu *)myItem->myMenu);
+ }
+ }
+
+ // Else we must determine whether the thumbnail needs to be replaced with the empty thumbnail.
+ else {
+
+ // If the mouse has moved outside of the entire range of all 10 buttons,
+ //or it is over a button which is not hilited it is to be removed.
+ if (menuItem::cursorInsideItem(myItem, x, y)
+ || (x < SL_SCROLL_FIELD_X)
+ || (x > SL_SCROLL_FIELD_X + SL_SCROLL_FIELD_W)
+ || (y < SL_SCROLL_FIELD_Y)
+ || (y > SL_SCROLL_FIELD_Y + SL_SCROLL_FIELD_H)) {
+
+ // Remove the thumbnail
+ if (_GM(saveLoadThumbNail)) {
+ _GM(saveLoadThumbNail) = _GM(menuSprites)[SL_EMPTY_THUMB];
+ guiMenu::itemRefresh(nullptr, SL_TAG_THUMBNAIL, (guiMenu *)myItem->myMenu);
+ }
+ }
+ }
+ }
+
+ return handled;
+}
+
+void SaveLoadMenu::cbCancel(void *, void *) {
+
+}
+
+void SaveLoadMenu::cbSave(void *, void *) {
+
+}
+
+void SaveLoadMenu::cbLoad(void *, void *) {
+
+}
+
+void SaveLoadMenu::cbSlot(void *, void *) {
+
+}
+
+void SaveLoadMenu::cbVSlider(void *, void *) {
+
+}
+
/*-------------------- ACCESS METHODS --------------------*/
void CreateGameMenu(RGB8 *myPalette) {
@@ -305,6 +557,43 @@ void CreateGameMenu(RGB8 *myPalette) {
GameMenu::show(myPalette);
}
+
+void CreateF2SaveMenu(RGB8 *myPalette) {
+ if ((!player_commands_allowed()) || (!INTERFACE_VISIBLE) ||
+ _G(pal_fade_in_progress) || _G(menuSystemInitialized)) {
+ return;
+ }
+
+ _GM(saveLoadFromHotkey) = true;
+ _GM(gameMenuFromMain) = false;
+ SaveLoadMenu::show(myPalette, true);
+}
+
+void CreateLoadMenu(RGB8 *myPalette) {
+ _GM(saveLoadFromHotkey) = false;
+ SaveLoadMenu::show(myPalette, false);
+}
+
+void CreateLoadMenuFromMain(RGB8 *myPalette) {
+ if (_G(pal_fade_in_progress) || _G(menuSystemInitialized)) {
+ return;
+ }
+
+ _GM(saveLoadFromHotkey) = true;
+ _GM(gameMenuFromMain) = true;
+ SaveLoadMenu::show(myPalette, false);
+}
+
+void CreateF3LoadMenu(RGB8 *myPalette) {
+ if ((!player_commands_allowed()) || (!INTERFACE_VISIBLE) ||
+ _G(pal_fade_in_progress) || _G(menuSystemInitialized)) {
+ return;
+ }
+
+ _GM(saveLoadFromHotkey) = true;
+ _GM(gameMenuFromMain) = false;
+ SaveLoadMenu::show(myPalette, false);
+}
} // namespace GUI
} // namespace Riddle
} // namespace M4
diff --git a/engines/m4/riddle/gui/game_menu.h b/engines/m4/riddle/gui/game_menu.h
index 64d1af006d9..72c88f0aaa2 100644
--- a/engines/m4/riddle/gui/game_menu.h
+++ b/engines/m4/riddle/gui/game_menu.h
@@ -24,6 +24,7 @@
#define M4_RIDDLE_GUI_GAME_MENU_H
#include "m4/gui/gui_menu_items.h"
+#include "m4/gui/game_menu.h"
namespace M4 {
namespace Riddle {
@@ -55,7 +56,27 @@ public:
static void show();
};
+class SaveLoadMenu : public M4::GUI::SaveLoadMenuBase {
+private:
+ static void destroyMenu(bool saveMenu);
+ static bool load_Handler(M4::GUI::menuItemButton *myItem, int32 eventType,
+ int32 event, int32 x, int32 y, void **currItem);
+ static void cbCancel(void *, void *);
+ static void cbSave(void *, void *);
+ static void cbLoad(void *, void *);
+ static void cbSlot(void *, void *);
+ static void cbVSlider(void *, void *);
+public:
+ static void show(RGB8 *myPalette, bool saveMenu);
+};
+
extern void CreateGameMenu(RGB8 *myPalette);
+extern void CreateF2SaveMenu(RGB8 *myPalette);
+extern void CreateLoadMenu(RGB8 *myPalette);
+extern void CreateF3LoadMenu(RGB8 *myPalette);
+// Routines used by the main menu
+void CreateLoadMenuFromMain(RGB8 *myPalette);
+void CreateGameMenuFromMain(RGB8 *myPalette);
} // namespace GUI
} // namespace Riddle
diff --git a/engines/m4/riddle/riddle.cpp b/engines/m4/riddle/riddle.cpp
index 779fa6e8fa2..a948f50d9ca 100644
--- a/engines/m4/riddle/riddle.cpp
+++ b/engines/m4/riddle/riddle.cpp
@@ -20,6 +20,7 @@
*/
#include "common/debug.h"
+#include "m4/riddle/gui/game_menu.h"
#include "m4/riddle/riddle.h"
#include "m4/riddle/triggers.h"
#include "m4/riddle/console.h"
@@ -64,6 +65,32 @@ void RiddleEngine::syncFlags(Common::Serializer &s) {
g_vars->_flags.sync(s);
}
+void RiddleEngine::showSaveScreen() {
+ if (_useOriginalSaveLoad) {
+ GUI::CreateF2SaveMenu(_G(master_palette));
+ } else {
+ M4Engine::showSaveScreen();
+ }
+}
+
+void RiddleEngine::showLoadScreen(LoadDialogSource source) {
+ if (_useOriginalSaveLoad) {
+ switch (source) {
+ case kLoadFromMainMenu:
+ GUI::CreateLoadMenuFromMain(_G(master_palette));
+ break;
+ case kLoadFromGameDialog:
+ GUI::CreateLoadMenu(_G(master_palette));
+ break;
+ case kLoadFromHotkey:
+ GUI::CreateF3LoadMenu(_G(master_palette));
+ break;
+ }
+ } else {
+ M4Engine::showLoadScreen(source);
+ }
+}
+
void RiddleEngine::global_daemon() {
_G(i_just_hyperwalked) = false;
diff --git a/engines/m4/riddle/riddle.h b/engines/m4/riddle/riddle.h
index 7d39d8b7a4b..70b6e23c2b4 100644
--- a/engines/m4/riddle/riddle.h
+++ b/engines/m4/riddle/riddle.h
@@ -88,6 +88,8 @@ public:
void showEngineInfo() override;
void syncFlags(Common::Serializer &s) override;
+ void showSaveScreen() override;
+ void showLoadScreen(LoadDialogSource source) override;
void global_daemon() override;
void global_parser() override;
More information about the Scummvm-git-logs
mailing list