ref: 532661b0cfcebb414ce17b6a005259b34ed032b3
parent: 08ee4c96a7b478fa4b9eb121e707da8e0651fe1e
author: Clownacy <[email protected]>
date: Sun Feb 24 09:35:35 EST 2019
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
--- 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"
--- a/src/Back.cpp
+++ b/src/Back.cpp
@@ -34,32 +34,24 @@
return FALSE;
}
-#ifdef FIX_BUGS // TODO: Maybe we need a 'BETTER_PORTABILITY' flag
- if (fgetc(fp) != 'B' || fgetc(fp) != 'M')
- {
- fclose(fp);
- return FALSE;
- }
-
- fseek(fp, 18, SEEK_SET);
-
- gBack.partsW = File_ReadLE32(fp);
- gBack.partsH = File_ReadLE32(fp);
- fclose(fp);
-#else
+#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];
- int16_t bmp_header_buffer[7];
- int32_t bmp_header_buffer2[10]; // We'll need a better solution when we stop using stdint.h
+ 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)
- return FALSE; // The original game forgets to close fp
+ {
+#ifdef FIX_BUGS
+ // The original game forgets to close fp
+ fclose(fp);
+#endif
+ return FALSE;
+ }
fread(bmp_header_buffer2, 40, 1, fp);
fclose(fp);
@@ -66,6 +58,18 @@
gBack.partsW = bmp_header_buffer2[1];
gBack.partsH = bmp_header_buffer2[2];
+#else
+ if (fgetc(fp) != 'B' || fgetc(fp) != 'M')
+ {
+ fclose(fp);
+ return FALSE;
+ }
+
+ fseek(fp, 18, SEEK_SET);
+
+ gBack.partsW = File_ReadLE32(fp);
+ gBack.partsH = File_ReadLE32(fp);
+ fclose(fp);
#endif
//Set background stuff and load texture
--- 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 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)
{
- //Read tiledata
- fread(gMap.data, 1, gMap.length * gMap.width, fp);
fclose(fp);
- return TRUE;
+ return FALSE;
}
else
{
+ //Read tiledata
+ fread(gMap.data, 1, gMap.length * gMap.width, fp);
fclose(fp);
- return FALSE;
+ return TRUE;
}
}
- else
- {
- fclose(fp);
- return FALSE;
- }
-
+
return FALSE;
}
@@ -74,11 +83,11 @@
//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 @@
void EndMapData()
{
- if (gMap.data)
- free(gMap.data);
+ free(gMap.data);
}
void ReleasePartsImage()
@@ -106,60 +114,74 @@
*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,35 +189,43 @@
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);
}
}
}
@@ -202,71 +232,77 @@
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);
}
}
}
--- a/src/Map.h
+++ b/src/Map.h
@@ -20,7 +20,7 @@
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);
--- 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 @@
npc->y += 0x2000;
}
- npc->rect = rect[0];
+ npc->rect = rect;
}
//Experience
--- 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 @@
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 @@
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 @@
//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