shithub: cstory

Download patch

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="&quot;SDL2-2.0.9/include&quot;;&quot;freetype-2.9.1/include&quot;;./"
-				PreprocessorDefinitions="WIN32;_DEBUG;WINDOWS"
+				PreprocessorDefinitions="WIN32;_DEBUG;WINDOWS;NONPORTABLE"
 				MinimalRebuild="TRUE"
 				BasicRuntimeChecks="0"
 				RuntimeLibrary="1"
@@ -73,7 +73,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				AdditionalIncludeDirectories="&quot;SDL2-2.0.9/include&quot;;&quot;freetype-2.9.1/include&quot;;./"
-				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