diff --git a/config/cflags.txt b/config/cflags.txt index 6e776022b..114381f1b 100644 --- a/config/cflags.txt +++ b/config/cflags.txt @@ -3135,3 +3135,29 @@ src/levels/shared/L00_003A53E8-g16.c -O2 -G16 -Wa,-G16 -ffunction-sections -frac src/levels/11_joba/L11_00420C88-state-g8.c -O2 -G8 -ffunction-sections -frac2-qcopy -frac2-qcopy-barrier src/levels/shared/L00_002D7940.c -O2 -G0 -ffunction-sections -Wa,--r5900-unsigned32-mask=sn src/levels/02_maktar_nebula/L02_003D0408-g8.c -O2 -G8 -ffunction-sections -frac2-hazard-labels +src/pal/levels/20_yeedil/L20_00449870.c -O2 -G0 -ffunction-sections -frac2-hazard-labels +src/pal/levels/shared/L00_003BFBD8-nointerblock-g8.c -O2 -G8 -ffunction-sections -fno-sched-interblock +src/pal/levels/shared/L02_00335678.c -O2 -G0 -ffunction-sections -mno-split-addresses +src/pal/levels/06_notak/L06_00405FA8-hz.c -O2 -G0 -ffunction-sections -g +src/pal/levels/shared/L04_0040B8B8-trail.c -O2 -G0 -ffunction-sections -g +src/pal/levels/11_joba/L11_00445BB8-g.c -O2 -G0 -ffunction-sections -g +src/pal/levels/shared/L02_0038CE70-hz.c -O2 -G0 -ffunction-sections -mno-split-addresses +src/pal/levels/shared/L00_002D5380-g8.c -O2 -G8 -ffunction-sections -frac2-hazard-labels +src/pal/levels/shared/L04_0033EB40-movement.c -O2 -G0 -g -ffunction-sections +src/pal/levels/shared/L18_003FDE80-switch-g8.c -O2 -G8 -ffunction-sections -frac2-keep-block-order +src/pal/levels/20_yeedil/L20_003A1940-g8-hz.c -O2 -G8 -ffunction-sections -mno-split-addresses +src/pal/levels/shared/L01_002A8B30.c -O2 -G0 -ffunction-sections +src/pal/levels/11_joba/L11_0043C288-g8.c -O2 -G8 -ffunction-sections -frac2-zero-ti-por -frac2-keep-block-order +src/pal/levels/01_oozla/L01_00414828-g8.c -O2 -G8 -ffunction-sections -mno-split-addresses +src/pal/levels/01_oozla/L01_003D5C30-g8.c -O2 -G8 -ffunction-sections -g +src/pal/levels/02_maktar_nebula/L02_00402030-g8.c -O2 -G8 -ffunction-sections +src/pal/levels/01_oozla/L01_00432438-g8.c -O2 -G8 -ffunction-sections -g -frac2-hazard-labels +src/pal/levels/00_aranos_tutorial/L00_004138A0-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 +src/pal/levels/01_oozla/L01_00415E78-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 +src/pal/levels/02_maktar_nebula/L02_0043F638-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 +src/pal/levels/05_feltzin_system/L05_00419C60-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 +src/pal/levels/06_notak/L06_0045ACC8-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 +src/pal/levels/10_hrugis_cloud/L10_0041A730-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 +src/pal/levels/11_joba/L11_00473908-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 +src/pal/levels/12_todano/L12_0041C930-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 +src/pal/levels/13_boldan/L13_00421C68-f7-g8.c -O2 -G8 -ffunction-sections -malign-loops=2 diff --git a/src/pal/levels/00_aranos_tutorial/L00_004138A0-f7-g8.c b/src/pal/levels/00_aranos_tutorial/L00_004138A0-f7-g8.c new file mode 100644 index 000000000..8599bf9f6 --- /dev/null +++ b/src/pal/levels/00_aranos_tutorial/L00_004138A0-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L00_004138A0, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L00_004138A0(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/00_aranos_tutorial/L00_004138A0.c b/src/pal/levels/00_aranos_tutorial/L00_004138A0.c index 3315fe6ac..877bd62d6 100644 --- a/src/pal/levels/00_aranos_tutorial/L00_004138A0.c +++ b/src/pal/levels/00_aranos_tutorial/L00_004138A0.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_004138A0); diff --git a/src/pal/levels/01_oozla/L01_003D2EF0.c b/src/pal/levels/01_oozla/L01_003D2EF0.c index ad27e85d3..558f07c8f 100644 --- a/src/pal/levels/01_oozla/L01_003D2EF0.c +++ b/src/pal/levels/01_oozla/L01_003D2EF0.c @@ -2,4 +2,3 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L01_003D2EF0); -INCLUDE_ASM("asm/pal/levels", func_PAL_L01_003D5C30); diff --git a/src/pal/levels/01_oozla/L01_003D5C30-g8.c b/src/pal/levels/01_oozla/L01_003D5C30-g8.c new file mode 100644 index 000000000..1e0a63df8 --- /dev/null +++ b/src/pal/levels/01_oozla/L01_003D5C30-g8.c @@ -0,0 +1,133 @@ +/* func_PAL_L01_003D5C30, the PAL copy of func_L01_003D1A48: the same C, where 1.0f / 60.0f becomes + 0.020000001f. */ +#include "common.h" + +typedef float Vec[4] __attribute__((aligned(16))); +typedef struct { Vec p[4]; int color[4]; float uv[4][2]; long gs[4]; } Quad; +extern long func_0027C878(int); +extern void func_00282F20(void *, void *, float); +extern void func_00282CC0(void *, void *, void *); +extern void func_00282CF0(void *, void *, void *); +extern u32 func_002AAE98(float, float, float, float); +extern float func_00283CC8(float *, float); +extern float func_00283198(float); +extern float func_002A7798(float); +extern int func_00283CF0(float); +extern void func_00280B90(void *, int, int); +extern float D_L01_001B04D4 __attribute__((sda)); +extern float D_L01_001B04D8 __attribute__((sda)); +extern float D_L01_001B04DC __attribute__((sda)); +extern int D_L01_001B04E0 __attribute__((sda)); +extern int D_L01_001B04E4 __attribute__((sda)); +extern int D_L01_001B04E8 __attribute__((sda)); +extern int D_L01_001B04EC __attribute__((sda)); +extern int D_L01_001B04F0 __attribute__((sda)); +extern float D_L01_001B04F4 __attribute__((sda)); +extern float D_L01_001B04F8 __attribute__((sda)); +extern float D_L01_001B04FC __attribute__((sda)); +extern float D_L01_001B0500 __attribute__((sda)); +extern float D_L01_001B0504 __attribute__((sda)); +extern float D_L01_001B0508 __attribute__((sda)); +extern float D_L01_001B050C __attribute__((sda)); +extern float D_L01_001B0510 __attribute__((sda)); +extern float D_L01_001B0514 __attribute__((sda)); +extern float D_L01_001B0518 __attribute__((sda)); +extern float D_L01_001B051C __attribute__((sda)); +extern float D_L01_001B0520 __attribute__((sda)); +extern float D_L01_001B0524 __attribute__((sda)); +extern float D_L01_001B0528 __attribute__((sda)); +extern float D_L01_001B052C __attribute__((sda)); +extern float D_L01_001B0530 __attribute__((sda)); +extern float D_L01_001B0534 __attribute__((sda)); +extern float D_L01_001B0538 __attribute__((sda)); +extern float D_L01_001B053C __attribute__((sda)); + +void func_PAL_L01_003D5C30(u8 *m) +{ + Quad q; + Vec a,b,c,d,e; + float phase; + u8 *s = *(u8 **)(m+0x68); + float width, step, t, v, angle, halfWidth, scroll; + long blend; + int color; + int i; + q.gs[1] = func_0027C878(*(int *)(s+0xB4)+0x3F); + width = D_L01_001B04D4 / D_L01_001B04D8; + scroll = (D_L01_001B053C * (0.020000001f)) / width; + halfWidth = -(D_L01_001B04D4*0.5f); + q.gs[2] = 0xFF9000000260ULL; + blend = (long)D_L01_001B04E0 | ((long)D_L01_001B04E4 << 2); + blend |= (long)D_L01_001B04E8 << 4; + blend |= (long)D_L01_001B04EC << 6; + blend |= (long)D_L01_001B04F0 << 32; + q.gs[3] = blend; + q.gs[0] = 0; + *(float *)(s+0xB8) -= scroll; + func_00282F20(a,m+0xC0,halfWidth); + func_00282CC0(a,a,s+0x60); + func_00282F20(b,m+0xC0,width); + func_00282F20(d,m+0xD0,-(D_L01_001B04DC*0.5f)); + func_00282F20(e,m+0xD0,D_L01_001B04DC*((1.0f-D_L01_001B0530)*0.5f)); + step = 1.0f / D_L01_001B04D8; + for(i=0;i<5;i++) { + v=0.0f; + switch(i) { + case 0: + a[2]+=D_L01_001B0528; + qcopy(c,a); + color=func_002AAE98(D_L01_001B04F8,D_L01_001B04FC,D_L01_001B0500,0.0f); + q.color[2]=q.color[3]=color; + v=func_00283CC8(&phase,*(float *)(s+0xB8)); + break; + case 1: + qcopy(c,a); + color=func_002AAE98(D_L01_001B0504,D_L01_001B0508,D_L01_001B050C,0.0f); + q.color[2]=q.color[3]=color; + v=func_00283CC8(&phase,*(float *)(s+0xB8)+0.5f); + break; + case 2: + a[2]+=D_L01_001B0528; + qcopy(c,a); + color=func_002AAE98(D_L01_001B0510,D_L01_001B0514,D_L01_001B0518,0.0f); + q.color[2]=q.color[3]=color; + func_00282F20(d,d,D_L01_001B04DC*(D_L01_001B052C*0.5f)); + width*=D_L01_001B0530; + step*=D_L01_001B0530; + func_00282F20(b,m+0xC0,width); + v=func_00283CC8(&phase,(D_L01_001B0534 * *(float *)(s+0xB8))/D_L01_001B0530); + break; + case 3: + v=func_00283CC8(&phase,(D_L01_001B0538 * *(float *)(s+0xB8))/D_L01_001B0530); + color=func_002AAE98(D_L01_001B051C,D_L01_001B0520,D_L01_001B0524,0.0f); + q.color[2]=q.color[3]=color; + func_00282CC0(c,a,e); + break; + case 4: + func_00282CF0(c,a,e); + break; + } + func_00282CF0(q.p[2],c,d); + t=step; + func_00282CC0(q.p[3],c,d); + func_00282CC0(c,c,b); + q.uv[2][0]=q.uv[0][0]=0.0f; + q.uv[3][0]=q.uv[1][0]=1.0f; + q.uv[1][1]=q.uv[0][1]=v; + q.uv[3][1]=q.uv[2][1]=v+1.0f; + while(t<1.0f) { + int rgb = 0xFFFFFF; + angle=func_002A7798(func_00283198(t*3.14159274f))*128.0f; + q.color[0]=q.color[1]=q.color[2]; + color=func_00283CF0((D_L01_001B04F4*angle)* *(float *)(s+0xAC)); + q.color[2]=q.color[3]=(q.color[0]&rgb)|(color<<24); + qcopy(q.p[0],q.p[2]); + qcopy(q.p[1],q.p[3]); + func_00282CF0(q.p[2],c,d); + t+=step; + func_00282CC0(q.p[3],c,d); + func_00282CC0(c,c,b); + func_00280B90(&q,0,1); + } + } +} diff --git a/src/pal/levels/01_oozla/L01_004145E0.c b/src/pal/levels/01_oozla/L01_004145E0.c index c196bbebd..3f0eb7ab9 100644 --- a/src/pal/levels/01_oozla/L01_004145E0.c +++ b/src/pal/levels/01_oozla/L01_004145E0.c @@ -1,7 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L01_00414828); -INCLUDE_ASM("asm/pal/levels", func_PAL_L01_00415E78); diff --git a/src/pal/levels/01_oozla/L01_00414828-g8.c b/src/pal/levels/01_oozla/L01_00414828-g8.c new file mode 100644 index 000000000..e1d10f4e8 --- /dev/null +++ b/src/pal/levels/01_oozla/L01_00414828-g8.c @@ -0,0 +1,102 @@ +/* func_PAL_L01_00414828, the PAL copy of func_L01_0040F5A8: the same C, where func_L00_0032A258 + becomes func_PAL_L00_0032C328; 0.016666668f becomes 0.020000001f; 0.083333336f becomes + 0.10000001f; func_00273730 becomes func_PAL_002735D0; 0.015000000596046448f becomes + 0.018000001f; func_L01_002E1680 becomes func_PAL_L01_002E2968; 0.0066666672937572f becomes + 0.008f; func_002B0A68 becomes func_PAL_002B15D8; func_L00_00326110 becomes + func_PAL_L00_003281C0; 0x78 becomes 0x64. */ +#include "common.h" + +typedef union { int q __attribute__((mode(TI))); float f[4]; } DebrisVector; + +extern s32 D_L01_001AEC38 SDATA(D_L01_001AEC38); +extern s32 D_L01_001AEC38_1 __asm__("D_L01_001AEC38"); +extern s32 D_L01_001B3468 SDATA(D_L01_001B3468); +extern s32 D_L01_001B3468_1 __asm__("D_L01_001B3468"); +extern float D_L01_001B2090 __attribute__((sda)); +extern float D_L01_001B208C __attribute__((sda)); +extern s32 D_L01_001B15E0 NOT_SDA; +extern float D_L01_001B1600[] SDATA(D_L01_001B1600); +extern float D_L01_001B15F8[] SDATA(D_L01_001B15F8); +extern float D_L01_001B15F0[] SDATA(D_L01_001B15F0); +extern float D_L01_001B1620 __attribute__((sda)); +extern float D_L01_001B1624 NOT_SDA; +extern float D_L01_001B1628 NOT_SDA; +extern char D_L01_001A8F60[] NOT_SDA; + +extern s32 func_00282948(char *); +extern void func_0029F338(char *); +extern void func_002A7750(char *, s32, s32); +extern s32 func_002A9640(char *, s32, s32); +extern float func_002A7878(float, float); +extern void *func_PAL_002735D0(char *, s32, s32, s32, char *, char *, void *, s32, float, float); +extern void func_00283098(void *, void *, void *); +extern void func_PAL_002B15D8(char *, s32, char *, s32, float, float, float, float); +extern s32 func_002B3868(char *); +extern void func_002E5CF8(s32, s32, char *); +extern void func_L00_00324F18(char *, void *, float, float, float); +extern void func_PAL_L00_003281C0(char *, s32, float); +extern void func_PAL_L00_0032C328(char *, void *, void *, void *, s32, s32, s32, s32, s32, u8, void *); +extern void func_PAL_L01_002E2968(float, float, float, void *, void *, s32, u32, s32); + +typedef struct { char pad0[0x31]; u8 active; u16 pad32; u16 flags; char pad36[0x62]; int target; } RetiringObject; +void func_PAL_L01_00414828(char *obj) +{ + DebrisVector velocity, jitter, position; + char *rec = *(char **)(obj + 0x68); + + switch (*(u8 *)(obj + 0x20)) { + case 0: + D_L01_001AEC38 = D_L01_001AEC38_1 + 1; + func_002A7750(obj, 1, -1); + break; + case 1: + if (func_002A9640(obj, 0x04010000, 0) != 0 && *(s32 *)rec == 0) { + D_L01_001AEC38 = D_L01_001AEC38_1 - 1; + func_002A7750(obj, 2, -1); + } + *(u8 *)(obj + 0xA8) = 0xFF; + break; + case 2: + if (*(u8 *)(obj + 0x31) != 0 && D_L01_001B2090 < 0.9f && D_L01_001B208C < 0.9f + && D_L01_001B3468 < D_L01_001B15E0) { + func_PAL_L00_0032C328(obj, D_L01_001B1600, D_L01_001B15F8, D_L01_001B15F0, + 65535, 0, 0, 6, 65535, 255, 0); + jitter.q = 0; + jitter.f[0] = func_002A7878(-1.0f, 1.0f) * 0.020000001f; + jitter.f[1] = func_002A7878(-1.0f, 1.0f) * 0.020000001f; + jitter.f[2] = 0.10000001f; + velocity.q = jitter.q; + func_PAL_002735D0(obj, 2, *(s16 *)(obj + 0xaa), 0, obj + 0x10, obj + 0xf0, + &velocity, 255, func_002A7878(180.0f, 360.0f), 15.0f); + jitter.q = 0; + jitter.f[1] = -0.018000001f; + func_L00_00324F18(obj, &position, D_L01_001B1620, D_L01_001B1624, D_L01_001B1628); + func_00283098(&jitter, &jitter, obj + 0xc0); + func_PAL_L01_002E2968(0.008f, 1.0f, 1.0299999713897705f, &position, &jitter, 10, 0x80808080, 0); + func_002A7750(obj, 3, -1); + } else { + func_PAL_002B15D8(obj, 17, D_L01_001A8F60, 255, 1.0f, 3.0f, 2.0f, 5.0f); + func_PAL_L00_003281C0(obj, 1, 0.0f); + func_002E5CF8(0, 0, obj); + } + func_002A7750(obj, 3, -1); + break; + case 3: + if (func_002B3868(obj) != 0) { + RetiringObject *retiring = (RetiringObject *)obj; + unsigned int flags = retiring->flags; + int count; + retiring->active = 0; + retiring->target = 0; + count = D_L01_001B3468_1; + retiring->flags = flags | 1; + *(int *)(rec + 8) = 0x64; + D_L01_001B3468_1 = count + 1; + } + if (func_00282948(rec + 8) != 0) { + D_L01_001B3468 = D_L01_001B3468 - 1; + func_0029F338(obj); + } + break; + } +} diff --git a/src/pal/levels/01_oozla/L01_00415E78-f7-g8.c b/src/pal/levels/01_oozla/L01_00415E78-f7-g8.c new file mode 100644 index 000000000..6b29bc330 --- /dev/null +++ b/src/pal/levels/01_oozla/L01_00415E78-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L01_00415E78, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L01_00415E78(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/01_oozla/L01_00432064.c b/src/pal/levels/01_oozla/L01_00432064.c index 45d3e0de7..faca2fd5f 100644 --- a/src/pal/levels/01_oozla/L01_00432064.c +++ b/src/pal/levels/01_oozla/L01_00432064.c @@ -2,4 +2,3 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L01_00432064); -INCLUDE_ASM("asm/pal/levels", func_PAL_L01_00432438); diff --git a/src/pal/levels/01_oozla/L01_00432438-g8.c b/src/pal/levels/01_oozla/L01_00432438-g8.c new file mode 100644 index 000000000..f44b108da --- /dev/null +++ b/src/pal/levels/01_oozla/L01_00432438-g8.c @@ -0,0 +1,108 @@ +/* func_PAL_L01_00432438, the PAL copy of func_L01_0042C8D8: the same C, where 0.016666668f becomes + 0.020000001f; func_L01_002BEB90 becomes func_PAL_L01_002BEC60. */ +#include "common.h" +typedef float RouteVector[4] __attribute__((aligned(16))); +typedef struct { short idx[8]; float angle[8]; float roll; } PathKeys; +typedef struct { char pad0[0x20]; int path; int look; int target; float offset[3]; char pad38; unsigned char finished; char pad3a[2]; float speed; char pad40[0x18]; int lock; } CameraPath; +typedef struct { int segment; float distance; float length; float scale; float travelled; short started; short stop; } PathMotion; +extern unsigned char *D_L01_001B1F04; +extern unsigned char *D_L01_001FE180[]; +extern unsigned char *D_L01_001B255C; +extern unsigned char D_L01_001B96F0[]; +extern unsigned char D_0018A0E0[]; +extern int D_L01_001B1FA8; +extern int D_L01_001B1FA8_gp SDATA(D_L01_001B1FA8); +extern int func_L00_00341820(void *, void *, void *, void *, int, float); +extern int func_00282978(void *); +extern void func_00283098(void *, void *, void *); +extern void func_00282CC0(void *, void *, void *); +extern void func_00282CF0(void *, void *, void *); +extern void func_00282D30(void *, void *, float); +extern void func_00282F20(void *, void *, float); +extern void func_00282DD8(void *, void *, void *); +extern float func_00282E48(void *, void *); +extern void func_0026FF08(int, int, float, float, float, float); +extern void func_00272198(float); +extern float func_002A7C00(float, float, float); +extern void func_PAL_L01_002BEC60(int, int); + +void func_PAL_L01_00432438(unsigned char *camera) +{ + RouteVector old, up, direction, target; + unsigned char *v = *(unsigned char **)(camera + 0x70); + CameraPath *c = *(CameraPath **)(D_L01_001B1F04 + *(short *)(camera + 0x84) * 32 + 0x1c); + PathMotion *motion = (PathMotion *)(v + 0x40); + unsigned char *path; + PathKeys *keys = (PathKeys *)(v + 0x58); + int done, i, j, k, target_index, local_segment; + float along, total, local_distance; + if (!motion->started) { + unsigned char *start = D_L01_001FE180[c->path]; + unsigned char *look = D_L01_001FE180[c->look]; + if (c->lock) D_L01_001B1FA8 = 1; + motion->started = 1; + qcopy(camera + 0x30, start + 0x10); + target_index = c->target; + if (target_index >= 0) { + float *src = c->offset; + unsigned char *entity = D_L01_001B255C + target_index * 256; + up[0] = src[0]; up[1] = src[1]; up[2] = src[2]; + *(int *)&up[3] = 0; + func_00283098(up, up, D_L01_001B96F0); + func_00282CC0(direction, entity + 0x10, up); + func_00282CF0(old, direction, camera + 0x30); + } else func_00282CF0(old, look + 0x10, camera + 0x30); + func_00282D30(up, D_0018A0E0, -1.0f); + func_00282F20(camera, old, 1.0f); + func_00282DD8(camera + 0x10, camera, up); + func_00282F20(camera + 0x10, camera + 0x10, 1.0f); + func_00282DD8(camera + 0x20, camera + 0x10, camera); + return; + } + path = D_L01_001FE180[c->path]; + qcopy(old, camera + 0x30); + done = func_L00_00341820(path, camera + 0x30, &motion->segment, v + 0x44, 0, c->speed * 0.020000001f); + if (motion->stop && func_00282978(v + 0x56)) done = 1; + if (c->finished) done = 1; + if (done) { + c->finished = 1; + func_0026FF08(0, 3, keys->roll, 0.005f, 0.2f, 0.0f); + func_00272198(4.0f); + *(short *)(camera + 0x7e) = 4; + if (c->lock) D_L01_001B1FA8_gp = 0; + func_PAL_L01_002BEC60(0, 1); + return; + } + for (i = 0; i < 7 && keys->idx[i] >= 0 && keys->idx[i + 1] >= 0; ++i) { + if (motion->segment >= keys->idx[i] && motion->segment < keys->idx[i + 1]) { + along = 0; + for (j = keys->idx[i]; j < motion->segment; ++j) along += *(float *)(path + j * 16 + 0x1c); + total = along; + along += motion->distance; + for (k = motion->segment; k < keys->idx[i + 1]; ++k) total += *(float *)(path + k * 16 + 0x1c); + func_0026FF08(0, 3, func_002A7C00(keys->angle[i], + keys->angle[i + 1], along / total) * 0.017453294f, 0.005f, 0.2f, 0); + } + } + motion->travelled += func_00282E48(old, camera + 0x30); + target_index = c->target; + if (target_index >= 0) { + float *src = c->offset; + unsigned char *entity = D_L01_001B255C + target_index * 256; + direction[0] = src[0]; direction[1] = src[1]; direction[2] = src[2]; + *(int *)&direction[3] = 0; + func_00283098(direction, direction, D_L01_001B96F0); + func_00282CC0(target, entity + 0x10, direction); + func_00282CF0(up, target, camera + 0x30); + } else { + float progress = motion->travelled / motion->length * motion->scale; + local_segment = 0; local_distance = 0; + func_L00_00341820(D_L01_001FE180[c->look], direction, &local_segment, &local_distance, 0, progress); + func_00282CF0(up, direction, camera + 0x30); + } + func_00282D30(direction, D_0018A0E0, -1.0f); + func_00282F20(camera, up, 1.0f); + func_00282DD8(camera + 0x10, camera, direction); + func_00282F20(camera + 0x10, camera + 0x10, 1.0f); + func_00282DD8(camera + 0x20, camera + 0x10, camera); +} diff --git a/src/pal/levels/02_maktar_nebula/L02_003D62B8-hz.c b/src/pal/levels/02_maktar_nebula/L02_003D62B8-hz.c new file mode 100644 index 000000000..48791b8ee --- /dev/null +++ b/src/pal/levels/02_maktar_nebula/L02_003D62B8-hz.c @@ -0,0 +1,49 @@ +/* func_PAL_L02_003D62B8, the PAL copy of func_L02_003D2248: the same C, where + 0.0055555556900799274f becomes 0.008f; 0.10333333909511566f becomes 0.124000005f; + 0.0034906589426100254f becomes 0.005026549f; 0.41887909173965454f becomes 0.5026549f; 0xA + becomes 0x8. */ +#include "common.h" + +extern void func_31E6A0(char *, int, int); + +extern void func_31E3C0(char *, int, int, int); + +extern void func_332710(float, float, float, float); + +extern void func_316150(char *, int, int, int); + +extern void func_316180(char *, int *, int *, int *); + +extern void func_L02_003D1E40(char *self); +void func_PAL_L02_003D62B8(char *arg0, int arg1) { + char *p = *(char **)(arg0 + 0x68); + + *(short *)(p + 0x2F6) = 0; + *(float *)(p + 0x20) = (float)*(short *)(p + 0x24); + func_332710(0.008f, 0.124000005f, 0.005026549f, + 0.5026549f); + func_31E6A0(arg0, 3, 1); + if (*(unsigned char *)(arg0 + 0x43) != 0) + func_31E3C0(arg0, 0, 0, 0x8); + *(int *)(arg0 + 0x98) = *(int *)(*(char **)(arg0 + 0x24) + 0x10); + *(unsigned char *)(p + 0x6A) = 0; + *(unsigned char *)(p + 0x2E) = 1; + *(unsigned char *)(arg0 + 0x7F) = 0; + *(unsigned char *)(arg0 + 0x31) = 1; + *(unsigned short *)(arg0 + 0x34) = (*(unsigned short *)(arg0 + 0x34) | 0x1000) & 0xFFB8; + func_L02_003D1E40(arg0); + *(short *)(p + 0x2FC) = arg1; + *(short *)(p + 0x88) = 0; + if (*(short *)(p + 0x50) != 0) { + *(short *)(p + 0x50) = 0; + func_316150(arg0, *(unsigned char *)(p + 0x54), *(unsigned char *)(p + 0x55), + *(unsigned char *)(p + 0x56)); + *(short *)(p + 0x52) = 1; + } + if (*(char **)(p + 0x2E4) != 0) { + int a, b, c; + + func_316180(arg0, &a, &b, &c); + func_316150(*(char **)(p + 0x2E4), a, b, c); + } +} diff --git a/src/pal/levels/02_maktar_nebula/L02_003D62B8.c b/src/pal/levels/02_maktar_nebula/L02_003D62B8.c index e144b048e..877bd62d6 100644 --- a/src/pal/levels/02_maktar_nebula/L02_003D62B8.c +++ b/src/pal/levels/02_maktar_nebula/L02_003D62B8.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L02_003D62B8); diff --git a/src/pal/levels/02_maktar_nebula/L02_00402030-g8.c b/src/pal/levels/02_maktar_nebula/L02_00402030-g8.c new file mode 100644 index 000000000..c102e1535 --- /dev/null +++ b/src/pal/levels/02_maktar_nebula/L02_00402030-g8.c @@ -0,0 +1,142 @@ +/* func_PAL_L02_00402030, the PAL copy of func_L02_003FD8B8: the same C, where func_L00_002C42E0 + becomes func_PAL_L00_002C4480; 15 becomes 12; func_L02_003FCA80 becomes func_PAL_L02_004011D8; + 60 becomes 50. */ +#include "common.h" + +extern int func_002B4BE8(void); +extern int func_00288D58(void); +extern int func_L02_003F9B70(unsigned int); +extern int func_PAL_L00_002C4480(int, int); +extern int func_002E5E58(int, int, void *); +extern int func_00282978(short *); +extern void func_002A7750(u8 *, int, int); +extern void func_003355A8(int); +extern void func_L00_002C8BA8(int); +extern int func_002B49E0(int, int, int, int, u8 *); +extern void func_PAL_L02_004011D8(u8 *); +extern void func_002B8518(void); +extern int func_L00_0032EF10(unsigned int, int, int *); +extern void func_L00_002E6CF0(void (*)(void *), void *); +extern void func_L02_003FE250(void *); +extern int D_0018C0B4[3], D_L02_002004A4[3]; + +typedef struct { + u8 pad[0x1a0]; + int field1a0, field1a4; + u8 gap[24]; + int field1c0, field1c4; +} InputView; +extern unsigned char D_00138180[]; +extern unsigned char D_00139568[], D_001395B8[]; +typedef struct { + u8 pad[4]; + u8 enabled; + u8 rest[0xdb]; +} MenuRecord; +extern unsigned char D_L02_00264A70[]; +#define MENU ((MenuRecord *)D_L02_00264A70) +extern int D_L02_001B1190 __attribute__((sda)); +#define TABLE ((int **)&D_L02_001B1190) +#define H(o) (*(short *)(state+(o))) + +void func_PAL_L02_00402030(u8 *object) +{ + u8 *state = *(u8 **)(object + 0x68); + int i, found; + InputView *input; + if (func_002B4BE8()==5) return; + if (D_0018C0B4[0]!=0x6f) func_PAL_L00_002C4480(0x6f,1); + if (H(0x11a)==0) { + if ((((InputView *)D_00138180)->field1c4&0x2000) && H(0x118)<13) { + for (i=H(0x118)+1;i<14;i++) { + if (!D_001395B8[func_L02_003F9B70(TABLE[i][2])]) continue; + if (i>=12 && !func_00288D58()) continue; + if (i==7) { + MenuRecord *choice = (MenuRecord *)(D_L02_00264A70 + D_00139568[0x1e] * 0xe0); + if (!choice->enabled) continue; + } + if (i==8) { + MenuRecord *choice = (MenuRecord *)(D_L02_00264A70 + D_00139568[0x2a] * 0xe0); + if (!choice->enabled) continue; + } + H(0x118)=i; + H(0x11a)=12; + H(0x128)=12; + func_002E5E58(3,0,0); + break; + } + } else if ((((InputView *)D_00138180)->field1c4&0x8000) && H(0x118)>0) { + found=0; + if (H(0x118)==1) { + H(0x118)=0; + found=1; + func_002E5E58(3,0,0); + } else for (i=H(0x118)-1;i>=0;i--) { + if (!D_001395B8[func_L02_003F9B70(TABLE[i][2])]) continue; + if (i>=12 && !func_00288D58()) continue; + if (i==7) { + MenuRecord *choice = (MenuRecord *)(D_L02_00264A70 + D_00139568[0x1e] * 0xe0); + if (!choice->enabled) continue; + } + if (i==8) { + MenuRecord *choice = (MenuRecord *)(D_L02_00264A70 + D_00139568[0x2a] * 0xe0); + if (!choice->enabled) continue; + } + H(0x118)=i; + found=1; + break; + } + if (!found) H(0x118)=0; + H(0x11a)=12; + H(0x126)=12; + func_002E5E58(3,0,0); + } + } else func_00282978((short *)(state+0x11a)); + input = (InputView *)D_00138180; + if (input->field1c4&0x40) { + if (H(0x118)==0) { + H(0x120)=*(unsigned short *)(state+0x118); + H(0x122)=0; + D_001395B8[0x3c]=state[0x118]; + func_002A7750(object,8,-1); + func_003355A8(2); + func_L00_002C8BA8(0); + func_002E5E58(4,0,0); + input->field1c4=0; + goto clear_buttons; + } else { + if (!D_001395B8[func_L02_003F9B70(TABLE[H(0x118)][2])]) return; + if (H(0x118)>=12 && !func_00288D58()) return; + if (H(0x118)==7 && !MENU[D_00139568[0x1e]].enabled) return; + if (H(0x118)==8 && !MENU[D_00139568[0x2a]].enabled) return; + } + H(0x120)=*(unsigned short *)(state+0x118); + H(0x122)=0; + D_001395B8[0x3c]=state[0x118]; + func_002A7750(object,8,-1); + func_003355A8(2); + func_L00_002C8BA8(0); + func_002E5E58(4,0,0); + input->field1c4=0; + goto clear_buttons; + } else if (input->field1c4&0x80) { + func_002B49E0(5,1,0,0,0); + return; + } else if (input->field1c4&0x10) { + func_PAL_L02_004011D8(object); + input->field1c4=0; +clear_buttons: + input->field1a0=0; + input->field1c0=0; + input->field1a4=0; + func_002B8518(); + return; + } else if (D_L02_002004A4[0] && + func_L00_0032EF10(1,50,0) && func_L00_0032EF10(2,50,0) && + func_L00_0032EF10(4,50,0) && func_L00_0032EF10(8,50,0)) { + H(0x120)=*(unsigned short *)(state+0x118); + func_002A7750(object,5,-1); + return; + } + func_L00_002E6CF0(func_L02_003FE250,object); +} diff --git a/src/pal/levels/02_maktar_nebula/L02_00402030.c b/src/pal/levels/02_maktar_nebula/L02_00402030.c index c3aca5dfe..877bd62d6 100644 --- a/src/pal/levels/02_maktar_nebula/L02_00402030.c +++ b/src/pal/levels/02_maktar_nebula/L02_00402030.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L02_00402030); diff --git a/src/pal/levels/02_maktar_nebula/L02_0043F638-f7-g8.c b/src/pal/levels/02_maktar_nebula/L02_0043F638-f7-g8.c new file mode 100644 index 000000000..ad621ecd5 --- /dev/null +++ b/src/pal/levels/02_maktar_nebula/L02_0043F638-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L02_0043F638, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L02_0043F638(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/02_maktar_nebula/L02_0043F638.c b/src/pal/levels/02_maktar_nebula/L02_0043F638.c index c89691c66..266833520 100644 --- a/src/pal/levels/02_maktar_nebula/L02_0043F638.c +++ b/src/pal/levels/02_maktar_nebula/L02_0043F638.c @@ -1,6 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L02_0043F638); #include "common.h" typedef int TI128 __attribute__((mode(TI))); diff --git a/src/pal/levels/03_endako/L03_003CAA68-6a28-g8.c b/src/pal/levels/03_endako/L03_003CAA68-6a28-g8.c new file mode 100644 index 000000000..de04a6eeb --- /dev/null +++ b/src/pal/levels/03_endako/L03_003CAA68-6a28-g8.c @@ -0,0 +1,144 @@ +/* func_PAL_L03_003CAA68, the PAL copy of func_L03_003C6A28: the same C, where 0x27BE becomes + 0x1310; 0x27A8 becomes 0x12FA; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_0029B810 + becomes func_PAL_0029C1A8; func_L03_0041F090 becomes func_PAL_L03_004244D8; func_0029B7C0 + becomes func_PAL_0029C158. */ +#include "include_asm.h" + +#include "common.h" + +typedef unsigned int Quad __attribute__((mode(TI))); + +typedef struct { + char pad0[0x80]; + float pos[4]; /* 0x80 */ + float rot[4]; /* 0x90 */ + char padA0[0x13C]; + short mode; /* 0x1DC */ + char pad1DE[0x1652]; + int field1830; /* 0x1830 */ +} Hero6A28; + +typedef struct { + char pad[0x3D4]; + float f; /* 0x3D4 */ + char pad2[0x10]; + char b0; /* 0x3E8 */ + char b1; /* 0x3E9 */ +} AimState6A28; + +extern void func_0029F338(char *); +extern void func_002A7750(char *, int, int); +extern float func_00282E80(char *, char *); +extern void func_00283698(void *, void *); +extern void func_00282CF0(void *, void *, void *); +extern void func_00283098(void *, void *, void *); +extern int func_002B38B8(char *); +extern int func_L03_0032AB20(int); +extern void func_002B0C28(int, int, int); +extern void func_00282CC0(void *, void *, void *); +extern void func_00282C88(void *); +extern float func_00283B98(float, float); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); +extern void func_L03_003C6E50(char *, void *, void *); +extern void func_00335438(void *, void *, int, int, int); +extern void func_L03_003C7A40(char *); +extern void func_L03_003C7A88(char *); +extern void func_003355A8(int); +extern void func_PAL_0029C1A8(int); +extern void func_00335370(void *); +extern void func_003353C8(void *); +extern int func_PAL_L03_004244D8(void *); +extern void func_L00_003294F0(void *, int); +extern void func_PAL_0029C158(void *, void *, int); +extern void func_L03_003C7018(void); + +extern Hero6A28 D_00189E20; +extern char D_00189EA0[]; +extern char *D_L03_001B2A1C MACRO_ADDR; +extern char *D_L03_001B2A1C_GP SDATA(D_L03_001B2A1C); +extern char *D_0018B650 NOT_SDA; +extern int D_00138324 NOT_SDA; +extern AimState6A28 D_L03_001B9840; +extern char D_L03_003C7010[]; + +void func_PAL_L03_003CAA68(char *obj) +{ + char mat[0x40] __attribute__((aligned(16))); + float local[4] __attribute__((aligned(16))); + float rot[4] __attribute__((aligned(16))); + float pos[4] __attribute__((aligned(16))); + float cam1[4] __attribute__((aligned(16))); + float cam2[4] __attribute__((aligned(16))); + char *vars = *(char **)(obj + 0x68); + + switch (*(u8 *)(obj + 0x20)) { + case 0: + if (*(int *)vars == -1) { + func_0029F338(obj); + break; + } + *(int *)(vars + 0x30) = -1; + *(int *)(obj + 0x98) = 0; + *(unsigned short *)(obj + 0x34) |= 1; + obj[0x31] = 0; + func_002A7750(obj, 1, -1); + break; + + case 1: + case 2: + if (func_00282E80(obj + 0x10, D_00189EA0) < 6.0f && *(int *)(D_00189EA0 + 0x2C0)) { + func_00283698(mat, obj + 0xC0); + func_00282CF0(local, D_00189EA0, obj + 0x10); + func_00283098(local, local, mat); + if (*(u8 *)(obj + 0x20) == 1 && func_002B38B8(obj)) + func_002A7750(obj, 2, -1); + if (local[0] < 4.0f && local[0] > 0.0f && local[1] < 2.5f && local[1] > -2.5f) { + if (*(u8 *)(obj + 0x20) == 1) { + func_002B0C28(8, 0x1310, 1); + break; + } + func_002B0C28(8, 0x12FA, 1); + if (func_L03_0032AB20(8) && (D_00138324 & 0x10)) { + func_002A7750(obj, 3, -1); + *(Quad *)pos = 0; + pos[0] = 2.0f; + func_00283098(pos, pos, obj + 0xC0); + func_00282CC0(pos, pos, obj + 0x10); + func_00282C88(rot); + rot[2] = func_00283B98(*(float *)(obj + 0xF8), 3.14159f); + func_PAL_L00_002B9CD8(pos, rot, 0x31, 1); + D_0018B650 = D_L03_001B2A1C + (*(int *)vars << 8); + func_L03_003C6E50(obj, cam1, cam2); + func_00335438(cam1, cam2, 1, 0, 0); + func_L03_003C7A40(D_L03_001B2A1C + (*(int *)vars << 8)); + } + } + } + break; + + case 3: + D_00189E20.mode = 5; + if (D_00138324 & 0x10) { + func_003355A8(0); + func_PAL_L00_002B9CD8(D_00189E20.pos, D_00189E20.rot, 0, 1); + D_00189E20.field1830 = 0; + func_L03_003C7A88(D_L03_001B2A1C + (*(int *)vars << 8)); + D_L03_001B9840.f = 64.42f; + D_L03_001B9840.b1 = 1; + D_L03_001B9840.b0 = 0; + func_002A7750(obj, 2, -1); + func_PAL_0029C1A8(0); + } else { + func_L03_003C6E50(obj, mat, mat + 0x10); + func_00335370(mat); + func_003353C8(mat + 0x10); + if (*(int *)(vars + 0x1C) != -1 + && func_PAL_L03_004244D8(D_L03_001B2A1C_GP + (*(int *)(vars + 0x1C) << 8))) { + if (*(int *)(vars + 0x20) != -1) + func_L00_003294F0(D_L03_001B2A1C_GP + (*(int *)(vars + 0x20) << 8), 1); + } + func_PAL_0029C158(D_L03_003C7010, func_L03_003C7018, 0); + } + break; + } +} diff --git a/src/pal/levels/03_endako/L03_003CAA68.c b/src/pal/levels/03_endako/L03_003CAA68.c index e7a48a674..877bd62d6 100644 --- a/src/pal/levels/03_endako/L03_003CAA68.c +++ b/src/pal/levels/03_endako/L03_003CAA68.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L03_003CAA68); diff --git a/src/pal/levels/03_endako/L03_003CBB00-g8.c b/src/pal/levels/03_endako/L03_003CBB00-g8.c new file mode 100644 index 000000000..8ce44f3be --- /dev/null +++ b/src/pal/levels/03_endako/L03_003CBB00-g8.c @@ -0,0 +1,89 @@ +/* func_PAL_L03_003CBB00, the PAL copy of func_L03_003C7AC0: the same C, where 1.0f / 60.0f becomes + 0.020000001f; 0.000277777785f becomes 0.00040000002f. */ +#include "common.h" +typedef int TI128 __attribute__((mode(TI))); +extern float D_L03_001B01BC __attribute__((sda)),D_L03_001B01A4 __attribute__((sda)),D_L03_001B01B4 __attribute__((sda)),D_L03_001B01AC __attribute__((sda)); +extern float D_L03_001B01A8 __attribute__((sda)),D_L03_001B01B8 __attribute__((sda)),D_L03_001B01B0 __attribute__((sda)); +extern u8 D_L03_001B01D4 __attribute__((sda)); +extern float D_L03_001B9998 NOT_SDA, D_L03_001BFDE8 NOT_SDA; +typedef struct { float vec[4]; char pad[0x2d4]; int mode; } PlayerState; +extern PlayerState D_0018BDD0; +typedef struct { char pad[0x74]; u8 active; char pad75[0x13]; char *owner; } L03ControlEntry; +extern u8 D_00188660[]; +extern float func_00283B98(float,float); +extern void func_002833F0(void *,void *); +extern float func_00282DF0(void *); +extern int func_002E5CF8(int,int,void *); +extern void func_002E59F8(int); +extern void func_00283098(void *,void *,void *); +extern void func_00282D30(void *,void *,float); +extern void func_00282C88(void *); +extern void func_00282CF0(void *,void *,void *); +extern void func_002AC9F8(void *,float); +extern void func_00282CC0(void *,void *,void *); +extern void func_002C9218(int,void *,void *,float); +extern void func_0029FCC0(void *,int,void *); +extern int func_002761F8(void *,void *,int,void *,int); +extern void func_002A93B0(void *); +void func_PAL_L03_003CBB00(char *obj) +{ + float a[4],b[4],c[4]; + union { float m[12]; struct { float pad[4], d[4]; } v; } scratch; + char *state=*(char **)(obj+0x68); + char *other; + int id; + if(*(u8 *)(obj+0x20)==2) { + *(TI128 *)c=0; + c[2]=func_00283B98(D_L03_001B9998,D_L03_001B01BC*0.017453294f); + *(TI128 *)(b)=*(TI128 *)(c); + func_002833F0(scratch.m,b); + qcopy(a,D_0018BDD0.vec); + if(func_00282DF0(a)>0.0f && D_0018BDD0.mode==0x31) { + L03ControlEntry *entry=(L03ControlEntry *)(D_00188660+*(int *)(state+0x108)*0x70); + if(entry->owner!=obj || !entry->active) + *(int *)(state+0x108)=func_002E5CF8(0,4,obj); + } else { + id=*(int *)(state+0x108); + if(id!=-1) { + L03ControlEntry *entry=(L03ControlEntry *)(D_00188660+id*0x70); + if(entry->owner==obj && entry->active) func_002E59F8(id); + } + *(int *)(state+0x108)=-1; + } + a[0]=-a[0]; + func_00283098(a,a,scratch.m); + other=*(char **)(state+0xf0); + if(other) { + if(*(short *)(other+0xaa)==0xb85) func_00282D30(a,a,D_L03_001B01AC*(0.020000001f)); + else func_00282D30(a,a,D_L03_001B01B4*(0.020000001f)); + } else func_00282D30(a,a,D_L03_001B01A4*(0.020000001f)); + } else { + id=*(int *)(state+0x108); + if(id!=-1) { + L03ControlEntry *entry=(L03ControlEntry *)(D_00188660+id*0x70); + if(entry->owner==obj && entry->active) func_002E59F8(id); + } + *(int *)(state+0x108)=-1; + func_00282C88(a); + } + func_00282CF0(b,a,state+0xe0); + b[2]=0; + other=*(char **)(state+0xf0); + if(other) { + if(*(short *)(other+0xaa)==0xb85) func_002AC9F8(b,D_L03_001B01B0*0.00040000002f); + else func_002AC9F8(b,D_L03_001B01B8*0.00040000002f); + } else { + func_002AC9F8(b,D_L03_001B01A8*0.00040000002f); + } + func_00282CC0(state+0xe0,state+0xe0,b); + func_00282CC0(obj+0x10,obj+0x10,state+0xe0); + func_002C9218(*(int *)state,obj+0x10,obj+0x10,1.25f); + func_0029FCC0(obj,2,c); + qcopy(scratch.m,c); + scratch.m[2]+=20.0f; + qcopy(scratch.v.d,c); + scratch.v.d[2]+=0.5f; + if(func_002761F8(scratch.v.d,scratch.m,2,obj,0)) *(float *)(state+0xf4)=D_L03_001BFDE8; + func_002A93B0(obj); + *(u8 *)(obj+0xbd)=D_L03_001B01D4; +} diff --git a/src/pal/levels/03_endako/L03_003CBB00.c b/src/pal/levels/03_endako/L03_003CBB00.c index 741b2d613..9d4359bd2 100644 --- a/src/pal/levels/03_endako/L03_003CBB00.c +++ b/src/pal/levels/03_endako/L03_003CBB00.c @@ -1,4 +1,3 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L03_003CBB00); diff --git a/src/pal/levels/03_endako/L03_00422624.c b/src/pal/levels/03_endako/L03_00422624.c index 3e78e8202..95c53d1be 100644 --- a/src/pal/levels/03_endako/L03_00422624.c +++ b/src/pal/levels/03_endako/L03_00422624.c @@ -80,4 +80,3 @@ void func_PAL_L03_00423128(u8 *entity) { -INCLUDE_ASM("asm/pal/levels", func_PAL_L03_00423F28); diff --git a/src/pal/levels/03_endako/L03_00423F28-g8.c b/src/pal/levels/03_endako/L03_00423F28-g8.c new file mode 100644 index 000000000..dbb82068e --- /dev/null +++ b/src/pal/levels/03_endako/L03_00423F28-g8.c @@ -0,0 +1,189 @@ +/* func_PAL_L03_00423F28, the PAL copy of func_L03_0041EAE0: the same C, where 0.00027777778f + becomes 0.00040000002f; 0.016666668f becomes 0.020000001f; func_002B0ED8 becomes + func_PAL_002B1A50; func_0032C700 becomes func_PAL_L00_003FB330; 0.06666667f becomes + 0.080000006f; func_002B0A68 becomes func_PAL_002B15D8; func_002B0A18 becomes func_PAL_002B1588; + func_002A6C58 becomes func_PAL_002A7650. */ +#include "common.h" + +extern void func_002E59F8(int); +extern void func_002A7750(void *,int,int); +extern void func_002A7398(void *,int,int); +extern int func_00283CF0(float); +extern void *func_002A9640(void *,u32,int); +extern int func_PAL_002B1A50(void *,void *,int); +extern void func_00283098(void *,void *,void *); +extern void func_00282CC0(void *,void *,void *); +extern void *func_PAL_L00_003FB330(void *,int,int,int,int,int,int,int,float,float,int,int,int,int); +extern void func_00282F20(void *,void *,float); +extern void func_PAL_002B15D8(void *,int,void *,float,float,float,float,u8); +extern int func_002E5E58(int,int,void *); +extern void func_PAL_002B1588(int,int); +extern int func_002E5CF8(int,int,void *); +extern void func_PAL_002A7650(void *,int,int); +extern void func_0029F338(void *); +extern float func_00282E48(void *,void *); +extern void func_002A93B0(void *); +extern u8 *D_L03_001FE700[] NOT_SDA; +extern float D_L03_001B1C00 __attribute__((sda)); +extern float D_L03_001B1C04 __attribute__((sda)); +extern float D_L03_001B1C0C __attribute__((sda)); +extern float D_L03_001B1C30[4] SDATA(D_L03_001B1C30) __attribute__((sda)); +extern int D_0018C0B4 NOT_SDA; +extern int D_L03_001A9044[] NOT_SDA __attribute__((sda)); +extern int D_L03_001A9044_gp SDATA(D_L03_001A9044) __attribute__((sda)); +extern int D_L03_001A903C[] __attribute__((sda)); +extern u8 D_001A7A60[] MACRO_ADDR; +extern float D_L03_001B9980[] NOT_SDA; +typedef struct { + u8 pad0[0x20]; + float f20; + s16 f24; + u8 pad26[0xA]; + float f30; + u8 pad34[0x14]; + u8 f48; + u8 pad49[0x1]; + u8 f4A; + u8 pad4B[0x15]; + u8 f60[0x10]; + u8 f70; + u8 pad71[0x1F]; + float f90; + float f94; + u8 pad98[0x4]; + float f9C; + float fA0; + u8 padA4[0x4]; + int fA8; + u8 padAC[0x34]; + float fE0[4]; + u8 padF0[0x20]; + float f110; + float f114; + float f118; + float f11C; + float f120; + u8 pad124[0xC]; + float f130; + float f134; + float f138; + u8 pad13C[0x4]; + float f140; + float f144; + int f148; + u8 pad14C[0x134]; + int f280; + u8 pad284[0x4]; + int f288; + int f28C; + int f290; + u8 pad294[0x98]; + s16 f32C; + u8 pad32E[0x2]; + float f330; + u8 pad334[0x8]; + float f33C; + int f340; +} StateEAE0; +void func_PAL_L03_00423F28(u8 *entity) { + StateEAE0 *st=*(StateEAE0 **)(entity+0x68); + float point[4],velocity[4]; + void *hit; + int pathIndex; + float a,b; + if(entity[0x20]==0) { + if(st->f340!=-1) { + func_002E59F8(st->f340); + st->f340=-1; + } + *(s16 *)(*(u8 **)(entity+0x24)+0x46)=5; + if(st->f288) { + func_002A7750(entity,4,1); + func_002A7398(entity,0,0); + st->f20=3; + st->f24=3; + st->f33C=4.5f; + } else { + pathIndex=st->f280; + if(pathIndex==-1) { + if(st->f340!=-1) { + func_002E59F8(st->f340); + st->f340=-1; + } + func_0029F338(entity); + return; + } + qcopy(entity+0x10,D_L03_001FE700[pathIndex]+16); + st->f148|=0x210; + st->f32C=1; + if(st->f28C) { + func_002A7750(entity,9,4); + func_002A7398(entity,0,0); + st->f33C=0; + *(int *)(entity+0x98)=0; + *(u16 *)(entity+0x34)=(*(u16 *)(entity+0x34)|0x41)&0xEFFF; + } else { + func_002A7750(entity,3,0); + func_002A7398(entity,0,0); + st->f33C=6; + } + } + st->f48=func_00283CF0(20); + st->f4A=func_00283CF0(17.6f); + st->f70=8; + st->fA8=3; + st->f90=0.5f; + st->f94=0.5f; + st->f9C=0.4f; + st->fA0=*(float *)(entity+0x18)-1; + a=D_L03_001B1C00*0.00040000002f; + b=D_L03_001B1C04*0.020000001f; + st->f30=0.75f; + st->f144=0.05f; + st->f114=0.25f; + st->f118=0.4f; + st->f134=a; + st->f110=0.5f; + st->f11C=0.4f; + st->f120=0.78539824f; + st->f140=0.52359885f; + st->f330=1; + st->f130=a; + st->f138=b; + *(float *)(entity+0x2C)=*(float *)(*(u8 **)(entity+0x24)+0x24)*D_L03_001B1C0C; + st->f290=0; + } + hit=func_002A9640(entity,0x10000,0); + if(hit && *(u8 **)((u8 *)hit+0x20)) { + u8 *other=*(u8 **)((u8 *)hit+0x20); + if(*(s16 *)(other+0xAA)==0xFFD && *(float *)(other+0x18)<*(float *)(entity+0x18)+2) entity[0xA8]=0xFF; + } + if(func_PAL_002B1A50(entity,st->f60,0) && st->f20<=0) { + func_00283098(point,D_L03_001B1C30,entity+0xC0); + func_00282CC0(point,point,entity+0x10); + func_PAL_L00_003FB330(point,0,25,20,20,20,45,0,0.5f,20.0f,1,0,0,0); + func_00282F20(velocity,st->fE0,0.080000006f); + func_PAL_002B15D8(entity,31,velocity,3,6,3,6,255); + if(D_0018C0B4==49) { + D_L03_001A9044_gp=D_L03_001A9044[0]+1; + if(D_L03_001A9044_gp>=10 && !D_001A7A60[0x1C]) { + D_001A7A60[0x1C]=1; + func_002E5E58(1,0,0); + func_PAL_002B1588(0x1233,-1); + D_L03_001A903C[0]=1; + } + } + func_002E5CF8(3,0,entity); + func_PAL_002A7650(entity,0,3); + if(st->f340!=-1) { + func_002E59F8(st->f340); + st->f340=-1; + } + func_0029F338(entity); + return; + } + if(entity[0x31] && func_00282E48(entity+0x10,D_L03_001B9980)<24) { + func_002A93B0(entity); + entity[0x6F]=22; + } +} diff --git a/src/pal/levels/04_barlow/L04_003F16D8-hz.c b/src/pal/levels/04_barlow/L04_003F16D8-hz.c new file mode 100644 index 000000000..efac3922e --- /dev/null +++ b/src/pal/levels/04_barlow/L04_003F16D8-hz.c @@ -0,0 +1,182 @@ +/* func_PAL_L04_003F16D8, the PAL copy of func_L04_003ED740: the same C, where func_L00_002B9D60 + becomes func_PAL_L00_002B9CD8. */ +#include "common.h" + +typedef struct { + char pad[0x284]; + char *target; + int timer; +} HeroD740; + +extern char *D_L04_001B24DC __attribute__((sda)); +extern char *D_L04_001B25CC[] __attribute__((sda)); +extern char D_00189EA0[], D_00188660[]; +extern HeroD740 D_L04_001B9540; +extern u8 D_0019B2E8[]; +extern char *D_0018C0B0; +extern int D_001A79F0 __attribute__((sda)); +extern int func_002A8508(int, int); +extern int func_002E5DA0(int, int, void *, int); +extern int func_002ACBC8(void *, int); +extern void func_L00_00429020(int); +extern int func_L00_00429048(int); +extern void func_002A0430(unsigned int); +extern void func_002DF3F8(void *, void *); +extern int func_L00_0035F5A0(int, int, void *); +extern void func_L00_003294F0(void *, int); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); +extern void func_002E59F8(int); + +void func_PAL_L04_003F16D8(char *o) +{ + char *p = *(char **)(o + 0x68); + + switch (*(u8 *)(o + 0x20)) { + case 0: + *(u8 *)(o + 0x20) = 1; + break; + case 1: { + int i, busy; + + busy = 0; + for (i = 0; i < 4; i++) + if (func_002A8508(*(int *)(p + 4 * i), -1)) + busy = 1; + if (!busy) { + if (*(int *)(p + 0x18) == 0) { + char *a, *b; + + a = D_L04_001B24DC + (*(int *)(p + 0x74) << 8); + b = D_L04_001B24DC + (*(int *)(p + 0x78) << 8); + if (*(u8 *)(a + 0x20) == 1) + func_002E5DA0(0, 0, a, 0xCE6); + *(u8 *)(a + 0x20) = 2; + *(u8 *)(b + 0x20) = 2; + if (func_002ACBC8(D_00189EA0, *(int *)(p + 0x70)) && + !(D_0019B2E8[*(u8 *)(o + 0xB0) + D_001A79F0 * 16] & 128)) { + func_L00_00429020(*(int *)(p + 0x10)); + *(u8 *)(o + 0x20) = 2; + *(u8 *)(a + 0x20) = 3; + *(u8 *)(b + 0x20) = 3; + } + } else if (*(int *)(p + 0x18) == 1) { + char *a, *b; + + if (!(D_0019B2E8[*(u8 *)(o + 0xB0) + D_001A79F0 * 16] & 128)) { + func_L00_00429020(*(int *)(p + 0x10)); + *(u8 *)(o + 0x20) = 4; + a = D_L04_001B24DC + (*(int *)(p + 0x74) << 8); + b = D_L04_001B24DC + (*(int *)(p + 0x78) << 8); + func_002E5DA0(0, 0, a, 0xCE6); + *(u8 *)(a + 0x20) = 2; + *(u8 *)(b + 0x20) = 2; + if (!(D_0019B2E8[*(u8 *)(o + 0xB0) + D_001A79F0 * 16] & 128)) { + func_002A0430(*(u8 *)(o + 0xB0)); + func_002DF3F8(o + 0x10, o + 0xF0); + } + } + } + } else if (*(int *)(p + 0x18) == 0 && + func_002ACBC8(D_00189EA0, *(int *)(p + 0x70)) && + !(D_0019B2E8[*(u8 *)(o + 0xB0) + D_001A79F0 * 16] & 128)) { + func_L00_00429020(*(int *)(p + 0x10)); + *(u8 *)(o + 0x20) = 2; + } + break; + } + case 2: { + if (func_L00_00429048(*(int *)(p + 0x10))) { + *(signed char *)(o + 0x95) = func_L00_0035F5A0(23, 4, D_0018C0B0); + { + char *base = D_L04_001B24DC; + int i; + + for (i = 0; i < 14; i++) { + char *a, *q; + int id = *(int *)(p + 0x20 + i * 4); + + if (id != -1) { + a = base + (id << 8); + if (a) { + q = *(char **)(a + 0x68); + *(int *)(q + 0x260) = *(int *)(q + 0x264); + *(int *)(q + 0x250) = *(int *)(q + 0x254); + *(int *)(a + 0x98) = *(int *)(*(char **)(a + 0x24) + 0x10); + *(u16 *)(a + 0x34) &= 0xFFBE; + } + } + } + } + { + char *a = D_L04_001B25CC[0] + (*(int *)(p + 0x14) << 7); + + qcopy(D_00189EA0, a + 0x30); + qcopy(D_00189EA0 + 0x10, a + 0x70); + func_L00_003294F0(o, 1); + *(u16 *)(o + 0x96) = 0; + *(u8 *)(o + 0x20) = 5; + } + } + break; + } + case 3: { + char *a, *b; + + if (func_L00_00429048(*(int *)(p + 0x10))) { + { + char *record = D_L04_001B25CC[0] + (*(int *)(p + 0x14) << 7); + + qcopy(D_00189EA0, record + 0x30); + record += 0x70; + qcopy(D_00189EA0 + 0x10, record); + } + a = D_L04_001B24DC + (*(int *)(p + 0x20) << 8); + b = D_L04_001B24DC + (*(int *)(p + 0x24) << 8); + *(u8 *)(a + 0x95) = 4; + *(u8 *)(a + 0x20) = 17; + if (!D_L04_001B9540.target) { + D_L04_001B9540.target = b; + D_L04_001B9540.timer = 0; + } + *(int *)(a + 0x98) = *(int *)(*(char **)(a + 0x24) + 0x10); + { + char *bd = *(char **)(b + 0x68); + *(int *)(bd + 0x270) = *(int *)(bd + 0x274); + } + { + char *ad = *(char **)(a + 0x68); + *(int *)(ad + 0x270) = *(int *)(ad + 0x274); + } + *(u8 *)(o + 0x20) = 5; + } + break; + } + case 4: { + char *a; + + if (func_L00_00429048(*(int *)(p + 0x10))) { + a = D_L04_001B25CC[0] + (*(int *)(p + 0x14) << 7); + func_PAL_L00_002B9CD8(a + 0x30, a + 0x70, 111, 1); + *(u8 *)(o + 0x20) = 5; + func_L00_003294F0(o, 1); + } + break; + } + case 5: { + if (*(u16 *)(o + 0x96) < 60) + ++*(u16 *)(o + 0x96); + else if (func_L00_00429048(*(int *)(p + 0x10))) { + int i = *(signed char *)(o + 0x95); + + if (i != -1) { + char *a = (char *)D_00188660 + i * 0x70; + if (*(char **)(a + 0x88) == D_0018C0B0 && *(u8 *)(a + 0x74)) + func_002E59F8(i); + } + i = -1; + *(signed char *)(o + 0x95) = i; + } + break; + } + } +} diff --git a/src/pal/levels/04_barlow/L04_003F16D8-sw2.c b/src/pal/levels/04_barlow/L04_003F16D8-sw2.c index e5293600d..8f2342df4 100644 --- a/src/pal/levels/04_barlow/L04_003F16D8-sw2.c +++ b/src/pal/levels/04_barlow/L04_003F16D8-sw2.c @@ -25,5 +25,4 @@ extern void func_L00_003294F0(void *, int); extern void func_PAL_L00_002B9CD8(void *, void *, int, int); extern void func_002E59F8(int); -INCLUDE_ASM("asm/pal/levels", func_PAL_L04_003F16D8); diff --git a/src/pal/levels/05_feltzin_system/L05_00419C60-f7-g8.c b/src/pal/levels/05_feltzin_system/L05_00419C60-f7-g8.c new file mode 100644 index 000000000..1270bdf53 --- /dev/null +++ b/src/pal/levels/05_feltzin_system/L05_00419C60-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L05_00419C60, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L05_00419C60(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/05_feltzin_system/L05_00419C60.c b/src/pal/levels/05_feltzin_system/L05_00419C60.c index 2c5dd3de9..8fb9102c7 100644 --- a/src/pal/levels/05_feltzin_system/L05_00419C60.c +++ b/src/pal/levels/05_feltzin_system/L05_00419C60.c @@ -1,6 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L05_00419C60); extern void func_00282C88(char *block); extern int func_002A77E0(int kind); diff --git a/src/pal/levels/06_notak/L06_00405FA8-hz.c b/src/pal/levels/06_notak/L06_00405FA8-hz.c new file mode 100644 index 000000000..2ddbee2c2 --- /dev/null +++ b/src/pal/levels/06_notak/L06_00405FA8-hz.c @@ -0,0 +1,50 @@ +/* func_PAL_L06_00405FA8, the PAL copy of func_L06_00402230: the same C with the spawn delay scale + 1/60 becomes 0x3CA3D70B, one ulp above 1/50, written 0.020000001f; the callee is PAL's + func_PAL_L06_00469110. */ +#include "common.h" + +extern void func_00282F20(void *, void *, float); +extern float func_00283180(float); +extern float func_00283198(float); +extern float func_002A7878(float low, float high); +extern void func_00283098(float *out, float *in, char *matrix); +extern void func_PAL_L06_00469110(char *moby, float *position, float *velocity, + int flags, float size, float life); + +/* Emit three rings of particles around the moby's local frame. + * The flat velocity[2] = 0.0f below is dead (flow deletes it), but it gives + * the 0.0f a second use, so loop.c keeps it in a callee-saved register + * instead of substituting it into the single call argument. This unit is + * built with -g, as line notes bound haifa-sched's regions here. */ +void func_PAL_L06_00405FA8(char *moby) +{ + float position[4]; + float velocity[4]; + int ring, spoke; + ring = 0; + do { + spoke = 0; + do { + float shell, angle, size, life; + if (ring != 0 || !(spoke & 1)) { + shell = (float)ring + func_002A7878(0.0f, 1.0f); + angle = 1.57079637f * ((float)spoke + (1.0f / 3.0f) * shell); + velocity[0] = func_00283180(angle); + velocity[1] = func_00283198(angle) * 0.25f; + velocity[2] = 0.0f; + velocity[2] = ((float)ring - 0.5f) * 0.25f; + func_00282F20(velocity, velocity, + func_002A7878(8.0f, 14.0f) * 0.020000001f /* 0x3CA3D70B, one ulp above 1/50 */); + func_00283098(velocity, velocity, moby + 0xC0); + position[0] = *(float *)(moby + 0x10) + velocity[0]; + position[1] = *(float *)(moby + 0x14) + velocity[1] * 3.0f; + position[2] = *(float *)(moby + 0x18) + 0.75f + shell * 0.5f; + size = func_002A7878(0.25f, 1.0f); + life = func_002A7878(0.25f, 1.25f); + func_PAL_L06_00469110(moby, position, velocity, 0, size, life); + } + spoke++; + } while (spoke < 4); + ring++; + } while (ring < 3); +} diff --git a/src/pal/levels/06_notak/L06_00405FA8.c b/src/pal/levels/06_notak/L06_00405FA8.c index f298bd48c..9d4359bd2 100644 --- a/src/pal/levels/06_notak/L06_00405FA8.c +++ b/src/pal/levels/06_notak/L06_00405FA8.c @@ -1,4 +1,3 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L06_00405FA8); diff --git a/src/pal/levels/06_notak/L06_0045ACC8-f7-g8.c b/src/pal/levels/06_notak/L06_0045ACC8-f7-g8.c new file mode 100644 index 000000000..d28dc799b --- /dev/null +++ b/src/pal/levels/06_notak/L06_0045ACC8-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L06_0045ACC8, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L06_0045ACC8(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/06_notak/L06_0045ACC8.c b/src/pal/levels/06_notak/L06_0045ACC8.c index ea71e6b24..4bebf0bae 100644 --- a/src/pal/levels/06_notak/L06_0045ACC8.c +++ b/src/pal/levels/06_notak/L06_0045ACC8.c @@ -1,6 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L06_0045ACC8); extern void func_PAL_002AC718(char *, char *, int, float, float, int, int, int, float, float, float, float, int, float, int, int, int, int, int); diff --git a/src/pal/levels/07_siberius/L07_003FC8D0-follow-g8.c b/src/pal/levels/07_siberius/L07_003FC8D0-follow-g8.c new file mode 100644 index 000000000..acb02a91f --- /dev/null +++ b/src/pal/levels/07_siberius/L07_003FC8D0-follow-g8.c @@ -0,0 +1,81 @@ +/* func_PAL_L07_003FC8D0, the PAL copy of func_L07_003F80B8: the same C, where func_L07_003F8430 + becomes func_PAL_L07_003FCC48; 0.0034906589426100254f becomes 0.005026549f; 0.20943955f becomes + 0.25132746f; 0.00027777778f becomes 0.00040000002f; 1.0f / 60.0f becomes 0.020000001f; + 0.0000048481375f becomes 6.981318e - 06f; 0.000290888245f becomes 0.0003490659f. */ +#include "include_asm.h" + +#include "common.h" + +extern void func_PAL_L07_003FCC48(u8 *); +extern void func_2E47D0(void *,void *,void *); +extern void func_2E4310(void *,void *,void *); +extern u8 *func_316FD8(void *); +extern void func_316638(void *,f32); +extern f32 func_2E5318(f32,f32); +extern f32 func_2E49C8(f32,f32); +extern void func_3144F0(void *,void *,f32,f32,f32,f32,s32); +extern void func_2E4340(void *,void *,void *); +extern f32 func_2E4458(void *); +extern f32 func_2E4248(f32); +extern void func_2E45F0(void *,void *,f32); +extern f32 func_2E4418(void *,void *); +extern f32 func_314038(f32 *,f32 *,f32,f32,f32,f32); +typedef struct {u8 pad[0x80];f32 pos[4];} Player; +extern Player D_00189E20; +extern f32 D_L07_001B1070 __attribute__((sda)); +extern f32 D_L07_001B1074 __attribute__((sda)); +extern f32 D_L07_001B1078 __attribute__((sda)); +extern f32 D_L07_001B107C __attribute__((sda)); +extern f32 D_L07_001B1080 __attribute__((sda)); +extern f32 D_L07_001B1084 __attribute__((sda)); +extern f32 D_L07_001B1088 __attribute__((sda)); +extern f32 D_L07_001B108C __attribute__((sda)); +void func_PAL_L07_003FC8D0(u8 *obj,f32 limit) +{ + f32 target[4],delta[4],move[4],accel[4]; + u8 *p=*(u8 **)(obj+0x68); + u8 *other; + f32 rate,speed,len,amount,angle,bank,turnRate,turnSpeed; + f32 *yaw; + func_PAL_L07_003FCC48(obj); + if(!obj[0x95]) { + func_2E47D0(target,p+0x3e0,*(u8 **)(p+0x418)+0xc0); + func_2E4310(target,target,*(u8 **)(p+0x418)+0x10); + other=func_316FD8(*(u8 **)(p+0x418)); + if(limit>=0.0f) { + qcopy(delta,other+0x10); + func_316638(delta,limit); + func_2E4310(obj+0x10,obj+0x10,delta); + } else func_2E4310(obj+0x10,obj+0x10,other+0x10); + *(f32 *)(obj+0xf8)=func_2E5318(*(f32 *)(*(u8 **)(p+0x418)+0xf8),3.1415927f); + } else { + qcopy(target,p+0x3e0); + yaw=(f32 *)(obj+0xf8); + angle=func_2E49C8(D_00189E20.pos[0]-*(f32 *)(obj+0x10),D_00189E20.pos[1]-*(f32 *)(obj+0x14)); + func_3144F0(yaw,p+0x424,angle,0.005026549f,0.005026549f,0.25132746f,0); + } + func_2E4340(delta,target,obj+0x10); + rate=(obj[0x95]?D_L07_001B1078:D_L07_001B1070)*0.00040000002f; + speed=(obj[0x95]?D_L07_001B107C:D_L07_001B1074)*(0.020000001f); + len=func_2E4458(delta); + amount=func_2E4248(len*rate*0.5f); + if(limit>=0.0f && limit1.5707965f) angle=1.5707965f; + else if(angle< -1.5707965f) angle= -1.5707965f; + turnRate=D_L07_001B1084; + turnSpeed=D_L07_001B1088; + turnRate*=6.981318e-06f; + turnSpeed*=0.0003490659f; + func_314038((f32 *)(obj+0xf0),(f32 *)(p+0x428),angle,turnRate,turnRate,turnSpeed); + bank=*(f32 *)(obj+0xf0)*D_L07_001B108C; + if(obj[0x43]>=8) *(f32 *)(p+0x2c0)=bank; + else *(f32 *)(p+0x2c4)=bank; +} diff --git a/src/pal/levels/07_siberius/L07_003FC8D0.c b/src/pal/levels/07_siberius/L07_003FC8D0.c index 04d8ee159..ed82879a7 100644 --- a/src/pal/levels/07_siberius/L07_003FC8D0.c +++ b/src/pal/levels/07_siberius/L07_003FC8D0.c @@ -1,6 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L07_003FC8D0); INCLUDE_ASM("asm/pal/levels", func_PAL_L07_003FCC48); diff --git a/src/pal/levels/08_tabora/L08_003DD170.c b/src/pal/levels/08_tabora/L08_003DD170.c index b25105bcf..411f4bba4 100644 --- a/src/pal/levels/08_tabora/L08_003DD170.c +++ b/src/pal/levels/08_tabora/L08_003DD170.c @@ -175,7 +175,6 @@ void func_PAL_L08_003DD368(Ent *a0) } -INCLUDE_ASM("asm/pal/levels", func_PAL_L08_003DD458); INCLUDE_ASM("asm/pal/levels", func_PAL_L08_003DD918); diff --git a/src/pal/levels/08_tabora/L08_003DD458.c b/src/pal/levels/08_tabora/L08_003DD458.c new file mode 100644 index 000000000..b4796a446 --- /dev/null +++ b/src/pal/levels/08_tabora/L08_003DD458.c @@ -0,0 +1,157 @@ +/* func_PAL_L08_003DD458, the PAL copy of func_L08_003D92D8: the same C, where 240 becomes 200; + 0.0017453294713050127f becomes 0.0025132746f; 0.10471977293491364f becomes 0.12566373f; 0.02f + becomes 0.028800001f; 0.4f becomes 0.57600003f. */ +#include "common.h" + +extern u8 D_L08_001B9B00[]; +extern f32 func_00282E48(void *, void *); + +extern void func_0029FCC0(void *, int, void *); + +typedef struct { + u8 pad00[0x20]; + u8 f20; + u8 f21; + u8 pad22[0x24 - 0x22]; + void *f24; + u8 pad28[0x2C - 0x28]; + f32 f2C; + u8 pad30[0x68 - 0x30]; + void *f68; + u8 pad6C[0x95 - 0x6C]; + u8 f95; + u16 f96; + u8 pad98[0xBC - 0x98]; + u8 fBC; + u8 padBD[0x100 - 0xBD]; +} Ent; + +typedef int V4 __attribute__((mode(TI))); + +extern s32 func_3357E8(Ent *, void *, s32); +extern void func_2FA0B8(void *, void *, f32); + +extern float func_00282E80(void *, void *); + +typedef struct { + int mode; + char pad4[8]; + int active; + char pad10[0x18]; + float lower; + char pad2C[12]; + float upper; +} HeightGate; +typedef struct { + u8 pad0[0x80]; + V4 position; + u8 pad90[0x40]; + V4 other; + u8 padE0[0x21B0]; + int handle; +} HeroTarget; +extern HeroTarget D_00189E20; +extern HeightGate D_L08_001CA080; +extern char D_L08_001BFF80[]; +extern int func_00278E78(void); +extern void func_002A93B0(void *); +extern void func_L08_003D82F0(void *); +extern void func_00283410(void *, void *); +extern void func_00283698(void *, void *); +extern float func_002A89A8(void *, int, float); +extern float func_00283248(float, float); +extern float func_002AAA00(void *, void *, float, float, float, float, int); +extern float func_00283BE0(float, float); +extern void func_002AEC48(void *, void *, int, float, float); +extern void func_00283098(void *, void *, void *); + +extern void func_L08_003D8A28(Ent *a0); +void func_PAL_L08_003DD458(u8 *object) +{ + float point[4], angles[4], matrix[16], inverse[16], other[16]; + char *state = *(char **)(object + 0x68); + float yaw, pitch, target; + float pointX, pointY; + float *pitchAngle, *rollAngle; + int hit; + + if (D_L08_001CA080.active) { + if (*(float *)(object + 0x18) < D_L08_001CA080.lower && D_L08_001CA080.mode == 1) return; + if (D_L08_001CA080.lower < *(float *)(object + 0x18) && D_L08_001CA080.mode == 0) return; + if (D_L08_001CA080.active == 2) { + if (D_L08_001CA080.upper < *(float *)(object + 0x18) && D_L08_001CA080.mode == 1) return; + if (*(float *)(object + 0x18) < D_L08_001CA080.upper && D_L08_001CA080.mode == 2) return; + } + } + if (object[0x31] && func_00282E48(object + 0x10, D_L08_001B9B00) < 24.0f) { + func_002A93B0(object); + object[0x6F] = 22; + } + func_L08_003D82F0(object); + if (*(float *)(object + 0x18) < *(float *)(state + 0x434) + 0.12f) { + if (func_00278E78() == 1 || func_00278E78() == 11) { + *(int *)(state + 0x20) = 0; + object[0x20] = 11; + return; + } + } + *(float *)(object + 0x2C) += + (*(float *)(*(char **)(object + 0x24) + 0x24) * 1.7f - *(float *)(object + 0x2C)) * 0.05f; + hit = func_3357E8((Ent *)object, state + 0x50, 0); + if (hit) { + if (hit == 5) *(int *)(state + 0xE0) = 0; + *(int *)(state + 0x48C) = 200; + func_L08_003D8A28((Ent *)object); + } + if (object[0x20] < 9 && object[0x20] != 4) { + pitchAngle = (float *)(object + 0xF4); + rollAngle = (float *)(object + 0xF0); + *(V4 *)angles = 0; + angles[2] = *(float *)(object + 0xF8); + *(V4 *)point = *(V4 *)angles; + func_00283410(matrix, point); + func_00283698(inverse, matrix); + func_00283698(other, object + 0xC0); + func_002A89A8(object + 0x10, 0, 0.5f); + func_2FA0B8(angles, D_L08_001BFF80, 1.0f); + func_00283098(angles, angles, inverse); + target = func_00283248(angles[2], angles[0]); + func_002AAA00(pitchAngle, state + 0x460, target, 0.0025132746f, + 0.0025132746f, 0.12566373f, 0); + target = -func_00283248(angles[2], angles[1]); + func_002AAA00(rollAngle, state + 0x464, target, 0.0025132746f, + 0.0025132746f, 0.12566373f, 0); + } + if (object[0x20] == 8 && !object[0x95]) { + func_0029FCC0(object, 1, point); + if (*(int *)(state + 0x250) == D_00189E20.handle) { + qcopy(state + 0x210, &D_00189E20.position); + qcopy(state + 0x230, &D_00189E20.other); + } + pointY = point[1]; + pointX = point[0]; + yaw = func_00283248(*(float *)(state + 0x230) - pointX, *(float *)(state + 0x234) - pointY); + pitch = func_00283248(func_00282E80(point, state + 0x230), *(float *)(state + 0x238) - point[2]); + yaw = func_00283BE0(yaw, *(float *)(object + 0xF8)) * 0.5f; + pitch = func_00283BE0(-pitch, *(float *)(object + 0xF4)) * 0.3333333432674408f; + { + int i; + for (i = 0; i < 3; i++) { + *(float *)(state + 0x2C8 + i * 0x80) = yaw; + if (yaw > 0.523598849773407f) *(float *)(state + 0x2C8 + i * 0x80) = 0.523598849773407f; + else if (yaw < -0.523598849773407f) *(float *)(state + 0x2C8 + i * 0x80) = -0.523598849773407f; + *(float *)(state + 0x2C4 + i * 0x80) = pitch; + } + } + } else { + int i; + for (i = 0; i < 3; i++) { + *(float *)(state + 0x2C0 + i * 0x80) = 0; + *(float *)(state + 0x2C4 + i * 0x80) = 0; + } + } + { + int i; + for (i = 0; i < 3; i++) func_002AEC48(object, state + 0x260 + i * 0x80, 3, 0.028800001f, 0.57600003f); + } +} diff --git a/src/pal/levels/09_dobbo/L09_00408290-g8.c b/src/pal/levels/09_dobbo/L09_00408290-g8.c new file mode 100644 index 000000000..08d8f3542 --- /dev/null +++ b/src/pal/levels/09_dobbo/L09_00408290-g8.c @@ -0,0 +1,88 @@ +/* func_PAL_L09_00408290, the PAL copy of func_L09_00403398: the same C, where 0.033333335f becomes + 0.040000003f; 0.087266475f becomes 0.10471977f; 0.026179943f becomes 0.031415932f. */ +#include "common.h" + +extern s32 D_L09_001B2878 __attribute__((sda)); +extern u8 *D_L09_001B285C MACRO_ADDR; +extern u16 *D_L09_001FB560[]; + +extern f32 D_L09_001B13B8 __attribute__((sda)); +extern f32 D_L09_001B13BC __attribute__((sda)); +extern f32 D_L09_001B13C4 __attribute__((sda)); +extern f32 D_L09_001B13C8 __attribute__((sda)); +extern f32 D_L09_001B13CC __attribute__((sda)); +extern f32 D_L09_001B13D0 __attribute__((sda)); +extern u8 *D_0018C0B0 NOT_SDA; + +extern void func_00282CF0(void *, void *, void *); +extern f32 func_00282DF0(void *); +extern void func_00282F20(void *, void *, f32); +extern void func_00282CC0(void *, void *, void *); +extern f32 func_002A7790(f32); +extern void func_002AEE70(u8 *, void *, void *, f32, f32, f32); +extern void func_002AEF28(u8 *, void *, void *, f32, f32, f32); + +void func_PAL_L09_00408290(u8 *a0) +{ + u8 *state = *(u8 **)(a0 + 0x68); + f32 P[4] __attribute__((aligned(16))); + f32 B[4] __attribute__((aligned(16))); + f32 C[4] __attribute__((aligned(16))); + u8 *t; + u16 *p; + u8 *e; + f32 f0, f2, len, w; + f32 height; + + *(f32 *)(state + 0x288) = *(f32 *)(a0 + 0x18); + if (a0[0x20] != 9 && a0[0x20] != 4) { + height = *(f32 *)(state + 0x294) - 0.040000003f; + *(f32 *)(state + 0x294) = height; + qcopy(P, a0 + 0x10); + P[2] = height + (D_L09_001B13C4 - D_L09_001B13BC); + t = *(u8 **)(state + 0x188); + if (t == 0 || (t != D_0018C0B0 && *(s16 *)(t + 0xAA) != 0xD57 && + *(s16 *)(*(u8 **)(t + 0x24) + 0x46) >= 11)) { + f0 = *(f32 *)(state + 0x288) + D_L09_001B13BC; + f2 = *(f32 *)(state + 0x294); + if (f2 < f0) + *(f32 *)(state + 0x294) = f2 + (f0 - f2) * D_L09_001B13C8; + } + f0 = *(f32 *)(state + 0x264) + D_L09_001B13BC; + f2 = *(f32 *)(state + 0x294); + if (f2 < f0) + *(f32 *)(state + 0x294) = f2 + (f0 - f2) * D_L09_001B13C8; + if (a0[0x20] >= 6 && a0[0x20] <= 8) { + f0 = *(f32 *)(*(u8 **)(state + 0x230) + 0x18) + D_L09_001B13B8; + f2 = *(f32 *)(state + 0x294); + if (f2 < f0) + *(f32 *)(state + 0x294) = f2 + (f0 - f2) * D_L09_001B13CC; + } + *(f32 *)(a0 + 0x18) = *(f32 *)(state + 0x294); + qzero_nc(B); + p = D_L09_001FB560[a0[0x21]]; + for (; + a0[0x21] != 0xFF && a0[0x21] <= D_L09_001B2878 && p != 0 && + ((p != 0 && (s16)p[-1] >= 0) || p == D_L09_001FB560[a0[0x21]]); + p++) { + e = D_L09_001B285C + ((*p & 0x7FFF) << 8); + if (e == 0) + break; + func_00282CF0(C, a0 + 0x10, e + 0x10); + len = func_00282DF0(C); + if (len > D_L09_001B13D0) + len = D_L09_001B13D0; + else if (len < 0.0f) + len = 0.0f; + w = 1.0f - len / D_L09_001B13D0; + func_002A7790(w); + func_00282F20(C, C, len * w); + func_00282CC0(B, B, C); + } + func_00282CC0(a0 + 0x10, a0 + 0x10, B); + func_002AEE70(a0, state + 0x278, state + 0x27C, 0.1f, 0.10471977f, *(f32 *)(a0 + 0x18)); + func_002AEF28(a0, state + 0x280, state + 0x284, 0.13962635f, 0.031415932f, 0.031415932f); + } else { + *(f32 *)(state + 0x294) = *(f32 *)(a0 + 0x18); + } +} diff --git a/src/pal/levels/09_dobbo/L09_00408290.c b/src/pal/levels/09_dobbo/L09_00408290.c index d52c31686..877bd62d6 100644 --- a/src/pal/levels/09_dobbo/L09_00408290.c +++ b/src/pal/levels/09_dobbo/L09_00408290.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L09_00408290); diff --git a/src/pal/levels/10_hrugis_cloud/L10_0041A730-f7-g8.c b/src/pal/levels/10_hrugis_cloud/L10_0041A730-f7-g8.c new file mode 100644 index 000000000..0c9f15c39 --- /dev/null +++ b/src/pal/levels/10_hrugis_cloud/L10_0041A730-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L10_0041A730, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L10_0041A730(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/10_hrugis_cloud/L10_0041A730.c b/src/pal/levels/10_hrugis_cloud/L10_0041A730.c index 63c0d4f72..877bd62d6 100644 --- a/src/pal/levels/10_hrugis_cloud/L10_0041A730.c +++ b/src/pal/levels/10_hrugis_cloud/L10_0041A730.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L10_0041A730); diff --git a/src/pal/levels/10_hrugis_cloud/L10_00423AA0-hz.c b/src/pal/levels/10_hrugis_cloud/L10_00423AA0-hz.c new file mode 100644 index 000000000..7d423bd35 --- /dev/null +++ b/src/pal/levels/10_hrugis_cloud/L10_00423AA0-hz.c @@ -0,0 +1,53 @@ +/* func_PAL_L10_00423AA0, the PAL copy of func_L10_0041EC10: the same C with the per-frame phase + step 2*pi/60 becomes 2*pi/50 (0.12566373f); the callee is PAL's func_PAL_L10_00423BE0, and the + 8-byte callback is catalogued in PAL as func_L00_00410D18. */ +#include "common.h" + +extern u32 *func_0037BA88(u8 *arg0); +extern f32 func_00335320(void); +extern u8 *func_0037B670(); +extern void func_0037BC48(u8 *arg0, s32 a1, s32 a2, s32 a3); +extern s32 func_0037D390(u8 *arg0, s32 a1, s32 a2, s32 a3); +extern f32 func_00309120(f32 f12); + +extern f32 func_00309B38(f32 f12, f32 f13); +extern u8 func_L10_00423780(void); +extern s32 func_00283D38(s32 a0, s32 a1, f32 f12); +extern void func_L00_00410D18(void); +extern void func_L10_0041EE00(u8 *arg0); +extern s32 D_001A79F0[] __attribute__((sda)); + +extern void func_PAL_L10_00423BE0(u8 *arg0); +void func_PAL_L10_00423AA0(u8 *arg0) { + u8 *s1 = *(u8 **)(arg0 + 0x68); + f32 f; + u8 *p; + s32 mode; + + switch (arg0[0x20]) { + case 0: + arg0[0x30] = 0xFF; + if (func_0037B670() != 0) { + func_PAL_L10_00423BE0(arg0); + if (*(s32 *)(s1 + 0x264) != 0) { + func_0037BC48(arg0, (s32)func_L00_00410D18, (s32)func_L10_0041EE00, 0); + } + *(f32 *)(s1 + 0x268) = func_00335320(); + } + break; + case 1: + p = func_0037BA88(arg0); + mode = D_001A79F0[0]; + *(s32 *)((u8 *)p + 0x14C) = 0; + if (mode == 10 && func_L10_00423780() == 2) { + *(u16 *)(arg0 + 0x34) |= 0x1000; + } else { + *(u16 *)(arg0 + 0x34) &= 0xEFFF; + } + func_0037D390(arg0, 0, 0, 0); + f = func_00309B38(*(f32 *)(s1 + 0x268), 0.12566373f); + *(f32 *)(s1 + 0x268) = f; + *(s32 *)(arg0 + 0x78) = func_00283D38(0x20202020, -1, (func_00309120(f) + 1.0f) * 0.5f); + break; + } +} diff --git a/src/pal/levels/10_hrugis_cloud/L10_00423AA0.c b/src/pal/levels/10_hrugis_cloud/L10_00423AA0.c index 89076d4c5..8c358763f 100644 --- a/src/pal/levels/10_hrugis_cloud/L10_00423AA0.c +++ b/src/pal/levels/10_hrugis_cloud/L10_00423AA0.c @@ -1,6 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L10_00423AA0); typedef signed int s32; typedef unsigned char u8; diff --git a/src/pal/levels/11_joba/L11_003E0D58-g8.c b/src/pal/levels/11_joba/L11_003E0D58-g8.c new file mode 100644 index 000000000..7bbbc7479 --- /dev/null +++ b/src/pal/levels/11_joba/L11_003E0D58-g8.c @@ -0,0 +1,46 @@ +/* func_PAL_L11_003E0D58, the PAL copy of func_L11_003DCEB0: the same C, where 0x79 becomes 0x65; + func_002ABBB8 becomes func_PAL_002AC718. */ +#include "common.h" + +extern f32 D_L11_001B0170 __attribute__((sda)); +extern f32 D_L11_001B016C __attribute__((sda)); +extern f32 D_L11_001B0174 __attribute__((sda)); +extern u8 D_L11_001C0D20[]; +extern u8 D_L11_001A8F20[] __attribute__((sda)); +extern s32 func_002761F8(void *, void *, s32, void *, s32); +extern void func_PAL_002AC718(void *, void *, void *, float, float, int, int, int, float, float, float, float, int, float, int, int, int, int, int); +extern void func_002E5CF8(s32, s32, u8 *); +extern void func_0029F338(u8 *); +extern void *func_002A9640(void *, int, int); +extern void func_00282CC0(void *, void *, void *); +extern void func_002A7750(void *, int, int); + +void func_PAL_L11_003E0D58(u8 *a0) { + u8 vec[16] __attribute__((aligned(16))); + u8 *s0 = *(u8 **)(a0 + 0x68); + s32 flag = 0; + u8 state = a0[0x20]; + + switch (state) { + case 0: + func_00282CC0(vec, a0 + 0x10, s0); + *(f32 *)(s0 + 8) = *(f32 *)(s0 + 8) - *(f32 *)(s0 + 0xC); + if (func_002761F8(a0 + 0x10, vec, 2, 0, 0) != 0) { + qcopy(a0 + 0x10, D_L11_001C0D20); + *(f32 *)(a0 + 0x18) = *(f32 *)(a0 + 0x18) + D_L11_001B0170 * D_L11_001B016C; + func_002A7750(a0, 1, -1); + } else { + qcopy(a0 + 0x10, vec); + } + break; + case 1: + *(u16 *)(a0 + 0x96) += 1; + if (*(u16 *)(a0 + 0x96) >= 0x65) flag = state; + break; + } + if (func_002A9640(a0, -1, 0) != 0 || flag != 0) { + func_PAL_002AC718(a0, D_L11_001A8F20, a0 + 0x10, D_L11_001B0174, 1.0f, 10, 3, 16, 4.0f, 2.0f, 9.0f, 1.0f, -1, 15.0f, 1, 1, -1, 0, 0x810001); + func_002E5CF8(0, 0, a0); + func_0029F338(a0); + } +} diff --git a/src/pal/levels/11_joba/L11_003E0D58.c b/src/pal/levels/11_joba/L11_003E0D58.c index a452ea301..1c3bbafc7 100644 --- a/src/pal/levels/11_joba/L11_003E0D58.c +++ b/src/pal/levels/11_joba/L11_003E0D58.c @@ -1,6 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_003E0D58); INCLUDE_ASM("asm/pal/levels", func_PAL_L11_003E0F10); diff --git a/src/pal/levels/11_joba/L11_0043C288-g8.c b/src/pal/levels/11_joba/L11_0043C288-g8.c new file mode 100644 index 000000000..e3bb7dc6e --- /dev/null +++ b/src/pal/levels/11_joba/L11_0043C288-g8.c @@ -0,0 +1,108 @@ +/* func_PAL_L11_0043C288, the PAL copy of func_L11_00436D08: the same C, where func_L01_00321178 + becomes func_PAL_L01_00323068. */ +#include "common.h" + +typedef int TI128 __attribute__((mode(TI))); + +typedef struct { + u8 pad00[0x10]; + float position[4]; + u8 pad20[0xE0]; +} Entity; + +typedef struct { + u8 pad000[0x134]; + float turnRate; + u8 pad138[0x278 - 0x138]; + s32 group; +} AimState; + +typedef struct { + u8 pad00[0x10]; + float position[4]; + u8 pad20[0x48]; + AimState *state; + u8 pad6C[0xE0 - 0x6C]; + float axis[4]; + u8 padF0[8]; + float heading; +} AimObject; + +extern u16 *D_L11_001FC420[]; +extern Entity *D_L11_001B359C[] __attribute__((sda)); +extern s32 D_L11_001B35B8 __attribute__((sda)); + +extern float D_L11_001B1230 __attribute__((sda)); +extern float D_L11_001B1234 __attribute__((sda)); +extern float D_L11_001B1238 __attribute__((sda)); + +extern int func_00283DB8(void *vec, float radius); +extern float func_00282E80(void *, void *); +extern float func_00283248(float, float); +extern float func_00283C80(float, float); +extern float func_00283BE0(float, float); +extern void func_00282CF0(void *, void *, void *); +extern void func_00282CC0(void *, void *, void *); +extern void func_002ACEC0(void *, void *, void *, float); +extern int func_PAL_L01_00323068(void *, void *); +extern int func_L02_003D7300(void *); + +/* Looks for an entity of the object's group that is in range and inside its view cone, and if + found turns the object toward it and runs the follow-up call with a tiny turn rate. */ +s32 func_PAL_L11_0043C288(AimObject *obj) +{ + AimState *state = obj->state; + float copy[4]; + float vec[4]; + u16 *ids; + Entity *entity; + float savedTurnRate; + float angle; + float turn; + + *(TI128 *)vec = 0; + vec[0] = obj->position[0]; + vec[1] = obj->position[1]; + vec[2] = obj->position[2]; + vec[3] = 2.0f; + *(TI128 *)copy = *(TI128 *)vec; + if (func_00283DB8(copy, 128.0f) <= 0) + return 0; + if (state->group == -1) + return 0; + + for (ids = D_L11_001FC420[state->group]; + (state->group & 0xFF) != 0xFF && state->group <= D_L11_001B35B8 && ids != 0 && + ((ids != 0 && (s16)ids[-1] >= 0) || ids == D_L11_001FC420[state->group]); + ids++) { + entity = D_L11_001B359C[0] + (*ids & 0x7FFF); + if (entity == 0) + return 0; + if (!func_L02_003D7300(entity)) + continue; + if (!(func_00282E80(obj->position, entity->position) < D_L11_001B1230)) + continue; + + angle = func_00283248(entity->position[0] - obj->position[0], + entity->position[1] - obj->position[1]); + if (!(func_00283C80(obj->heading, angle) < D_L11_001B1234 * 0.017453294f)) + continue; + if (ids == 0) + return 0; + + func_00282CF0(vec, obj->position, entity->position); + turn = D_L11_001B1238 * 0.017453294f; + angle = func_00283248(entity->position[0] - obj->position[0], + entity->position[1] - obj->position[1]); + func_002ACEC0(vec, vec, obj->axis, + func_00283BE0(obj->heading, angle) >= 0.0f ? -turn : turn); + func_00282CC0(vec, vec, entity->position); + + savedTurnRate = state->turnRate; + state->turnRate = 0.0001f; + func_PAL_L01_00323068(obj, vec); + state->turnRate = savedTurnRate; + return 1; + } + return 0; +} diff --git a/src/pal/levels/11_joba/L11_0043C288.c b/src/pal/levels/11_joba/L11_0043C288.c index 15cb86cb5..bfe4fd623 100644 --- a/src/pal/levels/11_joba/L11_0043C288.c +++ b/src/pal/levels/11_joba/L11_0043C288.c @@ -1,6 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_0043C288); #include "common.h" diff --git a/src/pal/levels/11_joba/L11_0043D438-hz.c b/src/pal/levels/11_joba/L11_0043D438-hz.c new file mode 100644 index 000000000..8c776b661 --- /dev/null +++ b/src/pal/levels/11_joba/L11_0043D438-hz.c @@ -0,0 +1,128 @@ +/* func_PAL_L11_0043D438, the PAL copy of func_L11_00437EA8: the same C with gravity -1/720 per + frame squared becomes -1/500. */ +#include "common.h" +struct RotorPath { + int count; + char pad04[12]; + float points[0][4]; +}; + +struct RotorState { + /* 0x000 */ char pad00[0x35]; + /* 0x035 */ u8 f35; + /* 0x036 */ char pad36[0x1A]; + /* 0x050 */ float aim[4]; + /* 0x060 */ int f60; + /* 0x064 */ char pad64[0x9C]; + /* 0x100 */ float points[13][4]; + /* 0x1D0 */ float oldPoints[13][4]; + /* 0x2A0 */ char pad2A0[0x10]; + /* 0x2B0 */ int choices[4][4]; + /* 0x2F0 */ char pad2F0[0x30]; + /* 0x320 */ int pathIndex; + /* 0x324 */ struct RotorPath *path; + /* 0x328 */ char pad328[8]; + /* 0x330 */ int records[10]; + /* 0x358 */ int linked; + /* 0x35C */ char pad35C[0xC]; + /* 0x368 */ int projectileClass; + /* 0x36C */ char pad36C[4]; + /* 0x370 */ s16 pathPoint; + /* 0x372 */ char pad372[2]; + /* 0x374 */ s16 projectileIndex; + /* 0x376 */ s16 projectileDelay; + /* 0x378 */ s16 ropeCount; + /* 0x37A */ u16 toggle; + /* 0x37C */ char pad37C[4]; + /* 0x380 */ u8 disabled[10]; +}; + +struct RotorAxis { + float x, y, z; + int w; +}; + +struct RotorObject { + /* 0x00 */ char pad00[0x10]; + /* 0x10 */ float pos[4]; + /* 0x20 */ u8 mode; + /* 0x21 */ char pad21[0x13]; + /* 0x34 */ u16 flags; + /* 0x36 */ char pad36[0x32]; + /* 0x68 */ struct RotorState *state; + /* 0x6C */ char pad6C[0x4C]; + /* 0xB8 */ int fB8; + /* 0xBC */ char padBC[4]; + /* 0xC0 */ struct RotorAxis basis[3]; +}; + +extern char D_00188660[]; +extern void func_3739C0(int); +extern float func_00283CE0(int); +extern float func_002AA140(float, float, float); + +extern int D_L11_001B359C __attribute__((sda)); + +typedef int TI128 __attribute__((mode(TI))); + +extern void func_00282CF0(void *, const void *, const void *); +extern void func_00282CC0(void *, void *, void *); + +static inline void stop_owned_sound(char *state, char *p) +{ + int slot = *(int *)(state + 0x14); + + if (slot != -1) { + char *e = D_00188660 + slot * 0x70; + + if (*(char **)(e + 0x88) == p && *(unsigned char *)(e + 0x74)) + func_3739C0(slot); + } + *(int *)(state + 0x14) = -1; +} + +extern void func_00282C88(void *); +extern void func_00282D30(void *, void *, float); + +typedef union Quad { + TI128 q; + float f[4]; +} Quad; + +/* Advances the thirteen chain points one Verlet step: each moves by its damped displacement + from its old position plus a small downward pull, and the old position takes the point's + previous value. The damping blends 0.97 to 0.98 with the count at 0x378. */ +void func_PAL_L11_0043D438(void *object) +{ + struct RotorObject *obj = object; + struct RotorState *state = obj->state; + float (*pos)[4]; + float (*old)[4]; + Quad saved; + Quad delta; + Quad gravity; + float t; + float damping; + int i; + + func_00282C88(&gravity); + pos = state->points; + old = state->oldPoints; + gravity.f[2] = -1.0f / 500.0f; + + t = func_00283CE0(state->ropeCount); + damping = func_002AA140(0.97f, 0.98f, (t -= 2.0f) / func_00283CE0(8)); + + for (i = 12; i >= 0; i--, pos++, old++) { + qcopy(&saved, pos); + func_00282CF0(delta.f, *pos, *old); + func_00282D30(&delta, &delta, damping); + func_00282CC0(pos, pos, &delta); + func_00282CC0(pos, pos, &gravity); + qcopy(old, &saved); + } +} + +#define STORED_RECORD(index) \ + ((struct RotorObject *)(((index) << 8) + D_L11_001B359C)) +#define LISTED_STORE(obj, i) STORED_RECORD((obj)->state->records[i]) diff --git a/src/pal/levels/11_joba/L11_0043D438.c b/src/pal/levels/11_joba/L11_0043D438.c index c693dcc8a..877bd62d6 100644 --- a/src/pal/levels/11_joba/L11_0043D438.c +++ b/src/pal/levels/11_joba/L11_0043D438.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_0043D438); diff --git a/src/pal/levels/11_joba/L11_00445BB8-g.c b/src/pal/levels/11_joba/L11_00445BB8-g.c new file mode 100644 index 000000000..728eb524f --- /dev/null +++ b/src/pal/levels/11_joba/L11_00445BB8-g.c @@ -0,0 +1,122 @@ +/* func_PAL_L11_00445BB8, the PAL copy of func_L11_00440360: the same C with the 600-frame timer + becomes 500; the callee is PAL's func_PAL_L11_0044B820. */ +#include "include_asm.h" +#include "common.h" + +#define S16(p,o) (*(short *)((p)+(o))) +#define U16(p,o) (*(unsigned short *)((p)+(o))) +#define I32(p,o) (*(int *)((p)+(o))) +#define F32(p,o) (*(float *)((p)+(o))) +extern u8 *D_L11_001FC420[]; +extern u8 *D_L11_001B359C __attribute__((section(".sdata"))); +extern u8 D_00189E20[]; +extern void func_PAL_L11_0044B820(u8 *, int, float, float); +extern int func_L00_0035F5A0(int, int, int); +extern int func_00282978(short *); +/* Tallies the group's living members and their health, records the losses in + * the four-slot history and stores their weighted sum at 0x14C. Built with -g: + * the debug line layout gives retail's single nop before div.s. */ +void func_PAL_L11_00445BB8(u8 *object) +{ + u8 *state = *(u8 **)(object + 0x68); + short *list; + short *groupList; + int active, i, slot, kind; + float total, weights, energy, motion; + u8 *member, *detail, *members; + typedef struct { u8 pad[0x20]; float health; } MemberHealth; + typedef struct { int value; int pad[3]; } HistInt; + typedef struct { float value; int pad[3]; } HistFloat; + struct HistoryFields { int count; float energy, motion; int pad; }; + struct StateHistory { u8 pad[0x50]; struct HistoryFields history[4]; }; + struct StateClassCount { u8 pad[0x200]; unsigned short count; }; + u8 *counts; + u8 *energies; + u8 *motions; + u8 *player; + if (I32(state,0xc0) == 255) return; + groupList = (short *)D_L11_001FC420[I32(state,0xc0)]; + if (groupList == 0) return; + list = groupList; + if (object[0x20] == 9 && object[0xbc] == 0) return; + ((struct StateClassCount *)state)->count = 0; + active=0; total=0.0f; + members=D_L11_001B359C; + do { + member = members + ((*list & 0x7fff) << 8); + if (member != 0 && member[0x20] != 254 && member[0x20] != 253 && member[0x20] != 1) { + kind = S16(member,0xaa); + if (kind == 0xd98) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + total += hp->health; + if (hp->health > 0.0f) active++; + } else if (kind == 0xdcf) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + total += hp->health; + if (hp->health > 0.0f) active++; + } else if (kind == 0xdf4) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + total += hp->health; + if (hp->health > 0.0f) active++; + } else if (kind == 0xdf7) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + total += hp->health; + if (hp->health > 0.0f) active++; + } else if (kind == 0xdf9) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + total += hp->health; + if (hp->health > 0.0f) active++; + } else if (kind == 0xd37) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + total += hp->health; + U16(state,0x200)++; + if (hp->health > 0.0f) active++; + } else if (kind == 0xd4a) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + active++; + total += hp->health; + } else if (kind == 0xd4b) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + total += hp->health; + if (hp->health > 0.0f) active++; + } else if (kind == 0xb3a) { + MemberHealth *hp = *(MemberHealth **)(member+0x68); + active++; + total += hp->health; + } + } + } while (*list++ >= 0); + player = D_00189E20; + func_PAL_L11_0044B820(object, I32(state,0x140)-active, F32(state,0x144)-total, + F32(state,0x148)-(float)I32(player,0x24cc)); + if (F32(state,0x148)-(float)I32(player,0x24cc) > 0.0f) + func_L00_0035F5A0(0x17,0,0); + if (active < I32(state,0x140)) + ((struct StateHistory *)state)->history[S16(state,0x1ec)].count += I32(state,0x140)-active; + if (total < F32(state,0x144)) + ((struct StateHistory *)state)->history[S16(state,0x1ec)].energy += F32(state,0x144)-total; + if ((float)I32(player,0x24cc) < F32(state,0x148)) + ((struct StateHistory *)state)->history[S16(state,0x1ec)].motion += F32(state,0x148)-(float)I32(player,0x24cc); + F32(state,0x144) = total; + I32(state,0x140) = active; + F32(state,0x148) = (float)I32(player,0x24cc); + weights=0.0f; energy=0.0f; motion=0.0f; + for (i=4;i>0;i--) { + float countTerm, energyTerm, motionTerm; + float denominator = 5.0f-(float)i; + float weight = 1.0f / denominator; energyTerm = weight*((struct StateHistory *)state)->history[(S16(state,0x1ec)+i)%4].energy; + countTerm = weight*(float)((struct StateHistory *)state)->history[(S16(state,0x1ec)+i)%4].count; + motionTerm = weight*((struct StateHistory *)state)->history[(S16(state,0x1ec)+i)%4].motion; + energy += energyTerm; + motion += motionTerm; + weights += countTerm; + } + F32(state,0x14c) = energy*0.2f + weights + motion * -2.0f; + if (func_00282978((short *)(state+0x1ee))) { + S16(state,0x1ec) = (short)(U16(state,0x1ec)+1)%4; + ((struct StateHistory *)state)->history[S16(state,0x1ec)].count=0; + ((struct StateHistory *)state)->history[S16(state,0x1ec)].energy=0; + ((struct StateHistory *)state)->history[S16(state,0x1ec)].motion=0; + S16(state,0x1ee)=500; + } +} diff --git a/src/pal/levels/11_joba/L11_00445BB8.c b/src/pal/levels/11_joba/L11_00445BB8.c index e0a3f20e2..6668f03ab 100644 --- a/src/pal/levels/11_joba/L11_00445BB8.c +++ b/src/pal/levels/11_joba/L11_00445BB8.c @@ -1,9 +1,7 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_00445BB8); -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_004460C0); #include "common.h" extern u8 D_L11_004465F8[]; diff --git a/src/pal/levels/11_joba/L11_004460C0.c b/src/pal/levels/11_joba/L11_004460C0.c new file mode 100644 index 000000000..70ef2b988 --- /dev/null +++ b/src/pal/levels/11_joba/L11_004460C0.c @@ -0,0 +1,49 @@ +/* func_PAL_L11_004460C0, the PAL copy of func_L11_00440868: the same C with the callee is PAL's + func_PAL_L11_003F72D0. */ +#include "include_asm.h" +#include "common.h" + +extern u8 *D_L11_001FC420[]; + +extern u8 *D_L11_001B359C __attribute__((section(".sdata"))); + +extern void func_PAL_L11_003F72D0(u8 *); + +extern void func_L11_00439950(u8 *); + +u8 *func_PAL_L11_004460C0(u8 *obj, s32 id) { + u8 *state = *(u8 **)(obj + 0x68); + s32 index = *(s32 *)(state + 0xC0); + u16 *cursor; + u8 *record; + u8 *list; + + if (index == 0xFF) { + return 0; + } + list = D_L11_001FC420[index]; + if (list == 0) { + return 0; + } + cursor = (u16 *)list; + do { + u16 value = *cursor & 0x7FFF; + record = D_L11_001B359C + (value << 8); + + if (record != 0 && record[0x20] != 0xFE && record[0x20] != 0xFD && + *(s16 *)(record + 0xAA) == id && record[0x20] == 1) { + *(u32 *)(record + 0xB8) = (u32)obj; + switch (id) { + case 0xD4A: + func_L11_00439950(record); + *(s32 *)(state + 0x118) += 1; + return record; + case 0xB3A: + func_PAL_L11_003F72D0(record); + *(s32 *)(state + 0x11C) += 1; + return record; + } + } + } while (*(s16 *)cursor++ >= 0); + return 0; +} diff --git a/src/pal/levels/11_joba/L11_0044BC30-g8.c b/src/pal/levels/11_joba/L11_0044BC30-g8.c new file mode 100644 index 000000000..fc0afcb4a --- /dev/null +++ b/src/pal/levels/11_joba/L11_0044BC30-g8.c @@ -0,0 +1,100 @@ +/* func_PAL_L11_0044BC30, the PAL copy of func_L11_004461E8: the same C, where 0.01666666753590107f + becomes 0.020000001f. */ +#include "common.h" + +#define S16(p,o) (*(short *)((p)+(o))) +#define I32(p,o) (*(int *)((p)+(o))) +#define F32(p,o) (*(float *)((p)+(o))) +typedef struct { u8 pad0[0x10]; float position[4]; u8 pad20[0x11]; u8 enabled; u16 mask, flags; u8 rest[0xCA]; } JobaRecord461E8; +typedef struct { u8 pad0[0x1bc]; float scale; } JobaState461E8; +#define SCALE(p) (((JobaState461E8 *)(p))->scale) +extern JobaRecord461E8 *D_L11_001B359C __attribute__((section(".sdata"))); +extern JobaRecord461E8 *D_L11_001B359C_GP SDATA(D_L11_001B359C); +extern u8 *D_L11_001FF580[]; +extern float D_L11_001B187C __attribute__((sda)), D_L11_001B1880 __attribute__((sda)); +extern float D_L11_001B1884 __attribute__((sda)), D_L11_001B1888 __attribute__((sda)); +extern void func_00283360(void *); +extern float func_002AA2E8(float *,float,float); +extern float func_00282C48(float); +extern void func_00282CF0(void *,void *,void *); +extern void func_00282D30(void *,void *,float); +extern void func_00282CC0(void *,void *,void *); +extern void func_00282F20(void *,void *,float); +extern float func_002A7878(float,float); +void func_PAL_L11_0044BC30(u8 *object) +{ + u8 *state = *(u8 **)(object+0x68); + float previous = SCALE(state); + float vector[4] __attribute__((aligned(16))); + switch (S16(state,0x1fa)) { + case 1: { + int i; + u8 *dst, *src; + func_00283360((u8 *)&D_L11_001B359C[I32(state,0x1b8)]+0xc0); + previous=1.0f; + dst=D_L11_001FF580[I32(state,0x1c8)]; + src=D_L11_001FF580[I32(state,0x1cc)]; + for(i=0;i1.0f) { + float random; + float *weight_row; + float *opposite; + *phase_row-=1.0f; + random = func_002A7878(0.3330000042915344f,0.6660000085830688f); + weight_row = weight + i; + opposite = weight + ((i+1)&1); + *weight_row = *opposite + random; + if(*weight_row>1.0f) *weight_row-=1.0f; + } + } + } +} diff --git a/src/pal/levels/11_joba/L11_0044BC30.c b/src/pal/levels/11_joba/L11_0044BC30.c index c5c6ef2fa..877bd62d6 100644 --- a/src/pal/levels/11_joba/L11_0044BC30.c +++ b/src/pal/levels/11_joba/L11_0044BC30.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_0044BC30); diff --git a/src/pal/levels/11_joba/L11_00456D04.c b/src/pal/levels/11_joba/L11_00456D04.c index cbb74826d..9f013e21e 100644 --- a/src/pal/levels/11_joba/L11_00456D04.c +++ b/src/pal/levels/11_joba/L11_00456D04.c @@ -2,4 +2,3 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L11_00456D04); -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_00458020); diff --git a/src/pal/levels/11_joba/L11_00458020-g8.c b/src/pal/levels/11_joba/L11_00458020-g8.c new file mode 100644 index 000000000..f374f3ea4 --- /dev/null +++ b/src/pal/levels/11_joba/L11_00458020-g8.c @@ -0,0 +1,196 @@ +/* func_PAL_L11_00458020, the PAL copy of func_L11_00452450: the same C, where 0.0055555557f + becomes 0.008f; 0.004444444552063942f becomes 0.0064000003f; 0.13333334028720856f becomes + 0.16000001f; 0.0011635529808700085f becomes 0.0016755164f; 0.10471977293491364f becomes + 0.12566373f; func_L11_00452DF8 becomes func_PAL_L11_004589C8; func_002B0ED8 becomes + func_PAL_002B1A50; 0.8377582f becomes 1.0053098f. */ +#include "common.h" + +extern float func_002A7878(float, float); +extern s32 func_002A77E0(s32); +extern void func_00282CC0(void *, void *, void *); + +typedef struct JobObject JobObject; + +typedef struct { + u8 pad00[0x18]; + float *params; /* +0x18, points at paramBlock */ + u8 pad1C[4]; + float health; /* +0x20 */ + u8 pad24[4]; + u8 f28; + u8 f29; + u8 pad2A[4]; + u8 f2E; + u8 pad2F; + float f30; + u8 f34; + u8 pad35[0x48 - 0x35]; + u8 f48; + u8 pad49; + u8 f4A; + u8 pad4B[5]; + u8 hitInfo[0x10]; /* +0x50 */ + u8 f60; + u8 pad61[8]; + u8 f69; + u8 pad6A[0x80 - 0x6A]; + float f80; + float f84; + u8 pad88[4]; + float f8C; + u8 pad90[8]; + s32 f98; + u8 pad9C[0xFC - 0x9C]; + float fFC; + float paramBlock[5]; /* +0x100 */ + u8 pad114[0x12C - 0x114]; + float f12C; + float f130; + float f134; + u8 pad138[0x1D4 - 0x138]; + float f1D4; + u8 pad1D8[0x1E6 - 0x1D8]; + u8 f1E6; + u8 pad1E7; + u8 f1E8; + u8 f1E9; + u8 pad1EA[0x1FC - 0x1EA]; + u16 spawnTimer; /* +0x1FC */ + u8 pad1FE[0x2F0 - 0x1FE]; + float basis[12]; /* +0x2F0 */ + float anchor[4]; /* +0x320 */ + u8 pad330[0x354 - 0x330]; + JobObject *turret; /* +0x354 */ + float turnRate; /* +0x358 */ + u8 pad35C[0x364 - 0x35C]; + s16 fireTimer; /* +0x364 */ + u8 pad366[0x36E - 0x366]; + s16 f36E; +} JobState; + +struct JobObject { + u8 pad00[0x10]; + float position[4]; /* +0x10 */ + u8 stage; /* +0x20 */ + u8 pad21[0x31 - 0x21]; + u8 f31; + u8 pad32[2]; + u16 flags; /* +0x34 */ + u8 pad36[0x68 - 0x36]; + JobState *state; /* +0x68 */ + u8 pad6C[3]; + u8 f6F; + u8 pad70[0x95 - 0x70]; + u8 f95; + u8 pad96[0xB8 - 0x96]; + s32 fB8; + u8 padBC[4]; + float rotation[12]; /* +0xC0 */ +}; + +extern s32 func_00283CF0(float); +extern float func_00282E48(void *, void *); +extern void func_002A93B0(void *); +extern void *func_002A9640(void *, s32, s32); +extern s32 func_PAL_002B1A50(void *, void *, s32); +extern void func_00283698(void *, void *); +extern void func_002AFFD8(void *, void *, s32); +extern s32 func_L11_004461C0(s32, void *); +extern void func_002A7750(void *, s32, s32); +extern char D_L11_001BA8C0[]; +extern s32 D_001A8FF4; + +extern void func_002B60B0(char *, float, float, float, float); +extern void func_PAL_L11_004589C8(void *); +extern void func_0029FCC0(void *, int, void *); +extern void func_0029FC20(void *, int, void *); +extern void func_00282C88(void *); +extern void func_002830C0(void *, void *, void *); +extern s32 func_002B3BA8(void *, s32, s32, s32, float, float); + +/* Per-frame update of an L11 object: on its first frame it seeds its state block (a random-sign + turn rate of 15 to 40 degrees, the 0.5/0.4 constant set) and runs its setup; then it sets the + proximity flag, rebuilds the frame at state + 0x290 and, from stage 3 on, runs its hit, death + and tracking checks. */ +void func_PAL_L11_00458020(char *object) +{ + char *state = *(char **)(object + 0x68); + char *aim; + char *hit; + char *source; + float matrix[16]; + float turnRate; + s16 kind; + + if (*(u8 *)(object + 0x20) == 0) { + *(char **)(state + 0x18) = state + 0x100; + turnRate = func_002A7878(15.0f, 40.0f) * 0.017453294f; + if (func_002A77E0(2) != 0) + turnRate = -turnRate; + *(f32 *)(state + 0x2C8) = turnRate; + if (func_002A77E0(2) == 1) + *(u16 *)(object + 0x34) |= 0x8000; + *(u8 *)(state + 0x48) = func_00283CF0(15.0f); + *(u8 *)(state + 0x4A) = func_00283CF0(12.0f); + *(u8 *)(state + 0x60) = 0xB; + *(s32 *)(state + 0x98) = 4; + *(f32 *)(state + 0x100) = 0.8f; + *(f32 *)(state + 0x104) = *(f32 *)(state + 0x84) = *(f32 *)(state + 0x80) = 0.5f; + *(f32 *)(state + 0x10C) = *(f32 *)(state + 0x108) = *(f32 *)(state + 0x8C) = 0.4f; + *(f32 *)(state + 0x110) = 1.5707965f; + *(f32 *)(state + 0x130) = 0.52359885f; + *(f32 *)(state + 0x12C) = 0.008f; + *(f32 *)(state + 0x134) = 2.8f; + func_002B60B0(object, 0.0064000003f, 0.16000001f, + 0.0016755164f, 0.12566373f); + *(u8 *)(state + 0x28) = 3; + func_PAL_L11_004589C8(object); + } + if (*(s16 *)(state + 0x2D8) == 0 && *(u8 *)(object + 0x20) != 0xC && D_001A8FF4 == 0) { + *(u16 *)(object + 0x34) |= 0x400; + if (*(u8 *)(object + 0x31) != 0 && func_00282E48(object + 0x10, D_L11_001BA8C0) < 24.0f) { + func_002A93B0(object); + *(u8 *)(object + 0x6F) = 0x16; + } + } else { + *(u16 *)(object + 0x34) &= 0xFBFF; + } + aim = state + 0x290; + func_0029FCC0(object, 1, state + 0x270); + func_0029FCC0(object, 2, state + 0x280); + func_0029FC20(object, 3, matrix); + func_00282C88(aim); + *(s32 *)(state + 0x298) = 0; + *(f32 *)(state + 0x290) = 0.25f; + func_002830C0(aim, aim, matrix); + func_00282CC0(aim, aim, matrix + 12); + if (*(u8 *)(object + 0x20) >= 3) { + hit = (char *)func_002A9640(object, 0x10000, 1); + if (hit != 0) { + source = *(char **)(hit + 0x20); + if (source != 0 && *(u8 *)(object + 0x31) == 0) { + kind = *(s16 *)(source + 0xAA); + if (kind == 0xA03 || kind == 0xB89) + *(s32 *)(hit + 0x2C) = 0; + } + } + if (func_PAL_002B1A50(object, state + 0x50, 0) == 5) { + *(s32 *)(state + 0xE0) = 0; + *(f32 *)(state + 0xE4) = 1.0053098f; + } + if (*(s16 *)(state + 0x2D8) != 0) { + char *pos; + func_00283698(state + 0x230, object + 0xC0); + pos = object + 0x10; + func_002AFFD8(pos, state + 0x260, 0); + if (func_L11_004461C0(*(s32 *)(object + 0xB8), pos) == 0) { + *(s32 *)(state + 0x20) = 0; + func_002A7750(object, 0xC, 4); + } + } + if (*(u8 *)(object + 0x20) >= 2 && *(u8 *)(state + 0x2E) == 2) + func_PAL_L11_004589C8(object); + *(s16 *)(state + 0x2D0) = func_002B3BA8(object, *(s32 *)(state + 0x2CC), 0, 0, 100.0f, 100.0f); + *(s32 *)(state + 0x2C4) = *(s32 *)(state + 0x220); + } +} diff --git a/src/pal/levels/11_joba/L11_00466178.c b/src/pal/levels/11_joba/L11_00466178.c index 8c0d38a1d..e5b06eaa1 100644 --- a/src/pal/levels/11_joba/L11_00466178.c +++ b/src/pal/levels/11_joba/L11_00466178.c @@ -2,6 +2,5 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L11_00466178); -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_00467118); INCLUDE_ASM("asm/pal/levels", func_PAL_L11_004676D0); diff --git a/src/pal/levels/11_joba/L11_00467118.c b/src/pal/levels/11_joba/L11_00467118.c new file mode 100644 index 000000000..5f0c46f7a --- /dev/null +++ b/src/pal/levels/11_joba/L11_00467118.c @@ -0,0 +1,121 @@ +/* func_PAL_L11_00467118, the PAL copy of func_L11_00461308: the same C, where func_002A7470 + becomes func_PAL_002A7E68; func_L11_003DD068 becomes func_PAL_L11_003E0F10; 0.00027777778f + becomes 0.00040000002f; 0.034906592f becomes 0.04188791f; func_002A05A8 becomes + func_PAL_002A0F68; 1.0f / 60.0f becomes 0.020000001f. */ +#include "common.h" +typedef int TI128 __attribute__((mode(TI))); +extern char *func_0029EFD0(int); +extern void func_002B37E8(char *, char *); +extern void func_PAL_002A7E68(char *, int, int, int); +extern void func_002A7750(char *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_0029FCC0(char *, int, void *); +extern void func_002830C0(void *, void *, void *); +extern u8 *func_PAL_L11_003E0F10(u8 *, u8 *, u8 *, float); +extern float func_002A7878(float, float); +extern float func_00283B98(float, float); +extern float func_00283180(float); +extern float func_00283198(float); +extern void func_00282D30(void *, void *, float); +extern void func_00282CC0(void *, void *, void *); +extern void func_PAL_002A0F68(char *); +extern void func_002A0F48(char *); +extern void func_L00_0033C0D0(char *, void *, void *, void *, int); +extern int D_L11_001B089C[] NOT_SDA __attribute__((sda)); +typedef struct { int unused; int flags; char pad[56]; } Entry61308; +extern Entry61308 D_L11_002B6D40[]; +extern char *D_L11_001B359C[] NOT_SDA __attribute__((sda)); +extern char *D_L11_001B368C[] NOT_SDA __attribute__((sda)); +extern char D_00189EA0[]; +extern float D_L11_001B2388 SDATA(D_L11_001B2388); +extern float D_L11_001B2388_block[] __asm__("D_L11_001B2388") __attribute__((sda)); +extern char D_L11_001B2378[] NOT_SDA __attribute__((sda)); +extern char D_L11_001B2368[] NOT_SDA __attribute__((sda)); +extern char D_L11_001B2358[] SDATA(D_L11_001B2358); +#define F(p,o) (*(float *)((char *)(p)+(o))) +#define I(p,o) (*(int *)((char *)(p)+(o))) +#define P(p,o) (*(char **)((char *)(p)+(o))) +#define H(p,o) (*(unsigned short *)((char *)(p)+(o))) +void func_PAL_L11_00467118(char *p) +{ + float v[4], pos[4], dir[4], tmp[4]; + char *s = P(p,0x68); + int active=0, i, ready; + float t, sn, cs; + switch ((unsigned char)p[0x20]) { + case 0: + P(s,0x10)=func_0029EFD0(0xCF6); + F(s,0x14)=0; F(s,0x18)=0; + if(P(s,0x10)) { + func_002B37E8(P(s,0x10),0); + H(P(s,0x10),0x34)|=6; + func_PAL_002A7E68(P(s,0x10),0x10,0,0); + } + func_002A7750(p,1,-1); + break; + case 1: + if ((D_L11_002B6D40[D_L11_001B089C[0]].flags&0x10) && !I(s,8)) { + H(p,0x34)|=0x41; + H(P(s,0x10),0x34)|=0x41; + I(p,0x98)=0; + return; + } + active=1; + H(p,0x34)&=0xFFBE; + H(P(s,0x10),0x34)&=0xFFBE; + I(p,0x98)=I(P(p,0x24),0x10); + ready=1; + if(I(s,0xC)!=-1) { char *m=D_L11_001B359C[0]+(I(s,0xC)<<8); ready=0; if((unsigned char)m[0x20]!=3) ready=active; } + if (ready && func_002ACBC8(D_00189EA0,I(s,0))) + func_002A7750(p,2,-1); + break; + case 2: + active=1; + t=func_002A7878(0.0f,0.333f); + for(i=0;i<3;i++) { + func_0029FCC0(p,i==0?3:i==1?2:4,v); + *(TI128 *)tmp = 0; + tmp[0]=func_002A7878(-1.0f,1.0f); + tmp[3]=1.0f; + tmp[1]=t+t-1.0f; + t+=0.333f; + *(TI128 *)dir=*(TI128 *)tmp; + func_002830C0(dir,dir,D_L11_001B368C[0]+(I(s,4)<<7)); + { + float high = D_L11_001B2388_block[1]; + float low = D_L11_001B2388; + func_PAL_L11_003E0F10(p,v,dir,func_002A7878(low,high)*0.00040000002f); + } + } + func_002A7750(p,3,-1); + break; + case 3: + active=1; + if(!func_002ACBC8(D_00189EA0,I(s,0))) func_002A7750(p,1,-1); + break; + } + if(active) { + F(s,0x14)=func_00283B98(F(s,0x14),0.04188791f); + sn=func_00283180(F(s,0x14)); + cs=func_00283198(F(s,0x14)); + F(p,0x18)-=F(s,0x18); + F(s,0x18)=cs*0.1f; + F(p,0x18)+=F(s,0x18); + F(p,0xF4)+=cs*0.0015f; + F(p,0xF0)+=sn*0.0015f; + *(TI128 *)(P(s,0x10)+0xF0)=*(TI128 *)(p+0xF0); + func_00282D30(v,p+0xE0,1.46f); + func_00282CC0(P(s,0x10)+0x10,p+0x10,v); + func_PAL_002A0F68(P(s,0x10)); + func_002A0F48(P(s,0x10)); + func_00282D30(v,p+0xE0,0.59f); + func_00282CC0(pos,p+0x10,v); + v[0]=v[1]=0.0f; + v[2]=-(func_002A7878(2.25f,3.5f)*(0.020000001f)); + func_L00_0033C0D0(p,pos,v,D_L11_001B2378,1); + v[2]=-(func_002A7878(3.0f,5.0f)*(0.020000001f)); + func_L00_0033C0D0(p,pos,v,D_L11_001B2368,1); + v[2]=-(func_002A7878(4.0f,8.0f)*(0.020000001f)); + func_L00_0033C0D0(p,pos,v,D_L11_001B2358,1); + } +} diff --git a/src/pal/levels/11_joba/L11_00473908-f7-g8.c b/src/pal/levels/11_joba/L11_00473908-f7-g8.c new file mode 100644 index 000000000..0b50392de --- /dev/null +++ b/src/pal/levels/11_joba/L11_00473908-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L11_00473908, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L11_00473908(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/11_joba/L11_00473908.c b/src/pal/levels/11_joba/L11_00473908.c index 8a5c304e7..9d4359bd2 100644 --- a/src/pal/levels/11_joba/L11_00473908.c +++ b/src/pal/levels/11_joba/L11_00473908.c @@ -1,4 +1,3 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_00473908); diff --git a/src/pal/levels/11_joba/L11_004791F0-g8.c b/src/pal/levels/11_joba/L11_004791F0-g8.c new file mode 100644 index 000000000..d8a3d3914 --- /dev/null +++ b/src/pal/levels/11_joba/L11_004791F0-g8.c @@ -0,0 +1,100 @@ +/* func_PAL_L11_004791F0, the PAL copy of func_L11_00472E10: the same C, where func_L00_002B9D60 + becomes func_PAL_L00_002B9CD8. */ + +typedef unsigned char u8; +typedef unsigned short u16; +extern u8 D_001A7B2B; +extern int D_001A79F0; +extern u8 D_0019B4A8[]; +typedef struct { u8 prefix[0x464]; u8 flags[1]; } LevelFlags; +extern LevelFlags D_L11_0021F8B0; +extern u8 D_00189EA0[]; +extern u8 D_00188660[]; +extern u8 *D_L11_001B359C __attribute__((sda)); +extern int func_002ACD38(void *); +extern void func_L00_003672F8(void); +extern void func_PAL_L00_002B9CD8(float *, float *, int, int); +extern float func_00282E80(void *, void *); +extern int func_L00_0035F5A0(int, int, int); +extern void func_002E59F8(int); +extern int func_002B38B8(u8 *); +extern void func_0029F338(void *); + +void func_PAL_L11_004791F0(u8 *object) { + float position[4]; + float rotation[4]; + int *state = *(int **)(object + 0x68); + int count, slot; + u8 *record; + u8 *counter; + if (object[0x20] == 0) { + if (D_001A7B2B) { + u16 id = *(u16 *)(object + 0xB2); + int bits; + if (D_L11_0021F8B0.flags[(short)id] == 0) { + bits = D_0019B4A8[((short)id >> 1) + D_001A79F0 * 0x400]; + if (*(u16 *)(object + 0xB2) & 1) bits = (bits >> 4) & 7; + else bits &= 7; + if (bits == 0 && func_002ACD38(object + 0x10)) { + func_L00_003672F8(); + position[0] = 363.18f; + position[1] = 680.68f; + position[2] = 155.73f; + rotation[2] = 2.3561947f; + rotation[0] = 0; + rotation[1] = 0; + func_PAL_L00_002B9CD8(position, rotation, 0, 1); + } + } + } + object[0x20] = 1; + } + if (func_00282E80(object + 0x10, D_00189EA0) < 32.0f) { + if (D_001A79F0 == 11) { + record = D_00188660 + state[8] * 0x70; + if (*(int *)(record + 0x88) != *(int *)(D_00189EA0 + 0x2210) || record[0x74] == 0) + state[8] = func_L00_0035F5A0(27, 6, *(int *)(D_00189EA0 + 0x2210)); + } + } else { + slot = state[8]; + if (slot != -1) { + record = D_00188660 + slot * 0x70; + if (*(int *)(record + 0x88) == *(int *)(D_00189EA0 + 0x2210) && record[0x74]) func_002E59F8(slot); + } + state[8] = -1; + } + if (!func_002B38B8(object)) { + u16 id = *(u16 *)(object + 0xB2); + int bits; + if (!D_L11_0021F8B0.flags[(short)id]) { + bits = D_0019B4A8[((short)id >> 1) + D_001A79F0 * 0x400]; + if ((*(u16 *)(object + 0xB2) & 1) + ? ((bits >> 4) & 7) != 0 + : (bits & 7) != 0) goto cleanup; + return; + } + } +cleanup: + for (count = 0; count < 8; count++) { + if (state[count] != -1) func_0029F338(D_L11_001B359C + state[count] * 0x100); + } + { + int counter_id = *(u16 *)(object + 0xB2); + if (counter_id & 1) { + counter = &D_0019B4A8[((short)counter_id >> 1) + D_001A79F0 * 0x400]; + if (((*counter >> 4) & 7) != 7) *counter += 16; + } else { + counter = &D_0019B4A8[((short)counter_id >> 1) + D_001A79F0 * 0x400]; + if ((*counter & 7) != 7) ++*counter; + } + } + { + int final_slot = state[8]; + if (final_slot != -1) { + record = D_00188660 + final_slot * 0x70; + if (*(int *)(record + 0x88) == *(int *)(D_00189EA0 + 0x2210) && record[0x74]) func_002E59F8(final_slot); + } + state[8] = -1; + func_0029F338(object); + } +} diff --git a/src/pal/levels/11_joba/L11_004791F0.c b/src/pal/levels/11_joba/L11_004791F0.c index 44634b540..877bd62d6 100644 --- a/src/pal/levels/11_joba/L11_004791F0.c +++ b/src/pal/levels/11_joba/L11_004791F0.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L11_004791F0); diff --git a/src/pal/levels/12_todano/L12_0041B520.c b/src/pal/levels/12_todano/L12_0041B520.c index 539aa9324..eeda4e2f7 100644 --- a/src/pal/levels/12_todano/L12_0041B520.c +++ b/src/pal/levels/12_todano/L12_0041B520.c @@ -2,4 +2,3 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L12_0041B520); -INCLUDE_ASM("asm/pal/levels", func_PAL_L12_0041C930); diff --git a/src/pal/levels/12_todano/L12_0041C930-f7-g8.c b/src/pal/levels/12_todano/L12_0041C930-f7-g8.c new file mode 100644 index 000000000..7e07ea84f --- /dev/null +++ b/src/pal/levels/12_todano/L12_0041C930-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L12_0041C930, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L12_0041C930(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/13_boldan/L13_00421C68-f7-g8.c b/src/pal/levels/13_boldan/L13_00421C68-f7-g8.c new file mode 100644 index 000000000..877cac043 --- /dev/null +++ b/src/pal/levels/13_boldan/L13_00421C68-f7-g8.c @@ -0,0 +1,195 @@ +/* func_PAL_L13_00421C68, the PAL copy of func_L00_0040EAA0: the same C, where func_002F5CC8 + becomes func_PAL_002F6C18; func_L00_002B9D60 becomes func_PAL_L00_002B9CD8; func_002AF0A8 + becomes func_PAL_002AFC10. */ +#include "common.h" + +typedef struct { + int msg; /* 0x0 */ + int link; /* 0x4 */ + unsigned char idx; /* 0x8 */ + signed char item; /* 0x9 */ + unsigned char on; /* 0xA */ + signed char count; /* 0xB */ + union { int word; signed char low; struct { char pad[1]; unsigned char quiet; char pad2; unsigned char had; } b; } tail; /* 0xC */ +} TriggerVars; + +extern void func_0026FEB8(const char *, ...); +extern int func_00288AA0(void *, int); +extern int func_00288BE8(void *); /* its result is tested elsewhere */ +extern void func_00288CB0(int, int); +extern void func_0029B3E0(int, int); +extern void func_0029F338(void *); +extern void func_002A0430(int); +extern void func_002A7750(void *, int, int); +extern int func_002ACBC8(void *, int); +extern void func_002AD7B8(int); +extern void func_PAL_002AFC10(int); +extern int func_002B38B8(void *); +extern void func_002DF3F8(void *, void *); +extern void func_PAL_002F6C18(void); +extern int func_002F5D10(void); +extern void func_PAL_L00_002B9CD8(void *, void *, int, int); + +extern unsigned int D_00139768[]; +typedef struct { + char pad0[0x80]; char body[0x2294 - 0x80]; + int mode; char pad2298[0x24CC - 0x2298]; + int health; +} HeroView; +extern HeroView D_00189E20; +extern char D_00189EA0[]; +extern unsigned char D_0019B2E8[]; +extern int D_001A79F0; +extern unsigned char D_001A7BC8[] MACRO_ADDR; +extern int D_L06_001A8F00; +extern char D_L06_001B1810[]; +extern int D_L06_001B2348; +extern char *D_L06_001B290C; +extern char D_L06_001BFA40[]; +extern short **D_L06_002AA490[]; +extern char D_L06_002E2210[]; + +typedef struct { + char pad00[0x10]; char pos[0x10]; + unsigned char state; char pad21[0x47]; + TriggerVars *vars; char pad6C[0x3E]; + short id; char padAC[4]; + unsigned char group; char padB1; short oclass; char padB4[8]; + unsigned char hit; char padBD[0x33]; + char dir[0x10]; +} Thing; + +void func_PAL_L13_00421C68(Thing *m) +{ + TriggerVars *p = m->vars; + int notify, i, missing, fail; + int played; + + switch (m->state) { + case 0: + if ((p->item != -1 && D_001A7BC8[p->item] != 0) + || (m->group != 0xFF && (D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80))) { + func_0029F338(m); + break; + } + func_002A7750(m, 1, -1); + case 1: + if (p->on == 0 && func_002B38B8(m) == 0 && m->hit == 0) + break; + p->on = 1; + func_002A7750(m, 2, -1); + case 2: + if (p->on == 0) { + func_002A7750(m, 1, -1); + break; + } + if (D_00189E20.mode == 0x1C) + break; + if (D_00189E20.health <= 0) + break; + if (D_L06_001A8F00 != 0) + break; + if (p->msg != -1 && func_002ACBC8(D_00189E20.body, p->msg) == 0) + break; + fail = 1; + missing = 1; + if (D_L06_002AA490[D_001A79F0] != 0 && D_L06_002AA490[D_001A79F0][p->idx] != 0) { + for (i = 0; D_L06_002AA490[D_001A79F0][p->idx][i] != -1; i++) { + int e = D_L06_002AA490[D_001A79F0][p->idx][i]; + + missing = 0; + if (p->tail.b.quiet == 0) { + int bit = 1 << (e & 0x1F); + if (D_00139768[(unsigned int)e >> 2] & bit) + continue; + } + if (func_00288AA0(D_L06_001BFA40, e) == 0 && i == 0) { + func_0026FEB8(D_L06_002E2210, m->id, m->oclass, D_001A79F0, p->idx, e); + return; + } + fail = 0; + } + } + /* Retail keeps missing in $s5 above fail: the test's do-while (a debug-print macro's + shape) counts it at loop depth, its fourth reference. Its loop label is not aligned + in retail, so the unit turns loop alignment off; the other loop's label is already + on an 8-byte boundary. */ + do { + if (missing != 0) + func_0026FEB8(D_L06_001B1810, D_001A79F0, p->idx); + } while (0); + if (fail != 0) { + p->tail.b.had = 0; + func_002A7750(m, 4, -1); + break; + } + p->tail.b.had = 1; + func_00288BE8(D_L06_001BFA40); + if (D_L06_001B2348 < 5 || (D_001A79F0 == 6 && p->idx == 0)) + func_PAL_002F6C18(); + func_002A7750(m, 3, -1); + break; + case 3: + if (func_002F5D10() == 0) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_PAL_L00_002B9CD8(o + 0x30, o + 0x70, 0, 1); + } + func_002A7750(m, 4, -1); + } + if (D_001A79F0 != 0) + break; + if (p->item == -1) + break; + if (func_002F5D10() != 0) + break; + notify = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + notify = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + notify = 1; + } + if (p->count != 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(m->pos, m->dir); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if (notify != 0 || p->tail.b.had != 0) + func_0029B3E0(0, -1); + break; + case 4: + played = 0; + if (p->item != -1) { + func_002AD7B8(p->item); + if (p->item != 0x18) + func_PAL_002AFC10(p->item); + played = 1; + } + if (m->group != 0xFF && !(D_0019B2E8[m->group + D_001A79F0 * 16] & 0x80)) { + func_002A0430(m->group); + played = 1; + } + if (p->count > 0 && (p->tail.word & 0xFFFF0000)) { + if (p->link != -1) { + char *o = D_L06_001B290C + (p->link << 7); + func_002DF3F8(o + 0x30, o + 0x70); + } else + func_002DF3F8(D_00189EA0, D_00189EA0 + 0x10); + } + if (p->tail.low != -1) + func_00288CB0(p->tail.low, 1); + else if ((played != 0 || p->tail.b.had != 0) && p->count != p->tail.low) + func_0029B3E0(0, -1); + func_0029F338(m); + break; + } +} diff --git a/src/pal/levels/13_boldan/L13_00421C68.c b/src/pal/levels/13_boldan/L13_00421C68.c index b365322bd..877bd62d6 100644 --- a/src/pal/levels/13_boldan/L13_00421C68.c +++ b/src/pal/levels/13_boldan/L13_00421C68.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L13_00421C68); diff --git a/src/pal/levels/17_smolg/L17_003D0B70-hz.c b/src/pal/levels/17_smolg/L17_003D0B70-hz.c new file mode 100644 index 000000000..bbc3e08f7 --- /dev/null +++ b/src/pal/levels/17_smolg/L17_003D0B70-hz.c @@ -0,0 +1,87 @@ +/* func_PAL_L17_003D0B70, the PAL copy of func_L17_003CC850: the same C, where 1.0f / 60.0f becomes + 0.020000001f; 0.0011111112544313073f becomes 0.0015584417f; 0.0005555556272156537f becomes + 0.0007894737f. */ +#include "common.h" + +extern f32 func_00283198(f32); + +typedef int TI128 __attribute__((mode(TI))); + +typedef struct { + u8 pad00[0x80]; + f32 x; + f32 y; + f32 z; + u8 pad8C[0x340 - 0x8C]; + s32 w340; +} L17Player; + +extern L17Player D_00189E20; +extern f32 D_L17_001B04BC SDATA(D_L17_001B04BC); +extern f32 func_00283248(f32, f32); +extern f32 func_00283C80(f32, f32); +extern f32 func_00283180(f32); +extern f32 func_002AA2E8(void *, f32, f32); +extern void func_00282CD8(void *, void *, void *); + +extern s32 func_L17_003CC798(u8 *a0, TI128 *a1, f32 f1, f32 f2); +void func_PAL_L17_003D0B70(u8 *a0) +{ + f32 *st = *(f32 **)(a0 + 0x68); + TI128 here __attribute__((aligned(16))); + f32 dir[4] __attribute__((aligned(16))); + + st[2] = D_L17_001B04BC; + switch (a0[0x20]) { + case 0: + *(f32 *)(a0 + 0x18) = *(f32 *)(a0 + 0x18) - 0.05f; + a0[0x20] = 1; + *(u16 *)(a0 + 0x34) |= 0x41; + break; + case 1: + break; + case 2: + if (!(D_00189E20.z < *(f32 *)(a0 + 0x18))) { + break; + } + if (!(func_00283C80(*(f32 *)(a0 + 0xF8), + func_00283248(D_00189E20.x - *(f32 *)(a0 + 0x10), + D_00189E20.y - *(f32 *)(a0 + 0x14))) < 1.5707965f)) { + break; + } + if (D_00189E20.w340 != 0) { + break; + } + a0[0x20] = 3; + st[3] = 0; + /* fall through */ + case 3: + if (D_00189E20.w340 != 0) { + a0[0x20] = 1; + break; + } + here = *(TI128 *)&D_00189E20.x; + if (func_L17_003CC798(a0, &here, 60.0f, 2.5f)) { + func_002AA2E8(st + 3, st[2] * (0.020000001f), st[2] * 0.0015584417f); + } else { + func_002AA2E8(st + 3, 0.0f, st[2] * 0.0007894737f); + } + dir[0] = func_00283180(*(f32 *)(a0 + 0xF8)) * st[3]; + dir[1] = func_00283198(*(f32 *)(a0 + 0xF8)) * st[3]; + dir[2] = 0; + func_00282CD8(&here, (u8 *)&D_00189E20 + 0x100, dir); + break; + } + if (a0[0x20] != 3) { + if (*(f32 *)(a0 + 0x18) <= D_00189E20.z) { + *(TI128 *)dir = *(TI128 *)&D_00189E20.x; + if (func_L17_003CC798(a0, (TI128 *)dir, st[0], st[1])) { + a0[0x20] = 2; + return; + } + } + if (a0[0x20] != 3) { + a0[0x20] = 1; + } + } +} diff --git a/src/pal/levels/17_smolg/L17_003D0B70.c b/src/pal/levels/17_smolg/L17_003D0B70.c index 48a575c23..877bd62d6 100644 --- a/src/pal/levels/17_smolg/L17_003D0B70.c +++ b/src/pal/levels/17_smolg/L17_003D0B70.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L17_003D0B70); diff --git a/src/pal/levels/19_grelbin/L19_00423BC8.c b/src/pal/levels/19_grelbin/L19_00423BC8.c index 31cf75756..9a4fe3d8e 100644 --- a/src/pal/levels/19_grelbin/L19_00423BC8.c +++ b/src/pal/levels/19_grelbin/L19_00423BC8.c @@ -3,7 +3,6 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L19_00423BC8); -INCLUDE_ASM("asm/pal/levels", func_PAL_L19_00425AE0); #include "common.h" extern void func_00282F20(void *, void *, float); diff --git a/src/pal/levels/19_grelbin/L19_00425AE0-g8.c b/src/pal/levels/19_grelbin/L19_00425AE0-g8.c new file mode 100644 index 000000000..ae24a052c --- /dev/null +++ b/src/pal/levels/19_grelbin/L19_00425AE0-g8.c @@ -0,0 +1,75 @@ +/* func_PAL_L19_00425AE0, the PAL copy of func_L19_004203F0: the same C, where func_L19_00423270 + becomes func_PAL_L19_004289C0; func_002A96A0 becomes func_PAL_002AA108; func_002AB800 becomes + func_PAL_002AC290; func_002AB8C0 becomes func_PAL_002AC3C0; 1.0f / 6.0f becomes 0.20000002f; + 0.15f becomes 0.18f; func_002B0A68 becomes func_PAL_002B15D8. */ +#include "common.h" +extern unsigned char D_0019B4A8[]; +extern struct { char pad[0x464]; u8 state[0]; } D_L19_0021EA30; +extern int D_001A79F0 SDATA(D_001A79F0); +extern int D_L19_001B1DE0 __attribute__((sda)); +extern char D_L19_001BFEC0[]; +extern void func_0029F338(void *); +extern int func_002ACD38(void *); +extern float func_002A89A8(void *, int, float); +extern int func_002761F8(void *, void *, int, void *, void *); +extern void func_002B0408(void *, void *, void *), func_002A7750(void *, int, int), func_PAL_L19_004289C0(void *); +extern void *func_002A9640(void *, int, int); +extern float func_PAL_002AA108(void *, void *), func_00283CE0(int); +extern int func_00283CF0(float); +extern void func_PAL_002AC290(void *, void *), func_002A7398(void *, int, int), func_PAL_002AC3C0(void *, void *); +extern int func_002A7820(int,int); +extern int func_002E5CF8(int,int,void *); +extern void func_PAL_002B15D8(void *, int, void *, float, float, float, float, int); +extern char *func_0029EFD0(int); +extern void func_002A0F48(void *), func_002AB650(void *); +/* Remove the object when its persistence state says so; otherwise apply hit damage + * and spawn object kind 0x1266 when health runs out. */ +void func_PAL_L19_00425AE0(char *o) +{ + char *d, *hit, *n; + float *health; char *color; + float a[4] __attribute__((aligned(16))), b[4] __attribute__((aligned(16))); + float damage; + if (*(u8 *)(o+0xb0)!=255) { + unsigned short id=*(unsigned short *)(o+0xb2); + int v; + if (D_L19_0021EA30.state[(short)id] || (v=D_0019B4A8[((short)id>>1)+(D_001A79F0<<10)], (id&1) ? ((v>>4)&7) : (v&7))) {func_0029F338(o);return;} + } + if (!func_002ACD38(o+0x10)) return; + d=*(char **)(o+0x68); + if (!*(u8 *)(o+0x20)) { + *(int *)(o+0x78)=D_L19_001B1DE0; + *(float *)(o+0x18)=func_002A89A8(o+0x10,0,0.5f)-0.1f; + *(u8 *)(o+0x31)=1; *(u16 *)(o+0x34)|=0x100; *(int *)(o+0x48)=0; + qcopy(a,o+0x10); qcopy(b,o+0x10); a[2]+=1; b[2]-=10; + func_002761F8(a,b,2,o,0); + func_002B0408(o+0xc0,D_L19_001BFEC0,0); func_002A7750(o,1,0); + } + if (*(u8 *)(o+0x31)) func_PAL_L19_004289C0(o); + if (*(u8 *)(o+0x20)!=1) return; + hit=func_002A9640(o,0x230000,0); + health=(float *)(d+0x20);color=d+0x50; + damage=func_PAL_002AA108(o,hit); + if(damage>0) { + *health-=damage; + *(u8 *)(color+7)=255; *(u8 *)(color+8)=255; *(u8 *)(color+9)=255; + func_PAL_002AC290(o,color); + func_002A7398(o,0,func_00283CF0(func_00283CE0(*(short *)(d+0x24))-*health)<8 ? func_00283CF0(func_00283CE0(*(short *)(d+0x24))-*health):7); + {int s=func_002A7820(0,2); if(*health>0)func_002E5CF8(s,0,o);} + } + *(u8 *)(o+0xa8)=255;func_PAL_002AC3C0(o,color); + if(*health<=0) { + qzero(a); a[2]=0.20000002f; + if(hit)qcopy(b,hit);else {qcopy(b,o+0x10); b[2]+=2;} + qzero(a);a[2]=0.18f; + func_PAL_002B15D8(o,15,a,3,6,3,6,255); + n=func_0029EFD0(0x1266); + if(n) { + *(u8 *)(n+0x23)=0x50;*(u16 *)(n+0x34)|=0x800; + *(float *)(n+0x2c)=*(float *)(*(char **)(n+0x24)+0x24)*0.65f; + *(u8 *)(n+0x30)=255;*(u16 *)(n+0x32)=255;*(u8 *)(n+0x31)=1;*(u8 *)(n+0x20)=0;*(u8 *)(n+0xbc)=0; + qcopy(n+0x10,o+0x10);func_002A0F48(n);func_002AB650(n);func_002E5CF8(3,0,o);*(char **)(*(char **)(n+0x68)+4)=o; + } + *(u8 *)(o+0x20)=2;*(u16 *)(o+0x34)=(*(u16 *)(o+0x34)|0x41)&0xefff;*(int *)(o+0x98)=0; + } +} diff --git a/src/pal/levels/20_yeedil/L20_003A1940-g8-hz.c b/src/pal/levels/20_yeedil/L20_003A1940-g8-hz.c new file mode 100644 index 000000000..7da6a6e98 --- /dev/null +++ b/src/pal/levels/20_yeedil/L20_003A1940-g8-hz.c @@ -0,0 +1,54 @@ +/* func_PAL_L20_003A1940, the PAL copy of func_L20_0039E9F8: the same C, where 0.00027777778f + becomes 0.00040000002f; 0.016666668f becomes 0.020000001f; 0.00087266474f becomes 0.0012566373f; + 0.052359886f becomes 0.062831864f. */ +#include "common.h" + +#define FLD(base, T, off) (((struct { u8 pad[off]; T v; } *)(base))->v) + +extern float D_L20_001AED10 __attribute__((sda)); +extern float D_L20_001AED0C __attribute__((sda)); +extern char *D_L20_001B308C __attribute__((nosda)); + +extern float func_00283B98(float, float); +extern float func_00283C80(float, float); +extern float func_002AAA00(void *, float, float, float, float, void *, int); +extern float func_002AA548(char *, char *, float, float, float, float); +extern float func_00282C48(float); +extern int func_00282C30(int); +extern void func_00282C90(char *); +extern void func_002830C0(char *, char *, char *); + +void func_PAL_L20_003A1940(char *obj) { + char *state = FLD(obj, char *, 0x68); + char *entry; + float turn; + float spin; + float target; + float r; + + entry = (char *)((FLD(state, int, 0x84) << 7) + (unsigned int)D_L20_001B308C); + turn = D_L20_001AED10 * 0.00040000002f; + spin = D_L20_001AED0C * 0.020000001f; + target = FLD(entry, float, 0x78); + if (FLD(state, int, 0x190) < 0) { + target = func_00283B98(target, 3.1415927f); + } + r = func_00283C80(FLD(obj, float, 0xF8), target); + if (r > 0.017453294f) { + func_002AAA00(obj + 0xF8, target, 0.0012566373f, 0.0012566373f, 0.062831864f, + state + 0x19C, 0); + } else { + func_002AA548(state + 0x194, state + 0x198, (float)FLD(state, int, 0x190), turn, + turn, spin); + r = FLD(state, float, 0x194) * (float)FLD(state, int, 0x190); + if (r > 0.0f) { + target = func_00282C48(FLD(state, float, 0x194)); + if ((float)func_00282C30(FLD(state, int, 0x190)) <= target) { + FLD(state, int, 0x190) = -FLD(state, int, 0x190); + } + } + } + func_00282C90(obj + 0x10); + FLD(obj, float, 0x10) = FLD(state, float, 0x194); + func_002830C0(obj + 0x10, obj + 0x10, D_L20_001B308C + (FLD(state, int, 0x84) << 7)); +} diff --git a/src/pal/levels/20_yeedil/L20_003A1940.c b/src/pal/levels/20_yeedil/L20_003A1940.c index 630c45ccc..715bd6eeb 100644 --- a/src/pal/levels/20_yeedil/L20_003A1940.c +++ b/src/pal/levels/20_yeedil/L20_003A1940.c @@ -1,6 +1,5 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L20_003A1940); INCLUDE_ASM("asm/pal/levels", func_PAL_L20_003A1B00); diff --git a/src/pal/levels/20_yeedil/L20_004495C0.c b/src/pal/levels/20_yeedil/L20_004495C0.c index 6eea160dc..31220959e 100644 --- a/src/pal/levels/20_yeedil/L20_004495C0.c +++ b/src/pal/levels/20_yeedil/L20_004495C0.c @@ -50,11 +50,9 @@ void func_PAL_L20_004495C0(char *arg0, char *arg1, char *arg2, float *arg3) { } -INCLUDE_ASM("asm/pal/levels", func_PAL_L20_00449750); INCLUDE_ASM("asm/pal/levels", func_PAL_L20_004497B8); -INCLUDE_ASM("asm/pal/levels", func_PAL_L20_00449870); INCLUDE_ASM("asm/pal/levels", func_PAL_L20_00449B08); diff --git a/src/pal/levels/20_yeedil/L20_00449750.c b/src/pal/levels/20_yeedil/L20_00449750.c new file mode 100644 index 000000000..aea09a20a --- /dev/null +++ b/src/pal/levels/20_yeedil/L20_00449750.c @@ -0,0 +1,19 @@ +/* func_PAL_L20_00449750, the PAL copy of func_L20_00443CF0: the same C with the callees are PAL's + func_PAL_L20_004495C0 and func_PAL_L20_00445B90. */ +#include "common.h" + +typedef int TI128 __attribute__((mode(TI))); + +extern void func_PAL_L20_004495C0(char *, char *, char *, float *); +extern u8 *func_PAL_L20_00445B90(int, const float *, const float *, float); + +u8 *func_PAL_L20_00449750(char *arg0) { + char *state = *(char **)(arg0 + 0x68); + TI128 v0; + TI128 v1; + float f; + + f = 1.0471977f; + func_PAL_L20_004495C0(arg0, (char *)&v0, (char *)&v1, &f); + return func_PAL_L20_00445B90(*(int *)(state + 0x21C), (float *)&v0, (float *)&v1, f); +} diff --git a/src/pal/levels/20_yeedil/L20_00449870.c b/src/pal/levels/20_yeedil/L20_00449870.c new file mode 100644 index 000000000..56dac6636 --- /dev/null +++ b/src/pal/levels/20_yeedil/L20_00449870.c @@ -0,0 +1,61 @@ +/* func_PAL_L20_00449870 (1 place), the PAL copy of func_L20_00443DF0 with 50 Hz values: the + per-frame scale 1/6 becomes 1/5 (0x3E4CCCCE, one ulp above 0.2f, written 0.20000002f), the + drop -1/30 becomes -1/25, the spread 90/180 becomes 75/150 and the projectile's 180 and 600 + frames become 150 and 500. -O2 -G0 -ffunction-sections -frac2-hazard-labels, as v1.01's. */ +#include "common.h" + +extern void func_PAL_L20_004495C0(char *, char *, char *, float *); +extern float func_00283B98(float, float); +extern float func_00283180(float); +extern float func_00283198(float); +extern int func_002A77E0(int); +extern void func_00282D30(void *, void *, float); +extern float func_002A7878(float, float); +extern void func_00282CC0(void *, void *, void *); +extern void func_00282CF0(void *, void *, void *); +extern void func_00282F20(void *, void *, float); +extern char *func_L03_003D09D0(int, int, void *, void *, void *, int, int, int); +extern char D_00189EA0[]; + +/* Clamps the aim angle's magnitude into [pi/6, pi/4], keeping its sign, then + launches a projectile along the rotated, flattened offset. Retail's + constants are 0x3F490FDC and 0x3F060A93, one ulp above the nearest floats + to pi/4 and pi/6, so they are written 0.78539825f and 0.52359885f. */ +char *func_PAL_L20_00449870(char *arg0) +{ + char *state = *(char **)(arg0 + 0x68); + float ang[4]; + float v[4]; + float w[4]; + float t; + float f; + + t = 0.78539825f; + func_PAL_L20_004495C0(arg0, (char *)ang, (char *)v, &t); + ang[2] = ang[2] + 1.0f; + if (t < 0.0f) { + if (t > -0.52359885f) + t = -0.52359885f; + else if (t < -0.78539825f) + t = -0.78539825f; + } else { + if (t > 0.78539825f) + t = 0.78539825f; + else if (t < 0.52359885f) + t = 0.52359885f; + } + f = func_00283B98(t, *(float *)(arg0 + 0xF8)); + v[0] = func_00283180(f) * 0.20000002f; + v[1] = func_00283198(f) * 0.20000002f; + v[2] = -0.04f; + if (func_002A77E0(2) != 0) { + func_00282D30(w, v, 75.0f); + } else { + func_00282D30(w, v, func_002A7878(0.4f, 0.6f) * 150.0f); + } + func_00282CC0(w, w, ang); + func_00282CF0(w, D_00189EA0, w); + w[2] = 0.0f; + func_00282F20(w, w, 0.20000002f); + return func_L03_003D09D0((int)arg0, 0, ang, v, w, 0x96, 0x1F4, *(unsigned char *)(state + 0x36)); +} diff --git a/src/pal/levels/shared/L00_002AB0C0-hz.c b/src/pal/levels/shared/L00_002AB0C0-hz.c new file mode 100644 index 000000000..faa2adc95 --- /dev/null +++ b/src/pal/levels/shared/L00_002AB0C0-hz.c @@ -0,0 +1,130 @@ +/* func_PAL_L00_002AB0C0, the PAL copy of func_L00_002AB1D8: the same C, where 0.05f becomes + 0.072000004f; 0.3f becomes 0.43200004f. */ +#include "include_asm.h" + +typedef unsigned char u8; + +#ifndef RAC2_T_RESIDENTSTATE_FD160FB9C +typedef struct { + u8 pad000[0x1b8]; + int f1B8; + u8 pad1bc[0x222 - 0x1bc]; + short s222; + u8 pad224[0xc2c - 0x224]; + int fC2C; + u8 padc30[0x149d - 0xc30]; + u8 b149D; + u8 pad149e[0x2290 - 0x149e]; + u8 *p2290; + int f2294; + u8 pad2298[0x22b8 - 0x2298]; + u8 b22B8; + u8 pad22b9[0x22bb - 0x22b9]; + u8 b22BB; + u8 pad22bc[0x22bf - 0x22bc]; + u8 b22BF; + u8 pad22c0[0x24ec - 0x22c0]; + short s24EC; +} ResidentState_Fd160fb9c; +#endif + +extern ResidentState_Fd160fb9c D_00189E20_16; + +extern float func_00282E48(void *source, void *table); + +extern int func_002ABB78(void *object); + +extern int func_L00_002ADEA0(int index); + +extern void *D_L00_001BF218; + +#ifndef RAC2_T_HEROBLOCK_2AB1D8 +typedef struct { + u8 pad000[0x1e4]; + float f1E4; +} HeroBlock_2ab1d8; +#endif + +extern HeroBlock_2ab1d8 D_00189EA0; + +extern short D_L00_001BF220_2[]; + +#ifndef RAC2_T_FLOATBLOCK_2AB1D8 +typedef struct { + u8 pad000[0x5e0]; + float f5E0; + float f5E4; + u8 pad5e8[0x624 - 0x5e8]; + float f624; + float f628; + u8 pad62c[0x690 - 0x62c]; + float f690; + float f694; + u8 pad698[0x6d4 - 0x698]; + float f6D4; + float f6D8; +} FloatBlock_2ab1d8; +#endif + +extern FloatBlock_2ab1d8 D_L00_0025BE10_1; + +extern int func_L00_002AB108(float *out, float scale, float amount); +void func_PAL_L00_002AB0C0(void) +{ + float ret; + float f1, f20, f21, f22; + int v; + + D_00189E20_16.s24EC = 0; + + if (D_00189E20_16.b22BB == 0) + return; + + if (D_00189E20_16.s222 != 0) + return; + + if (D_00189E20_16.b22BF != 0) + return; + + if (func_L00_002AB108(0, D_00189E20_16.b22B8 != 0 ? 0.7f : 0.57f, 1.3f) == 0) + return; + + if (D_00189E20_16.b22B8 != 0 && D_L00_001BF218 != 0) { + if (func_002ABB78(D_L00_001BF218) != 0) + return; + } + + D_L00_0025BE10_1.f6D4 = 0.072000004f; + D_L00_0025BE10_1.f6D8 = 0.43200004f; + + ret = func_00282E48(&D_00189EA0, D_L00_001BF220_2); + f1 = 1.3f - (ret - D_00189EA0.f1E4); + f22 = f1 * 0.9615385f; + f20 = f22 * (-70.0f * 0.017453294f); + if (-30.0f * 0.017453294f < f20) + f20 = -30.0f * 0.017453294f; + if (f20 < (-70.0f * 0.017453294f)) + f20 = -70.0f * 0.017453294f; + + f21 = 0.0f; + v = func_L00_002ADEA0(0); + if (v == 27 || v == 44) { + float f0 = 40.0f * 0.017453294f; + + f21 = f22 * f0; + if (f0 < f21) + f21 = f0; + } + + D_L00_0025BE10_1.f694 = f20; + D_L00_0025BE10_1.f690 = f21; + + if (D_00189E20_16.b22BB == 2) { + D_L00_0025BE10_1.f624 = D_L00_0025BE10_1.f6D4; + D_L00_0025BE10_1.f628 = D_L00_0025BE10_1.f6D8; + D_L00_0025BE10_1.f5E4 = f20; + D_L00_0025BE10_1.f5E0 = f21; + } + + D_00189E20_16.s24EC = 1; +} diff --git a/src/pal/levels/shared/L00_002AB0C0.c b/src/pal/levels/shared/L00_002AB0C0.c index 328865fe2..877bd62d6 100644 --- a/src/pal/levels/shared/L00_002AB0C0.c +++ b/src/pal/levels/shared/L00_002AB0C0.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_002AB0C0); diff --git a/src/pal/levels/shared/L00_002B3E90-hz.c b/src/pal/levels/shared/L00_002B3E90-hz.c new file mode 100644 index 000000000..6f6eb4c3c --- /dev/null +++ b/src/pal/levels/shared/L00_002B3E90-hz.c @@ -0,0 +1,72 @@ +/* func_PAL_L00_002B3E90, the PAL copy of func_L00_002B3F68: the same C, where 0.022f becomes + 0.031680003f; 0.02f becomes 0.028800001f; 0.01f becomes 0.014400001f; 0.09308424592018127f + becomes 0.11170109f; 0.06399541348218918f becomes 0.0767945f; 0.03199770674109459f becomes + 0.03839725f; 0.27f becomes 0.38880002f; 0.035f becomes 0.050400004f; 0.19489513337612152f + becomes 0.23387417f; 0.017f becomes 0.024480002f; 0.18f becomes 0.2592f; 0.1454441249370575f + becomes 0.17453296f; 0.009f becomes 0.01296f; 0.15f becomes 0.21600002f; 0.07853982597589493f + becomes 0.094247796f. */ +typedef struct { + unsigned char prefix[0x40F]; + unsigned char alternate; + unsigned char gap[0x1EA8]; + unsigned char special; + unsigned char gap2[0x1FF]; + float speed; +} MovementView; +extern char D_00189E20[]; +extern int func_L00_002ADEA0(int index); +extern void func_L00_002B3EF8(int index, float a, float b, float c); + +void func_PAL_L00_002B3E90(void) +{ + float speed = ((MovementView *)D_00189E20)->speed; + float first; + float second; + float third; + if (speed == 1.0f) { + first = 0.031680003f; + } else { + first = speed * 0.028800001f; + if (first > 0.031680003f) + first = 0.031680003f; + if (first < 0.014400001f) + first = 0.014400001f; + } + if (((MovementView *)D_00189E20)->speed == 1.0f) { + third = 0.11170109f; + } else { + third = speed * 0.0767945f; + if (third > 0.11170109f) + third = 0.11170109f; + if (third < 0.03839725f) + third = 0.03839725f; + } + second = 0.38880002f; + if (((MovementView *)D_00189E20)->alternate) { + first = 0.050400004f; + third = 0.23387417f; + } + switch (func_L00_002ADEA0(0)) { + case 16: + case 28: + case 29: + case 30: + case 39: + case 46: + if (((MovementView *)D_00189E20)->special && !((MovementView *)D_00189E20)->alternate) { + if (speed > 0.95f) { + first = 0.024480002f; + second = 0.2592f; + third = 0.17453296f; + } else { + first = speed * 0.01296f; + second = 0.21600002f; + third = speed * 0.094247796f; + } + } + break; + default: + break; + } + func_L00_002B3EF8(0, first, second, third); +} diff --git a/src/pal/levels/shared/L00_002B3E90-sw.c b/src/pal/levels/shared/L00_002B3E90-sw.c index 2fad9c0db..bab21beab 100644 --- a/src/pal/levels/shared/L00_002B3E90-sw.c +++ b/src/pal/levels/shared/L00_002B3E90-sw.c @@ -12,5 +12,4 @@ extern char D_00189E20[]; extern int func_L00_002ADEA0(int index); extern void func_L00_002B3EF8(int index, float a, float b, float c); -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_002B3E90); diff --git a/src/pal/levels/shared/L00_002D4F60.c b/src/pal/levels/shared/L00_002D4F60.c index 9f265ca08..73cb9c764 100644 --- a/src/pal/levels/shared/L00_002D4F60.c +++ b/src/pal/levels/shared/L00_002D4F60.c @@ -124,4 +124,3 @@ void func_PAL_L00_002D52C0(char *arg0) { func_L00_002B0968(arg0); } -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_002D5380); diff --git a/src/pal/levels/shared/L00_002D5380-g8.c b/src/pal/levels/shared/L00_002D5380-g8.c new file mode 100644 index 000000000..d9aa3d8da --- /dev/null +++ b/src/pal/levels/shared/L00_002D5380-g8.c @@ -0,0 +1,70 @@ +/* func_PAL_L00_002D5380, the PAL copy of func_L00_002D4E58: the same C with the callees are PAL's + func_PAL_L00_002D52C0 and func_PAL_L00_002D5150. */ +#include "common.h" + +typedef struct { + unsigned char pad0; + unsigned char initialized; + unsigned char pad2[0x20 - 2]; + float scale[3]; + unsigned char pad2C[0x40 - 0x2C]; +} Manipulator4E58; + +extern unsigned char D_001A7A40[] __attribute__((sda)); +extern float D_L00_001A7CF4 __attribute__((sda)); +extern float D_L00_001A7CF8 __attribute__((sda)); +extern Manipulator4E58 D_L00_001B16D0 __attribute__((sda)); +extern Manipulator4E58 D_L00_001B2D80[]; +extern int D_0018B090[]; +extern void func_0029F978(char *, int, Manipulator4E58 *); +extern void func_PAL_L00_002D52C0(char *); +extern void func_PAL_L00_002D5150(char *); + +/* Sets the two option-dependent scales, attaches manipulator 24 to the object (scaled 0.92, or + 0.97 of the first scale and the first scale itself) unless object kind 0xF6B, then either + runs the one-shot spawn or attaches manipulators 22 and 23 at scale 0.01 and runs + func_PAL_L00_002D5150. */ +void func_PAL_L00_002D5380(char *object, int spawn) +{ + Manipulator4E58 *record; + int i; + + if (D_001A7A40[1]) + D_L00_001A7CF4 = 1.57f; + else + D_L00_001A7CF4 = 0.875f; + if (D_001A7A40[3]) + D_L00_001A7CF8 = 1.8f; + else + D_L00_001A7CF8 = 1.0f; + if (D_L00_001B16D0.initialized == 0) { + func_0029F978(object, 24, &D_L00_001B16D0); + if (*(short *)(object + 0xAA) == 0xF6B) { + D_L00_001B16D0.scale[0] = 0.92f; + D_L00_001B16D0.scale[1] = 0.92f; + D_L00_001B16D0.scale[2] = 0.92f; + } else { + D_L00_001B16D0.scale[0] = D_L00_001A7CF4 * 0.97f; + D_L00_001B16D0.scale[1] = D_L00_001A7CF4 * 0.97f; + D_L00_001B16D0.scale[2] = D_L00_001A7CF4; + } + } + if (*(short *)(object + 0xAA) == 0xF6B) + return; + if (spawn) { + func_PAL_L00_002D52C0(object); + return; + } + if (D_0018B090[0]) { + record = D_L00_001B2D80; + for (i = 0; i < 2; i++, record++) { + if (record->initialized == 0) { + func_0029F978(object, i + 22, record); + record->scale[0] = 0.01f; + record->scale[1] = 0.01f; + record->scale[2] = 0.01f; + } + } + } + func_PAL_L00_002D5150(object); +} diff --git a/src/pal/levels/shared/L00_003B14C8.c b/src/pal/levels/shared/L00_003B14C8.c index 2f10497e9..889d291e8 100644 --- a/src/pal/levels/shared/L00_003B14C8.c +++ b/src/pal/levels/shared/L00_003B14C8.c @@ -4,6 +4,5 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L00_003B14C8); INCLUDE_ASM("asm/pal/levels", func_PAL_L00_003B16B8); -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_003B1D70); INCLUDE_ASM("asm/pal/levels", func_PAL_L00_003B2120); diff --git a/src/pal/levels/shared/L00_003B1D70.c b/src/pal/levels/shared/L00_003B1D70.c new file mode 100644 index 000000000..c3db05314 --- /dev/null +++ b/src/pal/levels/shared/L00_003B1D70.c @@ -0,0 +1,141 @@ +/* func_PAL_L00_003B1D70, the PAL copy of func_L00_003AE550: the same C, where 120 becomes 100; + 0.0027222224f becomes 0.00392f. */ +#include "include_asm.h" +#include "common.h" + +extern void func_00282CF0(void *, void *, void *); +extern void func_00282CC0(void *, void *, void *); + +typedef float ArcVector[4] __attribute__((aligned(16))); +typedef int ArcQuad __attribute__((mode(TI))); +typedef struct { + char pad0[0x80]; + ArcVector pos; + char pad90[0x80]; + ArcVector displacement; + char pad120[0x21C]; + char *ground; + char pad340[0x420]; + float facingX; + float facingY; + char pad768[0x1B28]; + char *moby; + int state; +} ArcHero; +typedef struct { + char pad[0x18]; + char *hit; + int count; + ArcVector point; + ArcVector unknown30; + ArcVector normal; +} ArcCollision; +extern ArcHero D_00189E20; +extern int D_L00_001A8F00 MACRO_ADDR; +extern ArcCollision D_L00_001BF200; +extern float D_L00_001B8DC0[]; +extern float func_00283248(float, float); +extern float func_00283B98(float, float); +extern float func_00283180(float); +extern float func_00283198(float); +extern int func_002AD0B0(void *); +extern int func_002761F8(void *, void *, int, void *, int); +extern int func_00278E78(void); +extern int func_00282948(int *); +extern void func_L00_002E6CF0(void *, void *); +extern void func_L00_003AD7C8(void *); +extern void func_00282D30(void *, void *, float); + +/* Steps a thrown object's arc until it lands and records the impact point; + RAC1's predict_mine_impact (overlays/shared/bolts_and_wrench.c) is the same routine. */ +int func_PAL_L00_003B1D70(char *motion, char *object, int mode) +{ + ArcVector position; + ArcVector velocity; + ArcVector previous; + ArcVector probe; + int timer; + ArcHero *hero = &D_00189E20; + int i; + char *vars; + + if (hero->state == 0x6F) + return 0; + if (D_L00_001A8F00 != 0) + return 0; + qcopy(previous, object + 0x10); + if (*(unsigned char *)(object + 0x20) == 1) { + position[0] = func_00283180(func_00283B98(-0.36196801f, func_00283248(hero->facingX, hero->facingY))) * 0.859039f; + position[1] = func_00283198(func_00283B98(-0.36196801f, func_00283248(hero->facingX, hero->facingY))) * 0.859039f; + *(int *)&position[2] = 0; + func_00282CC0(position, position, hero->pos); + position[2] = position[2] + 0.49082f; + qcopy(velocity, motion); + if (hero->ground != 0 && func_002AD0B0(hero->ground) != 0 && mode != 0) { + func_00282CC0(velocity, velocity, hero->displacement); + } + timer = 100; + } else { + vars = *(char **)(*(char **)(motion + 0x30) + 0x68); + qcopy(position, object + 0x10); + qcopy(velocity, motion); + { + short frames = *(short *)(motion + 0x34); + int flag = *(int *)(vars + 0x50); + + timer = frames; + if (flag != 0) + *(short *)(motion + 0x36) = 1; + } + } + { + ArcHero *player = &D_00189E20; + char *moby = player->moby; + + *(ArcQuad *)probe = *(ArcQuad *)(moby + 0x10); + probe[2] = position[2]; + if (func_002761F8(probe, position, 0x10, moby, 0) != 0) { + if (func_00278E78() != 0 && D_L00_001BF200.count > 0) { + qcopy(motion + 0x10, D_L00_001BF200.point); + } + } + } + while (func_00282948(&timer) == 0) { + qcopy(previous, position); + i = 9; + do { + func_00282CC0(position, position, velocity); + velocity[2] = velocity[2] - 0.00392f; + } while (--i >= 0); + if (func_002761F8(previous, position, 0x12, object, 0) == 0) + continue; + if (func_00278E78() == 0 && 0.0f < velocity[2]) + continue; + if (D_L00_001BF200.count > 0) { + qcopy(motion + 0x10, D_L00_001BF200.point); + break; + } + } + if (timer != 0) { + if (mode == 0) { + if (D_L00_001BF200.hit == 0) + return 0; + if (func_002AD0B0(D_L00_001BF200.hit) == 0) + return 0; + } + if (mode != 2 || D_L00_001BF200.hit == 0 || func_002AD0B0(D_L00_001BF200.hit) == 0) { + func_L00_002E6CF0(func_L00_003AD7C8, object); + } + { + float *camera = D_L00_001B8DC0; + char *impact = motion + 0x10; + + *(ArcQuad *)(motion + 0x20) = *(ArcQuad *)D_L00_001BF200.normal; + func_00282CF0(previous, impact, camera); + func_00282D30(previous, previous, 0.95f); + func_00282CC0(impact, previous, camera); + } + return 1; + } + return 0; +} diff --git a/src/pal/levels/shared/L00_003BF2F8.c b/src/pal/levels/shared/L00_003BF2F8.c index 7a10d36ea..e3388065d 100644 --- a/src/pal/levels/shared/L00_003BF2F8.c +++ b/src/pal/levels/shared/L00_003BF2F8.c @@ -3,4 +3,3 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L00_003BF548); -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_003BFBD8); diff --git a/src/pal/levels/shared/L00_003BFBD8-nointerblock-g8.c b/src/pal/levels/shared/L00_003BFBD8-nointerblock-g8.c new file mode 100644 index 000000000..e7cbf0a24 --- /dev/null +++ b/src/pal/levels/shared/L00_003BFBD8-nointerblock-g8.c @@ -0,0 +1,48 @@ +/* func_PAL_L00_003BFBD8, the PAL copy of func_L00_003BBF48: the same C with the callee is PAL's + func_PAL_L00_003BFEB8. */ +#include "include_asm.h" +#include "common.h" + +extern char D_L00_0023DDA0[] __attribute__((nosda)); + +extern void func_PAL_L00_003BFEB8(char *a0, char *a1); + +extern int func_002A7820(int a, int b); + +extern float func_002A7940(void); + +extern void func_00281EB8(char *a, int b, unsigned int c, int d, float e, float f, float g); + +/* Walks the level's table of records and draws the two sprites of the record the owner + holds, when that record is still free. The record's own field is the owner, the one + after it says whether it is free. Without interblock scheduling the two skips stay likely + branches. Each sprite's colour is its own local: one shared variable dies twice, becomes a + global pseudo, and the shifted alpha no longer ties to its saved register. */ +void func_PAL_L00_003BFBD8(char *a0) +{ + unsigned int firstRGB = 0x103080; + unsigned int secondRGB = 0xFFFFFF; + char *base = D_L00_0023DDA0; + char *p = base + 0x30; + char *q = base; + int i; + int color; + int color2; + float f; + + for (i = 29; i >= 0; p += 0xA0, i--, q += 0xA0) { + if (*(int *)(p + 0x5C) == (int)a0) { + func_PAL_L00_003BFEB8(a0, q); + if (*(int *)(p + 0x64) == 0) { + color = func_002A7820(0x50, 0x60); + color = (int)(color << 24) | firstRGB; + f = func_002A7940(); + func_00281EB8(p, 0x31, color, 1, 0.5f, 0.15f, f); + color2 = func_002A7820(0x50, 0x60); + color2 = (int)(color2 << 24) | secondRGB; + f = func_002A7940(); + func_00281EB8(p, 0x31, color2, 1, 0.3f, 0.151f, f); + } + } + } +} diff --git a/src/pal/levels/shared/L00_003F9B90-g8.c b/src/pal/levels/shared/L00_003F9B90-g8.c new file mode 100644 index 000000000..b38080a27 --- /dev/null +++ b/src/pal/levels/shared/L00_003F9B90-g8.c @@ -0,0 +1,49 @@ +/* func_PAL_L00_003F9B90, the PAL copy of func_L00_003F5750: the same C, where 0.016666668f becomes + 0.020000001f. */ +#include "include_asm.h" +#include "common.h" + +extern char *func_L00_0032A088(int a0, int a1); + +extern void func_L00_003F5870(char *rec, int index); + +extern float func_00283CE0(int); +extern float func_002ABB18(float); +extern float func_002A7878(float,float); +extern float func_002A78D8(float,float); +extern float D_L00_001B0940 __attribute__((sda)); +extern float D_L00_001B0944 __attribute__((sda)); +extern float D_L00_001B0948 __attribute__((sda)); +extern float D_L00_001B094C __attribute__((sda)); +extern float D_L00_001B0950 __attribute__((sda)); +extern float D_L00_001B0954 __attribute__((sda)); + +typedef struct { + float offset[4]; + float position[4]; + float angle; + float length; + float f28; + float f2c; +} L00Joint; + +/* Places one joint of a table entry's chain at `position`: its angle, length and two + rates come from level tuning values, then func_L00_003F5870 lays out its offset and + the entry's joint count advances. The record offset is computed once and added to the + reloaded chain pointer at every store, as retail's addu order shows. */ +void func_PAL_L00_003F9B90(char *object, char *position) +{ + char *state = *(char **)(object + 0x68); + char **table = (char **)func_L00_0032A088(0xc04, *(short *)(state + 0x1a)); + short index = *(short *)(state + 0x20); + char **entry; + int offset = index * 0x30; + entry = (char **)((*(short *)(state + 0x18) << 2) + (int)table); + qcopy(((L00Joint *)(offset + (int)*entry))->position, position); + ((L00Joint *)(offset + (int)*entry))->angle = func_002ABB18(func_00283CE0(index) * 0.017453294f * D_L00_001B0948); + ((L00Joint *)(offset + (int)*entry))->f28 = func_002A7878(D_L00_001B0940, D_L00_001B0944) * 0.017453294f; + ((L00Joint *)(offset + (int)*entry))->length = D_L00_001B094C; + ((L00Joint *)(offset + (int)*entry))->f2c = func_002A78D8(D_L00_001B0950, D_L00_001B0954) * 0.020000001f; + func_L00_003F5870(*entry, index); + (*(unsigned short *)(state + 0x20))++; +} diff --git a/src/pal/levels/shared/L00_003F9B90.c b/src/pal/levels/shared/L00_003F9B90.c index 3fcfda8f3..877bd62d6 100644 --- a/src/pal/levels/shared/L00_003F9B90.c +++ b/src/pal/levels/shared/L00_003F9B90.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_003F9B90); diff --git a/src/pal/levels/shared/L00_00403200.c b/src/pal/levels/shared/L00_00403200.c index 9f95a6127..c29dbed9f 100644 --- a/src/pal/levels/shared/L00_00403200.c +++ b/src/pal/levels/shared/L00_00403200.c @@ -1,7 +1,6 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_004033A8); diff --git a/src/pal/levels/shared/L00_004033A8-eac8-g8.c b/src/pal/levels/shared/L00_004033A8-eac8-g8.c new file mode 100644 index 000000000..bb97d9b6c --- /dev/null +++ b/src/pal/levels/shared/L00_004033A8-eac8-g8.c @@ -0,0 +1,46 @@ +/* func_PAL_L00_004033A8, the PAL copy of func_L00_003FEAC8: the same C with the 30-frame lifetime + becomes 25; the callees are PAL's func_PAL_L00_00403480 and func_PAL_L00_003AD088. */ +#include "common.h" + +typedef struct { + u8 pad00[0x70]; + float scale; + u8 pad74[0xE0 - 0x74]; +} TableEntry_L00_003FEAC8; + +typedef struct { + u8 pad00[0x10]; + char *spawned[1]; +} SpawnSlots_L00_003FEAC8; + +extern u8 D_00139581[]; +extern TableEntry_L00_003FEAC8 D_L00_00262570[]; +extern float D_L00_001B0C14 __attribute__((sda)); + +extern void ref_L00_003FEAC8_00(void *unused, void *pos, void *direction); +extern float ref_L00_003FEAC8_01(void *vec); +extern int ref_L00_003FEAC8_02(int min, int max); +extern char *ref_L00_003FEAC8_03(void *pos, void *direction, void *owner, float length, float scale, int count, float param); + +/* Sparks along direction from pos, then spawns an object there, stores it in the owner's + slot and links it back to the owner. */ +void func_PAL_L00_004033A8(char *obj, char *pos, void *direction, int slot) +{ + SpawnSlots_L00_003FEAC8 *slots = *(SpawnSlots_L00_003FEAC8 **)(obj + 0x68); + float dir[4] __attribute__((aligned(16))); + float scale; + TableEntry_L00_003FEAC8 *entry; + float length; + char *spawned; + + qcopy(dir, direction); + entry = D_L00_00262570 + D_00139581[0]; + scale = entry->scale; + ref_L00_003FEAC8_00(obj, pos, direction); + length = ref_L00_003FEAC8_01(dir); + spawned = ref_L00_003FEAC8_03(pos, dir, obj, length, scale, ref_L00_003FEAC8_02(1, 25), D_L00_001B0C14); + slots->spawned[slot] = spawned; + if (spawned != 0) { + *(char **)(spawned + 0xB8) = obj; + } +} diff --git a/src/pal/levels/shared/L00_00430188.c b/src/pal/levels/shared/L00_00430188.c index b583c0075..640866439 100644 --- a/src/pal/levels/shared/L00_00430188.c +++ b/src/pal/levels/shared/L00_00430188.c @@ -38,4 +38,3 @@ void func_PAL_L00_00430188(char *self) { } -INCLUDE_ASM("asm/pal/levels", func_PAL_L00_00430308); diff --git a/src/pal/levels/shared/L00_00430308.c b/src/pal/levels/shared/L00_00430308.c new file mode 100644 index 000000000..4fae699f0 --- /dev/null +++ b/src/pal/levels/shared/L00_00430308.c @@ -0,0 +1,46 @@ +/* func_PAL_L00_00430308, the PAL copy of func_L00_0042AD98: the same C with the seconds-to-frames + factor 60 becomes 50. */ +/* Clamp the listener position to the emitter box and update its sound slot. */ +#include "common.h" +extern char D_L00_001B8C80_1[]; +extern void func_00282CF0(char *, char *, char *); +extern void func_00282CC0_4(char *, char *, char *); +extern float func_00282C48(float); +extern void func_00283098(char *, char *, char *); +extern int func_00282948(char *); +extern int func_L00_0035F640(int, int, char *, int); +extern int func_002A77E0(int); +extern char D_00188660[]; +extern char (*D_L00_001B19EC)[32] __attribute__((section(".sdata"))); +void func_PAL_L00_00430308(char *a) +{ + float v[4] __attribute__((aligned(16))); + float local[4] __attribute__((aligned(16))); + int *state = *(int **)(a + 8); + int kind = 8; + char *sound; + func_00282CF0((char *)v, D_L00_001B8C80_1 + 0x140, a + 0x40); + v[3] = 0; + func_00283098((char *)local, (char *)v, a + 0x50); + if (func_00282C48(local[0]) <= 1.0f && func_00282C48(local[1]) <= 1.0f && func_00282C48(local[2]) <= 1.0f) { + qcopy(v, D_L00_001B8C80_1 + 0x140); + } else { + if (local[0] > 1.0f) local[0] = 1.0f; + else if (local[0] < -1.0f) local[0] = -1.0f; + if (local[1] > 1.0f) local[1] = 1.0f; + else if (local[1] < -1.0f) local[1] = -1.0f; + if (local[2] > 1.0f) local[2] = 1.0f; + else if (local[2] < -1.0f) local[2] = -1.0f; + func_00283098((char *)v, (char *)local, a + 0x10); + func_00282CC0_4((char *)v, (char *)v, a + 0x40); + } + sound = D_00188660 + state[4] * 0x70; + if (*(unsigned char *)(D_L00_001B19EC[state[0]] + 0x18)) kind = 12; + if (*(char **)(sound + 0x8C) != a || *(unsigned char *)(sound + 0x74) == 0) { + if (func_00282948((char *)&state[3])) { + state[4] = func_L00_0035F640(state[0], kind, a, 0x400); + if (state[2] > 0) state[3] = (int)((state[1] + func_002A77E0(state[2] - state[1])) * 50.0f); + } else state[4] = -1; + } + if (state[4] != -1) qcopy(D_00188660 + 0x90 + state[4]*0x70, v); +} diff --git a/src/pal/levels/shared/L01_002A8368.c b/src/pal/levels/shared/L01_002A8368.c index 1621f7ebd..2d970b248 100644 --- a/src/pal/levels/shared/L01_002A8368.c +++ b/src/pal/levels/shared/L01_002A8368.c @@ -81,7 +81,6 @@ extern void func_002A677C(int a0); extern void func_L01_002A9298(void); extern void func_L00_002A9760(void); -INCLUDE_ASM("asm/pal/levels", func_PAL_L01_002A8B30); diff --git a/src/pal/levels/shared/L01_002A8B30.c b/src/pal/levels/shared/L01_002A8B30.c new file mode 100644 index 000000000..52515e7f0 --- /dev/null +++ b/src/pal/levels/shared/L01_002A8B30.c @@ -0,0 +1,122 @@ +/* func_PAL_L01_002A8B30, the PAL copy of func_L01_002A8C48: the same C, where func_L01_002A84D8 + becomes func_PAL_L01_002A8368; func_L00_002B36E0 becomes func_PAL_L00_002B3608; + func_L01_002AE128 becomes func_PAL_L01_002AE010; func_L01_002C37C8 becomes + func_PAL_L01_002C3A10; func_L00_002AC1A0 becomes func_PAL_L00_002AC088; func_L00_002AB1D8 + becomes func_PAL_L00_002AB0C0; func_L00_002AB420 becomes func_PAL_L00_002AB308; + func_L00_002ABBA0 becomes func_PAL_L00_002ABA88; func_L00_002AB948 becomes + func_PAL_L00_002AB830; func_L00_002A5518 becomes func_PAL_L00_002A53A8; func_L00_002A5840 + becomes func_PAL_L00_002A56D0; func_L00_002B7718 becomes func_PAL_L00_002B7688; + func_L00_002B2120 becomes func_PAL_L00_002B2018; func_L00_002B2318 becomes + func_PAL_L00_002B2230; func_L00_002B2200 becomes func_PAL_L00_002B20F8; func_L00_002A67F8 + becomes func_PAL_L00_002A6688; func_L00_002D5EB8 becomes func_PAL_L00_002D6408; + func_L00_002A6420 becomes func_PAL_L00_002A62B0; func_L00_002D5158 becomes + func_PAL_L00_002D5680. */ + +#include "common.h" + +extern char D_00189E20[]; +extern int D_L01_001A8F40 MACRO_ADDR; +extern char D_00189EA0[]; + +extern void func_PAL_L01_002A8368(void); +extern void func_2C7CA8(void); +extern void func_PAL_L00_002B3608(void); +extern void func_L01_002ADDC8(void); +extern void func_PAL_L01_002AE010(char *a0, char *a1, char *a2); +extern void func_PAL_L01_002C3A10(void); +extern void func_2C8628(void); +extern void func_L00_002D3068(void); +extern void func_2AEB80(void); +extern void func_2B9878(void); +extern void func_PAL_L00_002AC088(void); +extern void func_PAL_L00_002AB0C0(void); +extern void func_PAL_L00_002AB308(void); +extern void func_PAL_L00_002ABA88(void); +extern void func_PAL_L00_002AB830(void); +extern void func_PAL_L00_002A53A8(void); +extern void func_PAL_L00_002A56D0(void); +extern void func_PAL_L00_002B7688(void); +extern void func_2A7740(void); +extern void func_2AB028(void); +extern void func_L00_002AA178(int a0); +extern void func_PAL_L00_002B2018(void); +extern void func_PAL_L00_002B2230(void); +extern void func_PAL_L00_002B20F8(void); +extern void func_L00_002AFBC0(void); +extern int func_L00_002D6418(void); +extern void func_2A9520(void); +extern void func_2A9310(void); +extern void func_PAL_L00_002A6688(void); +extern void func_PAL_L00_002D6408(void); +extern void func_PAL_L00_002A62B0(void); +extern void func_PAL_L00_002D5680(void); +extern int func_L00_002A7000(void); +extern void func_L00_003080D0(void *a0); +extern void func_30F444(int a0); +extern void func_L01_002A9298(void); +extern void func_2AB328(void); + +void func_PAL_L01_002A8B30(void) { + char *p; + + p = D_00189E20; + *(short *)(p + 0x2162) = 0; + *(short *)(p + 0x2160) = 0; + if (*(unsigned char *)(p + 0x22B4) != 0) { + func_PAL_L01_002A8368(); + return; + } + func_2C7CA8(); + func_PAL_L00_002B3608(); + func_L01_002ADDC8(); + func_PAL_L01_002AE010(p + 0x80, p + 0x90, p + 0x550); + func_PAL_L01_002C3A10(); + if (D_L01_001A8F40 == 2 || D_L01_001A8F40 == 6) { + if (*(unsigned char *)(p + 0x22B5) != 0) + func_2C8628(); + else + func_L00_002D3068(); + return; + } + func_2AEB80(); + if (*(unsigned char *)(p + 0x22B4) != 0) + return; + func_2B9878(); + func_PAL_L00_002AC088(); + func_PAL_L00_002AB0C0(); + func_PAL_L00_002AB308(); + func_PAL_L00_002ABA88(); + func_PAL_L00_002AB830(); + func_PAL_L00_002A53A8(); + func_PAL_L00_002A56D0(); + func_PAL_L00_002B7688(); + func_2A7740(); + func_2AB028(); + func_L00_002AA178(0); + func_PAL_L00_002B2018(); + func_PAL_L00_002B2230(); + func_PAL_L00_002B20F8(); + func_L00_002AFBC0(); + if (*(unsigned char *)(p + 0x22B5) != 0 || func_L00_002D6418() != 0) + func_2C8628(); + else + func_L00_002D3068(); + func_2A9520(); + func_2A9310(); + func_PAL_L00_002A6688(); + func_PAL_L00_002D6408(); + func_PAL_L00_002A62B0(); + func_PAL_L00_002D5680(); + { + char *q = D_00189E20; + if ((*(int *)(q + 0x229C) != 0x16 && *(int *)(q + 0x229C) != 0x1F + && *(int *)(q + 0x2294) != 0x31) || func_L00_002A7000() != 0) + func_L00_003080D0(D_00189EA0); + } + { + char *q = D_00189E20; + func_30F444(*(int *)(q + 0x2290)); + } + func_L01_002A9298(); + func_2AB328(); +} diff --git a/src/pal/levels/shared/L02_00335630.c b/src/pal/levels/shared/L02_00335630.c index 298d9a589..d5ee6e5cc 100644 --- a/src/pal/levels/shared/L02_00335630.c +++ b/src/pal/levels/shared/L02_00335630.c @@ -10,4 +10,3 @@ void func_PAL_L02_00335630(char *arg0, char *arg1) { func_L02_00333480(arg0, arg1, tmp); } -INCLUDE_ASM("asm/pal/levels", func_PAL_L02_00335678); diff --git a/src/pal/levels/shared/L02_00335678.c b/src/pal/levels/shared/L02_00335678.c new file mode 100644 index 000000000..d0aa0cf3d --- /dev/null +++ b/src/pal/levels/shared/L02_00335678.c @@ -0,0 +1,51 @@ +/* func_PAL_L02_00335678, the PAL copy of func_L02_00333480: the same C with the callee is PAL's + func_PAL_L02_00334C78. */ +#include "include_asm.h" +#include "common.h" + +extern void *func_L00_0032C638(char *); +extern void func_L02_00332900(void); +extern void func_00283698(void *, void *); +extern void func_002AFFD8(char *, char *, int); +extern void func_L00_00325600(void *, void *, void *); +extern void func_00283098(void *, void *, void *); +extern void func_L00_0032C5E8(char *, char *); +extern void func_L02_00333300(char *, char *); +extern void func_PAL_L02_00334C78(char *, char *, void *, void *, void *, void *, void *); +extern void func_L02_00332D28(char *, char *, void *, void *, void *); +extern void func_L02_00332EF0(char *, char *, void *, void *, void *); +extern int D_L02_001B30C8 __attribute__((sda)); + +int func_PAL_L02_00335678(char *object, void *target, void *input) { + float inverse[16], direction[4], rotated[12]; + float previous[4], output0[4], output1[4]; + float *m; + char *data = (char *)func_L00_0032C638(object); + if (!data) + return 8; + if (D_L02_001B30C8 == *(int *)(data + 0xBC)) + return *(int *)(data + 0x94); + func_L02_00332900(); + func_00283698(inverse, object + 0xC0); + m = inverse; + func_002AFFD8(object + 0x10, (char *)direction, 0); + func_L00_00325600(object + 0xC0, direction, rotated); + func_00283098(data + 0xA0, data + 0xA0, rotated); + *(int *)(data + 0x98) = *(int *)(data + 0x94); + *(int *)(data + 0x94) = 0; + func_L00_0032C5E8(object, data); + qcopy_nc(previous, object + 0x10); + if (D_L02_001B30C8 - *(int *)(data + 0xBC) >= 2 || *(int *)(data + 0xBC) == 0) { + func_L02_00333300(object, data); + *(int *)(data + 0x80) = 0; + *(unsigned char *)(data + 0xEA) = 0xFF; + *(int *)(data + 0x9C) &= ~2; + *(int *)(data + 0xB4) = 0; + qzero_nc(data + 0xA0); + } + *(int *)(data + 0xBC) = D_L02_001B30C8; + func_PAL_L02_00334C78(object, data, target, input, &output0, &output1, m); + func_L02_00332D28(object, data, &previous, &output1, m); + func_L02_00332EF0(object, data, target, &previous, m); + return *(int *)(data + 0x94); +} diff --git a/src/pal/levels/shared/L02_0038CE70-hz.c b/src/pal/levels/shared/L02_0038CE70-hz.c new file mode 100644 index 000000000..6fcb52df5 --- /dev/null +++ b/src/pal/levels/shared/L02_0038CE70-hz.c @@ -0,0 +1,35 @@ +/* func_PAL_L02_0038CE70, the PAL copy of func_L02_00389F70: the same C with the callee is PAL's + func_PAL_002B1588. */ +#include "include_asm.h" + +extern int D_L02_001A9048 __attribute__((sda)); +extern int D_001A79F0 __attribute__((sda)); +extern unsigned char D_001A7A6B __attribute__((nosda)); +extern int D_L02_001A903C __attribute__((sda)); + +extern int func_002E5E58(int, int, void *); +extern void func_PAL_002B1588(int, int); + +struct TriggerState { + unsigned char pad00[0x20]; + unsigned char initialized; + unsigned char pad21[15]; + unsigned char state; +}; + +void func_PAL_L02_0038CE70(struct TriggerState *self) { + if (self->initialized == 0) { + self->state = 0xFF; + self->initialized = 1; + } + if (D_L02_001A9048 < 14) + return; + if (D_001A79F0 != 16) + return; + if (D_001A7A6B != 0) + return; + D_001A7A6B = 1; + func_002E5E58(1, 0, 0); + func_PAL_002B1588(0x1233, -1); + D_L02_001A903C = 1; +} diff --git a/src/pal/levels/shared/L02_0038CE70.c b/src/pal/levels/shared/L02_0038CE70.c index 5d2c9a753..9d4359bd2 100644 --- a/src/pal/levels/shared/L02_0038CE70.c +++ b/src/pal/levels/shared/L02_0038CE70.c @@ -1,4 +1,3 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L02_0038CE70); diff --git a/src/pal/levels/shared/L02_00405E88-spawn.c b/src/pal/levels/shared/L02_00405E88-spawn.c new file mode 100644 index 000000000..d4bda02c0 --- /dev/null +++ b/src/pal/levels/shared/L02_00405E88-spawn.c @@ -0,0 +1,48 @@ +/* func_PAL_L02_00405E88, the PAL copy of func_L02_00401530: the same C with the 270-frame count + becomes 225. */ +#include "common.h" + +typedef int TI128 __attribute__((mode(TI))); + +struct SpawnHeader { + u8 unknown000[0x20]; + u8 mode; + u8 unknown021[11]; + f32 rate; + u8 flags, unknown031; + u16 kind; +}; + +extern char *func_0029EFD0(int); + +extern void func_002A0F48(void *); + +char *func_PAL_L02_00405E88(TI128 *a0, TI128 *a1, TI128 *a2, unsigned char a3, + unsigned char a4, unsigned char a5, float a6, float a7, float a8) { + char *s0; + char *v1; + struct SpawnHeader *header; + + s0 = func_0029EFD0(0xB5A); + if (s0 == 0) + goto end; + qcopy(s0 + 0x10, a0); + header = (struct SpawnHeader *)s0; + header->rate = 0.014999999664723873f; + header->kind = 0xFF; + header->flags = 0xFF; + header->mode = 0; + v1 = *(char **)(s0 + 0x68); + qcopy(v1, a1); + qcopy(v1 + 0x10, a2); + *(int *)(v1 + 0x70) = 0xE1; + *(unsigned char *)(v1 + 0x75) = a3; + *(unsigned char *)(v1 + 0x76) = a4; + *(unsigned char *)(v1 + 0x77) = a5; + *(float *)(v1 + 0x68) = a7; + *(float *)(v1 + 0x6C) = a6; + *(float *)(v1 + 0x64) = a8; + func_002A0F48(s0); +end: + return s0; +} diff --git a/src/pal/levels/shared/L02_00405E88.c b/src/pal/levels/shared/L02_00405E88.c index 97a5f0292..877bd62d6 100644 --- a/src/pal/levels/shared/L02_00405E88.c +++ b/src/pal/levels/shared/L02_00405E88.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L02_00405E88); diff --git a/src/pal/levels/shared/L03_003DC998.c b/src/pal/levels/shared/L03_003DC998.c index 2d7ea8a31..2d0bafb4d 100644 --- a/src/pal/levels/shared/L03_003DC998.c +++ b/src/pal/levels/shared/L03_003DC998.c @@ -40,4 +40,3 @@ void func_PAL_L03_003DD8A8(u8 *p) { } -INCLUDE_ASM("asm/pal/levels", func_PAL_L03_003DDB50); diff --git a/src/pal/levels/shared/L03_003DDB50-g8.c b/src/pal/levels/shared/L03_003DDB50-g8.c new file mode 100644 index 000000000..c44f3c7ef --- /dev/null +++ b/src/pal/levels/shared/L03_003DDB50-g8.c @@ -0,0 +1,37 @@ +/* func_PAL_L03_003DDB50, the PAL copy of func_L03_003D9820: the same C with the 90-frame timer + becomes 75. */ +#include "common.h" + +typedef struct { + f32 velocity[4]; + s16 timer; + s16 count; + u8 *owner; + s32 value; +} SpawnVars; + +extern u8 *func_0029EFD0(s32); +extern void func_002B37E8(u8 *, u8 *); +extern f32 func_00283248(f32, f32); +extern f32 func_00282E20(void *); +extern f32 D_L03_001B08D8 __attribute__((sda)); + +u8 *func_PAL_L03_003DDB50(u8 *owner, void *position, f32 *velocity, s32 value) +{ + u8 *object = func_0029EFD0(0xA72); + SpawnVars *vars; + if (object != 0) { + vars = *(SpawnVars **)(object + 0x68); + func_002B37E8(object, owner); + qcopy(object + 0x10, position); + *(f32 *)(object + 0xF8) = func_00283248(velocity[0], velocity[1]); + *(f32 *)(object + 0xF4) = -func_00283248(func_00282E20(velocity), velocity[2]); + qcopy(vars, velocity); + vars->value = value; + vars->timer = 0x4B; + vars->owner = owner; + vars->count = 0; + *(f32 *)(object + 0x2C) = *(f32 *)(*(u8 **)(object + 0x24) + 0x24) * D_L03_001B08D8; + } + return object; +} diff --git a/src/pal/levels/shared/L04_0033EB40-movement.c b/src/pal/levels/shared/L04_0033EB40-movement.c new file mode 100644 index 000000000..5ebe54964 --- /dev/null +++ b/src/pal/levels/shared/L04_0033EB40-movement.c @@ -0,0 +1,100 @@ +/* func_PAL_L04_0033EB40, the PAL copy of func_L04_0033CC00: the same C with the per-frame values + scale by (60/50)^2: the fall step 0.0025 becomes 0.0036000002f (0x3B6BEDFB) and the -0.01 drop + speed -0.012. */ +#include "common.h" + +extern void func_00282CC0(void *, void *, void *); +extern void func_00282F20(float *, float *, float); +extern void func_00282CF0(float *, float *, float *); +extern void func_00282D30(void *, void *, float); + +extern float func_00282E20(void *); +extern float func_00283180(float); +extern float func_00283198(float); +extern float func_00283248(float,float); +extern int func_L04_0033C420(void *,void *,int,float,float); +extern int func_L04_0033CB08(float,void *,void *,int,float,int); +extern float func_002A89A8(void *,int,float); +typedef struct { float fields[16]; float normal[4]; } CollisionResult; +extern CollisionResult D_L04_001BFAC0; +typedef union { int q __attribute__((mode(TI))); float f[4]; } CollisionVec; +#define F(p,o) (*(float *)((char *)(p)+(o))) +typedef union { float f[20]; int i[20]; } MovementConfig; +/* Accelerates obj toward target, probes the ground ahead and returns the collision flags. */ +int func_PAL_L04_0033EB40(char *obj,MovementConfig *cfg,float *target,void *out,float scale) +{ + CollisionVec old; + float move[4] __attribute__((aligned(16))); + float test[4] __attribute__((aligned(16))); + float probe[4] __attribute__((aligned(16))); + float accel=cfg->f[0x1C/4]*scale; + float max=cfg->f[0x24/4]*scale; + float distance,step,height,first,second,speed; + int flags=0,result; + func_00282CF0(move,target,(float *)(obj+0x10)); + distance=func_00282E20(move); + old.q=((CollisionVec *)(obj+0x10))->q; + step=accel*distance; + if (accelf[0x10/4]+=step; + if (distancef[0x10/4]*10.0f) cfg->f[0x10/4]-=cfg->f[0x20/4]*cfg->f[0x10/4]; + if (maxf[0x10/4]) cfg->f[0x10/4]=max; + else if (cfg->f[0x10/4]<-max) cfg->f[0x10/4]=-max; + if (cfg->i[0x38/4]&4) { + move[0]=func_00283180(cfg->f[0x4C/4])*cfg->f[0x10/4]; + move[1]=func_00283198(cfg->f[0x4C/4])*cfg->f[0x10/4]; + } else { + move[0]=func_00283180(F(obj,0xF8))*cfg->f[0x10/4]; + move[1]=func_00283198(F(obj,0xF8))*cfg->f[0x10/4]; + } + if (cfg->i[0x38/4]&1) move[2]=0; + else { move[2]=cfg->f[0x18/4]; cfg->f[0x18/4]-=0.0036000002f; } + height=F(obj,0x18)+0.04f; + func_00282CC0(test,obj+0x10,move); + test[2]=F(obj,0x18)-cfg->f[0x30/4]; + if (func_L04_0033C420(test,obj,cfg->i[0x38/4]&0x20,cfg->f[8/4],cfg->f[12/4])) { + step=func_00283248(D_L04_001BFAC0.normal[2],func_00282E20(D_L04_001BFAC0.normal)); + first=D_L04_001BFAC0.fields[10]; + if (step>0.5f) { + if (func_00282E20(move)>0.1f) { + func_00282F20(probe,move,0.57f); + func_00282CC0(probe,probe,obj+0x10); + probe[2]=F(obj,0x18)-cfg->f[0x30/4]; + if (func_L04_0033C420(probe,obj,cfg->i[0x38/4]&0x20,cfg->f[8/4],cfg->f[12/4])) { + second=D_L04_001BFAC0.fields[10]; + if (func_00283248(D_L04_001BFAC0.normal[2],func_00282E20(D_L04_001BFAC0.normal))>=0.5f) { + flags=0x22; + if ((cfg->i[0x38/4]&8) && secondi[0x38/4]&8) && firsti[0x38/4]&8) flags=8; + } + if (!(flags&2)) { + speed=func_00282E20(move); + func_00282D30(test,move,1.0f/speed); + result=func_L04_0033CB08(cfg->f[4/4],obj,move,cfg->i[0/4],cfg->f[0x30/4],cfg->i[0x38/4]); + if (result&2) cfg->f[0x18/4]=-0.012f; + if (result&1) { + flags|=1; + if (move[0]*test[0]+move[1]*test[1]f[8/4]f[12/4]q=old.q; + } + } + } + qcopy(out,move); + } else if ((cfg->i[0x38/4]^1)&1) cfg->f[0x18/4]=-0.012f; + if (distancef[0x2C/4]) flags|=4; + return flags; +} diff --git a/src/pal/levels/shared/L04_0033EB40.c b/src/pal/levels/shared/L04_0033EB40.c index 19614676e..9d4359bd2 100644 --- a/src/pal/levels/shared/L04_0033EB40.c +++ b/src/pal/levels/shared/L04_0033EB40.c @@ -1,4 +1,3 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L04_0033EB40); diff --git a/src/pal/levels/shared/L04_0040B520.c b/src/pal/levels/shared/L04_0040B520.c index 3ed1e4f20..b9d1c0350 100644 --- a/src/pal/levels/shared/L04_0040B520.c +++ b/src/pal/levels/shared/L04_0040B520.c @@ -2,7 +2,6 @@ INCLUDE_ASM("asm/pal/levels", func_PAL_L04_0040B520); -INCLUDE_ASM("asm/pal/levels", func_PAL_L04_0040B8B8); #include "common.h" extern void func_00282CF0(void *, void *, void *); diff --git a/src/pal/levels/shared/L04_0040B8B8-trail.c b/src/pal/levels/shared/L04_0040B8B8-trail.c new file mode 100644 index 000000000..d99143873 --- /dev/null +++ b/src/pal/levels/shared/L04_0040B8B8-trail.c @@ -0,0 +1,109 @@ +/* func_PAL_L04_0040B8B8, the PAL copy of func_L04_004073E8: the same C with the trail keeps at + most 25 points instead of 30. */ +#include "common.h" + +typedef int Quad __attribute__((mode(TI))); +typedef union { Quad quad; float f[4]; } Vec73E8; +typedef struct { Vec73E8 vertex[4]; u32 color[4]; float uv[8]; u64 primitive, texture, mode, flags; } Packet73E8; +extern char D_001A8F20[] __attribute__((sda)); +extern char D_L04_001B9680[]; +extern void func_00283388(void *); +extern void func_L04_0030EDE0(void *, void *, void *); +extern void func_00282CF0(void *, void *, void *); +extern void func_00282CD8(void *, void *, void *); +extern void func_00282DD8(void *, void *, void *); +extern void func_00282F20(void *, void *, float); +extern float func_00283CE0(int); +extern u64 func_0027C878(int); +extern void func_00280B90(void *, void *, int); + +/* Draws the trail behind the object: up to 30 points, each the previous one less the drifting + offset at +0x00 of the state, and two strips of quads on both sides of them, widening from 0 + at the head to the width at +0x3C, fading out to the tail. + + The spelling of each access picks retail's addresses: `p + i` keeps the frame offset out of + the index sum, `&p[i + 1]` folds it into the base, and one `side` array (left edge, then right + edge) shares its base, so the right-edge store joins the points' induction variable. */ +void func_PAL_L04_0040B8B8(u8 *obj) +{ + Packet73E8 pkt; + float cam[12]; + Vec73E8 head; + Vec73E8 pts[30]; + Vec73E8 side[60]; /* [0, 30): left edge, [30, 60): right edge */ + Vec73E8 off; + Vec73E8 eye; + Vec73E8 normal; + Vec73E8 tangent; + Vec73E8 d; + u8 *st = *(u8 **)(obj + 0x68); + int n; + int i; + int j; + int k; + float t; + u32 c; + + if (*(short *)(st + 0x32) < 3) + return; + func_00283388(cam); + head.quad = *(Quad *)D_001A8F20; + n = *(short *)(st + 0x32); + if (n > 25) + n = 25; + pts[0].quad = *(Quad *)(obj + 0x10); + off.quad = *(Quad *)st; + for (j = 1; j < n; j++) { + (pts + j)->quad = pts[j - 1].quad; + off.f[2] += *(float *)(st + 0x38); + func_L04_0030EDE0(&eye, &pts[j], &off); + } + for (i = 0; i < n - 1; i++) { + Vec73E8 *l = &side[i]; + + t = func_00283CE0(n - i) / func_00283CE0(n); + if (t > 1.0f) + t = 1.0f; + t *= *(float *)(st + 0x3C); + if (i == 0) + t = 0.0f; + func_00282CF0(&d, &pts[i + 1], &pts[i]); + tangent.quad = d.quad; + func_00282CF0(&d, D_L04_001B9680, &pts[i]); + eye.quad = d.quad; + func_00282DD8(&normal, &eye, &tangent); + func_00282F20(l, &normal, t); + func_00282CF0(&d, &pts[i], l); + side[i + 30].quad = d.quad; + func_00282CD8(&d, l, &pts[i]); + } + pkt.texture = func_0027C878(0x16); + pkt.mode = 0xFF9000000260ULL; + pkt.flags = 0x8000000048ULL; + pkt.primitive = 0; + pkt.uv[0] = 0.5f; + pkt.uv[2] = 0.7f; + pkt.uv[4] = 0.5f; + pkt.uv[6] = 0.7f; + for (k = 0; k < n - 2; k++) { + pkt.uv[1] = func_00283CE0(k) / func_00283CE0(n); + pkt.uv[3] = func_00283CE0(k) / func_00283CE0(n); + pkt.uv[5] = func_00283CE0(k + 1) / func_00283CE0(n); + pkt.uv[7] = func_00283CE0(k + 1) / func_00283CE0(n); + c = ((n - k) * 0x60 / n) << 24 | 0x30FF; + pkt.color[3] = 0x8080; + pkt.color[1] = 0x8080; + pkt.color[2] = c; + pkt.color[0] = c; + pkt.vertex[0].quad = (pts + k)->quad; + pkt.vertex[1].quad = (side + k)->quad; + pkt.vertex[2].quad = (&pts[k + 1])->quad; + pkt.vertex[3].quad = (&side[k + 1])->quad; + func_00280B90(&pkt, cam, 0); + pkt.vertex[0].quad = (pts + k)->quad; + pkt.vertex[1].quad = (side + k + 30)->quad; + pkt.vertex[2].quad = (&pts[k + 1])->quad; + pkt.vertex[3].quad = (&side[k + 31])->quad; + func_00280B90(&pkt, cam, 0); + } +} diff --git a/src/pal/levels/shared/L05_0037C968-g8.c b/src/pal/levels/shared/L05_0037C968-g8.c new file mode 100644 index 000000000..7d73d6821 --- /dev/null +++ b/src/pal/levels/shared/L05_0037C968-g8.c @@ -0,0 +1,100 @@ +/* func_PAL_L05_0037C968, the PAL copy of func_L05_0037A218: the same C, where 30 becomes 25; + func_L05_0037AC80 becomes func_PAL_L05_0037D3D0; func_L05_0037DA58 becomes + func_PAL_L05_00380258. */ +#include "common.h" +typedef struct { + float position[4], previous[4], origin[4], target[4], velocity[4]; + u8 *object; + float distance; + int flags,color,effect,mode; + float rate,spin,life; + u8 pad74[12]; +} L05Projectile; +extern L05Projectile D_L05_00221DD0[]; +extern int D_L05_00221D10[]; +extern void *D_L05_00225DD0[]; +extern void (*D_L05_00225ED0[])(void *); +extern int D_L05_001A8F00; +extern int D_L05_001AC4D4 __attribute__((sda)); +extern int D_001A79F0 __attribute__((sda)); +extern u8 D_00188660[]; +typedef struct { u8 pad[0x160]; float slow; int pad164,frames,flags; } L05ImpactState; +extern L05ImpactState D_L05_001B9580; +typedef struct { int on; int pad; float pos[4]; } L05Hit; +extern L05Hit D_L05_001BFB18; +extern u8 D_L05_001A8F20[] MACRO_ADDR; +extern int func_L00_004272A0(void); +extern s32 func_002ED688(u8 *); +extern float func_002A7878(float,float); +extern void func_00282F20(void *,void *,float); +extern void func_00282CC0(void *,void *,void *); +extern float func_00282E48(void *,void *); +extern int func_002A77E0(int); +extern int func_002E5DA0(int,int,char *,int); +extern void func_PAL_L05_0037D3D0(float); +extern int func_00283DB8(void *,float); +extern int func_002761F8(void *,void *,int,void *,void *); +extern void func_PAL_L05_00380258(void *,int,int,int); +extern void func_002A8F70(void *,void *,int,void *,void *,float); +extern float func_002A7940(void); +extern void func_00281EB8(void *,int,int,int,float,float,float); +extern void func_L05_0037D7D8(void *,void *,u32,int,float); +/* Update active object callbacks, then advance and resolve the projectile pool. */ +void func_PAL_L05_0037C968(void *unused) +{ + float step[4],check[4]; + float scale,speed,angle; + u8 *state,*target,*sound; + L05Projectile *record; float *pos; + int i,j; + (void)unused; + if (D_L05_001A8F00 == 2) return; + for (i=0;iobject) continue; + pos = record->position; + state = (u8 *)func_002ED688(record->object); + if (D_L05_00221D10[0x2C/4] == 1 || *(int *)(state+0x110) == 0 || record->distance >= 350.0f) { + record->object = 0; + continue; + } + scale = func_002A7878(1.1f,0.6f); + speed = record->life; + func_00282F20(step,record->velocity,scale*speed); + func_00282CC0(record->position,record->position,step); + func_00282CC0(record->previous,record->previous,step); + record->distance += scale*speed; + if (record->flags == 0 && record->mode && func_00282E48(record->position,*(u8 **)(state+0x120)+0x10) < record->rate) { + D_L05_001B9580.frames = 25; + D_L05_001B9580.slow = 0.05f; + D_L05_001B9580.flags = 0; + if (func_002A77E0(6) && (target=*(u8 **)(state+0x120)) && *(s16 *)(target+0xAA) == 0xFBF) { + sound = D_00188660+D_L05_001AC4D4*0x70; + if ((*(u8 **)(sound+0x88) != target || !sound[0x74]) && D_001A79F0 != 10) + D_L05_001AC4D4 = func_002E5DA0(14,0,(char *)target,0xFBF); + } + func_PAL_L05_0037D3D0(1.0f); + record->flags = 1; + record->object = 0; + } + if (record->effect && *(u8 **)(state+0x120) && func_00282E48(record->position,*(u8 **)(state+0x120)+0x10) < 32.0f) { + qcopy(check, pos); + check[3] = 1.0f; + if (func_00283DB8(check,256.0f) != -1 && func_002761F8(record->previous,record->position,0,0,0)) { + func_PAL_L05_00380258(D_L05_001BFB18.pos,20,record->color,60); + if (D_L05_001BFB18.on) + func_002A8F70(*(u8 **)(state+0x120),record->object,0x10000,D_L05_001BFB18.pos,D_L05_001A8F20,0.25f); + record->object = 0; + } + } + angle = func_002A7940(); + func_00281EB8(record->position,0x31,record->color,1,0.35f,0.0f,angle); + func_L05_0037D7D8(record->position,record->previous,0x807F7F7F,14,record->spin*0.05f); + func_L05_0037D7D8(record->position,record->previous,record->color,14,record->spin*0.1f); + } +} diff --git a/src/pal/levels/shared/L05_0037C968.c b/src/pal/levels/shared/L05_0037C968.c index d409c9b71..877bd62d6 100644 --- a/src/pal/levels/shared/L05_0037C968.c +++ b/src/pal/levels/shared/L05_0037C968.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L05_0037C968); diff --git a/src/pal/levels/shared/L05_004319A8.c b/src/pal/levels/shared/L05_004319A8.c index 33ddc0a76..9d4359bd2 100644 --- a/src/pal/levels/shared/L05_004319A8.c +++ b/src/pal/levels/shared/L05_004319A8.c @@ -1,4 +1,3 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L05_00432530); diff --git a/src/pal/levels/shared/L05_00432530-g8.c b/src/pal/levels/shared/L05_00432530-g8.c new file mode 100644 index 000000000..7641e9976 --- /dev/null +++ b/src/pal/levels/shared/L05_00432530-g8.c @@ -0,0 +1,74 @@ +/* func_PAL_L05_00432530, the PAL copy of func_L05_0042C928: the same C, where 0.00029088825f + becomes 0.0003490659f; func_L01_00397950 becomes func_PAL_L01_0039AD60. */ +#include "include_asm.h" +#include "common.h" + +typedef struct ListMoby_0042C928 { + char pad0[0x28]; + struct ListMoby_0042C928 *next; + char pad2C[0x7E]; + short oclass; +} ListMoby_0042C928; +extern u8 D_0019B278[] MACRO_ADDR; +extern int D_001A79F0_1; +extern char *D_0018C0B0 NOT_SDA; +extern float D_L05_001B1748 __attribute__((sda)); +extern float D_L05_001B174C __attribute__((sda)); +extern float D_L05_001B1750 __attribute__((sda)); +extern ListMoby_0042C928 *D_L05_001B1780 __attribute__((sda)); +extern ListMoby_0042C928 *D_L05_001B2528; +extern char *func_0029EFD0(s32 a0); +extern float func_002A7940(void); +extern void func_PAL_L01_0039AD60(char *a0); +extern void func_002A0488(char *a0, s32 a1, s32 a2, s32 a3); + +char *func_PAL_L05_00432530(float *pos, u32 kind, s32 a2, s32 a3) +{ + char *moby; + char *vars; + ListMoby_0042C928 *p; + u8 *collected = D_0019B278; + + if (kind >= 4 || collected[kind + (D_001A79F0_1 << 2)] != 0) + return 0; + moby = func_0029EFD0(0x126C); + if (moby != 0) { + float x, y, z, r; + + vars = *(char **)(moby + 0x68); + *(long *)(moby + 0x38) = *(long *)(D_0018C0B0 + 0x38); + qcopy(moby + 0x10, pos); + *(s16 *)(moby + 0x32) = 0x40; + *(u8 *)(moby + 0x30) = 0x40; + *(u8 *)(moby + 0x31) = 1; + *(u32 *)vars = kind; + qcopy(vars + 0x10, moby + 0x10); + *(float *)(vars + 0x1C) = *(float *)(moby + 0xF8); + *(float *)(moby + 0xF0) = func_002A7940(); + *(float *)(moby + 0xF4) = func_002A7940(); + *(float *)(moby + 0xF8) = func_002A7940(); + r = func_002A7940(); + x = D_L05_001B1748; + y = D_L05_001B174C; + z = D_L05_001B1750; + *(float *)(moby + 0xFC) = r; + *(s32 *)(vars + 8) = a3; + *(s32 *)(vars + 4) = a2; + x *= 0.0003490659f; + y *= 0.0003490659f; + z *= 0.0003490659f; + *(float *)(vars + 0x60) = z; + *(float *)(vars + 0x68) = x; + *(float *)(vars + 0x64) = y; + *(u8 *)(moby + 0x20) = 1; + func_PAL_L01_0039AD60(moby); + func_002A0488(moby, 0x82, 0x82, 0x82); + if (D_L05_001B1780 == 0) { + for (p = D_L05_001B2528; p != 0; p = p->next) { + if (p->oclass == 0xFBF) + D_L05_001B1780 = p; + } + } + } + return moby; +} diff --git a/src/pal/levels/shared/L05_00447F28-g8.c b/src/pal/levels/shared/L05_00447F28-g8.c new file mode 100644 index 000000000..365c972cb --- /dev/null +++ b/src/pal/levels/shared/L05_00447F28-g8.c @@ -0,0 +1,169 @@ +/* func_PAL_L05_00447F28, the PAL copy of func_L05_00441D40: the same C, where 0.016666668f becomes + 0.020000001f. */ +#include "include_asm.h" +#include "common.h" + +extern int D_L05_001B1B20 __attribute__((sda)); + +extern char *D_L05_001B1EC4 MACRO_ADDR; +extern char *D_L05_001B251C MACRO_ADDR; +extern float D_L05_001B1A58 __attribute__((sda)); +extern float D_L05_001B1A5C __attribute__((sda)); +extern float D_L05_001B1A64 __attribute__((sda)); +extern float D_L05_001B1A4C __attribute__((sda)); +extern float D_L05_001B1A50 __attribute__((sda)); +extern float D_L05_001B1A54 __attribute__((sda)); +extern float D_L05_001B1A70 __attribute__((sda)); +extern float D_L05_001B1A6C __attribute__((sda)); + +typedef struct ListMoby_0042C928 { + char pad0[0x28]; + struct ListMoby_0042C928 *next; + char pad2C[0x7E]; + short oclass; +} ListMoby_0042C928; + +extern float D_L05_001B1A10 __attribute__((sda)); +extern float D_L05_001B1A14 __attribute__((sda)); +extern float D_L05_001B1A18 __attribute__((sda)); +extern float D_L05_001B1AC0 __attribute__((sda)); +extern int D_L05_001B1B74 __attribute__((sda)); +extern int D_L05_001B1B78 __attribute__((sda)); +extern void func_00282C88(void *a0); +extern void func_L05_00441EA0(void *a0); +extern void func_L00_002E54E0(float a0); +extern void func_L05_003D1E20(void); +extern void func_L05_00442720(void); + +typedef struct Block_00441D40 { + float f00, f04, f08, f0C, f10, f14; + int f18; + short f1C; + u8 f1E, f1F; + int pad20; + int f24; + char pad28[0x28]; + char v50[0x10]; + char v60[0x10]; + int f70; + float f74; + float f78; +} Block_00441D40; + +typedef struct Tail_00441D40 { + char pad0[4]; + short f04; + short f06; + char pad8[4]; + short f0C; + char padE[2]; + short f10; +} Tail_00441D40; + +typedef struct State_00441D40 { + float pos[3]; + int pad0C; + char v10[0x30]; + int f40; + int f44; + char pad48[8]; + Block_00441D40 blk; + char padCC[8]; + Tail_00441D40 tail; +} State_00441D40; + +typedef struct Entry_00441D40 { + char pad0[0x20]; + int index; + char pad24[0x34]; + int f58; +} Entry_00441D40; + +typedef struct Slot_00441D40 { + char pad0[0x1C]; + Entry_00441D40 *entry; +} Slot_00441D40; + +typedef struct ActorVars_00441D40 { + char pad0[0x38]; + float rate; + char pad3C[0x1D8]; + int f214; +} ActorVars_00441D40; + +typedef struct Actor_00441D40 { + char pad0[0x68]; + ActorVars_00441D40 *vars; + char pad6C[0x94]; +} Actor_00441D40; + +typedef struct Object_00441D40 { + char pad0[0x70]; + State_00441D40 *state; + char pad74[0xA]; + short f7E; + char pad80[4]; + short f84; +} Object_00441D40; + +void func_PAL_L05_00447F28(Object_00441D40 *object) +{ + State_00441D40 *state; + State_00441D40 *state2; + Block_00441D40 *blk; + Tail_00441D40 *tail; + Entry_00441D40 *entry; + ActorVars_00441D40 *vars; + Slot_00441D40 *table; + char *actors; + float rate; + + state = object->state; + state->pos[0] = D_L05_001B1A10; + state->pos[1] = D_L05_001B1A14; + state->pos[2] = D_L05_001B1A18; + func_00282C88(state->v10); + state->f40 = 0; + state->f44 = 0; + + state2 = object->state; + blk = &state2->blk; + blk->f00 = D_L05_001B1A4C; + blk->f04 = D_L05_001B1A50; + blk->f08 = D_L05_001B1A54; + blk->f74 = D_L05_001B1A70; + blk->f78 = D_L05_001B1A6C; + blk->f0C = D_L05_001B1A58; + blk->f10 = D_L05_001B1A5C; + blk->f14 = D_L05_001B1A64; + blk->f70 = 0; + blk->f1C = 0; + blk->f18 = 0; + blk->f24 = 0; + blk->f1E = 0; + blk->f1F = 0; + func_00282C88(state2->blk.v50); + func_00282C88(state2->blk.v60); + func_L05_00441EA0(object); + func_L00_002E54E0(4096.0f); + + table = (Slot_00441D40 *)D_L05_001B1EC4; + actors = D_L05_001B251C; + tail = &object->state->tail; + tail->f06 = 0; + tail->f0C = 0; + tail->f10 = 0; + tail->f04 = 0; + rate = D_L05_001B1AC0 * 0.020000001f; + entry = table[object->f84].entry; + entry->f58 = 0; + vars = ((Actor_00441D40 *)(actors + (entry->index << 8)))->vars; + vars->rate = rate; + vars->f214 = -1; + object->f7E = 0; + D_L05_001B1B20 = 0; + func_L05_003D1E20(); + D_L05_001B1B74 = 0; + D_L05_001B1B78 = 0; + func_L05_00442720(); +} diff --git a/src/pal/levels/shared/L05_00447F28.c b/src/pal/levels/shared/L05_00447F28.c index 420e19461..877bd62d6 100644 --- a/src/pal/levels/shared/L05_00447F28.c +++ b/src/pal/levels/shared/L05_00447F28.c @@ -1,3 +1,2 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L05_00447F28); diff --git a/src/pal/levels/shared/L06_003E7588.c b/src/pal/levels/shared/L06_003E7588.c index 7affffeea..0b251194f 100644 --- a/src/pal/levels/shared/L06_003E7588.c +++ b/src/pal/levels/shared/L06_003E7588.c @@ -1,5 +1,4 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L06_003E8240); diff --git a/src/pal/levels/shared/L06_003E8240-path-g8.c b/src/pal/levels/shared/L06_003E8240-path-g8.c new file mode 100644 index 000000000..e41315e21 --- /dev/null +++ b/src/pal/levels/shared/L06_003E8240-path-g8.c @@ -0,0 +1,89 @@ +/* func_PAL_L06_003E8240, the PAL copy of func_L06_003E4BE0: the same C, where 1.0f / 60.0f becomes + 0.020000001f; 0.00027777778450399637f becomes 0.00040000002f; 0.000004848137291264255f becomes + 6.981318e - 06f; 0.20943954586982727f becomes 0.25132746f; 0.0002908882452175021f becomes + 0.0003490659f. */ +#include "common.h" +typedef int L06Qword __attribute__((mode(TI))); +typedef union { L06Qword bits; float f[4]; } L06Vector; +extern char *D_L06_001FE500[]; +extern u8 D_L06_001DB610[]; +extern char D_00188660[]; +extern float D_L06_001AF528 __attribute__((sda)); +extern float D_L06_001AF52C __attribute__((sda)); +extern float D_L06_001AF530 __attribute__((sda)); +extern float D_L06_001AF534 __attribute__((sda)); +extern float D_L06_001AF538 __attribute__((sda)); +extern float D_L06_001AF53C __attribute__((sda)); +extern float D_L06_001AF540 __attribute__((sda)); +extern void func_00282CF0(void *, void *, void *); +extern void func_00282CC0(void *, void *, void *); +extern float func_00282DF0(void *); +extern float func_00282E20(void *); +extern float func_00282E48(void *, void *); +extern void func_00282F20(void *, void *, float); +extern float func_00283248(float, float); +extern float func_002AA548(void *, void *, float, float, float, float); +extern float func_002AAA00(void *, void *, int, float, float, float, float); +extern int func_002E59B0(void *, int); +extern int func_002E5DA0(int, int, void *, int); +extern void func_002E59F8(int); + +int func_PAL_L06_003E8240(char *moby, int path, int *sound) +{ + L06Vector target, delta; + float height; + char **route = &D_L06_001FE500[path]; + char *st = *(char **)(moby + 0x68); + int done = 0; + float limit, angle; + int handle; + u8 *slot; + float *yaw; + int point = *(int *)(st + 0x64); + char *node = *route; + height = 0; + qcopy(&target, node + point * 16 + 0x10); + *(float *)(st + 0x108) = target.f[2]; + *(float *)(st + 0xEC) = 0; + *(float *)(st + 0xE8) = 0; + func_00282CF0(&delta, &target, moby + 0x10); + if (func_00282DF0(&delta) < D_L06_001AF528 * (0.020000001f) * 2.0f) { + ++*(int *)(st + 0x64); + done = *(int *)(st + 0x64) == *(int *)*route; + } + limit = func_00282E48(moby + 0x10, *route + *(int *)*route * 16); + func_002AA548(&height, st + 0x60, limit, + D_L06_001AF52C * 0.00040000002f, + D_L06_001AF52C * 0.00040000002f, + D_L06_001AF528 * (0.020000001f)); + func_00282F20(&delta, &delta, *(float *)(st + 0x60)); + func_00282CC0(moby + 0x10, &delta, moby + 0x10); + angle = -func_00283248(func_00282E20(&delta), delta.f[2]); + if (angle > 0.2617994248867035f) angle = 0.2617994248867035f; + else if (angle < -0.2617994248867035f) angle = -0.2617994248867035f; + yaw = (float *)(moby + 0xF8); + func_002AAA00(moby + 0xF4, st + 0x6C, 0, angle, + D_L06_001AF538 * 6.981318e-06f, + D_L06_001AF538 * 6.981318e-06f, 0.25132746f); + angle = func_00283248(target.f[0] - *(float *)(moby + 0x10), target.f[1] - *(float *)(moby + 0x14)); + func_002AAA00(yaw, st + 0x68, 0, angle, + D_L06_001AF530 * 6.981318e-06f, + D_L06_001AF530 * 6.981318e-06f, + D_L06_001AF534 * 0.0003490659f); + func_002AAA00(moby + 0xF0, st + 0x70, 0, + *(float *)(st + 0x68) * *(float *)(st + 0x60) * D_L06_001AF540, + D_L06_001AF53C * 6.981318e-06f, + D_L06_001AF53C * 6.981318e-06f, 0.25132746f); + if (!done) { + if (!func_002E59B0(moby, *sound) && D_L06_001DB610[0] != 0xFF) + *sound = func_002E5DA0(0, 4, moby, 0x330); + } else { + handle = *sound; + if (handle != -1) { + slot = (u8 *)D_00188660 + handle * 0x70; + if (*(char **)(slot + 0x88) == moby && slot[0x74]) func_002E59F8(handle); + } + *sound = -1; + } + return done; +} diff --git a/src/pal/levels/shared/L12_0040C938.c b/src/pal/levels/shared/L12_0040C938.c index 74ab30edb..9d4359bd2 100644 --- a/src/pal/levels/shared/L12_0040C938.c +++ b/src/pal/levels/shared/L12_0040C938.c @@ -1,4 +1,3 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L12_0040CBA0); diff --git a/src/pal/levels/shared/L12_0040CBA0-g8.c b/src/pal/levels/shared/L12_0040CBA0-g8.c new file mode 100644 index 000000000..0e62ced2d --- /dev/null +++ b/src/pal/levels/shared/L12_0040CBA0-g8.c @@ -0,0 +1,50 @@ +/* func_PAL_L12_0040CBA0, the PAL copy of func_L12_00408050: the same C with the two 15-frame + effect durations become 12. */ +#include "common.h" + +typedef int TI128 __attribute__((mode(TI))); +extern u8 *func_0029EFD0(s32); +extern void func_002833F0(void *, void *); +extern float func_002A7878(float, float); +extern u8 *func_002C2210(void *, s32, s32, s32, s32, void *, float, float, float, s32); +extern float D_L12_001B15B0 __attribute__((sda)); +extern s32 D_L12_001B1520 __attribute__((sda)); +extern s32 D_L12_001B1524 __attribute__((sda)); +extern u8 D_L12_001A8F20[] MACRO_ADDR; + +/* The func_L16_00413D10 spawner for the 0xEA5 object: places it at the position with the + velocity, hands it to its owner, and starts two particle bursts on it. The burst table is a + MACRO_ADDR object, so its lui/addiu pair is emitted again for each call. */ +u8 *func_PAL_L12_0040CBA0(u8 *owner, TI128 *velocity, TI128 *position, float speed) +{ + u8 *obj; + u8 *state; + u8 *pos; + float scale; + obj = func_0029EFD0(0xEA5); + if (obj) { + obj[0x30] = 255; + *(u16 *)(obj + 0x32) = 255; + obj[0x31] = 1; + obj[0x20] = 0; + *(s64 *)(obj + 0x38) = *(s64 *)(owner + 0x38); + pos = obj + 0x10; + qcopy(pos, position); + state = *(u8 **)(obj + 0x68); + qcopy(state, velocity); + *(float *)(state + 0x14) = speed; + *(float *)(state + 0x20) = 0.15f; + *(u8 **)(state + 0x10) = owner; + *(u16 *)(obj + 0x34) |= 0x208; + qcopy(obj + 0xF0, owner + 0xF0); + func_002833F0(obj + 0xC0, obj + 0xF0); + obj[0x23] = 128; + *(float *)(obj + 0x2C) = D_L12_001B15B0; + *(u16 *)(obj + 0x34) |= 0x100; + *(s32 *)(state + 0x24) = 0; + scale = func_002A7878(8.0f, 10.0f); + func_002C2210(pos, 12, D_L12_001B1520, 0, 10, D_L12_001A8F20, scale * 0.3f, scale, 0.0f, 0); + func_002C2210(pos, 12, D_L12_001B1524, 1, -10, D_L12_001A8F20, scale * 0.04f, scale * 0.4f, 0.0f, 0); + } + return obj; +} diff --git a/src/pal/levels/shared/L13_003F0F10-hz.c b/src/pal/levels/shared/L13_003F0F10-hz.c new file mode 100644 index 000000000..e6c89b6b2 --- /dev/null +++ b/src/pal/levels/shared/L13_003F0F10-hz.c @@ -0,0 +1,65 @@ +/* func_PAL_L13_003F0F10, the PAL copy of func_L13_003ECD48: the same C with the callees are PAL's + func_PAL_002B1A50 and func_PAL_L00_003FB330. */ +#include "include_asm.h" + +#ifndef RAC2_T_OBJ_389848 +typedef struct { + char pad[0xAA]; + short key; /* +0xAA */ +} Obj_389848; +#endif + +static __inline__ void qcopy(void *dst, const void *src) { + __asm__ __volatile__("lq $2,0x0(%1)\n\tsq $2,0x0(%0)" + : : "r"(dst), "r"(src) : "$2", "memory"); +} + +extern int func_PAL_002B1A50(void *, void *, int); +extern int func_002E5CF8(int, int, char *); +extern void func_00282F20(void *, void *, float); +extern void func_00282CC0(void *, void *, void *); +extern void *func_PAL_L00_003FB330(void *, int, int, int, int, int, int, int, float, float, int, int, int, int); +extern void func_0029F338(void *); + +typedef struct { + unsigned char pad0[0x20]; + float f20; + unsigned char pad24[0x50 - 0x24]; + unsigned char sub50[0x11]; + unsigned char b61; + unsigned char b62; + unsigned char pad63[0x6A - 0x63]; + unsigned char b6A; + unsigned char pad6B[0xA8 - 0x6B]; + float fA8; +} L13_CD48Vars; + +extern void func_L13_00389848(Obj_389848 *object); +void func_PAL_L13_003F0F10(unsigned char *m) +{ + L13_CD48Vars *v = *(L13_CD48Vars **)(m + 0x68); + float p[4] __attribute__((aligned(16))); + float b[4] __attribute__((aligned(16))); + float a[4] __attribute__((aligned(16))); + + if (m[0x20] == 0) { + func_L13_00389848((Obj_389848 *)m); + m[0x20] = 1; + } + v->b6A = 2; + v->fA8 = 0.01f; + v->b61 = 0xFF; + v->b62 = 0xFF; + if (func_PAL_002B1A50(m, v->sub50, 0) != 0) { + func_002E5CF8(0, 0, (char *)m); + } + if (v->f20 <= 0.0f) { + qcopy(p, m + 0x10); + func_00282F20(a, m + 0xD0, -2.0f); + func_00282CC0(p, a, p); + func_00282F20(b, m + 0xC0, 1.5f); + func_00282CC0(p, b, p); + func_PAL_L00_003FB330(p, 0, 0x19, 0x14, 0x14, 0x14, 0x2D, 1, 0.75f, 20.0f, 1, 0, 0, 0); + func_0029F338(m); + } +} diff --git a/src/pal/levels/shared/L13_003F0F10.c b/src/pal/levels/shared/L13_003F0F10.c index f2683fd58..9d4359bd2 100644 --- a/src/pal/levels/shared/L13_003F0F10.c +++ b/src/pal/levels/shared/L13_003F0F10.c @@ -1,4 +1,3 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L13_003F0F10); diff --git a/src/pal/levels/shared/L18_003FDE80-switch-g8.c b/src/pal/levels/shared/L18_003FDE80-switch-g8.c new file mode 100644 index 000000000..97f523fca --- /dev/null +++ b/src/pal/levels/shared/L18_003FDE80-switch-g8.c @@ -0,0 +1,53 @@ +/* func_PAL_L18_003FDE80, the PAL copy of func_L18_003F9DA0: the same C, where func_L00_002D70A0 + becomes func_PAL_L00_002D7850. */ +#include "include_asm.h" +#include "common.h" + +extern s32 D_L18_001C9D40 NOT_SDA; + +extern const float D_L18_001B0430 __attribute__((sda)); +extern const float D_L18_001B0434 __attribute__((sda)); +extern const float D_L18_001B0438 __attribute__((sda)); +extern const float D_L18_001B043C __attribute__((sda)); +extern const float D_L18_001B0440 __attribute__((sda)); +extern const float D_L18_001B0444 __attribute__((sda)); +extern const float D_L18_001B0448 __attribute__((sda)); +extern const float D_L18_001B044C __attribute__((sda)); +extern const float D_L18_001B0450 __attribute__((sda)); +extern void *func_PAL_L00_002D7850(s32); +extern void func_L00_002D7140(void *); + +/* While D_L18_001C9D40 is clear: allocates the vector at +0x80 of the object's state block + (func_PAL_L00_002D7850(5)) when it has none, else sets it to the constant triple of MODE (1, 2 or + any other). Once D_L18_001C9D40 is set: frees the vector and clears the pointer. */ +void func_PAL_L18_003FDE80(char *a0, s32 mode) +{ + char *state = *(char **)(a0 + 0x68); + + if (D_L18_001C9D40 == 0) { + if (*(float **)(state + 0x80) == 0) { + *(void **)(state + 0x80) = func_PAL_L00_002D7850(5); + } else { + switch (mode) { + case 1: + (*(float **)(state + 0x80))[0] = D_L18_001B043C; + (*(float **)(state + 0x80))[1] = D_L18_001B0440; + (*(float **)(state + 0x80))[2] = D_L18_001B0444; + break; + case 2: + (*(float **)(state + 0x80))[0] = D_L18_001B0448; + (*(float **)(state + 0x80))[1] = D_L18_001B044C; + (*(float **)(state + 0x80))[2] = D_L18_001B0450; + break; + default: + (*(float **)(state + 0x80))[0] = D_L18_001B0430; + (*(float **)(state + 0x80))[1] = D_L18_001B0434; + (*(float **)(state + 0x80))[2] = D_L18_001B0438; + break; + } + } + } else { + func_L00_002D7140(*(void **)(state + 0x80)); + *(int *)(state + 0x80) = 0; + } +} diff --git a/src/pal/levels/shared/L18_003FDE80.c b/src/pal/levels/shared/L18_003FDE80.c index db8b8d3da..590440250 100644 --- a/src/pal/levels/shared/L18_003FDE80.c +++ b/src/pal/levels/shared/L18_003FDE80.c @@ -1,5 +1,4 @@ #include "include_asm.h" -INCLUDE_ASM("asm/pal/levels", func_PAL_L18_003FDE80); INCLUDE_ASM("asm/pal/levels", func_PAL_L18_003FDF30);