Made NpcAct000.cpp *really* ASM-accurate

Unlike the other files, I've gone out of my way to get accurate stack
frame layouts. The Devilution comparer tool really comes in handy here.
This commit is contained in:
Clownacy 2019-02-24 02:34:19 +00:00
parent a58f5e2f77
commit 3fc8ceb0a6
3 changed files with 101 additions and 86 deletions

View file

@ -17,13 +17,13 @@
MAP_DATA gMap; MAP_DATA gMap;
bool InitMapData2() BOOL InitMapData2()
{ {
gMap.data = (uint8_t*)malloc(PXM_BUFFER_SIZE); gMap.data = (uint8_t*)malloc(PXM_BUFFER_SIZE);
return true; return TRUE;
} }
bool LoadMapData2(char *path_map) BOOL LoadMapData2(const char *path_map)
{ {
//Get path //Get path
char path[PATH_LENGTH]; char path[PATH_LENGTH];
@ -32,7 +32,7 @@ bool LoadMapData2(char *path_map)
//Open file //Open file
FILE *fp = fopen(path, "rb"); FILE *fp = fopen(path, "rb");
if (fp == NULL) if (fp == NULL)
return false; return FALSE;
//Make sure file begins with "PXM" //Make sure file begins with "PXM"
char check[3]; char check[3];
@ -52,24 +52,24 @@ bool LoadMapData2(char *path_map)
//Read tiledata //Read tiledata
fread(gMap.data, 1, gMap.length * gMap.width, fp); fread(gMap.data, 1, gMap.length * gMap.width, fp);
fclose(fp); fclose(fp);
return true; return TRUE;
} }
else else
{ {
fclose(fp); fclose(fp);
return false; return FALSE;
} }
} }
else else
{ {
fclose(fp); fclose(fp);
return false; return FALSE;
} }
return false; return FALSE;
} }
bool LoadAttributeData(char *path_atrb) BOOL LoadAttributeData(const char *path_atrb)
{ {
//Open file //Open file
char path[260]; char path[260];
@ -77,12 +77,12 @@ bool LoadAttributeData(char *path_atrb)
FILE *fp = fopen(path, "rb"); FILE *fp = fopen(path, "rb");
if (fp == NULL) if (fp == NULL)
return false; return FALSE;
//Read data //Read data
fread(gMap.atrb, 1, 0x100, fp); fread(gMap.atrb, 1, 0x100, fp);
fclose(fp); fclose(fp);
return true; return TRUE;
} }
void EndMapData() void EndMapData()
@ -110,7 +110,7 @@ int GetAttribute(int x, int y)
{ {
if (x >= 0 && y >= 0 && gMap.width > x && gMap.length > y) if (x >= 0 && y >= 0 && gMap.width > x && gMap.length > y)
return gMap.atrb[gMap.data[y * gMap.width + x]]; return gMap.atrb[gMap.data[y * gMap.width + x]];
return false; return 0;
} }
void DeleteMapParts(int x, int y) void DeleteMapParts(int x, int y)
@ -123,14 +123,14 @@ void ShiftMapParts(int x, int y)
--gMap.data[y * gMap.width + x]; --gMap.data[y * gMap.width + x];
} }
bool ChangeMapParts(int x, int y, uint8_t no) BOOL ChangeMapParts(int x, int y, uint8_t no)
{ {
if (gMap.data[y * gMap.width + x] == no) if (gMap.data[y * gMap.width + x] == no)
return false; return FALSE;
gMap.data[y * gMap.width + x] = no; gMap.data[y * gMap.width + x] = no;
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
SetNpChar(4, x << 13, y << 13, 0, 0, 0, 0, 0); SetNpChar(4, x << 13, y << 13, 0, 0, 0, 0, 0);
return true; return TRUE;
} }
void PutStage_Back(int fx, int fy) void PutStage_Back(int fx, int fy)

View file

