#include "elevator.h" #include "core.h" #include "cycle.h" #include "debug.h" #include "draw.h" #include "game_mouse.h" #include "game_sound.h" #include "map.h" #include "pipboy.h" #include "scripts.h" #include "window_manager.h" #include #include // 0x43E950 const int gElevatorFrmIds[ELEVATOR_FRM_COUNT] = { 141, // ebut_in.frm - map elevator screen 142, // ebut_out.frm - map elevator screen 149, // gaj000.frm - map elevator screen }; // 0x43E95C const ElevatorBackground gElevatorBackgrounds[ELEVATOR_COUNT] = { { 143, -1 }, { 143, 150 }, { 144, -1 }, { 144, 145 }, { 146, -1 }, { 146, 147 }, { 146, -1 }, { 146, 151 }, { 148, -1 }, { 146, -1 }, { 146, -1 }, { 146, 147 }, { 388, -1 }, { 143, 150 }, { 148, -1 }, { 148, -1 }, { 148, -1 }, { 143, 150 }, { 143, 150 }, { 143, 150 }, { 143, 150 }, { 143, 150 }, { 143, 150 }, { 143, 150 }, }; // Number of levels for eleveators. // // 0x43EA1C const int gElevatorLevels[ELEVATOR_COUNT] = { 4, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 2, 4, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, }; // 0x43EA7C const ElevatorDescription gElevatorDescriptions[ELEVATOR_COUNT][ELEVATOR_LEVEL_MAX] = { { { 14, 0, 18940 }, { 14, 1, 18936 }, { 15, 0, 21340 }, { 15, 1, 21340 }, }, { { 13, 0, 20502 }, { 14, 0, 14912 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 33, 0, 12498 }, { 33, 1, 20094 }, { 34, 0, 17312 }, { 0, 0, -1 }, }, { { 34, 0, 16140 }, { 34, 1, 16140 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 49, 0, 14920 }, { 49, 1, 15120 }, { 50, 0, 12944 }, { 0, 0, -1 }, }, { { 50, 0, 24520 }, { 50, 1, 25316 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 42, 0, 22526 }, { 42, 1, 22526 }, { 42, 2, 22526 }, { 0, 0, -1 }, }, { { 42, 2, 14086 }, { 43, 0, 14086 }, { 43, 2, 14086 }, { 0, 0, -1 }, }, { { 40, 0, 14104 }, { 40, 1, 22504 }, { 40, 2, 17312 }, { 0, 0, -1 }, }, { { 9, 0, 13704 }, { 9, 1, 23302 }, { 9, 2, 17308 }, { 0, 0, -1 }, }, { { 28, 0, 19300 }, { 28, 1, 19300 }, { 28, 2, 20110 }, { 0, 0, -1 }, }, { { 28, 2, 20118 }, { 29, 0, 21710 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 28, 0, 20122 }, { 28, 1, 20124 }, { 28, 2, 20940 }, { 29, 0, 22540 }, }, { { 12, 1, 16052 }, { 12, 2, 14480 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 6, 0, 14104 }, { 6, 1, 22504 }, { 6, 2, 17312 }, { 0, 0, -1 }, }, { { 30, 0, 14104 }, { 30, 1, 22504 }, { 30, 2, 17312 }, { 0, 0, -1 }, }, { { 36, 0, 13704 }, { 36, 1, 23302 }, { 36, 2, 17308 }, { 0, 0, -1 }, }, { { 39, 0, 17285 }, { 36, 0, 19472 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 109, 2, 10701 }, { 109, 1, 10705 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 109, 2, 14697 }, { 109, 1, 15099 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 109, 2, 23877 }, { 109, 1, 25481 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 109, 2, 26130 }, { 109, 1, 24721 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 137, 0, 23953 }, { 148, 1, 16526 }, { 0, 0, -1 }, { 0, 0, -1 }, }, { { 62, 0, 13901 }, { 63, 1, 17923 }, { 0, 0, -1 }, { 0, 0, -1 }, }, }; // NOTE: These values are also used as key bindings. // // 0x43EEFC const char gElevatorLevelLabels[ELEVATOR_COUNT][ELEVATOR_LEVEL_MAX] = { { '1', '2', '3', '4' }, { 'G', '1', '\0', '\0' }, { '1', '2', '3', '\0' }, { '3', '4', '\0', '\0' }, { '1', '2', '3', '\0' }, { '3', '4', '\0', '\0' }, { '1', '2', '3', '\0' }, { '3', '4', '6', '\0' }, { '1', '2', '3', '\0' }, { '1', '2', '3', '\0' }, { '1', '2', '3', '\0' }, { '3', '4', '\0', '\0' }, { '1', '2', '3', '4' }, { '1', '2', '\0', '\0' }, { '1', '2', '3', '\0' }, { '1', '2', '3', '\0' }, { '1', '2', '3', '\0' }, { '1', '2', '\0', '\0' }, { '1', '2', '\0', '\0' }, { '1', '2', '\0', '\0' }, { '1', '2', '\0', '\0' }, { '1', '2', '\0', '\0' }, { '1', '2', '\0', '\0' }, { '1', '2', '\0', '\0' }, }; // 0x51862C const char* gElevatorSoundEffects[ELEVATOR_LEVEL_MAX - 1][ELEVATOR_LEVEL_MAX] = { { "ELV1_1", "ELV1_1", "ERROR", "ERROR", }, { "ELV1_2", "ELV1_2", "ELV1_1", "ERROR", }, { "ELV1_3", "ELV1_3", "ELV2_3", "ELV1_1", }, }; // 0x570A2C Size gElevatorFrmSizes[ELEVATOR_FRM_COUNT]; // 0x570A44 int gElevatorBackgroundFrmWidth; // 0x570A48 int gElevatorBackgroundFrmHeight; // 0x570A4C int gElevatorPanelFrmWidth; // 0x570A50 int gElevatorPanelFrmHeight; // 0x570A54 int gElevatorWindow; // 0x570A58 CacheEntry* gElevatorFrmHandles[ELEVATOR_FRM_COUNT]; // 0x570A64 CacheEntry* gElevatorBackgroundFrmHandle; // 0x570A68 CacheEntry* gElevatorPanelFrmHandle; // 0x570A6C unsigned char* gElevatorWindowBuffer; // 0x570A70 bool gElevatorWindowIsoWasEnabled; // 0x570A74 unsigned char* gElevatorFrmData[ELEVATOR_FRM_COUNT]; // 0x570A80 unsigned char* gElevatorBackgroundFrmData; // 0x570A84 unsigned char* gElevatorPanelFrmData; // Presents elevator dialog for player to pick a desired level. // // 0x43EF5C int elevatorSelectLevel(int elevator, int* mapPtr, int* elevationPtr, int* tilePtr) { if (elevator < 0 || elevator >= ELEVATOR_COUNT) { return -1; } if (elevatorWindowInit(elevator) == -1) { return -1; } const ElevatorDescription* elevatorDescription = gElevatorDescriptions[elevator]; int index; for (index = 0; index < ELEVATOR_LEVEL_MAX; index++) { if (elevatorDescription[index].map == *mapPtr) { break; } } if (index < ELEVATOR_LEVEL_MAX) { if (elevatorDescription[*elevationPtr + index].tile != -1) { *elevationPtr += index; } } if (elevator == ELEVATOR_SIERRA_2) { if (*elevationPtr <= 2) { *elevationPtr -= 2; } else { *elevationPtr -= 3; } } else if (elevator == ELEVATOR_MILITARY_BASE_LOWER) { if (*elevationPtr >= 2) { *elevationPtr -= 2; } } else if (elevator == ELEVATOR_MILITARY_BASE_UPPER && *elevationPtr == 4) { *elevationPtr -= 2; } if (*elevationPtr > 3) { *elevationPtr -= 3; } debugPrint("\n the start elev level %d\n", *elevationPtr); int v18 = (gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width * gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].height) / 13; float v42 = 12.0f / (float)(gElevatorLevels[elevator] - 1); blitBufferToBuffer( gElevatorFrmData[ELEVATOR_FRM_GAUGE] + v18 * (int)((float)(*elevationPtr) * v42), gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width, gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].height / 13, gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width, gElevatorWindowBuffer + gElevatorBackgroundFrmWidth * 41 + 121, gElevatorBackgroundFrmWidth); windowRefresh(gElevatorWindow); bool done = false; int keyCode; while (!done) { keyCode = _get_input(); if (keyCode == KEY_ESCAPE) { done = true; } if (keyCode >= 500 && keyCode < 504) { done = true; } if (keyCode > 0 && keyCode < 500) { int level = elevatorGetLevelFromKeyCode(elevator, keyCode); if (level != 0) { keyCode = 500 + level - 1; done = true; } } } if (keyCode != KEY_ESCAPE) { keyCode -= 500; if (*elevationPtr != keyCode) { float v43 = (float)(gElevatorLevels[elevator] - 1) / 12.0f; unsigned int delay = (unsigned int)(v43 * 276.92307); if (keyCode < *elevationPtr) { v43 = -v43; } int numberOfLevelsTravelled = keyCode - *elevationPtr; if (numberOfLevelsTravelled < 0) { numberOfLevelsTravelled = -numberOfLevelsTravelled; } soundPlayFile(gElevatorSoundEffects[gElevatorLevels[elevator] - 2][numberOfLevelsTravelled]); float v41 = (float)keyCode * v42; float v44 = (float)(*elevationPtr) * v42; do { unsigned int tick = _get_time(); v44 += v43; blitBufferToBuffer( gElevatorFrmData[ELEVATOR_FRM_GAUGE] + v18 * (int)v44, gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width, gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].height / 13, gElevatorFrmSizes[ELEVATOR_FRM_GAUGE].width, gElevatorWindowBuffer + gElevatorBackgroundFrmWidth * 41 + 121, gElevatorBackgroundFrmWidth); windowRefresh(gElevatorWindow); while (getTicksSince(tick) < delay) { } } while ((v43 <= 0.0 || v44 < v41) && (v43 > 0.0 || v44 > v41)); coreDelayProcessingEvents(200); } } elevatorWindowFree(); if (keyCode != KEY_ESCAPE) { const ElevatorDescription* description = &(elevatorDescription[keyCode]); *mapPtr = description->map; *elevationPtr = description->elevation; *tilePtr = description->tile; } return 0; } // 0x43F324 int elevatorWindowInit(int elevator) { gElevatorWindowIsoWasEnabled = isoDisable(); colorCycleDisable(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); gameMouseObjectsHide(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); scriptsDisable(); int index; for (index = 0; index < ELEVATOR_FRM_COUNT; index++) { int fid = buildFid(6, gElevatorFrmIds[index], 0, 0, 0); gElevatorFrmData[index] = artLockFrameDataReturningSize(fid, &(gElevatorFrmHandles[index]), &(gElevatorFrmSizes[index].width), &(gElevatorFrmSizes[index].height)); if (gElevatorFrmData[index] == NULL) { break; } } if (index != ELEVATOR_FRM_COUNT) { for (int reversedIndex = index - 1; reversedIndex >= 0; reversedIndex--) { artUnlock(gElevatorFrmHandles[reversedIndex]); } if (gElevatorWindowIsoWasEnabled) { isoEnable(); } colorCycleEnable(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); return -1; } gElevatorPanelFrmData = ELEVATOR_BACKGROUND_NULL; gElevatorBackgroundFrmData = ELEVATOR_BACKGROUND_NULL; const ElevatorBackground* elevatorBackground = &(gElevatorBackgrounds[elevator]); bool backgroundsLoaded = true; int backgroundFid = buildFid(6, elevatorBackground->backgroundFrmId, 0, 0, 0); gElevatorBackgroundFrmData = artLockFrameDataReturningSize(backgroundFid, &gElevatorBackgroundFrmHandle, &gElevatorBackgroundFrmWidth, &gElevatorBackgroundFrmHeight); if (gElevatorBackgroundFrmData != NULL) { if (elevatorBackground->panelFrmId != -1) { int panelFid = buildFid(6, elevatorBackground->panelFrmId, 0, 0, 0); gElevatorPanelFrmData = artLockFrameDataReturningSize(panelFid, &gElevatorPanelFrmHandle, &gElevatorPanelFrmWidth, &gElevatorPanelFrmHeight); if (gElevatorPanelFrmData == NULL) { gElevatorPanelFrmData = ELEVATOR_BACKGROUND_NULL; backgroundsLoaded = false; } } } else { gElevatorBackgroundFrmData = ELEVATOR_BACKGROUND_NULL; backgroundsLoaded = false; } if (!backgroundsLoaded) { if (gElevatorBackgroundFrmData != ELEVATOR_BACKGROUND_NULL) { artUnlock(gElevatorBackgroundFrmHandle); } if (gElevatorPanelFrmData != ELEVATOR_BACKGROUND_NULL) { artUnlock(gElevatorPanelFrmHandle); } for (int index = 0; index < ELEVATOR_FRM_COUNT; index++) { artUnlock(gElevatorFrmHandles[index]); } if (gElevatorWindowIsoWasEnabled) { isoEnable(); } colorCycleEnable(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); return -1; } gElevatorWindow = windowCreate( (640 - gElevatorBackgroundFrmWidth) / 2, (379 - gElevatorBackgroundFrmHeight) / 2, gElevatorBackgroundFrmWidth, gElevatorBackgroundFrmHeight, 256, WINDOW_FLAG_0x10 | WINDOW_FLAG_0x02); if (gElevatorWindow == -1) { if (gElevatorBackgroundFrmData != ELEVATOR_BACKGROUND_NULL) { artUnlock(gElevatorBackgroundFrmHandle); } if (gElevatorPanelFrmData != ELEVATOR_BACKGROUND_NULL) { artUnlock(gElevatorPanelFrmHandle); } for (int index = 0; index < ELEVATOR_FRM_COUNT; index++) { artUnlock(gElevatorFrmHandles[index]); } if (gElevatorWindowIsoWasEnabled) { isoEnable(); } colorCycleEnable(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); return -1; } gElevatorWindowBuffer = windowGetBuffer(gElevatorWindow); memcpy(gElevatorWindowBuffer, (unsigned char*)gElevatorBackgroundFrmData, gElevatorBackgroundFrmWidth * gElevatorBackgroundFrmHeight); if (gElevatorPanelFrmData != ELEVATOR_BACKGROUND_NULL) { blitBufferToBuffer((unsigned char*)gElevatorPanelFrmData, gElevatorPanelFrmWidth, gElevatorPanelFrmHeight, gElevatorPanelFrmWidth, gElevatorWindowBuffer + gElevatorBackgroundFrmWidth * (gElevatorBackgroundFrmHeight - gElevatorPanelFrmHeight), gElevatorBackgroundFrmWidth); } int y = 40; for (int level = 0; level < gElevatorLevels[elevator]; level++) { int btn = buttonCreate(gElevatorWindow, 13, y, gElevatorFrmSizes[ELEVATOR_FRM_BUTTON_DOWN].width, gElevatorFrmSizes[ELEVATOR_FRM_BUTTON_DOWN].height, -1, -1, -1, 500 + level, gElevatorFrmData[ELEVATOR_FRM_BUTTON_UP], gElevatorFrmData[ELEVATOR_FRM_BUTTON_DOWN], NULL, BUTTON_FLAG_TRANSPARENT); if (btn != -1) { buttonSetCallbacks(btn, _gsound_red_butt_press, NULL); } y += 60; } return 0; } // 0x43F6D0 void elevatorWindowFree() { windowDestroy(gElevatorWindow); if (gElevatorBackgroundFrmData != ELEVATOR_BACKGROUND_NULL) { artUnlock(gElevatorBackgroundFrmHandle); } if (gElevatorPanelFrmData != ELEVATOR_BACKGROUND_NULL) { artUnlock(gElevatorPanelFrmHandle); } for (int index = 0; index < ELEVATOR_FRM_COUNT; index++) { artUnlock(gElevatorFrmHandles[index]); } scriptsEnable(); if (gElevatorWindowIsoWasEnabled) { isoEnable(); } colorCycleEnable(); gameMouseSetCursor(MOUSE_CURSOR_ARROW); } // 0x43F73C int elevatorGetLevelFromKeyCode(int elevator, int keyCode) { // TODO: Check if result is really unused? toupper(keyCode); for (int index = 0; index < ELEVATOR_LEVEL_MAX; index++) { char c = gElevatorLevelLabels[elevator][index]; if (c == '\0') { break; } if (c == (char)(keyCode & 0xFF)) { return index + 1; } } return 0; }