Merge branch 'master' into improveGToK

This commit is contained in:
Gabriel Ravier 2019-05-12 16:04:10 +02:00
commit da07dc5ab5
6 changed files with 406 additions and 218 deletions

View file

@ -515,6 +515,66 @@ addr = 0x414B20
name = "SetMapping" name = "SetMapping"
addr = 0x414B40 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]] [[func]]
name = "ChangeOrganFrequency" name = "ChangeOrganFrequency"
addr = 0x41ABA0 addr = 0x41ABA0
@ -570,6 +630,22 @@ addr = 0x41C8F0
name = "MakePixelWaveData" name = "MakePixelWaveData"
addr = 0x41CB10 addr = 0x41CB10
[[func]]
name = "IsProfile"
addr = 0x41CFC0
[[func]]
name = "SaveProfile"
addr = 0x41D040
[[func]]
name = "LoadProfile"
addr = 0x41D260
[[func]]
name = "InitializeGame"
addr = 0x41D550
[[func]] [[func]]
name = "ShootBullet_Frontia1" name = "ShootBullet_Frontia1"
addr = 0x41DBD0 addr = 0x41DBD0

View file

@ -49,7 +49,7 @@
int g_GameFlags; int g_GameFlags;
int gCounter; int gCounter;
bool bContinue; BOOL bContinue;
int Random(int min, int max) int Random(int min, int max)
{ {
@ -275,13 +275,13 @@ int ModeTitle()
// Set character // Set character
time_counter = LoadTimeCounter(); time_counter = LoadTimeCounter();
if (time_counter && time_counter < 18000) if (time_counter && time_counter < 6 * 60 * 50) // 6 minutes
char_type = 1; char_type = 1;
if (time_counter && time_counter < 15000) if (time_counter && time_counter < 5 * 60 * 50) // 5 minutes
char_type = 2; char_type = 2;
if (time_counter && time_counter < 12000) if (time_counter && time_counter < 4 * 60 * 50) // 4 minutes
char_type = 3; char_type = 3;
if (time_counter && time_counter < 9000) if (time_counter && time_counter < 3 * 60 * 50) // 3 minutes
char_type = 4; char_type = 4;
// Set music to character's specific music // Set music to character's specific music
@ -405,7 +405,7 @@ int ModeTitle()
} }
int char_y; int char_y;
if (bContinue == 1) if (bContinue == TRUE)
char_y = (WINDOW_HEIGHT + 54) / 2; char_y = (WINDOW_HEIGHT + 54) / 2;
else else
char_y = (WINDOW_HEIGHT + 14) / 2; char_y = (WINDOW_HEIGHT + 14) / 2;

View file

