Improved the functionality of ElevatorsFile to allow to change the FRM images of the elevator panel and create new elevator types (from Mr.Stalin)

This commit is contained in:
NovaRain
2018-12-31 10:05:59 +08:00
parent 7b92d0f939
commit d89603e56d
3 changed files with 94 additions and 44 deletions
+23 -3
View File
@@ -1,11 +1,12 @@
;Controls the elevators ;Controls the elevators
;Image must match up with the image of an existing elevator ;Image must match up with the image of an existing elevator (can be overrided in sfall 4.1.4 or newer)
;Make sure you specify the correct number of exit targets ;Make sure you specify the correct number of exit targets
;The maximum number of elevators is currently capped at 50 ;The maximum number of elevators is currently capped at 50
;Use the line number (0-indexed) of the corresponding FRM in intrface.lst to set the appearance of the elevator
;Override elevator 0 ;Override elevator 0
[000] [0]
;This elevator uses the frm of the original forth elevator ;This elevator will use the settings of the original forth elevator
Image=4 Image=4
;Set up the first exit point ;Set up the first exit point
@@ -24,3 +25,22 @@ Elevation3=0
Tile3=12944 Tile3=12944
;No forth exit point ;No forth exit point
;Override FRM images of elevator 0. Set ButtonsFrm to -1 to use default buttons from MainFrm
MainFrm=143
ButtonsFrm=-1
;An example of a new elevator
[24]
;Set Image to 24 to create a new elevator type (0-23 are the original elevator types)
Image=24
;Set the number of buttons
ButtonCount=3
;Set up the appearance of the elevator
MainFrm=148
ButtonsFrm=151
;Set up the exit points for all three buttons (see examples above)
+6
View File
@@ -260,6 +260,12 @@ struct ElevatorExit {
long tile; long tile;
}; };
#pragma pack(1)
struct ElevatorFrms {
DWORD main;
DWORD buttons;
};
#pragma pack(1) #pragma pack(1)
struct FrmFile { struct FrmFile {
long id; //0x00 long id; //0x00
+60 -36
View File
@@ -27,70 +27,74 @@ namespace sfall
static const int exitsPerElevator = 4; static const int exitsPerElevator = 4;
static const int vanillaElevatorCount = 24; static const int vanillaElevatorCount = 24;
static const int elevatorCount = 50; static const int elevatorCount = 50;
static char elevFile[MAX_PATH];
static fo::ElevatorExit elevatorExits[elevatorCount][exitsPerElevator]; static char elevFile[MAX_PATH] = ".\\";
static DWORD menus[elevatorCount];
static DWORD elevatorType[elevatorCount];
static fo::ElevatorExit elevatorExits[elevatorCount][exitsPerElevator]; // _retvals
static fo::ElevatorFrms elevatorsFrms[elevatorCount]; // _intotal
static DWORD elevatorsBtnCount[elevatorCount]; // _btncount
static void __declspec(naked) GetMenuHook() { static void __declspec(naked) GetMenuHook() {
__asm { __asm {
push ebx; lea edx, elevatorType;
lea ebx, menus;
shl eax, 2; shl eax, 2;
mov eax, [ebx+eax]; mov eax, [edx + eax];
call fo::funcoffs::elevator_start_; jmp fo::funcoffs::elevator_start_;
pop ebx;
ret;
} }
} }
static void __declspec(naked) UnknownHook() { static void __declspec(naked) CheckHotKeysHook() {
__asm { __asm {
cmp eax, vanillaElevatorCount;
jge skip; // skip hotkeys data
push ebx; push ebx;
lea ebx, menus; lea ebx, elevatorType;
shl eax, 2; shl eax, 2;
mov eax, [ebx+eax]; mov eax, [ebx + eax];
call fo::funcoffs::Check4Keys_; call fo::funcoffs::Check4Keys_;
pop ebx; pop ebx;
ret; retn;
skip:
xor eax, eax;
retn;
} }
} }
/*
static void __declspec(naked) UnknownHook2() { static void __declspec(naked) UnknownHook2() {
__asm { __asm {
push ebx; lea edx, elevatorType;
lea ebx, menus;
shl eax, 2; shl eax, 2;
mov eax, [ebx+eax]; mov eax, [edx + eax];
call fo::funcoffs::elevator_end_; jmp fo::funcoffs::elevator_end_;
pop ebx;
ret;
} }
} }
*/
static void __declspec(naked) GetNumButtonsHook1() { static void __declspec(naked) GetNumButtonsHook1() {
__asm { __asm {
lea esi, menus; lea esi, elevatorType;
mov eax, [esi+edi*4]; mov eax, [esi + edi * 4];
mov eax, [FO_VAR_btncnt + eax*4]; mov eax, [elevatorsBtnCount + eax * 4];
retn; retn;
} }
} }
static void __declspec(naked) GetNumButtonsHook2() { static void __declspec(naked) GetNumButtonsHook2() {
__asm { __asm {
lea edx, menus; lea edx, elevatorType;
mov eax, [edx+edi*4]; mov eax, [edx + edi * 4];
mov eax, [FO_VAR_btncnt + eax*4]; mov eax, [elevatorsBtnCount + eax * 4];
retn; retn;
} }
} }
static void __declspec(naked) GetNumButtonsHook3() { static void __declspec(naked) GetNumButtonsHook3() {
__asm { __asm {
lea eax, menus; lea eax, elevatorType;
mov eax, [eax+edi*4]; mov eax, [eax + edi * 4];
mov eax, [FO_VAR_btncnt+eax*4]; mov eax, [elevatorsBtnCount + eax * 4];
retn; retn;
} }
} }
@@ -98,13 +102,28 @@ static void __declspec(naked) GetNumButtonsHook3() {
void ResetElevators() { void ResetElevators() {
memcpy(elevatorExits, fo::var::retvals, sizeof(fo::ElevatorExit) * vanillaElevatorCount * exitsPerElevator); memcpy(elevatorExits, fo::var::retvals, sizeof(fo::ElevatorExit) * vanillaElevatorCount * exitsPerElevator);
memset(&elevatorExits[vanillaElevatorCount], 0, sizeof(fo::ElevatorExit) * (elevatorCount - vanillaElevatorCount) * exitsPerElevator); memset(&elevatorExits[vanillaElevatorCount], 0, sizeof(fo::ElevatorExit) * (elevatorCount - vanillaElevatorCount) * exitsPerElevator);
for (int i = 0; i < vanillaElevatorCount; i++) menus[i] = i;
for (int i = vanillaElevatorCount; i < elevatorCount; i++) menus[i] = 0; memcpy(elevatorsFrms, (void*)FO_VAR_intotal, sizeof(fo::ElevatorFrms) * vanillaElevatorCount);
memset(&elevatorsFrms[vanillaElevatorCount], 0, sizeof(fo::ElevatorFrms) * (elevatorCount - vanillaElevatorCount));
memcpy(elevatorsBtnCount, (void*)FO_VAR_btncnt, sizeof(DWORD) * vanillaElevatorCount);
for (int i = 0; i < vanillaElevatorCount; i++) elevatorType[i] = i;
for (int i = vanillaElevatorCount; i < elevatorCount; i++) elevatorType[i] = 0;
char section[4]; char section[4];
if (elevFile) { if (elevFile) {
for (int i = 0; i < elevatorCount; i++) { for (int i = 0; i < elevatorCount; i++) {
_itoa_s(i, section, 10); _itoa_s(i, section, 10);
menus[i] = GetPrivateProfileIntA(section, "Image", menus[i], elevFile); int type = GetPrivateProfileIntA(section, "Image", elevatorType[i], elevFile);
elevatorType[i] = min(type, elevatorCount - 1);
if (i >= vanillaElevatorCount) {
int cBtn = GetPrivateProfileIntA(section, "ButtonCount", 2, elevFile);
if (cBtn > exitsPerElevator) cBtn = exitsPerElevator;
elevatorsBtnCount[i] = max(2, cBtn);
}
elevatorsFrms[i].main = GetPrivateProfileIntA(section, "MainFrm", elevatorsFrms[i].main, elevFile);
elevatorsFrms[i].buttons = GetPrivateProfileIntA(section, "ButtonsFrm", elevatorsFrms[i].buttons, elevFile);
char setting[32]; char setting[32];
for (int j = 0; j < exitsPerElevator; j++) { for (int j = 0; j < exitsPerElevator; j++) {
sprintf_s(setting, "ID%d", j + 1); sprintf_s(setting, "ID%d", j + 1);
@@ -119,21 +138,26 @@ void ResetElevators() {
} }
void ElevatorsInit(const char* file) { void ElevatorsInit(const char* file) {
strcpy_s(elevFile, ".\\");
strcat_s(elevFile, file); strcat_s(elevFile, file);
HookCall(0x43EF83, GetMenuHook); HookCall(0x43EF83, GetMenuHook);
HookCall(0x43F141, UnknownHook); HookCall(0x43F141, CheckHotKeysHook);
HookCall(0x43F2D2, UnknownHook2); //HookCall(0x43F2D2, UnknownHook2); // unused
SafeWrite8(0x43EF76, (BYTE)elevatorCount); SafeWrite8(0x43EF76, (BYTE)elevatorCount);
SafeWrite32(0x43EFA4, (DWORD)elevatorExits); SafeWrite32(0x43EFA4, (DWORD)elevatorExits);
SafeWrite32(0x43EFB9, (DWORD)elevatorExits); SafeWrite32(0x43EFB9, (DWORD)elevatorExits);
SafeWrite32(0x43EFEA, (DWORD)&elevatorExits[0][0].tile);
SafeWrite32(0x43F2FC, (DWORD)elevatorExits); SafeWrite32(0x43F2FC, (DWORD)elevatorExits);
SafeWrite32(0x43F309, (DWORD)&elevatorExits[0][0].elevation); SafeWrite32(0x43EFEA, (DWORD)&elevatorExits[0][0].tile);
SafeWrite32(0x43F315, (DWORD)&elevatorExits[0][0].tile); SafeWrite32(0x43F315, (DWORD)&elevatorExits[0][0].tile);
SafeWrite32(0x43F309, (DWORD)&elevatorExits[0][0].elevation);
SafeWrite32(0x43F438, (DWORD)&elevatorsFrms[0].main);
SafeWrite32(0x43F475, (DWORD)&elevatorsFrms[0].buttons);
// _btncnt
SafeWrite32(0x43F65E, (DWORD)elevatorsBtnCount);
SafeWrite32(0x43F6BB, (DWORD)elevatorsBtnCount);
MakeCall(0x43F05D, GetNumButtonsHook1, 2); MakeCall(0x43F05D, GetNumButtonsHook1, 2);
MakeCall(0x43F184, GetNumButtonsHook2, 2); MakeCall(0x43F184, GetNumButtonsHook2, 2);
MakeCall(0x43F1E4, GetNumButtonsHook3, 2); MakeCall(0x43F1E4, GetNumButtonsHook3, 2);