shithub: cstory

Download patch

ref: 22f994eee7b62f986058e800b68ef44d244baacd
parent: 929adaabf0837f081023d0725a06c8675ed64bc1
parent: 98c5db93f272e1068bc02a3e408737412f207aaa
author: Gabriel Ravier <gabravier@gmail.com>
date: Sun May 12 12:04:06 EDT 2019

Merge branch 'master' into makeFlagsMacros

--- a/msvc2003/devilution/comparer-config.toml
+++ b/msvc2003/devilution/comparer-config.toml
@@ -516,6 +516,66 @@
 addr = 0x414B40
 
 [[func]]
+name = "AddExpMyChar"
+addr = 0x4196F0
+
+[[func]]
+name = "ZeroExpMyChar"
+addr = 0x419890
+
+[[func]]
+name = "IsMaxExpMyChar"
+addr = 0x4198C0
+
+[[func]]
+name = "DamageMyChar"
+addr = 0x419910
+
+[[func]]
+name = "ZeroArmsEnergy_All"
+addr = 0x419B50
+
+[[func]]
+name = "AddBulletMyChar"
+addr = 0x419BA0
+
+[[func]]
+name = "AddLifeMyChar"
+addr = 0x419C60
+
+[[func]]
+name = "AddMaxLifeMyChar"
+addr = 0x419CB0
+
+[[func]]
+name = "PutArmsEnergy"
+addr = 0x419D10
+
+[[func]]
+name = "PutActiveArmsList"
+addr = 0x41A0B0
+
+[[func]]
+name = "PutMyLife"
+addr = 0x41A1D0
+
+[[func]]
+name = "PutMyAir"
+addr = 0x41A350
+
+[[func]]
+name = "PutTimeCounter"
+addr = 0x41A430
+
+[[func]]
+name = "SaveTimeCounter"
+addr = 0x41A5D0
+
+[[func]]
+name = "LoadTimeCounter"
+addr = 0x41A7C0
+
+[[func]]
 name = "ChangeOrganFrequency"
 addr = 0x41ABA0
 size = 0xC9
@@ -569,6 +629,22 @@
 [[func]]
 name = "MakePixelWaveData"
 addr = 0x41CB10
+
+[[func]]
+name = "IsProfile"
+addr = 0x41CFC0
+
+[[func]]
+name = "SaveProfile"
+addr = 0x41D040
+
+[[func]]
+name = "LoadProfile"
+addr = 0x41D260
+
+[[func]]
+name = "InitializeGame"
+addr = 0x41D550
 
 [[func]]
 name = "ShootBullet_Frontia1"
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -49,7 +49,7 @@
 int g_GameFlags;
 int gCounter;
 
-bool bContinue;
+BOOL bContinue;
 
 int Random(int min, int max)
 {
@@ -275,13 +275,13 @@
 	//Set character
 	time_counter = LoadTimeCounter();
 
-	if (time_counter && time_counter < 18000)
+	if (time_counter && time_counter < 6 * 60 * 50)	// 6 minutes
 		char_type = 1;
-	if (time_counter && time_counter < 15000)
+	if (time_counter && time_counter < 5 * 60 * 50)	// 5 minutes
 		char_type = 2;
-	if (time_counter && time_counter < 12000)
+	if (time_counter && time_counter < 4 * 60 * 50)	// 4 minutes
 		char_type = 3;
-	if (time_counter && time_counter < 9000)
+	if (time_counter && time_counter < 3 * 60 * 50)	// 3 minutes
 		char_type = 4;
 
 	//Set music to character's specific music
@@ -405,7 +405,7 @@
 		}
 
 		int char_y;
-		if (bContinue == 1)
+		if (bContinue == TRUE)
 			char_y = (WINDOW_HEIGHT + 54) / 2;
 		else
 			char_y = (WINDOW_HEIGHT + 14) / 2;
