From 17c73a81dacddbc4ceab01b6ba2fdf786849bda9 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 26 Oct 2021 09:02:32 +0800 Subject: [PATCH] Added ViewMap.cpp/h and EdgeBorder.cpp/h --- sfall/FalloutEngine/VariableOffsets.h | 2 + sfall/HRP/Init.cpp | 7 + sfall/HRP/MainMenu.cpp | 15 +- sfall/HRP/ViewMap/EdgeBorder.cpp | 258 ++++++++++++++++++++++++++ sfall/HRP/ViewMap/EdgeBorder.h | 18 ++ sfall/HRP/ViewMap/ViewMap.cpp | 66 +++++++ sfall/HRP/ViewMap/ViewMap.h | 24 +++ sfall/ddraw.vcxproj | 4 + sfall/ddraw.vcxproj.filters | 15 ++ 9 files changed, 402 insertions(+), 7 deletions(-) create mode 100644 sfall/HRP/ViewMap/EdgeBorder.cpp create mode 100644 sfall/HRP/ViewMap/EdgeBorder.h create mode 100644 sfall/HRP/ViewMap/ViewMap.cpp create mode 100644 sfall/HRP/ViewMap/ViewMap.h diff --git a/sfall/FalloutEngine/VariableOffsets.h b/sfall/FalloutEngine/VariableOffsets.h index bc7156f5..db56fcf9 100644 --- a/sfall/FalloutEngine/VariableOffsets.h +++ b/sfall/FalloutEngine/VariableOffsets.h @@ -29,6 +29,8 @@ #define FO_VAR_bottom_line 0x664524 #define FO_VAR_btable 0x59E944 #define FO_VAR_btncnt 0x43EA1C +#define FO_VAR_buf_length_2 0x66BE14 +#define FO_VAR_buf_width_2 0x66BE30 #define FO_VAR_button_down_data 0x519500 #define FO_VAR_button_up_data 0x5194FC #define FO_VAR_cap 0x518064 diff --git a/sfall/HRP/Init.cpp b/sfall/HRP/Init.cpp index 8d54bfd1..23359f40 100644 --- a/sfall/HRP/Init.cpp +++ b/sfall/HRP/Init.cpp @@ -8,6 +8,7 @@ #include "..\FalloutEngine\Fallout2.h" #include "..\Modules\LoadOrder.h" +#include "viewmap\ViewMap.h" #include "SplashScreen.h" #include "MainMenu.h" @@ -61,6 +62,11 @@ void HRP::init() { //END_SLIDE_SIZE //HELP_SCRN_SIZE + std::string x = IniReader::GetString("MAPS", "SCROLL_DIST_X", "480", 16, f2ResIni); + std::string y = IniReader::GetString("MAPS", "SCROLL_DIST_Y", "400", 16, f2ResIni); + ViewMap::SCROLL_DIST_X = (x == "HALF_SCRN") ? (SCR_WIDTH / 2) + 32 : std::atol(x.c_str()); + ViewMap::SCROLL_DIST_Y = (y == "HALF_SCRN") ? (SCR_HEIGHT / 2) + 24 : std::atol(y.c_str()); + // add before sfall.dat and after critter.dat LoadOrder::AddResourcePatches( IniReader::GetString("Main", "f2_res_dat", "f2_res.dat", MAX_PATH, f2ResIni), @@ -76,6 +82,7 @@ void HRP::init() { // Inits SplashScreen::init(); MainMenuScreen::init(); + ViewMap::init(); } } diff --git a/sfall/HRP/MainMenu.cpp b/sfall/HRP/MainMenu.cpp index 5f306fd5..833df138 100644 --- a/sfall/HRP/MainMenu.cpp +++ b/sfall/HRP/MainMenu.cpp @@ -219,6 +219,7 @@ scale: } static BYTE* buttonImageData; +static BYTE* downButtonImageData; // reference static long __fastcall ButtonScale(long &width, long xPos, BYTE* &upImageData, BYTE* &downImageData, long &yPos) { if (MainMenuScreen::USE_HIRES_IMAGES) { @@ -234,15 +235,15 @@ static long __fastcall ButtonScale(long &width, long xPos, BYTE* &upImageData, B // up Image::Scale(*(BYTE**)FO_VAR_button_up_data, width, width, buttonImageData, sWidth, sWidth); // down - BYTE* downImage = &buttonImageData[size]; - Image::Scale(*(BYTE**)FO_VAR_button_down_data, width, width, downImage, sWidth, sWidth); + downButtonImageData = &buttonImageData[size]; + Image::Scale(*(BYTE**)FO_VAR_button_down_data, width, width, downButtonImageData, sWidth, sWidth); - upImageData = buttonImageData; - downImageData = downImage; - - fo::var::setInt(FO_VAR_button_up_data) = (long)buttonImageData; - fo::var::setInt(FO_VAR_button_down_data) = (long)downImage; + //fo::var::setInt(FO_VAR_button_up_data) = (long)buttonImageData; + //fo::var::setInt(FO_VAR_button_down_data) = (long)downButtonImageData; } + upImageData = buttonImageData; + downImageData = downButtonImageData; + width = sWidth; yPos = (long)(yPos * scaleFactor); return (long)(xPos * scaleFactor); diff --git a/sfall/HRP/ViewMap/EdgeBorder.cpp b/sfall/HRP/ViewMap/EdgeBorder.cpp new file mode 100644 index 00000000..2b1318c7 --- /dev/null +++ b/sfall/HRP/ViewMap/EdgeBorder.cpp @@ -0,0 +1,258 @@ +/* + * sfall + * Copyright (C) 2008-2021 The sfall team + * + */ + +#include "..\..\main.h" +#include "..\..\FalloutEngine\Fallout2.h" + +#include "ViewMap.h" + +#include "EdgeBorder.h" + +namespace sfall +{ + +static struct Edge { // sizeof = 0x54 + long centerX; + long centerY; + RECT rect_1; + RECT rect_2; + RECT tileRect_3; + RECT rect_4; + long field_48; + Edge* nextEdgeData_4C; // unused? (used in 3.06) + Edge* nextEdgeData_50; + + // make a destructor + +} *MapEdgeData; + +long EdgeVersion; +long isLoadingMapEdge; + +// Implementation from HRP by Mash +static void CalcEdgeData(Edge* edgeData, long w, long h) { + long x = 0, y = 0; + + ViewMap::GetTileCoordOffset(edgeData->tileRect_3.left, x, y); + edgeData->rect_1.left = x; + + ViewMap::GetTileCoordOffset(edgeData->tileRect_3.right, x, y); + edgeData->rect_1.right = x; + + ViewMap::GetTileCoordOffset(edgeData->tileRect_3.top, x, y); + edgeData->rect_1.top = y; + + ViewMap::GetTileCoordOffset(edgeData->tileRect_3.bottom, x, y); + edgeData->rect_1.bottom = y; + + long mapWinW = (fo::var::getInt(FO_VAR_buf_width_2) / 2) - 1; // 1280/2 -1 = 639 (320) + long mapWinH = (fo::var::getInt(FO_VAR_buf_length_2) / 2) - 1; // 720/2 -1 = 359 (240) + + edgeData->rect_2.left = edgeData->rect_1.left - mapWinW; + edgeData->rect_2.right = edgeData->rect_1.right - mapWinW; + edgeData->rect_2.top = edgeData->rect_1.top + mapWinH; + edgeData->rect_2.bottom = edgeData->rect_1.bottom + mapWinH; + + long v13 = (edgeData->rect_1.left - edgeData->rect_1.right) / 2; + long v14 = v13; + if (v13 & 31) { + v13 &= ~31; // truncate + v14 = v13 + 32; + } + long left, right; + if (v13 < w) { + left = edgeData->rect_1.left - v13; + right = v14 + edgeData->rect_1.right; + } else { + left = edgeData->rect_1.left - w; + right = w + edgeData->rect_1.right; + } + edgeData->rect_1.right = right; + edgeData->rect_1.left = left; + + long v19 = (edgeData->rect_1.bottom - edgeData->rect_1.top) / 2; + long v20 = v19; + if (v19 % 24) { + v19 -= v19 % 24; // truncate + v20 = v19 + 24; + } + long top, bottom; + if (v19 < h) { + top = v20 + edgeData->rect_1.top; + bottom = edgeData->rect_1.bottom - v19; + } else { + bottom = edgeData->rect_1.bottom - h; + top = h + edgeData->rect_1.top; + } + edgeData->rect_1.top = top; + edgeData->rect_1.bottom = bottom; + + if (edgeData->rect_1.left < edgeData->rect_1.right) edgeData->rect_1.left = edgeData->rect_1.right; + if (edgeData->rect_1.bottom < edgeData->rect_1.top) edgeData->rect_1.bottom = edgeData->rect_1.top; + + if (edgeData->rect_1.left - edgeData->rect_1.right == 32) edgeData->rect_1.left = edgeData->rect_1.right; + if (edgeData->rect_1.bottom - edgeData->rect_1.top == 24) edgeData->rect_1.bottom = edgeData->rect_1.top; + + // R2000, L1000 : 1000-2000 = -1000/2 = -500+2000 = 1500 not an error here? + x = edgeData->rect_1.right + ((edgeData->rect_1.left - edgeData->rect_1.right) / 2); + edgeData->centerX = x & ~31; + + y = edgeData->rect_1.top + ((edgeData->rect_1.bottom - edgeData->rect_1.top) / 2); + edgeData->centerY = y - (y % 24); +} + +static void SetDefaultEdgeData() { + long w = 0, h = 0; + ViewMap::GetMapWindowSize(w, h); + + if (MapEdgeData == nullptr) MapEdgeData = new Edge[3]; + + for (size_t i = 0; i < 3; i++) { + Edge* edge = &MapEdgeData[i]; + + edge->tileRect_3.left = 199; + edge->tileRect_3.top = 0; + edge->tileRect_3.right = 39800; + edge->tileRect_3.bottom = 39999; + //edge->nextEdgeData_50 = nullptr; + + CalcEdgeData(edge, w, h); + + edge->rect_4.left = 99; + edge->rect_4.top = 0; + edge->rect_4.right = 0; + edge->rect_4.bottom = 99; + + edge->field_48 = 0; + edge->nextEdgeData_50 = nullptr; + } + EdgeVersion = 0; + //isDefaultSetEdge = 1; +} + +// Implementation from HRP by Mash +static fo::DbFile* LoadMapEdgeFileSub(char* mapName) { + char mapPath[32]; + + char* posDot = std::strchr(mapName, '.'); + *posDot = '\0'; + std::sprintf(mapPath, "maps\\%s.edg", mapName); + *posDot = '.'; + + fo::DbFile* file = fo::func::db_fopen(mapPath, "rb"); + if (!file) { + SetDefaultEdgeData(); + return file; + } + + DWORD getValue; + fo::func::db_freadInt(file, &getValue); + if (getValue != 'EDGE') return file; + + fo::func::db_freadInt(file, &getValue); + if (getValue == 1) { + EdgeVersion = 0; + } else { + if (getValue != 2) return file; + EdgeVersion = 1; + } + + // get count? + getValue = 0; + if (fo::func::db_freadInt(file, &getValue) || getValue) return file; + + long w = 0, h = 0; + ViewMap::GetMapWindowSize(w, h); + + if (MapEdgeData) { + //delete[] MapEdgeData; + // release nested data + } else { + MapEdgeData = new Edge[3]; + } + + long mapLevel = 0; + do { + Edge* edgeData = &MapEdgeData[mapLevel]; + + if (EdgeVersion) { + // loading a rectangle? + if (fo::func::db_freadIntCount(file, (DWORD*)&edgeData->rect_4, 4) || fo::func::db_freadInt(file, (DWORD*)&edgeData->field_48)) { + return file; // read error + } + } else { + edgeData->rect_4.left = 99; + edgeData->rect_4.top = 0; + edgeData->rect_4.right = 0; + edgeData->rect_4.bottom = 99; + edgeData->field_48 = 0; + } + + if (getValue == mapLevel) { + while (true) { + // loading a rectangle? + long result = fo::func::db_freadIntCount(file, (DWORD*)&edgeData->tileRect_3, 4); + if (result != 0) return file; // read error + + CalcEdgeData(edgeData, w, h); + + if (fo::func::db_freadInt(file, &getValue)) { + // read error + if (mapLevel != 2) return file; + + getValue = -1; + break; // next level + } + + if (getValue == mapLevel) { + Edge *edge = new Edge; + edge->nextEdgeData_50 = nullptr; + edge->rect_4 = edgeData->rect_4; // copy + edgeData->nextEdgeData_50 = edge; + edgeData = edge; + continue; // next read + } + break; // next level + } + } + } while (++mapLevel < 3); + + fo::func::db_fclose(file); + return 0; +} + +static void __fastcall LoadMapEdgeFile(char* mapName) { + isLoadingMapEdge = 0; + + fo::DbFile* file = LoadMapEdgeFileSub(mapName); + if (file) { // load error + fo::func::db_fclose(file); + SetDefaultEdgeData(); + } +} + +// open map file +static void __declspec(naked) map_load_hook_db_fopen() { + __asm { + push ecx; + mov ecx, eax; // mapName + call fo::funcoffs::db_fopen_; + test eax, eax; + jz fail; + push eax; + call LoadMapEdgeFile; + pop eax; +fail: + pop ecx; + retn; + } +} + +void EdgeBorder::init() { + //HookCall(0x482AE1, map_load_hook_db_fopen); +} + +} diff --git a/sfall/HRP/ViewMap/EdgeBorder.h b/sfall/HRP/ViewMap/EdgeBorder.h new file mode 100644 index 00000000..82d41622 --- /dev/null +++ b/sfall/HRP/ViewMap/EdgeBorder.h @@ -0,0 +1,18 @@ +/* + * sfall + * Copyright (C) 2008-2021 The sfall team + * + */ + +#pragma once + +namespace sfall +{ + +class EdgeBorder { +public: + static void init(); + +}; + +} diff --git a/sfall/HRP/ViewMap/ViewMap.cpp b/sfall/HRP/ViewMap/ViewMap.cpp new file mode 100644 index 00000000..814713eb --- /dev/null +++ b/sfall/HRP/ViewMap/ViewMap.cpp @@ -0,0 +1,66 @@ +/* + * sfall + * Copyright (C) 2008-2021 The sfall team + * + */ + +#include "..\..\main.h" +#include "..\..\FalloutEngine\Fallout2.h" + +#include "EdgeBorder.h" + +#include "ViewMap.h" + +namespace sfall +{ + +long ViewMap::SCROLL_DIST_X; +long ViewMap::SCROLL_DIST_Y; + +static long mapDisplayWinWidthMod; +static long mapDisplayWinHeightMod; + +void ViewMap::GetTileCoord(long tile, long &outX, long &outY) { + int x = tile % 200; // tile % _grid_width // 20100%200 = 100 + int y = (tile / 200) + (x / 2); // tile / _grid_width + x / 2 // 20100/200 = 100+(100/2) = y:150 ??? + outY = y; + outX = (2 * x) - y; // 2*100 = 200-150 = x:50 ??? +} + +void ViewMap::GetTileCoordOffset(long tile, long &outX, long &outY) { + int x = tile % 200; // tile % _grid_width // 20100%200 = 100 + int y = (tile / 200) + (x / 2); // tile / _grid_width + x / 2 // 20100/200 = 100+(100/2) = y:150 ??? + y &= 0xFFFFFFFE; // even to down + x = (2 * x) + 200 - y; // 2*100 = 200+200-150 = x:250 ??? + + outY = 12 * y; + outX = 16 * x; +} + +void ViewMap::GetMapWindowSize(long &outW, long &outH) { + //win = fo::func::GNW_find(fo::var::display_win); + long mapWinWidth = fo::var::getInt(FO_VAR_buf_width_2); + long mapWinHeight = fo::var::getInt(FO_VAR_buf_length_2); + + long wHalf = mapWinWidth >> 1; // 1280/2 = 640 + mapDisplayWinWidthMod = wHalf & 31; // 640&31 = 0 + outW = wHalf - mapDisplayWinWidthMod; // truncate by 32 units + + long hHalf = mapWinHeight >> 1; // 720/2 = 360 + mapDisplayWinHeightMod = hHalf % 24; // 360%24=0 + outH = hHalf - mapDisplayWinHeightMod; // truncate by 24 units +} + +void ViewMap::init() { + + if (SCROLL_DIST_X < 480) SCROLL_DIST_X = 480; + if (SCROLL_DIST_Y < 400) SCROLL_DIST_Y = 400; + + + // Dev block tile_set_border_ + BlockCall(0x4B11A3); // tile_init_ + + EdgeBorder::init(); +} + +} diff --git a/sfall/HRP/ViewMap/ViewMap.h b/sfall/HRP/ViewMap/ViewMap.h new file mode 100644 index 00000000..a34d6156 --- /dev/null +++ b/sfall/HRP/ViewMap/ViewMap.h @@ -0,0 +1,24 @@ +/* + * sfall + * Copyright (C) 2008-2021 The sfall team + * + */ + +#pragma once + +namespace sfall +{ + +class ViewMap { +public: + static void init(); + + static long SCROLL_DIST_X; + static long SCROLL_DIST_Y; + + static void GetTileCoord(long tile, long &outX, long &outY); + static void GetTileCoordOffset(long tile, long &outX, long &outY); + static void GetMapWindowSize(long &outW, long &outH); +}; + +} diff --git a/sfall/ddraw.vcxproj b/sfall/ddraw.vcxproj index 2ad5934c..50dbcc97 100644 --- a/sfall/ddraw.vcxproj +++ b/sfall/ddraw.vcxproj @@ -313,6 +313,8 @@ + + @@ -434,6 +436,8 @@ + + diff --git a/sfall/ddraw.vcxproj.filters b/sfall/ddraw.vcxproj.filters index cc64cf42..368441af 100644 --- a/sfall/ddraw.vcxproj.filters +++ b/sfall/ddraw.vcxproj.filters @@ -31,6 +31,9 @@ {12f6f063-3ef2-45e9-a55f-d6423dd62126} + + {d15672c6-4446-4325-8e14-a1143f26fc23} + @@ -385,6 +388,12 @@ HRP + + HRP\ViewMap + + + HRP\ViewMap + @@ -708,6 +717,12 @@ HRP + + HRP\ViewMap + + + HRP\ViewMap +