From 532661b0cfcebb414ce17b6a005259b34ed032b3 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Sun, 24 Feb 2019 14:35:35 +0000 Subject: [PATCH] Made Map.cpp and some of NpcAct020.cpp ASM-accurate Also added a new constant 'NONPORTABLE', for enabling bits of code that are non-portable, but needed for accuracy --- msvc2003/CSE2.vcproj | 4 +- src/Back.cpp | 46 ++++--- src/Map.cpp | 310 ++++++++++++++++++++++++------------------- src/Map.h | 2 +- src/NpcAct000.cpp | 4 +- src/NpcAct020.cpp | 16 +-- 6 files changed, 211 insertions(+), 171 deletions(-) diff --git a/msvc2003/CSE2.vcproj b/msvc2003/CSE2.vcproj index 0d607c82..d5aa2256 100644 --- a/msvc2003/CSE2.vcproj +++ b/msvc2003/CSE2.vcproj @@ -22,7 +22,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=""SDL2-2.0.9/include";"freetype-2.9.1/include";./" - PreprocessorDefinitions="WIN32;_DEBUG;WINDOWS" + PreprocessorDefinitions="WIN32;_DEBUG;WINDOWS;NONPORTABLE" MinimalRebuild="TRUE" BasicRuntimeChecks="0" RuntimeLibrary="1" @@ -73,7 +73,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=""SDL2-2.0.9/include";"freetype-2.9.1/include";./" - PreprocessorDefinitions="WIN32;NDEBUG;WINDOWS" + PreprocessorDefinitions="WIN32;NDEBUG;WINDOWS;NONPORTABLE" MinimalRebuild="TRUE" RuntimeLibrary="0" AssemblerOutput="4" diff --git a/src/Back.cpp b/src/Back.cpp index a3d5139e..3dbca733 100644 --- a/src/Back.cpp +++ b/src/Back.cpp @@ -34,7 +34,31 @@ BOOL InitBack(const char *fName, int type) return FALSE; } -#ifdef FIX_BUGS // TODO: Maybe we need a 'BETTER_PORTABILITY' flag +#ifdef NONPORTABLE + // This is ridiculously platform-dependant: + // It should break on big-endian CPUs, and platforms + // where short isn't 16-bit and long isn't 32-bit. + short bmp_header_buffer[7]; + long bmp_header_buffer2[10]; + + fread(bmp_header_buffer, 14, 1, fp); + + // Check if this is a valid bitmap file + if (bmp_header_buffer[0] != 0x4D42) // 'MB' (we use hex to prevent a compiler warning) + { +#ifdef FIX_BUGS + // The original game forgets to close fp + fclose(fp); +#endif + return FALSE; + } + + fread(bmp_header_buffer2, 40, 1, fp); + fclose(fp); + + gBack.partsW = bmp_header_buffer2[1]; + gBack.partsH = bmp_header_buffer2[2]; +#else if (fgetc(fp) != 'B' || fgetc(fp) != 'M') { fclose(fp); @@ -46,26 +70,6 @@ BOOL InitBack(const char *fName, int type) gBack.partsW = File_ReadLE32(fp); gBack.partsH = File_ReadLE32(fp); fclose(fp); -#else - // This is ridiculously platform-dependant: - // It should break on big-endian CPUs, and platforms - // where short isn't 16-bit and long isn't 32-bit. -// short bmp_header_buffer[7]; -// long bmp_header_buffer2[10]; - int16_t bmp_header_buffer[7]; - int32_t bmp_header_buffer2[10]; // We'll need a better solution when we stop using stdint.h - - fread(bmp_header_buffer, 14, 1, fp); - - // Check if this is a valid bitmap file - if (bmp_header_buffer[0] != 0x4D42) // 'MB' (we use hex to prevent a compiler warning) - return FALSE; // The original game forgets to close fp - - fread(bmp_header_buffer2, 40, 1, fp); - fclose(fp); - - gBack.partsW = bmp_header_buffer2[1]; - gBack.partsH = bmp_header_buffer2[2]; #endif //Set background stuff and load texture diff --git a/src/Map.cpp b/src/Map.cpp index 817268a9..592fe34f 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -17,6 +17,8 @@ MAP_DATA gMap; +static const char *code_pxma = "PXM"; + BOOL InitMapData2() { gMap.data = (uint8_t*)malloc(PXM_BUFFER_SIZE); @@ -25,47 +27,54 @@ BOOL InitMapData2() BOOL LoadMapData2(const char *path_map) { + unsigned char dum; + //Get path char path[PATH_LENGTH]; sprintf(path, "%s/%s", gDataPath, path_map); - + //Open file FILE *fp = fopen(path, "rb"); if (fp == NULL) return FALSE; - + //Make sure file begins with "PXM" char check[3]; fread(check, 1, 3, fp); - - if (!memcmp(check, "PXM", 3)) + + if (memcmp(check, code_pxma, 3)) { - uint8_t nul; - fread(&nul, 1, 1, fp); - + fclose(fp); + return FALSE; + } + else + { + fread(&dum, 1, 1, fp); //Get width and height +#ifdef NONPORTABLE + // This fails on big-endian hardware, and platforms + // where short is not two bytes long. + fread(&gMap.width, 2, 1, fp); + fread(&gMap.length, 2, 1, fp); +#else gMap.width = File_ReadLE16(fp); gMap.length = File_ReadLE16(fp); - - if (gMap.data) +#endif + + if (gMap.data == NULL) + { + fclose(fp); + return FALSE; + } + else { //Read tiledata fread(gMap.data, 1, gMap.length * gMap.width, fp); fclose(fp); return TRUE; } - else - { - fclose(fp); - return FALSE; - } } - else - { - fclose(fp); - return FALSE; - } - + return FALSE; } @@ -74,11 +83,11 @@ BOOL LoadAttributeData(const char *path_atrb) //Open file char path[260]; sprintf(path, "%s/%s", gDataPath, path_atrb); - + FILE *fp = fopen(path, "rb"); if (fp == NULL) return FALSE; - + //Read data fread(gMap.atrb, 1, 0x100, fp); fclose(fp); @@ -87,8 +96,7 @@ BOOL LoadAttributeData(const char *path_atrb) void EndMapData() { - if (gMap.data) - free(gMap.data); + free(gMap.data); } void ReleasePartsImage() @@ -106,60 +114,74 @@ void GetMapData(uint8_t **data, int16_t *mw, int16_t *ml) *ml = gMap.length; } -int GetAttribute(int x, int y) +unsigned char GetAttribute(int x, int y) { - if (x >= 0 && y >= 0 && gMap.width > x && gMap.length > y) - return gMap.atrb[gMap.data[y * gMap.width + x]]; - return 0; + if (x < 0 || y < 0 || x >= gMap.width || y >= gMap.length) + return 0; + + const size_t a = *(gMap.data + x + gMap.width * y); + return gMap.atrb[a]; } void DeleteMapParts(int x, int y) { - gMap.data[y * gMap.width + x] = 0; + *(gMap.data + x + gMap.width * y) = 0; } void ShiftMapParts(int x, int y) { - --gMap.data[y * gMap.width + x]; + *(gMap.data + x + gMap.width * y) -= 1; } BOOL ChangeMapParts(int x, int y, uint8_t no) { - if (gMap.data[y * gMap.width + x] == no) + if (*(gMap.data + x + gMap.width * y) == no) return FALSE; - gMap.data[y * gMap.width + x] = no; + + *(gMap.data + x + gMap.width * y) = no; + for (int i = 0; i < 3; i++) - SetNpChar(4, x << 13, y << 13, 0, 0, 0, 0, 0); + SetNpChar(4, x * 0x200 * 0x10, y * 0x200 * 0x10, 0, 0, 0, 0, 0); + return TRUE; } void PutStage_Back(int fx, int fy) { + int num_y; + int put_x; + int put_y; + int i; + int j; + int offset; + int atrb; + RECT rect; + int num_x; + //Get range to draw - int num_x = ((WINDOW_WIDTH + 0xF) >> 4) + 1; - int num_y = ((WINDOW_HEIGHT + 0xF) >> 4) + 1; - int put_x = (fx / 0x200 + 8) / 16; - int put_y = (fy / 0x200 + 8) / 16; - - for (int j = put_y; put_y + num_y > j; j++) + num_x = ((WINDOW_WIDTH + 0xF) / 0x10) + 1; + num_y = ((WINDOW_HEIGHT + 0xF) / 0x10) + 1; + put_x = (fx / 0x200 + 8) / 0x10; + put_y = (fy / 0x200 + 8) / 0x10; + + for (j = put_y; j < put_y + num_y; j++) { - for (int i = put_x; put_x + num_x > i; i++) + for (i = put_x; i < put_x + num_x; i++) { //Get attribute - int offset = i + j * gMap.width; - int atrb = GetAttribute(i, j); - - if (atrb < 0x20) - { - //Draw tile - RECT rect; - rect.left = 16 * (gMap.data[offset] & 0xF); - rect.top = 16 * (gMap.data[offset] >> 4); - rect.right = rect.left + 16; - rect.bottom = rect.top + 16; - - PutBitmap3(&grcGame, 8 * (2 * i - 1) - fx / 0x200, 8 * (2 * j - 1) - fy / 0x200, &rect, SURFACE_ID_LEVEL_TILESET); - } + offset = i + j * gMap.width; + atrb = GetAttribute(i, j); + + if (atrb >= 0x20) + continue; + + //Draw tile + rect.left = 16 * (gMap.data[offset] % 0x10); + rect.top = 16 * (gMap.data[offset] / 0x10); + rect.right = rect.left + 16; + rect.bottom = rect.top + 16; + + PutBitmap3(&grcGame, 0x10 * i - 8 - fx / 0x200, 0x10 * j - 8 - fy / 0x200, &rect, SURFACE_ID_LEVEL_TILESET); } } } @@ -167,106 +189,120 @@ void PutStage_Back(int fx, int fy) void PutStage_Front(int fx, int fy) { RECT rcSnack = {256, 48, 272, 64}; - + int num_y; + int put_x; + int put_y; + int j; + int i; + int offset; + int atrb; + RECT rect; + int num_x; + //Get range to draw - int num_x = ((WINDOW_WIDTH + 0xF) >> 4) + 1; - int num_y = ((WINDOW_HEIGHT + 0xF) >> 4) + 1; - int put_x = (fx / 0x200 + 8) / 16; - int put_y = (fy / 0x200 + 8) / 16; - - for (int j = put_y; put_y + num_y > j; j++) + num_x = ((WINDOW_WIDTH + 0xF) >> 4) + 1; + num_y = ((WINDOW_HEIGHT + 0xF) >> 4) + 1; + put_x = (fx / 0x200 + 8) / 16; + put_y = (fy / 0x200 + 8) / 16; + + for (j = put_y; j < put_y + num_y; j++) { - for (int i = put_x; put_x + num_x > i; i++) + for (i = put_x; i < put_x + num_x; i++) { //Get attribute - int offset = i + j * gMap.width; - int atrb = GetAttribute(i, j); - - if (atrb >= 0x40 && atrb < 0x80) - { - //Draw tile - RECT rect; - rect.left = 16 * (gMap.data[offset] & 0xF); - rect.top = 16 * (gMap.data[offset] >> 4); - rect.right = rect.left + 16; - rect.bottom = rect.top + 16; - - PutBitmap3(&grcGame, 8 * (2 * i - 1) - fx / 0x200, 8 * (2 * j - 1) - fy / 0x200, &rect, SURFACE_ID_LEVEL_TILESET); - - if (atrb == 0x43) - PutBitmap3(&grcGame, 8 * (2 * i - 1) - fx / 0x200, 8 * (2 * j - 1) - fy / 0x200, &rcSnack, SURFACE_ID_NPC_SYM); - } + offset = i + j * gMap.width; + atrb = GetAttribute(i, j); + + if (atrb < 0x40 || atrb >= 0x80) + continue; + + //Draw tile + rect.left = 16 * (gMap.data[offset] % 0x10); + rect.top = 16 * (gMap.data[offset] / 0x10); + rect.right = rect.left + 16; + rect.bottom = rect.top + 16; + + PutBitmap3(&grcGame, 16 * i - 8 - fx / 0x200, 16 * j - 8 - fy / 0x200, &rect, SURFACE_ID_LEVEL_TILESET); + + if (atrb == 0x43) + PutBitmap3(&grcGame, 16 * i - 8 - fx / 0x200, 16 * j - 8 - fy / 0x200, &rcSnack, SURFACE_ID_NPC_SYM); } } } void PutMapDataVector(int fx, int fy) { - //Get range to draw - int num_x = ((WINDOW_WIDTH + 0xF) >> 4) + 1; - int num_y = ((WINDOW_HEIGHT + 0xF) >> 4) + 1; - int put_x = (fx / 0x200 + 8) / 16; - int put_y = (fy / 0x200 + 8) / 16; - + int num_y; + int put_x; + int put_y; + int i; + int j; + int offset; + int atrb; + RECT rect; + int num_x; + //Animate the wind - static int count = 0; + static unsigned char count = 0; count += 2; - - for (int j = put_y; put_y + num_y > j; j++) + + //Get range to draw + num_x = ((WINDOW_WIDTH + 0xF) >> 4) + 1; + num_y = ((WINDOW_HEIGHT + 0xF) >> 4) + 1; + put_x = (fx / 0x200 + 8) / 16; + put_y = (fy / 0x200 + 8) / 16; + + for (j = put_y; j < put_y + num_y; j++) { - for (int i = put_x; put_x + num_x > i; i++) + for (i = put_x; i < put_x + num_x; i++) { //Get attribute - int offset = i + j * gMap.width; - int atrb = GetAttribute(i, j); - - if ( atrb == 0x80 - || atrb == 0x81 - || atrb == 0x82 - || atrb == 0x83 - || atrb == 0xA0 - || atrb == 0xA1 - || atrb == 0xA2 - || atrb == 0xA3) + offset = i + j * gMap.width; + atrb = GetAttribute(i, j); + + if (atrb != 0x80 + && atrb != 0x81 + && atrb != 0x82 + && atrb != 0x83 + && atrb != 0xA0 + && atrb != 0xA1 + && atrb != 0xA2 + && atrb != 0xA3) + continue; + + switch (atrb) { - RECT rect; - - switch ( atrb ) - { - case 128: - case 160: - rect.left = (count & 0xF) + 224; - rect.right = (count & 0xF) + 240; - rect.top = 48; - rect.bottom = 64; - break; - case 129: - case 161: - rect.left = 224; - rect.right = 240; - rect.top = (count & 0xF) + 48; - rect.bottom = (count & 0xF) + 64; - break; - case 130: - case 162: - rect.left = 240 - (count & 0xF); - rect.right = rect.left + 16; - rect.top = 48; - rect.bottom = 64; - break; - case 131: - case 163: - rect.left = 224; - rect.right = 240; - rect.top = 64 - (count & 0xF); - rect.bottom = rect.top + 16; - break; - default: - break; - } - - PutBitmap3(&grcGame, 8 * (2 * i - 1) - fx / 0x200, 8 * (2 * j - 1) - fy / 0x200, &rect, SURFACE_ID_CARET); + case 128: + case 160: + rect.left = 224 + (count % 0x10); + rect.right = rect.left + 16; + rect.top = 48; + rect.bottom = rect.top + 16; + break; + case 129: + case 161: + rect.left = 224; + rect.right = rect.left + 16; + rect.top = 48 + (count % 0x10); + rect.bottom = rect.top + 16; + break; + case 130: + case 162: + rect.left = 240 - (count % 0x10); + rect.right = rect.left + 16; + rect.top = 48; + rect.bottom = rect.top + 16; + break; + case 131: + case 163: + rect.left = 224; + rect.right = rect.left + 16; + rect.top = 64 - (count % 0x10); + rect.bottom = rect.top + 16; + break; } + + PutBitmap3(&grcGame, 16 * i - 8 - fx / 0x200, 16 * j - 8 - fy / 0x200, &rect, SURFACE_ID_CARET); } } } diff --git a/src/Map.h b/src/Map.h index 4581fe48..858fa998 100644 --- a/src/Map.h +++ b/src/Map.h @@ -20,7 +20,7 @@ BOOL LoadAttributeData(const char *path_atrb); void EndMapData(); void ReleasePartsImage(); void GetMapData(uint8_t **data, int16_t *mw, int16_t *ml); -int GetAttribute(int x, int y); +unsigned char GetAttribute(int x, int y); void DeleteMapParts(int x, int y); void ShiftMapParts(int x, int y); BOOL ChangeMapParts(int x, int y, uint8_t no); diff --git a/src/NpcAct000.cpp b/src/NpcAct000.cpp index e17b6930..a3732e8f 100644 --- a/src/NpcAct000.cpp +++ b/src/NpcAct000.cpp @@ -15,7 +15,7 @@ //Null void ActNpc000(NPCHAR *npc) { - RECT rect[1] = {0x00, 0x00, 0x10, 0x10}; + RECT rect = {0x00, 0x00, 0x10, 0x10}; if (npc->act_no == 0) { @@ -25,7 +25,7 @@ void ActNpc000(NPCHAR *npc) npc->y += 0x2000; } - npc->rect = rect[0]; + npc->rect = rect; } //Experience diff --git a/src/NpcAct020.cpp b/src/NpcAct020.cpp index 5563b141..8ff8d440 100644 --- a/src/NpcAct020.cpp +++ b/src/NpcAct020.cpp @@ -14,7 +14,7 @@ //Computer void ActNpc020(NPCHAR *npc) { - RECT rcLeft[1] = {288, 16, 320, 40}; + RECT rcLeft = {288, 16, 320, 40}; RECT rcRight[3] = { {288, 40, 320, 64}, @@ -32,7 +32,7 @@ void ActNpc020(NPCHAR *npc) npc->ani_no = 0; if (npc->direct == 0) - npc->rect = rcLeft[0]; + npc->rect = rcLeft; else npc->rect = rcRight[npc->ani_no]; } @@ -48,9 +48,9 @@ void ActNpc021(NPCHAR *npc) npc->y += 0x2000; } - RECT rect[1] = {224, 40, 240, 48}; + RECT rect = {224, 40, 240, 48}; - npc->rect = rect[0]; + npc->rect = rect; } //Teleporter @@ -1008,13 +1008,13 @@ void ActNpc033(NPCHAR *npc) //Bed void ActNpc034(NPCHAR *npc) { - RECT rcLeft[1] = {192, 48, 224, 64}; - RECT rcRight[1] = {192, 184, 224, 200}; + RECT rcLeft = {192, 48, 224, 64}; + RECT rcRight = {192, 184, 224, 200}; if (npc->direct == 0) - npc->rect = rcLeft[0]; + npc->rect = rcLeft; else - npc->rect = rcRight[0]; + npc->rect = rcRight; } //Mannan