--- a/src/MycParam.cpp
+++ b/src/MycParam.cpp
@@ -46,9 +46,9 @@
 
 	if (lv == 2)
 	{
-		if (gArmsData[gSelectedArms].exp >= gArmsLevelTable[0].exp[3 * arms_code + 2])
+		if (gArmsData[gSelectedArms].exp >= gArmsLevelTable[arms_code].exp[lv])
 		{
-			gArmsData[gSelectedArms].exp = gArmsLevelTable[0].exp[3 * arms_code + 2];
+			gArmsData[gSelectedArms].exp = gArmsLevelTable[arms_code].exp[lv];
 
 			if (gMC.equip & 0x80)
 			{
@@ -59,9 +59,9 @@
 	}
 	else
 	{
-		while (lv <= 1)
+		for (; lv < 2; ++lv)
 		{
-			if (gArmsData[gSelectedArms].exp >= gArmsLevelTable[0].exp[lv + 3 * arms_code])
+			if (gArmsData[gSelectedArms].exp >= gArmsLevelTable[arms_code].exp[lv])
 			{
 				++gArmsData[gSelectedArms].level;
 				gArmsData[gSelectedArms].exp = 0;
@@ -72,19 +72,17 @@
 					SetCaret(gMC.x, gMC.y, 10, 0);
 				}
 			}
-
-			++lv;
 		}
 	}
 
-	if (gArmsData[gSelectedArms].code == 13)
+	if (gArmsData[gSelectedArms].code != 13)
 	{
-		gMC.exp_wait = 10;
+		gMC.exp_count += x;
+		gMC.exp_wait = 30;
 	}
 	else
 	{
-		gMC.exp_count += x;
-		gMC.exp_wait = 30;
+		gMC.exp_wait = 10;
 	}
 }
 
@@ -96,58 +94,87 @@
 
 BOOL IsMaxExpMyChar()
 {
-	return gArmsData[gSelectedArms].level == 3
-		&& gArmsData[gSelectedArms].exp >= gArmsLevelTable[gArmsData[gSelectedArms].code].exp[2];
+	if (gArmsData[gSelectedArms].level == 3)
+	{
+		int arms_code = gArmsData[gSelectedArms].code;
+
+		if (gArmsData[gSelectedArms].exp >= gArmsLevelTable[arms_code].exp[2])
+			return TRUE;
+	}
+
+	return FALSE;
 }
 
 void DamageMyChar(int damage)
 {
-	if (!gMC.shock)
+#ifdef FIX_BUGS
+	if ((g_GameFlags & 2) == 0)
+#else
+	// I'm preeeetty sure this is a typo. The Linux port optimised it out.
+	if ((g_GameFlags | 2) == 0)
+#endif
+		return;
+
+	if (gMC.shock)
+		return;
+
+	// Damage player
+	PlaySoundObject(16, 1);
+	gMC.cond &= ~1;
+	gMC.shock = 128;
+
+	if (gMC.unit == 1)
 	{
-		// Damage player
-		PlaySoundObject(16, 1);
-		gMC.cond &= ~1;
-		gMC.shock = 128;
-		if (gMC.unit != 1)
-			gMC.ym = -0x400;
-		gMC.life -= damage;
+		// Another weird case where there *has* to be an empty 'if' here to produce the same assembly
+	}
+	else
+	{
+		gMC.ym = -0x400;
+	}
 
-		// Lose a whimsical star
-		if (gMC.equip & 0x80 && gMC.star > 0)
-			--gMC.star;
+	gMC.life -= (short)damage;
 
-		// Lose experience
-		if (gMC.equip & 4)
-			gArmsData[gSelectedArms].exp -= damage;
-		else
-			gArmsData[gSelectedArms].exp -= 2 * damage;
+	// Lose a whimsical star
+	if (gMC.equip & 0x80 && gMC.star > 0)
+		gMC.star = (short)gMC.star - 1;	// Why the hell is it written this way?
 
-		while (gArmsData[gSelectedArms].exp < 0)
+	// Lose experience
+	if (gMC.equip & 4)
+		gArmsData[gSelectedArms].exp -= damage;
+	else
+		gArmsData[gSelectedArms].exp -= 2 * damage;
+
+	while (gArmsData[gSelectedArms].exp < 0)
+	{
+		if (gArmsData[gSelectedArms].level > 1)
 		{
-			if (gArmsData[gSelectedArms].level <= 1)
-			{
-				gArmsData[gSelectedArms].exp = 0;
-			}
-			else
-			{
-				gArmsData[gSelectedArms].exp += gArmsLevelTable[0].exp[--gArmsData[gSelectedArms].level - 1 + 3 * gArmsData[gSelectedArms].code];
-				if (gMC.life > 0 && gArmsData[gSelectedArms].code != 13)
-					SetCaret(gMC.x, gMC.y, 10, 2);
-			}
-		}
+			--gArmsData[gSelectedArms].level;
 
-		// Tell player how much damage was taken
-		SetValueView(&gMC.x, &gMC.y, -damage);
+			int lv = gArmsData[gSelectedArms].level - 1;
+			int arms_code = gArmsData[gSelectedArms].code;
 
-		// Death
-		if (gMC.life <= 0)
+			gArmsData[gSelectedArms].exp = gArmsLevelTable[arms_code].exp[lv] + gArmsData[gSelectedArms].exp;
+
+			if (gMC.life > 0 && gArmsData[gSelectedArms].code != 13)
+				SetCaret(gMC.x, gMC.y, 10, 2);
+		}
+		else
 		{
-			PlaySoundObject(17, 1);
-			gMC.cond = 0;
-			SetDestroyNpChar(gMC.x, gMC.y, 0x1400, 0x40);
-			StartTextScript(40);
+			gArmsData[gSelectedArms].exp = 0;
 		}
 	}
