mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added displaying terrain types on the world map
(from Rotators repo)
This commit is contained in:
+5
-5
@@ -123,11 +123,11 @@ ActionPointsBar=0
|
||||
WorldTravelMarkers=0
|
||||
;Uncomment these lines to change the appearance of the markers
|
||||
;The color index in Fallout default palette (valid range: 1..255; default is 133)
|
||||
;MarkerColor=133
|
||||
;The lengh in pixels of the dots (valid range: 1..10)
|
||||
;MarkerLength=1
|
||||
;The spacing in pixels between the dots (valid range: 1..10)
|
||||
;MarkerSpaces=2
|
||||
;TravelMarkerColor=133
|
||||
;The lengh of the dots in pixels (valid range: 1..10)
|
||||
;TravelMarkerLength=1
|
||||
;The spacing between the dots in pixels (valid range: 1..10)
|
||||
;TravelMarkerSpaces=2
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Input]
|
||||
|
||||
@@ -212,23 +212,77 @@ void GetObjectsTileRadius(std::vector<fo::GameObject*> &objs, long sourceTile, l
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the name of the terrain type in the position of the player's marker on the world map
|
||||
const char* wmGetCurrentTerrainName() {
|
||||
long* terrainId = *(long**)FO_VAR_world_subtile;
|
||||
if (terrainId == nullptr) {
|
||||
__asm {
|
||||
lea ebx, terrainId;
|
||||
mov edx, dword ptr ds:[FO_VAR_world_ypos];
|
||||
mov eax, dword ptr ds:[FO_VAR_world_xpos];
|
||||
call fo::funcoffs::wmFindCurSubTileFromPos_;
|
||||
}
|
||||
}
|
||||
return GetMessageStr(&fo::var::wmMsgFile, 1000 + *terrainId);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//print text to surface
|
||||
void PrintText(char *DisplayText, BYTE ColourIndex, DWORD Xpos, DWORD Ypos, DWORD TxtWidth, DWORD ToWidth, BYTE *ToSurface) {
|
||||
DWORD posOffset = Ypos * ToWidth + Xpos;
|
||||
// copy the area from the interface buffer to the data array
|
||||
void RectCopyToMemory(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromBuff, BYTE* toMem) {
|
||||
fromBuff += fromY * fromWidth + fromX;
|
||||
long i = 0;
|
||||
for (long h = 0; h < height; h++) {
|
||||
for (long w = 0; w < width; w++) {
|
||||
toMem[i++] = fromBuff[w];
|
||||
}
|
||||
fromBuff += fromWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// copy data from memory to the area of the interface buffer
|
||||
void MemCopyToWinBuffer(long toX, long toY, long width, long height, long toWidth, BYTE* toBuff, BYTE* fromMem) {
|
||||
toBuff += toY * toWidth + toX;
|
||||
long i = 0;
|
||||
for (long h = 0; h < height; h++) {
|
||||
for (long w = 0; w < width; w++) {
|
||||
toBuff[w] = fromMem[i++];
|
||||
}
|
||||
toBuff += toWidth;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// print text to surface
|
||||
void PrintText(char* displayText, BYTE colourIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface) {
|
||||
DWORD posOffset = yPos * toWidth + xPos;
|
||||
__asm {
|
||||
xor eax, eax;
|
||||
mov al, ColourIndex;
|
||||
mov al, colourIndex;
|
||||
mov edx, displayText;
|
||||
push eax;
|
||||
mov edx, DisplayText;
|
||||
mov ebx, TxtWidth;
|
||||
mov ecx, ToWidth;
|
||||
mov eax, ToSurface;
|
||||
mov ebx, txtWidth;
|
||||
mov eax, toSurface;
|
||||
mov ecx, toWidth;
|
||||
add eax, posOffset;
|
||||
call dword ptr ds:[FO_VAR_text_to_buf];
|
||||
}
|
||||
}
|
||||
|
||||
void PrintTextFM(char* displayText, BYTE colorIndex, DWORD xPos, DWORD yPos, DWORD txtWidth, DWORD toWidth, BYTE* toSurface) {
|
||||
DWORD posOffset = yPos * toWidth + xPos;
|
||||
__asm {
|
||||
xor eax, eax;
|
||||
mov al, colorIndex;
|
||||
mov edx, displayText;
|
||||
push eax;
|
||||
mov ebx, txtWidth;
|
||||
mov eax, toSurface;
|
||||
mov ecx, toWidth;
|
||||
add eax, posOffset;
|
||||
call fo::funcoffs::FMtext_to_buf_;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//gets the height of the currently selected font
|
||||
DWORD GetTextHeight() {
|
||||
@@ -249,6 +303,13 @@ DWORD GetTextWidth(const char *TextMsg) {
|
||||
}
|
||||
}
|
||||
|
||||
DWORD GetTextWidthFM(const char *TextMsg) {
|
||||
__asm {
|
||||
mov eax, TextMsg;
|
||||
call fo::funcoffs::FMtext_width_; //get text width
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//get width of Char for current font
|
||||
DWORD GetCharWidth(char CharVal) {
|
||||
|
||||
@@ -80,12 +80,20 @@ long __fastcall GetTopWindowID(long xPos, long yPos);
|
||||
|
||||
void GetObjectsTileRadius(std::vector<fo::GameObject*> &objs, long sourceTile, long radius, long elev, long type);
|
||||
|
||||
const char* wmGetCurrentTerrainName();
|
||||
|
||||
void RectCopyToMemory(long fromX, long fromY, long width, long height, long fromWidth, BYTE* fromBuff, BYTE* toMem);
|
||||
|
||||
void MemCopyToWinBuffer(long toX, long toY, long width, long height, long toWidth, BYTE* toBuff, BYTE* fromMem);
|
||||
|
||||
// Print text to surface
|
||||
void PrintText(char *displayText, BYTE colorIndex, DWORD x, DWORD y, DWORD textWidth, DWORD destWidth, BYTE *surface);
|
||||
void PrintText(char* displayText, BYTE colorIndex, DWORD x, DWORD y, DWORD textWidth, DWORD destWidth, BYTE* surface);
|
||||
void PrintTextFM(char* displayText, BYTE colorIndex, DWORD x, DWORD y, DWORD textWidth, DWORD destWidth, BYTE* surface);
|
||||
// gets the height of the currently selected font
|
||||
DWORD GetTextHeight();
|
||||
// gets the length of a string using the currently selected font
|
||||
DWORD GetTextWidth(const char *textMsg);
|
||||
DWORD GetTextWidthFM(const char *textMsg);
|
||||
// get width of Char for current font
|
||||
DWORD GetCharWidth(char charVal);
|
||||
// get maximum string length for current font - if all characters were maximum width
|
||||
|
||||
@@ -25,6 +25,7 @@ WRAP_WATCOM_FFUNC3(FrmFrameData*, frame_ptr, FrmHeaderData*, frm, long, frame, l
|
||||
WRAP_WATCOM_FFUNC3(void, intface_update_items, long, animate, long, modeLeft,long, modeRight)
|
||||
WRAP_WATCOM_FFUNC3(long, item_add_force, GameObject*, critter, GameObject*, item, long, count)
|
||||
WRAP_WATCOM_FFUNC7(void, make_straight_path_func, GameObject*, objFrom, DWORD, tileFrom, DWORD, tileTo, void*, rotationPtr, DWORD*, result, long, flags, void*, func)
|
||||
WRAP_WATCOM_FFUNC3(long, message_find, DWORD*, msgFile, long, msgNumber, DWORD*, outBuf)
|
||||
WRAP_WATCOM_FFUNC4(long, mouse_click_in, long, x, long, y, long, x_end, long, y_end)
|
||||
WRAP_WATCOM_FFUNC3(GameObject*, obj_blocking_at, GameObject*, object, long, tile, long, elevation)
|
||||
WRAP_WATCOM_FFUNC4(long, obj_move_to_tile, GameObject*, object, long, tile, long, elevation, RECT*, rect)
|
||||
@@ -172,6 +173,7 @@ WRAP_WATCOM_FUNC1(void, win_show, DWORD, winRef)
|
||||
WRAP_WATCOM_FUNC1(void, win_hide, DWORD, winRef)
|
||||
WRAP_WATCOM_FUNC1(BYTE*, win_get_buf, DWORD, winRef)
|
||||
WRAP_WATCOM_FUNC1(void, win_draw, DWORD, winRef)
|
||||
WRAP_WATCOM_FUNC2(void, win_draw_rect, DWORD, winRef, RECT*, rect)
|
||||
WRAP_WATCOM_FUNC1(void, win_delete, DWORD, winRef)
|
||||
WRAP_WATCOM_FUNC0(long, windowWidth)
|
||||
WRAP_WATCOM_FUNC1(void, wmCarUseGas, long, gasAmount)
|
||||
|
||||
@@ -239,16 +239,19 @@
|
||||
#define FO_VAR_wd_obj 0x59E98C
|
||||
#define FO_VAR_window 0x6ADE58
|
||||
#define FO_VAR_wmAreaInfoList 0x51DDF8
|
||||
#define FO_VAR_wmBkWin 0x51DE14
|
||||
#define FO_VAR_wmBkWinBuf 0x51DE24
|
||||
#define FO_VAR_wmLastRndTime 0x51DEA0
|
||||
#define FO_VAR_wmMaxMapNum 0x51DE10
|
||||
#define FO_VAR_wmMaxTileNum 0x51DDF0
|
||||
#define FO_VAR_wmMsgFile 0x672FB0
|
||||
#define FO_VAR_wmNumHorizontalTiles 0x51DDF4
|
||||
#define FO_VAR_wmViewportRightScrlLimit 0x672EFC
|
||||
#define FO_VAR_wmViewportBottomtScrlLimit 0x672F00
|
||||
#define FO_VAR_wmWorldOffsetX 0x51DE2C
|
||||
#define FO_VAR_wmWorldOffsetY 0x51DE30
|
||||
#define FO_VAR_wmYesNoStrs 0x51DD90
|
||||
#define FO_VAR_world_subtile 0x672E14
|
||||
#define FO_VAR_world_xpos 0x672E0C
|
||||
#define FO_VAR_world_ypos 0x672E10
|
||||
#define FO_VAR_WorldMapCurrArea 0x672E08
|
||||
|
||||
@@ -79,7 +79,7 @@ VAR_(i_rhand, GameObject*)
|
||||
VAR_(i_wid, DWORD)
|
||||
VAR_(i_worn, GameObject*)
|
||||
VAR_(idle_func, DWORD)
|
||||
VAR_(In_WorldMap, DWORD)
|
||||
VAR_(In_WorldMap, DWORD) // moving on WorldMap
|
||||
VAR_(info_line, DWORD)
|
||||
VAR_(interfaceWindow, DWORD)
|
||||
VAR_(intfaceEnabled, DWORD)
|
||||
@@ -209,6 +209,7 @@ VAR_(WhiteColor, BYTE)
|
||||
VAR_(wmAreaInfoList, DWORD)
|
||||
VAR_(wmLastRndTime, DWORD)
|
||||
VAR_(wmMaxTileNum, DWORD)
|
||||
VAR_(wmMsgFile, MessageList)
|
||||
VAR_(wmNumHorizontalTiles, DWORD)
|
||||
VAR_(wmViewportRightScrlLimit, DWORD)
|
||||
VAR_(wmViewportBottomtScrlLimit, DWORD)
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "..\FalloutEngine\EngineUtils.h"
|
||||
#include "Graphics.h"
|
||||
#include "LoadGameHook.h"
|
||||
//#include "Worldmap.h"
|
||||
|
||||
#include "Interface.h"
|
||||
|
||||
@@ -459,6 +463,8 @@ static void WorldmapViewportPatch() {
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
////////////////////////////// FALLOUT 1 FEATURES //////////////////////////////
|
||||
|
||||
struct DotPosition {
|
||||
long x;
|
||||
long y;
|
||||
@@ -468,7 +474,7 @@ static std::vector<DotPosition> dots;
|
||||
static long optionLenDot = 1;
|
||||
static long optionSpaceDot = 2;
|
||||
|
||||
static unsigned char colorDot = 133; // color index in palette: R = 252, G = 0, B = 0
|
||||
static unsigned char colorDot = 0; // color index in palette: R = 252, G = 0, B = 0
|
||||
static long spaceLen = 2;
|
||||
static long dotLen = 1;
|
||||
static long dot_xpos = 0;
|
||||
@@ -529,8 +535,31 @@ static void __declspec(naked) DrawingDots() {
|
||||
}
|
||||
}
|
||||
|
||||
static std::array<unsigned char, 15 * 100> wmTmpBuffer;
|
||||
static bool hoveringHotspot = false;
|
||||
static bool backImageIsCopy = false;
|
||||
|
||||
static void PrintTerrainType(long x, long y) {
|
||||
char* terrainText = (char*)fo::wmGetCurrentTerrainName();
|
||||
long txtWidth = fo::GetTextWidthFM(terrainText);
|
||||
if (txtWidth > 100) txtWidth = 100;
|
||||
|
||||
// offset position
|
||||
y += 4;
|
||||
x += 25 - (txtWidth / 2);
|
||||
|
||||
fo::PrintTextFM(terrainText, 228, x, y, txtWidth, wmapWinWidth, *(BYTE**)FO_VAR_wmBkWinBuf); // text shadow
|
||||
fo::PrintTextFM(terrainText, 215, x - 1, y - 1, txtWidth, wmapWinWidth, *(BYTE**)FO_VAR_wmBkWinBuf);
|
||||
}
|
||||
|
||||
static void PrintTerrainType() {
|
||||
long y = fo::var::world_ypos - fo::var::wmWorldOffsetY;
|
||||
long x = fo::var::world_xpos - fo::var::wmWorldOffsetX;
|
||||
PrintTerrainType(x, y);
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmInterfaceRefresh_hook() {
|
||||
if (fo::var::target_xpos != -1) {
|
||||
if (colorDot && fo::var::target_xpos != -1) {
|
||||
if (fo::var::In_WorldMap) {
|
||||
DrawingDots();
|
||||
} else if (!fo::var::target_xpos && !fo::var::target_ypos) {
|
||||
@@ -540,9 +569,63 @@ static void __declspec(naked) wmInterfaceRefresh_hook() {
|
||||
spaceLen = optionSpaceDot;
|
||||
}
|
||||
}
|
||||
if (hoveringHotspot && !fo::var::In_WorldMap) {
|
||||
PrintTerrainType();
|
||||
hoveringHotspot = backImageIsCopy = false;
|
||||
}
|
||||
__asm jmp fo::funcoffs::wmDrawCursorStopped_;
|
||||
}
|
||||
|
||||
static long __fastcall wmDetectHotspotHover(long wmMouseX, long wmMouseY) {
|
||||
long deltaX = abs((long)fo::var::world_xpos - (wmMouseX - 20 + fo::var::wmWorldOffsetX));
|
||||
long deltaY = abs((long)fo::var::world_ypos - (wmMouseY - 20 + fo::var::wmWorldOffsetY));
|
||||
|
||||
bool hovered = hoveringHotspot;
|
||||
hoveringHotspot = deltaX < 6 && deltaY < 6;
|
||||
if (hoveringHotspot != hovered) { // if value has changed
|
||||
// upper left corner
|
||||
long y = fo::var::world_ypos - fo::var::wmWorldOffsetY;
|
||||
long x = fo::var::world_xpos - fo::var::wmWorldOffsetX;
|
||||
long x_offset = x - 25;
|
||||
if (!backImageIsCopy) {
|
||||
backImageIsCopy = true;
|
||||
// copy image to memory (size 100 x 15)
|
||||
fo::RectCopyToMemory(x_offset, y, 100, 15, wmapWinWidth, *(BYTE**)FO_VAR_wmBkWinBuf, wmTmpBuffer.data());
|
||||
PrintTerrainType(x, y);
|
||||
} else {
|
||||
// restore saved image
|
||||
fo::MemCopyToWinBuffer(x_offset, y, 100, 15, wmapWinWidth, *(BYTE**)FO_VAR_wmBkWinBuf, wmTmpBuffer.data());
|
||||
backImageIsCopy = false;
|
||||
}
|
||||
// redraw worldmap interface rectangle
|
||||
RECT rect;
|
||||
rect.top = y;
|
||||
rect.left = x_offset;
|
||||
rect.right = x + 100;
|
||||
rect.bottom = y + 15;
|
||||
fo::func::win_draw_rect(*(long*)FO_VAR_wmBkWin, &rect);
|
||||
}
|
||||
return fo::var::wmWorldOffsetY; // overwritten code
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmWorldMap_hack() {
|
||||
__asm {
|
||||
cmp ds:[FO_VAR_In_WorldMap], 1; // player is moving
|
||||
jne checkHover;
|
||||
mov eax, dword ptr ds:[FO_VAR_wmWorldOffsetY];
|
||||
retn;
|
||||
checkHover:
|
||||
push ecx;
|
||||
mov ecx, [esp + 0x38 - 0x30 + 8]; // x
|
||||
mov edx, [esp + 0x38 - 0x34 + 8]; // y
|
||||
call wmDetectHotspotHover;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void __declspec(naked) wmInterfaceRefreshCarFuel_hack_empty() {
|
||||
__asm {
|
||||
mov byte ptr [eax - 1], 13;
|
||||
@@ -606,21 +689,23 @@ static void WorldMapInterfacePatch() {
|
||||
}
|
||||
|
||||
if (GetConfigInt("Interface", "WorldTravelMarkers", 0)) {
|
||||
optionLenDot = GetConfigInt("Interface", "MarkerLength", optionLenDot);
|
||||
optionSpaceDot = GetConfigInt("Interface", "MarkerSpaces", optionSpaceDot);
|
||||
int color = GetConfigInt("Interface", "MarkerColor", colorDot);
|
||||
optionLenDot = GetConfigInt("Interface", "TravelMarkerLength", optionLenDot);
|
||||
optionSpaceDot = GetConfigInt("Interface", "TravelMarkerSpaces", optionSpaceDot);
|
||||
int color = GetConfigInt("Interface", "TravelMarkerColor", 133);
|
||||
|
||||
if (color > 255) color = 255; else if (color < 1) color = 1;
|
||||
colorDot = color;
|
||||
if (optionLenDot > 10) optionLenDot = 10; else if (optionLenDot < 1) optionLenDot = 1;
|
||||
if (optionSpaceDot > 10) optionSpaceDot = 10; else if (optionSpaceDot < 1) optionSpaceDot = 1;
|
||||
|
||||
HookCall(0x4C3C7E, wmInterfaceRefresh_hook); // when calling wmDrawCursorStopped_
|
||||
dots.reserve(512);
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
dots.clear();
|
||||
};
|
||||
}
|
||||
// Fallout 1 features, travel markers and displaying terrain type
|
||||
HookCall(0x4C3C7E, wmInterfaceRefresh_hook); // when calling wmDrawCursorStopped_
|
||||
MakeCall(0x4BFE84, wmWorldMap_hack);
|
||||
|
||||
// Car fuel gauge graphics patch
|
||||
MakeCall(0x4C528A, wmInterfaceRefreshCarFuel_hack_empty);
|
||||
|
||||
@@ -58,6 +58,10 @@ static float scriptMapMulti = 1.0;
|
||||
static bool addYear = false; // used as additional years indicator
|
||||
static DWORD addedYears = 0;
|
||||
|
||||
static void __stdcall WorldmapLoopHook() {
|
||||
onWorldmapLoop.invoke();
|
||||
}
|
||||
|
||||
static __declspec(naked) void TimeDateFix() {
|
||||
__asm {
|
||||
test edi, edi; // year buf
|
||||
@@ -120,10 +124,6 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
static void __stdcall WorldmapLoopHook() {
|
||||
onWorldmapLoop.invoke();
|
||||
}
|
||||
|
||||
static void __declspec(naked) WorldMapFpsPatch() {
|
||||
__asm {
|
||||
push dword ptr ds:[FO_VAR_last_buttons];
|
||||
@@ -177,9 +177,9 @@ subLoop:
|
||||
// Only used if the world map speed patch is disabled, so that world map scripts are still run
|
||||
static void __declspec(naked) wmWorldMap_hook() {
|
||||
__asm {
|
||||
pushadc;
|
||||
//pushadc;
|
||||
call WorldmapLoopHook;
|
||||
popadc;
|
||||
//popadc;
|
||||
jmp fo::funcoffs::get_input_;
|
||||
}
|
||||
}
|
||||
@@ -223,7 +223,7 @@ static void __declspec(naked) wmTownMapFunc_hack() {
|
||||
mov [esi], edx
|
||||
retn;
|
||||
end:
|
||||
add esp, 4; // destroy the return address
|
||||
add esp, 4; // destroy the return address
|
||||
mov eax, 0x4C4976;
|
||||
jmp eax;
|
||||
}
|
||||
@@ -315,8 +315,8 @@ end:
|
||||
|
||||
static void RestRestore() {
|
||||
if (!restMode) return;
|
||||
|
||||
restMode = false;
|
||||
|
||||
SafeWrite8(0x49952C, 0x85);
|
||||
SafeWrite8(0x497557, 0x85);
|
||||
SafeWrite8(0x42E587, 0xC7);
|
||||
|
||||
Reference in New Issue
Block a user