Various custom asset support (#756)

* use asset paths for better custom asset support

* fix keyframe animation timings

* display title cards as a full texture

* asset support for gfxprint

* support pause menu overworld map

* fix more resources that need to be loaded

* pr feedback
This commit is contained in:
Archez 2024-08-23 17:19:41 -04:00 committed by GitHub
parent d74699740e
commit 0c2a51c9f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 232 additions and 94 deletions

View File

@ -476,7 +476,7 @@ extern "C" void InitOTR() {
OTRMessage_Init();
OTRAudio_Init();
// OTRExtScanner();
OTRExtScanner();
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnFileDropped>(Ben_ProcessDroppedFiles);

View File

@ -102,6 +102,7 @@ void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size);
void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size);
uint64_t GetPerfCounter();
bool ResourceMgr_IsAltAssetsEnabled();
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime);
void ResourceMgr_UnregisterSkeleton(SkelAnime* skelAnime);
void ResourceMgr_ClearSkeletons();

View File

@ -3,6 +3,10 @@
#include "libc/stdint.h"
#include <libultraship/libultra/convert.h>
#if 0
#define OS_CLOCK_RATE 62500000LL
#define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4)
@ -12,12 +16,14 @@
#define OS_CYCLES_TO_NSEC(c) (((u64)(c)*(1000000000LL/15625000LL))/(OS_CPU_COUNTER/15625000LL))
#define OS_CYCLES_TO_USEC(c) (((u64)(c)*(1000000LL/15625LL))/(OS_CPU_COUNTER/15625LL))
#define OS_K0_TO_PHYSICAL(x) (x)
#define OS_K0_TO_PHYSICAL(x) (u32)(((char*)(x)-0x80000000))
#define OS_K1_TO_PHYSICAL(x) (u32)(((char*)(x)-0xA0000000))
#define OS_PHYSICAL_TO_K0(x) (void*)(((u32)(x)+0x80000000))
#define OS_PHYSICAL_TO_K1(x) (void*)(((u32)(x)+0xA0000000))
#endif
#define OS_MSEC_TO_CYCLES(n) OS_USEC_TO_CYCLES((n) * 1000)
#define OS_SEC_TO_CYCLES(n) OS_MSEC_TO_CYCLES((n) * 1000)

View File

@ -25,8 +25,8 @@
#define RDRAM_CACHED KSEG0
#define PHYSICAL_TO_VIRTUAL(addr) (addr) //((uintptr_t)(addr) + RDRAM_CACHED)
#define SEGMENTED_TO_K0(addr) (addr) //(void*)((gSegments[SEGMENT_NUMBER(addr)] + K0BASE) + SEGMENT_OFFSET(addr))
#define PHYSICAL_TO_VIRTUAL(addr) (addr) // ((uintptr_t)(addr) + RDRAM_CACHED)
#define SEGMENTED_TO_K0(addr) (addr) // (void*)((gSegments[SEGMENT_NUMBER(addr)] + K0BASE) + SEGMENT_OFFSET(addr))
#define GET_ACTIVE_CAM(play) ((play)->cameraPtrs[(play)->activeCamId])

View File