+
+	// Tell player how much damage was taken
+	SetValueView(&gMC.x, &gMC.y, -damage);
+
+	// Death
+	if (gMC.life <= 0)
+	{
+		PlaySoundObject(17, 1);
+		gMC.cond = 0;
+		SetDestroyNpChar(gMC.x, gMC.y, 0x1400, 0x40);
+		StartTextScript(40);
+	}
 }
 
 void ZeroArmsEnergy_All()
@@ -161,34 +188,31 @@
 
 void AddBulletMyChar(int no, int val)
 {
+	int a = 0;
+
 	// Missile Launcher
-	for (int a = 0; a < ARMS_MAX; a++)
-	{
-		if (gArmsData[a].code == 5)
-		{
-			gArmsData[a].num += val;
-			if (gArmsData[a].num > gArmsData[a].max_num)
-				gArmsData[a].num = gArmsData[a].max_num;
-			break;
-		}
-	}
+	while (a < ARMS_MAX && gArmsData[a].code != 5)
+		++a;
 
-	// Super Missile Launcher
-	for (int a = 0; a < ARMS_MAX; a++)
+	if (a == ARMS_MAX)
 	{
-		if (gArmsData[a].code == 10)
-		{
-			gArmsData[a].num += val;
-			if (gArmsData[a].num > gArmsData[a].max_num)
-				gArmsData[a].num = gArmsData[a].max_num;
-			break;
-		}
+		// Super Missile Launcher
+		a = 0;
+		while (a < ARMS_MAX && gArmsData[a].code != 10)
+			++a;
+
+		if (a == ARMS_MAX)
+			return;
 	}
+
+	gArmsData[a].num += val;
+	if (gArmsData[a].num > gArmsData[a].max_num)
+		gArmsData[a].num = gArmsData[a].max_num;
 }
 
 void AddLifeMyChar(int x)
 {
-	gMC.life += x;
+	gMC.life += (short)x;
 	if (gMC.life > gMC.max_life)
 		gMC.life = gMC.max_life;
 	gMC.lifeBr = gMC.life;
@@ -196,15 +220,25 @@
 
 void AddMaxLifeMyChar(int val)
 {
-	gMC.max_life += val;
+	gMC.max_life += (short)val;
 	if (gMC.max_life > 232)
 		gMC.max_life = 232;
-	gMC.life += val;
+	gMC.life += (short)val;
 	gMC.lifeBr = gMC.life;
 }
 
-void PutArmsEnergy(bool flash)
+void PutArmsEnergy(BOOL flash)
 {
+	RECT rcExpBox;
+	RECT rcExpVal;
+	RECT rcExpMax;
+	RECT rcExpFlash;
+
+	int lv;
+	int arms_code;
+	int exp_now;
+	int exp_next;
+
 	RECT rcPer = {72, 48, 80, 56};
 	RECT rcLv = {80, 80, 96, 88};
 	RECT rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT};
@@ -228,107 +262,111 @@
 	}
 
 	// Draw experience and ammo
