diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cff9a9..278f36e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ add_executable(OpenJazz src/logo.h src/loop.h src/main.cpp + src/menu/filemenu.cpp src/menu/gamemenu.cpp src/menu/mainmenu.cpp src/menu/menu.cpp diff --git a/Makefile b/Makefile index 449456f..f51d021 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,7 @@ OJOBJS = \ src/level/level.o \ src/level/movable.o \ src/main.o \ + src/menu/filemenu.o \ src/menu/gamemenu.o \ src/menu/mainmenu.o \ src/menu/menu.o \ diff --git a/res/unix/OpenJazz.6.adoc b/res/unix/OpenJazz.6.adoc index 27413b7..c1f90bf 100644 --- a/res/unix/OpenJazz.6.adoc +++ b/res/unix/OpenJazz.6.adoc @@ -135,6 +135,7 @@ Additional coding (logger, CLI, ...) + Modernizing + UI improvements Lars Persson (anotherguest):: Movie playback fixes +CYBERDEViL:: Savegame algorithm Scott Smith (Pickle):: GP2X/WIZ, Canoo, Pandora ports Przemysław Buczkowski (przemub):: Android, Haiku ports Matthieu Milan (usineur):: PSVita port @@ -145,4 +146,3 @@ Ricerind:: Mac OS X port Slaanesh:: GP32 port GPF:: Dreamcast port Cameron Cawley (ccawley2011):: RISC OS, SDL2 port -CYBERDEViL:: Savegame support diff --git a/src/OpenJazz.h b/src/OpenJazz.h index 4183a9b..b96d05b 100644 --- a/src/OpenJazz.h +++ b/src/OpenJazz.h @@ -58,8 +58,7 @@ #define E_DEMOTYPE -(0x12) #define E_FILE -(0x11) #define E_VIDEO -(0x10) -#define E_SAVE -(0x0F) -#define E_LOAD -(0x0E) +#define E_LOAD -(0x0F) #define E_RETURN -(0x02) #define E_QUIT -(0x01) diff --git a/src/level/level.cpp b/src/level/level.cpp index 23f4b99..7e8560d 100644 --- a/src/level/level.cpp +++ b/src/level/level.cpp @@ -278,9 +278,9 @@ void Level::drawOverlay (unsigned char bg, bool menu, int option, for (count = 0; count < 6; count++) { - // Gray out Save and Load options, as they are unimplemented + // Gray out options in multiplayer and Save (unimplemented) - if (count == 2 || count == 3) { + if ((multiplayer && count >= 2 && count <= 4) || count == 2) { drawRect((canvasW >> 2) - 4, (canvasH >> 1) + (count << 4) - 48, 136, 15, textPalIndex); @@ -326,13 +326,35 @@ int Level::select (bool& menu, int option) { case 2: // Save - //return E_SAVE; - // FALLTHROUGH + if (!multiplayer) { + + int ret = fileMenu.main(true, false); + if (ret == E_QUIT) return E_QUIT; + if (ret >= 0) { + // TODO + } + + // Restore level palette + video.setPalette(palette); + + } + + break; case 3: // Load - //return E_LOAD; - playSound(SE::WAIT); + if (!multiplayer) { + + int ret = fileMenu.main(false, false); + if (ret == E_QUIT) return E_QUIT; + if (ret >= 0) { + return E_LOAD; // TODO + } + + // Restore level palette + video.setPalette(palette); + + } break; diff --git a/src/level/level.h b/src/level/level.h index 834fd16..6f54d7a 100644 --- a/src/level/level.h +++ b/src/level/level.h @@ -89,6 +89,7 @@ class Level { private: const char* menuOptions[6]; SetupMenu setupMenu; ///< Setup menu to run on the player's command + FileMenu fileMenu; ///< Save and Load menus to run on the player's command int select (bool& menu, int option); diff --git a/src/menu/filemenu.cpp b/src/menu/filemenu.cpp new file mode 100644 index 0000000..b90f6c8 --- /dev/null +++ b/src/menu/filemenu.cpp @@ -0,0 +1,117 @@ + +/** + * + * @file filemenu.cpp + * + * Part of the OpenJazz project + * + * @par Licence: + * Copyright (c) + * + * OpenJazz is distributed under the terms of + * the GNU General Public License, version 2.0 + * + * @par Description: + * Deals with the running of the menus used save and load a game. + * + */ + +#include "menu.h" + +#include "io/controls.h" +#include "io/gfx/font.h" +#include "io/gfx/video.h" +#include "io/sound.h" +#include "jj1/save/jj1save.h" +#include "loop.h" +#include "util.h" +#include + +int FileMenu::main (bool forSaving, bool showCustom) { + int x, y; + int chosen = 0; + std::unique_ptr save[4]; + int options = showCustom ? 5 : 4; + + // load save games + + char* fileName = createString("SAVE.0"); + for (int i = 0; i < 4; i++) { + save[i] = std::make_unique(fileName); + fileName[5]++; + } + delete[] fileName; + + const char *loadGameOptions[5] = {save[0]->name, save[1]->name, save[2]->name, save[3]->name, "custom"}; + + auto fileChosen = [&]() -> bool { + if (chosen < 4 && !forSaving) { + if(!save[chosen]->valid) { + playSound(SE::WAIT); + + return false; + } + } + + playConfirmSound(); + return true; + }; + + video.setPalette(menuPalette); + + while (true) { + + if (loop(NORMAL_LOOP) == E_QUIT) return E_QUIT; + + if (controls.release(C_ESCAPE)) return E_RETURN; + + if (controls.release(C_UP)) chosen = (chosen + options - 1) % options; + + if (controls.release(C_DOWN)) chosen = (chosen + 1) % options; + + if (controls.release(C_ENTER)) { + if(fileChosen()) + return chosen; + } + + if (controls.getCursor(x, y)) { + + if ((x < 100) && (y >= canvasH - 12) && controls.wasCursorReleased()) return E_RETURN; + + x -= canvasW >> 2; + y -= (canvasH >> 1) - (options << 3); + + if ((x >= 0) && (x < 256) && (y >= 0) && (y < (options << 4))) { + + chosen = y >> 4; + + if (controls.wasCursorReleased()) { + if(fileChosen()) + return chosen; + } + } + + } + + SDL_Delay(T_MENU_FRAME); + + video.clearScreen(0); + + fontmn2->showString(forSaving ? "SAVE GAME" : "LOAD GAME", canvasW >> 2, (canvasH >> 1) - (options << 3) - 32); + + for (int i = 0; i < options; i++) { + + if (i == chosen) fontmn2->mapPalette(240, 8, 114, 16); + + fontmn2->showString(loadGameOptions[i], canvasW >> 2, + (canvasH >> 1) + (i << 4) - (options << 3)); + + if (i == chosen) fontmn2->restorePalette(); + + } + + showEscString(); + } + + return E_NONE; +} diff --git a/src/menu/gamemenu.cpp b/src/menu/gamemenu.cpp index 723a4d7..4238839 100644 --- a/src/menu/gamemenu.cpp +++ b/src/menu/gamemenu.cpp @@ -34,7 +34,8 @@ #include "jj1/save/jj1save.h" #include "loop.h" #include "util.h" - +#include "io/log.h" +#include /** * Create the game menu. @@ -87,6 +88,8 @@ GameMenu::GameMenu (File *file) { } + fileMenu = new FileMenu(); + } @@ -99,6 +102,8 @@ GameMenu::~GameMenu () { SDL_FreeSurface(difficultyScreen); + delete fileMenu; + } @@ -158,6 +163,11 @@ int GameMenu::playNewGame (GameModeType mode, char* firstLevel) { switch (ret) { + case E_LOAD: + + LOG_WARN("Implement in-game loading"); + return E_LOAD; + case E_QUIT: return E_QUIT; @@ -282,48 +292,37 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum) * @return Error code */ int GameMenu::loadGame () { - int ret, option = 0; - JJ1Save* save[4]; - char* fileName; - - // load save games - - fileName = createString("SAVE.0"); - for (int i = 0; i < 4; i++) { - save[i] = new JJ1Save(fileName); - fileName[5]++; - } - delete[] fileName; - - const char *loadGameOptions[5] = {save[0]->name, save[1]->name, save[2]->name, save[3]->name, "custom"}; + int ret; while (true) { - video.setPalette(menuPalette); - - ret = generic(loadGameOptions, 5, option); - if (ret < 0) break; - - if (option == 4) { - if (loadGameCustom() == E_QUIT) ret = E_QUIT; - if (ret < 0) break; + ret = fileMenu->main(false, true); + if (ret < 0) return ret; + + if (ret == 4) { + while (true) { + ret = loadGameCustom(); + if (ret == E_QUIT) return E_QUIT; // return to main menu + if (ret <= 0) break; // return to load menu + } } else { - if(save[option]->valid) { - char* firstLevel = createFileName("LEVEL", save[option]->level, save[option]->planet); - difficulty = save[option]->difficulty; + // load save game + char* fileName = createString("SAVE.0"); + fileName[5] += ret; + auto save = std::make_unique(fileName); + delete[] fileName; + + if(save->valid) { + char* firstLevel = createFileName("LEVEL", save->level, save->planet); + difficulty = save->difficulty; ret = playNewGame(M_SINGLE, firstLevel); delete[] firstLevel; + } else + ret = E_NONE; - break; - } else { - playSound(SE::WAIT); - } + break; } } - for (int i = 0; i < 4; i++) { - delete save[i]; - } - return ret; } @@ -335,8 +334,6 @@ int GameMenu::loadGame () { */ int GameMenu::loadGameCustom () { - /// @todo Actual loading of saved games - int option, worldNum, levelNum, x, y; worldNum = levelNum = option = 0; diff --git a/src/menu/menu.h b/src/menu/menu.h index e267f5b..478bc70 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -52,6 +52,14 @@ class Menu { }; +/// Saving and loading menu +class FileMenu : public Menu { + + public: + int main (bool forSaving, bool showCustom); + +}; + /// New game menus class GameMenu : public Menu { @@ -62,6 +70,7 @@ class GameMenu : public Menu { SDL_Color greyPalette[MAX_PALETTE_COLORS]; ///< Greyed-out episode selection palette int episodes; ///< Number of episodes unsigned char difficulty; ///< Difficulty setting (0 = easy, 1 = medium, 2 = hard, 3 = turbo (hard in JJ2 levels)) + FileMenu* fileMenu; ///< Load menu int playNewGame (GameModeType mode, char* firstLevel); int newGameDifficulty (GameModeType mode, char* firstLevel);