@ -1,5 +1,24 @@
#include "global.h"
#include "2s2h/BenPort.h"
#include "align_asset_macro.h"
// #region 2S2H [HD Textures]
#define drGfxPrintFontData "__OTR__textures/font/sGfxPrintFontData"
static const ALIGN_ASSET(2) char rGfxPrintFontData[] = drGfxPrintFontData;
#define drGfxPrintFontDataAlt "__OTR__alt/textures/font/sGfxPrintFontData"
static const ALIGN_ASSET(2) char rGfxPrintFontDataAlt[] = drGfxPrintFontDataAlt;
bool sHasArchiveTexture = false;
// Checks if we have a gfx font as a resource in an archive, which needs to be rendered differently
bool GfxPrint_HasArchiveTexture() {
return ResourceMgr_FileExists(rGfxPrintFontData) ||
(ResourceMgr_IsAltAssetsEnabled() && ResourceMgr_FileExists(rGfxPrintFontDataAlt));
}
// #endregion
#define GFXP_FLAG_HIRAGANA (1 << 0)
#define GFXP_FLAG_RAINBOW (1 << 1)
#define GFXP_FLAG_SHADOW (1 << 2)
@ -144,8 +163,18 @@ void GfxPrint_Setup(GfxPrint* this) {
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_XLU_SURF | G_RM_XLU_SURF2);
gDPSetCombineMode(this->dList++, G_CC_DECALRGBA, G_CC_DECALRGBA);
gDPLoadTextureBlock_4b(this->dList++, sGfxPrintFontData, G_IM_FMT_CI, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
// 2S2H [HD Textures] Font data from an archive has 4 times the width as the letter columns are side by side
if (sHasArchiveTexture) {
gDPLoadTextureBlock_4b(this->dList++, rGfxPrintFontData, G_IM_FMT_CI, width * 4, height, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
} else {
gDPLoadTextureBlock_4b(this->dList++, sGfxPrintFontData, G_IM_FMT_CI, width, height, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
}
gDPLoadTLUT(this->dList++, 64, 256, sGfxPrintFontTLUT);
for (i = 1; i < 4; i++) {
@ -156,17 +185,18 @@ void GfxPrint_Setup(GfxPrint* this) {
gDPSetColor(this->dList++, G_SETPRIMCOLOR, this->color.rgba);
// BENTODO: CRASH
// #region 2S2H [Port] Rainbow disabled until LUS supports multiple palettes and tiles
// gDPLoadMultiTile_4b(this->dList++, sGfxPrintRainbowData, 0, 1, G_IM_FMT_CI, 2, 8, 0, 0, 1, 7, 4,
// G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 1, 3, G_TX_NOLOD, G_TX_NOLOD);
// gDPLoadTLUT(this->dList++, 16, 320, sGfxPrintRainbowTLUT);
for (i = 1; i < 4; i++) {
gDPSetTile(this->dList++, G_IM_FMT_CI, G_IM_SIZ_4b, 1, 0, i * 2 + 1, 4, G_TX_NOMIRROR | G_TX_WRAP, 3,
G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 1, G_TX_NOLOD);
gDPSetTileSize(this->dList++, i * 2 + 1, 0, 0, 4, 28);
}
// for (i = 1; i < 4; i++) {
// gDPSetTile(this->dList++, G_IM_FMT_CI, G_IM_SIZ_4b, 1, 0, i * 2 + 1, 4, G_TX_NOMIRROR | G_TX_WRAP, 3,
// G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 1, G_TX_NOLOD);
// gDPSetTileSize(this->dList++, i * 2 + 1, 0, 0, 4, 28);
// }
// #endregion
}
void GfxPrint_SetColor(GfxPrint* this, u32 r, u32 g, u32 b, u32 a) {
@ -201,7 +231,7 @@ void GfxPrint_PrintCharImpl(GfxPrint* this, u8 c) {
this->flags &= ~GFXP_FLAG_UPDATE;
gDPPipeSync(this->dList++);
// BENTODO: CRASH HERE
// 2S2H [Port] Rainbow disabled until LUS supports multiple palettes and tiles
if (this->flags & GFXP_FLAG_RAINBOW && false) {
gDPSetTextureLUT(this->dList++, G_TT_RGBA16);
gDPSetCycleType(this->dList++, G_CYC_2CYCLE);
@ -215,17 +245,27 @@ void GfxPrint_PrintCharImpl(GfxPrint* this, u8 c) {
}
}
// 2S2H [HD Textures] The font data is normally 4 sets of 2 columns overlayed on top of each other with
// different CI palette values. Custom font data from archives instead are all 4 sets laid out side by side.
// This means we have to compute an additional offset value that represents which of the 4 sets a letter is from.
u16 assetOffsetX = 0;
if (sHasArchiveTexture) {
// Multiplied by the offset of 2 columns before added with the original value below
assetOffsetX = (c & 0x3) * (256 * 2);
tile = 0;
}
if (this->flags & GFXP_FLAG_SHADOW) {
gDPSetColor(this->dList++, G_SETPRIMCOLOR, 0);
gSPTextureRectangle(this->dList++, this->posX + 4, this->posY + 4, this->posX + 4 + 32, this->posY + 4 + 32,
tile, s << 6, t << 8, 1 << 10, 1 << 10);
tile, assetOffsetX + (s << 6), t << 8, 1 << 10, 1 << 10);
gDPSetColor(this->dList++, G_SETPRIMCOLOR, this->color.rgba);
}
gSPTextureRectangle(this->dList++, this->posX, this->posY, this->posX + 32, this->posY + 32, tile, s << 6, t << 8,
1 << 10, 1 << 10);
gSPTextureRectangle(this->dList++, this->posX, this->posY, this->posX + 32, this->posY + 32, tile,
assetOffsetX + (s << 6), t << 8, 1 << 10, 1 << 10);
this->posX += 32;
}
@ -265,14 +305,12 @@ void GfxPrint_PrintChar(GfxPrint* this, u8 c) {
this->flags &= ~GFXP_FLAG_HIRAGANA;
break;
case GFXP_RAINBOW_ON_CHAR:
// BENTODO: CRASH
// this->flags |= GFXP_FLAG_RAINBOW;
// this->flags |= GFXP_FLAG_UPDATE;
this->flags |= GFXP_FLAG_RAINBOW;
this->flags |= GFXP_FLAG_UPDATE;
break;
case GFXP_RAINBOW_OFF_CHAR:
// BENTODO: CRASH
// this->flags &= ~GFXP_FLAG_RAINBOW;
// this->flags |= GFXP_FLAG_UPDATE;
this->flags &= ~GFXP_FLAG_RAINBOW;
this->flags |= GFXP_FLAG_UPDATE;
break;
case GFXP_UNUSED_CHAR:
default:
@ -320,6 +358,9 @@ void GfxPrint_Init(GfxPrint* this) {
this->flags &= ~GFXP_FLAG_RAINBOW;
this->flags |= GFXP_FLAG_SHADOW;
this->flags |= GFXP_FLAG_UPDATE;
// 2S2H [HD Textures] Track whether we have a archive font for the life of this printer
sHasArchiveTexture = GfxPrint_HasArchiveTexture();
}
void GfxPrint_Destroy(GfxPrint* this) {

View File

@ -123,20 +123,17 @@ void Keyframe_ResetFlex(KFSkelAnimeFlex* kfSkelAnime) {
// cKF_SkeletonInfo_R_ct
void Keyframe_InitFlex(KFSkelAnimeFlex* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation,
Vec3s* jointTable, Vec3s* morphTable, UnkKeyframeCallback* callbacks) {
if (ResourceMgr_OTRSigCheck(skeleton)) {
skeleton = (KeyFrameSkeleton*)ResourceMgr_LoadKeyFrameSkelByName(skeleton);
}
if (ResourceMgr_OTRSigCheck(animation)) {
animation = (KeyFrameAnimation*)ResourceMgr_LoadKeyFrameAnimByName(animation);
}
Keyframe_ResetFlex(kfSkelAnime);
FrameCtrl_Init(&kfSkelAnime->frameCtrl);
KeyFrameSkeleton* skel = skeleton;
KeyFrameAnimation* anim = animation;
if (ResourceMgr_OTRSigCheck(skel)) {
skel = (KeyFrameSkeleton*)ResourceMgr_LoadKeyFrameSkelByName(skeleton);
}
if (ResourceMgr_OTRSigCheck(anim)) {
anim = (KeyFrameAnimation*)ResourceMgr_LoadKeyFrameAnimByName(animation);
}
kfSkelAnime->skeleton = skel;
kfSkelAnime->animation = anim;
kfSkelAnime->skeleton = (KeyFrameSkeleton*)Lib_SegmentedToVirtual(skeleton);
kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation);
kfSkelAnime->jointTable = jointTable;
kfSkelAnime->morphTable = morphTable;
kfSkelAnime->callbacks = callbacks;
@ -187,20 +184,22 @@ void Keyframe_FlexPlayLoopWithMorph(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimat
void Keyframe_FlexChangeAnim(KFSkelAnimeFlex* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation,
f32 startTime, f32 endTime, f32 t, f32 speed, f32 morphFrames, s32 animMode) {
kfSkelAnime->morphFrames = morphFrames;
if (ResourceMgr_OTRSigCheck(skeleton)) {
skeleton = ResourceMgr_LoadKeyFrameSkelByName(skeleton);
}
if (kfSkelAnime->skeleton != skeleton) {
kfSkelAnime->skeleton = skeleton;
}
if (ResourceMgr_OTRSigCheck(animation)) {
animation = ResourceMgr_LoadKeyFrameAnimByName(animation);
// Overwrite the end time after fetching the animation data as the parent caller most likely
// passed in garbage data from the "fake" animation pointer (casted from resource string)
endTime = animation->duration;
}
kfSkelAnime->animation = animation;
kfSkelAnime->morphFrames = morphFrames;
if (kfSkelAnime->skeleton != skeleton) {
kfSkelAnime->skeleton = (KeyFrameSkeleton*)Lib_SegmentedToVirtual(skeleton);
}
kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation);
FrameCtrl_SetProperties(&kfSkelAnime->frameCtrl, startTime, endTime, kfSkelAnime->animation->duration, t, speed,
animMode);
@ -211,7 +210,7 @@ void Keyframe_FlexChangeAnimQuick(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimatio
animation = ResourceMgr_LoadKeyFrameAnimByName(animation);
}
kfSkelAnime->animation = animation;
kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation);
kfSkelAnime->frameCtrl.duration = kfSkelAnime->animation->duration;
}
@ -559,19 +558,17 @@ void Keyframe_ResetStandard(KFSkelAnime* kfSkelAnime) {
void Keyframe_InitStandard(KFSkelAnime* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation,
Vec3s* jointTable, Vec3s* morphTable) {
Keyframe_ResetStandard(kfSkelAnime);
FrameCtrl_Init(&kfSkelAnime->frameCtrl);
if (ResourceMgr_OTRSigCheck(animation)) {
animation = ResourceMgr_LoadKeyFrameAnimByName(animation);
}
if (ResourceMgr_OTRSigCheck(skeleton)) {
skeleton = ResourceMgr_LoadKeyFrameSkelByName(skeleton);
}
kfSkelAnime->skeleton = skeleton;
kfSkelAnime->animation = animation;
Keyframe_ResetStandard(kfSkelAnime);
FrameCtrl_Init(&kfSkelAnime->frameCtrl);
kfSkelAnime->skeleton = (KeyFrameSkeleton*)Lib_SegmentedToVirtual(skeleton);
kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation);
kfSkelAnime->jointTable = jointTable;
kfSkelAnime->morphTable = morphTable;
}
@ -626,18 +623,16 @@ void Keyframe_StandardPlayLoopWithMorph(KFSkelAnime* kfSkelAnime, KeyFrameAnimat
void Keyframe_StandardChangeAnim(KFSkelAnime* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation,
f32 startTime, f32 endTime, f32 t, f32 speed, f32 morphFrames, s32 animMode,
Vec3s* rotOffsetsTable) {
kfSkelAnime->morphFrames = morphFrames;
if (ResourceMgr_OTRSigCheck(animation)) {
animation = ResourceMgr_LoadKeyFrameAnimByName(animation);
}
if (ResourceMgr_OTRSigCheck(skeleton)) {
skeleton = ResourceMgr_LoadKeyFrameSkelByName(skeleton);
}
kfSkelAnime->skeleton = skeleton;
kfSkelAnime->animation = animation;
kfSkelAnime->morphFrames = morphFrames;
kfSkelAnime->skeleton = (KeyFrameSkeleton*)Lib_SegmentedToVirtual(skeleton);
kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation);
FrameCtrl_SetProperties(&kfSkelAnime->frameCtrl, startTime, endTime, kfSkelAnime->animation->duration, t, speed,
animMode);
@ -649,7 +644,7 @@ void Keyframe_StandardChangeAnimQuick(KFSkelAnime* kfSkelAnime, KeyFrameAnimatio
animation = ResourceMgr_LoadKeyFrameAnimByName(animation);
}
kfSkelAnime->animation = animation;
kfSkelAnime->animation = Lib_SegmentedToVirtual(animation);
kfSkelAnime->frameCtrl.duration = kfSkelAnime->animation->duration;
}

View File

@ -967,7 +967,9 @@ void TitleCard_Draw(GameState* gameState, TitleCardContext* titleCtx) {
OPEN_DISPS(gameState->gfxCtx);
if (width * height > TMEM_SIZE) {
height = TMEM_SIZE / width;
// 2S2H [HD Textures] Commenting out the below so that we can render the full texture in one rectangle,
// as we are not restricted to the console TMEM limit
// height = TMEM_SIZE / width;
}
titleSecondY = titleY + (height * 4);

View File

@ -6,6 +6,8 @@
#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
#include <stdio.h>
#include "2s2h/BenPort.h"
#define DYNA_RAYCAST_FLOORS 1
#define DYNA_RAYCAST_WALLS 2
#define DYNA_RAYCAST_CEILINGS 4
@ -3965,6 +3967,10 @@ s32 BgCheck_SphVsFirstDynaPoly(CollisionContext* colCtx, u16 xpFlags, CollisionP
* SEGMENTED_TO_K0 CollisionHeader members
*/
void CollisionHeader_SegmentedToVirtual(CollisionHeader* colHeader) {
if (ResourceMgr_OTRSigCheck(colHeader)) {
colHeader = ResourceMgr_LoadColByName(colHeader);
}
colHeader->vtxList = Lib_SegmentedToVirtual(colHeader->vtxList);
colHeader->polyList = Lib_SegmentedToVirtual(colHeader->polyList);
if (colHeader->surfaceTypeList) {
@ -3982,6 +3988,10 @@ void CollisionHeader_SegmentedToVirtual(CollisionHeader* colHeader) {
* Convert CollisionHeader Segmented to Virtual addressing
*/
void CollisionHeader_GetVirtual(CollisionHeader* colHeader, CollisionHeader** dest) {
if (ResourceMgr_OTRSigCheck(colHeader)) {
colHeader = ResourceMgr_LoadColByName(colHeader);
}
*dest = Lib_SegmentedToVirtual(colHeader);
CollisionHeader_SegmentedToVirtual(*dest);
}

View File

@ -28,6 +28,8 @@
#include "global.h"
#include "z64curve.h"
#include "2s2h/BenPort.h"
void SkelCurve_Clear(SkelCurve* skelCurve) {
skelCurve->limbCount = 0;
skelCurve->skeleton = NULL;
@ -46,6 +48,10 @@ void SkelCurve_Clear(SkelCurve* skelCurve) {
*/
s32 SkelCurve_Init(PlayState* play, SkelCurve* skelCurve, CurveSkeletonHeader* skeletonHeaderSeg,
CurveAnimationHeader* animation) {
if (ResourceMgr_OTRSigCheck(skeletonHeaderSeg)) {
skeletonHeaderSeg = ResourceMgr_LoadSkeletonByName(skeletonHeaderSeg, NULL);
}
SkelCurveLimb** limbs;
CurveSkeletonHeader* skeletonHeader = Lib_SegmentedToVirtual(skeletonHeaderSeg);
@ -103,6 +109,11 @@ s32 SkelCurve_Update(PlayState* play, SkelCurve* skelCurve) {
s32 vecType;
animation = Lib_SegmentedToVirtual(skelCurve->animation);
if (ResourceMgr_OTRSigCheck(animation)) {
animation = ResourceMgr_LoadAnimByName(animation);
}
knotCounts = Lib_SegmentedToVirtual(animation->knotCounts);
startKnot = Lib_SegmentedToVirtual(animation->interpolationData);
constantData = Lib_SegmentedToVirtual(animation->constantData);

View File

@ -1,6 +1,5 @@
#include "global.h"
#include <libultraship/bridge.h>
#include "BenPort.h"
f32 Math_CosS(s16 angle) {
return coss(angle) * SHT_MINV;
@ -677,11 +676,12 @@ f32 Math_Vec3f_StepTo(Vec3f* start, Vec3f* target, f32 speed) {
void Lib_Nop801004FC(void) {
}
// 2S2H [Port] For the port, resources aren't loaded into memory addresses like on console.
// Instead we deal with resource strings and leave systems to deal with pointers later (renderer, etc).
// We've modified the macros used below and similar ones to just return what its given (noop).
void* Lib_SegmentedToVirtual(void* ptr) {
if (ResourceMgr_OTRSigCheck(ptr)) {
return ResourceGetDataByName(ptr); // SEGMENTED_TO_VIRTUAL(ptr);
}
return ptr;
return SEGMENTED_TO_K0(ptr);
}
void* Lib_SegmentedToVirtualNull(void* ptr) {

View File

@ -43,6 +43,8 @@
// Assets for other actors
#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
#include "2s2h/BenPort.h"
#include "2s2h/Enhancements/GameInteractor/GameInteractor.h"
void PlayerCall_Init(Actor* thisx, PlayState* play);
@ -2128,7 +2130,7 @@ void Player_DrawZoraShield(PlayState* play, Player* player) {
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
// clang-format off
vtx = Lib_SegmentedToVirtual(&object_link_zora_Vtx_011210); phi_a0 = Lib_SegmentedToVirtual(&object_link_zora_U8_011710);
vtx = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(&object_link_zora_Vtx_011210)); phi_a0 = (u8*)ResourceMgr_LoadArrayByName(Lib_SegmentedToVirtual(&object_link_zora_U8_011710));
// clang-format on
// ARRAY_COUNT(object_link_zora_Vtx_011210)

View File

@ -628,6 +628,7 @@ void SkelAnime_DrawTransformFlexOpa(PlayState* play, void** skeleton, Vec3s* joi
void SkelAnime_GetFrameData(AnimationHeader* animation, s32 frame, s32 limbCount, Vec3s* frameTable) {
if (ResourceMgr_OTRSigCheck(animation))
animation = ResourceMgr_LoadAnimByName(animation);
AnimationHeader* animHeader = Lib_SegmentedToVirtual(animation);
JointIndex* jointIndices = Lib_SegmentedToVirtual(animHeader->jointIndices);
s16* frameData = Lib_SegmentedToVirtual(animHeader->frameData);
@ -649,6 +650,7 @@ void SkelAnime_GetFrameData(AnimationHeader* animation, s32 frame, s32 limbCount
s16 Animation_GetLength(void* animation) {
if (ResourceMgr_OTRSigCheck(animation))
animation = ResourceMgr_LoadAnimByName(animation);
AnimationHeaderCommon* common = Lib_SegmentedToVirtual(animation);
return common->frameCount;
@ -657,6 +659,7 @@ s16 Animation_GetLength(void* animation) {
s16 Animation_GetLastFrame(void* animation) {
if (ResourceMgr_OTRSigCheck(animation))
animation = ResourceMgr_LoadAnimByName(animation);
AnimationHeaderCommon* common = Lib_SegmentedToVirtual(animation);
return (u16)common->frameCount - 1;
@ -1017,6 +1020,7 @@ void AnimationContext_SetLoadFrame(PlayState* play, PlayerAnimationHeader* anima
if (entry != NULL) {
if (ResourceMgr_OTRSigCheck(animation) != 0)
animation = ResourceMgr_LoadAnimByName(animation);
PlayerAnimationHeader* playerAnimHeader = Lib_SegmentedToVirtual(animation);
Vec3s* ram = frameTable;
@ -1227,8 +1231,10 @@ void SkelAnime_InitPlayer(PlayState* play, SkelAnime* skelAnime, FlexSkeletonHea
s32 headerJointCount;
s32 limbCount;
size_t allocSize;
if (ResourceMgr_OTRSigCheck(skeletonHeaderSeg) != 0)
skeletonHeaderSeg = ResourceMgr_LoadSkeletonByName(skeletonHeaderSeg, skelAnime);
skeletonHeader = Lib_SegmentedToVirtual(skeletonHeaderSeg);
headerJointCount = skeletonHeader->sh.limbCount;
skelAnime->initFlags = flags;
@ -1566,10 +1572,11 @@ s32 PlayerAnimation_OnFrame(SkelAnime* skelAnime, f32 frame) {
void SkelAnime_Init(PlayState* play, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg,
AnimationHeader* animation, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount) {
SkeletonHeader* skeletonHeader;
if (ResourceMgr_OTRSigCheck(skeletonHeaderSeg))
skeletonHeaderSeg = ResourceMgr_LoadSkeletonByName(skeletonHeaderSeg, NULL);
skeletonHeader = skeletonHeaderSeg;
skeletonHeader = Lib_SegmentedToVirtual(skeletonHeaderSeg);
skelAnime->limbCount = skeletonHeader->limbCount + 1;
skelAnime->skeleton = Lib_SegmentedToVirtual(skeletonHeader->segment);
if (jointTable == NULL) {
@ -1590,10 +1597,13 @@ void SkelAnime_Init(PlayState* play, SkelAnime* skelAnime, SkeletonHeader* skele
*/
void SkelAnime_InitFlex(PlayState* play, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg,
AnimationHeader* animation, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount) {
FlexSkeletonHeader* skeletonHeader;
if (ResourceMgr_OTRSigCheck(skeletonHeaderSeg))
if (ResourceMgr_OTRSigCheck(skeletonHeaderSeg)) {
skeletonHeaderSeg = ResourceMgr_LoadSkeletonByName(skeletonHeaderSeg, NULL);
skeletonHeader = skeletonHeaderSeg;
}
FlexSkeletonHeader* skeletonHeader;
skeletonHeader = Lib_SegmentedToVirtual(skeletonHeaderSeg);
skelAnime->limbCount = skeletonHeader->sh.limbCount + 1;
skelAnime->dListCount = skeletonHeader->dListCount;
skelAnime->skeleton = Lib_SegmentedToVirtual(skeletonHeader->sh.segment);
@ -1617,10 +1627,13 @@ void SkelAnime_InitFlex(PlayState* play, SkelAnime* skelAnime, FlexSkeletonHeade
*/
void SkelAnime_InitSkin(GameState* gameState, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg,
AnimationHeader* animation) {
SkeletonHeader* skeletonHeader;
if (ResourceMgr_OTRSigCheck(skeletonHeaderSeg))
if (ResourceMgr_OTRSigCheck(skeletonHeaderSeg)) {
skeletonHeaderSeg = ResourceMgr_LoadSkeletonByName(skeletonHeaderSeg, NULL);
skeletonHeader = skeletonHeaderSeg;
}
SkeletonHeader* skeletonHeader;
skeletonHeader = Lib_SegmentedToVirtual(skeletonHeaderSeg);
skelAnime->limbCount = skeletonHeader->limbCount + 1;
skelAnime->skeleton = Lib_SegmentedToVirtual(skeletonHeader->segment);
skelAnime->jointTable = ZeldaArena_Malloc(sizeof(*skelAnime->jointTable) * skelAnime->limbCount);

View File

@ -1,6 +1,8 @@
#include "global.h"
#include "z64skin.h"
#include "2s2h/BenPort.h"
void Skin_Setup(Skin* skin) {
skin->skeletonHeader = NULL;
skin->limbCount = 0;
@ -48,6 +50,11 @@ void Skin_Init(GameState* gameState, Skin* skin, SkeletonHeader* skeletonHeader,
s32 limbCount;
s32 i;
SkinLimb** skeleton;
if (ResourceMgr_OTRSigCheck(skeletonHeader)) {
skeletonHeader = ResourceMgr_LoadSkeletonByName(skeletonHeader, NULL);
}
SkeletonHeader* virtSkelHeader = Lib_SegmentedToVirtual(skeletonHeader);
skin->limbCount = virtSkelHeader->limbCount;

View File

@ -34,6 +34,8 @@
#include "overlays/actors/ovl_En_Tanron1/z_en_tanron1.h"
#include "overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h"
#include "2s2h/BenPort.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20)
#define THIS ((Boss01*)thisx)
@ -2612,7 +2614,7 @@ void Boss01_DrawSwordTrail(Boss01* this, PlayState* play) {
OPEN_DISPS(play->state.gfxCtx);
vtx = Lib_SegmentedToVirtual(&gOdolwaSwordTrailVtx);
vtx = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(&gOdolwaSwordTrailVtx));
for (i = 0; i < ARRAY_COUNT(sSwordTrailOuterVertexIndices); i++) {
vtx[sSwordTrailOuterVertexIndices[i]].v.ob[0] = cosf((i * M_PI) / sSwordTrailAngularRangeDivisor) * 200.0f;

View File

@ -8,6 +8,8 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_efc_tw/object_efc_tw.h"
#include "2s2h/BenPort.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20)
#define THIS ((DemoEffect*)thisx)
@ -164,7 +166,7 @@ void DemoEffect_SetupTimewarp(DemoEffect* this, PlayState* play) {
void DemoEffect_SetPerVertexAlpha(f32 alphaScale) {
static u8 sAlphaTypes[] = { 1, 1, 2, 0, 1, 1, 2, 0, 1, 2, 0, 2, 1, 0, 1, 0, 2, 0, 2, 2, 0 };
Vtx* vtx = Lib_SegmentedToVirtual(gTimewarpVtx);
Vtx* vtx = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(gTimewarpVtx));
s32 i;
u8 alphas[3];

View File

@ -7,6 +7,8 @@
#include "z_demo_syoten.h"
#include "objects/object_syoten/object_syoten.h"
#include "2s2h/BenPort.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20)
#define THIS ((DemoSyoten*)thisx)
@ -200,7 +202,7 @@ void func_80C168D0(DemoSyoten* this, PlayState* play) {
}
void func_80C16974(f32 arg0) {
Vtx* vtx = Lib_SegmentedToVirtual(&object_syotenVtx_0018C0);
Vtx* vtx = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(&object_syotenVtx_0018C0));
u8 sp20[3];
s32 i;

View File

@ -7,6 +7,8 @@
#include "z_eff_kamejima_wave.h"
#include "objects/object_kamejima/object_kamejima.h"
#include "2s2h/BenPort.h"
#define FLAGS (ACTOR_FLAG_10)
#define THIS ((EffKamejimaWave*)thisx)
@ -137,7 +139,7 @@ void EffKamejimaWave_Update(Actor* thisx, PlayState* play) {
}
void EffKamejimaWave_SetVtxAlpha(u8 alpha) {
Vtx* vtx = Lib_SegmentedToVirtual(&gTurtleWaveVtx);
Vtx* vtx = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(&gTurtleWaveVtx));
vtx[2].v.cn[3] = alpha;
vtx[6].v.cn[3] = alpha;

View File

@ -7,6 +7,8 @@
#include "z_eff_lastday.h"
#include "objects/object_lastday/object_lastday.h"
#include "2s2h/BenPort.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20)
#define THIS ((EffLastday*)thisx)
@ -224,7 +226,7 @@ void EffLastday_Update(Actor* thisx, PlayState* play) {
}
void EffLastday_SetVtxAlpha(s16 alpha) {
Vtx* vtx = Lib_SegmentedToVirtual(object_lastday_Vtx_000000);
Vtx* vtx = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(object_lastday_Vtx_000000));
vtx[0].v.cn[3] = alpha;
vtx[3].v.cn[3] = alpha;

View File

@ -7,6 +7,8 @@
#include "z_en_dy_extra.h"
#include "objects/object_dy_obj/object_dy_obj.h"
#include "2s2h/BenPort.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20)
#define THIS ((EnDyExtra*)thisx)
@ -102,7 +104,7 @@ void EnDyExtra_Draw(Actor* thisx, PlayState* play) {
s32 pad;
EnDyExtra* this = THIS;
GraphicsContext* gfxCtx = play->state.gfxCtx;
Vtx* vertices = Lib_SegmentedToVirtual(gGreatFairySpiralBeamVtx);
Vtx* vertices = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(gGreatFairySpiralBeamVtx));
s32 i;
u8 alphas[3];

View File

@ -22,6 +22,8 @@
#include "objects/object_lodmoon/object_lodmoon.h"
#include "objects/object_moonston/object_moonston.h"
#include "2s2h/BenPort.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20)
#define THIS ((EnFall*)thisx)
@ -581,7 +583,7 @@ static u8 sAlphaTableIndices[] = {
void EnFall_Fireball_SetPerVertexAlpha(f32 fireballAlpha) {
s32 pad;
u8 perVertexAlphaTable[5];
Vtx* vertices = Lib_SegmentedToVirtual(gMoonFireballVtx);
Vtx* vertices = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(gMoonFireballVtx));
s32 i;
if (fireballAlpha > 1.0f) {

View File

@ -7,6 +7,8 @@
#include "z_en_fall2.h"
#include "objects/object_fall2/object_fall2.h"
#include "2s2h/BenPort.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20)
#define THIS ((EnFall2*)thisx)
@ -62,7 +64,7 @@ static u8 sAlphaTableIndices[] = {
};
void func_80C1B724(f32 arg0) {
Vtx* vertex = Lib_SegmentedToVirtual(object_fall2_Vtx_005F10);
Vtx* vertex = ResourceMgr_LoadVtxByName(Lib_SegmentedToVirtual(object_fall2_Vtx_005F10));
u8 perVertexAlphaTable[6];
s32 i;

View File

@ -556,7 +556,7 @@ void KaleidoScope_DrawWorldMap(PlayState* play) {
if ((pauseCtx->pageIndex == PAUSE_MAP) && (pauseCtx->state == PAUSE_STATE_MAIN) &&
((pauseCtx->mainState == PAUSE_MAIN_STATE_IDLE) || (pauseCtx->mainState == PAUSE_MAIN_STATE_EQUIP_ITEM)) &&
YREG(6) && (pauseCtx->state != PAUSE_STATE_SAVEPROMPT) && !IS_PAUSE_STATE_GAMEOVER) {
char* tex = ResourceMgr_LoadTexOrDListByName(gWorldMapImageTex);
// Draw the world map image flat
// Because it is flat, the texture is loaded by filling it in 8 rows at a time.
// 8 is chosen because it is smaller than `TMEM_SIZE / 2 / textureWidth` and divides the texture's height.
@ -574,9 +574,19 @@ void KaleidoScope_DrawWorldMap(PlayState* play) {
// Process the 128 rows of pixels for gWorldMapImageTex, 8 rows at a time over 16 iterations
// Loop over yPos (t), textureIndex (j)
for (t = 62, j = 0; j < 16; j++, t += 8) {
gDPLoadTextureBlock(POLY_OPA_DISP++, &tex[j * (WORLD_MAP_IMAGE_WIDTH * 8)], G_IM_FMT_CI, G_IM_SIZ_8b,
WORLD_MAP_IMAGE_WIDTH, 8, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
// 2S2H [Port][HD Textures] Here and below we use LoadMultTile and SetTileSize to allow us to pass the
// resource path to the renderer and calculate the tile offset after the renderer loads it
/*
gDPLoadTextureBlock(POLY_OPA_DISP++, (u8*)gWorldMapImageTex + j * (WORLD_MAP_IMAGE_WIDTH * 8), G_IM_FMT_CI,
G_IM_SIZ_8b, WORLD_MAP_IMAGE_WIDTH, 8, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
*/
gDPLoadMultiTile(POLY_OPA_DISP++, gWorldMapImageTex, 0, G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b,
WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_HEIGHT, 0, j * 8, WORLD_MAP_IMAGE_WIDTH - 1,
(j + 1) * 8 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPSetTileSize(POLY_OPA_DISP++, G_TX_RENDERTILE, 0, 0, (WORLD_MAP_IMAGE_WIDTH - 1) << G_TEXTURE_IMAGE_FRAC,
(8 - 1) << G_TEXTURE_IMAGE_FRAC);
rectLeft = 51 << 2;
rectRight = rectLeft + (WORLD_MAP_IMAGE_WIDTH << 2);
@ -610,12 +620,19 @@ void KaleidoScope_DrawWorldMap(PlayState* play) {
// Process the first 72 rows of pixels for gWorldMapImageTex, 9 rows at a time over 8 iterations
// Loop over quadIndex of this loop (i), quadIndex of the entire texture (k), vtxIndex (j)
char* tex = ResourceMgr_LoadTexOrDListByName(gWorldMapImageTex);
for (i = 0, k = 0, j = 0; i < 8; i++, k++, j += 4) {
gDPLoadTextureBlock(POLY_OPA_DISP++, &tex[k * (WORLD_MAP_IMAGE_WIDTH * WORLD_MAP_IMAGE_FRAG_HEIGHT)],
G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_FRAG_HEIGHT, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
/*
gDPLoadTextureBlock(
POLY_OPA_DISP++, (u8*)gWorldMapImageTex + k * (WORLD_MAP_IMAGE_WIDTH * WORLD_MAP_IMAGE_FRAG_HEIGHT),
G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_FRAG_HEIGHT, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
*/
gDPLoadMultiTile(POLY_OPA_DISP++, gWorldMapImageTex, 0, G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b,
WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_HEIGHT, 0, k * 9, WORLD_MAP_IMAGE_WIDTH - 1,
(k + 1) * 9 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPSetTileSize(POLY_OPA_DISP++, G_TX_RENDERTILE, 0, 0, (WORLD_MAP_IMAGE_WIDTH - 1) << G_TEXTURE_IMAGE_FRAC,
(9 - 1) << G_TEXTURE_IMAGE_FRAC);
gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0);
}
@ -627,19 +644,36 @@ void KaleidoScope_DrawWorldMap(PlayState* play) {
// Process the next 54 rows of pixels for gWorldMapImageTex, 9 rows at a time over 6 iterations
// Loop over quadIndex of this loop (i), quadIndex of the entire texture (k), vtxIndex (j)
for (i = 0, j = 0; i < 6; i++, k++, j += 4) {
gDPLoadTextureBlock(POLY_OPA_DISP++, &tex[k * (WORLD_MAP_IMAGE_WIDTH * WORLD_MAP_IMAGE_FRAG_HEIGHT)],
G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_FRAG_HEIGHT, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
/*
gDPLoadTextureBlock(
POLY_OPA_DISP++, (u8*)gWorldMapImageTex + k * (WORLD_MAP_IMAGE_WIDTH * WORLD_MAP_IMAGE_FRAG_HEIGHT),
G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_FRAG_HEIGHT, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
*/
gDPLoadMultiTile(POLY_OPA_DISP++, gWorldMapImageTex, 0, G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b,
WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_HEIGHT, 0, k * 9, WORLD_MAP_IMAGE_WIDTH - 1,
(k + 1) * 9 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPSetTileSize(POLY_OPA_DISP++, G_TX_RENDERTILE, 0, 0, (WORLD_MAP_IMAGE_WIDTH - 1) << G_TEXTURE_IMAGE_FRAC,
(9 - 1) << G_TEXTURE_IMAGE_FRAC);
gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0);
}
// Process the last 2 rows of pixels for gWorldMapImageTex
gDPLoadTextureBlock(POLY_OPA_DISP++, &tex[k * (WORLD_MAP_IMAGE_WIDTH * WORLD_MAP_IMAGE_FRAG_HEIGHT)],
G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_WIDTH,
WORLD_MAP_IMAGE_HEIGHT % WORLD_MAP_IMAGE_FRAG_HEIGHT, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
/*
gDPLoadTextureBlock(
POLY_OPA_DISP++, (u8*)gWorldMapImageTex + k * (WORLD_MAP_IMAGE_WIDTH * WORLD_MAP_IMAGE_FRAG_HEIGHT),
G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_HEIGHT % WORLD_MAP_IMAGE_FRAG_HEIGHT, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
*/
gDPLoadMultiTile(POLY_OPA_DISP++, gWorldMapImageTex, 0, G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b,
WORLD_MAP_IMAGE_WIDTH, WORLD_MAP_IMAGE_HEIGHT, 0, k * 9, WORLD_MAP_IMAGE_WIDTH - 1,
(k * 9 + 2) - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPSetTileSize(POLY_OPA_DISP++, G_TX_RENDERTILE, 0, 0, (WORLD_MAP_IMAGE_WIDTH - 1) << G_TEXTURE_IMAGE_FRAC,
(2 - 1) << G_TEXTURE_IMAGE_FRAC);
gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0);
}