-	if (!flash || !((gMC.shock >> 1) & 1))
-	{
-		PutBitmap3(&rcView, gArmsEnergyX + 32, 24, &rcPer, SURFACE_ID_TEXT_BOX);
-		PutBitmap3(&rcView, gArmsEnergyX, 32, &rcLv, SURFACE_ID_TEXT_BOX);
-		PutNumber4(gArmsEnergyX - 8, 32, gArmsData[gSelectedArms].level, 0);
+	if (flash == TRUE && (gMC.shock / 2) % 2)
+		return;
 
-		RECT rcExpBox = {0, 72, 40, 80};
-		RECT rcExpVal = {0, 80, 0, 88};
-		RECT rcExpMax = {40, 72, 80, 80};
-		RECT rcExpFlash = {40, 80, 80, 88};
+	PutBitmap3(&rcView, gArmsEnergyX + 32, 24, &rcPer, SURFACE_ID_TEXT_BOX);
+	PutBitmap3(&rcView, gArmsEnergyX, 32, &rcLv, SURFACE_ID_TEXT_BOX);
+	PutNumber4(gArmsEnergyX - 8, 32, gArmsData[gSelectedArms].level, 0);
 
-		int lv = gArmsData[gSelectedArms].level - 1;
-		int arms_code = gArmsData[gSelectedArms].code;
-		int exp_now = gArmsData[gSelectedArms].exp;
-		int exp_next = gArmsLevelTable[0].exp[lv + 3 * arms_code];
+	SET_RECT(rcExpBox, 0, 72, 40, 80)
+	SET_RECT(rcExpVal, 0, 80, 0, 88)
+	SET_RECT(rcExpMax, 40, 72, 80, 80)
+	SET_RECT(rcExpFlash, 40, 80, 80, 88)
 
-		PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpBox, SURFACE_ID_TEXT_BOX);
+	lv = gArmsData[gSelectedArms].level - 1;
+	arms_code = gArmsData[gSelectedArms].code;
+	exp_now = gArmsData[gSelectedArms].exp;
+	exp_next = gArmsLevelTable[arms_code].exp[lv];
 
-		if (lv != 2 || gArmsData[gSelectedArms].exp != gArmsLevelTable[0].exp[3 * arms_code + 2])
-		{
-			if (exp_next)
-				rcExpVal.right += 40 * exp_now / exp_next;
-			else
-				rcExpVal.right = 0;
+	PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpBox, SURFACE_ID_TEXT_BOX);
 
-			PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpVal, SURFACE_ID_TEXT_BOX);
-		}
+	if (lv == 2 && gArmsData[gSelectedArms].exp == gArmsLevelTable[arms_code].exp[lv])
+	{
+		PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpMax, SURFACE_ID_TEXT_BOX);
+	}
+	else
+	{
+		if (exp_next)
+			rcExpVal.right += 40 * exp_now / exp_next;
 		else
-		{
-			PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpMax, SURFACE_ID_TEXT_BOX);
-		}
+			rcExpVal.right = 0;
 
-		static int add_flash = true;
-		if (gMC.exp_wait && ((add_flash++ >> 1) & 1))
-			PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpFlash, SURFACE_ID_TEXT_BOX);
+		PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpVal, SURFACE_ID_TEXT_BOX);
 	}
+
+	static unsigned char add_flash;
+	if (gMC.exp_wait && ((add_flash++ / 2) % 2))
+		PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpFlash, SURFACE_ID_TEXT_BOX);
 }
 
 void PutActiveArmsList()
 {
+	int x;
+	int a;
+	int arms_num;
 	RECT rect = {0, 0, 0, 16};
 
-	int arms_num;
-	for (arms_num = 0; gArmsData[arms_num].code != 0; ++arms_num);
+	arms_num = 0;
+	while (gArmsData[arms_num].code != 0)
+		++arms_num;
 
-	if (arms_num)
+	if (arms_num == 0)
+		return;
+
+	for (a = 0; a < arms_num; a++)
 	{
-		for (int a = 0; a < arms_num; a++)
-		{
-			// Get X position to draw at
-			int x = 16 * (a - gSelectedArms) + gArmsEnergyX;
+		// Get X position to draw at
+		x = 16 * (a - gSelectedArms) + gArmsEnergyX;
 
-			if (x >= 8)
-			{
-				if (x >= 24)
-					x += 48;
-			}
-			else
-			{
-				x += 16 * (arms_num + 3);
-			}
+		if (x < 8)
+			x += 48 + (16 * arms_num);
+		else if (x >= 24)
+			x += 48;
 
-			if (8 * (2 * (arms_num + 3) + 1) <= x)
-				x += 16 * (-3 - arms_num);
-			if (x < 72 && x >= 24)
-				x -= 48;
+		if (x >= 72 + (16 * (arms_num - 1)))
+			x -= 48 + (16 * arms_num);
+		if (x < 72 && x >= 24)
+			x -= 48;
 
-			// Draw icon
-			rect.left = 16 * gArmsData[a].code;
-			rect.right = rect.left + 16;
-			PutBitmap3(&grcGame, x, 16, &rect, SURFACE_ID_ARMS_IMAGE);
-		}
+		// Draw icon
+		rect.left = 16 * gArmsData[a].code;
+		rect.right = rect.left + 16;
+		PutBitmap3(&grcGame, x, 16, &rect, SURFACE_ID_ARMS_IMAGE);
 	}
 }
 
