mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp
synced 2025-10-05 16:12:49 +02:00
1.2.1 Changes (#625)
* Update runtime for hook and callback sorting, update version number * Actually update version number * Automatically open mods menu when dragging a mod which also prevents issues when installing a mod from the launcher menu * Update RT64 to add texture pack shift configuration and fix minimized memory leak * Update runtime for return hook getter exports * Actually update rt64 * Update RT64 to fix texture pack ordering * Implement optional dependencies, fix memory slotmaps, bump version number to 1.2.1-dev * Add command-line option to show console output on Windows. (#632) * Add new raphnet adapter revision to controller DB * Add another mayflash N64 adapter to the controller database file * Update runtime after merge for optional dependencies * Update runtime for optional dependency mod callback fix * Add mayflash magic NS to controller database * Update RT64 for extended address fix and x11 dependency removal * Update RT64 to fix build issue caused by x11 * Update runtime to remove unnnecessary x11 includes * Fix more x11 define compilation issues * Fix the x86-64 CPU requirement listing in the readme (#634) * Transform tagging for keaton grass tornado * Interpolation for sword trails * Switch RT64 to gEXVertex fix branch (temporary until merge) * Add 8bitdo 64 bluetooth controller to database * Add export to get bowstring transform ID * Update RT64 to fix linux dev mode menu and texture streaming race condition * Fix all the interpolation glitches in the Gibdo Mask cutscene (#641) * Fix the actor extension API breaking when registering an extension for actor type 0 first * Remove slotmap submodule and integrate header directly after submodule URL changed * Transform tagging for ObjGrass * Adding autosave events. (#611) * Adding autosave events. Dead simple. * Update autosaving.c to include @recomp_event comments * Prevent autosaves during minigames and fix holding powder keg on autosave load (#640) * Update runtime for more accurate VI and switch to improved pacing RT64 branch (#644) * Update runtime for more accurate VI and switch to improved pacing RT64 branch * Update N64ModernRuntime and RT64 after merge * Update recompiler to match runtime symbol list * Remove unused gibdo patch file --------- Co-authored-by: Darío <dariosamo@gmail.com> Co-authored-by: Reonu <15913880+Reonu@users.noreply.github.com>
This commit is contained in:
2
.github/workflows/validate.yml
vendored
2
.github/workflows/validate.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
N64RECOMP_COMMIT:
|
||||
type: string
|
||||
required: false
|
||||
default: '989a86b36912403cd323de884bf834f2605ea770'
|
||||
default: 'a13e5cff96686776b0e03baf23923e3c1927b770'
|
||||
DXC_CHECKSUM:
|
||||
type: string
|
||||
required: false
|
||||
|
@@ -291,7 +291,7 @@ if (WIN32)
|
||||
)
|
||||
|
||||
target_sources(Zelda64Recompiled PRIVATE ${CMAKE_SOURCE_DIR}/icons/app.rc)
|
||||
target_link_libraries(Zelda64Recompiled PRIVATE SDL2)
|
||||
target_link_libraries(Zelda64Recompiled PRIVATE SDL2 Winmm.lib)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
|
@@ -48,7 +48,7 @@ A GPU supporting Direct3D 12.0 (Shader Model 6), Vulkan 1.2, or Metal Argument B
|
||||
* Intel HD 510 (Skylake)
|
||||
* A Mac with Apple Silicon or an Intel 7th Gen CPU with MacOS 13.0+
|
||||
|
||||
On x86-64 PCs, a CPU supporting the AVX instruction set is also required (Intel Core 2000 series or AMD Bulldozer and newer). ARM64 builds will work on any ARM64 CPU.
|
||||
On x86-64 PCs, a CPU supporting the SSE4.1 instruction set is also required (Intel Core 2 Penryn series or AMD Bulldozer and newer). ARM64 builds will work on any ARM64 CPU.
|
||||
|
||||
If you have issues with crashes on startup, make sure your graphics drivers are fully up to date.
|
||||
|
||||
|
@@ -27,7 +27,7 @@ namespace zelda64 {
|
||||
|
||||
void enable_instant_present() override;
|
||||
void send_dl(const OSTask *task) override;
|
||||
void update_screen(uint32_t vi_origin) override;
|
||||
void update_screen() override;
|
||||
void shutdown() override;
|
||||
uint32_t get_display_framerate() const override;
|
||||
float get_resolution_scale() const override;
|
||||
|
@@ -7,7 +7,8 @@
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "Zelda64Recompiled.exe",
|
||||
"name": "Zelda64Recompiled.exe",
|
||||
"currentDir": "${workspaceRoot}"
|
||||
"currentDir": "${workspaceRoot}",
|
||||
"args": ["--show-console"]
|
||||
}
|
||||
]
|
||||
}
|
Submodule lib/N64ModernRuntime updated: c5e268aa0f...df7e820d8c
2
lib/rt64
2
lib/rt64
Submodule lib/rt64 updated: ada6cc62c4...b552151c34
@@ -76,6 +76,17 @@ void camera_post_play_update(PlayState* play) {
|
||||
if (force_interpolation) {
|
||||
force_camera_interpolation();
|
||||
}
|
||||
// Dedicated section for workarounds where the heuristic fails to detect small camera teleports.
|
||||
bool force_no_interpolation = false;
|
||||
|
||||
// Music Box House. The camera gets teleported by a very small amount when Link gets the Gibdo mask.
|
||||
if (play->sceneId == SCENE_MUSICHOUSE && play->csCtx.scriptIndex == 2 && play->csCtx.curFrame == 525 && active_cam->setting == CAM_SET_FREE0) {
|
||||
force_no_interpolation = true;
|
||||
}
|
||||
|
||||
if (force_no_interpolation) {
|
||||
force_camera_skip_interpolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,3 +14,33 @@ symbols = [
|
||||
{ name = "FileSelect_Init_NORELOCATE", vram = 0x80813C98 },
|
||||
{ name = "DayTelop_Init_NORELOCATE", vram = 0x80815820 },
|
||||
]
|
||||
|
||||
[[section]]
|
||||
name = "..ovl_En_Hg"
|
||||
rom = 0x01034170
|
||||
vram = 0x80BCF1D0
|
||||
size = 0x10E0
|
||||
|
||||
symbols = [
|
||||
{ name = "sPamelasFatherGibdoAnimationInfo", vram = 0x80bd0008 },
|
||||
]
|
||||
|
||||
[[section]]
|
||||
name = "..ovl_En_Hgo"
|
||||
rom = 0x01035250
|
||||
vram = 0x80BD02B0
|
||||
size = 0xF30
|
||||
|
||||
symbols = [
|
||||
{ name = "sPamelasFatherHumanAnimationInfo", vram = 0x80BD0EA0 },
|
||||
]
|
||||
|
||||
[[section]]
|
||||
name = "..ovl_En_Pamera"
|
||||
rom = 0x0103D250
|
||||
vram = 0x80BD82B0
|
||||
size = 0x2780
|
||||
|
||||
symbols = [
|
||||
{ name = "sPamelaAnimationInfo", vram = 0x80BDA4B8 },
|
||||
]
|
||||
|
@@ -0,0 +1,45 @@
|
||||
typedef enum PamelasFatherGibdoLimb {
|
||||
/* 0x00 */ PAMELAS_FATHER_GIBDO_LIMB_NONE,
|
||||
/* 0x01 */ PAMELAS_FATHER_GIBDO_LIMB_ROOT,
|
||||
/* 0x02 */ PAMELAS_FATHER_GIBDO_LIMB_ABDOMEN,
|
||||
/* 0x03 */ PAMELAS_FATHER_GIBDO_LIMB_CHEST,
|
||||
/* 0x04 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_UPPER_ARM,
|
||||
/* 0x05 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_FOREARM,
|
||||
/* 0x06 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_HAND,
|
||||
/* 0x07 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_UPPER_ARM,
|
||||
/* 0x08 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_FOREARM,
|
||||
/* 0x09 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_HAND,
|
||||
/* 0x0A */ PAMELAS_FATHER_GIBDO_LIMB_EYEBROWS,
|
||||
/* 0x0B */ PAMELAS_FATHER_GIBDO_LIMB_HEAD,
|
||||
/* 0x0C */ PAMELAS_FATHER_GIBDO_LIMB_PELVIS,
|
||||
/* 0x0D */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_THIGH,
|
||||
/* 0x0E */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_SHIN,
|
||||
/* 0x0F */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_FOOT,
|
||||
/* 0x10 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_THIGH,
|
||||
/* 0x11 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_SHIN,
|
||||
/* 0x12 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_FOOT,
|
||||
/* 0x13 */ PAMELAS_FATHER_GIBDO_LIMB_MAX
|
||||
} PamelasFatherGibdoLimb;
|
||||
|
||||
typedef enum PamelasFatherHumanLimb {
|
||||
/* 0x00 */ PAMELAS_FATHER_HUMAN_LIMB_NONE,
|
||||
/* 0x01 */ PAMELAS_FATHER_HUMAN_LIMB_ROOT,
|
||||
/* 0x02 */ PAMELAS_FATHER_HUMAN_LIMB_ABDOMEN,
|
||||
/* 0x03 */ PAMELAS_FATHER_HUMAN_LIMB_CHEST,
|
||||
/* 0x04 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_UPPER_ARM,
|
||||
/* 0x05 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_FOREARM,
|
||||
/* 0x06 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_HAND,
|
||||
/* 0x07 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_UPPER_ARM,
|
||||
/* 0x08 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_FOREARM,
|
||||
/* 0x09 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_HAND,
|
||||
/* 0x0A */ PAMELAS_FATHER_HUMAN_LIMB_EYEBROWS,
|
||||
/* 0x0B */ PAMELAS_FATHER_HUMAN_LIMB_HEAD,
|
||||
/* 0x0C */ PAMELAS_FATHER_HUMAN_LIMB_PELVIS,
|
||||
/* 0x0D */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_THIGH,
|
||||
/* 0x0E */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_SHIN,
|
||||
/* 0x0F */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_FOOT,
|
||||
/* 0x10 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_THIGH,
|
||||
/* 0x11 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_SHIN,
|
||||
/* 0x12 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_FOOT,
|
||||
/* 0x13 */ PAMELAS_FATHER_HUMAN_LIMB_MAX
|
||||
} PamelasFatherHumanLimb;
|
26
patches/dummy_headers/objects/object_pamera/object_pamera.h
Normal file
26
patches/dummy_headers/objects/object_pamera/object_pamera.h
Normal file
@@ -0,0 +1,26 @@
|
||||
typedef enum PamelaLimb {
|
||||
/* 0x00 */ PAMELA_LIMB_NONE,
|
||||
/* 0x01 */ PAMELA_LIMB_ROOT,
|
||||
/* 0x02 */ PAMELA_LIMB_UPPER_BODY_ROOT,
|
||||
/* 0x03 */ PAMELA_LIMB_LEFT_UPPER_ARM,
|
||||
/* 0x04 */ PAMELA_LIMB_LEFT_FOREARM,
|
||||
/* 0x05 */ PAMELA_LIMB_LEFT_HAND,
|
||||
/* 0x06 */ PAMELA_LIMB_RIGHT_UPPER_ARM,
|
||||
/* 0x07 */ PAMELA_LIMB_RIGHT_FOREARM,
|
||||
/* 0x08 */ PAMELA_LIMB_RIGHT_HAND,
|
||||
/* 0x09 */ PAMELA_LIMB_HEAD,
|
||||
/* 0x0A */ PAMELA_LIMB_HAIR_END,
|
||||
/* 0x0B */ PAMELA_LIMB_CHEST,
|
||||
/* 0x0C */ PAMELA_LIMB_NECK,
|
||||
/* 0x0D */ PAMELA_LIMB_LEFT_THIGH,
|
||||
/* 0x0E */ PAMELA_LIMB_LEFT_LEG,
|
||||
/* 0x0F */ PAMELA_LIMB_LEFT_FOOT,
|
||||
/* 0x10 */ PAMELA_LIMB_RIGHT_THIGH,
|
||||
/* 0x11 */ PAMELA_LIMB_RIGHT_LEG,
|
||||
/* 0x12 */ PAMELA_LIMB_RIGHT_FOOT,
|
||||
/* 0x13 */ PAMELA_LIMB_FRONT_DRESS,
|
||||
/* 0x14 */ PAMELA_LIMB_BACK_DRESS,
|
||||
/* 0x15 */ PAMELA_LIMB_ABDOMEN,
|
||||
/* 0x16 */ PAMELA_LIMB_PELVIS,
|
||||
/* 0x17 */ PAMELA_LIMB_MAX
|
||||
} PamelaLimb;
|
107
patches/gibdo_mask_cutscene_father_human.c
Normal file
107
patches/gibdo_mask_cutscene_father_human.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "patches.h"
|
||||
#include "transform_ids.h"
|
||||
#include "overlays/actors/ovl_En_Hgo/z_en_hgo.h"
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ HGO_ANIM_ARMS_FOLDED,
|
||||
/* 1 */ HGO_ANIM_ASTONISHED,
|
||||
/* 2 */ HGO_ANIM_KNEEL_DOWN_AND_HUG,
|
||||
/* 3 */ HGO_ANIM_CONSOLE,
|
||||
/* 4 */ HGO_ANIM_CONSOLE_HEAD_UP,
|
||||
/* 5 */ HGO_ANIM_REACH_DOWN_TO_LIFT,
|
||||
/* 6 */ HGO_ANIM_TOSS,
|
||||
/* 7 */ HGO_ANIM_MAX
|
||||
} HgoAnimation;
|
||||
|
||||
extern AnimationInfo sPamelasFatherHumanAnimationInfo[];
|
||||
extern void EnHgo_Draw(Actor* thisx, PlayState* play);
|
||||
extern void EnHgo_DoNothing(EnHgo* this, PlayState* play);
|
||||
extern void EnHgo_SetupInitCollision(EnHgo* this);
|
||||
|
||||
// @recomp Skip interpolation when the animations change during the cutscene, as the
|
||||
// animation changes are meant to happen at the same time as the camera cuts.
|
||||
RECOMP_PATCH s32 EnHgo_HandleCsAction(EnHgo* this, PlayState* play) {
|
||||
s32 cueChannel;
|
||||
|
||||
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_486)) {
|
||||
cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_486);
|
||||
if (this->cueId != play->csCtx.actorCues[cueChannel]->id) {
|
||||
this->cueId = play->csCtx.actorCues[cueChannel]->id;
|
||||
switch (play->csCtx.actorCues[cueChannel]->id) {
|
||||
case 1:
|
||||
this->animIndex = HGO_ANIM_ARMS_FOLDED;
|
||||
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_ARMS_FOLDED);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
this->actor.draw = EnHgo_Draw;
|
||||
this->animIndex = HGO_ANIM_ASTONISHED;
|
||||
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_ASTONISHED);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
this->animIndex = HGO_ANIM_KNEEL_DOWN_AND_HUG;
|
||||
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_KNEEL_DOWN_AND_HUG);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
this->animIndex = HGO_ANIM_CONSOLE;
|
||||
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
this->animIndex = HGO_ANIM_CONSOLE_HEAD_UP;
|
||||
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE_HEAD_UP);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
this->animIndex = HGO_ANIM_REACH_DOWN_TO_LIFT;
|
||||
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_REACH_DOWN_TO_LIFT);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
actor_set_interpolation_skipped(&this->actor);
|
||||
} else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
|
||||
switch (this->animIndex) {
|
||||
case HGO_ANIM_ASTONISHED:
|
||||
if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && !this->isInCutscene) {
|
||||
this->isInCutscene = true;
|
||||
if ((gSaveContext.sceneLayer == 0) &&
|
||||
((play->csCtx.scriptIndex == 2) || (play->csCtx.scriptIndex == 4))) {
|
||||
Actor_PlaySfx(&this->actor, NA_SE_VO_GBVO02);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HGO_ANIM_KNEEL_DOWN_AND_HUG:
|
||||
this->animIndex = HGO_ANIM_CONSOLE;
|
||||
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE);
|
||||
break;
|
||||
|
||||
case HGO_ANIM_REACH_DOWN_TO_LIFT:
|
||||
this->animIndex = HGO_ANIM_TOSS;
|
||||
Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_TOSS);
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((play->csCtx.state == CS_STATE_IDLE) && CHECK_WEEKEVENTREG(WEEKEVENTREG_75_20) &&
|
||||
(this->actionFunc == EnHgo_DoNothing)) {
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y;
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, this->actor.focus.pos.x, this->actor.focus.pos.y,
|
||||
this->actor.focus.pos.z, 7, 0, 0, 0x7F5A);
|
||||
EnHgo_SetupInitCollision(this);
|
||||
}
|
||||
|
||||
this->cueId = 99;
|
||||
return false;
|
||||
}
|
26
patches/gibdo_mask_cutscene_mask.c
Normal file
26
patches/gibdo_mask_cutscene_mask.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "patches.h"
|
||||
#include "transform_ids.h"
|
||||
#include "overlays/actors/ovl_Dm_Char05/z_dm_char05.h"
|
||||
|
||||
extern void func_80AADF54(PlayState* play, DmChar05* this);
|
||||
|
||||
// @recomp Patched to avoid an interpolation glitch in Pamela's dad's cutscene
|
||||
// that happens when the mask is meant to teleport offscreen.
|
||||
RECOMP_PATCH void func_80AADB4C(Actor* thisx, PlayState* play) {
|
||||
DmChar05* this = (DmChar05*)thisx;
|
||||
if (this->unk_18E == 0) {
|
||||
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_518) &&
|
||||
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_518)]->id != 1)) {
|
||||
// @recomp During this cue the mask does nothing other than teleport offscreen and stay still,
|
||||
// so we can just skip interpolation the entire time.
|
||||
if (play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_518)]->id == 3) {
|
||||
actor_set_interpolation_skipped(thisx);
|
||||
}
|
||||
Gfx_SetupDL25_Opa(play->state.gfxCtx);
|
||||
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
|
||||
this->skelAnime.dListCount, NULL, NULL, &this->actor);
|
||||
}
|
||||
} else if (this->unk_18E == 1) {
|
||||
func_80AADF54(play, this);
|
||||
}
|
||||
}
|
74
patches/gibdo_mask_cutscene_pamela.c
Normal file
74
patches/gibdo_mask_cutscene_pamela.c
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "patches.h"
|
||||
#include "transform_ids.h"
|
||||
#include "overlays/actors/ovl_En_Pamera/z_en_pamera.h"
|
||||
|
||||
extern void EnPamera_Draw(Actor* thisx, PlayState* play);
|
||||
extern void func_80BD9E88(EnPamera* this);
|
||||
extern void func_80BD9EE0(EnPamera* this);
|
||||
extern void func_80BDA038(EnPamera* this);
|
||||
extern void func_80BDA0A0(EnPamera* this);
|
||||
extern void func_80BDA170(EnPamera* this);
|
||||
extern void func_80BDA288(EnPamera* this);
|
||||
extern void func_80BD994C(EnPamera* this, PlayState* play);
|
||||
extern void EnPamera_HandleDialogue(EnPamera* this, PlayState* play);
|
||||
extern void func_80BD9904(EnPamera* this);
|
||||
extern void func_80BD9E60(EnPamera* this);
|
||||
|
||||
// @recomp Skip interpolation when the animations change during the cutscene, as the
|
||||
// animation changes are meant to happen at the same time as the camera cuts.
|
||||
RECOMP_PATCH s32 func_80BD9CB8(EnPamera* this, PlayState* play) {
|
||||
s32 cueChannel;
|
||||
|
||||
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_485)) {
|
||||
cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_485);
|
||||
if (this->cueId != play->csCtx.actorCues[cueChannel]->id) {
|
||||
this->cueId = play->csCtx.actorCues[cueChannel]->id;
|
||||
|
||||
switch (play->csCtx.actorCues[cueChannel]->id) {
|
||||
case 1:
|
||||
func_80BD9E88(this);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (this->actor.draw == NULL) {
|
||||
this->actor.draw = EnPamera_Draw;
|
||||
this->actor.flags |= ACTOR_FLAG_TARGETABLE;
|
||||
}
|
||||
func_80BD9EE0(this);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
func_80BDA038(this);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
func_80BDA0A0(this);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
func_80BDA170(this);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
func_80BDA288(this);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
actor_set_interpolation_skipped(&this->actor);
|
||||
}
|
||||
Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel);
|
||||
this->setupFunc(this, play);
|
||||
return true;
|
||||
}
|
||||
if ((play->csCtx.state == CS_STATE_IDLE) && CHECK_WEEKEVENTREG(WEEKEVENTREG_75_20)) {
|
||||
if ((this->actionFunc != func_80BD994C) && (this->actionFunc != EnPamera_HandleDialogue)) {
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y;
|
||||
func_80BD9904(this);
|
||||
func_80BD9E60(this);
|
||||
}
|
||||
}
|
||||
this->cueId = 99;
|
||||
return false;
|
||||
}
|
@@ -185,3 +185,6 @@ RECOMP_PATCH void Player_DrawGameplay(PlayState* play, Player* this, s32 lod, Gf
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
RECOMP_EXPORT u32 z64recomp_get_bowstring_transform_id() {
|
||||
return BOWSTRING_TRANSFORM_ID;
|
||||
}
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include "overlays/actors/ovl_En_Twig/z_en_twig.h"
|
||||
#include "overlays/actors/ovl_En_Honotrap/z_en_honotrap.h"
|
||||
#include "overlays/actors/ovl_En_Tanron1/z_en_tanron1.h"
|
||||
#include "overlays/actors/ovl_En_Kusa2/z_en_kusa2.h"
|
||||
#include "overlays/actors/ovl_Obj_Grass/z_obj_grass.h"
|
||||
|
||||
// Decomp renames, TODO update decomp and remove these
|
||||
#define EnHonotrap_FlameGroup func_8092F878
|
||||
@@ -1331,3 +1333,154 @@ RECOMP_PATCH void func_80BB5AAC(EnTanron1* this, PlayState* play) {
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
extern Gfx gKakeraLeafTipDL[];
|
||||
extern Gfx gKakeraLeafMiddleDL[];
|
||||
extern EnKusa2UnkBssStruct D_80A5F1C0;
|
||||
|
||||
// Patched to tag the particles that spawn from Keaton grass.
|
||||
RECOMP_PATCH void func_80A5E6F0(Actor* thisx, PlayState* play) {
|
||||
static Gfx* D_80A5EB68[] = {
|
||||
gKakeraLeafTipDL,
|
||||
gKakeraLeafMiddleDL,
|
||||
};
|
||||
EnKusa2* this = (EnKusa2*)thisx;
|
||||
s32 i;
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
Gfx_SetupDL25_Opa(play->state.gfxCtx);
|
||||
|
||||
// @recomp Get the base transform ID for this actor.
|
||||
u32 cur_transform_id = actor_transform_id(thisx);
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0480); i++) {
|
||||
EnKusa2UnkBssSubStruct2* s = &D_80A5F1C0.unk_0480[i];
|
||||
|
||||
if (s->unk_2C > 0) {
|
||||
Matrix_SetTranslateRotateYXZ(s->unk_04.x, s->unk_04.y, s->unk_04.z, &s->unk_20);
|
||||
Matrix_Scale(s->unk_00, s->unk_00, s->unk_00, MTXMODE_APPLY);
|
||||
|
||||
// @recomp Create a matrix group for this particle.
|
||||
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, cur_transform_id + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
|
||||
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, D_80A5EB68[i & 1]);
|
||||
|
||||
// @recomp Pop the matrix group.
|
||||
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
extern Gfx gObjGrass_D_809AA9F0[];
|
||||
extern Gfx gObjGrass_D_809AAA68[];
|
||||
extern Gfx gObjGrass_D_809AAAE0[];
|
||||
void ObjGrass_OverrideMatrixCurrent(MtxF* matrix);
|
||||
|
||||
// @recomp Patched to set matrix groups for grass.
|
||||
RECOMP_PATCH void ObjGrass_DrawOpa(Actor* thisx, PlayState* play2) {
|
||||
ObjGrass* this = (ObjGrass*)thisx;
|
||||
PlayState* play = play2;
|
||||
Lights* lights;
|
||||
ObjGrassGroup* grassGroup;
|
||||
s32 i;
|
||||
s32 j;
|
||||
Vec3s rot = { 0, 0, 0 };
|
||||
ObjGrassElement* grassElem;
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
Gfx_SetupDL25_Opa(play->state.gfxCtx);
|
||||
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
|
||||
gSPDisplayList(POLY_OPA_DISP++, gObjGrass_D_809AA9F0);
|
||||
|
||||
// @recomp Extract this actor's ID.
|
||||
u32 actor_id = actor_transform_id(thisx);
|
||||
|
||||
for (i = 0; i < this->activeGrassGroups; i++) {
|
||||
grassGroup = &this->grassGroups[i];
|
||||
|
||||
if (grassGroup->flags & OBJ_GRASS_GROUP_DRAW) {
|
||||
lights = LightContext_NewLights(&play->lightCtx, play->state.gfxCtx);
|
||||
Lights_BindAll(lights, play->lightCtx.listHead, &grassGroup->homePos, play);
|
||||
Lights_Draw(lights, play->state.gfxCtx);
|
||||
|
||||
for (j = 0; j < grassGroup->count; j++) {
|
||||
grassElem = &grassGroup->elements[j];
|
||||
|
||||
if ((grassElem->flags & OBJ_GRASS_ELEM_DRAW) && (grassElem->alpha == 255)) {
|
||||
rot.y = grassElem->rotY;
|
||||
Matrix_SetTranslateRotateYXZ(grassElem->pos.x, grassElem->pos.y, grassElem->pos.z, &rot);
|
||||
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
|
||||
if (grassElem->flags & OBJ_GRASS_ELEM_ANIM) {
|
||||
ObjGrass_OverrideMatrixCurrent(&this->distortionMtx[j]);
|
||||
}
|
||||
|
||||
// @recomp Push a matrix group.
|
||||
gEXMatrixGroupDecomposedNormal(POLY_OPA_DISP++, actor_id + i * OBJ_GRASS_GROUP_ELEM_COUNT_MAX + j, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, gObjGrass_D_809AAAE0);
|
||||
|
||||
// @recomp Pop the matrix group.
|
||||
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
// @recomp Patched to set matrix groups for grass.
|
||||
RECOMP_PATCH void ObjGrass_DrawXlu(Actor* thisx, PlayState* play) {
|
||||
ObjGrass* this = (ObjGrass*)thisx;
|
||||
ObjGrassGroup* grassGroup;
|
||||
ObjGrassElement* grassElem;
|
||||
s32 i;
|
||||
s32 j;
|
||||
Vec3s rot = { 0, 0, 0 };
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
|
||||
|
||||
gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAA68);
|
||||
|
||||
// @recomp Extract this actor's ID.
|
||||
u32 actor_id = actor_transform_id(thisx);
|
||||
|
||||
for (i = 0; i < this->activeGrassGroups; i++) {
|
||||
grassGroup = &this->grassGroups[i];
|
||||
|
||||
if (grassGroup->flags & OBJ_GRASS_GROUP_DRAW) {
|
||||
for (j = 0; j < grassGroup->count; j++) {
|
||||
grassElem = &grassGroup->elements[j];
|
||||
|
||||
if ((grassElem->flags & OBJ_GRASS_ELEM_DRAW) && (grassElem->alpha > 0) && (grassElem->alpha < 255)) {
|
||||
rot.y = grassElem->rotY;
|
||||
Matrix_SetTranslateRotateYXZ(grassElem->pos.x, grassElem->pos.y, grassElem->pos.z, &rot);
|
||||
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
|
||||
|
||||
// @recomp Push a matrix group.
|
||||
gEXMatrixGroupDecomposedNormal(POLY_XLU_DISP++, actor_id + i * OBJ_GRASS_GROUP_ELEM_COUNT_MAX + j, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, grassElem->alpha);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAAE0);
|
||||
|
||||
// @recomp Pop the matrix group.
|
||||
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
509
patches/sword_trail_transform_tagging.c
Normal file
509
patches/sword_trail_transform_tagging.c
Normal file
@@ -0,0 +1,509 @@
|
||||
#include "patches.h"
|
||||
|
||||
#define VTX_EX_T(x, y, z, s, t, cr, cg, cb, a, px, py, pz) \
|
||||
{ { x, y, z }, 0, { s, t }, { cr, cg, cb, a }, {px, py, pz} }
|
||||
|
||||
void EffectBlure_GetComputedValues(EffectBlure* this, s32 index, f32 ratio, Vec3s* vec1, Vec3s* vec2,
|
||||
Color_RGBA8* color1, Color_RGBA8* color2);
|
||||
void EffectBlure_DrawSimple(EffectBlure* this2, GraphicsContext* gfxCtx);
|
||||
void EffectBlure_DrawSmooth(EffectBlure* this2, GraphicsContext* gfxCtx);
|
||||
|
||||
// @recomp Patched to interpolate the vertices towards the front of the trail section if this is the last trail being drawn currently.
|
||||
RECOMP_PATCH void EffectBlure_DrawElemNoInterpolation(EffectBlure* this, EffectBlureElement* elem, s32 index,
|
||||
GraphicsContext* gfxCtx) {
|
||||
// @recomp Change baseVtx to a VertexEX.
|
||||
static VertexEXColor baseVtx = VTX_EX_T(/* pos */ 0, 0, 0, /* st */ 0, 0, /* color */ 255, 255, 255, 255, /* prev pos */ 0, 0, 0);
|
||||
// @recomp Change the vertex type to VertexEX.
|
||||
VertexEX* vtx;
|
||||
Vec3s sp8C;
|
||||
Vec3s sp84;
|
||||
f32 ratio;
|
||||
Color_RGBA8 sp7C;
|
||||
Color_RGBA8 sp78;
|
||||
Vec3f sp6C;
|
||||
Vec3f sp60;
|
||||
Vec3f sp54;
|
||||
|
||||
OPEN_DISPS(gfxCtx);
|
||||
|
||||
Math_Vec3s_ToVec3f(&sp6C, &this->elements[0].p2);
|
||||
|
||||
// @recomp Debug print.
|
||||
// recomp_printf("No interpolation index %d:\n"
|
||||
// " Blure: calcMode %08X flags: %04X addAngle %04X addAngle %04X elemDuration %d\n"
|
||||
// " Element: state %08X timer: %d flags %04X\n",
|
||||
// index,
|
||||
// this->calcMode, this->flags, (u16)this->addAngleChange, (u16)this->addAngle, this->elemDuration,
|
||||
// elem->state, elem->timer, elem->flags);
|
||||
|
||||
// @recomp Allocate using the size of VertexEX instead.
|
||||
vtx = GRAPH_ALLOC(gfxCtx, 4 * sizeof(VertexEX));
|
||||
if (vtx == NULL) {
|
||||
} else {
|
||||
vtx[0].v = baseVtx;
|
||||
vtx[1].v = baseVtx;
|
||||
vtx[2].v = baseVtx;
|
||||
vtx[3].v = baseVtx;
|
||||
|
||||
ratio = (f32)elem->timer / (f32)this->elemDuration;
|
||||
EffectBlure_GetComputedValues(this, index, ratio, &sp8C, &sp84, &sp7C, &sp78);
|
||||
|
||||
sp60.x = sp84.x;
|
||||
sp60.y = sp84.y;
|
||||
sp60.z = sp84.z;
|
||||
Math_Vec3f_Diff(&sp60, &sp6C, &sp54);
|
||||
Math_Vec3f_Scale(&sp54, 10.0f);
|
||||
vtx[0].v.ob[0] = sp54.x;
|
||||
vtx[0].v.ob[1] = sp54.y;
|
||||
vtx[0].v.ob[2] = sp54.z;
|
||||
vtx[0].v.cn[0] = sp78.r;
|
||||
vtx[0].v.cn[1] = sp78.g;
|
||||
vtx[0].v.cn[2] = sp78.b;
|
||||
vtx[0].v.cn[3] = sp78.a;
|
||||
|
||||
sp60.x = sp8C.x;
|
||||
sp60.y = sp8C.y;
|
||||
sp60.z = sp8C.z;
|
||||
Math_Vec3f_Diff(&sp60, &sp6C, &sp54);
|
||||
Math_Vec3f_Scale(&sp54, 10.0f);
|
||||
vtx[1].v.ob[0] = sp54.x;
|
||||
vtx[1].v.ob[1] = sp54.y;
|
||||
vtx[1].v.ob[2] = sp54.z;
|
||||
vtx[1].v.cn[0] = sp7C.r;
|
||||
vtx[1].v.cn[1] = sp7C.g;
|
||||
vtx[1].v.cn[2] = sp7C.b;
|
||||
vtx[1].v.cn[3] = sp7C.a;
|
||||
|
||||
ratio = (f32)(elem + 1)->timer / (f32)this->elemDuration;
|
||||
EffectBlure_GetComputedValues(this, index + 1, ratio, &sp8C, &sp84, &sp7C, &sp78);
|
||||
|
||||
sp60.x = sp8C.x;
|
||||
sp60.y = sp8C.y;
|
||||
sp60.z = sp8C.z;
|
||||
Math_Vec3f_Diff(&sp60, &sp6C, &sp54);
|
||||
Math_Vec3f_Scale(&sp54, 10.0f);
|
||||
vtx[2].v.ob[0] = sp54.x;
|
||||
vtx[2].v.ob[1] = sp54.y;
|
||||
vtx[2].v.ob[2] = sp54.z;
|
||||
vtx[2].v.cn[0] = sp7C.r;
|
||||
vtx[2].v.cn[1] = sp7C.g;
|
||||
vtx[2].v.cn[2] = sp7C.b;
|
||||
vtx[2].v.cn[3] = sp7C.a;
|
||||
|
||||
sp60.x = sp84.x;
|
||||
sp60.y = sp84.y;
|
||||
sp60.z = sp84.z;
|
||||
Math_Vec3f_Diff(&sp60, &sp6C, &sp54);
|
||||
Math_Vec3f_Scale(&sp54, 10.0f);
|
||||
vtx[3].v.ob[0] = sp54.x;
|
||||
vtx[3].v.ob[1] = sp54.y;
|
||||
vtx[3].v.ob[2] = sp54.z;
|
||||
vtx[3].v.cn[0] = sp78.r;
|
||||
vtx[3].v.cn[1] = sp78.g;
|
||||
vtx[3].v.cn[2] = sp78.b;
|
||||
vtx[3].v.cn[3] = sp78.a;
|
||||
|
||||
// @recomp Set the previous position of the first two vertices to their current position.
|
||||
vtx[0].v.obp[0] = vtx[0].v.ob[0];
|
||||
vtx[0].v.obp[1] = vtx[0].v.ob[1];
|
||||
vtx[0].v.obp[2] = vtx[0].v.ob[2];
|
||||
vtx[1].v.obp[0] = vtx[1].v.ob[0];
|
||||
vtx[1].v.obp[1] = vtx[1].v.ob[1];
|
||||
vtx[1].v.obp[2] = vtx[1].v.ob[2];
|
||||
|
||||
// @recomp If this trail just spawned (timer == 2), set the previous vertex positions for the last two vertices to the positions of the last two (interpolation).
|
||||
// Otherwise, set them to the current position of the respective vertex (no interpolation).
|
||||
if (elem->timer == 2) {
|
||||
// Vertex 2 interpolates from a start position equal to the position of vertex 1.
|
||||
vtx[2].v.obp[0] = vtx[1].v.ob[0];
|
||||
vtx[2].v.obp[1] = vtx[1].v.ob[1];
|
||||
vtx[2].v.obp[2] = vtx[1].v.ob[2];
|
||||
// Vertex 3 interpolates from a start position equal to the position of vertex 0.
|
||||
vtx[3].v.obp[0] = vtx[0].v.ob[0];
|
||||
vtx[3].v.obp[1] = vtx[0].v.ob[1];
|
||||
vtx[3].v.obp[2] = vtx[0].v.ob[2];
|
||||
}
|
||||
else {
|
||||
vtx[2].v.obp[0] = vtx[2].v.ob[0];
|
||||
vtx[2].v.obp[1] = vtx[2].v.ob[1];
|
||||
vtx[2].v.obp[2] = vtx[2].v.ob[2];
|
||||
vtx[3].v.obp[0] = vtx[3].v.ob[0];
|
||||
vtx[3].v.obp[1] = vtx[3].v.ob[1];
|
||||
vtx[3].v.obp[2] = vtx[3].v.ob[2];
|
||||
}
|
||||
|
||||
// @recomp Use gEXVertex in place of gSPVertex.
|
||||
gEXVertex(POLY_XLU_DISP++, vtx, 4, 0);
|
||||
gSP2Triangles(POLY_XLU_DISP++, 0, 1, 2, 0, 0, 2, 3, 0);
|
||||
}
|
||||
|
||||
CLOSE_DISPS(gfxCtx);
|
||||
}
|
||||
|
||||
// @recomp Patched to interpolate the vertices towards the front of the trail section if this is the last trail being drawn currently.
|
||||
RECOMP_PATCH void EffectBlure_DrawElemHermiteInterpolation(EffectBlure* this, EffectBlureElement* elem, s32 index,
|
||||
GraphicsContext* gfxCtx) {
|
||||
// @recomp Change baseVtx to a VertexEX.
|
||||
static VertexEXColor baseVtx = VTX_EX_T(/* pos */ 0, 0, 0, /* st */ 0, 0, /* color */ 255, 255, 255, 255, /* prev pos */ 0, 0, 0);
|
||||
// @recomp Change the vertex type to VertexEX.
|
||||
VertexEX* vtx;
|
||||
Vec3s sp1EC;
|
||||
Vec3s sp1E4;
|
||||
f32 ratio;
|
||||
Color_RGBA8 sp1DC;
|
||||
Color_RGBA8 sp1D8;
|
||||
Vec3f sp1CC;
|
||||
Vec3f sp1C0;
|
||||
Vec3f sp1B4;
|
||||
Vec3f sp1A8;
|
||||
Color_RGBA8 sp1A4;
|
||||
Color_RGBA8 sp1A0;
|
||||
Color_RGBA8 sp19C;
|
||||
Color_RGBA8 sp198;
|
||||
Vec3f sp18C;
|
||||
Vec3f sp180;
|
||||
Vec3f sp174;
|
||||
Vec3f sp168;
|
||||
s32 i;
|
||||
Vec3f sp158;
|
||||
Vec3f sp14C;
|
||||
Color_RGBA8 sp148;
|
||||
Color_RGBA8 sp144;
|
||||
Vec3f sp138;
|
||||
|
||||
// @recomp Debug print.
|
||||
// recomp_printf("Hermite interpolation index %d:\n"
|
||||
// " Blure: calcMode %08X flags: %04X addAngle %04X addAngle %04X elemDuration %d\n"
|
||||
// " Element: state %08X timer: %d flags %04X\n",
|
||||
// index,
|
||||
// this->calcMode, this->flags, (u16)this->addAngleChange, (u16)this->addAngle, this->elemDuration,
|
||||
// elem->state, elem->timer, elem->flags);
|
||||
|
||||
OPEN_DISPS(gfxCtx);
|
||||
|
||||
Math_Vec3s_ToVec3f(&sp138, &this->elements[0].p2);
|
||||
|
||||
ratio = (f32)elem->timer / (f32)this->elemDuration;
|
||||
EffectBlure_GetComputedValues(this, index, ratio, &sp1EC, &sp1E4, &sp1A4, &sp1A0);
|
||||
Math_Vec3s_ToVec3f(&sp1CC, &sp1EC);
|
||||
Math_Vec3s_ToVec3f(&sp1C0, &sp1E4);
|
||||
|
||||
ratio = (f32)(elem + 1)->timer / (f32)this->elemDuration;
|
||||
EffectBlure_GetComputedValues(this, index + 1, ratio, &sp1EC, &sp1E4, &sp19C, &sp198);
|
||||
Math_Vec3s_ToVec3f(&sp18C, &sp1EC);
|
||||
Math_Vec3s_ToVec3f(&sp180, &sp1E4);
|
||||
|
||||
if ((elem->flags & (EFFECT_BLURE_ELEMENT_FLAG_1 | EFFECT_BLURE_ELEMENT_FLAG_2)) == EFFECT_BLURE_ELEMENT_FLAG_2) {
|
||||
Math_Vec3f_Diff(&sp18C, &sp1CC, &sp1B4);
|
||||
Math_Vec3f_Diff(&sp180, &sp1C0, &sp1A8);
|
||||
} else {
|
||||
Vec3f sp118;
|
||||
Vec3f sp10C;
|
||||
|
||||
ratio = (f32)(elem - 1)->timer / (f32)this->elemDuration;
|
||||
EffectBlure_GetComputedValues(this, index - 1, ratio, &sp1EC, &sp1E4, &sp1DC, &sp1D8);
|
||||
Math_Vec3s_ToVec3f(&sp118, &sp1EC);
|
||||
Math_Vec3s_ToVec3f(&sp10C, &sp1E4);
|
||||
Math_Vec3f_Diff(&sp18C, &sp118, &sp1B4);
|
||||
Math_Vec3f_Diff(&sp180, &sp10C, &sp1A8);
|
||||
}
|
||||
|
||||
Math_Vec3f_Scale(&sp1B4, 0.5f);
|
||||
Math_Vec3f_Scale(&sp1A8, 0.5f);
|
||||
|
||||
if (((elem + 1)->flags & (EFFECT_BLURE_ELEMENT_FLAG_1 | EFFECT_BLURE_ELEMENT_FLAG_2)) ==
|
||||
EFFECT_BLURE_ELEMENT_FLAG_2) {
|
||||
Math_Vec3f_Diff(&sp18C, &sp1CC, &sp174);
|
||||
Math_Vec3f_Diff(&sp180, &sp1C0, &sp168);
|
||||
} else {
|
||||
Vec3f sp100;
|
||||
Vec3f spF4;
|
||||
|
||||
ratio = (f32)(elem + 2)->timer / (f32)this->elemDuration;
|
||||
EffectBlure_GetComputedValues(this, index + 2, ratio, &sp1EC, &sp1E4, &sp1DC, &sp1D8);
|
||||
Math_Vec3s_ToVec3f(&sp100, &sp1EC);
|
||||
Math_Vec3s_ToVec3f(&spF4, &sp1E4);
|
||||
Math_Vec3f_Diff(&sp100, &sp1CC, &sp174);
|
||||
Math_Vec3f_Diff(&spF4, &sp1C0, &sp168);
|
||||
}
|
||||
|
||||
Math_Vec3f_Scale(&sp174, 0.5f);
|
||||
Math_Vec3f_Scale(&sp168, 0.5f);
|
||||
|
||||
// @recomp Allocate using the size of VertexEX instead.
|
||||
vtx = GRAPH_ALLOC(gfxCtx, 16 * sizeof(VertexEX));
|
||||
if (vtx == NULL) {
|
||||
} else {
|
||||
Math_Vec3f_Diff(&sp1CC, &sp138, &sp158);
|
||||
Math_Vec3f_Scale(&sp158, 10.0f);
|
||||
Math_Vec3f_Diff(&sp1C0, &sp138, &sp14C);
|
||||
Math_Vec3f_Scale(&sp14C, 10.0f);
|
||||
|
||||
Color_RGBA8_Copy(&sp148, &sp1A4);
|
||||
Color_RGBA8_Copy(&sp144, &sp1A0);
|
||||
|
||||
vtx[0].v = baseVtx;
|
||||
vtx[1].v = baseVtx;
|
||||
|
||||
vtx[0].v.ob[0] = Math_FNearbyIntF(sp158.x);
|
||||
vtx[0].v.ob[1] = Math_FNearbyIntF(sp158.y);
|
||||
vtx[0].v.ob[2] = Math_FNearbyIntF(sp158.z);
|
||||
vtx[0].v.cn[0] = sp148.r;
|
||||
vtx[0].v.cn[1] = sp148.g;
|
||||
vtx[0].v.cn[2] = sp148.b;
|
||||
vtx[0].v.cn[3] = sp148.a;
|
||||
vtx[1].v.ob[0] = Math_FNearbyIntF(sp14C.x);
|
||||
vtx[1].v.ob[1] = Math_FNearbyIntF(sp14C.y);
|
||||
vtx[1].v.ob[2] = Math_FNearbyIntF(sp14C.z);
|
||||
vtx[1].v.cn[0] = sp144.r;
|
||||
vtx[1].v.cn[1] = sp144.g;
|
||||
vtx[1].v.cn[2] = sp144.b;
|
||||
vtx[1].v.cn[3] = sp144.a;
|
||||
|
||||
// @recomp Set the previous position of the first two vertices to their current position.
|
||||
vtx[0].v.obp[0] = vtx[0].v.ob[0];
|
||||
vtx[0].v.obp[1] = vtx[0].v.ob[1];
|
||||
vtx[0].v.obp[2] = vtx[0].v.ob[2];
|
||||
vtx[1].v.obp[0] = vtx[1].v.ob[0];
|
||||
vtx[1].v.obp[1] = vtx[1].v.ob[1];
|
||||
vtx[1].v.obp[2] = vtx[1].v.ob[2];
|
||||
|
||||
for (i = 1; i < 8; i++) {
|
||||
s32 j1 = 2 * i;
|
||||
s32 j2 = 2 * i + 1;
|
||||
Vec3f spE0;
|
||||
f32 temp_f28 = i / 7.0f; // t
|
||||
f32 temp_f0 = SQ(temp_f28); // t^2
|
||||
f32 temp_f2 = temp_f0 * temp_f28; // t^3
|
||||
f32 temp_f20 = temp_f2 - temp_f0; // t^3 - t^2
|
||||
f32 temp_f22 = temp_f2 - 2.0f * temp_f0 + temp_f28; // t^3 - 2t^2 + t
|
||||
f32 temp_f24 = 2.0f * temp_f2 - temp_f0 * 3.0f + 1.0f; // 2t^3 - 3t^2 + 1
|
||||
f32 temp_f26 = temp_f0 * 3.0f - 2.0f * temp_f2; // 3t^2 - 2t^3
|
||||
s32 pad1;
|
||||
s32 pad2;
|
||||
|
||||
// p = (2t^3 - 3t^2 + 1)p0 + (3t^2 - 2t^3)p1 + (t^3 - 2t^2 + t)m0 + (t^3 - t^2)m1
|
||||
spE0.x = (temp_f24 * sp1CC.x) + (temp_f26 * sp18C.x) + (temp_f22 * sp1B4.x) + (temp_f20 * sp174.x);
|
||||
spE0.y = (temp_f24 * sp1CC.y) + (temp_f26 * sp18C.y) + (temp_f22 * sp1B4.y) + (temp_f20 * sp174.y);
|
||||
spE0.z = (temp_f24 * sp1CC.z) + (temp_f26 * sp18C.z) + (temp_f22 * sp1B4.z) + (temp_f20 * sp174.z);
|
||||
Math_Vec3f_Diff(&spE0, &sp138, &sp158);
|
||||
Math_Vec3f_Scale(&sp158, 10.0f);
|
||||
|
||||
spE0.x = (temp_f24 * sp1C0.x) + (temp_f26 * sp180.x) + (temp_f22 * sp1A8.x) + (temp_f20 * sp168.x);
|
||||
spE0.y = (temp_f24 * sp1C0.y) + (temp_f26 * sp180.y) + (temp_f22 * sp1A8.y) + (temp_f20 * sp168.y);
|
||||
spE0.z = (temp_f24 * sp1C0.z) + (temp_f26 * sp180.z) + (temp_f22 * sp1A8.z) + (temp_f20 * sp168.z);
|
||||
Math_Vec3f_Diff(&spE0, &sp138, &sp14C);
|
||||
Math_Vec3f_Scale(&sp14C, 10.0f);
|
||||
|
||||
vtx[j1].v = baseVtx;
|
||||
vtx[j2].v = baseVtx;
|
||||
|
||||
vtx[j1].v.ob[0] = Math_FNearbyIntF(sp158.x);
|
||||
vtx[j1].v.ob[1] = Math_FNearbyIntF(sp158.y);
|
||||
vtx[j1].v.ob[2] = Math_FNearbyIntF(sp158.z);
|
||||
vtx[j1].v.cn[0] = func_800B0A24(sp1A4.r, sp19C.r, temp_f28);
|
||||
vtx[j1].v.cn[1] = func_800B0A24(sp1A4.g, sp19C.g, temp_f28);
|
||||
vtx[j1].v.cn[2] = func_800B0A24(sp1A4.b, sp19C.b, temp_f28);
|
||||
vtx[j1].v.cn[3] = func_800B0A24(sp1A4.a, sp19C.a, temp_f28);
|
||||
|
||||
vtx[j2].v.ob[0] = Math_FNearbyIntF(sp14C.x);
|
||||
vtx[j2].v.ob[1] = Math_FNearbyIntF(sp14C.y);
|
||||
vtx[j2].v.ob[2] = Math_FNearbyIntF(sp14C.z);
|
||||
vtx[j2].v.cn[0] = func_800B0A24(sp1A0.r, sp198.r, temp_f28);
|
||||
vtx[j2].v.cn[1] = func_800B0A24(sp1A0.g, sp198.g, temp_f28);
|
||||
vtx[j2].v.cn[2] = func_800B0A24(sp1A0.b, sp198.b, temp_f28);
|
||||
vtx[j2].v.cn[3] = func_800B0A24(sp1A0.a, sp198.a, temp_f28);
|
||||
|
||||
// @recomp If this trail just spawned (timer == 2), set the previous vertex positions for the remaining vertices to the positions of the first two (interpolation).
|
||||
// Otherwise, set them to the current position of the respective vertex (no interpolation).
|
||||
if (elem->timer == 2) {
|
||||
vtx[j1].v.obp[0] = vtx[0].v.ob[0];
|
||||
vtx[j1].v.obp[1] = vtx[0].v.ob[1];
|
||||
vtx[j1].v.obp[2] = vtx[0].v.ob[2];
|
||||
vtx[j2].v.obp[0] = vtx[1].v.ob[0];
|
||||
vtx[j2].v.obp[1] = vtx[1].v.ob[1];
|
||||
vtx[j2].v.obp[2] = vtx[1].v.ob[2];
|
||||
}
|
||||
else {
|
||||
vtx[j1].v.obp[0] = vtx[j1].v.ob[0];
|
||||
vtx[j1].v.obp[1] = vtx[j1].v.ob[1];
|
||||
vtx[j1].v.obp[2] = vtx[j1].v.ob[2];
|
||||
vtx[j2].v.obp[0] = vtx[j2].v.ob[0];
|
||||
vtx[j2].v.obp[1] = vtx[j2].v.ob[1];
|
||||
vtx[j2].v.obp[2] = vtx[j2].v.ob[2];
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Use gEXVertex in place of gSPVertex.
|
||||
gEXVertex(POLY_XLU_DISP++, vtx, 16, 0);
|
||||
gSP2Triangles(POLY_XLU_DISP++, 0, 1, 3, 0, 0, 3, 2, 0);
|
||||
gSP2Triangles(POLY_XLU_DISP++, 2, 3, 5, 0, 2, 5, 4, 0);
|
||||
gSP2Triangles(POLY_XLU_DISP++, 4, 5, 7, 0, 4, 7, 6, 0);
|
||||
gSP2Triangles(POLY_XLU_DISP++, 6, 7, 9, 0, 6, 9, 8, 0);
|
||||
gSP2Triangles(POLY_XLU_DISP++, 8, 9, 11, 0, 8, 11, 10, 0);
|
||||
gSP2Triangles(POLY_XLU_DISP++, 10, 11, 13, 0, 10, 13, 12, 0);
|
||||
gSP2Triangles(POLY_XLU_DISP++, 12, 13, 15, 0, 12, 15, 14, 0);
|
||||
}
|
||||
|
||||
CLOSE_DISPS(gfxCtx);
|
||||
}
|
||||
|
||||
// @recomp Patched to interpolate the vertices towards the front of the trail section if this is the last trail being drawn currently.
|
||||
RECOMP_PATCH void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
|
||||
EffectBlure* this = (EffectBlure*)thisx;
|
||||
// @recomp Change the vertex type to VertexEX.
|
||||
VertexEX* vtx;
|
||||
EffectBlureElement* elem;
|
||||
s32 i;
|
||||
s32 j;
|
||||
s32 phi_t2;
|
||||
|
||||
OPEN_DISPS(gfxCtx);
|
||||
|
||||
gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
if (this->numElements != 0) {
|
||||
if (this->flags == 0) {
|
||||
Gfx_SetupDL38_Xlu(gfxCtx);
|
||||
gDPPipeSync(POLY_XLU_DISP++);
|
||||
|
||||
// @recomp Allocate using the size of VertexEX instead.
|
||||
vtx = GRAPH_ALLOC(gfxCtx, 32 * sizeof(VertexEX));
|
||||
if (vtx == NULL) {
|
||||
} else {
|
||||
j = 0;
|
||||
for (i = 0; i < this->numElements; i++) {
|
||||
elem = &this->elements[i];
|
||||
|
||||
// @recomp Debug print.
|
||||
// recomp_printf("Flag 0 %d:\n"
|
||||
// " Blure: calcMode %08X flags: %04X addAngle %04X addAngle %04X elemDuration %d\n"
|
||||
// " Element: state %08X timer: %d flags %04X\n",
|
||||
// i,
|
||||
// this->calcMode, this->flags, (u16)this->addAngleChange, (u16)this->addAngle, this->elemDuration,
|
||||
// elem->state, elem->timer, elem->flags);
|
||||
|
||||
if (elem->state == 1) {
|
||||
f32 ratio = (f32)elem->timer / (f32)this->elemDuration;
|
||||
|
||||
switch (this->calcMode) {
|
||||
case 1:
|
||||
vtx[j].v.ob[0] = func_800B09D0(elem->p1.x, elem->p2.x, ratio);
|
||||
vtx[j].v.ob[1] = func_800B09D0(elem->p1.y, elem->p2.y, ratio);
|
||||
vtx[j].v.ob[2] = func_800B09D0(elem->p1.z, elem->p2.z, ratio);
|
||||
vtx[j + 1].v.ob[0] = elem->p2.x;
|
||||
vtx[j + 1].v.ob[1] = elem->p2.y;
|
||||
vtx[j + 1].v.ob[2] = elem->p2.z;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
vtx[j].v.ob[0] = elem->p1.x;
|
||||
vtx[j].v.ob[1] = elem->p1.y;
|
||||
vtx[j].v.ob[2] = elem->p1.z;
|
||||
vtx[j + 1].v.ob[0] = func_800B09D0(elem->p2.x, elem->p1.x, ratio);
|
||||
vtx[j + 1].v.ob[1] = func_800B09D0(elem->p2.y, elem->p1.y, ratio);
|
||||
vtx[j + 1].v.ob[2] = func_800B09D0(elem->p2.z, elem->p1.z, ratio);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
ratio *= 0.5f;
|
||||
vtx[j].v.ob[0] = func_800B09D0(elem->p1.x, elem->p2.x, ratio);
|
||||
vtx[j].v.ob[1] = func_800B09D0(elem->p1.y, elem->p2.y, ratio);
|
||||
vtx[j].v.ob[2] = func_800B09D0(elem->p1.z, elem->p2.z, ratio);
|
||||
vtx[j + 1].v.ob[0] = func_800B09D0(elem->p2.x, elem->p1.x, ratio);
|
||||
vtx[j + 1].v.ob[1] = func_800B09D0(elem->p2.y, elem->p1.y, ratio);
|
||||
vtx[j + 1].v.ob[2] = func_800B09D0(elem->p2.z, elem->p1.z, ratio);
|
||||
ratio *= 2.0f;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
vtx[j].v.ob[0] = elem->p1.x;
|
||||
vtx[j].v.ob[1] = elem->p1.y;
|
||||
vtx[j].v.ob[2] = elem->p1.z;
|
||||
vtx[j + 1].v.ob[0] = elem->p2.x;
|
||||
vtx[j + 1].v.ob[1] = elem->p2.y;
|
||||
vtx[j + 1].v.ob[2] = elem->p2.z;
|
||||
break;
|
||||
}
|
||||
|
||||
// @recomp If this trail just spawned (timer == 1), set the previous vertex positions for this vertex that of the second previous vertex (interpolation).
|
||||
// Otherwise, set them to the current position of the respective vertex (no interpolation).
|
||||
if (elem->timer == 1 && j >= 2) {
|
||||
vtx[j].v.obp[0] = vtx[j - 2].v.ob[0];
|
||||
vtx[j].v.obp[1] = vtx[j - 2].v.ob[1];
|
||||
vtx[j].v.obp[2] = vtx[j - 2].v.ob[2];
|
||||
}
|
||||
else {
|
||||
vtx[j].v.obp[0] = vtx[j].v.ob[0];
|
||||
vtx[j].v.obp[1] = vtx[j].v.ob[1];
|
||||
vtx[j].v.obp[2] = vtx[j].v.ob[2];
|
||||
}
|
||||
|
||||
vtx[j].v.flag = 0;
|
||||
vtx[j].v.tc[0] = 0;
|
||||
vtx[j].v.tc[1] = 0;
|
||||
vtx[j].v.cn[0] = func_800B0A24(this->p1StartColor[0], this->p1EndColor[0], ratio);
|
||||
vtx[j].v.cn[1] = func_800B0A24(this->p1StartColor[1], this->p1EndColor[1], ratio);
|
||||
vtx[j].v.cn[2] = func_800B0A24(this->p1StartColor[2], this->p1EndColor[2], ratio);
|
||||
vtx[j].v.cn[3] = func_800B0A24(this->p1StartColor[3], this->p1EndColor[3], ratio);
|
||||
j++;
|
||||
|
||||
// @recomp If this trail just spawned (timer == 1), set the previous vertex positions for this vertex that of the second previous vertex (interpolation).
|
||||
// Otherwise, set them to the current position of the respective vertex (no interpolation).
|
||||
if (elem->timer == 1 && j >= 2) {
|
||||
vtx[j].v.obp[0] = vtx[j - 2].v.ob[0];
|
||||
vtx[j].v.obp[1] = vtx[j - 2].v.ob[1];
|
||||
vtx[j].v.obp[2] = vtx[j - 2].v.ob[2];
|
||||
}
|
||||
else {
|
||||
vtx[j].v.obp[0] = vtx[j].v.ob[0];
|
||||
vtx[j].v.obp[1] = vtx[j].v.ob[1];
|
||||
vtx[j].v.obp[2] = vtx[j].v.ob[2];
|
||||
}
|
||||
|
||||
vtx[j].v.flag = 0;
|
||||
vtx[j].v.tc[0] = 0;
|
||||
vtx[j].v.tc[1] = 0;
|
||||
vtx[j].v.cn[0] = func_800B0A24(this->p2StartColor[0], this->p2EndColor[0], ratio);
|
||||
vtx[j].v.cn[1] = func_800B0A24(this->p2StartColor[1], this->p2EndColor[1], ratio);
|
||||
vtx[j].v.cn[2] = func_800B0A24(this->p2StartColor[2], this->p2EndColor[2], ratio);
|
||||
vtx[j].v.cn[3] = func_800B0A24(this->p2StartColor[3], this->p2EndColor[3], ratio);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
phi_t2 = 0;
|
||||
j = 0;
|
||||
|
||||
// @recomp Use gEXVertex in place of gSPVertex.
|
||||
gEXVertex(POLY_XLU_DISP++, vtx, 32, 0);
|
||||
|
||||
for (i = 0; i < this->numElements; i++) {
|
||||
elem = &this->elements[i];
|
||||
|
||||
if (elem->state == 0) {
|
||||
phi_t2 = 0;
|
||||
} else {
|
||||
if (phi_t2 == 0) {
|
||||
phi_t2 = 1;
|
||||
} else {
|
||||
gSP1Quadrangle(POLY_XLU_DISP++, j - 2, j - 1, j + 1, j, 0);
|
||||
|
||||
if (this->unkFlag == 1) {
|
||||
phi_t2 = 0;
|
||||
}
|
||||
}
|
||||
j += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (this->drawMode <= EFF_BLURE_DRAW_MODE_SIMPLE_ALT_COLORS) {
|
||||
EffectBlure_DrawSimple(this, gfxCtx);
|
||||
} else {
|
||||
EffectBlure_DrawSmooth(this, gfxCtx);
|
||||
}
|
||||
}
|
||||
|
||||
CLOSE_DISPS(gfxCtx);
|
||||
}
|
@@ -17,8 +17,12 @@
|
||||
03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
|
||||
03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
||||
0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||
03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000242f0000f400000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
|
||||
03000000790000007918000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,righttrigger:b7,rightx:a3,righty:a2,start:b8,platform:Windows,
|
||||
030000008f0e00001330000000000000,Mayflash Controller Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,
|
||||
030000006f0e00001311000000000000,N64 Controller,+rightx:b10,+righty:b3,-rightx:b0,-righty:b11,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,platform:Windows,
|
||||
03000000790000004518000000000000,NEXILUX GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||
@@ -30,8 +34,10 @@
|
||||
030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
|
||||
030000009b2800006100000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
|
||||
030000009b2800006300000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
|
||||
030000009b2800006400000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
|
||||
03000000341200000400000000000000,RetroUSB N64 RetroPort,+rightx:b8,+righty:b10,-rightx:b9,-righty:b11,a:b7,b:b6,dpdown:b2,dpleft:b1,dpright:b0,dpup:b3,leftshoulder:b13,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b12,start:b4,platform:Windows,
|
||||
03000000c82d00006928000000010000,8BitDo N64,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
|
||||
03000000c82d00001930000000000000,8bitdo 64 BT,platform:Windows,a:b0,b:b1,back:b17,guide:b10,start:b11,leftstick:b13,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,
|
||||
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
|
||||
03000000242e0000ff0b000000010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Mac OS X,
|
||||
|
@@ -79,7 +79,7 @@ extern "C" void recomp_register_actor_extension(uint8_t* rdram, recomp_context*
|
||||
}
|
||||
|
||||
if (actor_data_sizes.size() <= actor_type) {
|
||||
actor_data_sizes.resize(2 * actor_type);
|
||||
actor_data_sizes.resize(actor_type + 1);
|
||||
}
|
||||
|
||||
// Increase the actor type's extension data size by the provided size (rounded up to a multiple of 16).
|
||||
|
@@ -569,8 +569,18 @@ void recomputil_u32_slotmap_size(uint8_t* rdram, recomp_context* ctx) {
|
||||
// memory slotmap.
|
||||
|
||||
void recomputil_create_memory_slotmap(uint8_t* rdram, recomp_context* ctx) {
|
||||
(void)rdram;
|
||||
_return(ctx, memory_slotmaps.create());
|
||||
uint32_t element_size = _arg<0, uint32_t>(rdram, ctx);
|
||||
|
||||
// Create the map.
|
||||
uint32_t map_key = memory_slotmaps.create();
|
||||
|
||||
// Retrieve the map and set its element size to the provided value.
|
||||
MemorySlotmap* map;
|
||||
memory_slotmaps.get(map_key, &map);
|
||||
map->second = element_size;
|
||||
|
||||
// Return the created map's key.
|
||||
_return(ctx, map_key);
|
||||
}
|
||||
|
||||
void recomputil_destroy_memory_slotmap(uint8_t* rdram, recomp_context* ctx) {
|
||||
@@ -628,7 +638,7 @@ void recomputil_memory_slotmap_create(uint8_t* rdram, recomp_context* ctx) {
|
||||
// Store the allocated pointer.
|
||||
PTR(void)* value_ptr;
|
||||
map->first.get(key, &value_ptr);
|
||||
MEM_W(0, *value_ptr) = addr;
|
||||
*value_ptr = static_cast<PTR(void)>(addr);
|
||||
|
||||
// Return the key.
|
||||
_return(ctx, key);
|
||||
|
@@ -18,6 +18,13 @@
|
||||
#else
|
||||
#include "SDL2/SDL.h"
|
||||
#include "SDL2/SDL_syswm.h"
|
||||
// Undefine x11 macros that get included by SDL_syswm.h.
|
||||
#undef None
|
||||
#undef Status
|
||||
#undef LockMask
|
||||
#undef ControlMask
|
||||
#undef Success
|
||||
#undef Always
|
||||
#endif
|
||||
|
||||
#include "recomp_ui.h"
|
||||
@@ -43,12 +50,13 @@
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <timeapi.h>
|
||||
#include "SDL_syswm.h"
|
||||
#endif
|
||||
|
||||
#include "../../lib/rt64/src/contrib/stb/stb_image.h"
|
||||
|
||||
const std::string version_string = "1.2.0";
|
||||
const std::string version_string = "1.2.1-dev";
|
||||
|
||||
template<typename... Ts>
|
||||
void exit_error(const char* str, Ts ...args) {
|
||||
@@ -579,6 +587,26 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Set up high resolution timing period.
|
||||
timeBeginPeriod(1);
|
||||
|
||||
// Process arguments.
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (strcmp(argv[i], "--show-console") == 0)
|
||||
{
|
||||
if (GetConsoleWindow() == nullptr)
|
||||
{
|
||||
AllocConsole();
|
||||
freopen("CONIN$", "r", stdin);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up console output to accept UTF-8 on windows
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
|
||||
@@ -722,5 +750,10 @@ int main(int argc, char** argv) {
|
||||
release_preload(preload_context);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// End high resolution timing period.
|
||||
timeEndPeriod(1);
|
||||
#endif
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@@ -56,21 +56,6 @@ unsigned int DPC_BUFBUSY_REG = 0;
|
||||
unsigned int DPC_PIPEBUSY_REG = 0;
|
||||
unsigned int DPC_TMEM_REG = 0;
|
||||
|
||||
unsigned int VI_STATUS_REG = 0;
|
||||
unsigned int VI_ORIGIN_REG = 0;
|
||||
unsigned int VI_WIDTH_REG = 0;
|
||||
unsigned int VI_INTR_REG = 0;
|
||||
unsigned int VI_V_CURRENT_LINE_REG = 0;
|
||||
unsigned int VI_TIMING_REG = 0;
|
||||
unsigned int VI_V_SYNC_REG = 0;
|
||||
unsigned int VI_H_SYNC_REG = 0;
|
||||
unsigned int VI_LEAP_REG = 0;
|
||||
unsigned int VI_H_START_REG = 0;
|
||||
unsigned int VI_V_START_REG = 0;
|
||||
unsigned int VI_V_BURST_REG = 0;
|
||||
unsigned int VI_X_SCALE_REG = 0;
|
||||
unsigned int VI_Y_SCALE_REG = 0;
|
||||
|
||||
void dummy_check_interrupts() {}
|
||||
|
||||
RT64::UserConfiguration::Antialiasing compute_max_supported_aa(RT64::RenderSampleCounts bits) {
|
||||
@@ -250,20 +235,22 @@ zelda64::renderer::RT64Context::RT64Context(uint8_t* rdram, ultramodern::rendere
|
||||
appCore.DPC_PIPEBUSY_REG = &DPC_PIPEBUSY_REG;
|
||||
appCore.DPC_TMEM_REG = &DPC_TMEM_REG;
|
||||
|
||||
appCore.VI_STATUS_REG = &VI_STATUS_REG;
|
||||
appCore.VI_ORIGIN_REG = &VI_ORIGIN_REG;
|
||||
appCore.VI_WIDTH_REG = &VI_WIDTH_REG;
|
||||
appCore.VI_INTR_REG = &VI_INTR_REG;
|
||||
appCore.VI_V_CURRENT_LINE_REG = &VI_V_CURRENT_LINE_REG;
|
||||
appCore.VI_TIMING_REG = &VI_TIMING_REG;
|
||||
appCore.VI_V_SYNC_REG = &VI_V_SYNC_REG;
|
||||
appCore.VI_H_SYNC_REG = &VI_H_SYNC_REG;
|
||||
appCore.VI_LEAP_REG = &VI_LEAP_REG;
|
||||
appCore.VI_H_START_REG = &VI_H_START_REG;
|
||||
appCore.VI_V_START_REG = &VI_V_START_REG;
|
||||
appCore.VI_V_BURST_REG = &VI_V_BURST_REG;
|
||||
appCore.VI_X_SCALE_REG = &VI_X_SCALE_REG;
|
||||
appCore.VI_Y_SCALE_REG = &VI_Y_SCALE_REG;
|
||||
ultramodern::renderer::ViRegs* vi_regs = ultramodern::renderer::get_vi_regs();
|
||||
|
||||
appCore.VI_STATUS_REG = &vi_regs->VI_STATUS_REG;
|
||||
appCore.VI_ORIGIN_REG = &vi_regs->VI_ORIGIN_REG;
|
||||
appCore.VI_WIDTH_REG = &vi_regs->VI_WIDTH_REG;
|
||||
appCore.VI_INTR_REG = &vi_regs->VI_INTR_REG;
|
||||
appCore.VI_V_CURRENT_LINE_REG = &vi_regs->VI_V_CURRENT_LINE_REG;
|
||||
appCore.VI_TIMING_REG = &vi_regs->VI_TIMING_REG;
|
||||
appCore.VI_V_SYNC_REG = &vi_regs->VI_V_SYNC_REG;
|
||||
appCore.VI_H_SYNC_REG = &vi_regs->VI_H_SYNC_REG;
|
||||
appCore.VI_LEAP_REG = &vi_regs->VI_LEAP_REG;
|
||||
appCore.VI_H_START_REG = &vi_regs->VI_H_START_REG;
|
||||
appCore.VI_V_START_REG = &vi_regs->VI_V_START_REG;
|
||||
appCore.VI_V_BURST_REG = &vi_regs->VI_V_BURST_REG;
|
||||
appCore.VI_X_SCALE_REG = &vi_regs->VI_X_SCALE_REG;
|
||||
appCore.VI_Y_SCALE_REG = &vi_regs->VI_Y_SCALE_REG;
|
||||
|
||||
// Set up the RT64 application configuration fields.
|
||||
RT64::ApplicationConfiguration appConfig;
|
||||
@@ -338,9 +325,7 @@ void zelda64::renderer::RT64Context::send_dl(const OSTask* task) {
|
||||
app->processDisplayLists(app->core.RDRAM, task->t.data_ptr & 0x3FFFFFF, 0, true);
|
||||
}
|
||||
|
||||
void zelda64::renderer::RT64Context::update_screen(uint32_t vi_origin) {
|
||||
VI_ORIGIN_REG = vi_origin;
|
||||
|
||||
void zelda64::renderer::RT64Context::update_screen() {
|
||||
app->updateScreen();
|
||||
}
|
||||
|
||||
|
@@ -900,6 +900,13 @@ void recompui::drop_files(const std::list<std::filesystem::path> &file_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
recompui::set_config_tab(recompui::ConfigTab::Mods);
|
||||
// If the config menu isn't open, open it in the mods tab.
|
||||
if (!recompui::is_context_shown(recompui::get_config_context_id())) {
|
||||
recompui::hide_all_contexts();
|
||||
recompui::show_context(recompui::get_config_context_id(), "");
|
||||
}
|
||||
|
||||
recompui::open_notification("Installing Mods", "Please Wait");
|
||||
// TODO: Needs a progress callback and a prompt for every mod that needs to be confirmed to be overwritten.
|
||||
// TODO: Run this on a background thread and use the callbacks to advance the state instead of blocking.
|
||||
|
Reference in New Issue
Block a user