@ -2,6 +2,8 @@
#include <stdint.h> #include <stdint.h>
#include "WindowsWrapper.h"
struct MAP_DATA struct MAP_DATA
{ {
uint8_t *data; uint8_t *data;
@ -12,16 +14,16 @@ struct MAP_DATA
extern MAP_DATA gMap; extern MAP_DATA gMap;
bool InitMapData2(); BOOL InitMapData2();
bool LoadMapData2(char *path_map); BOOL LoadMapData2(const char *path_map);
bool LoadAttributeData(char *path_atrb); BOOL LoadAttributeData(const char *path_atrb);
void EndMapData(); void EndMapData();
void ReleasePartsImage(); void ReleasePartsImage();
void GetMapData(uint8_t **data, int16_t *mw, int16_t *ml); void GetMapData(uint8_t **data, int16_t *mw, int16_t *ml);
int GetAttribute(int x, int y); int GetAttribute(int x, int y);
void DeleteMapParts(int x, int y); void DeleteMapParts(int x, int y);
void ShiftMapParts(int x, int y); void ShiftMapParts(int x, int y);
bool ChangeMapParts(int x, int y, uint8_t no); BOOL ChangeMapParts(int x, int y, uint8_t no);
void PutStage_Back(int fx, int fy); void PutStage_Back(int fx, int fy);
void PutStage_Front(int fx, int fy); void PutStage_Front(int fx, int fy);
void PutMapDataVector(int fx, int fy); void PutMapDataVector(int fx, int fy);

View file

@ -137,8 +137,8 @@ void ActNpc001(NPCHAR *npc)
} }
//Move //Move
npc->x += npc->xm;
npc->y += npc->ym; npc->y += npc->ym;
npc->x += npc->xm;
//Get framerects //Get framerects
RECT rect[6] = { RECT rect[6] = {
@ -361,12 +361,14 @@ void ActNpc004(NPCHAR *npc)
{80, 128, 96, 144}, {80, 128, 96, 144},
}; };
unsigned char deg;
if (npc->act_no == 0) if (npc->act_no == 0)
{ {
//Move in random direction at random speed //Move in random direction at random speed
if (npc->direct == 0 || npc->direct == 1) if (npc->direct == 0 || npc->direct == 1)
{ {
const unsigned char deg = Random(0, 0xFF); deg = Random(0, 0xFF);
npc->xm = GetCos(deg) * Random(0x200, 0x5FF) / 0x200; npc->xm = GetCos(deg) * Random(0x200, 0x5FF) / 0x200;
npc->ym = GetSin(deg) * Random(0x200, 0x5FF) / 0x200; npc->ym = GetSin(deg) * Random(0x200, 0x5FF) / 0x200;
} }
@ -697,10 +699,10 @@ void ActNpc007(NPCHAR *npc)
break; break;
} }
if (npc->xm >= 0) if (npc->xm < 0)
npc->direct = 2;
else
npc->direct = 0; npc->direct = 0;
else
npc->direct = 2;
if (npc->xm > 0x5FF) if (npc->xm > 0x5FF)
npc->xm = 0x5FF; npc->xm = 0x5FF;
@ -740,7 +742,26 @@ void ActNpc008(NPCHAR *npc)
switch (npc->act_no) switch (npc->act_no)
{ {
case 0: case 0:
if (gMC.x >= npc->x + 0x2000 || gMC.x <= npc->x - 0x2000) if (gMC.x < npc->x + 0x2000 && gMC.x > npc->x - 0x2000)
{
npc->bits |= 0x20;
npc->ym = -0x100;
npc->tgt_y = npc->y;
npc->act_no = 1;
npc->damage = 2;
if (npc->direct == 0)
{
npc->x = gMC.x + 0x20000;
npc->xm = -0x2FF;
}
else
{
npc->x = gMC.x - 0x20000;
npc->xm = 0x2FF;
}
}
else
{ {
npc->bits &= ~0x20; npc->bits &= ~0x20;
npc->rect.right = 0; npc->rect.right = 0;
@ -750,23 +771,6 @@ void ActNpc008(NPCHAR *npc)
return; return;
} }
npc->bits |= 0x20;
npc->ym = -0x100;
npc->tgt_y = npc->y;
npc->act_no = 1;
npc->damage = 2;
if (npc->direct == 0)
{
npc->x = gMC.x + 0x20000;
npc->xm = -0x2FF;
}
else
{
npc->x = gMC.x - 0x20000;
npc->xm = 0x2FF;
}
break; break;
case 1: case 1:
@ -828,6 +832,8 @@ void ActNpc008(NPCHAR *npc)
//Balrog (drop-in) //Balrog (drop-in)
void ActNpc009(NPCHAR *npc) void ActNpc009(NPCHAR *npc)
{ {
int i;
switch (npc->act_no) switch (npc->act_no)
{ {
case 0: case 0:
@ -837,19 +843,19 @@ void ActNpc009(NPCHAR *npc)
case 1: case 1:
npc->ym += 0x20; npc->ym += 0x20;
if (npc->count1 >= 40) if (npc->count1 < 40)
{
++npc->count1;
}
else
{ {
npc->bits &= ~8; npc->bits &= ~8;
npc->bits |= 1; npc->bits |= 1;
} }
else
{
++npc->count1;
}
if (npc->flag & 8) if (npc->flag & 8)
{ {
for (int i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
npc->act_no = 2; npc->act_no = 2;
@ -901,6 +907,10 @@ void ActNpc009(NPCHAR *npc)
//Balrog (shooting) (super-secret version from prototype) //Balrog (shooting) (super-secret version from prototype)
void ActNpc010(NPCHAR *npc) void ActNpc010(NPCHAR *npc)
{ {
unsigned char deg;
int ym;
int xm;
switch (npc->act_no) switch (npc->act_no)
{ {
case 0: case 0:
@ -923,10 +933,10 @@ void ActNpc010(NPCHAR *npc)
--npc->count1; --npc->count1;
npc->act_wait = 0; npc->act_wait = 0;
unsigned char deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y); deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y);
deg += Random(-0x10, 0x10); deg += (unsigned char)Random(-0x10, 0x10);
int ym = GetSin(deg); ym = GetSin(deg);
int xm = GetCos(deg); xm = GetCos(deg);
SetNpChar(11, npc->x, npc->y + 0x800, xm, ym, 0, 0, 0x100); SetNpChar(11, npc->x, npc->y + 0x800, xm, ym, 0, 0, 0x100);
PlaySoundObject(39, 1); PlaySoundObject(39, 1);
@ -956,7 +966,7 @@ void ActNpc010(NPCHAR *npc)
if (npc->flag & 5) if (npc->flag & 5)
npc->xm = 0; npc->xm = 0;
if (gMC.y > npc->y + 0x2000) if (npc->y + 0x2000 < gMC.y)
npc->damage = 5; npc->damage = 5;
else else
npc->damage = 0; npc->damage = 0;
@ -1006,7 +1016,7 @@ void ActNpc010(NPCHAR *npc)
{120, 24, 160, 48}, {120, 24, 160, 48},
}; };
if (gMC.x > npc->x) if (npc->x < gMC.x)
npc->direct = 2; npc->direct = 2;
else else
npc->direct = 0; npc->direct = 0;
@ -1055,12 +1065,16 @@ void ActNpc011(NPCHAR *npc)
//Balrog (cutscene) //Balrog (cutscene)
void ActNpc012(NPCHAR *npc) void ActNpc012(NPCHAR *npc)
{ {
int i;
int x;
int y;
switch (npc->act_no) switch (npc->act_no)
{ {
case 0: case 0:
if (npc->direct == 4) if (npc->direct == 4)
{ {
if (gMC.x < npc->x) if (npc->x > gMC.x)
npc->direct = 0; npc->direct = 0;
else else
npc->direct = 2; npc->direct = 2;
@ -1091,7 +1105,7 @@ void ActNpc012(NPCHAR *npc)
case 10: case 10:
if (npc->direct == 4) if (npc->direct == 4)
{ {
if (gMC.x < npc->x) if (npc->x > gMC.x)
npc->direct = 0; npc->direct = 0;
else else
npc->direct = 2; npc->direct = 2;
@ -1130,7 +1144,7 @@ void ActNpc012(NPCHAR *npc)
case 20: case 20:
if (npc->direct == 4) if (npc->direct == 4)
{ {
if (gMC.x < npc->x) if (npc->x > gMC.x)
npc->direct = 0; npc->direct = 0;
else else
npc->direct = 2; npc->direct = 2;
@ -1141,7 +1155,7 @@ void ActNpc012(NPCHAR *npc)
npc->act_wait = 0; npc->act_wait = 0;
npc->count1 = 0; npc->count1 = 0;
for (int i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
PlaySoundObject(72, 1); PlaySoundObject(72, 1);
@ -1184,7 +1198,7 @@ void ActNpc012(NPCHAR *npc)
case 40: case 40:
if (npc->direct == 4) if (npc->direct == 4)
{ {
if (gMC.x < npc->x) if (npc->x > gMC.x)
npc->direct = 0; npc->direct = 0;
else else
npc->direct = 2; npc->direct = 2;
@ -1205,7 +1219,7 @@ void ActNpc012(NPCHAR *npc)
case 42: case 42:
if (npc->direct == 4) if (npc->direct == 4)
{ {
if (gMC.x < npc->x) if (npc->x > gMC.x)
npc->direct = 0; npc->direct = 0;
else else
npc->direct = 2; npc->direct = 2;
@ -1303,8 +1317,8 @@ void ActNpc012(NPCHAR *npc)
case 102: case 102:
{ {
int x = npc->x / 0x200 / 0x10; x = npc->x / 0x200 / 0x10;
int y = npc->y / 0x200 / 0x10; y = npc->y / 0x200 / 0x10;
if (y >= 0 && y < 35 && ChangeMapParts(x, y, 0)) if (y >= 0 && y < 35 && ChangeMapParts(x, y, 0))
{ {
@ -1412,17 +1426,20 @@ void ActNpc014(NPCHAR *npc)
{224, 0, 240, 16}, {224, 0, 240, 16},
}; };
if (npc->act_no == 0) switch (npc->act_no)
{ {
npc->act_no = 1; case 0:
npc->act_no = 1;
if (npc->direct == 2) if (npc->direct == 2)
{ {
npc->ym = -0x200; npc->ym = -0x200;
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
} }
break;
} }
if (++npc->ani_wait > 1) if (++npc->ani_wait > 1)
@ -1563,8 +1580,7 @@ void ActNpc017(NPCHAR *npc)
{304, 0, 320, 16}, {304, 0, 320, 16},
}; };
int aa; int a;
switch (npc->act_no) switch (npc->act_no)
{ {
case 0: case 0:
@ -1572,27 +1588,22 @@ void ActNpc017(NPCHAR *npc)
if (npc->direct == 2) if (npc->direct == 2)
{ {
npc->ym = -512; npc->ym = -0x200;
for (int a = 0; a < 4; ++a) for (a = 0; a < 4; ++a)
SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
} }
// Fallthrough // Fallthrough
case 1: case 1:
aa = Random(0, 30); a = Random(0, 30);
if (aa >= 10) if (a < 10)
{
if (aa >= 25)
npc->act_no = 4;
else
npc->act_no = 3;
}
else
{
npc->act_no = 2; npc->act_no = 2;
} else if (a < 25)
npc->act_no = 3;
else
npc->act_no = 4;
npc->act_wait = Random(0x10, 0x40); npc->act_wait = Random(0x10, 0x40);
npc->ani_wait = 0; npc->ani_wait = 0;
@ -1665,10 +1676,12 @@ void ActNpc018(NPCHAR *npc)
// Balrog (burst) // Balrog (burst)
void ActNpc019(NPCHAR *npc) void ActNpc019(NPCHAR *npc)
{ {
int i;
switch (npc->act_no) switch (npc->act_no)
{ {
case 0: case 0:
for (int i = 0; i < 0x10; ++i) for (i = 0; i < 0x10; ++i)
SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
npc->y += 0x1400; npc->y += 0x1400;