-void PutMyLife(bool flash)
+void PutMyLife(BOOL flash)
 {
 	RECT rcCase = {0, 40, 232, 48};
 	RECT rcLife = {0, 24, 232, 32};
 	RECT rcBr = {0, 32, 232, 40};
 
-	if (!flash || !((gMC.shock >> 1) & 1))
-	{
-		if (gMC.lifeBr < gMC.life)
-			gMC.lifeBr = gMC.life;
+	if (flash == TRUE && (gMC.shock / 2) % 2)
+		return;
 
-		if (gMC.lifeBr <= gMC.life)
-			gMC.lifeBr_count = 0;
-		else if (++gMC.lifeBr_count > 30)
+	if (gMC.lifeBr < gMC.life)
+		gMC.lifeBr = gMC.life;
+
+	if (gMC.lifeBr > gMC.life)
+	{
+		if (++gMC.lifeBr_count > 30)
 			--gMC.lifeBr;
+	}
+	else
+	{
+		gMC.lifeBr_count = 0;
+	}
 
-		// Draw bar
-		rcCase.right = 64;
-		rcLife.right = 40 * gMC.life / gMC.max_life - 1;
-		rcBr.right = 40 * gMC.lifeBr / gMC.max_life - 1;
+	// Draw bar
+	rcCase.right = 64;
+	rcLife.right = 40 * gMC.life / gMC.max_life - 1;
+	rcBr.right = 40 * gMC.lifeBr / gMC.max_life - 1;
 
-		PutBitmap3(&grcGame, 16, 40, &rcCase, SURFACE_ID_TEXT_BOX);
-		PutBitmap3(&grcGame, 40, 40, &rcBr, SURFACE_ID_TEXT_BOX);
-		PutBitmap3(&grcGame, 40, 40, &rcLife, SURFACE_ID_TEXT_BOX);
-		PutNumber4(8, 40, gMC.lifeBr, 0);
-	}
+	PutBitmap3(&grcGame, 16, 40, &rcCase, SURFACE_ID_TEXT_BOX);
+	PutBitmap3(&grcGame, 40, 40, &rcBr, SURFACE_ID_TEXT_BOX);
+	PutBitmap3(&grcGame, 40, 40, &rcLife, SURFACE_ID_TEXT_BOX);
+	PutNumber4(8, 40, gMC.lifeBr, 0);
 }
 
 void PutMyAir(int x, int y)
@@ -338,17 +376,20 @@
 		{112, 80, 144, 88},
 	};
 
-	if (!(gMC.equip & 0x10) && gMC.air_get)
+	if (gMC.equip & 0x10)
+		return;
+
+	if (gMC.air_get)
 	{
 		// Draw how much air is left
-		if (gMC.air_get % 6 <= 3)
+		if (gMC.air_get % 6 < 4)
 			PutNumber4(x + 32, y, gMC.air / 10, 0);
 
 		// Draw "AIR" text
-		if (gMC.air % 30 <= 10)
-			PutBitmap3(&grcGame, x, y, &rcAir[1], SURFACE_ID_TEXT_BOX);
-		else
+		if (gMC.air % 30 > 10)
 			PutBitmap3(&grcGame, x, y, &rcAir[0], SURFACE_ID_TEXT_BOX);
+		else
+			PutBitmap3(&grcGame, x, y, &rcAir[1], SURFACE_ID_TEXT_BOX);
 	}
 }
 
@@ -365,13 +406,13 @@
 		// Draw clock and increase time
 		if (g_GameFlags & 2)
 		{
-			if (time_count < 300000)
+			if (time_count < 100 * 60 * 50)	// 100 minutes
 				++time_count;
 
-			if (time_count % 30 <= 10)
-				PutBitmap3(&grcGame, x, y, &rcTime[1], SURFACE_ID_TEXT_BOX);
-			else
+			if (time_count % 30 > 10)
 				PutBitmap3(&grcGame, x, y, &rcTime[0], SURFACE_ID_TEXT_BOX);
+			else
+				PutBitmap3(&grcGame, x, y, &rcTime[1], SURFACE_ID_TEXT_BOX);
 		}
 		else
 		{
@@ -379,7 +420,7 @@
 		}
 
 		// Draw time
