From f5060c301b5853424abe110905454bc051751cd8 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Wed, 3 Aug 2022 12:34:13 +0300 Subject: [PATCH] Add elevators improvements (#29) --- src/elevator.cc | 80 ++++++++++++++++++++++++++++++++++++++++++--- src/elevator.h | 2 ++ src/map.cc | 4 +++ src/sfall_config.cc | 1 + src/sfall_config.h | 1 + 5 files changed, 83 insertions(+), 5 deletions(-) diff --git a/src/elevator.cc b/src/elevator.cc index e7e49a4..770f772 100644 --- a/src/elevator.cc +++ b/src/elevator.cc @@ -12,11 +12,14 @@ #include "map.h" #include "pipboy.h" #include "scripts.h" +#include "sfall_config.h" #include "window_manager.h" #include #include +#include + // The maximum number of elevator levels. #define ELEVATOR_LEVEL_MAX (4) @@ -26,6 +29,10 @@ // (instead of using NULL). #define ELEVATOR_BACKGROUND_NULL ((unsigned char*)(-1)) +// Max number of elevators that can be loaded from elevators.ini. This limit is +// emposed by Sfall. +#define ELEVATORS_MAX 50 + typedef enum ElevatorFrm { ELEVATOR_FRM_BUTTON_DOWN, ELEVATOR_FRM_BUTTON_UP, @@ -56,7 +63,7 @@ static const int gElevatorFrmIds[ELEVATOR_FRM_COUNT] = { }; // 0x43E95C -static const ElevatorBackground gElevatorBackgrounds[ELEVATOR_COUNT] = { +static ElevatorBackground gElevatorBackgrounds[ELEVATORS_MAX] = { { 143, -1 }, { 143, 150 }, { 144, -1 }, @@ -86,7 +93,7 @@ static const ElevatorBackground gElevatorBackgrounds[ELEVATOR_COUNT] = { // Number of levels for eleveators. // // 0x43EA1C -static const int gElevatorLevels[ELEVATOR_COUNT] = { +static int gElevatorLevels[ELEVATORS_MAX] = { 4, 2, 3, @@ -114,7 +121,7 @@ static const int gElevatorLevels[ELEVATOR_COUNT] = { }; // 0x43EA7C -static const ElevatorDescription gElevatorDescriptions[ELEVATOR_COUNT][ELEVATOR_LEVEL_MAX] = { +static ElevatorDescription gElevatorDescriptions[ELEVATORS_MAX][ELEVATOR_LEVEL_MAX] = { { { 14, 0, 18940 }, { 14, 1, 18936 }, @@ -264,7 +271,7 @@ static const ElevatorDescription gElevatorDescriptions[ELEVATOR_COUNT][ELEVATOR_ // NOTE: These values are also used as key bindings. // // 0x43EEFC -static const char gElevatorLevelLabels[ELEVATOR_COUNT][ELEVATOR_LEVEL_MAX] = { +static char gElevatorLevelLabels[ELEVATORS_MAX][ELEVATOR_LEVEL_MAX] = { { '1', '2', '3', '4' }, { 'G', '1', '\0', '\0' }, { '1', '2', '3', '\0' }, @@ -360,10 +367,11 @@ static unsigned char* gElevatorPanelFrmData; // 0x43EF5C int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tilePtr) { - if (elevator < 0 || elevator >= ELEVATOR_COUNT) { + if (elevator < 0 || elevator >= ELEVATORS_MAX) { return -1; } + // SFALL if (elevatorWindowInit(elevator) == -1) { return -1; } @@ -681,3 +689,65 @@ static int elevatorGetLevelFromKeyCode(int elevator, int keyCode) } return 0; } + +void elevatorsInit() +{ + char* elevatorsFileName; + configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_ELEVATORS_FILE_KEY, &elevatorsFileName); + if (elevatorsFileName != NULL && *elevatorsFileName == '\0') { + elevatorsFileName = NULL; + } + + if (elevatorsFileName != NULL) { + Config elevatorsConfig; + if (configInit(&elevatorsConfig)) { + if (configRead(&elevatorsConfig, elevatorsFileName, false)) { + char sectionKey[4]; + char key[32]; + for (int index = 0; index < ELEVATORS_MAX; index++) { + sprintf(sectionKey, "%d", index); + + if (index >= ELEVATOR_COUNT) { + int levels = 0; + configGetInt(&elevatorsConfig, sectionKey, "ButtonCount", &levels); + gElevatorLevels[index] = std::clamp(levels, 2, ELEVATOR_LEVEL_MAX); + } + + configGetInt(&elevatorsConfig, sectionKey, "MainFrm", &(gElevatorBackgrounds[index].backgroundFrmId)); + configGetInt(&elevatorsConfig, sectionKey, "ButtonsFrm", &(gElevatorBackgrounds[index].panelFrmId)); + + for (int level = 0; level < ELEVATOR_LEVEL_MAX; level++) { + sprintf(key, "ID%d", level + 1); + configGetInt(&elevatorsConfig, sectionKey, key, &(gElevatorDescriptions[index][level].map)); + + sprintf(key, "Elevation%d", level + 1); + configGetInt(&elevatorsConfig, sectionKey, key, &(gElevatorDescriptions[index][level].elevation)); + + sprintf(key, "Tile%d", level + 1); + configGetInt(&elevatorsConfig, sectionKey, key, &(gElevatorDescriptions[index][level].tile)); + } + } + + // NOTE: Sfall implementation is slightly different. It uses one + // loop and stores `type` value in a separate lookup table. This + // value is then used in the certain places to remap from + // requested elevator to the new one. + for (int index = 0; index < ELEVATORS_MAX; index++) { + sprintf(sectionKey, "%d", index); + + int type; + if (configGetInt(&elevatorsConfig, sectionKey, "Image", &type)) { + type = std::clamp(type, 0, ELEVATORS_MAX - 1); + if (index != type) { + memcpy(&(gElevatorBackgrounds[index]), &(gElevatorBackgrounds[type]), sizeof(*gElevatorBackgrounds)); + memcpy(&(gElevatorLevels[index]), &(gElevatorLevels[type]), sizeof(*gElevatorLevels)); + memcpy(&(gElevatorLevelLabels[index]), &(gElevatorLevelLabels[type]), sizeof(*gElevatorLevelLabels)); + } + } + } + } + + configFree(&elevatorsConfig); + } + } +} diff --git a/src/elevator.h b/src/elevator.h index f659b13..ba1985c 100644 --- a/src/elevator.h +++ b/src/elevator.h @@ -20,4 +20,6 @@ typedef enum Elevator { int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tilePtr); +void elevatorsInit(); + #endif /* ELEVATOR_H */ diff --git a/src/map.cc b/src/map.cc index 66cba32..9a5ff53 100644 --- a/src/map.cc +++ b/src/map.cc @@ -11,6 +11,7 @@ #include "cycle.h" #include "debug.h" #include "draw.h" +#include "elevator.h" #include "game.h" #include "game_config.h" #include "game_mouse.h" @@ -215,6 +216,9 @@ int isoInit() debugPrint(">intface_init\t\t"); + // SFALL + elevatorsInit(); + mapMakeMapsDirectory(); gEnteringElevation = -1; diff --git a/src/sfall_config.cc b/src/sfall_config.cc index eb78e2c..57b0e65 100644 --- a/src/sfall_config.cc +++ b/src/sfall_config.cc @@ -38,6 +38,7 @@ bool sfallConfigInit(int argc, char** argv) configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_OVERRIDE_CRITICALS_FILE_KEY, ""); configSetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_REMOVE_CRITICALS_TIME_LIMITS_KEY, false); configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BOOKS_FILE_KEY, ""); + configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_ELEVATORS_FILE_KEY, ""); char path[COMPAT_MAX_PATH]; char* executable = argv[0]; diff --git a/src/sfall_config.h b/src/sfall_config.h index 5458a55..de8266d 100644 --- a/src/sfall_config.h +++ b/src/sfall_config.h @@ -26,6 +26,7 @@ #define SFALL_CONFIG_OVERRIDE_CRITICALS_FILE_KEY "OverrideCriticalFile" #define SFALL_CONFIG_REMOVE_CRITICALS_TIME_LIMITS_KEY "RemoveCriticalTimelimits" #define SFALL_CONFIG_BOOKS_FILE_KEY "BooksFile" +#define SFALL_CONFIG_ELEVATORS_FILE_KEY "ElevatorsFile" extern bool gSfallConfigInitialized; extern Config gSfallConfig;