@ -46,9 +46,9 @@ void AddExpMyChar(int x)
if (lv == 2) 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) if (gMC.equip & 0x80)
{ {
@ -59,9 +59,9 @@ void AddExpMyChar(int x)
} }
else 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].level;
gArmsData[gSelectedArms].exp = 0; gArmsData[gSelectedArms].exp = 0;
@ -72,20 +72,18 @@ void AddExpMyChar(int x)
SetCaret(gMC.x, gMC.y, 10, 0); SetCaret(gMC.x, gMC.y, 10, 0);
} }
} }
++lv;
} }
} }
if (gArmsData[gSelectedArms].code == 13) if (gArmsData[gSelectedArms].code != 13)
{
gMC.exp_wait = 10;
}
else
{ {
gMC.exp_count += x; gMC.exp_count += x;
gMC.exp_wait = 30; gMC.exp_wait = 30;
} }
else
{
gMC.exp_wait = 10;
}
} }
void ZeroExpMyChar() void ZeroExpMyChar()
@ -96,25 +94,49 @@ void ZeroExpMyChar()
BOOL IsMaxExpMyChar() BOOL IsMaxExpMyChar()
{ {
return gArmsData[gSelectedArms].level == 3 if (gArmsData[gSelectedArms].level == 3)
&& gArmsData[gSelectedArms].exp >= gArmsLevelTable[gArmsData[gSelectedArms].code].exp[2]; {
int arms_code = gArmsData[gSelectedArms].code;
if (gArmsData[gSelectedArms].exp >= gArmsLevelTable[arms_code].exp[2])
return TRUE;
}
return FALSE;
} }
void DamageMyChar(int damage) 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 // Damage player
PlaySoundObject(16, 1); PlaySoundObject(16, 1);
gMC.cond &= ~1; gMC.cond &= ~1;
gMC.shock = 128; gMC.shock = 128;
if (gMC.unit != 1)
if (gMC.unit == 1)
{
// Another weird case where there *has* to be an empty 'if' here to produce the same assembly
}
else
{
gMC.ym = -0x400; gMC.ym = -0x400;
gMC.life -= damage; }
gMC.life -= (short)damage;
// Lose a whimsical star // Lose a whimsical star
if (gMC.equip & 0x80 && gMC.star > 0) if (gMC.equip & 0x80 && gMC.star > 0)
--gMC.star; gMC.star = (short)gMC.star - 1; // Why the hell is it written this way?
// Lose experience // Lose experience
if (gMC.equip & 4) if (gMC.equip & 4)
@ -124,15 +146,21 @@ void DamageMyChar(int damage)
while (gArmsData[gSelectedArms].exp < 0) while (gArmsData[gSelectedArms].exp < 0)
{ {
if (gArmsData[gSelectedArms].level <= 1) if (gArmsData[gSelectedArms].level > 1)
{ {
gArmsData[gSelectedArms].exp = 0; --gArmsData[gSelectedArms].level;
int lv = gArmsData[gSelectedArms].level - 1;
int arms_code = gArmsData[gSelectedArms].code;
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 else
{ {
gArmsData[gSelectedArms].exp += gArmsLevelTable[0].exp[--gArmsData[gSelectedArms].level - 1 + 3 * gArmsData[gSelectedArms].code]; gArmsData[gSelectedArms].exp = 0;
if (gMC.life > 0 && gArmsData[gSelectedArms].code != 13)
SetCaret(gMC.x, gMC.y, 10, 2);
} }
} }
@ -147,7 +175,6 @@ void DamageMyChar(int damage)
SetDestroyNpChar(gMC.x, gMC.y, 0x1400, 0x40); SetDestroyNpChar(gMC.x, gMC.y, 0x1400, 0x40);
StartTextScript(40); StartTextScript(40);
} }
}
} }
void ZeroArmsEnergy_All() void ZeroArmsEnergy_All()
@ -161,34 +188,31 @@ void ZeroArmsEnergy_All()
void AddBulletMyChar(int no, int val) void AddBulletMyChar(int no, int val)
{ {
int a = 0;
// Missile Launcher // Missile Launcher
for (int a = 0; a < ARMS_MAX; a++) while (a < ARMS_MAX && gArmsData[a].code != 5)
++a;
if (a == ARMS_MAX)
{ {
if (gArmsData[a].code == 5) // Super Missile Launcher
{ a = 0;
gArmsData[a].num += val; while (a < ARMS_MAX && gArmsData[a].code != 10)
if (gArmsData[a].num > gArmsData[a].max_num) ++a;
gArmsData[a].num = gArmsData[a].max_num;
break; if (a == ARMS_MAX)
} return;
} }
// Super Missile Launcher
for (int a = 0; a < ARMS_MAX; a++)
{
if (gArmsData[a].code == 10)
{
gArmsData[a].num += val; gArmsData[a].num += val;
if (gArmsData[a].num > gArmsData[a].max_num) if (gArmsData[a].num > gArmsData[a].max_num)
gArmsData[a].num = gArmsData[a].max_num; gArmsData[a].num = gArmsData[a].max_num;
break;
}
}
} }
void AddLifeMyChar(int x) void AddLifeMyChar(int x)
{ {
gMC.life += x; gMC.life += (short)x;
if (gMC.life > gMC.max_life) if (gMC.life > gMC.max_life)
gMC.life = gMC.max_life; gMC.life = gMC.max_life;
gMC.lifeBr = gMC.life; gMC.lifeBr = gMC.life;
@ -196,15 +220,25 @@ void AddLifeMyChar(int x)
void AddMaxLifeMyChar(int val) void AddMaxLifeMyChar(int val)
{ {
gMC.max_life += val; gMC.max_life += (short)val;
if (gMC.max_life > 232) if (gMC.max_life > 232)
gMC.max_life = 232; gMC.max_life = 232;
gMC.life += val; gMC.life += (short)val;
gMC.lifeBr = gMC.life; 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 rcPer = {72, 48, 80, 56};
RECT rcLv = {80, 80, 96, 88}; RECT rcLv = {80, 80, 96, 88};
RECT rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}; RECT rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT};
@ -228,25 +262,30 @@ void PutArmsEnergy(bool flash)
} }
// Draw experience and ammo // Draw experience and ammo
if (!flash || !((gMC.shock >> 1) & 1)) if (flash == TRUE && (gMC.shock / 2) % 2)
{ return;
PutBitmap3(&rcView, gArmsEnergyX + 32, 24, &rcPer, SURFACE_ID_TEXT_BOX); PutBitmap3(&rcView, gArmsEnergyX + 32, 24, &rcPer, SURFACE_ID_TEXT_BOX);
PutBitmap3(&rcView, gArmsEnergyX, 32, &rcLv, SURFACE_ID_TEXT_BOX); PutBitmap3(&rcView, gArmsEnergyX, 32, &rcLv, SURFACE_ID_TEXT_BOX);
PutNumber4(gArmsEnergyX - 8, 32, gArmsData[gSelectedArms].level, 0); PutNumber4(gArmsEnergyX - 8, 32, gArmsData[gSelectedArms].level, 0);
RECT rcExpBox = {0, 72, 40, 80}; SET_RECT(rcExpBox, 0, 72, 40, 80)
RECT rcExpVal = {0, 80, 0, 88}; SET_RECT(rcExpVal, 0, 80, 0, 88)
RECT rcExpMax = {40, 72, 80, 80}; SET_RECT(rcExpMax, 40, 72, 80, 80)
RECT rcExpFlash = {40, 80, 80, 88}; SET_RECT(rcExpFlash, 40, 80, 80, 88)
int lv = gArmsData[gSelectedArms].level - 1; lv = gArmsData[gSelectedArms].level - 1;
int arms_code = gArmsData[gSelectedArms].code; arms_code = gArmsData[gSelectedArms].code;
int exp_now = gArmsData[gSelectedArms].exp; exp_now = gArmsData[gSelectedArms].exp;
int exp_next = gArmsLevelTable[0].exp[lv + 3 * arms_code]; exp_next = gArmsLevelTable[arms_code].exp[lv];
PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpBox, SURFACE_ID_TEXT_BOX); PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpBox, SURFACE_ID_TEXT_BOX);
if (lv != 2 || gArmsData[gSelectedArms].exp != gArmsLevelTable[0].exp[3 * arms_code + 2]) 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) if (exp_next)
rcExpVal.right += 40 * exp_now / exp_next; rcExpVal.right += 40 * exp_now / exp_next;
@ -255,43 +294,38 @@ void PutArmsEnergy(bool flash)
PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpVal, SURFACE_ID_TEXT_BOX); PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpVal, SURFACE_ID_TEXT_BOX);
} }
else
{
PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpMax, SURFACE_ID_TEXT_BOX);
}
static int add_flash = true; static unsigned char add_flash;
if (gMC.exp_wait && ((add_flash++ >> 1) & 1)) if (gMC.exp_wait && ((add_flash++ / 2) % 2))
PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpFlash, SURFACE_ID_TEXT_BOX); PutBitmap3(&rcView, gArmsEnergyX + 24, 32, &rcExpFlash, SURFACE_ID_TEXT_BOX);
}
} }
void PutActiveArmsList() void PutActiveArmsList()
{ {
int x;
int a;
int arms_num;
RECT rect = {0, 0, 0, 16}; RECT rect = {0, 0, 0, 16};
int arms_num; arms_num = 0;
for (arms_num = 0; gArmsData[arms_num].code != 0; ++arms_num); while (gArmsData[arms_num].code != 0)
++arms_num;
if (arms_num) if (arms_num == 0)
{ return;
for (int a = 0; a < arms_num; a++)
for (a = 0; a < arms_num; a++)
{ {
// Get X position to draw at // Get X position to draw at
int x = 16 * (a - gSelectedArms) + gArmsEnergyX; x = 16 * (a - gSelectedArms) + gArmsEnergyX;
if (x >= 8) if (x < 8)
{ x += 48 + (16 * arms_num);
if (x >= 24) else if (x >= 24)
x += 48; x += 48;
}
else
{
x += 16 * (arms_num + 3);
}
if (8 * (2 * (arms_num + 3) + 1) <= x) if (x >= 72 + (16 * (arms_num - 1)))
x += 16 * (-3 - arms_num); x -= 48 + (16 * arms_num);
if (x < 72 && x >= 24) if (x < 72 && x >= 24)
x -= 48; x -= 48;
@ -300,24 +334,29 @@ void PutActiveArmsList()
rect.right = rect.left + 16; rect.right = rect.left + 16;
PutBitmap3(&grcGame, x, 16, &rect, SURFACE_ID_ARMS_IMAGE); PutBitmap3(&grcGame, x, 16, &rect, SURFACE_ID_ARMS_IMAGE);
} }
}
} }
void PutMyLife(bool flash) void PutMyLife(BOOL flash)
{ {
RECT rcCase = {0, 40, 232, 48}; RECT rcCase = {0, 40, 232, 48};
RECT rcLife = {0, 24, 232, 32}; RECT rcLife = {0, 24, 232, 32};
RECT rcBr = {0, 32, 232, 40}; RECT rcBr = {0, 32, 232, 40};
if (!flash || !((gMC.shock >> 1) & 1)) if (flash == TRUE && (gMC.shock / 2) % 2)
{ return;
if (gMC.lifeBr < gMC.life) if (gMC.lifeBr < gMC.life)
gMC.lifeBr = gMC.life; gMC.lifeBr = gMC.life;
if (gMC.lifeBr <= gMC.life) if (gMC.lifeBr > gMC.life)
gMC.lifeBr_count = 0; {
else if (++gMC.lifeBr_count > 30) if (++gMC.lifeBr_count > 30)
--gMC.lifeBr; --gMC.lifeBr;
}
else
{
gMC.lifeBr_count = 0;
}
// Draw bar // Draw bar
rcCase.right = 64; rcCase.right = 64;
@ -328,7 +367,6 @@ void PutMyLife(bool flash)
PutBitmap3(&grcGame, 40, 40, &rcBr, SURFACE_ID_TEXT_BOX); PutBitmap3(&grcGame, 40, 40, &rcBr, SURFACE_ID_TEXT_BOX);
PutBitmap3(&grcGame, 40, 40, &rcLife, SURFACE_ID_TEXT_BOX); PutBitmap3(&grcGame, 40, 40, &rcLife, SURFACE_ID_TEXT_BOX);
PutNumber4(8, 40, gMC.lifeBr, 0); PutNumber4(8, 40, gMC.lifeBr, 0);
}
} }
void PutMyAir(int x, int y) void PutMyAir(int x, int y)
@ -338,17 +376,20 @@ void PutMyAir(int x, int y)
{112, 80, 144, 88}, {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 // 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); PutNumber4(x + 32, y, gMC.air / 10, 0);
// Draw "AIR" text // Draw "AIR" text
if (gMC.air % 30 <= 10) if (gMC.air % 30 > 10)
PutBitmap3(&grcGame, x, y, &rcAir[1], SURFACE_ID_TEXT_BOX);
else
PutBitmap3(&grcGame, x, y, &rcAir[0], SURFACE_ID_TEXT_BOX); 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 @@ void PutTimeCounter(int x, int y)
// Draw clock and increase time // Draw clock and increase time
if (g_GameFlags & 2) if (g_GameFlags & 2)
{ {
if (time_count < 300000) if (time_count < 100 * 60 * 50) // 100 minutes
++time_count; ++time_count;
if (time_count % 30 <= 10) if (time_count % 30 > 10)
PutBitmap3(&grcGame, x, y, &rcTime[1], SURFACE_ID_TEXT_BOX);
else
PutBitmap3(&grcGame, x, y, &rcTime[0], SURFACE_ID_TEXT_BOX); PutBitmap3(&grcGame, x, y, &rcTime[0], SURFACE_ID_TEXT_BOX);
else
PutBitmap3(&grcGame, x, y, &rcTime[1], SURFACE_ID_TEXT_BOX);
} }
else else
{ {
@ -379,7 +420,7 @@ void PutTimeCounter(int x, int y)
} }
// Draw time // 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 + 20, y, time_count / 50 % 60, true);
PutNumber4(x + 32, y, time_count / 5 % 10, false); PutNumber4(x + 32, y, time_count / 5 % 10, false);
PutBitmap3(&grcGame, x + 30, y, &rcTime[2], SURFACE_ID_TEXT_BOX); PutBitmap3(&grcGame, x + 30, y, &rcTime[2], SURFACE_ID_TEXT_BOX);
@ -390,13 +431,16 @@ void PutTimeCounter(int x, int y)
} }
} }
bool SaveTimeCounter() BOOL SaveTimeCounter()
{ {
unsigned char *p;
int i;
REC rec; REC rec;
// Quit if player doesn't have the Nikumaru Counter // Quit if player doesn't have the Nikumaru Counter
if (!(gMC.equip & 0x100)) if (!(gMC.equip & 0x100))
return true; return TRUE;
// Get last time // Get last time
char path[PATH_LENGTH]; char path[PATH_LENGTH];
@ -406,6 +450,9 @@ bool SaveTimeCounter()
if (fp) if (fp)
{ {
// Read data // Read data
#ifdef NONPORTABLE
fread(&rec, sizeof(REC), 1, fp);
#else
rec.counter[0] = File_ReadLE32(fp); rec.counter[0] = File_ReadLE32(fp);
rec.counter[1] = File_ReadLE32(fp); rec.counter[1] = File_ReadLE32(fp);
rec.counter[2] = File_ReadLE32(fp); rec.counter[2] = File_ReadLE32(fp);
@ -414,35 +461,53 @@ bool SaveTimeCounter()
rec.random[1] = fgetc(fp); rec.random[1] = fgetc(fp);
rec.random[2] = fgetc(fp); rec.random[2] = fgetc(fp);
rec.random[3] = fgetc(fp); rec.random[3] = fgetc(fp);
#endif
fclose(fp); fclose(fp);
uint8_t *p = (uint8_t*)&rec.counter[0]; p = (unsigned char*)&rec.counter[0];
p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[0]) : (rec.random[0] >> 1); #ifdef NONPORTABLE
p[0] -= rec.random[0];
p[1] -= rec.random[0]; p[1] -= rec.random[0];
p[2] -= 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 this is faster than our new time, quit
if (rec.counter[0] < time_count) if (rec.counter[0] < time_count)
return true; return TRUE;
} }
// Save new time // Save new time
for (int i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
rec.counter[i] = time_count; rec.counter[i] = time_count;
rec.random[i] = Random(0, 250) + i; rec.random[i] = Random(0, 250) + i;
uint8_t *p = (uint8_t*)&rec.counter[i]; p = (unsigned char*)&rec.counter[i];
p[0] += (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i]) : (rec.random[i] >> 1); #ifdef NONPORTABLE
p[0] += rec.random[i];
p[1] += rec.random[i]; p[1] += rec.random[i];
p[2] += 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"); fp = fopen(path, "wb");
if (fp == NULL) 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[0], fp);
File_WriteLE32(rec.counter[1], fp); File_WriteLE32(rec.counter[1], fp);
File_WriteLE32(rec.counter[2], fp); File_WriteLE32(rec.counter[2], fp);
@ -451,12 +516,17 @@ bool SaveTimeCounter()
fputc(rec.random[1], fp); fputc(rec.random[1], fp);
fputc(rec.random[2], fp); fputc(rec.random[2], fp);
fputc(rec.random[3], fp); fputc(rec.random[3], fp);
#endif
fclose(fp); fclose(fp);
return true; return TRUE;
} }
int LoadTimeCounter() int LoadTimeCounter()
{ {
unsigned char *p;
int i;
// Open file // Open file
char path[PATH_LENGTH]; char path[PATH_LENGTH];
sprintf(path, "%s/290.rec", gModulePath); sprintf(path, "%s/290.rec", gModulePath);
@ -468,6 +538,9 @@ int LoadTimeCounter()
REC rec; REC rec;
// Read data // Read data
#ifdef NONPORTABLE
fread(&rec, sizeof(REC), 1, fp);
#else
rec.counter[0] = File_ReadLE32(fp); rec.counter[0] = File_ReadLE32(fp);
rec.counter[1] = File_ReadLE32(fp); rec.counter[1] = File_ReadLE32(fp);
rec.counter[2] = File_ReadLE32(fp); rec.counter[2] = File_ReadLE32(fp);
@ -476,27 +549,35 @@ int LoadTimeCounter()
rec.random[1] = fgetc(fp); rec.random[1] = fgetc(fp);
rec.random[2] = fgetc(fp); rec.random[2] = fgetc(fp);
rec.random[3] = fgetc(fp); rec.random[3] = fgetc(fp);
#endif
fclose(fp); fclose(fp);
// Decode from checksum // 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 = (unsigned char*)&rec.counter[i];
p[0] -= (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? (rec.random[i]) : (rec.random[i] >> 1); #ifdef NONPORTABLE
p[0] -= rec.random[i];
p[1] -= rec.random[i]; p[1] -= rec.random[i];
p[2] -= 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 // 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];
}
else
{ {
time_count = 0; time_count = 0;
return 0; return 0;
} }
else
{
time_count = rec.counter[0];
return time_count;
}
} }