-		PutNumber4(x,		y, time_count / 3000,		false);
+		PutNumber4(x,		y, time_count / (60 * 50),	false);
 		PutNumber4(x + 20,	y, time_count / 50 % 60,	true);
 		PutNumber4(x + 32,	y, time_count / 5 % 10,		false);
 		PutBitmap3(&grcGame, x + 30, y, &rcTime[2], SURFACE_ID_TEXT_BOX);
@@ -390,13 +431,16 @@
 	}
 }
 
-bool SaveTimeCounter()
+BOOL SaveTimeCounter()
 {
+	unsigned char *p;
+	int i;
+
 	REC rec;
 
 	// Quit if player doesn't have the Nikumaru Counter
 	if (!(gMC.equip & 0x100))
-		return true;
+		return TRUE;
 
 	// Get last time
 	char path[PATH_LENGTH];
@@ -406,6 +450,9 @@
 	if (fp)
 	{
 		// Read data
+#ifdef NONPORTABLE
+		fread(&rec, sizeof(REC), 1, fp);
+#else
 		rec.counter[0] = File_ReadLE32(fp);
 		rec.counter[1] = File_ReadLE32(fp);
 		rec.counter[2] = File_ReadLE32(fp);
@@ -414,35 +461,53 @@
 		rec.random[1] = fgetc(fp);
 		rec.random[2] = fgetc(fp);
 		rec.random[3] = fgetc(fp);
+#endif
 		fclose(fp);
 
-		uint8_t *p = (uint8_t*)&rec.counter[0];
-		p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[0]) : (rec.random[0] >> 1);
+		p = (unsigned char*)&rec.counter[0];
+#ifdef NONPORTABLE
+		p[0] -= rec.random[0];
 		p[1] -= rec.random[0];
 		p[2] -= rec.random[0];
-		p[3] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[0] >> 1) : (rec.random[0]);
-
+		p[3] -= rec.random[0] / 2;
+#else
+		p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[0]) : (rec.random[0] / 2);
+		p[1] -= rec.random[0];
+		p[2] -= rec.random[0];
+		p[3] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[0] / 2) : (rec.random[0]);
+#endif
 		// If this is faster than our new time, quit
 		if (rec.counter[0] < time_count)
-			return true;
+			return TRUE;
 	}
 
 	// Save new time
-	for (int i = 0; i < 4; i++)
+	for (i = 0; i < 4; i++)
 	{
 		rec.counter[i] = time_count;
 		rec.random[i] = Random(0, 250) + i;
 
-		uint8_t *p = (uint8_t*)&rec.counter[i];
-		p[0] += (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i]) : (rec.random[i] >> 1);
+		p = (unsigned char*)&rec.counter[i];
+#ifdef NONPORTABLE
+		p[0] += rec.random[i];
 		p[1] += rec.random[i];
 		p[2] += rec.random[i];
-		p[3] += (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i] >> 1) : (rec.random[i]);
+		p[3] += rec.random[i] / 2;
+#else
+		p[0] += (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i]) : (rec.random[i] / 2);
+		p[1] += rec.random[i];
+		p[2] += rec.random[i];
+		p[3] += (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i] / 2) : (rec.random[i]);
+#endif
 	}
 
 	fp = fopen(path, "wb");
 	if (fp == NULL)
-		return false;
+		return FALSE;
+
+#ifdef NONPORTABLE
+	fwrite(&rec, sizeof(REC), 1, fp);
+#else
 	File_WriteLE32(rec.counter[0], fp);
 	File_WriteLE32(rec.counter[1], fp);
 	File_WriteLE32(rec.counter[2], fp);
@@ -451,12 +516,17 @@
 	fputc(rec.random[1], fp);
 	fputc(rec.random[2], fp);
 	fputc(rec.random[3], fp);
+#endif
+
 	fclose(fp);
