Added code for the previous commit

This commit is contained in:
NovaRain
2021-10-27 10:03:42 +08:00
parent 17c73a81da
commit 4385807cd3
7 changed files with 299 additions and 41 deletions
+7
View File
@@ -109,6 +109,13 @@ struct AnimationSad {
static_assert(sizeof(AnimationSad) == 3240, "Incorrect AnimationSad definition.");
struct SquareRect {
long y;
long x;
long offx;
long offy;
};
// Bounding rectangle, used by tile_refresh_rect and related functions.
struct BoundRect {
long x;
+11
View File
@@ -30,6 +30,7 @@
#define FO_VAR_btable 0x59E944
#define FO_VAR_btncnt 0x43EA1C
#define FO_VAR_buf_length_2 0x66BE14
#define FO_VAR_buf_rect_2 0x66BBD4
#define FO_VAR_buf_width_2 0x66BE30
#define FO_VAR_button_down_data 0x519500
#define FO_VAR_button_up_data 0x5194FC
@@ -76,6 +77,7 @@
#define FO_VAR_disp_curr 0x56FB48
#define FO_VAR_disp_init 0x51850C
#define FO_VAR_disp_start 0x56FB54
#define FO_VAR_display_buf 0x631D50
#define FO_VAR_display_string_buf 0x56DBFC
#define FO_VAR_display_win 0x631E4C
#define FO_VAR_displayMapList 0x41B560
@@ -257,6 +259,7 @@
#define FO_VAR_quick_done 0x5193BC
#define FO_VAR_read_callback 0x51DEEC
#define FO_VAR_rectList 0x51DEF4
#define FO_VAR_refresh_enabled 0x51D968
#define FO_VAR_retvals 0x43EA7C
#define FO_VAR_rm_FrameCount 0x6B36A8
#define FO_VAR_rotation 0x631D34
@@ -268,6 +271,8 @@
#define FO_VAR_script_engine_running 0x51C714
#define FO_VAR_script_path_base 0x51C710
#define FO_VAR_scriptListInfo 0x51C7C8
#define FO_VAR_scroll_blocking_on 0x51D954
#define FO_VAR_scroll_limiting_on 0x51D958
#define FO_VAR_skill_data 0x51D118
#define FO_VAR_skldxwin 0x668140
#define FO_VAR_slot_cursor 0x5193B8
@@ -277,6 +282,7 @@
#define FO_VAR_sound_music_path2 0x518E7C
#define FO_VAR_speech_volume 0x518E8C
#define FO_VAR_square 0x631E40
#define FO_VAR_square_rect 0x66BDE4 // _square_y
#define FO_VAR_squares 0x66BE08
#define FO_VAR_stack 0x59E86C
#define FO_VAR_stack_offset 0x59E844
@@ -304,6 +310,11 @@
#define FO_VAR_text_to_buf 0x51E3B8
#define FO_VAR_text_width 0x51E3C0
#define FO_VAR_tile 0x631D30
#define FO_VAR_tile_center_tile 0x66BE34
#define FO_VAR_tile_offx 0x66BDFC
#define FO_VAR_tile_offy 0x66BDF8
#define FO_VAR_tile_x 0x66BE18
#define FO_VAR_tile_y 0x66BE1C
#define FO_VAR_title_color 0x56D750
#define FO_VAR_title_font 0x56D748
#define FO_VAR_trait_data 0x51DB84
+1
View File
@@ -203,6 +203,7 @@ VAR_(sound_music_path1, char*)
VAR_(sound_music_path2, char*)
VAR_(speech_volume, DWORD)
VAR_(square, DWORD)
VAR_(square_rect, fo::SquareRect) // _square_y
VAR_(squares, DWORD*)
VARA(stack, DWORD, 10)
VARA(stack_offset, DWORD, 10)
+166 -37
View File
@@ -14,7 +14,7 @@
namespace sfall
{
static struct Edge { // sizeof = 0x54
static struct Edge {
long centerX;
long centerY;
RECT rect_1;
@@ -22,15 +22,29 @@ static struct Edge { // sizeof = 0x54
RECT tileRect_3;
RECT rect_4;
long field_48;
Edge* nextEdgeData_4C; // unused? (used in 3.06)
Edge* prevEdgeData_4C; // unused? (used in 3.06)
Edge* nextEdgeData_50;
// make a destructor
void Release() {
Edge* edge = nextEdgeData_50;
while (edge) {
Edge* edgeNext = edge->nextEdgeData_50;
delete edge;
edge = edgeNext;
};
}
~Edge() {
Release();
}
} *MapEdgeData;
// reference
Edge* CurrentMapEdge;
long EdgeVersion;
long isLoadingMapEdge;
bool isDefaultSetEdge;
// Implementation from HRP by Mash
static void CalcEdgeData(Edge* edgeData, long w, long h) {
@@ -49,23 +63,23 @@ static void CalcEdgeData(Edge* edgeData, long w, long h) {
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)
long mapWinH = (fo::var::getInt(FO_VAR_buf_length_2) / 2) - 1; // 620/2 -1 = 309 (190)
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 rectW = (edgeData->rect_1.left - edgeData->rect_1.right) / 2;
long _rectW = rectW;
if (rectW & 31) {
rectW &= ~31; // truncate
_rectW = rectW + 32;
}
long left, right;
if (v13 < w) {
left = edgeData->rect_1.left - v13;
right = v14 + edgeData->rect_1.right;
if (rectW < w) {
left = edgeData->rect_1.left - rectW;
right = _rectW + edgeData->rect_1.right;
} else {
left = edgeData->rect_1.left - w;
right = w + edgeData->rect_1.right;
@@ -73,16 +87,16 @@ static void CalcEdgeData(Edge* edgeData, long w, long h) {
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 rectH = (edgeData->rect_1.bottom - edgeData->rect_1.top) / 2;
long _rectH = rectH;
if (rectH % 24) {
rectH -= rectH % 24; // truncate
_rectH = rectH + 24;
}
long top, bottom;
if (v19 < h) {
top = v20 + edgeData->rect_1.top;
bottom = edgeData->rect_1.bottom - v19;
if (rectH < h) {
top = _rectH + edgeData->rect_1.top;
bottom = edgeData->rect_1.bottom - rectH;
} else {
bottom = edgeData->rect_1.bottom - h;
top = h + edgeData->rect_1.top;
@@ -96,7 +110,7 @@ static void CalcEdgeData(Edge* edgeData, long w, long h) {
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?
// here right is less than left
x = edgeData->rect_1.right + ((edgeData->rect_1.left - edgeData->rect_1.right) / 2);
edgeData->centerX = x & ~31;
@@ -117,7 +131,7 @@ static void SetDefaultEdgeData() {
edge->tileRect_3.top = 0;
edge->tileRect_3.right = 39800;
edge->tileRect_3.bottom = 39999;
//edge->nextEdgeData_50 = nullptr;
edge->prevEdgeData_4C = nullptr;
CalcEdgeData(edge, w, h);
@@ -130,19 +144,19 @@ static void SetDefaultEdgeData() {
edge->nextEdgeData_50 = nullptr;
}
EdgeVersion = 0;
//isDefaultSetEdge = 1;
isDefaultSetEdge = true;
}
// Implementation from HRP by Mash
static fo::DbFile* LoadMapEdgeFileSub(char* mapName) {
char mapPath[32];
char edgPath[32];
char* posDot = std::strchr(mapName, '.');
*posDot = '\0';
std::sprintf(mapPath, "maps\\%s.edg", mapName);
std::sprintf(edgPath, "%s.edg", mapName); //maps
*posDot = '.';
fo::DbFile* file = fo::func::db_fopen(mapPath, "rb");
fo::DbFile* file = fo::func::db_fopen(edgPath, "rb");
if (!file) {
SetDefaultEdgeData();
return file;
@@ -160,16 +174,16 @@ static fo::DbFile* LoadMapEdgeFileSub(char* mapName) {
EdgeVersion = 1;
}
// get count?
getValue = 0;
if (fo::func::db_freadInt(file, &getValue) || getValue) return file;
if (fo::func::db_freadInt(file, &getValue) || getValue) return file; // unknown for now
long w = 0, h = 0;
ViewMap::GetMapWindowSize(w, h);
if (MapEdgeData) {
//delete[] MapEdgeData;
// release nested data
MapEdgeData[0].Release();
MapEdgeData[1].Release();
MapEdgeData[2].Release();
} else {
MapEdgeData = new Edge[3];
}
@@ -179,7 +193,7 @@ static fo::DbFile* LoadMapEdgeFileSub(char* mapName) {
Edge* edgeData = &MapEdgeData[mapLevel];
if (EdgeVersion) {
// loading a rectangle?
// load 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
}
@@ -193,24 +207,23 @@ static fo::DbFile* LoadMapEdgeFileSub(char* mapName) {
if (getValue == mapLevel) {
while (true) {
// loading a rectangle?
long result = fo::func::db_freadIntCount(file, (DWORD*)&edgeData->tileRect_3, 4);
long result = fo::func::db_freadIntCount(file, (DWORD*)&edgeData->tileRect_3, 4); // load the rectangle
if (result != 0) return file; // read error
CalcEdgeData(edgeData, w, h);
if (fo::func::db_freadInt(file, &getValue)) {
// read error
// the end of file is reached (read error)
if (mapLevel != 2) return file;
getValue = -1;
break; // next level
}
if (getValue == mapLevel) {
if (getValue == mapLevel) { // there are more rectangles for the current map level
Edge *edge = new Edge;
edge->nextEdgeData_50 = nullptr;
edge->rect_4 = edgeData->rect_4; // copy
edge->rect_4 = edgeData->rect_4; // rect copy
edgeData->nextEdgeData_50 = edge;
edgeData = edge;
continue; // next read
@@ -251,8 +264,124 @@ fail:
}
}
// Implementation from HRP by Mash
long EdgeBorder::GetCenterTile(long tile, long mapLevel) {
if (!isDefaultSetEdge) SetDefaultEdgeData(); // needed at game initialization
long x = 0, y = 0;
ViewMap::GetTileCoordOffset(tile, x, y);
Edge* edgeData = &MapEdgeData[mapLevel];
CurrentMapEdge = edgeData;
long mapWinW = fo::var::getInt(FO_VAR_buf_width_2);
long mapWinH = fo::var::getInt(FO_VAR_buf_length_2);
// fill with black, why?
//std::memset((void*)fo::var::getInt(FO_VAR_display_buf), 0, mapWinW * mapWinH); // can use the _buf_size variable instead of multiplication
//fo::func::win_draw(fo::var::getInt(FO_VAR_display_win));
if (edgeData->nextEdgeData_50) {
long width = (mapWinW / 2) - 1;
long height = (mapWinH / 2) + 1;
Edge* edge = edgeData;
while (x >= width + edge->rect_2.left || x <= width + edge->rect_2.right ||
y <= edge->rect_2.top - height || y >= edge->rect_2.bottom - height)
{
edge = edgeData->nextEdgeData_50;
if (!edge) break;
edgeData = edge;
CurrentMapEdge = edge;
}
}
long left = edgeData->rect_1.left;
if (x <= left) {
long right = edgeData->rect_1.right;
if (x >= right) {
edgeData->centerX = x;
} else {
edgeData->centerX = right;
}
} else {
edgeData->centerX = left;
}
long bottom = edgeData->rect_1.bottom;
if (y <= bottom) {
long top = edgeData->rect_1.top;
if (y >= top) {
edgeData->centerY = y;
} else {
edgeData->centerY = top;
}
} else {
edgeData->centerY = bottom;
}
ViewMap::mapHalfHeight = 0;
ViewMap::mapHalfWidth = 0;
if (edgeData->centerX == edgeData->rect_1.left) {
ViewMap::mapHalfHeight = -ViewMap::MapDisplayWinHalfWidth;
} else if (edgeData->centerX == edgeData->rect_1.right) {
ViewMap::mapHalfHeight = ViewMap::MapDisplayWinHalfWidth;
}
if (edgeData->centerY == edgeData->rect_1.top) {
ViewMap::mapHalfWidth = -ViewMap::MapDisplayWinHalfHeight;
} else if (edgeData->centerY == edgeData->rect_1.bottom) {
ViewMap::mapHalfWidth = ViewMap::MapDisplayWinHalfHeight;
}
long cX = edgeData->centerX;
long cY = edgeData->centerY;
ViewMap::GetCoord(cX, cY);
return cX + (cY * 200); // tile of center?
}
// Implementation from HRP by Mash
long EdgeBorder::CheckBorder(long tile) {
long y, x;
ViewMap::GetTileCoordOffset(tile, x, y);
if (x > CurrentMapEdge->rect_1.left || x < CurrentMapEdge->rect_1.right ||
y > CurrentMapEdge->rect_1.bottom || y < CurrentMapEdge->rect_1.top)
{
return 0;
}
long _mapHalfWidth = ViewMap::mapHalfWidth;
long _mapHalfHeight = ViewMap::mapHalfHeight;
ViewMap::mapHalfHeight = 0;
ViewMap::mapHalfWidth = 0;
long halfWidth = 0;
long halfHeight = 0;
if (x == CurrentMapEdge->rect_1.left) {
halfWidth = -ViewMap::MapDisplayWinHalfWidth;
ViewMap::mapHalfHeight = halfWidth;
} else if (x == CurrentMapEdge->rect_1.right) {
halfWidth = ViewMap::MapDisplayWinHalfWidth;
ViewMap::mapHalfHeight = halfWidth;
}
if (y == CurrentMapEdge->rect_1.top) {
halfHeight = -ViewMap::MapDisplayWinHalfHeight;
ViewMap::mapHalfWidth = halfHeight;
} else if (y == CurrentMapEdge->rect_1.bottom) {
halfHeight = ViewMap::MapDisplayWinHalfHeight;
ViewMap::mapHalfWidth = halfHeight;
}
return (_mapHalfHeight != halfWidth || _mapHalfWidth != halfHeight) ? 1 : -1;
}
void EdgeBorder::init() {
//HookCall(0x482AE1, map_load_hook_db_fopen);
HookCall(0x482AE1, map_load_hook_db_fopen);
}
}
+2
View File
@@ -13,6 +13,8 @@ class EdgeBorder {
public:
static void init();
static long GetCenterTile(long tile, long mapLevel);
static long CheckBorder(long tile);
};
}
+105 -4
View File
@@ -20,6 +20,18 @@ long ViewMap::SCROLL_DIST_Y;
static long mapDisplayWinWidthMod;
static long mapDisplayWinHeightMod;
long ViewMap::MapDisplayWinHalfWidth;
long ViewMap::MapDisplayWinHalfHeight;
long ViewMap::mapHalfWidth;
long ViewMap::mapHalfHeight;
void ViewMap::GetCoord(long &inOutX, long &inOutY) {
int y = inOutY / 24;
int x = (inOutX / 32) + y - 100;
inOutX = x;
inOutY = (2 * y) - (x / 2);
}
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 ???
@@ -38,17 +50,103 @@ void ViewMap::GetTileCoordOffset(long tile, long &outX, long &outY) {
}
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
outW = wHalf - mapDisplayWinWidthMod; // truncated by 32 units
long hHalf = mapWinHeight >> 1; // 720/2 = 360
mapDisplayWinHeightMod = hHalf % 24; // 360%24=0
outH = hHalf - mapDisplayWinHeightMod; // truncate by 24 units
outH = hHalf - mapDisplayWinHeightMod; // truncated by 24 units
}
// Implementation from HRP by Mash
static long __fastcall tile_set_center(long tile, long modeFlags) {
if (tile < 0 || tile >= 40000) return -1; // _grid_size
long mapElevation = fo::var::map_elevation;
if (modeFlags) tile = EdgeBorder::GetCenterTile(tile, mapElevation);
if (!(modeFlags & 2) && fo::var::getInt(FO_VAR_scroll_limiting_on)) {
long x = 0, y = 0;
ViewMap::GetTileCoord(tile, x, y);
long dudeX = 0, dudeY = 0;
ViewMap::GetTileCoord(fo::var::obj_dude->tile, dudeX, dudeY);
long distanceX = 16 * std::abs(x - dudeX);
long distanceY = 12 * std::abs(y - dudeY);
if (distanceX >= ViewMap::SCROLL_DIST_X || distanceY >= ViewMap::SCROLL_DIST_Y) { // doesn't seem to work
long centerX = 0, centerY = 0;
ViewMap::GetTileCoord(fo::var::getInt(FO_VAR_tile_center_tile), centerX, centerY);
if ((16 * std::abs(centerX - tile)) < distanceX || (12 * std::abs(centerY - dudeY)) < distanceY) {
return -1;
}
}
}
if (!(modeFlags & 2) && fo::var::getInt(FO_VAR_scroll_blocking_on)) {
long result = EdgeBorder::CheckBorder(tile);
if (!result) return -1; // scroll block?
if (result == 1) modeFlags |= 1; // redraw
}
long mapWinW = fo::var::getInt(FO_VAR_buf_width_2);
long mapWinH = fo::var::getInt(FO_VAR_buf_length_2);
long tile_offx = ViewMap::mapHalfHeight + (mapWinW - 32) / 2;
long tile_offy = ViewMap::mapHalfWidth + (mapWinH - 16) / 2;
/* vanilla code */
fo::var::setInt(FO_VAR_tile_center_tile) = tile;
long tile_y = tile / 200; // _grid_width
long tile_x = 200 - (tile % 200) - 1;
if (tile_x & 1) {
tile_x--;
tile_offx -= 32;
}
fo::var::setInt(FO_VAR_tile_x) = tile_x;
fo::var::setInt(FO_VAR_tile_y) = tile_y;
fo::var::setInt(FO_VAR_tile_offx) = tile_offx;
fo::var::setInt(FO_VAR_tile_offy) = tile_offy;
if (tile_y & 1) {
tile_offy -= 12;
tile_offx -= 16;
}
// set square variables
fo::var::square_rect.x = tile_x / 2;
fo::var::square_rect.y = tile_y / 2;
fo::var::square_rect.offx = tile_offx - 16;
fo::var::square_rect.offy = tile_offy - 2;
//fo::var::setInt(FO_VAR_square_x) = tile_x / 2;
//fo::var::setInt(FO_VAR_square_y) = tile_y / 2;
//fo::var::setInt(FO_VAR_square_offx) = tile_offx - 16;
//fo::var::setInt(FO_VAR_square_offy) = tile_offy - 2;
if (modeFlags & 1) fo::func::tile_refresh_display();
return 0; //-1;
}
static void __declspec(naked) tile_set_center_hack_replacement() {
__asm {
push ecx;
mov ecx, eax;
call tile_set_center;
pop ecx;
retn;
}
}
void ViewMap::init() {
@@ -57,8 +155,11 @@ void ViewMap::init() {
if (SCROLL_DIST_Y < 400) SCROLL_DIST_Y = 400;
MakeJump(fo::funcoffs::tile_set_center_, tile_set_center_hack_replacement); // 0x4B12F8
MakeJump(fo::funcoffs::tile_scroll_to_, tile_set_center_hack_replacement);
// Dev block tile_set_border_
BlockCall(0x4B11A3); // tile_init_
//BlockCall(0x4B11A3); // tile_init_
EdgeBorder::init();
}
+7
View File
@@ -16,6 +16,13 @@ public:
static long SCROLL_DIST_X;
static long SCROLL_DIST_Y;
static long MapDisplayWinHalfWidth;
static long MapDisplayWinHalfHeight;
static long mapHalfWidth;
static long mapHalfHeight;
static void GetCoord(long &inOutX, long &inOutY);
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);