mirror of
				https://github.com/Zelda64Recomp/Zelda64Recomp.git
				synced 2025-10-30 08:03:03 +00:00 
			
		
		
		
	* 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:
		
							parent
							
								
									46d9e92dda
								
							
						
					
					
						commit
						b5360b0546
					
				
					 23 changed files with 1070 additions and 44 deletions
				
			
		
							
								
								
									
										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"] | ||||
|     } | ||||
|   ] | ||||
| } | ||||
|  | @ -1 +1 @@ | |||
| Subproject commit c5e268aa0f71cf06a10a001da981dc3e02e7dff0 | ||||
| Subproject commit df7e820d8c55e4fcb4616c210cbb2c01b25cd48c | ||||
							
								
								
									
										2
									
								
								lib/rt64
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								lib/rt64
									
										
									
									
									
								
							|  | @ -1 +1 @@ | |||
| Subproject commit ada6cc62c421b142d9d90154765e44348115bd9e | ||||
| Subproject commit b552151c3498dc45ba06e98f57aaf0fa709cdf9f | ||||
|  | @ -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.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Wiseguy
						Wiseguy