-	return true;
+	return TRUE;
 }
 
 int LoadTimeCounter()
 {
+	unsigned char *p;
+	int i;
+
 	// Open file
 	char path[PATH_LENGTH];
 	sprintf(path, "%s/290.rec", gModulePath);
@@ -468,6 +538,9 @@
 	REC rec;
 
 	// Read data
+#ifdef NONPORTABLE
+	fread(&rec, sizeof(REC), 1, fp);
+#else
 	rec.counter[0] = File_ReadLE32(fp);
 	rec.counter[1] = File_ReadLE32(fp);
 	rec.counter[2] = File_ReadLE32(fp);
@@ -476,27 +549,35 @@
 	rec.random[1] = fgetc(fp);
 	rec.random[2] = fgetc(fp);
 	rec.random[3] = fgetc(fp);
+#endif
 	fclose(fp);
 
 	// Decode from checksum
-	for (int i = 0; i < 4; i++)
+	for (i = 0; i < 4; i++)
 	{
-		uint8_t *p = (uint8_t*)&rec.counter[i];
-		p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i]) : (rec.random[i] >> 1);
+		p = (unsigned char*)&rec.counter[i];
+#ifdef NONPORTABLE
+		p[0] -= rec.random[i];
 		p[1] -= rec.random[i];
 		p[2] -= rec.random[i];
-		p[3] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i] >> 1) : (rec.random[i]);
+		p[3] -= rec.random[i] / 2;
+#else
+		p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i]) : (rec.random[i] / 2);
+		p[1] -= rec.random[i];
+		p[2] -= rec.random[i];
+		p[3] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i] / 2) : (rec.random[i]);
+#endif
 	}
 
 	// Verify checksum's result
-	if (rec.counter[0] == rec.counter[1] && rec.counter[0] == rec.counter[2])
+	if (rec.counter[0] != rec.counter[1] || rec.counter[0] != rec.counter[2])
 	{
-		time_count = rec.counter[0];
-		return rec.counter[0];
+		time_count = 0;
+		return 0;
 	}
 	else
 	{
-		time_count = 0;
-		return 0;
+		time_count = rec.counter[0];
+		return time_count;
 	}
 }
--- a/src/MycParam.h
+++ b/src/MycParam.h
@@ -25,10 +25,10 @@
 void AddBulletMyChar(int no, int val);
 void AddLifeMyChar(int x);
 void AddMaxLifeMyChar(int val);
-void PutArmsEnergy(bool flash);
+void PutArmsEnergy(BOOL flash);
 void PutActiveArmsList();
-void PutMyLife(bool flash);
+void PutMyLife(BOOL flash);
 void PutMyAir(int x, int y);
 void PutTimeCounter(int x, int y);
-bool SaveTimeCounter();
+BOOL SaveTimeCounter();
 int LoadTimeCounter();
--- a/src/Profile.cpp
+++ b/src/Profile.cpp
@@ -5,6 +5,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "SDL.h"
+
 #include "WindowsWrapper.h"
 
 #include "ArmsItem.h"
@@ -27,7 +29,7 @@
 const char *gDefaultName = "Profile.dat";
 const char *gProfileCode = "Do041220";
 
-bool IsProfile()
+BOOL IsProfile()
 {
 	char path[PATH_LENGTH];
 	sprintf(path, "%s/%s", gModulePath, gDefaultName);
@@ -34,17 +36,20 @@
 
 	FILE *fp = fopen(path, "rb");
 	if (fp == NULL)
-		return false;
+		return FALSE;
 
 	fclose(fp);
-	return true;
+	return TRUE;
 }
 
-bool SaveProfile(const char *name)
+BOOL SaveProfile(const char *name)
 {
-	//Get path
+	PROFILE profile;
+	FILE *fp;
+	char *FLAG = "FLAG";
 	char path[PATH_LENGTH];
 
+	//Get path
 	if (name)
 		sprintf(path, "%s/%s", gModulePath, name);
 	else
@@ -51,16 +56,14 @@
 		sprintf(path, "%s/%s", gModulePath, gDefaultName);
 
 	//Open file
-	PROFILE profile;
-
-	FILE *fp = fopen(path, "wb");
+	fp = fopen(path, "wb");
 	if (fp == NULL)
-		return false;
+		return FALSE;
 
 	//Set up profile
 	memset(&profile, 0, sizeof(PROFILE));
 	memcpy(profile.code, gProfileCode, sizeof(profile.code));
-	memcpy(profile.FLAG, "FLAG", sizeof(profile.FLAG));
+	memcpy(profile.FLAG, FLAG, sizeof(profile.FLAG));
 	profile.stage = gStageNo;
 	profile.music = gMusicNo;
 	profile.x = gMC.x;
@@ -81,6 +84,9 @@
 	memcpy(profile.flags, gFlagNPC, sizeof(profile.flags));
 
 	//Write to file
+#ifdef NONPORTABLE
+	fwrite(&profile, sizeof(PROFILE), 1, fp);
+#else
 	fwrite(profile.code, 8, 1, fp);
 	File_WriteLE32(profile.stage, fp);
 	File_WriteLE32(profile.music, fp);
@@ -112,20 +118,21 @@
 		File_WriteLE32(profile.permitstage[stage].event, fp);
 	}
 	fwrite(profile.permit_mapping, 0x80, 1, fp);
