mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added WorldMapInterface option to expand the world map interface.
Fixed the up/down button images in the world map interface. Added loading sfall.dat resource file, which contains new WorldMap.frm and AppHeroWin.frm.
This commit is contained in:
@@ -196,6 +196,11 @@ WorldMapEncounterRate=5
|
||||
;Setting this greater than 17 requires a replacement background FRM, or you'll get glitched graphics
|
||||
WorldMapSlots=0
|
||||
|
||||
;Set to 1 to use the expanded world map interface
|
||||
;Requires High Resolution Patch v4.1.8 and a new worldmap.frm file in art\intrface\ (included in sfall.dat)
|
||||
;The fullscreen resolution of hi-res patch must be set to at least 890x720
|
||||
WorldMapInterface=0
|
||||
|
||||
;To start a new game somewhere other than artemple.map, uncomment the next line and set it to the map you want to load
|
||||
;StartingMap=
|
||||
|
||||
|
||||
Binary file not shown.
@@ -325,6 +325,9 @@ static void RemoveSavFiles() {
|
||||
}
|
||||
|
||||
void LoadOrder::init() {
|
||||
// Load external sfall resource file
|
||||
patchFiles.push_back("sfall.dat");
|
||||
|
||||
GetExtraPatches();
|
||||
|
||||
if (GetConfigInt("Misc", "DataLoadOrderPatch", 0)) {
|
||||
|
||||
@@ -651,6 +651,243 @@ long __fastcall Worldmap::GetRestMapLevel(long elev, int mapId) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////// WORLDMAP INTERFACE //////////////////////////////
|
||||
|
||||
#define WMAP_WIN_WIDTH (890)
|
||||
#define WMAP_WIN_HEIGHT (720)
|
||||
#define WMAP_TOWN_BUTTONS (15)
|
||||
|
||||
static DWORD wmTownMapSubButtonIds[WMAP_TOWN_BUTTONS + 1]; // replace _wmTownMapSubButtonIds (index 0 - unused element)
|
||||
|
||||
// Window width
|
||||
static const DWORD wmWinWidth[] = {
|
||||
// wmInterfaceInit_
|
||||
0x4C239E, 0x4C247A,
|
||||
// wmInterfaceRefresh_
|
||||
0x4C38EA, 0x4C3978,
|
||||
// wmInterfaceDrawCircleOverlay_
|
||||
0x4C3FCA, 0x4C408E,
|
||||
// wmRefreshInterfaceDial_
|
||||
0x4C5757,
|
||||
// wmInterfaceRefreshDate_
|
||||
0x4C3D0A, 0x4C3D79, 0x4C3DBB, 0x4C3E87, 0x4C3E1F,
|
||||
// wmRefreshTabs_
|
||||
0x4C52BF, 0x4C53F5, 0x4C55A5, 0x4C557E, 0x4C54B2, 0x4C53E8,
|
||||
// wmRefreshInterfaceOverlay_
|
||||
0x4C50FD, 0x4C51CF, 0x4C51F8, 0x4C517F,
|
||||
// wmInterfaceRefreshCarFuel_
|
||||
0x4C528B, 0x4C529F, 0x4C52AA,
|
||||
// wmInterfaceDrawSubTileList_
|
||||
0x4C41C1, 0x4C41D2,
|
||||
// wmTownMapRefresh_
|
||||
0x4C4BDF,
|
||||
// wmDrawCursorStopped_
|
||||
0x4C42EE, 0x4C43C8, 0x4C445F,
|
||||
// wmTownMapRefresh_
|
||||
0x4C4BDF
|
||||
};
|
||||
|
||||
// Right limit of the viewport (450)
|
||||
static const DWORD wmViewportEndRight[] = {
|
||||
0x4C3937, 0x4C393E, 0x4C39BB, 0x4C3B2F, 0x4C3B36, 0x4C3C4B, // wmInterfaceRefresh_
|
||||
0x4C4288, 0x4C436A, 0x4C4409, // wmDrawCursorStopped_
|
||||
0x4BC91F, // wmWorldMap_init_
|
||||
0x4C44B4, // wmCursorIsVisible_
|
||||
};
|
||||
|
||||
// Bottom limit of viewport (443)
|
||||
static const DWORD wmViewportEndBottom[] = {
|
||||
0x4C3963, 0x4C38D7, 0x4C39DA, 0x4C3B62, 0x4C3AE7, 0x4C3C74, // wmInterfaceRefresh_
|
||||
0x4C429A, 0x4C4378, 0x4C4413, // wmDrawCursorStopped_
|
||||
0x4BC947, // wmWorldMap_init_
|
||||
0x4C44BE, // wmCursorIsVisible_
|
||||
};
|
||||
|
||||
static const DWORD wmInterfaceInit_Ret = 0x4C23A7;
|
||||
static void __declspec(naked) wmInterfaceInit_hack() {
|
||||
__asm {
|
||||
push eax;
|
||||
mov eax, 640 - WMAP_WIN_WIDTH;
|
||||
mov edx, 480 - WMAP_WIN_HEIGHT;
|
||||
jmp wmInterfaceInit_Ret;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmInterfaceDrawSubTileList_hack() {
|
||||
__asm {
|
||||
mov edx, [esp + 0x10 - 0x10 + 4];
|
||||
imul edx, WMAP_WIN_WIDTH;
|
||||
add edx, ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmInterfaceDrawCircleOverlay_hack() {
|
||||
__asm {
|
||||
mov eax, ecx;
|
||||
imul eax, WMAP_WIN_WIDTH;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmDrawCursorStopped_hack0() {
|
||||
__asm {
|
||||
mov ebx, ecx;
|
||||
imul ebx, WMAP_WIN_WIDTH;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmDrawCursorStopped_hack1() {
|
||||
__asm {
|
||||
mov ebx, eax;
|
||||
imul ebx, WMAP_WIN_WIDTH;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmRefreshTabs_hook() {
|
||||
__asm {
|
||||
mov eax, edx;
|
||||
imul eax, WMAP_WIN_WIDTH;
|
||||
sub ebp, eax;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmTownMapRefresh_hook() {
|
||||
__asm {
|
||||
cmp edx, 700; //_wmTownWidth
|
||||
jl scale;
|
||||
cmp ebx, 682; //_wmTownHeight
|
||||
jl scale;
|
||||
jmp fo::funcoffs::buf_to_buf_;
|
||||
scale:
|
||||
push WMAP_WIN_WIDTH; // to_width
|
||||
push 684; // height
|
||||
push 702; // width
|
||||
push eax; // to_buff
|
||||
mov ecx, edx; // from_width
|
||||
mov eax, esi; // from_buff
|
||||
call fo::funcoffs::cscale_;
|
||||
retn; // don't delete
|
||||
}
|
||||
}
|
||||
|
||||
void WorldmapViewportPatch() {
|
||||
// Fix images for up/down buttons
|
||||
SafeWrite32(0x4C2C0A, 199); // index of UPARWOFF.FRM
|
||||
SafeWrite8(0x4C2C7C, 0x43); // dec ebx > inc ebx
|
||||
SafeWrite32(0x4C2C92, 181); // index of DNARWOFF.FRM
|
||||
SafeWrite8(0x4C2D04, 0x46); // dec esi > inc esi
|
||||
|
||||
// check enabled HRP
|
||||
if (*(DWORD*)0x4E4480 == 0x278805C7 || GetConfigInt("Misc", "WorldMapInterface", 0) == 0 || GetPrivateProfileIntA("MAIN", "SCR_HEIGHT", 0, ".\\f2_res.ini") < WMAP_WIN_HEIGHT) return;
|
||||
dlog("Applying world map interface patch.", DL_INIT);
|
||||
|
||||
mapSlotsScrollMax -= 216;
|
||||
if (mapSlotsScrollMax < 0) mapSlotsScrollMax = 0;
|
||||
|
||||
SafeWriteBatch<DWORD>(135, {0x4C23BD, 0x4C2408}); // use unused worldmap.frm for new world map interface (wmInterfaceInit_)
|
||||
|
||||
// x/y axis offset of interface window
|
||||
MakeJump(0x4C23A2, wmInterfaceInit_hack);
|
||||
// size of the created window/buffer
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_WIDTH, wmWinWidth); // width
|
||||
SafeWrite32(0x4C238B, WMAP_WIN_HEIGHT); // height (wmInterfaceInit_)
|
||||
|
||||
// Mouse scrolling area (wmMouseBkProc_)
|
||||
SafeWrite32(0x4C331D, WMAP_WIN_WIDTH - 1);
|
||||
SafeWrite32(0x4C3337, WMAP_WIN_HEIGHT - 1);
|
||||
|
||||
MakeCall(0x4C41A4, wmInterfaceDrawSubTileList_hack); // 640 * 21
|
||||
MakeCall(0x4C4082, wmInterfaceDrawCircleOverlay_hack); // 640 * y
|
||||
MakeCall(0x4C4452, wmDrawCursorStopped_hack1);
|
||||
MakeCalls(wmDrawCursorStopped_hack0, {0x4C43BB, 0x4C42E1});
|
||||
MakeCall(0x4C5325, wmRefreshTabs_hook);
|
||||
HookCall(0x4C4BFF, wmTownMapRefresh_hook);
|
||||
|
||||
// up/down buttons of the location list (wmInterfaceInit_)
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_WIDTH - (640 - 480), { // offset by X (480)
|
||||
0x4C2D3C,
|
||||
0x4C2D7A
|
||||
});
|
||||
|
||||
// town/world button (wmInterfaceInit_)
|
||||
SafeWrite32(0x4C2B9B, WMAP_WIN_HEIGHT - (480 - 439)); // offset by Y (439)
|
||||
SafeWrite32(0x4C2BAF, WMAP_WIN_WIDTH - (640 - 519)); // offset by X (508)
|
||||
|
||||
// viewport size for mouse click
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_HEIGHT - (480 - 465), { // height/offset by Y (465 - 21 = 444 (443))
|
||||
0x4C0154, 0x4C02BA, // wmWorldMap_
|
||||
0x4C3A47, // wmInterfaceRefresh_
|
||||
});
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_WIDTH - (640 - 472), { // width/offset by X (472 - 22 = 450)
|
||||
0x4C0159, 0x4C02BF, // wmWorldMap_
|
||||
0x4C3A3A, // wmInterfaceRefresh_
|
||||
0x4C417C, 0x4C4184 // wmInterfaceDrawSubTileList_
|
||||
});
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_HEIGHT - (480 - 464), { // width/offset by X (464)
|
||||
0x4C3FED, // wmInterfaceDrawCircleOverlay_
|
||||
0x4C4157, 0x4C415F, // wmInterfaceDrawSubTileList_
|
||||
});
|
||||
// right limit of the viewport (450)
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_WIDTH - (640 - 450), wmViewportEndRight); // 890 - 190 = 700 + 22 = 722
|
||||
// bottom limit of the viewport (443)
|
||||
SafeWriteBatch<DWORD>(WMAP_WIN_HEIGHT - (480 - 443), wmViewportEndBottom); // 720 - 37 = 683 + 21 = 704
|
||||
|
||||
// Night/Day frm (wmRefreshInterfaceDial_)
|
||||
SafeWrite32(0x4C577F, WMAP_WIN_WIDTH - (640 - 532)); // X offset (532)
|
||||
SafeWrite32(0x4C575D, (WMAP_WIN_WIDTH * 49) - ((640 * 49) - 31252)); // start offset in buffer (31252 / 640 = 49)
|
||||
|
||||
// Date/Time frm
|
||||
SafeWrite32(0x4C3EC7, WMAP_WIN_WIDTH - (640 - 487)); // start offset by X (487)
|
||||
SafeWrite32(0x4C3ED1, WMAP_WIN_WIDTH - (640 - 630)); // end offset by X (630)
|
||||
SafeWrite32(0x4C3D10, (WMAP_WIN_WIDTH * 13) - ((640 * 13) - 8167)); // 8167 start offset in buffer (12327)
|
||||
SafeWrite32(0x4C3DC1, WMAP_WIN_WIDTH + (666 - 640)); // 666
|
||||
|
||||
// WMCARMVE/WMGLOBE/WMSCREEN frms (wmRefreshInterfaceOverlay_)
|
||||
SafeWrite32(0x4C51D5, (WMAP_WIN_WIDTH * 577) - ((640 * 337) - 215554)); // start offset for image WMCARMVE
|
||||
SafeWrite32(0x4C5184, (WMAP_WIN_WIDTH * 571) - ((640 * 331) - 211695)); // start offset for image WMGLOBE
|
||||
SafeWrite32(0x4C51FD, (WMAP_WIN_WIDTH * 571) - ((640 * 331) - 211699)); // start offset for image WMSCREEN
|
||||
// Car gas indicator
|
||||
SafeWrite32(0x4C527E, (WMAP_WIN_WIDTH * 580) - ((640 * 340) - 217460)); // start offset in buffer (217460 / 640 = 340 + (720 - 480) = 580 Y-axes)
|
||||
|
||||
// WMTABS.frm
|
||||
SafeWriteBatch<DWORD>((WMAP_WIN_WIDTH * 136) - ((640 * 136) - 86901), {
|
||||
0x4C52C4, 0x4C55AA // wmRefreshTabs_
|
||||
});
|
||||
SafeWrite32(0x4C52FF, (WMAP_WIN_WIDTH * 139) - ((640 * 139) - 88850)); // wmRefreshTabs_
|
||||
SafeWriteBatch<DWORD>((WMAP_WIN_WIDTH * 27), { // start offset in buffer (17280)
|
||||
0x4C54DE, 0x4C5424 // wmRefreshTabs_
|
||||
});
|
||||
SafeWrite32(0x4C52E5, WMAP_WIN_HEIGHT - 480 + 178 - 19); // height (178)
|
||||
|
||||
// Buttons of cities, now 15
|
||||
SafeWrite32(0x4C2BD9, WMAP_WIN_WIDTH - (640 - 508)); // offset of the buttons by X (508)
|
||||
SafeWriteBatch<BYTE>(WMAP_TOWN_BUTTONS * 4, {0x4C2C01, 0x4C21B6, 0x4C2289}); // number of buttons (28 = 7 * 4)
|
||||
int btn = (mapSlotsScrollLimit) ? WMAP_TOWN_BUTTONS : WMAP_TOWN_BUTTONS + 1;
|
||||
SafeWrite32(0x4C21FD, 27 * btn); // scroll limit for buttons
|
||||
// number of city labels (6) wmRefreshTabs_
|
||||
SafeWriteBatch<BYTE>(WMAP_TOWN_BUTTONS - 1, {0x4C54F6, 0x4C542A});
|
||||
SafeWrite8(0x4C555E, 0);
|
||||
SafeWrite32(0x4C0348, 350 + WMAP_TOWN_BUTTONS); // buttons input code (wmWorldMap_)
|
||||
|
||||
SafeWrite32(0x4C2BFB, (DWORD)&wmTownMapSubButtonIds[0]); // wmInterfaceInit_
|
||||
SafeWriteBatch<DWORD>((DWORD)&wmTownMapSubButtonIds[1], {
|
||||
// 0x4C22DD, 0x4C230A, // wmInterfaceScrollTabsUpdate_ (never called)
|
||||
0x4C227B, // wmInterfaceScrollTabsStop_
|
||||
0x4C21A8 // wmInterfaceScrollTabsStart_
|
||||
});
|
||||
// WMTBEDGE.frm (wmRefreshTabs_)
|
||||
BlockCall(0x4C55BF);
|
||||
|
||||
// Town map frm images (wmTownMapRefresh_)
|
||||
SafeWrite32(0x4C4BE4, (WMAP_WIN_WIDTH * 21) + 22); // start offset for town map image (13462)
|
||||
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
void Worldmap::init() {
|
||||
PathfinderFixInit();
|
||||
StartingStatePatches();
|
||||
@@ -660,6 +897,7 @@ void Worldmap::init() {
|
||||
WorldmapFpsPatch();
|
||||
WorldMapFontPatch();
|
||||
PipBoyAutomapsPatch();
|
||||
WorldmapViewportPatch(); // must be located after WorldMapSlots patch
|
||||
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
SetCarInterfaceArt(433); // set index
|
||||
|
||||
Reference in New Issue
Block a user