View file

@ -25,10 +25,10 @@ void ZeroArmsEnergy_All();
void AddBulletMyChar(int no, int val); void AddBulletMyChar(int no, int val);
void AddLifeMyChar(int x); void AddLifeMyChar(int x);
void AddMaxLifeMyChar(int val); void AddMaxLifeMyChar(int val);
void PutArmsEnergy(bool flash); void PutArmsEnergy(BOOL flash);
void PutActiveArmsList(); void PutActiveArmsList();
void PutMyLife(bool flash); void PutMyLife(BOOL flash);
void PutMyAir(int x, int y); void PutMyAir(int x, int y);
void PutTimeCounter(int x, int y); void PutTimeCounter(int x, int y);
bool SaveTimeCounter(); BOOL SaveTimeCounter();
int LoadTimeCounter(); int LoadTimeCounter();

View file

@ -5,6 +5,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "SDL.h"
#include "WindowsWrapper.h" #include "WindowsWrapper.h"
#include "ArmsItem.h" #include "ArmsItem.h"
@ -27,40 +29,41 @@
const char *gDefaultName = "Profile.dat"; const char *gDefaultName = "Profile.dat";
const char *gProfileCode = "Do041220"; const char *gProfileCode = "Do041220";
bool IsProfile() BOOL IsProfile()
{ {
char path[PATH_LENGTH]; char path[PATH_LENGTH];
sprintf(path, "%s/%s", gModulePath, gDefaultName); sprintf(path, "%s/%s", gModulePath, gDefaultName);
FILE *fp = fopen(path, "rb"); FILE *fp = fopen(path, "rb");
if (fp == NULL) if (fp == NULL)
return false; return FALSE;
fclose(fp); 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]; char path[PATH_LENGTH];
//Get path
if (name) if (name)
sprintf(path, "%s/%s", gModulePath, name); sprintf(path, "%s/%s", gModulePath, name);
else else
sprintf(path, "%s/%s", gModulePath, gDefaultName); sprintf(path, "%s/%s", gModulePath, gDefaultName);
//Open file //Open file
PROFILE profile; fp = fopen(path, "wb");
FILE *fp = fopen(path, "wb");
if (fp == NULL) if (fp == NULL)
return false; return FALSE;
//Set up profile //Set up profile
memset(&profile, 0, sizeof(PROFILE)); memset(&profile, 0, sizeof(PROFILE));
memcpy(profile.code, gProfileCode, sizeof(profile.code)); 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.stage = gStageNo;
profile.music = gMusicNo; profile.music = gMusicNo;
profile.x = gMC.x; profile.x = gMC.x;
@ -81,6 +84,9 @@ bool SaveProfile(const char *name)
memcpy(profile.flags, gFlagNPC, sizeof(profile.flags)); memcpy(profile.flags, gFlagNPC, sizeof(profile.flags));
//Write to file //Write to file
#ifdef NONPORTABLE
fwrite(&profile, sizeof(PROFILE), 1, fp);
#else
fwrite(profile.code, 8, 1, fp); fwrite(profile.code, 8, 1, fp);
File_WriteLE32(profile.stage, fp); File_WriteLE32(profile.stage, fp);
File_WriteLE32(profile.music, fp); File_WriteLE32(profile.music, fp);
@ -112,20 +118,21 @@ bool SaveProfile(const char *name)
File_WriteLE32(profile.permitstage[stage].event, fp); File_WriteLE32(profile.permitstage[stage].event, fp);
} }
fwrite(profile.permit_mapping, 0x80, 1, fp); fwrite(profile.permit_mapping, 0x80, 1, fp);
fwrite("FLAG", 4, 1, fp); fwrite(FLAG, 4, 1, fp);
fwrite(profile.flags, 1000, 1, fp); fwrite(profile.flags, 1000, 1, fp);
#endif
fclose(fp); fclose(fp);
return true; return TRUE;
} }
bool LoadProfile(const char *name) BOOL LoadProfile(const char *name)
{ {
//Get path //Get path
char path[PATH_LENGTH]; char path[PATH_LENGTH];
if (name) if (name)
strcpy(path, name); sprintf(path, "%s", name);
else else
sprintf(path, "%s/%s", gModulePath, gDefaultName); sprintf(path, "%s/%s", gModulePath, gDefaultName);
@ -134,7 +141,7 @@ bool LoadProfile(const char *name)
FILE *fp = fopen(path, "rb"); FILE *fp = fopen(path, "rb");
if (fp == NULL) if (fp == NULL)
return false; return FALSE;
//Check header code //Check header code
fread(profile.code, 8, 1, fp); fread(profile.code, 8, 1, fp);
@ -143,11 +150,15 @@ bool LoadProfile(const char *name)
#ifdef FIX_BUGS #ifdef FIX_BUGS
fclose(fp); // The original game forgets to close the file fclose(fp); // The original game forgets to close the file
#endif #endif
return false; return FALSE;
} }
//Read data //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); fread(profile.code, 8, 1, fp);
profile.stage = File_ReadLE32(fp); profile.stage = File_ReadLE32(fp);
profile.music = File_ReadLE32(fp); profile.music = File_ReadLE32(fp);
@ -181,6 +192,7 @@ bool LoadProfile(const char *name)
fread(profile.permit_mapping, 0x80, 1, fp); fread(profile.permit_mapping, 0x80, 1, fp);
fread(profile.FLAG, 4, 1, fp); fread(profile.FLAG, 4, 1, fp);
fread(profile.flags, 1000, 1, fp); fread(profile.flags, 1000, 1, fp);
#endif
fclose(fp); fclose(fp);
//Set things //Set things
@ -198,7 +210,7 @@ bool LoadProfile(const char *name)
ChangeMusic(profile.music); ChangeMusic(profile.music);
InitMyChar(); InitMyChar();
if (!TransferStage(profile.stage, 0, 0, 1)) if (!TransferStage(profile.stage, 0, 0, 1))
return false; return FALSE;
//Set character properties //Set character properties
gMC.equip = profile.equip; gMC.equip = profile.equip;
@ -227,10 +239,10 @@ bool LoadProfile(const char *name)
InitStar(); InitStar();
ClearValueView(); ClearValueView();
gCurlyShoot_wait = 0; gCurlyShoot_wait = 0;
return true; return TRUE;
} }
bool InitializeGame() BOOL InitializeGame()
{ {
InitMyChar(); InitMyChar();
gSelectedArms = 0; gSelectedArms = 0;
@ -242,7 +254,24 @@ bool InitializeGame()
StartMapping(); StartMapping();
InitFlags(); InitFlags();
if (!TransferStage(13, 200, 10, 8)) if (!TransferStage(13, 200, 10, 8))
return false; {
// TODO - restore this when hWnd is available
/*#if defined(NONPORTABLE) && defined(WINDOWS)
#ifdef JAPANESE
MessageBoxA(hWnd, "ステージの読み込みに失敗", "エラー", MB_OK);
#else
MessageBoxA(hWnd, "Failed to load stage", "Error", MB_OK);
#endif
#else*/
#ifdef JAPANESE
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "エラー", "ステージの読み込みに失敗", NULL);
#else
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Failed to load stage", NULL);
#endif
//#endif
return FALSE;
}
ClearFade(); ClearFade();
SetFrameMyChar(); SetFrameMyChar();
SetFrameTargetMyChar(16); SetFrameTargetMyChar(16);
@ -252,5 +281,5 @@ bool InitializeGame()
gCurlyShoot_wait = 0; gCurlyShoot_wait = 0;
SetFadeMask(); SetFadeMask();
SetFrameTargetMyChar(16); SetFrameTargetMyChar(16);
return true; return TRUE;
} }

View file

@ -2,6 +2,8 @@
#include <stdint.h> #include <stdint.h>
#include "WindowsWrapper.h"
#include "ArmsItem.h" #include "ArmsItem.h"
#include "SelStage.h" #include "SelStage.h"
@ -30,7 +32,7 @@ struct PROFILE
uint8_t flags[1000]; uint8_t flags[1000];
}; };
bool IsProfile(); BOOL IsProfile();
bool SaveProfile(const char *name); BOOL SaveProfile(const char *name);
bool LoadProfile(const char *name); BOOL LoadProfile(const char *name);
bool InitializeGame(); BOOL InitializeGame();