Add Alucard sprite support (#1272)

This commit is contained in:
Luciano Ciccariello 2024-06-06 23:11:18 +01:00 committed by GitHub
parent 6057bddea4
commit 0495f89ca3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 65 additions and 45 deletions

View File

@ -35,6 +35,7 @@ set(SOURCE_FILES_PC
src/pc/pc.c
src/pc/str.c
src/pc/sim_pc.c
src/pc/pl_arc.c
src/pc/pl_ric.c
src/pc/stages/stage_loader.c
src/pc/stages/stage_dummy.c

View File

@ -1410,7 +1410,7 @@ typedef struct {
} PlayerOvl;
extern PlayerOvl g_PlOvl;
extern u8** g_PlOvlAluBatSpritesheet[1];
extern u8* g_PlOvlSpritesheet[99];
extern u8* g_PlOvlSpritesheet[];
/**** Helper signatures ****/
extern void (*g_api_FreePrimitives)(s32);

40
src/pc/pl_arc.c Normal file
View File

@ -0,0 +1,40 @@
#include <game.h>
#include <log.h>
#include "pc.h"
u8* g_PlOvlSpritesheet[256];
static u8* sprite_data = NULL;
void InitPlayerArc(FileLoad* file) {
int i;
g_PlayableCharacter = PLAYER_ALUCARD;
if (sprite_data) {
free(sprite_data);
}
// this is not freed anywhere else, technically a memory leak but it's not
DEBUGF("allocating %d bytes for ARC spritesheet", file->length);
sprite_data = malloc(file->length);
memcpy(sprite_data, file->content, file->length);
// clean-up previously allocated data, only useful for memory sanity checks
memset(g_PlOvlSpritesheet, 0, sizeof(g_PlOvlSpritesheet));
const u32 BaseAddr = 0x8013C000;
u32* ptr = (u32*)sprite_data + 8;
for (i = 0; i < LEN(g_PlOvlSpritesheet); i++) {
u32 psxPtr = *ptr++;
// assume PSX ptr to not be in an unexptected range
if (psxPtr < BaseAddr) {
break;
}
size_t dataPos = psxPtr - BaseAddr;
if (dataPos >= file->length) {
break;
}
g_PlOvlSpritesheet[i] = sprite_data + dataPos;
}
}

View File

@ -141,6 +141,7 @@ void LoadStageTileset(u8* pTilesetData, size_t len, s32 y) {
void InitStageDummy(Overlay* o);
void InitStageSel(Overlay* o);
void InitPlayerArc(FileLoad* file);
void InitPlayerRic(void);
void func_80131EBC(const char* str, s16 arg1);
s32 LoadFileSimToMem(SimKind kind) {
@ -260,6 +261,9 @@ bool LoadFilePc(FileLoad* file, SimFile* sim) {
LoadStageTileset(sim->addr, file->length, 0x100);
LoadImage(&g_Vram.D_800ACD98, D_800A04CC);
break;
case 99:
InitPlayerArc(file);
break;
default:
g_SimFile = sim;
if (LoadFileSimToMem(sim->kind) < 0) {
@ -292,6 +296,7 @@ s32 LoadFileSim(s32 fileId, SimFileType type) {
break;
case 4:
sim.path = "BIN/ARC_F.BIN";
sim.kind = 99;
break;
case 5:
InitPlayerRic();
@ -392,7 +397,7 @@ s32 LoadFileSim(s32 fileId, SimFileType type) {
}
snprintf(buf, sizeof(buf), "disks/us/%s", sim.path);
INFOF("open %s", buf);
DEBUGF("about to load %s", buf);
if (!FileUseContent(LoadFilePc, buf, &sim)) {
ERRORF("failed to load '%s'", buf);
D_800A04EC = 0;

View File

@ -78,6 +78,7 @@ s32 func_800EA5E4(u32);
void LoadGfxAsync(s32 gfxId);
void PlaySfx(s16 sfxId);
void func_800EA538(s32 arg0);
void func_800EA5AC(u16 arg0, u8 arg1, u8 arg2, u8 arg3);
bool func_80131F68(void);
u16* func_80106A28(u32 arg0, u16 kind);
void PlayAnimation(s8* frameProps, AnimationFrame** frames);
@ -138,7 +139,7 @@ bool InitGame(void) {
api.PlaySfx = PlaySfx;
api.func_800EDB58 = NULL;
api.func_800EA538 = func_800EA538;
api.g_pfn_800EA5AC = NULL;
api.g_pfn_800EA5AC = func_800EA5AC;
api.func_801027C4 = NULL;
api.func_800EB758 = NULL;
api.CreateEntFactoryFromEntity = NULL;

View File

@ -7,19 +7,26 @@
#include "sfx.h"
static void Update(void);
static void TestCollisions(void);
static void HitDetection(void);
static void func_8018A7AC(void);
static void InitRoomEntities(s32 objLayoutId);
static RoomHeader g_Rooms[1];
static s16** g_SpriteBanks[1];
static u16* g_Cluts[1];
static void* g_EntityGfxs[17];
static u32* empty_entity_gfx[] = {
(u32*)0xFFFFFFFF,
};
static u_long* empty_clut_load[] = {
(u_long*)0x00000000,
};
static RoomHeader g_Rooms[1] = {{40, 12, 40, 12, {0, 0, 0, 0}}};
static u_long* g_SpriteBanks[1] = {NULL};
static u16* g_Cluts[] = {empty_clut_load, NULL};
static void* g_EntityGfxs[] = {empty_entity_gfx, NULL};
static void UpdateStageEntities(void);
static Overlay g_StageDesc = {
Update,
TestCollisions,
HitDetection,
func_8018A7AC,
InitRoomEntities,
g_Rooms,
@ -36,47 +43,14 @@ static Overlay g_StageDesc = {
NULL,
};
static RoomHeader g_Rooms[1] = {0};
static s16** g_SpriteBanks[1] = {0};
static u32* D_801801B8[] = {
(u32*)0x00000000, (u32*)0x00000000, (u32*)0x00000000,
(u32*)0x00000000, (u32*)0xFFFFFFFF,
};
static void* g_EntityGfxs[] = {
D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8,
D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8, D_801801B8,
D_801801B8, D_801801B8, D_801801B8, D_801801B8, NULL,
};
static u8 D_80181D08[0x2000];
static u32* D_801800A0[] = {
(u32*)0x00000005, (u32*)0x00002000, (u32*)0x00000010,
(u32*)D_80181D08, (u32*)0xFFFFFFFF,
};
static u16* g_Cluts[] = {
D_801800A0,
};
void InitStageDummy(Overlay* o) {
FILE* f;
f = fopen("assets/st/wrp/D_80181D08.dec", "rb");
if (f) {
fseek(f, 0, SEEK_END);
size_t len = ftell(f);
fseek(f, 0, SEEK_SET);
fread(D_80181D08, len, 1, f);
fclose(f);
}
g_StageDesc.tileLayers = LoadRooms("assets/st/wrp/rooms.layers.json");
memcpy(o, &g_StageDesc, sizeof(Overlay));
}
static void Update(void) { NOT_IMPLEMENTED; }
static void TestCollisions(void) { NOT_IMPLEMENTED; }
static void HitDetection(void) { NOT_IMPLEMENTED; }
static void func_8018A7AC(void) { NOT_IMPLEMENTED; }
@ -91,7 +65,7 @@ static void InitRoomEntities(s32 objLayoutId) {
}
INFOF("Stage ID: %02X", g_StageId);
PlaySfx(MU_REQUIEM_FOR_THE_GODS);
PlaySfx(MU_CRYSTAL_TEARDROPS);
}
static void UpdateStageEntities(void) { NOT_IMPLEMENTED; }

View File

@ -421,7 +421,6 @@ s32 D_800B091C;
s32 D_800B0920;
PlayerOvl g_PlOvl = {0};
u8** g_PlOvlAluBatSpritesheet[1] = {0};
u8* g_PlOvlSpritesheet[99] = {0};
// sound bss
s16 g_SoundCommandRingBufferReadPos;