-	fwrite("FLAG", 4, 1, fp);
+	fwrite(FLAG, 4, 1, fp);
 	fwrite(profile.flags, 1000, 1, fp);
+#endif
 
 	fclose(fp);
-	return true;
+	return TRUE;
 }
 
-bool LoadProfile(const char *name)
+BOOL LoadProfile(const char *name)
 {
 	//Get path
 	char path[PATH_LENGTH];
 
 	if (name)
-		strcpy(path, name);
+		sprintf(path, "%s", name);
 	else
 		sprintf(path, "%s/%s", gModulePath, gDefaultName);
 
@@ -134,7 +141,7 @@
 
 	FILE *fp = fopen(path, "rb");
 	if (fp == NULL)
-		return false;
+		return FALSE;
 
 	//Check header code
 	fread(profile.code, 8, 1, fp);
@@ -143,11 +150,15 @@
 #ifdef FIX_BUGS
 		fclose(fp);	// The original game forgets to close the file
 #endif
-		return false;
+		return FALSE;
 	}
 
 	//Read data
-	fseek(fp, 0, SEEK_SET); //Pixel epic redundant code 😎😎😎
+	fseek(fp, 0, SEEK_SET);
+	memset(&profile, 0, sizeof(PROFILE));
+#ifdef NONPORTABLE
+	fread(&profile, sizeof(PROFILE), 1, fp);
+#else
 	fread(profile.code, 8, 1, fp);
 	profile.stage = File_ReadLE32(fp);
 	profile.music = File_ReadLE32(fp);
@@ -181,6 +192,7 @@
 	fread(profile.permit_mapping, 0x80, 1, fp);
 	fread(profile.FLAG, 4, 1, fp);
 	fread(profile.flags, 1000, 1, fp);
+#endif
 	fclose(fp);
 
 	//Set things
@@ -198,7 +210,7 @@
 	ChangeMusic(profile.music);
 	InitMyChar();
 	if (!TransferStage(profile.stage, 0, 0, 1))
-		return false;
+		return FALSE;
 
 	//Set character properties
 	gMC.equip = profile.equip;
@@ -227,10 +239,10 @@
 	InitStar();
 	ClearValueView();
 	gCurlyShoot_wait = 0;
-	return true;
+	return TRUE;
 }
 
-bool InitializeGame()
+BOOL InitializeGame()
 {
 	InitMyChar();
 	gSelectedArms = 0;
@@ -242,7 +254,24 @@
 	StartMapping();
 	InitFlags();
 	if (!TransferStage(13, 200, 10, 8))
-		return false;
+	{
+		// TODO - restore this when hWnd is available
+/*#if defined(NONPORTABLE) && defined(WINDOWS)
+#ifdef JAPANESE
+		MessageBoxA(hWnd, "�X�e�[�W�̓ǂݍ��݂Ɏ��s", "�G���[", MB_OK);
+#else
+		MessageBoxA(hWnd, "Failed to load stage", "Error", MB_OK);
+#endif
+#else*/
+#ifdef JAPANESE
+		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "�G���[", "�X�e�[�W�̓ǂݍ��݂Ɏ��s", NULL);
+#else
+		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Failed to load stage", NULL);
+#endif
+//#endif
+		return FALSE;
+	}
+
 	ClearFade();
 	SetFrameMyChar();
 	SetFrameTargetMyChar(16);
@@ -252,5 +281,5 @@
 	gCurlyShoot_wait = 0;
 	SetFadeMask();
 	SetFrameTargetMyChar(16);
-	return true;
+	return TRUE;
 }
--- a/src/Profile.h
+++ b/src/Profile.h
@@ -2,6 +2,8 @@
 
 #include <stdint.h>
 
+#include "WindowsWrapper.h"
+
 #include "ArmsItem.h"
 #include "SelStage.h"
 
@@ -30,7 +32,7 @@
 	uint8_t flags[1000];
 };
 
-bool IsProfile();
-bool SaveProfile(const char *name);
-bool LoadProfile(const char *name);
-bool InitializeGame();
+BOOL IsProfile();
+BOOL SaveProfile(const char *name);
+BOOL LoadProfile(const char *name);
+BOOL InitializeGame();