mirror of
https://github.com/HarbourMasters/Starship
synced 2026-05-23 06:54:39 -04:00
Merge branch 'main' of github.com:HarbourMasters/Starship
This commit is contained in:
+5
-7
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
|
||||
|
||||
# Set the project version and language
|
||||
project(Starship VERSION 0.1.0 LANGUAGES C CXX ASM)
|
||||
project(Starship VERSION 2.0.1 LANGUAGES C CXX ASM)
|
||||
include(FetchContent)
|
||||
|
||||
set(NATO_PHONETIC_ALPHABET
|
||||
@@ -17,8 +17,8 @@ math(EXPR PATCH_INDEX "${PROJECT_VERSION_PATCH}")
|
||||
# Use the patch number to select the correct word
|
||||
list(GET NATO_PHONETIC_ALPHABET ${PATCH_INDEX} PROJECT_PATCH_WORD)
|
||||
|
||||
set(PROJECT_BUILD_NAME "Centauri ${PROJECT_PATCH_WORD}" CACHE STRING "" FORCE)
|
||||
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "" FORCE)
|
||||
set(PROJECT_BUILD_NAME "Barnard ${PROJECT_PATCH_WORD}" CACHE STRING "" FORCE)
|
||||
set(PROJECT_TEAM "SonicDcer & Lywx" CACHE STRING "" FORCE)
|
||||
|
||||
if(APPLE)
|
||||
enable_language(OBJCXX)
|
||||
@@ -30,10 +30,6 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment ve
|
||||
# Set the C++ standard and enable the MSVC parallel build option
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use")
|
||||
set(PROJECT_TEAM "Lywx & YoshiCrystal")
|
||||
set(PROJECT_VERSION_MAJOR 2)
|
||||
set(PROJECT_VERSION_MINOR 0)
|
||||
set(PROJECT_VERSION_PATCH 0)
|
||||
#add_compile_options(-fsanitize=address)
|
||||
#add_link_options(-fsanitize=address)
|
||||
|
||||
@@ -574,6 +570,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
|
||||
else()
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
|
||||
set(CPU_OPTION -msse2 -mfpmath=sse)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
|
||||
set(CPU_OPTION -mfpu=neon)
|
||||
endif()
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
|
||||
@@ -18,27 +18,33 @@ If you're having any trouble after reading through this `README`, feel free ask
|
||||
Starship does not include any copyrighted assets. You are required to provide a supported copy of the game.
|
||||
|
||||
### 1. Verify your ROM dump
|
||||
The supported ROM is the USA 1.1 Rev A version. You can verify you have dumped a supported copy of the game by using the SHA-1 File Checksum Online at https://www.romhacking.net/hash/. The hash for a US 1.1 ROM is SHA-1: 09F0D105F476B00EFA5303A3EBC42E60A7753B7A.
|
||||
The supported ROMs are US 1.0 and US 1.1 Rev A versions. You can verify you have dumped a supported copy of the game by using the SHA-1 File Checksum Online at https://www.romhacking.net/hash/.
|
||||
|
||||
* The SHA-1 hash for a US 1.0 ROM is D8B1088520F7C5F81433292A9258C1184AFA1457.
|
||||
* The SHA-1 hash for a US 1.1 ROM is 09F0D105F476B00EFA5303A3EBC42E60A7753B7A.
|
||||
|
||||
Starship also supports voice language replacement use from both EU (Lylat) and JP (Japanese) when used in conjunction with an US ROM.
|
||||
|
||||
Note: JP and EU versions of the game are not supported for the base asset O2R creation, a US ROM must be used for it.
|
||||
|
||||
### 2. Verify your ROM is in .z64 format
|
||||
Your ROM needs to be in .z64 format. If it's in .n64 format, use the following to convert it to a .z64: https://hack64.net/tools/swapper.php
|
||||
|
||||
### 2. Download Starship from [Releases](https://github.com/HarbourMasters/Starship/releases)
|
||||
|
||||
### 3. Generating the O2R from the ROM
|
||||
### 3. Generating the OTR from the ROM and Play!
|
||||
#### Windows
|
||||
* Extract every file from the zip into a folder of your choosing.
|
||||
* Copy your ROM to the root of the folder you extracted the zip to.
|
||||
* Run "generate_o2r.bat"
|
||||
* Run starship.exe and select your US 1.0 or US 1.1 ROM.
|
||||
|
||||
#### Linux
|
||||
* Extract every file from the zip into a folder of your choosing.
|
||||
* Execute starship.appimage. You may have to chmod +x the appimage via terminal.
|
||||
* Select your US 1.0 or US 1.1 ROM.
|
||||
|
||||
#### MacOS
|
||||
* Extract every file from the zip into a folder of your choosing.
|
||||
* Copy your ROM to the root of the folder you extracted the zip to.
|
||||
* Run "generate_o2r.sh"
|
||||
|
||||
### 4. Play!
|
||||
* Launch `Starship.exe`
|
||||
Congratulations, you are now sailing with Starship! Have fun!
|
||||
* Run starship and select your US 1.0 or US 1.1 ROM.
|
||||
|
||||
# Configuration
|
||||
|
||||
|
||||
+1
-1
Submodule libultraship updated: a8cddd2f89...45c4f8d6c1
@@ -144,17 +144,13 @@ void Audio_InitNoteSub(Note* note, NoteAttributes* noteAttr) {
|
||||
panVolumeCenter = 1.0f;
|
||||
}
|
||||
else if (stereo.s.is_sfx) { // SFX
|
||||
float pan_angle = (float)(pan + 64) / 128 * 2 * M_PI;
|
||||
float pan_angle = ((float) pan) / 128 * 2 * M_PI;
|
||||
|
||||
// Speaker angles in radians
|
||||
const float front_left = -0.5236;
|
||||
const float front_right = 0.5236;
|
||||
const float rear_left = -1.92;
|
||||
const float rear_right = 1.92;
|
||||
|
||||
// Normalize pan_angle to [0, 2π]
|
||||
pan_angle = fmodf(pan_angle, 2 * M_PI);
|
||||
if (pan_angle < 0) pan_angle += 2 * M_PI;
|
||||
const float front_left = (CVarGetInteger("gPositionFrontLeft", 240) - 90) * (M_PI / 180.0f);
|
||||
const float front_right = (CVarGetInteger("gPositionFrontRight", 300) - 90) * (M_PI / 180.0f);
|
||||
const float rear_left = (CVarGetInteger("gPositionRearLeft", 160) - 90) * (M_PI / 180.0f);
|
||||
const float rear_right = (CVarGetInteger("gPositionRearRight", 20) - 90) * (M_PI / 180.0f);
|
||||
|
||||
// Calculate volumes using cosine panning law
|
||||
panVolumeLeft = fmaxf(0, cosf(pan_angle - front_left)); // Front Left
|
||||
@@ -164,8 +160,10 @@ void Audio_InitNoteSub(Note* note, NoteAttributes* noteAttr) {
|
||||
} else { // MUSIC
|
||||
panVolumeLeft = gStereoPanVolume[pan];
|
||||
panVolumeRight = gStereoPanVolume[ARRAY_COUNT(gStereoPanVolume) - 1 - pan];
|
||||
panVolumeRearLeft = gStereoPanVolume[pan];
|
||||
panVolumeRearRight = gStereoPanVolume[ARRAY_COUNT(gStereoPanVolume) - 1 - pan];
|
||||
|
||||
f32 rearMusicVolume = CVarGetFloat("gVolumeRearMusic", 1.0f);
|
||||
panVolumeRearLeft = gStereoPanVolume[pan] * rearMusicVolume;
|
||||
panVolumeRearRight = gStereoPanVolume[ARRAY_COUNT(gStereoPanVolume) - 1 - pan] * rearMusicVolume;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1368,6 +1368,7 @@ Acmd* AudioSynth_ProcessEnvelope(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisS
|
||||
synthState->curVolLfe = curVolLfe + (rampLfe * aiBufLenSmall);
|
||||
synthState->curVolRLeft = curVolRLeft + (rampRLeft * aiBufLenSmall);
|
||||
synthState->curVolRRight = curVolRRight + (rampRRight * aiBufLenSmall);
|
||||
uint32_t cutoffFreqLfe = CVarGetInteger("gSubwooferThreshold", 80);
|
||||
|
||||
if (noteSub->bitField0.usesHeadsetPanEffects) {
|
||||
int32_t num_audio_channels = 2;
|
||||
@@ -1378,24 +1379,24 @@ Acmd* AudioSynth_ProcessEnvelope(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisS
|
||||
switch (delaySide) {
|
||||
case HAAS_EFFECT_DELAY_LEFT:
|
||||
aEnvMixer(aList++, dmemSrc, aiBufLen, ((sourceReverbVol & 0x80) >> 7),
|
||||
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, (DMEM_WET_LEFT_CH << 16) | DMEM_LEFT_CH, DMEM_HAAS_TEMP << 16, num_audio_channels);
|
||||
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, (DMEM_WET_LEFT_CH << 16) | DMEM_LEFT_CH, DMEM_HAAS_TEMP << 16, num_audio_channels, cutoffFreqLfe);
|
||||
break;
|
||||
|
||||
case HAAS_EFFECT_DELAY_RIGHT:
|
||||
aEnvMixer(aList++, dmemSrc, aiBufLen, ((sourceReverbVol & 0x80) >> 7),
|
||||
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, (DMEM_WET_LEFT_CH << 16) | DMEM_LEFT_CH, DMEM_HAAS_TEMP, num_audio_channels);
|
||||
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, (DMEM_WET_LEFT_CH << 16) | DMEM_LEFT_CH, DMEM_HAAS_TEMP, num_audio_channels, cutoffFreqLfe);
|
||||
break;
|
||||
|
||||
default: // HAAS_EFFECT_DELAY_NONE
|
||||
aEnvMixer(aList++, dmemSrc, aiBufLen, ((sourceReverbVol & 0x80) >> 7),
|
||||
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, (DMEM_WET_LEFT_CH << 16) | DMEM_LEFT_CH, 0, num_audio_channels);
|
||||
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, (DMEM_WET_LEFT_CH << 16) | DMEM_LEFT_CH, 0, num_audio_channels, cutoffFreqLfe);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
aEnvSetup1(aList++, (sourceReverbVol & 0x7F), rampReverb, rampLeft, rampRight, rampCenter, rampLfe, rampRLeft, rampRRight);
|
||||
aEnvSetup2(aList++, curVolLeft, curVolRight, curVolCenter, curVolLfe, curVolRLeft, curVolRRight);
|
||||
aEnvMixer(aList++, dmemSrc, aiBufLen, ((sourceReverbVol & 0x80) >> 7),
|
||||
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, (DMEM_WET_LEFT_CH << 16) | DMEM_LEFT_CH, 0, GetNumAudioChannels());
|
||||
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, (DMEM_WET_LEFT_CH << 16) | DMEM_LEFT_CH, 0, GetNumAudioChannels(), cutoffFreqLfe);
|
||||
}
|
||||
|
||||
return aList;
|
||||
|
||||
+3
-3
@@ -77,7 +77,6 @@ static __m128i m256i_clamp_to_m128i(m256i a) {
|
||||
#define BUF_S16(a) (int16_t*) BUF_U8(a)
|
||||
|
||||
#define SAMPLE_RATE 32000 // Adjusted to match the actual sample rate of 32 kHz
|
||||
#define CUTOFF_FREQ_LFE 80 // Cutoff frequency of 80 Hz
|
||||
|
||||
static struct {
|
||||
uint16_t in;
|
||||
@@ -645,7 +644,8 @@ void aEnvSetup2Impl(uint16_t initial_vol_left, uint16_t initial_vol_right, int16
|
||||
|
||||
void aEnvMixerImpl(uint16_t in_addr, uint16_t n_samples, bool swap_reverb,
|
||||
bool neg_left, bool neg_right,
|
||||
uint32_t wet_dry_addr, uint32_t haas_temp_addr, uint32_t num_channels)
|
||||
uint32_t wet_dry_addr, uint32_t haas_temp_addr, uint32_t num_channels,
|
||||
uint32_t cutoff_freq_lfe)
|
||||
{
|
||||
// Note: max number of samples is 192 (192 * 2 = 384 bytes = 0x180)
|
||||
int max_num_samples = 192;
|
||||
@@ -675,7 +675,7 @@ void aEnvMixerImpl(uint16_t in_addr, uint16_t n_samples, bool swap_reverb,
|
||||
|
||||
if (num_channels == 6) {
|
||||
// Calculate the filter coefficient
|
||||
float RC = 1.f / (2 * M_PI * CUTOFF_FREQ_LFE);
|
||||
float RC = 1.f / (2 * M_PI * cutoff_freq_lfe);
|
||||
float dt = 1.f / SAMPLE_RATE;
|
||||
float alpha = dt / (RC + dt);
|
||||
|
||||
|
||||
+4
-3
@@ -47,7 +47,8 @@ void aEnvSetup1Impl(uint8_t initial_vol_wet, uint16_t rate_wet, uint16_t rate_le
|
||||
void aEnvSetup2Impl(uint16_t initial_vol_left, uint16_t initial_vol_right, int16_t initial_vol_center,
|
||||
int16_t initial_vol_lfe, int16_t initial_vol_rear_left, int16_t initial_vol_rear_right);
|
||||
void aEnvMixerImpl(uint16_t in_addr, uint16_t n_samples, bool swap_reverb, bool neg_left,
|
||||
bool neg_right, uint32_t wet_dry_addr, uint32_t haas_temp_addr, uint32_t num_channels);
|
||||
bool neg_right, uint32_t wet_dry_addr, uint32_t haas_temp_addr, uint32_t num_channels,
|
||||
uint32_t cutoff_freq_lfe);
|
||||
void aMixImpl(uint16_t count, int16_t gain, uint16_t in_addr, uint16_t out_addr);
|
||||
void aS8DecImpl(uint8_t flags, ADPCM_STATE state);
|
||||
void aAddMixerImpl(uint16_t count, uint16_t in_addr, uint16_t out_addr);
|
||||
@@ -76,8 +77,8 @@ void aUnkCmd19Impl(uint8_t f, uint16_t count, uint16_t out_addr, uint16_t in_add
|
||||
aEnvSetup1Impl(initialVolReverb, rampReverb, rampLeft, rampRight, rampCenter, rampLfe, rampRLeft, rampRRight)
|
||||
#define aEnvSetup2(pkt, initialVolLeft, initialVolRight, initialVolCenter, initialVolLfe, initialVolRLeft, initialVolRRight) \
|
||||
aEnvSetup2Impl(initialVolLeft, initialVolRight, initialVolCenter, initialVolLfe, initialVolRLeft, initialVolRRight)
|
||||
#define aEnvMixer(pkt, inAddr, nSamples, swapReverb, negLeft, negRight, wetDryAddr, haasTempAddr, numChannels) \
|
||||
aEnvMixerImpl(inAddr, nSamples, swapReverb, negLeft, negRight, wetDryAddr, haasTempAddr, numChannels)
|
||||
#define aEnvMixer(pkt, inAddr, nSamples, swapReverb, negLeft, negRight, wetDryAddr, haasTempAddr, numChannels, cutoffFreqLfe) \
|
||||
aEnvMixerImpl(inAddr, nSamples, swapReverb, negLeft, negRight, wetDryAddr, haasTempAddr, numChannels, cutoffFreqLfe)
|
||||
#define aMix(pkt, c, g, i, o) aMixImpl(c, g, i, o)
|
||||
#define aS8Dec(pkt, f, s) aS8DecImpl(f, s)
|
||||
#define aAddMixer(pkt, s, d, c) aAddMixerImpl(s, d, c)
|
||||
|
||||
@@ -432,6 +432,10 @@ void Display_LandmasterThrusters(Player* player) {
|
||||
}
|
||||
|
||||
Matrix_Push(&gGfxMatrix);
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Display_LandmasterThrusters_1", player->num);
|
||||
|
||||
Matrix_Translate(gGfxMatrix, 20.0f, 30.0f, -10.0f, MTXF_APPLY);
|
||||
|
||||
if (!gVersusMode) {
|
||||
@@ -447,6 +451,10 @@ void Display_LandmasterThrusters(Player* player) {
|
||||
} else {
|
||||
gSPDisplayList(gMasterDisp++, D_versus_301B6E0);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
Matrix_Pop(&gGfxMatrix);
|
||||
}
|
||||
|
||||
@@ -461,6 +469,10 @@ void Display_LandmasterThrusters(Player* player) {
|
||||
}
|
||||
|
||||
Matrix_Push(&gGfxMatrix);
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Display_LandmasterThrusters_2", player->num);
|
||||
|
||||
Matrix_Translate(gGfxMatrix, -20.0f, 30.0f, -10.0f, MTXF_APPLY);
|
||||
|
||||
if (!gVersusMode) {
|
||||
@@ -476,8 +488,13 @@ void Display_LandmasterThrusters(Player* player) {
|
||||
} else {
|
||||
gSPDisplayList(gMasterDisp++, D_versus_301B6E0);
|
||||
}
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
Matrix_Pop(&gGfxMatrix);
|
||||
}
|
||||
|
||||
Matrix_Pop(&gGfxMatrix);
|
||||
}
|
||||
|
||||
|
||||
+20
-1
@@ -218,6 +218,9 @@ void Effect_Effect372_Draw(Effect372* this) {
|
||||
}
|
||||
|
||||
void Effect_Effect382_Draw(Effect382* this) {
|
||||
// @port Skip interpolation
|
||||
FrameInterpolation_ShouldInterpolateFrame(false);
|
||||
|
||||
RCP_SetupDL_49();
|
||||
gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 255, this->unk_44);
|
||||
gDPSetEnvColor(gMasterDisp++, 255, 255, 255, this->unk_44);
|
||||
@@ -225,6 +228,10 @@ void Effect_Effect382_Draw(Effect382* this) {
|
||||
Matrix_Translate(gGfxMatrix, 0.0f, 20.0f, 0.0f, MTXF_APPLY);
|
||||
Matrix_SetGfxMtx(&gMasterDisp);
|
||||
gSPDisplayList(gMasterDisp++, D_ZO_6024220);
|
||||
|
||||
// @port renable interpolation
|
||||
FrameInterpolation_ShouldInterpolateFrame(true);
|
||||
|
||||
RCP_SetupDL(&gMasterDisp, SETUPDL_64);
|
||||
}
|
||||
|
||||
@@ -746,6 +753,9 @@ void Effect_Effect357_Draw(Effect357* this) {
|
||||
gSPFogPosition(gMasterDisp++, gFogNear, 1005);
|
||||
}
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("Effect357", this->unk_4C | (this->index << 16) & 0x00FF);
|
||||
|
||||
Graphics_SetScaleMtx(this->scale2);
|
||||
|
||||
switch (gCurrentLevel) {
|
||||
@@ -887,6 +897,8 @@ void Effect_Effect357_Draw(Effect357* this) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
RCP_SetupDL(&gMasterDisp, SETUPDL_64);
|
||||
|
||||
@@ -2276,11 +2288,18 @@ void Effect_Effect374_Draw(Effect374* this) {
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// @port Skip interpolation
|
||||
FrameInterpolation_ShouldInterpolateFrame(false);
|
||||
|
||||
Matrix_Scale(gGfxMatrix, this->scale1, this->scale2, 2.5f, MTXF_APPLY);
|
||||
Matrix_SetGfxMtx(&gMasterDisp);
|
||||
RCP_SetupDL_40();
|
||||
gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK);
|
||||
gSPDisplayList(gMasterDisp++, D_ENMY_PLANET_4008F70);
|
||||
|
||||
// @port renable interpolation
|
||||
FrameInterpolation_ShouldInterpolateFrame(true);
|
||||
|
||||
RCP_SetupDL(&gMasterDisp, SETUPDL_64);
|
||||
break;
|
||||
}
|
||||
@@ -3795,7 +3814,7 @@ void Effect_Effect395_Update(Effect395* this) {
|
||||
D_ctx_801779A8[0] = 50.0f;
|
||||
if (this->unk_46 == 10) {
|
||||
gFillScreenRed = gFillScreenGreen = gFillScreenBlue = 255;
|
||||
if (CVarGetInteger("gDisableGorgonFlash", 0) == 0){
|
||||
if (CVarGetInteger("gDisableGorgonFlash", 0) == 0) {
|
||||
gFillScreenAlpha = gFillScreenAlphaTarget = 255;
|
||||
}
|
||||
gFillScreenAlphaTarget = 0;
|
||||
|
||||
@@ -34,6 +34,7 @@ void Load_RomFile(void* vRomAddress, void* dest, ptrdiff_t size) {
|
||||
|
||||
u8 Load_SceneFiles(Scene* scene) {
|
||||
#if 1
|
||||
// TODO: BUG! sCurrentScene and scene never change so this will never be true.
|
||||
bool hasSceneChanged = memcmp(&sCurrentScene, scene, sizeof(Scene)) != 0;
|
||||
sCurrentScene = *scene;
|
||||
return hasSceneChanged;
|
||||
|
||||
@@ -42,6 +42,8 @@ void Lib_Texture_Scroll(u16* texture, s32 width, s32 height, u8 mode) {
|
||||
width = newWidth;
|
||||
height = newHeight;
|
||||
|
||||
scale = 1; // TODO: a higher scale causes performance issues for large textures ?
|
||||
|
||||
for(s32 i = 0; i < (s32) scale; i++){
|
||||
switch (mode) {
|
||||
case 0:
|
||||
|
||||
@@ -97,7 +97,7 @@ void func_versus_800BC9DC(f32 xPos, f32 yPos, f32 scale, s32 yScale) {
|
||||
s32 D_800D4AB0[] = { 40, 64, 64 };
|
||||
|
||||
Lib_TextureRect_CI8(&gMasterDisp, D_800D4ABC[yScale], D_800D4AA4[yScale], D_800D4AB0[yScale], 40, xPos, yPos, scale,
|
||||
scale);
|
||||
scale);
|
||||
}
|
||||
|
||||
void func_versus_800BCB44(f32 xPos, f32 yPos, f32 scale) {
|
||||
@@ -110,7 +110,7 @@ void func_versus_800BCC48(f32 xPos, f32 yPos, f32 xScale, f32 yScale, s32 arg4)
|
||||
s32 D_800D4AE8[] = { 104, 152, 168, 152 };
|
||||
|
||||
Lib_TextureRect_CI8(&gMasterDisp, D_800D4AD8[arg4], D_800D4AC8[arg4], D_800D4AE8[arg4], 25, xPos, yPos, xScale,
|
||||
yScale);
|
||||
yScale);
|
||||
}
|
||||
|
||||
void func_versus_800BCE24(f32 xPos, f32 yPos, f32 xScale, f32 yScale) {
|
||||
@@ -168,8 +168,7 @@ void func_versus_800BD350(f32 xPos, f32 yPos) {
|
||||
}
|
||||
|
||||
void func_versus_800BD3A8(f32 xPos, f32 yPos) {
|
||||
Lib_TextureRect_CI4(&gMasterDisp, aVsHandicapFrameTex, aVsHandicapFrameTLUT, 80, 71, xPos, yPos, 1.0f,
|
||||
1.0f);
|
||||
Lib_TextureRect_CI4(&gMasterDisp, aVsHandicapFrameTex, aVsHandicapFrameTLUT, 80, 71, xPos, yPos, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void func_versus_800BD4D4(f32 xPos, f32 yPos, s32 arg2) {
|
||||
@@ -1262,6 +1261,9 @@ s32 func_versus_800C1138(s32 max, s32 arg1) {
|
||||
void Versus_InitMatch(void) {
|
||||
s32 i;
|
||||
|
||||
// Until Load_SceneFiles gets fixed, this fixes most of the audio issues in versus
|
||||
AUDIO_SET_SPEC_ALT(SFXCHAN_3, AUDIOSPEC_16);
|
||||
|
||||
for (i = 0, sVsPlayerCount = 0; i < 4; i++) {
|
||||
if (!gPlayerInactive[i]) {
|
||||
sVsPlayerCount++;
|
||||
|
||||
@@ -48,6 +48,25 @@ bool D_ending_80198584;
|
||||
s32 D_ending_80198588;
|
||||
s32 D_ending_8019858C;
|
||||
|
||||
void Ending_Port_InitOverlay(void) {
|
||||
D_ending_80192E70 = 0; // ending sequence frame counter
|
||||
D_ending_80196D04 = 0; // ending text frame counter
|
||||
memset(D_ending_80196D08, 0, sizeof(D_ending_80196D08));
|
||||
D_ending_80196F88 = 0;
|
||||
D_ending_80196F8C = 0;
|
||||
D_ending_80196F90 = 0;
|
||||
D_ending_80196F94 = 0;
|
||||
D_ending_80196F98 = 0;
|
||||
D_ending_80196F9C = 0.0f;
|
||||
memset(D_ending_80196FA0, 0, sizeof(D_ending_80196FA0));
|
||||
memset(D_ending_80197900, 0, sizeof(D_ending_80197900));
|
||||
memset(D_ending_80198260, 0, sizeof(D_ending_80198260));
|
||||
D_ending_80198580 = 0.0f;
|
||||
D_ending_80198584 = false;
|
||||
D_ending_80198588 = 0;
|
||||
D_ending_8019858C = 0;
|
||||
}
|
||||
|
||||
const char str1[] = "fogR= %d, fogG= %d, fogB= %d\n";
|
||||
const char str2[] = "ligR= %d, ligG= %d, ligB= %d\n";
|
||||
const char str3[] = "kanR= %d, kanG= %d, kanB= %d\n";
|
||||
@@ -1028,8 +1047,19 @@ void Ending_Main(void) {
|
||||
gCsFrameCount++;
|
||||
gGameFrameCount++;
|
||||
|
||||
if (gSaveFile.save.data.padEE[0] == 1) {
|
||||
gControllerLock = 0;
|
||||
if (gControllerPress[0].button & START_BUTTON) {
|
||||
D_ending_80196D00 = 7;
|
||||
D_ending_80196D04 = 7200;
|
||||
D_ending_80192E70 = 7200;
|
||||
}
|
||||
} else {
|
||||
gControllerLock = 10000;
|
||||
}
|
||||
|
||||
switch (D_ending_80196D00) {
|
||||
case 0:
|
||||
case 0: // Ending Init
|
||||
gRadioState = 0;
|
||||
gGameFrameCount = 0;
|
||||
gSceneSetup = 0;
|
||||
@@ -1037,6 +1067,12 @@ void Ending_Main(void) {
|
||||
gCsCamAtX = gCsCamAtY = 0.0f;
|
||||
gCsCamAtZ = -100.0f;
|
||||
D_ending_80196D00 = 1;
|
||||
|
||||
// @port Bugfix:
|
||||
// In the original game, these variables are set to zero when the overlay is reloaded.
|
||||
// Since we don't use overlays, the absence of this initializer causes the ending not to play
|
||||
// as it should after a the first playthrough.
|
||||
Ending_Port_InitOverlay();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
@@ -458,8 +458,24 @@ void Ending_8018EDB8(u32 arg0, AssetInfo* asset) {
|
||||
|
||||
gDPLoadTextureBlock(gMasterDisp++, D_END_700EA38, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0, G_TX_WRAP | G_TX_NOMIRROR,
|
||||
G_TX_WRAP | G_TX_NOMIRROR, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
|
||||
gDPSetupTile(gMasterDisp++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, arg0 * 14, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
|
||||
int interpolatedFrames = GameEngine_GetInterpolationFrameCount();
|
||||
|
||||
float scrollArg = arg0 * 14;
|
||||
float inc = 14 / (float) interpolatedFrames;
|
||||
|
||||
for (int i = 0; i < interpolatedFrames; i++) {
|
||||
gDPSetInterpolation(gMasterDisp++, i);
|
||||
|
||||
gDPSetupTile2(gMasterDisp++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, scrollArg, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
gDPSetTileSizeInterp(gMasterDisp, G_TX_RENDERTILE, scrollArg, 0, 32 << 2, 0);
|
||||
|
||||
gMasterDisp += 3;
|
||||
|
||||
scrollArg += inc;
|
||||
}
|
||||
|
||||
gSPDisplayList(gMasterDisp++, D_END_700E9E0);
|
||||
}
|
||||
|
||||
@@ -820,6 +836,10 @@ void Ending_80191234(u32 arg0, AssetInfo* asset) {
|
||||
gBgColor = 0;
|
||||
gStarCount = 0;
|
||||
gControllerLock = 10;
|
||||
|
||||
// @port: Ending seen at least once.
|
||||
gSaveFile.save.data.padEE[0] = 1;
|
||||
Save_Write();
|
||||
}
|
||||
|
||||
void Ending_80191294(u32 arg0, AssetInfo* asset) {
|
||||
@@ -1083,7 +1103,11 @@ void Ending_801924EC(u32 arg0) {
|
||||
}
|
||||
|
||||
void Ending_801926D4(void) {
|
||||
gControllerLock = 10000;
|
||||
if (gSaveFile.save.data.padEE[0] == 1) {
|
||||
gControllerLock = 0;
|
||||
} else {
|
||||
gControllerLock = 10000;
|
||||
}
|
||||
|
||||
Matrix_Push(&gGfxMatrix);
|
||||
|
||||
|
||||
@@ -5925,11 +5925,17 @@ void Macbeth_MaBombDrop_Draw(MaBombDrop* this) {
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// @port Skip interpolation
|
||||
FrameInterpolation_ShouldInterpolateFrame(false);
|
||||
|
||||
Matrix_Scale(gGfxMatrix, this->fwork[0], this->scale, 2.5f, MTXF_APPLY);
|
||||
Matrix_SetGfxMtx(&gMasterDisp);
|
||||
RCP_SetupDL_40();
|
||||
gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK);
|
||||
gSPDisplayList(gMasterDisp++, D_ENMY_PLANET_4008F70);
|
||||
|
||||
// @port renable interpolation
|
||||
FrameInterpolation_ShouldInterpolateFrame(true);
|
||||
RCP_SetupDL(&gMasterDisp, SETUPDL_64);
|
||||
break;
|
||||
}
|
||||
@@ -6496,12 +6502,6 @@ f32 D_i5_801BA854[8] = { 1.5f, -1.0f, 0.7f, 0.0f, 0.9f, 0.7f, -1.0f, 1.5f };
|
||||
f32 D_i5_801BA874[8] = { 200.0f, 300.0f, 400.0f, 0.0f, 500.0f, 100.0f, 120.0f, 100.0f };
|
||||
f32 D_i5_801BA894[8] = { 200.0f, 250.0f, 220.0f, 0.0f, 200.0f, 230.0f, 220.0f, 350.0f };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void Macbeth_LevelComplete2(Player* player) {
|
||||
s32 i;
|
||||
s32 j;
|
||||
|
||||
@@ -1959,7 +1959,7 @@ void Option_Data_Select(void) {
|
||||
}
|
||||
|
||||
void Option_Data_Draw(void) {
|
||||
s32 i;
|
||||
s32 i = 0;
|
||||
s32 sp7C[2];
|
||||
s32 mask[2];
|
||||
static f32 D_menu_801AF084[2] = { 172.0f, 76.0f };
|
||||
@@ -1974,8 +1974,7 @@ void Option_Data_Draw(void) {
|
||||
|
||||
gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 255, 255);
|
||||
|
||||
Lib_TextureRect_IA8(&gMasterDisp, D_OPT_80084B0, 176, 13, D_menu_801AF094[0], D_menu_801AF0AC[0] + (4.0f * i), 1.0f,
|
||||
1.0f);
|
||||
Lib_TextureRect_IA8(&gMasterDisp, D_OPT_80084B0, 176, 13, D_menu_801AF094[0], D_menu_801AF0AC[0], 1.0f, 1.0f);
|
||||
|
||||
if (D_menu_801B91CC < 2) {
|
||||
Lib_TextureRect_IA8_MirX(&gMasterDisp, aArrowTex, 8, 8, D_menu_801AF084[D_menu_801B91C0], 140.0f, 1.0f, 1.0f);
|
||||
@@ -2250,7 +2249,7 @@ void Option_80197914(void) {
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("RANKING_BORDERS", i);
|
||||
|
||||
Matrix_Translate(gGfxMatrix, vec1->x, vec1->y, -500.0f, MTXF_APPLY);
|
||||
Matrix_Translate(gGfxMatrix, vec1->x, vec1->y, -500.0f, MTXF_APPLY);
|
||||
|
||||
// @port: Increase the scale by 2.5f to compensate for missing borders
|
||||
Matrix_Scale(gGfxMatrix, vec2->x * 4, vec2->y + 2.5f, 1.0f, MTXF_APPLY);
|
||||
@@ -3492,6 +3491,9 @@ void Option_DrawMenuCard(OptionCardFrame arg0) {
|
||||
|
||||
Matrix_Push(&gGfxMatrix);
|
||||
|
||||
// @port: Tag the transform.
|
||||
FrameInterpolation_RecordOpenChild("MenuCard", (u32) & arg0);
|
||||
|
||||
Matrix_Translate(gGfxMatrix, arg0.x, arg0.y, arg0.z, MTXF_APPLY);
|
||||
Matrix_Scale(gGfxMatrix, arg0.xScale, arg0.yScale, 1.0f, MTXF_APPLY);
|
||||
Matrix_RotateX(gGfxMatrix, M_DTOR * 90.0f, MTXF_APPLY);
|
||||
@@ -3502,6 +3504,9 @@ void Option_DrawMenuCard(OptionCardFrame arg0) {
|
||||
|
||||
Matrix_Pop(&gGfxMatrix);
|
||||
|
||||
// @port Pop the transform id.
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
Lib_InitPerspective(&gMasterDisp);
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +146,8 @@ f32 D_menu_801B9078;
|
||||
f32 D_menu_801B907C;
|
||||
f32 D_menu_801B9080;
|
||||
f32 D_menu_801B9084;
|
||||
|
||||
// @port: Timer for drawing the mirrored Great Fox Deck.
|
||||
s32 segataSanshiroTimer = 0;
|
||||
|
||||
TitleAnimation sTeamAnim[4] = {
|
||||
|
||||
+4
-4
@@ -88,7 +88,7 @@ GameEngine::GameEngine() {
|
||||
if (std::filesystem::exists(main_path)) {
|
||||
archiveFiles.push_back(main_path);
|
||||
} else {
|
||||
if (ShowYesNoBox("No O2R Files", "No O2R files found. Generate one now?") == IDYES) {
|
||||
if (ShowYesNoBox("Starship - Asset Extraction", "Please provide a Starfox 64 ROM.\n\nSupported Versions:\nUS 1.0\nUS 1.1\n\nAssets will be extracted into an O2R file.") == IDYES) {
|
||||
if(!GenAssetFile()){
|
||||
ShowMessage("Error", "An error occured, no O2R file was generated.\n\nExiting...");
|
||||
exit(1);
|
||||
@@ -96,7 +96,7 @@ GameEngine::GameEngine() {
|
||||
archiveFiles.push_back(main_path);
|
||||
}
|
||||
|
||||
if (ShowYesNoBox("Extraction Complete", "ROM Extracted. Extract another?") == IDYES) {
|
||||
if (ShowYesNoBox("Extraction Complete", "ROM Extracted. Extract another?\n\n Starship supports JP and EU ROMs for voice replacement.\n Voice replacement ROM assets can also be installed in:\n Settings->Language->Install JP/EU Audio") == IDYES) {
|
||||
if(!GenAssetFile()){
|
||||
ShowMessage("Error", "An error occured, no O2R file was generated.");
|
||||
}
|
||||
@@ -291,7 +291,7 @@ bool GameEngine::GenAssetFile(bool exitOnFail) {
|
||||
}
|
||||
}
|
||||
|
||||
ShowMessage(("Found " + game.value()).c_str(), "The extraction process will now begin.\n\nThis may take a few minutes.", SDL_MESSAGEBOX_INFORMATION);
|
||||
ShowMessage(("Starship - Extraction - Found " + game.value()).c_str(), "The extraction process will now begin.\n\nThis may take a few minutes.", SDL_MESSAGEBOX_INFORMATION);
|
||||
|
||||
return extractor->GenerateOTR();
|
||||
}
|
||||
@@ -522,7 +522,7 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) {
|
||||
|
||||
if (wnd != nullptr) {
|
||||
wnd->SetTargetFps(fps);
|
||||
wnd->SetMaximumFrameLatency(CVarGetInteger("gRenderParallelization", 0) ? 2 : 1);
|
||||
wnd->SetMaximumFrameLatency(CVarGetInteger("gRenderParallelization", 1) ? 2 : 1);
|
||||
}
|
||||
|
||||
// When the gfx debugger is active, only run with the final mtx
|
||||
|
||||
+131
-3
@@ -116,6 +116,117 @@ static const char* voiceLangs[] = {
|
||||
"Original", /*"Japanese",*/ "Lylat"
|
||||
};
|
||||
|
||||
void DrawSpeakerPositionEditor() {
|
||||
static ImVec2 lastCanvasPos;
|
||||
ImGui::Text("Speaker Position Editor");
|
||||
ImVec2 canvasSize = ImVec2(200, 200); // Static canvas size
|
||||
ImVec2 canvasPos = ImGui::GetCursorScreenPos();
|
||||
ImVec2 center = ImVec2(canvasPos.x + canvasSize.x / 2, canvasPos.y + canvasSize.y / 2);
|
||||
|
||||
// Speaker positions
|
||||
static ImVec2 speakerPositions[4];
|
||||
static bool initialized = false;
|
||||
static float radius = 80.0f;
|
||||
|
||||
// Reset positions if canvas position changed (window resized/moved)
|
||||
if (!initialized || (lastCanvasPos.x != canvasPos.x || lastCanvasPos.y != canvasPos.y)) {
|
||||
const char* cvarNames[4] = { "gPositionFrontLeft", "gPositionFrontRight", "gPositionRearLeft", "gPositionRearRight" };
|
||||
float angles[4] = { 240.f, 300.f, 160.f, 20.f }; // Default angles
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int savedAngle = CVarGetInteger(cvarNames[i], -1);
|
||||
if (savedAngle != -1) {
|
||||
angles[i] = static_cast<float>(savedAngle);
|
||||
}
|
||||
|
||||
float rad = angles[i] * (M_PI / 180.0f);
|
||||
speakerPositions[i] = ImVec2(center.x + radius * cosf(rad), center.y + radius * sinf(rad));
|
||||
}
|
||||
initialized = true;
|
||||
lastCanvasPos = canvasPos;
|
||||
}
|
||||
|
||||
// Draw canvas
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
drawList->AddRectFilled(canvasPos, ImVec2(canvasPos.x + canvasSize.x, canvasPos.y + canvasSize.y), IM_COL32(26, 26, 26, 255));
|
||||
drawList->AddCircleFilled(center, 5.0f, IM_COL32(255, 255, 255, 255)); // Central person
|
||||
|
||||
// Draw circle line for speaker positions
|
||||
drawList->AddCircle(center, radius, IM_COL32(163, 163, 163, 255), 100);
|
||||
|
||||
// Add markers at 0, 22.5, 45, etc.
|
||||
for (float angle = 0; angle < 360; angle += 22.5f) {
|
||||
float rad = angle * (M_PI / 180.0f);
|
||||
ImVec2 markerStart = ImVec2(center.x + (radius - 5) * cosf(rad), center.y + (radius - 5) * sinf(rad));
|
||||
ImVec2 markerEnd = ImVec2(center.x + radius * cosf(rad), center.y + radius * sinf(rad));
|
||||
drawList->AddLine(markerStart, markerEnd, IM_COL32(163, 163, 163, 255));
|
||||
}
|
||||
|
||||
const char* speakerLabels[4] = { "L", "R", "RL", "RR" };
|
||||
const char* cvarNames[4] = { "gPositionFrontLeft", "gPositionFrontRight", "gPositionRearLeft", "gPositionRearRight" };
|
||||
|
||||
const float snapThreshold = 2.5f; // Degrees within which snapping occurs
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// Draw speaker as a darker blue circle
|
||||
drawList->AddCircleFilled(speakerPositions[i], 10.0f, IM_COL32(34, 52, 78, 255)); // Dark blue color
|
||||
drawList->AddText(ImVec2(speakerPositions[i].x - 6, speakerPositions[i].y - 6), IM_COL32(255, 255, 255, 255), speakerLabels[i]);
|
||||
|
||||
// Handle dragging
|
||||
ImGui::SetCursorScreenPos(ImVec2(speakerPositions[i].x - 10, speakerPositions[i].y - 10));
|
||||
ImGui::InvisibleButton(speakerLabels[i], ImVec2(20, 20));
|
||||
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
|
||||
ImVec2 mouseDelta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Left);
|
||||
ImVec2 newPos = ImVec2(speakerPositions[i].x + mouseDelta.x, speakerPositions[i].y + mouseDelta.y);
|
||||
|
||||
// Constrain position to the circle
|
||||
ImVec2 direction = ImVec2(newPos.x - center.x, newPos.y - center.y);
|
||||
float length = sqrtf(direction.x * direction.x + direction.y * direction.y);
|
||||
ImVec2 constrainedPos = ImVec2(center.x + (direction.x / length) * radius, center.y + (direction.y / length) * radius);
|
||||
|
||||
// Calculate angle of the constrained position
|
||||
float angle = atan2f(constrainedPos.y - center.y, constrainedPos.x - center.x) * (180.0f / M_PI);
|
||||
if (angle < 0) angle += 360.0f;
|
||||
|
||||
// Snap to the nearest 22.5-degree marker if within the snap threshold
|
||||
float snappedAngle = roundf(angle / 22.5f) * 22.5f;
|
||||
if (fabsf(snappedAngle - angle) <= snapThreshold) {
|
||||
float rad = snappedAngle * (M_PI / 180.0f);
|
||||
constrainedPos = ImVec2(center.x + radius * cosf(rad), center.y + radius * sinf(rad));
|
||||
}
|
||||
|
||||
speakerPositions[i] = constrainedPos;
|
||||
ImGui::ResetMouseDragDelta();
|
||||
|
||||
// Save the updated angle to CVar after dragging
|
||||
float updatedAngle = atan2f(speakerPositions[i].y - center.y, speakerPositions[i].x - center.x) * (180.0f / M_PI);
|
||||
if (updatedAngle < 0) updatedAngle += 360.0f;
|
||||
CVarSetInteger(cvarNames[i], static_cast<int>(updatedAngle));
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); // Mark for saving
|
||||
}
|
||||
|
||||
// Calculate angle and save to CVar
|
||||
float angle = atan2f(speakerPositions[i].y - center.y, speakerPositions[i].x - center.x) * (180.0f / M_PI);
|
||||
if (angle < 0) angle += 360.0f;
|
||||
CVarSetInteger(cvarNames[i], static_cast<int>(angle));
|
||||
}
|
||||
|
||||
// Reset cursor position for button placement
|
||||
ImGui::SetCursorScreenPos(ImVec2(canvasPos.x, canvasPos.y + canvasSize.y + 10));
|
||||
if (ImGui::Button("Reset Positions")) {
|
||||
float defaultAngles[4] = { 240.f, 300.f, 160.f, 20.f };
|
||||
for (int i = 0; i < 4; i++) {
|
||||
float rad = defaultAngles[i] * (M_PI / 180.0f);
|
||||
speakerPositions[i] = ImVec2(center.x + radius * cosf(rad), center.y + radius * sinf(rad));
|
||||
CVarSetInteger(cvarNames[i], static_cast<int>(defaultAngles[i]));
|
||||
}
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
|
||||
// Reset cursor position to ensure canvas size remains static
|
||||
ImGui::SetCursorScreenPos(ImVec2(canvasPos.x, canvasPos.y + canvasSize.y + 10));
|
||||
}
|
||||
|
||||
void DrawSettingsMenu(){
|
||||
if(UIWidgets::BeginMenu("Settings")){
|
||||
if (UIWidgets::BeginMenu("Audio")) {
|
||||
@@ -173,6 +284,23 @@ void DrawSettingsMenu(){
|
||||
}
|
||||
|
||||
UIWidgets::PaddedEnhancementCheckbox("Surround 5.1 (Needs reload)", "gAudioChannelsSetting", 1, 0);
|
||||
|
||||
if (CVarGetInteger("gAudioChannelsSetting", 0) == 1) {
|
||||
// Subwoofer threshold
|
||||
UIWidgets::CVarSliderInt("Subwoofer threshold (Hz)", "gSubwooferThreshold", 10u, 1000u, 80u, {
|
||||
.tooltip = "The threshold for the subwoofer to be activated. Any sound under this frequency will be played on the subwoofer.",
|
||||
.format = "%d",
|
||||
});
|
||||
|
||||
// Rear music volume slider
|
||||
UIWidgets::CVarSliderFloat("Rear music volume", "gVolumeRearMusic", 0.0f, 1.0f, 1.0f, {
|
||||
.format = "%.0f%%",
|
||||
.isPercentage = true,
|
||||
});
|
||||
|
||||
// Configurable positioning of speakers
|
||||
DrawSpeakerPositionEditor();
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@@ -192,10 +320,10 @@ void DrawSettingsMenu(){
|
||||
};
|
||||
} else {
|
||||
if (UIWidgets::Button("Install JP/EU Audio")) {
|
||||
if (GameEngine::GenAssetFile()){
|
||||
if (GameEngine::GenAssetFile(false)){
|
||||
GameEngine::ShowMessage("Success", "Audio assets installed. Changes will be applied on the next startup.", SDL_MESSAGEBOX_INFORMATION);
|
||||
Ship::Context::GetInstance()->GetWindow()->Close();
|
||||
}
|
||||
Ship::Context::GetInstance()->GetWindow()->Close();
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
@@ -321,7 +449,7 @@ void DrawSettingsMenu(){
|
||||
UIWidgets::Tooltip("Matches interpolation value to the refresh rate of your display.");
|
||||
|
||||
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Render parallelization","gRenderParallelization", true, false);
|
||||
UIWidgets::PaddedEnhancementCheckbox("Render parallelization","gRenderParallelization", true, false, {}, {}, {}, true);
|
||||
UIWidgets::Tooltip(
|
||||
"This setting allows the CPU to work on one frame while GPU works on the previous frame.\n"
|
||||
"Recommended if you can't reach the FPS you set, despite it being set below your refresh rate "
|
||||
|
||||
+1
-1
Submodule tools/Torch updated: 9c460ea543...f75facb208
Reference in New Issue
Block a user