First compilation, we just need more stupid assets

This commit is contained in:
KiritoDv
2024-03-24 02:01:28 -06:00
parent 126a55aa0e
commit 641a43cbf9
113 changed files with 3537 additions and 10111 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
#include "sys.h"
#include "sf64audio_provisional.h"
#include "context.h"
#include "sf64context.h"
#include "audiothread_cmd.h"
#include "audioseq_cmd.h"
+11 -22
View File
@@ -296,7 +296,7 @@ s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId) {
void AudioLoad_AsyncLoadSampleBank(s32 sampleBankId, s32 nChunks, s32 retData, OSMesgQueue* retQueue) {
if (AudioLoad_AsyncLoadInner(2, AudioLoad_GetLoadTableIndex(2, sampleBankId), nChunks, retData, retQueue) == NULL) {
osSendMesg(retQueue, NULL, 0);
osSendMesg(retQueue, OS_MESG_PTR(NULL), 0);
}
}
@@ -742,7 +742,7 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData,
ramAddr = AudioLoad_SearchCaches(tableType, id);
if (ramAddr != NULL) {
loadStatus = 2;
osSendMesg(retQueue, (void*) (retData << 0x18), 0);
osSendMesg(retQueue, OS_MESG_32(retData << 0x18), 0);
} else {
table = AudioLoad_GetLoadTable(tableType);
size = table->entries[id].size;
@@ -842,21 +842,9 @@ void AudioLoad_Init(void) {
for (; dwordsLeft >= 0; dwordsLeft--) {
*clearContext++ = 0;
}
switch (osTvType) {
case OS_TV_PAL:
gMaxTempoTvTypeFactors = 20.03042f;
gRefreshRate = 50;
break;
case OS_TV_MPAL:
gMaxTempoTvTypeFactors = 16.546f;
gRefreshRate = 60;
break;
default:
case OS_TV_NTSC:
gMaxTempoTvTypeFactors = 16.713f;
gRefreshRate = 60;
break;
}
// TODO: osTVType should be unnecessary
gMaxTempoTvTypeFactors = 16.713f;
gRefreshRate = 60;
AudioThread_Init();
for (i = 0; i < 3; i++) {
gAiBuffLengths[i] = 0xA0;
@@ -1084,7 +1072,7 @@ AudioAsyncLoad* AudioLoad_StartAsyncLoad(u32 devAddr, u8* ramAddr, u32 size, s32
asyncLoad->delay = 3;
asyncLoad->medium = medium;
asyncLoad->retMsg = retMesg;
asyncLoad->retMsg = OS_MESG_32(retMesg);
osCreateMesgQueue(&asyncLoad->msgQueue, &asyncLoad->msg, 1);
return asyncLoad;
@@ -1128,7 +1116,7 @@ void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus) {
}
}
if (asyncLoad->bytesRemaining == 0) {
temp = asyncLoad->retMsg;
temp = asyncLoad->retMsg.data32;
pad1 = (temp >> 0x10) & 0xFF;
sp24 = (temp >> 8) & 0xFF;
pad2 = temp & 0xFF;
@@ -1352,17 +1340,18 @@ s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus) {
s32 sampleAddr;
u32 size;
s32 nChunks;
OSMesg mesg;
if (gPreloadSampleStackTop > 0) {
if (resetStatus != 0) {
if (osRecvMesg(&gPreloadSampleQueue, (OSMesg) &preloadIndex, 0)) {}
if (osRecvMesg(&gPreloadSampleQueue, &mesg, 0)) {}
gPreloadSampleStackTop = 0;
return false;
}
if (osRecvMesg(&gPreloadSampleQueue, (OSMesg) &preloadIndex, 0) == -1) {
if (osRecvMesg(&gPreloadSampleQueue, &mesg, 0) == -1) {
return false;
}
// "Receive %d\n"
preloadIndex = mesg.data32;
preloadIndex >>= 0x18;
if (gPreloadSampleStack[preloadIndex].isFree == 0) {
+4 -4
View File
@@ -1215,22 +1215,22 @@ Acmd* func_8000B51C(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthSt
switch (delaySide) {
case 1:
aEnvMixer(aList++, dmemSrc, aiBufLen, 0, 0, ((temp_a1 & 0x80) >> 7),
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x65B1C9E1);
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x65B1C9E1, 0);
break;
case 2:
aEnvMixer(aList++, dmemSrc, aiBufLen, 0, 0, ((temp_a1 & 0x80) >> 7),
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x9965C9E1);
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x9965C9E1, 0);
break;
default:
aEnvMixer(aList++, dmemSrc, aiBufLen, 0, 0, ((temp_a1 & 0x80) >> 7),
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x99B1C9E1);
noteSub->bitField0.stereoStrongRight, noteSub->bitField0.stereoStrongLeft, 0x99B1C9E1, 0);
break;
}
} else {
aEnvSetup1(aList++, (temp_a1 & 0x7F), var_a2, var_t0, var_a3);
aEnvSetup2(aList++, temp_t1, temp_t2);
aEnvMixer(aList++, dmemSrc, aiBufLen, 0, 0, ((temp_a1 & 0x80) >> 7), noteSub->bitField0.stereoStrongRight,
noteSub->bitField0.stereoStrongLeft, 0x99B1C9E1);
noteSub->bitField0.stereoStrongLeft, 0x99B1C9E1, 0);
}
return aList;
+18 -18
View File
@@ -49,15 +49,15 @@ SPTask* AudioThread_CreateTask(void) {
OSTask_t* task;
u16* sp40;
s32 pad3C;
u32 sp38;
u32 sp34;
OSMesg sp38;
OSMesg sp34;
s32 pad30;
gAudioTaskCountQ++;
if ((gAudioTaskCountQ % gAudioBufferParams.specUnk4) != 0) {
return gWaitingAudioTask;
}
osSendMesg(gAudioTaskStartQueue, (OSMesg) gAudioTaskCountQ, 0);
osSendMesg(gAudioTaskStartQueue, OS_MESG_32(gAudioTaskCountQ), 0);
gAudioTaskIndexQ ^= 1;
gCurAiBuffIndex++;
gCurAiBuffIndex %= 3;
@@ -71,15 +71,15 @@ SPTask* AudioThread_CreateTask(void) {
gCurAudioFrameDmaCount = 0;
AudioLoad_DecreaseSampleDmaTtls();
AudioLoad_ProcessLoads(gResetStatus);
if (osRecvMesg(gAudioUnkQueue, (OSMesg) &sp38, 0) != -1) {
if (osRecvMesg(gAudioUnkQueue, &sp38, 0) != -1) {
if (gResetStatus == 0) {
gResetStatus = 5;
}
gAudioSpecId = sp38;
gAudioSpecId = sp38.data32;
}
if ((gResetStatus != 0) && (AudioHeap_ResetStep() == 0)) {
if (gResetStatus == 0) {
osSendMesg(gAudioResetQueue, (OSMesg) (s32) gAudioSpecId, 0);
osSendMesg(gAudioResetQueue, OS_MESG_32((s32) gAudioSpecId), 0);
}
gWaitingAudioTask = NULL;
return NULL;
@@ -102,8 +102,8 @@ SPTask* AudioThread_CreateTask(void) {
if (gAiBuffLengths[sp4C] > gAudioBufferParams.maxAiBufferLength) {
gAiBuffLengths[sp4C] = gAudioBufferParams.maxAiBufferLength;
}
while (osRecvMesg(gThreadCmdProcQueue, (OSMesg) &sp34, 0) != -1) {
AudioThread_ProcessCmds(sp34);
while (osRecvMesg(gThreadCmdProcQueue, &sp34, 0) != -1) {
AudioThread_ProcessCmds(sp34.data32);
}
gCurAbiCmdBuffer = func_80009B64(gCurAbiCmdBuffer, &sp50, sp40, gAiBuffLengths[sp4C]);
gAudioRandom = osGetCount() * (gAudioRandom + gAudioTaskCountQ);
@@ -112,19 +112,19 @@ SPTask* AudioThread_CreateTask(void) {
sp4C = gAudioTaskIndexQ;
gAudioCurTask->msgQueue = NULL;
gAudioCurTask->msg = NULL;
gAudioCurTask->msg = OS_MESG_PTR(NULL);
task = &gAudioCurTask->task.t;
task->type = 2;
task->flags = 0;
task->ucode_boot = rspbootTextStart;
task->ucode_boot_size = (uintptr_t) rspbootTextEnd - (uintptr_t) rspbootTextStart;
task->ucode = aspMainTextStart;
task->ucode_data = aspMainDataStart;
task->ucode_size = SP_UCODE_SIZE;
task->ucode_data_size = (aspMainDataEnd - aspMainDataStart) * 8;
// task->ucode_boot = rspbootTextStart;
// task->ucode_boot_size = (uintptr_t) rspbootTextEnd - (uintptr_t) rspbootTextStart;
//
// task->ucode = aspMainTextStart;
// task->ucode_data = aspMainDataStart;
// task->ucode_size = SP_UCODE_SIZE;
// task->ucode_data_size = (aspMainDataEnd - aspMainDataStart) * 8;
task->dram_stack = NULL;
task->dram_stack_size = 0;
@@ -282,7 +282,7 @@ void AudioThread_ScheduleProcessCmds(void) {
D_800C7C70 = (u8) (gThreadCmdWritePos - gThreadCmdReadPos + 0x100);
}
msg = (((gThreadCmdReadPos & 0xFF) << 8) | (gThreadCmdWritePos & 0xFF));
osSendMesg(gThreadCmdProcQueue, (OSMesg) msg, 0);
osSendMesg(gThreadCmdProcQueue, OS_MESG_32(msg), 0);
gThreadCmdReadPos = gThreadCmdWritePos;
}
@@ -420,7 +420,7 @@ void AudioThread_ResetAudioHeap(s32 specId) {
// clang-format on
AudioThread_ResetCmdQueue();
osSendMesg(gAudioUnkQueue, (OSMesg) specId, 0);
osSendMesg(gAudioUnkQueue, OS_MESG_32(specId), 0);
}
void AudioThread_PreNMIReset(void) {
-1
View File
@@ -1,6 +1,5 @@
#include "global.h"
u64 gDramStack[SP_DRAM_STACK_SIZE64];
u8 gOSYieldData[OS_YIELD_DATA_SIZE];
FrameBuffer gZBuffer; // z buffer
u8 gTaskOutputBuffer[0x30000];
+78 -78
View File
@@ -6,82 +6,82 @@
{ NULL, { NULL, NULL }, false }
DmaEntry gDmaTable[90] = {
{ SEGMENT_ROM_START(makerom), { SEGMENT_ROM_START(makerom), SEGMENT_ROM_END(makerom) }, false },
{ SEGMENT_ROM_START(main), { SEGMENT_ROM_START(main), SEGMENT_ROM_END(main) }, false },
{ SEGMENT_ROM_START(dma_table), { SEGMENT_ROM_START(dma_table), SEGMENT_ROM_END(dma_table) }, false },
{ SEGMENT_ROM_START(audio_seq), { SEGMENT_ROM_START(audio_seq), SEGMENT_ROM_END(audio_seq) }, false },
{ SEGMENT_ROM_START(audio_bank), { SEGMENT_ROM_START(audio_bank), SEGMENT_ROM_END(audio_bank) }, false },
{ SEGMENT_ROM_START(audio_table), { SEGMENT_ROM_START(audio_table), SEGMENT_ROM_END(audio_table) }, false },
{ SEGMENT_ROM_START(ast_common), { SEGMENT_ROM_START(ast_common), SEGMENT_ROM_END(ast_common) }, false },
{ SEGMENT_ROM_START(ast_bg_space), { SEGMENT_ROM_START(ast_bg_space), SEGMENT_ROM_END(ast_bg_space) }, false },
{ SEGMENT_ROM_START(ast_bg_planet), { SEGMENT_ROM_START(ast_bg_planet), SEGMENT_ROM_END(ast_bg_planet) }, false },
{ SEGMENT_ROM_START(ast_arwing), { SEGMENT_ROM_START(ast_arwing), SEGMENT_ROM_END(ast_arwing) }, false },
{ SEGMENT_ROM_START(ast_landmaster),
{ SEGMENT_ROM_START(ast_landmaster), SEGMENT_ROM_END(ast_landmaster) },
false },
{ SEGMENT_ROM_START(ast_blue_marine),
{ SEGMENT_ROM_START(ast_blue_marine), SEGMENT_ROM_END(ast_blue_marine) },
false },
{ SEGMENT_ROM_START(ast_versus), { SEGMENT_ROM_START(ast_versus), SEGMENT_ROM_END(ast_versus) }, false },
{ SEGMENT_ROM_START(ast_enmy_planet),
{ SEGMENT_ROM_START(ast_enmy_planet), SEGMENT_ROM_END(ast_enmy_planet) },
false },
{ SEGMENT_ROM_START(ast_enmy_space),
{ SEGMENT_ROM_START(ast_enmy_space), SEGMENT_ROM_END(ast_enmy_space) },
false },
{ SEGMENT_ROM_START(ast_great_fox), { SEGMENT_ROM_START(ast_great_fox), SEGMENT_ROM_END(ast_great_fox) }, false },
{ SEGMENT_ROM_START(ast_star_wolf), { SEGMENT_ROM_START(ast_star_wolf), SEGMENT_ROM_END(ast_star_wolf) }, false },
{ SEGMENT_ROM_START(ast_allies), { SEGMENT_ROM_START(ast_allies), SEGMENT_ROM_END(ast_allies) }, false },
{ SEGMENT_ROM_START(ast_corneria), { SEGMENT_ROM_START(ast_corneria), SEGMENT_ROM_END(ast_corneria) }, false },
{ SEGMENT_ROM_START(ast_meteo), { SEGMENT_ROM_START(ast_meteo), SEGMENT_ROM_END(ast_meteo) }, false },
{ SEGMENT_ROM_START(ast_titania), { SEGMENT_ROM_START(ast_titania), SEGMENT_ROM_END(ast_titania) }, false },
{ SEGMENT_ROM_START(ast_7_ti_2), { SEGMENT_ROM_START(ast_7_ti_2), SEGMENT_ROM_END(ast_7_ti_2) }, false },
{ SEGMENT_ROM_START(ast_8_ti), { SEGMENT_ROM_START(ast_8_ti), SEGMENT_ROM_END(ast_8_ti) }, false },
{ SEGMENT_ROM_START(ast_9_ti), { SEGMENT_ROM_START(ast_9_ti), SEGMENT_ROM_END(ast_9_ti) }, false },
{ SEGMENT_ROM_START(ast_A_ti), { SEGMENT_ROM_START(ast_A_ti), SEGMENT_ROM_END(ast_A_ti) }, false },
{ SEGMENT_ROM_START(ast_7_ti_1), { SEGMENT_ROM_START(ast_7_ti_1), SEGMENT_ROM_END(ast_7_ti_1) }, false },
{ SEGMENT_ROM_START(ast_sector_x), { SEGMENT_ROM_START(ast_sector_x), SEGMENT_ROM_END(ast_sector_x) }, false },
{ SEGMENT_ROM_START(ast_sector_z), { SEGMENT_ROM_START(ast_sector_z), SEGMENT_ROM_END(ast_sector_z) }, false },
{ SEGMENT_ROM_START(ast_aquas), { SEGMENT_ROM_START(ast_aquas), SEGMENT_ROM_END(ast_aquas) }, false },
{ SEGMENT_ROM_START(ast_area_6), { SEGMENT_ROM_START(ast_area_6), SEGMENT_ROM_END(ast_area_6) }, false },
{ SEGMENT_ROM_START(ast_venom_1), { SEGMENT_ROM_START(ast_venom_1), SEGMENT_ROM_END(ast_venom_1) }, false },
{ SEGMENT_ROM_START(ast_venom_2), { SEGMENT_ROM_START(ast_venom_2), SEGMENT_ROM_END(ast_venom_2) }, false },
{ SEGMENT_ROM_START(ast_ve1_boss), { SEGMENT_ROM_START(ast_ve1_boss), SEGMENT_ROM_END(ast_ve1_boss) }, false },
{ SEGMENT_ROM_START(ast_bolse), { SEGMENT_ROM_START(ast_bolse), SEGMENT_ROM_END(ast_bolse) }, false },
{ SEGMENT_ROM_START(ast_fortuna), { SEGMENT_ROM_START(ast_fortuna), SEGMENT_ROM_END(ast_fortuna) }, false },
{ SEGMENT_ROM_START(ast_sector_y), { SEGMENT_ROM_START(ast_sector_y), SEGMENT_ROM_END(ast_sector_y) }, false },
{ SEGMENT_ROM_START(ast_solar), { SEGMENT_ROM_START(ast_solar), SEGMENT_ROM_END(ast_solar) }, false },
{ SEGMENT_ROM_START(ast_zoness), { SEGMENT_ROM_START(ast_zoness), SEGMENT_ROM_END(ast_zoness) }, false },
{ SEGMENT_ROM_START(ast_katina), { SEGMENT_ROM_START(ast_katina), SEGMENT_ROM_END(ast_katina) }, false },
{ SEGMENT_ROM_START(ast_macbeth), { SEGMENT_ROM_START(ast_macbeth), SEGMENT_ROM_END(ast_macbeth) }, false },
{ SEGMENT_ROM_START(ast_warp_zone), { SEGMENT_ROM_START(ast_warp_zone), SEGMENT_ROM_END(ast_warp_zone) }, false },
{ SEGMENT_ROM_START(ast_title), { SEGMENT_ROM_START(ast_title), SEGMENT_ROM_END(ast_title) }, false },
{ SEGMENT_ROM_START(ast_map), { SEGMENT_ROM_START(ast_map), SEGMENT_ROM_END(ast_map) }, false },
{ SEGMENT_ROM_START(ast_option), { SEGMENT_ROM_START(ast_option), SEGMENT_ROM_END(ast_option) }, false },
{ SEGMENT_ROM_START(ast_vs_menu), { SEGMENT_ROM_START(ast_vs_menu), SEGMENT_ROM_END(ast_vs_menu) }, false },
{ SEGMENT_ROM_START(ast_font), { SEGMENT_ROM_START(ast_font), SEGMENT_ROM_END(ast_font) }, false },
{ SEGMENT_ROM_START(ast_font_3d), { SEGMENT_ROM_START(ast_font_3d), SEGMENT_ROM_END(ast_font_3d) }, false },
{ SEGMENT_ROM_START(ast_andross), { SEGMENT_ROM_START(ast_andross), SEGMENT_ROM_END(ast_andross) }, false },
{ SEGMENT_ROM_START(ast_logo), { SEGMENT_ROM_START(ast_logo), SEGMENT_ROM_END(ast_logo) }, false },
{ SEGMENT_ROM_START(ast_ending), { SEGMENT_ROM_START(ast_ending), SEGMENT_ROM_END(ast_ending) }, false },
{ SEGMENT_ROM_START(ast_ending_award_front),
{ SEGMENT_ROM_START(ast_ending_award_front), SEGMENT_ROM_END(ast_ending_award_front) },
false },
{ SEGMENT_ROM_START(ast_ending_award_back),
{ SEGMENT_ROM_START(ast_ending_award_back), SEGMENT_ROM_END(ast_ending_award_back) },
false },
{ SEGMENT_ROM_START(ast_ending_expert),
{ SEGMENT_ROM_START(ast_ending_expert), SEGMENT_ROM_END(ast_ending_expert) },
false },
{ SEGMENT_ROM_START(ast_training), { SEGMENT_ROM_START(ast_training), SEGMENT_ROM_END(ast_training) }, false },
{ SEGMENT_ROM_START(ast_radio), { SEGMENT_ROM_START(ast_radio), SEGMENT_ROM_END(ast_radio) }, false },
{ SEGMENT_ROM_START(ovl_i1), { SEGMENT_ROM_START(ovl_i1), SEGMENT_ROM_END(ovl_i1) }, false },
{ SEGMENT_ROM_START(ovl_i2), { SEGMENT_ROM_START(ovl_i2), SEGMENT_ROM_END(ovl_i2) }, false },
{ SEGMENT_ROM_START(ovl_i3), { SEGMENT_ROM_START(ovl_i3), SEGMENT_ROM_END(ovl_i3) }, false },
{ SEGMENT_ROM_START(ovl_i4), { SEGMENT_ROM_START(ovl_i4), SEGMENT_ROM_END(ovl_i4) }, false },
{ SEGMENT_ROM_START(ovl_i5), { SEGMENT_ROM_START(ovl_i5), SEGMENT_ROM_END(ovl_i5) }, false },
{ SEGMENT_ROM_START(ovl_i6), { SEGMENT_ROM_START(ovl_i6), SEGMENT_ROM_END(ovl_i6) }, false },
{ SEGMENT_ROM_START(ovl_menu), { SEGMENT_ROM_START(ovl_menu), SEGMENT_ROM_END(ovl_menu) }, false },
{ SEGMENT_ROM_START(ovl_ending), { SEGMENT_ROM_START(ovl_ending), SEGMENT_ROM_END(ovl_ending) }, false },
{ SEGMENT_ROM_START(ovl_unused), { SEGMENT_ROM_START(ovl_unused), SEGMENT_ROM_END(ovl_unused) }, false },
// { SEGMENT_ROM_START(makerom), { SEGMENT_ROM_START(makerom), SEGMENT_ROM_END(makerom) }, false },
// { SEGMENT_ROM_START(main), { SEGMENT_ROM_START(main), SEGMENT_ROM_END(main) }, false },
// { SEGMENT_ROM_START(dma_table), { SEGMENT_ROM_START(dma_table), SEGMENT_ROM_END(dma_table) }, false },
// { SEGMENT_ROM_START(audio_seq), { SEGMENT_ROM_START(audio_seq), SEGMENT_ROM_END(audio_seq) }, false },
// { SEGMENT_ROM_START(audio_bank), { SEGMENT_ROM_START(audio_bank), SEGMENT_ROM_END(audio_bank) }, false },
// { SEGMENT_ROM_START(audio_table), { SEGMENT_ROM_START(audio_table), SEGMENT_ROM_END(audio_table) }, false },
// { SEGMENT_ROM_START(ast_common), { SEGMENT_ROM_START(ast_common), SEGMENT_ROM_END(ast_common) }, false },
// { SEGMENT_ROM_START(ast_bg_space), { SEGMENT_ROM_START(ast_bg_space), SEGMENT_ROM_END(ast_bg_space) }, false },
// { SEGMENT_ROM_START(ast_bg_planet), { SEGMENT_ROM_START(ast_bg_planet), SEGMENT_ROM_END(ast_bg_planet) }, false },
// { SEGMENT_ROM_START(ast_arwing), { SEGMENT_ROM_START(ast_arwing), SEGMENT_ROM_END(ast_arwing) }, false },
// { SEGMENT_ROM_START(ast_landmaster),
// { SEGMENT_ROM_START(ast_landmaster), SEGMENT_ROM_END(ast_landmaster) },
// false },
// { SEGMENT_ROM_START(ast_blue_marine),
// { SEGMENT_ROM_START(ast_blue_marine), SEGMENT_ROM_END(ast_blue_marine) },
// false },
// { SEGMENT_ROM_START(ast_vs_player), { SEGMENT_ROM_START(ast_vs_player), SEGMENT_ROM_END(ast_vs_player) }, false },
// { SEGMENT_ROM_START(ast_enmy_planet),
// { SEGMENT_ROM_START(ast_enmy_planet), SEGMENT_ROM_END(ast_enmy_planet) },
// false },
// { SEGMENT_ROM_START(ast_enmy_space),
// { SEGMENT_ROM_START(ast_enmy_space), SEGMENT_ROM_END(ast_enmy_space) },
// false },
// { SEGMENT_ROM_START(ast_great_fox), { SEGMENT_ROM_START(ast_great_fox), SEGMENT_ROM_END(ast_great_fox) }, false },
// { SEGMENT_ROM_START(ast_star_wolf), { SEGMENT_ROM_START(ast_star_wolf), SEGMENT_ROM_END(ast_star_wolf) }, false },
// { SEGMENT_ROM_START(ast_allies), { SEGMENT_ROM_START(ast_allies), SEGMENT_ROM_END(ast_allies) }, false },
// { SEGMENT_ROM_START(ast_corneria), { SEGMENT_ROM_START(ast_corneria), SEGMENT_ROM_END(ast_corneria) }, false },
// { SEGMENT_ROM_START(ast_meteo), { SEGMENT_ROM_START(ast_meteo), SEGMENT_ROM_END(ast_meteo) }, false },
// { SEGMENT_ROM_START(ast_titania), { SEGMENT_ROM_START(ast_titania), SEGMENT_ROM_END(ast_titania) }, false },
// { SEGMENT_ROM_START(ast_7_ti_2), { SEGMENT_ROM_START(ast_7_ti_2), SEGMENT_ROM_END(ast_7_ti_2) }, false },
// { SEGMENT_ROM_START(ast_8_ti), { SEGMENT_ROM_START(ast_8_ti), SEGMENT_ROM_END(ast_8_ti) }, false },
// { SEGMENT_ROM_START(ast_9_ti), { SEGMENT_ROM_START(ast_9_ti), SEGMENT_ROM_END(ast_9_ti) }, false },
// { SEGMENT_ROM_START(ast_A_ti), { SEGMENT_ROM_START(ast_A_ti), SEGMENT_ROM_END(ast_A_ti) }, false },
// { SEGMENT_ROM_START(ast_7_ti_1), { SEGMENT_ROM_START(ast_7_ti_1), SEGMENT_ROM_END(ast_7_ti_1) }, false },
// { SEGMENT_ROM_START(ast_sector_x), { SEGMENT_ROM_START(ast_sector_x), SEGMENT_ROM_END(ast_sector_x) }, false },
// { SEGMENT_ROM_START(ast_sector_z), { SEGMENT_ROM_START(ast_sector_z), SEGMENT_ROM_END(ast_sector_z) }, false },
// { SEGMENT_ROM_START(ast_aquas), { SEGMENT_ROM_START(ast_aquas), SEGMENT_ROM_END(ast_aquas) }, false },
// { SEGMENT_ROM_START(ast_area_6), { SEGMENT_ROM_START(ast_area_6), SEGMENT_ROM_END(ast_area_6) }, false },
// { SEGMENT_ROM_START(ast_venom_1), { SEGMENT_ROM_START(ast_venom_1), SEGMENT_ROM_END(ast_venom_1) }, false },
// { SEGMENT_ROM_START(ast_venom_2), { SEGMENT_ROM_START(ast_venom_2), SEGMENT_ROM_END(ast_venom_2) }, false },
// { SEGMENT_ROM_START(ast_ve1_boss), { SEGMENT_ROM_START(ast_ve1_boss), SEGMENT_ROM_END(ast_ve1_boss) }, false },
// { SEGMENT_ROM_START(ast_bolse), { SEGMENT_ROM_START(ast_bolse), SEGMENT_ROM_END(ast_bolse) }, false },
// { SEGMENT_ROM_START(ast_fortuna), { SEGMENT_ROM_START(ast_fortuna), SEGMENT_ROM_END(ast_fortuna) }, false },
// { SEGMENT_ROM_START(ast_sector_y), { SEGMENT_ROM_START(ast_sector_y), SEGMENT_ROM_END(ast_sector_y) }, false },
// { SEGMENT_ROM_START(ast_solar), { SEGMENT_ROM_START(ast_solar), SEGMENT_ROM_END(ast_solar) }, false },
// { SEGMENT_ROM_START(ast_zoness), { SEGMENT_ROM_START(ast_zoness), SEGMENT_ROM_END(ast_zoness) }, false },
// { SEGMENT_ROM_START(ast_katina), { SEGMENT_ROM_START(ast_katina), SEGMENT_ROM_END(ast_katina) }, false },
// { SEGMENT_ROM_START(ast_macbeth), { SEGMENT_ROM_START(ast_macbeth), SEGMENT_ROM_END(ast_macbeth) }, false },
// { SEGMENT_ROM_START(ast_warp_zone), { SEGMENT_ROM_START(ast_warp_zone), SEGMENT_ROM_END(ast_warp_zone) }, false },
// { SEGMENT_ROM_START(ast_title), { SEGMENT_ROM_START(ast_title), SEGMENT_ROM_END(ast_title) }, false },
// { SEGMENT_ROM_START(ast_map), { SEGMENT_ROM_START(ast_map), SEGMENT_ROM_END(ast_map) }, false },
// { SEGMENT_ROM_START(ast_option), { SEGMENT_ROM_START(ast_option), SEGMENT_ROM_END(ast_option) }, false },
// { SEGMENT_ROM_START(ast_versus), { SEGMENT_ROM_START(ast_versus), SEGMENT_ROM_END(ast_versus) }, false },
// { SEGMENT_ROM_START(ast_font), { SEGMENT_ROM_START(ast_font), SEGMENT_ROM_END(ast_font) }, false },
// { SEGMENT_ROM_START(ast_font_3d), { SEGMENT_ROM_START(ast_font_3d), SEGMENT_ROM_END(ast_font_3d) }, false },
// { SEGMENT_ROM_START(ast_andross), { SEGMENT_ROM_START(ast_andross), SEGMENT_ROM_END(ast_andross) }, false },
// { SEGMENT_ROM_START(ast_logo), { SEGMENT_ROM_START(ast_logo), SEGMENT_ROM_END(ast_logo) }, false },
// { SEGMENT_ROM_START(ast_ending), { SEGMENT_ROM_START(ast_ending), SEGMENT_ROM_END(ast_ending) }, false },
// { SEGMENT_ROM_START(ast_ending_award_front),
// { SEGMENT_ROM_START(ast_ending_award_front), SEGMENT_ROM_END(ast_ending_award_front) },
// false },
// { SEGMENT_ROM_START(ast_ending_award_back),
// { SEGMENT_ROM_START(ast_ending_award_back), SEGMENT_ROM_END(ast_ending_award_back) },
// false },
// { SEGMENT_ROM_START(ast_ending_expert),
// { SEGMENT_ROM_START(ast_ending_expert), SEGMENT_ROM_END(ast_ending_expert) },
// false },
// { SEGMENT_ROM_START(ast_training), { SEGMENT_ROM_START(ast_training), SEGMENT_ROM_END(ast_training) }, false },
// { SEGMENT_ROM_START(ast_radio), { SEGMENT_ROM_START(ast_radio), SEGMENT_ROM_END(ast_radio) }, false },
// { SEGMENT_ROM_START(ovl_i1), { SEGMENT_ROM_START(ovl_i1), SEGMENT_ROM_END(ovl_i1) }, false },
// { SEGMENT_ROM_START(ovl_i2), { SEGMENT_ROM_START(ovl_i2), SEGMENT_ROM_END(ovl_i2) }, false },
// { SEGMENT_ROM_START(ovl_i3), { SEGMENT_ROM_START(ovl_i3), SEGMENT_ROM_END(ovl_i3) }, false },
// { SEGMENT_ROM_START(ovl_i4), { SEGMENT_ROM_START(ovl_i4), SEGMENT_ROM_END(ovl_i4) }, false },
// { SEGMENT_ROM_START(ovl_i5), { SEGMENT_ROM_START(ovl_i5), SEGMENT_ROM_END(ovl_i5) }, false },
// { SEGMENT_ROM_START(ovl_i6), { SEGMENT_ROM_START(ovl_i6), SEGMENT_ROM_END(ovl_i6) }, false },
// { SEGMENT_ROM_START(ovl_menu), { SEGMENT_ROM_START(ovl_menu), SEGMENT_ROM_END(ovl_menu) }, false },
// { SEGMENT_ROM_START(ovl_ending), { SEGMENT_ROM_START(ovl_ending), SEGMENT_ROM_END(ovl_ending) }, false },
// { SEGMENT_ROM_START(ovl_unused), { SEGMENT_ROM_START(ovl_unused), SEGMENT_ROM_END(ovl_unused) }, false },
};
+4 -2
View File
@@ -2272,10 +2272,12 @@ void ActorAllRange_Draw(Actor* actor) {
break;
}
} else if (gCurrentLevel == LEVEL_SECTOR_Z) {
gSPDisplayList(gMasterDisp++, D_SZ_6004FE0) Matrix_Translate(gGfxMatrix, 0.0f, 0.0f, -60.0f, 1);
gSPDisplayList(gMasterDisp++, D_SZ_6004FE0);
Matrix_Translate(gGfxMatrix, 0.0f, 0.0f, -60.0f, 1);
func_edisplay_8005B1E8(actor, 2);
} else if (gCurrentLevel == LEVEL_BOLSE) {
gSPDisplayList(gMasterDisp++, D_BO_6008770) Matrix_Push(&gGfxMatrix);
gSPDisplayList(gMasterDisp++, D_BO_6008770);
Matrix_Push(&gGfxMatrix);
Matrix_Translate(gGfxMatrix, 0.0f, 0.0f, -60.0f, 1);
func_edisplay_8005B1E8(actor, 2);
Matrix_Pop(&gGfxMatrix);
+17 -18
View File
@@ -27,22 +27,21 @@ OverlayInit sCurrentOverlay = {
};
void Overlay_LoadSegment(void* vRomAddress, void* dest, ptrdiff_t size) {
s32 i;
for (i = 0; gDmaTable[i].pRom.end != NULL; i++) {
if (gDmaTable[i].vRomAddress == vRomAddress) {
if (gDmaTable[i].compFlag == 0) {
Lib_DmaRead(gDmaTable[i].pRom.start, dest, size);
} else {
Lib_FillScreen(true);
sFillTimer = 3;
D_game_80161A39 = true;
Lib_DmaRead(gDmaTable[i].pRom.start, gFrameBuffers, SEGMENT_SIZE(gDmaTable[i].pRom));
Mio0_Decompress(gFrameBuffers, dest);
}
break;
}
}
// s32 i;
// for (i = 0; gDmaTable[i].pRom.end != NULL; i++) {
// if (gDmaTable[i].vRomAddress == vRomAddress) {
// if (gDmaTable[i].compFlag == 0) {
// Lib_DmaRead(gDmaTable[i].pRom.start, dest, size);
// } else {
// Lib_FillScreen(true);
// sFillTimer = 3;
// D_80161A39 = true;
// Lib_DmaRead(gDmaTable[i].pRom.start, gFrameBuffers, SEGMENT_SIZE(gDmaTable[i].pRom));
// Mio0_Decompress(gFrameBuffers, dest);
// }
// break;
// }
// }
}
u8 Overlay_Init(OverlayInit* ovlInit) {
@@ -196,6 +195,6 @@ u8 Overlay_Load(u8 ovlSetup, u8 ovlStage) {
}
void Overlay_InitDma(void) {
Lib_DmaRead(SEGMENT_ROM_START(dma_table), SEGMENT_VRAM_START(dma_table), SEGMENT_ROM_SIZE(dma_table));
Overlay_LoadSegment(SEGMENT_ROM_START(ast_radio), SEGMENT_VRAM_START(ast_radio), SEGMENT_ROM_SIZE(ast_radio));
// Lib_DmaRead(SEGMENT_ROM_START(dma_table), SEGMENT_VRAM_START(dma_table), SEGMENT_ROM_SIZE(dma_table));
// Overlay_LoadSegment(SEGMENT_ROM_START(ast_radio), SEGMENT_VRAM_START(ast_radio), SEGMENT_ROM_SIZE(ast_radio));
}
+2 -7
View File
@@ -4,12 +4,7 @@
{ NULL, NULL }
#define OVERLAY_OFFSETS(file) \
{ \
{ SEGMENT_ROM_START(file), SEGMENT_ROM_END(file) }, { SEGMENT_BSS_START(file), SEGMENT_BSS_END(file) }, \
{ SEGMENT_TEXT_START(file), SEGMENT_TEXT_END(file) }, { \
SEGMENT_DATA_START(file), SEGMENT_RODATA_END(file) \
} \
}
NO_OVERLAY
#define NO_OVERLAY \
{ \
@@ -19,7 +14,7 @@
}
#define ROM_SEGMENT(file) \
{ SEGMENT_ROM_START(file), SEGMENT_ROM_END(file) }
NO_SEGMENT
OverlayInit sNoOvl_Logo[1] = {
{ NO_OVERLAY,
+6 -6
View File
@@ -39,26 +39,26 @@ u16 Save_Checksum(Save* arg0) {
}
s32 Save_Write(void) {
void* sp1C;
OSMesg sp1C;
gSaveFile.save.checksum = Save_Checksum(&gSaveFile.save);
gSaveFile.backup = gSaveFile.save;
gSaveIOBuffer = gSaveFile;
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_WRITE_SAVE, OS_MESG_PRI_NORMAL);
osSendMesg(&gSerialThreadMsgQueue, OS_MESG_32(SI_WRITE_SAVE), OS_MESG_PRI_NORMAL);
osRecvMesg(&gSaveMsgQueue, &sp1C, OS_MESG_BLOCK);
if (sp1C != (OSMesg) SI_SAVE_SUCCESS) {
if (sp1C.data32 != SI_SAVE_SUCCESS) {
return -1;
}
return 0;
}
s32 Save_Read(void) {
void* sp24;
OSMesg* sp24;
s32 i;
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_SAVE, OS_MESG_PRI_NORMAL);
osSendMesg(&gSerialThreadMsgQueue, OS_MESG_32(SI_READ_SAVE), OS_MESG_PRI_NORMAL);
osRecvMesg(&gSaveMsgQueue, &sp24, OS_MESG_BLOCK);
if ((s32) sp24 != SI_SAVE_SUCCESS) {
if (sp24->data32 != SI_SAVE_SUCCESS) {
return -1;
}
+40
View File
@@ -0,0 +1,40 @@
#include <libultraship.h>
#include <math.h>
void guPerspectiveF(float mf[4][4], u16 *perspNorm, float fovy, float aspect, float near, float far,
float scale) {
float yscale;
int row;
int col;
guMtxIdentF(mf);
fovy *= GU_PI / 180.0;
yscale = cosf(fovy / 2) / sinf(fovy / 2);
mf[0][0] = yscale / aspect;
mf[1][1] = yscale;
mf[2][2] = (near + far) / (near - far);
mf[2][3] = -1;
mf[3][2] = 2 * near * far / (near - far);
mf[3][3] = 0.0f;
for (row = 0; row < 4; row++) {
for (col = 0; col < 4; col++) {
mf[row][col] *= scale;
}
}
if (perspNorm != NULL) {
if (near + far <= 2.0) {
*perspNorm = 65535;
} else {
*perspNorm = (double) (1 << 17) / (near + far);
if (*perspNorm <= 0) {
*perspNorm = 1;
}
}
}
}
void guPerspective(Mtx *m, u16 *perspNorm, float fovy, float aspect, float near, float far,
float scale) {
float mat[4][4];
guPerspectiveF(mat, perspNorm, fovy, aspect, near, far, scale);
guMtxF2L(mat, m);
}
+73
View File
@@ -0,0 +1,73 @@
#include <libultraship.h>
void guLookAtF(float mf[4][4], float xEye, float yEye, float zEye, float xAt, float yAt, float zAt, float xUp,
float yUp, float zUp) {
float len;
float xLook;
float yLook;
float zLook;
float xRight;
float yRight;
float zRight;
guMtxIdentF(mf);
xLook = xAt - xEye;
yLook = yAt - yEye;
zLook = zAt - zEye;
/* Negate because positive Z is behind us: */
len = -1.0 / guSqrtf(xLook * xLook + yLook * yLook + zLook * zLook);
xLook *= len;
yLook *= len;
zLook *= len;
/* Right = Up x Look */
xRight = yUp * zLook - zUp * yLook;
yRight = zUp * xLook - xUp * zLook;
zRight = xUp * yLook - yUp * xLook;
len = 1.0 / guSqrtf(xRight * xRight + yRight * yRight + zRight * zRight);
xRight *= len;
yRight *= len;
zRight *= len;
/* Up = Look x Right */
xUp = yLook * zRight - zLook * yRight;
yUp = zLook * xRight - xLook * zRight;
zUp = xLook * yRight - yLook * xRight;
len = 1.0 / guSqrtf(xUp * xUp + yUp * yUp + zUp * zUp);
xUp *= len;
yUp *= len;
zUp *= len;
mf[0][0] = xRight;
mf[1][0] = yRight;
mf[2][0] = zRight;
mf[3][0] = -(xEye * xRight + yEye * yRight + zEye * zRight);
mf[0][1] = xUp;
mf[1][1] = yUp;
mf[2][1] = zUp;
mf[3][1] = -(xEye * xUp + yEye * yUp + zEye * zUp);
mf[0][2] = xLook;
mf[1][2] = yLook;
mf[2][2] = zLook;
mf[3][2] = -(xEye * xLook + yEye * yLook + zEye * zLook);
mf[0][3] = 0;
mf[1][3] = 0;
mf[2][3] = 0;
mf[3][3] = 1;
}
void guLookAt(Mtx* m, float xEye, float yEye, float zEye, float xAt, float yAt, float zAt, float xUp, float yUp,
float zUp) {
float mf[4][4];
guLookAtF(mf, xEye, yEye, zEye, xAt, yAt, zAt, xUp, yUp, zUp);
guMtxF2L(mf, m);
}
+23 -23
View File
@@ -6,26 +6,26 @@ void* proutSprintf(void* dst, const char* fmt, size_t size) {
return (void*) ((uintptr_t) memcpy(dst, fmt, size) + size);
}
s32 vsprintf(char* dst, const char* fmt, va_list args) {
s32 ret = _Printf((outfun*) proutSprintf, dst, fmt, args);
if (ret > -1) {
dst[ret] = 0;
}
return ret;
}
int sprintf(char* s, const char* fmt, ...) {
s32 ret;
va_list args;
va_start(args, fmt);
ret = _Printf((outfun*) proutSprintf, s, fmt, args);
if (ret >= 0) {
s[ret] = 0;
}
va_end(args);
return ret;
}
// s32 vsprintf(char* dst, const char* fmt, va_list args) {
// s32 ret = _Printf((outfun*) proutSprintf, dst, fmt, args);
//
// if (ret > -1) {
// dst[ret] = 0;
// }
// return ret;
// }
//
// int sprintf(char* s, const char* fmt, ...) {
// s32 ret;
// va_list args;
// va_start(args, fmt);
//
// ret = _Printf((outfun*) proutSprintf, s, fmt, args);
//
// if (ret >= 0) {
// s[ret] = 0;
// }
// va_end(args);
//
// return ret;
// }
+1 -1
View File
@@ -10,7 +10,7 @@
* *
**************************************************************************/
#include "PR/ultratypes.h"
#include <libultra/types.h>
#include "PR/guint.h"
/* ====================================================================
+1 -1
View File
@@ -1,4 +1,4 @@
#include "PR/ultratypes.h"
#include <libultra/types.h>
#include "PR/gbi.h"
#include "PR/gu.h"
+1 -2
View File
@@ -10,8 +10,7 @@
* *
**************************************************************************/
#include "PR/ultratypes.h"
#include "PR/guint.h"
#include <libultraship.h>
void guMtxF2L(float mf[4][4], Mtx* m) {
int i, j;
+1 -2
View File
@@ -1,5 +1,4 @@
#include "PR/ultratypes.h"
#include "PR/gu.h"
#include <libultraship.h>
void guOrthoF(float mf[4][4], float l, float r, float b, float t, float n, float f, float scale) {
int i;
+1 -1
View File
@@ -11,7 +11,7 @@
* *
**************************************************************************/
#include "PR/ultratypes.h"
#include <libultra/types.h>
#include "PR/guint.h"
extern f32 __cosf(f32);
+1 -1
View File
@@ -10,7 +10,7 @@
* *
**************************************************************************/
#include "PR/ultratypes.h"
#include <libultra/types.h>
#include "PR/guint.h"
/* ====================================================================
+2 -2
View File
@@ -1,5 +1,5 @@
#include "PR/ultratypes.h"
#include "libc/math.h"
#include <libultra/types.h>
#include "math.h"
f32 guSqrtf(f32 value) {
return sqrtf(value);
+1 -1
View File
@@ -1,4 +1,4 @@
#include "libc/stdbool.h"
#include "stdbool.h"
#include "PR/rcp.h"
s32 __osAiDeviceBusy(void) {
+1 -1
View File
@@ -1,4 +1,4 @@
#include "PR/rcp.h"
#include <libultraship.h>
extern s32 osViClock;
+1 -1
View File
@@ -1,4 +1,4 @@
#include "libc/stdlib.h"
#include "stdlib.h"
lldiv_t lldiv(long long numer, long long denom) {
lldiv_t val;
+1 -1
View File
@@ -1,4 +1,4 @@
#include "PR/ultratypes.h"
#include <libultra/types.h>
void* memcpy(void* s1, const void* s2, size_t n) {
unsigned char* su1 = (unsigned char*) s1;
+2 -2
View File
@@ -1,5 +1,5 @@
#include "libc/stdlib.h"
#include "libc/string.h"
#include "stdlib.h"
#include "string.h"
#include "PR/xstdio.h"
// TODO: these come from headers
+2 -2
View File
@@ -1,6 +1,6 @@
#include "PR/xstdio.h"
#include "libc/string.h"
#include "libc/stdlib.h"
#include "string.h"
#include "stdlib.h"
#define BUFF_LEN 0x18
+2 -2
View File
@@ -1,6 +1,6 @@
#include "macros.h"
#include "libc/string.h"
#include "libc/stdarg.h"
#include "string.h"
#include "stdarg.h"
#include "PR/xstdio.h"
// TODO: these come from headers
+1 -1
View File
@@ -2216,7 +2216,7 @@ void Bolse_80192264(void) {
gDPLoadTileTexture(gMasterDisp++, D_BO_600AD80, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32);
}
Matrix_SetGfxMtx(&gMasterDisp);
gSPDisplayList(gMasterDisp++, D_BO_600BEC0)
gSPDisplayList(gMasterDisp++, D_BO_600BEC0);
}
Matrix_Pop(&gGfxMatrix);
}
+1 -1
View File
@@ -219,7 +219,7 @@ void Title_8018DF0C(f32 arg0);
void Title_8018E058(void);
void Title_8018E200(void);
bool Title_8018EDC8(s32, Gfx **, Vec3f *, Vec3f *, void *);
void Title_8018E67C(s32);
void Title_8018E67C(s32);
void Title_8018F438(void);
void Title_80190144(void);
void Title_801903B8(void);
+119
View File
@@ -0,0 +1,119 @@
#include "Engine.h"
#include "ui/ImguiUI.h"
#include "ZAPDUtils/Utils/StringHelper.h"
#include "libultraship/src/Context.h"
#include <Fast3D/gfx_pc.h>
#include <Fast3D/gfx_rendering_api.h>
#include <SDL2/SDL_net.h>
#include <utility>
extern "C" {
float gInterpolationStep = 0.0f;
}
GameEngine* GameEngine::Instance;
GameEngine::GameEngine() {
std::vector<std::string> OTRFiles;
if (const std::string cube_path = LUS::Context::GetPathRelativeToAppDirectory("smcube.otr"); std::filesystem::exists(cube_path)) {
OTRFiles.push_back(cube_path);
}
if (const std::string sm64_otr_path = LUS::Context::GetPathRelativeToAppBundle("lylat.otr"); std::filesystem::exists(sm64_otr_path)) {
OTRFiles.push_back(sm64_otr_path);
}
if (const std::string patches_path = LUS::Context::GetPathRelativeToAppDirectory("mods"); !patches_path.empty() && std::filesystem::exists(patches_path)) {
if (std::filesystem::is_directory(patches_path)) {
for (const auto&p: std::filesystem::recursive_directory_iterator(patches_path)) {
if (StringHelper::IEquals(p.path().extension().string(), ".otr")) {
OTRFiles.push_back(p.path().generic_string());
}
}
}
}
this->context = LUS::Context::CreateInstance("Lylat64", "sf64", "lylat.cfg.json", OTRFiles,
{0xFF2B5A63, 0xE3DAA4E}, 3);
// this->context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(
// LUS::ResourceType::SAnim, "Animation", std::make_shared<CubeOS::AnimationFactory>());
}
void GameEngine::Create(){
const auto instance = Instance = new GameEngine();
GameUI::SetupGuiElements();
}
void GameEngine::Destroy(){
}
bool ShouldClearTextureCacheAtEndOfFrame = false;
void GameEngine::StartFrame() const{
using LUS::KbScancode;
const int32_t dwScancode = this->context->GetWindow()->GetLastScancode();
this->context->GetWindow()->SetLastScancode(-1);
switch (dwScancode) {
case KbScancode::LUS_KB_TAB: {
// Toggle HD Assets
CVarSetInteger("gAltAssets", !CVarGetInteger("gAltAssets", 0));
ShouldClearTextureCacheAtEndOfFrame = true;
break;
}
default: break;
}
this->context->GetWindow()->StartFrame();
}
void GameEngine::ProcessFrame(void (*run_one_game_iter)()) const {
this->context->GetWindow()->MainLoop(run_one_game_iter);
}
void GameEngine::RunCommands(Gfx* Commands) {
gfx_run(Commands, {});
gfx_end_frame();
if (ShouldClearTextureCacheAtEndOfFrame) {
gfx_texture_cache_clear();
ShouldClearTextureCacheAtEndOfFrame = false;
}
}
void GameEngine::ProcessGfxCommands(Gfx* commands) {
RunCommands(commands);
Instance->context->GetWindow()->SetTargetFps(30);
Instance->context->GetWindow()->SetMaximumFrameLatency(1);
}
extern "C" uint32_t GameEngine_GetSampleRate() {
auto player = LUS::Context::GetInstance()->GetAudio()->GetAudioPlayer();
if (player == nullptr) {
return 0;
}
if (!player->IsInitialized()) {
return 0;
}
return player->GetSampleRate();
}
extern "C" uint32_t GameEngine_GetSamplesPerFrame(){
return SAMPLES_PER_FRAME;
}
// End
extern "C" float GameEngine_GetAspectRatio() {
return gfx_current_dimensions.aspect_ratio;
}
extern "C" uint32_t GameEngine_GetGameVersion() {
return 0x00000001;
}
extern "C" int GameEngine_OTRSigCheck(const char* data) {
static const char* sOtrSignature = "__OTR__";
return strncmp(data, sOtrSignature, strlen(sOtrSignature)) == 0;
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "libultraship/src/Context.h"
#ifdef __cplusplus
#include <vector>
#include <Fast3D/gfx_pc.h>
#define SAMPLES_HIGH 544
#define SAMPLES_LOW 528
#define AUDIO_FRAMES_PER_UPDATE 2
#define NUM_AUDIO_CHANNELS 2
#define SAMPLES_PER_FRAME (SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 2)
class GameEngine {
public:
static GameEngine* Instance;
std::shared_ptr<LUS::Context> context;
GameEngine();
static void Create();
void StartFrame() const;
static void RunCommands(Gfx* Commands);
void ProcessFrame(void (*run_one_game_iter)()) const;
static void Destroy();
void ProcessGfxCommands(Gfx* commands);
};
#else
void GameEngine_ProcessGfxCommands(Gfx* commands);
float GameEngine_GetAspectRatio();
int GameEngine_OTRSigCheck(char* imgData);
#endif
+45
View File
@@ -0,0 +1,45 @@
#include <libultraship.h>
#include "Engine.h"
#include "DisplayList.h"
#include "Array.h"
extern "C" int GameEngine_OTRSigCheck(const char* data);
extern "C" void gSPDisplayList(Gfx* pkt, Gfx* dl) {
char* imgData = (char*)dl;
if (GameEngine_OTRSigCheck(imgData) == 1) {
auto resource = LUS::Context::GetInstance()->GetResourceManager()->LoadResource(imgData);
auto res = std::static_pointer_cast<LUS::DisplayList>(resource);
dl = &res->Instructions[0];
}
__gSPDisplayList(pkt, dl);
}
extern "C" void gSPVertex(Gfx* pkt, uintptr_t v, int n, int v0) {
if (GameEngine_OTRSigCheck((char*)v) == 1) {
v = (uintptr_t) ResourceGetDataByName((char *) v);
}
__gSPVertex(pkt, v, n, v0);
}
extern "C" void gSPInvalidateTexCache(Gfx* pkt, uintptr_t texAddr) {
char* imgData = (char*)texAddr;
if (texAddr != 0 && GameEngine_OTRSigCheck(imgData)) {
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResource(imgData);
if (res->GetInitData()->Type == LUS::ResourceType::DisplayList)
texAddr = (uintptr_t)&((std::static_pointer_cast<LUS::DisplayList>(res))->Instructions[0]);
else if (res->GetInitData()->Type == LUS::ResourceType::Array)
texAddr = (uintptr_t)(std::static_pointer_cast<LUS::Array>(res))->Vertices.data();
else {
texAddr = (uintptr_t) res->GetRawPointer();
}
}
__gSPInvalidateTexCache(pkt, texAddr);
}
+31
View File
@@ -0,0 +1,31 @@
#include <libultraship.h>
#include <Fast3D/gfx_pc.h>
#include "Engine.h"
extern "C"
// void exec_display_list(SPTask *spTask) {
// GameEngine::ProcessGfxCommands((Gfx *) spTask->task.t.data_ptr);
// }
void push_frame() {
// GameEngine::StartAudioFrame();
GameEngine::Instance->StartFrame();
// thread5_iteration();
// GameEngine::EndAudioFrame();
}
#ifdef _WIN32
int SDL_main(int argc, char **argv) {
#else
int main(){
#endif
GameEngine::Create();
// alloc_pool();
// audio_init();
// sound_init();
// thread5_game_loop();
GameEngine::Instance->ProcessFrame(push_frame);
GameEngine::Instance->Destroy();
return 0;
}
+6
View File
@@ -0,0 +1,6 @@
#include <libultraship.h>
#include <Fast3D/gfx_pc.h>
extern "C" {
}
+508
View File
@@ -0,0 +1,508 @@
#include "ImguiUI.h"
#include "UIWidgets.h"
#include "ResolutionEditor.h"
#include <spdlog/spdlog.h>
#include <ImGui/imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS
#include "libultraship/src/Context.h"
#include <ImGui/imgui_internal.h>
#include <libultraship/libultraship.h>
#include <Fast3D/gfx_pc.h>
#include "port/Engine.h"
namespace GameUI {
std::shared_ptr<GameMenuBar> mGameMenuBar;
std::shared_ptr<LUS::GuiWindow> mConsoleWindow;
std::shared_ptr<LUS::GuiWindow> mStatsWindow;
std::shared_ptr<LUS::GuiWindow> mInputEditorWindow;
std::shared_ptr<LUS::GuiWindow> mGfxDebuggerWindow;
std::shared_ptr<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow> mAdvancedResolutionSettingsWindow;
void SetupGuiElements() {
auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
auto& style = ImGui::GetStyle();
style.FramePadding = ImVec2(4.0f, 6.0f);
style.ItemSpacing = ImVec2(8.0f, 6.0f);
style.Colors[ImGuiCol_MenuBarBg] = UIWidgets::Colors::DarkGray;
mGameMenuBar = std::make_shared<GameMenuBar>("gOpenMenuBar", CVarGetInteger("gOpenMenuBar", 0));
gui->SetMenuBar(mGameMenuBar);
mStatsWindow = gui->GetGuiWindow("Stats");
if (mStatsWindow == nullptr) {
SPDLOG_ERROR("Could not find stats window");
}
mConsoleWindow = gui->GetGuiWindow("Console");
if (mConsoleWindow == nullptr) {
SPDLOG_ERROR("Could not find console window");
}
mInputEditorWindow = gui->GetGuiWindow("Input Editor");
if (mInputEditorWindow == nullptr) {
SPDLOG_ERROR("Could not find input editor window");
return;
}
mGfxDebuggerWindow = gui->GetGuiWindow("GfxDebuggerWindow");
if (mGfxDebuggerWindow == nullptr) {
SPDLOG_ERROR("Could not find input GfxDebuggerWindow");
}
mAdvancedResolutionSettingsWindow = std::make_shared<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow>("gAdvancedResolutionEditorEnabled", "Advanced Resolution Settings");
gui->AddGuiWindow(mAdvancedResolutionSettingsWindow);
}
void Destroy() {
mAdvancedResolutionSettingsWindow = nullptr;
mConsoleWindow = nullptr;
mStatsWindow = nullptr;
mInputEditorWindow = nullptr;
}
std::string GetWindowButtonText(const char* text, bool menuOpen) {
char buttonText[100] = "";
if (menuOpen) {
strcat(buttonText, ICON_FA_CHEVRON_RIGHT " ");
}
strcat(buttonText, text);
if (!menuOpen) { strcat(buttonText, " "); }
return buttonText;
}
}
static const char* filters[3] = {
#ifdef __WIIU__
"",
#else
"Three-Point",
#endif
"Linear", "None"
};
void DrawSettingsMenu(){
if(UIWidgets::BeginMenu("Settings")){
// if (UIWidgets::BeginMenu("Audio")) {
// UIWidgets::CVarSliderFloat("Master Volume", "gGameMasterVolume", 0.0f, 1.0f, 1.0f, {
// .format = "%.0f%%",
// .isPercentage = true,
// });
// if (UIWidgets::CVarSliderFloat("Main Music Volume", "gMainMusicVolume", 0.0f, 1.0f, 1.0f, {
// .format = "%.0f%%",
// .isPercentage = true,
// })) {
// audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f));
// }
// if (UIWidgets::CVarSliderFloat("Sound Effects Volume", "gSFXMusicVolume", 0.0f, 1.0f, 1.0f, {
// .format = "%.0f%%",
// .isPercentage = true,
// })) {
// audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
// }
// if (UIWidgets::CVarSliderFloat("Environment Volume", "gEnvironmentVolume", 0.0f, 1.0f, 1.0f, {
// .format = "%.0f%%",
// .isPercentage = true,
// })) {
// audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f));
// }
//
// static std::unordered_map<LUS::AudioBackend, const char*> audioBackendNames = {
// { LUS::AudioBackend::WASAPI, "Windows Audio Session API" },
// { LUS::AudioBackend::PULSE, "PulseAudio" },
// { LUS::AudioBackend::SDL, "SDL" },
// };
//
// ImGui::Text("Audio API (Needs reload)");
// auto currentAudioBackend = LUS::Context::GetInstance()->GetAudio()->GetAudioBackend();
//
// if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
// UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
// }
// if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) {
// for (uint8_t i = 0; i < LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) {
// auto backend = LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i];
// if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) {
// LUS::Context::GetInstance()->GetAudio()->SetAudioBackend(backend);
// }
// }
// ImGui::EndCombo();
// }
// if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
// UIWidgets::ReEnableComponent("");
// }
//
// ImGui::EndMenu();
// }
UIWidgets::Spacer(0);
if (UIWidgets::BeginMenu("Controller")) {
UIWidgets::WindowButton("Controller Mapping", "gInputEditorWindow", GameUI::mInputEditorWindow);
UIWidgets::Spacer(0);
#ifndef __SWITCH__
UIWidgets::CVarCheckbox("Menubar Controller Navigation", "gControlNav", {
.tooltip = "Allows controller navigation of the SOH menu bar (Settings, Enhancements,...)\nCAUTION: This will disable game inputs while the menubar is visible.\n\nD-pad to move between items, A to select, and X to grab focus on the menu bar"
});
#endif
UIWidgets::CVarCheckbox("Show Inputs", "gInputEnabled", {
.tooltip = "Shows currently pressed inputs on the bottom right of the screen"
});
if (CVarGetInteger("gInputEnabled", 0)) {
UIWidgets::CVarSliderFloat("Input Scale", "gInputScale", 1.0f, 3.0f, 1.0f, {
.tooltip = "Sets the on screen size of the displayed inputs from the Show Inputs setting",
.format = "%.1fx",
});
}
ImGui::EndMenu();
}
ImGui::EndMenu();
}
ImGui::SetCursorPosY(0.0f);
if (UIWidgets::BeginMenu("Graphics")) {
UIWidgets::WindowButton("Resolution Editor", "gAdvancedResolutionEditorEnabled", GameUI::mAdvancedResolutionSettingsWindow);
UIWidgets::Spacer(0);
// Previously was running every frame, and nothing was setting it? Maybe a bad copy/paste?
// LUS::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1));
// UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing");
#ifndef __WIIU__
if (UIWidgets::CVarSliderInt("MSAA: %d", "gMSAAValue", 1, 8, 1, {
.tooltip = "Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel"
})) {
LUS::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger("gMSAAValue", 1));
}
#endif
{ // FPS Slider
const int minFps = 30;
static int maxFps;
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
maxFps = 360;
} else {
maxFps = LUS::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
}
int currentFps = 0;
#ifdef __WIIU__
UIWidgets::Spacer(0);
// only support divisors of 60 on the Wii U
if (currentFps > 60) {
currentFps = 60;
} else {
currentFps = 60 / (60 / currentFps);
}
int fpsSlider = 1;
if (currentFps == 30) {
ImGui::Text("FPS: Original (30)");
} else {
ImGui::Text("FPS: %d", currentFps);
if (currentFps == 30) {
fpsSlider = 2;
} else { // currentFps == 60
fpsSlider = 3;
}
}
if (CVarGetInteger("gMatchRefreshRate", 0)) {
UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
}
if (ImGui::Button(" - ##WiiUFPS")) {
fpsSlider--;
}
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
UIWidgets::Spacer(0);
ImGui::PushItemWidth(std::min((ImGui::GetContentRegionAvail().x - 60.0f), 260.0f));
ImGui::SliderInt("##WiiUFPSSlider", &fpsSlider, 1, 3, "", ImGuiSliderFlags_AlwaysClamp);
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
if (ImGui::Button(" + ##WiiUFPS")) {
fpsSlider++;
}
if (CVarGetInteger("gMatchRefreshRate", 0)) {
UIWidgets::ReEnableComponent("");
}
if (fpsSlider > 3) {
fpsSlider = 3;
} else if (fpsSlider < 1) {
fpsSlider = 1;
}
if (fpsSlider == 1) {
currentFps = 20;
} else if (fpsSlider == 2) {
currentFps = 30;
} else if (fpsSlider == 3) {
currentFps = 60;
}
CVarSetInteger("gInterpolationFPS", currentFps);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
#else
bool matchingRefreshRate =
CVarGetInteger("gMatchRefreshRate", 0) && LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() != LUS::WindowBackend::DX11;
UIWidgets::CVarSliderInt((currentFps == 20) ? "FPS: Original (20)" : "FPS: %d", "gInterpolationFPS", minFps, maxFps, 1, {
.disabled = matchingRefreshRate
});
#endif
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
UIWidgets::Tooltip(
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is purely "
"visual and does not impact game logic, execution of glitches etc.\n\n"
"A higher target FPS than your monitor's refresh rate will waste resources, and might give a worse result."
);
} else {
UIWidgets::Tooltip(
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is purely "
"visual and does not impact game logic, execution of glitches etc."
);
}
} // END FPS Slider
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
UIWidgets::Spacer(0);
if (ImGui::Button("Match Refresh Rate")) {
int hz = LUS::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
if (hz >= 30 && hz <= 360) {
CVarSetInteger("gInterpolationFPS", hz);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
}
} else {
UIWidgets::PaddedEnhancementCheckbox("Match Refresh Rate", "gMatchRefreshRate", true, false);
}
UIWidgets::Tooltip("Matches interpolation value to the current game's window refresh rate");
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
UIWidgets::PaddedEnhancementSliderInt(CVarGetInteger("gExtraLatencyThreshold", 80) == 0 ? "Jitter fix: Off" : "Jitter fix: >= %d FPS",
"##ExtraLatencyThreshold", "gExtraLatencyThreshold", 0, 360, "", 80, true, true, false);
UIWidgets::Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag (e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to work on one frame while GPU works on the previous frame.\nThis setting should be used when your computer is too slow to do CPU + GPU work in time.");
}
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
static std::unordered_map<LUS::WindowBackend, const char*> windowBackendNames = {
{ LUS::WindowBackend::DX11, "DirectX" },
{ LUS::WindowBackend::SDL_OPENGL, "OpenGL"},
{ LUS::WindowBackend::SDL_METAL, "Metal" },
{ LUS::WindowBackend::GX2, "GX2"}
};
ImGui::Text("Renderer API (Needs reload)");
LUS::WindowBackend runningWindowBackend = LUS::Context::GetInstance()->GetWindow()->GetWindowBackend();
LUS::WindowBackend configWindowBackend;
int configWindowBackendId = LUS::Context::GetInstance()->GetConfig()->GetInt("Window.Backend.Id", -1);
if (configWindowBackendId != -1 && configWindowBackendId < static_cast<int>(LUS::WindowBackend::BACKEND_COUNT)) {
configWindowBackend = static_cast<LUS::WindowBackend>(configWindowBackendId);
} else {
configWindowBackend = runningWindowBackend;
}
if (LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) {
UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
}
if (ImGui::BeginCombo("##RApi", windowBackendNames[configWindowBackend])) {
for (size_t i = 0; i < LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size(); i++) {
auto backend = LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->data()[i];
if (ImGui::Selectable(windowBackendNames[backend], backend == configWindowBackend)) {
LUS::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", static_cast<int>(backend));
LUS::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name",
windowBackendNames[backend]);
LUS::Context::GetInstance()->GetConfig()->Save();
}
}
ImGui::EndCombo();
}
if (LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) {
UIWidgets::ReEnableComponent("");
}
if (LUS::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) {
UIWidgets::PaddedEnhancementCheckbox("Enable Vsync", "gVsyncEnabled", true, false);
}
if (LUS::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen()) {
UIWidgets::PaddedEnhancementCheckbox("Windowed fullscreen", "gSdlWindowedFullscreen", true, false);
}
if (LUS::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports()) {
UIWidgets::PaddedEnhancementCheckbox("Allow multi-windows", "gEnableMultiViewports", true, false, false, "", UIWidgets::CheckboxGraphics::Cross, true);
UIWidgets::Tooltip("Allows windows to be able to be dragged off of the main game window. Requires a reload to take effect.");
}
// If more filters are added to LUS, make sure to add them to the filters list here
ImGui::Text("Texture Filter (Needs reload)");
UIWidgets::EnhancementCombobox("gTextureFilter", filters, 0);
UIWidgets::Spacer(0);
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings();
ImGui::EndMenu();
}
}
void DrawMenuBarIcon() {
static bool gameIconLoaded = false;
if (!gameIconLoaded) {
// LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTexture("Game_Icon", "textures/icons/gIcon.png");
gameIconLoaded = false;
}
if (LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Game_Icon")) {
#ifdef __SWITCH__
ImVec2 iconSize = ImVec2(20.0f, 20.0f);
float posScale = 1.0f;
#elif defined(__WIIU__)
ImVec2 iconSize = ImVec2(16.0f * 2, 16.0f * 2);
float posScale = 2.0f;
#else
ImVec2 iconSize = ImVec2(20.0f, 20.0f);
float posScale = 1.5f;
#endif
ImGui::SetCursorPos(ImVec2(5, 2.5f) * posScale);
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Game_Icon"), iconSize);
ImGui::SameLine();
ImGui::SetCursorPos(ImVec2(25, 0) * posScale);
}
}
void DrawGameMenu() {
if (UIWidgets::BeginMenu("Ghostship")) {
if (UIWidgets::MenuItem("Reset",
#ifdef __APPLE__
"Command-R"
#else
"Ctrl+R"
#endif
)) {
std::reinterpret_pointer_cast<LUS::ConsoleWindow>(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch("reset");
}
#if !defined(__SWITCH__) && !defined(__WIIU__)
if (UIWidgets::MenuItem("Toggle Fullscreen", "F9")) {
LUS::Context::GetInstance()->GetWindow()->ToggleFullscreen();
}
if (UIWidgets::MenuItem("Quit")) {
LUS::Context::GetInstance()->GetWindow()->Close();
}
#endif
ImGui::EndMenu();
}
}
void DrawEnhancementsMenu() {
if (UIWidgets::BeginMenu("Enhancements")) {
if (UIWidgets::BeginMenu("Gameplay")) {
UIWidgets::CVarCheckbox("No Level of Detail (LOD)", "gDisableLOD", {
.tooltip = "Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance"
});
UIWidgets::CVarCheckbox("Select any star from menu", "gSelectAllStars", {
.tooltip = "Let's you select any star from the menu regardless of the courses completion status."
});
UIWidgets::CVarCheckbox("Collecting Stars Will Not Exit Level", "gStarNoExit", {
.tooltip = "Stars act like the 100 coin star and will not take you out of the level"
});
UIWidgets::CVarCheckbox("Avoid playing peach cutscene", "gDisablePeachCutscene", {
.tooltip = "Avoid playing the peach cutscene when starting a new game"
});
ImGui::EndMenu();
}
ImGui::EndMenu();
}
}
void DrawCheatsMenu() {
if (UIWidgets::BeginMenu("Cheats")) {
UIWidgets::CVarCheckbox("Infinite Health", "gInfiniteHealth");
UIWidgets::CVarCheckbox("Infinite Lives", "gInfiniteLives");
ImGui::EndMenu();
}
}
const char* debugInfoPages[6] = {
"Object",
"Check Surface",
"Map",
"Stage",
"Effect",
"Enemy",
};
void DrawDebugMenu() {
if (UIWidgets::BeginMenu("Developer")) {
UIWidgets::WindowButton("Gfx Debugger", "gGfxDebuggerEnabled", GameUI::mGfxDebuggerWindow, {
.tooltip = "Enables the Gfx Debugger window, allowing you to input commands, type help for some examples"
});
UIWidgets::CVarCheckbox("Debug mode", "gEnableDebugMode", {
.tooltip = "Various debug features, including a level selector from the main menu"
});
UIWidgets::CVarCheckbox("Better Level Select", "gDeveloper.BetterLevelSelect", {
.tooltip = "Tweaks to the level select screen, like naming and allowing C-buttons to be used"
});
UIWidgets::CVarCheckbox("Draw DebugInfo", "gDeveloper.DrawDebugInfo");
if (CVarGetInteger("gDeveloper.DrawDebugInfo", 0)) {
UIWidgets::CVarCombobox("DebugInfo mode", "gDeveloper.DebugInfoPage", debugInfoPages, {
.defaultIndex = 0,
});
}
UIWidgets::Spacer(0);
UIWidgets::WindowButton("Stats", "gStatsEnabled", GameUI::mStatsWindow, {
.tooltip = "Shows the stats window, with your FPS and frametimes, and the OS you're playing on"
});
UIWidgets::WindowButton("Console", "gConsoleEnabled", GameUI::mConsoleWindow, {
.tooltip = "Enables the console window, allowing you to input commands, type help for some examples"
});
ImGui::EndMenu();
}
}
void GameMenuBar::DrawElement() {
if(ImGui::BeginMenuBar()){
DrawMenuBarIcon();
DrawGameMenu();
ImGui::SetCursorPosY(0.0f);
DrawSettingsMenu();
ImGui::SetCursorPosY(0.0f);
DrawEnhancementsMenu();
ImGui::SetCursorPosY(0.0f);
DrawCheatsMenu();
ImGui::SetCursorPosY(0.0f);
DrawDebugMenu();
ImGui::EndMenuBar();
}
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <libultraship/libultraship.h>
namespace GameUI {
void SetupGuiElements();
void Destroy();
}
class GameMenuBar : public LUS::GuiMenuBar {
public:
using LUS::GuiMenuBar::GuiMenuBar;
protected:
void DrawElement() override;
void InitElement() override {};
void UpdateElement() override {};
};
+422
View File
@@ -0,0 +1,422 @@
#include "ResolutionEditor.h"
#include "UIWidgets.h"
#include "libultraship/src/Context.h"
#include <ImGui/imgui.h>
#include <libultraship/libultraship.h>
#include <graphic/Fast3D/gfx_pc.h>
/* Console Variables are grouped under gAdvancedResolution. (e.g. "gAdvancedResolution.Enabled")
The following CVars are used in Libultraship and can be edited here:
- Enabled - Turns Advanced Resolution Mode on.
- AspectRatioX, AspectRatioY - Aspect ratio controls. To toggle off, set either to zero.
- VerticalPixelCount, VerticalResolutionToggle - Resolution controls.
- PixelPerfectMode, IntegerScale.Factor - Pixel Perfect Mode a.k.a. integer scaling controls.
(Waiting on a second PR merge on LUS for this to fully function.):
- IntegerScale.FitAutomatically - Automatic resizing for Pixel Perfect Mode.
- IntegerScale.NeverExceedBounds - Prevents manual resizing from exceeding screen bounds.
The following CVars are also implemented in LUS for niche use cases:
- IgnoreAspectCorrection - Stretch framebuffer to fill screen.
This is something of a power-user setting for niche setups that most people won't need or care about,
but may be useful if playing the Switch/Wii U ports on a 4:3 television.
- IntegerScale.ExceedBoundsBy - Offset the max screen bounds, usually by +1.
This isn't that useful at the moment.
*/
namespace AdvancedResolutionSettings {
enum setting { UPDATE_aspectRatioX, UPDATE_aspectRatioY, UPDATE_verticalPixelCount };
const char* aspectRatioPresetLabels[] = {
"Off", "Custom", "Original (4:3)", "Widescreen (16:9)", "Nintendo 3DS (5:3)", "16:10 (8:5)", "Ultrawide (21:9)"
};
const float aspectRatioPresetsX[] = { 0.0f, 12.0f, 4.0f, 16.0f, 5.0f, 16.0f, 21.0f };
const float aspectRatioPresetsY[] = { 0.0f, 9.0f, 3.0f, 9.0f, 3.0f, 10.0f, 9.0f };
const int default_aspectRatio = 1; // Default combo list option
const char* pixelCountPresetLabels[] = { "Custom", "Native N64 (240p)", "2x (480p)", "3x (720p)", "4x (960p)",
"5x (1200p)", "6x (1440p)", "Full HD (1080p)", "4K (2160p)" };
const int pixelCountPresets[] = { 480, 240, 480, 720, 960, 1200, 1440, 1080, 2160, 480 };
const int default_pixelCount = 0; // Default combo list option
const uint32_t minVerticalPixelCount = 240; // see: LUS::AdvancedResolution()
const uint32_t maxVerticalPixelCount = 4320;
const unsigned short default_maxIntegerScaleFactor = 6; // Default size of Integer scale factor slider.
const float enhancementSpacerHeight = 19.0f;
// This will need to be determined more intelligently when Hi-DPI UI support is added.
void AdvancedResolutionSettingsWindow::InitElement() {
}
void AdvancedResolutionSettingsWindow::DrawElement() {
ImGui::SetNextWindowSize(ImVec2(497, 532), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Advanced Resolution Settings", &mIsVisible)) {
// Initialise update flags.
bool update[sizeof(setting)];
for (unsigned short i = 0; i < sizeof(setting); i++)
update[i] = false;
static short updateCountdown = 0;
short countdownStartingValue = CVarGetInteger("gInterpolationFPS", 20) / 2; // half of a second, in frames.
// Initialise integer scale bounds.
short max_integerScaleFactor = default_maxIntegerScaleFactor; // default value, which may or may not get
// overridden depending on viewport res
short integerScale_maximumBounds = 1; // can change when window is resized
// This is mostly just for UX purposes, as Fit Automatically logic is part of LUS.
if (((float)gfx_current_game_window_viewport.width / gfx_current_game_window_viewport.height) >
((float)gfx_current_dimensions.width / gfx_current_dimensions.height)) {
// Scale to window height
integerScale_maximumBounds = gfx_current_game_window_viewport.height / gfx_current_dimensions.height;
} else {
// Scale to window width
integerScale_maximumBounds = gfx_current_game_window_viewport.width / gfx_current_dimensions.width;
}
// Lower-clamping maximum bounds value to 1 is no-longer necessary as that's accounted for in LUS.
// Letting it go below 1 in this Editor will even allow for checking if screen bounds are being exceeded.
if (default_maxIntegerScaleFactor < integerScale_maximumBounds) {
max_integerScaleFactor =
integerScale_maximumBounds + CVarGetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0);
}
// Stored Values for non-UIWidgets elements
static float aspectRatioX = CVarGetFloat("gAdvancedResolution.AspectRatioX", 16.0f);
static float aspectRatioY = CVarGetFloat("gAdvancedResolution.AspectRatioY", 9.0f);
static int verticalPixelCount = CVarGetInteger("gAdvancedResolution.VerticalPixelCount", 480);
// Combo List defaults
static int item_aspectRatio = default_aspectRatio;
static int item_pixelCount = default_pixelCount;
// Additional settings
static bool showHorizontalResField = false;
static int horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
#ifdef __APPLE__
ImGui::Text("Note: these settings may behave incorrectly on Apple Retina Displays.");
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
#endif
// The original resolution slider (for convenience)
if (UIWidgets::EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f,
"", 1.0f, true, true,
(CVarGetInteger("gAdvancedResolution.VerticalResolutionToggle", 0) &&
CVarGetInteger("gAdvancedResolution.Enabled", 0)) ||
CVarGetInteger("gLowResMode", 0))) {
LUS::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1));
}
UIWidgets::Tooltip("Multiplies your output resolution by the value entered, as a more intensive but effective "
"form of anti-aliasing"); // Description pulled from SohMenuBar.cpp
// N64 Mode toggle (again for convenience)
// UIWidgets::PaddedEnhancementCheckbox("(Enhancements>Graphics) N64 Mode", "gLowResMode", false, false, false,
// "", UIWidgets::CheckboxGraphics::Cross, false);
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
// Activator
UIWidgets::PaddedEnhancementCheckbox("Enable advanced settings.", "gAdvancedResolution.Enabled", false, false,
false, "", UIWidgets::CheckboxGraphics::Cross, false);
// Error/Warning display
if (!CVarGetInteger("gLowResMode", 0)) {
if (IsDroppingFrames()) { // Significant frame drop warning
ImGui::TextColored({ 0.85f, 0.85f, 0.0f, 1.0f },
ICON_FA_EXCLAMATION_TRIANGLE " Significant frame rate (FPS) drops may be occuring.");
UIWidgets::Spacer(2);
} else { // No warnings
UIWidgets::Spacer(enhancementSpacerHeight);
}
} else { // N64 Mode warning
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f },
ICON_FA_QUESTION_CIRCLE " \"N64 Mode\" is overriding these settings.");
ImGui::SameLine();
if (ImGui::Button("Click to disable")) {
CVarSetInteger("gLowResMode", (int)false);
CVarSave();
}
}
// Resolution visualiser
ImGui::Text("Viewport dimensions: %d x %d", gfx_current_game_window_viewport.width,
gfx_current_game_window_viewport.height);
ImGui::Text("Internal resolution: %d x %d", gfx_current_dimensions.width, gfx_current_dimensions.height);
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
// Aspect Ratio
ImGui::Text("Force aspect ratio:");
ImGui::SameLine();
ImGui::TextColored({ 0.75f, 0.75f, 0.75f, 1.0f }, "(Select \"Off\" to disable.)");
if (ImGui::Combo(" ", &item_aspectRatio, aspectRatioPresetLabels,
IM_ARRAYSIZE(aspectRatioPresetLabels)) &&
item_aspectRatio != default_aspectRatio) { // don't change anything if "Custom" is selected.
aspectRatioX = aspectRatioPresetsX[item_aspectRatio];
aspectRatioY = aspectRatioPresetsY[item_aspectRatio];
update[UPDATE_aspectRatioX] = true;
update[UPDATE_aspectRatioY] = true;
if (showHorizontalResField) {
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
}
}
if (item_aspectRatio == default_aspectRatio && !showHorizontalResField) {
// Declaring the Y input interaction in particular as a variable beforehand
// will prevent a bug where the Y field would disappear when modifying X.
bool inputX = ImGui::InputFloat("X", &aspectRatioX, 0.1f, 1.0f, "%.3f");
bool inputY = ImGui::InputFloat("Y", &aspectRatioY, 0.1f, 1.0f, "%.3f");
if (inputX || inputY) {
item_aspectRatio = default_aspectRatio;
update[UPDATE_aspectRatioX] = true;
update[UPDATE_aspectRatioY] = true;
}
} else if (showHorizontalResField) { // Show calculated aspect ratio
if (item_aspectRatio) {
UIWidgets::Spacer(2);
float resolvedAspectRatio = (float)gfx_current_dimensions.height / gfx_current_dimensions.width;
ImGui::Text("Aspect ratio: %.4f", resolvedAspectRatio);
} else {
UIWidgets::Spacer(enhancementSpacerHeight);
}
}
UIWidgets::Spacer(0);
// Vertical Resolution
UIWidgets::PaddedEnhancementCheckbox("Set fixed vertical resolution (disables Resolution slider)",
"gAdvancedResolution.VerticalResolutionToggle", true, false, false, "",
UIWidgets::CheckboxGraphics::Cross, false);
UIWidgets::Tooltip(
"Override the resolution scale slider and use the settings below, irrespective of window size.");
if (ImGui::Combo("Pixel Count Presets", &item_pixelCount, pixelCountPresetLabels,
IM_ARRAYSIZE(pixelCountPresetLabels)) &&
item_pixelCount != default_pixelCount) { // don't change anything if "Custom" is selected.
verticalPixelCount = pixelCountPresets[item_pixelCount];
update[UPDATE_verticalPixelCount] = true;
if (showHorizontalResField) {
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
}
}
// Horizontal Resolution, if visibility is enabled for it.
if (showHorizontalResField) {
// Only show the field if Aspect Ratio is being enforced.
if ((aspectRatioX > 0.0f) && (aspectRatioY > 0.0f)) {
// So basically we're "faking" this one by setting aspectRatioX instead.
if (ImGui::InputInt("Horiz. Pixel Count", &horizontalPixelCount, 8, 320)) {
item_aspectRatio = default_aspectRatio;
if (horizontalPixelCount < (minVerticalPixelCount / 3.0f) * 4.0f) {
horizontalPixelCount = (minVerticalPixelCount / 3.0f) * 4.0f;
}
aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
update[UPDATE_aspectRatioX] = true;
}
} else { // Display a notice instead.
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f },
ICON_FA_QUESTION_CIRCLE " \"Force aspect ratio\" required.");
// ImGui::Text(" ");
ImGui::SameLine();
if (ImGui::Button("Click to resolve")) {
item_aspectRatio = default_aspectRatio; // Set it to Custom
aspectRatioX = aspectRatioPresetsX[2]; // but use the 4:3 defaults
aspectRatioY = aspectRatioPresetsY[2];
update[UPDATE_aspectRatioX] = true;
update[UPDATE_aspectRatioY] = true;
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
}
}
}
// Vertical Resolution part 2
if (ImGui::InputInt("Vertical Pixel Count", &verticalPixelCount, 8, 240)) {
item_pixelCount = default_pixelCount;
update[UPDATE_verticalPixelCount] = true;
// Account for the natural instinct to enter horizontal first.
// Ignore vertical resolutions that are below the lower clamp constant.
if (showHorizontalResField && !(verticalPixelCount < minVerticalPixelCount)) {
aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
update[UPDATE_aspectRatioX] = true;
}
}
UIWidgets::Spacer(0);
// UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
// Integer scaling settings group
if (ImGui::CollapsingHeader("Integer Scaling Settings")) {
// Pixel-perfect Mode
UIWidgets::PaddedEnhancementCheckbox("Pixel-perfect Mode", "gAdvancedResolution.PixelPerfectMode", true,
true,
!CVarGetInteger("gAdvancedResolution.VerticalResolutionToggle", 0), "",
UIWidgets::CheckboxGraphics::Cross, false);
UIWidgets::Tooltip("Don't scale image to fill window.");
if (!CVarGetInteger("gAdvancedResolution.VerticalResolutionToggle", 0)) {
CVarSetInteger("gAdvancedResolution.PixelPerfectMode", (int)false);
CVarSave();
}
// Integer Scaling
UIWidgets::EnhancementSliderInt("Integer scale factor: %d", "##ARSIntScale",
"gAdvancedResolution.IntegerScale.Factor", 1, max_integerScaleFactor, "%d",
1, true,
!CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0) ||
CVarGetInteger("gAdvancedResolution.IntegerScale.FitAutomatically", 0));
UIWidgets::Tooltip("Integer scales the image. Only available in pixel-perfect mode.");
// Display warning if size is being clamped or if framebuffer is larger than viewport.
if (CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0) &&
(CVarGetInteger("gAdvancedResolution.IntegerScale.NeverExceedBounds", 1) &&
CVarGetInteger("gAdvancedResolution.IntegerScale.Factor", 1) > integerScale_maximumBounds)) {
ImGui::SameLine();
ImGui::TextColored({ 0.85f, 0.85f, 0.0f, 1.0f }, ICON_FA_EXCLAMATION_TRIANGLE " Window exceeded.");
}
UIWidgets::PaddedEnhancementCheckbox("Automatically scale image to fit viewport",
"gAdvancedResolution.IntegerScale.FitAutomatically", true, true,
!CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0), "",
UIWidgets::CheckboxGraphics::Cross, false);
UIWidgets::Tooltip("Automatically sets scale factor to fit window. Only available in pixel-perfect mode.");
if (CVarGetInteger("gAdvancedResolution.IntegerScale.FitAutomatically", 0)) {
// This is just here to update the value shown on the slider.
// The function in LUS to handle this setting will ignore IntegerScaleFactor while active.
CVarSetInteger("gAdvancedResolution.IntegerScale.Factor", integerScale_maximumBounds);
// CVarSave();
}
}
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
// Collapsible panel for additional settings
if (ImGui::CollapsingHeader("Additional Settings")) {
UIWidgets::Spacer(0);
#if defined(__SWITCH__) || defined(__WIIU__)
// Disable aspect correction, stretching the framebuffer to fill the viewport.
// This option is only really needed on systems limited to 16:9 TV resolutions, such as consoles.
// The associated CVar is still functional on PC platforms if you want to use it though.
UIWidgets::PaddedEnhancementCheckbox("Disable aspect correction and stretch the output image.\n"
"(Might be useful for 4:3 televisions!)\n"
"Not available in Pixel Perfect Mode.",
"gAdvancedResolution.IgnoreAspectCorrection", false, true,
CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0), "",
UIWidgets::CheckboxGraphics::Cross, false);
#else
if (CVarGetInteger("gAdvancedResolution.IgnoreAspectCorrection", 0)) {
// This setting is intentionally not exposed on PC platforms,
// but may be accidentally activated for varying reasons.
// Having this button should hopefully prevent support headaches.
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f }, ICON_FA_QUESTION_CIRCLE
" If the image is stretched and you don't know why, click this.");
if (ImGui::Button("Click to reenable aspect correction.")) {
CVarSetInteger("gAdvancedResolution.IgnoreAspectCorrection", (int)false);
CVarSave();
}
UIWidgets::Spacer(2);
}
#endif
if (ImGui::Checkbox("Show a horizontal resolution field.", &showHorizontalResField)) {
if (!showHorizontalResField && (aspectRatioX > 0.0f)) { // when turning this setting off
// Refresh relevant values
aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
} else { // when turning this setting on
item_aspectRatio = default_aspectRatio;
if (aspectRatioX > 0.0f) {
// Refresh relevant values in the opposite order
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
aspectRatioX = aspectRatioY * horizontalPixelCount / verticalPixelCount;
}
}
update[UPDATE_aspectRatioX] = true;
}
UIWidgets::PaddedEnhancementCheckbox(
"Don't allow integer scaling to exceed screen bounds.\n"
"(Makes screen bounds take priority over specified factor.)",
"gAdvancedResolution.IntegerScale.NeverExceedBounds", true, false,
!CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0) ||
CVarGetInteger("gAdvancedResolution.IntegerScale.FitAutomatically", 0),
"", UIWidgets::CheckboxGraphics::Cross, true);
if (!CVarGetInteger("gAdvancedResolution.IntegerScale.NeverExceedBounds", 1) ||
CVarGetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0)) {
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f },
" " ICON_FA_QUESTION_CIRCLE
" A scroll bar may become visible if screen bounds are exceeded.");
// Another helpful button for an unused CVar.
if (CVarGetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0)) {
if (ImGui::Button("Click to reset an unused CVar that may be causing this.")) {
CVarSetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0);
CVarSave();
}
}
} else {
UIWidgets::Spacer(enhancementSpacerHeight);
}
// I've ended up dummying this one out because it doesn't function in a satisfactory way.
// Consider this idea on the table, but I don't deem it an important enough feature to push for.
/*
UIWidgets::PaddedEnhancementCheckbox("Allow integer scale factor to go 1x above maximum screen bounds.",
"gAdvancedResolution.IntegerScale.ExceedBoundsBy", false, false,
!CVarGetInteger("gAdvancedResolution.PixelPerfectMode", 0), "",
UIWidgets::CheckboxGraphics::Cross, false);
if (CVarGetInteger("gAdvancedResolution.IntegerScale.ExceedBoundsBy", 0)) {
ImGui::TextColored({ 0.0f, 0.85f, 0.85f, 1.0f },
" " ICON_FA_QUESTION_CIRCLE
" A scroll bar may become visible if screen bounds are exceeded.");
}*/
} // end of Additional Settings
// Clamp and update the CVars that don't use UIWidgets
if (IsBoolArrayTrue(update)) {
if (update[UPDATE_aspectRatioX]) {
if (aspectRatioX < 0.0f) {
aspectRatioX = 0.0f;
}
CVarSetFloat("gAdvancedResolution.AspectRatioX", aspectRatioX);
}
if (update[UPDATE_aspectRatioY]) {
if (aspectRatioY < 0.0f) {
aspectRatioY = 0.0f;
}
CVarSetFloat("gAdvancedResolution.AspectRatioY", aspectRatioY);
}
if (update[UPDATE_verticalPixelCount]) {
// There's a upper and lower clamp on the Libultraship side too,
// so clamping it here is purely visual, so the vertical resolution field reflects it.
if (verticalPixelCount < minVerticalPixelCount) {
verticalPixelCount = minVerticalPixelCount;
}
if (verticalPixelCount > maxVerticalPixelCount) {
verticalPixelCount = maxVerticalPixelCount;
}
CVarSetInteger("gAdvancedResolution.VerticalPixelCount", verticalPixelCount);
}
// Delay saving this set of CVars by a predetermined length of time, in frames.
updateCountdown = countdownStartingValue;
}
if (updateCountdown > 0) {
updateCountdown--;
} else {
CVarSave();
}
}
ImGui::End();
}
void AdvancedResolutionSettingsWindow::UpdateElement() {
}
bool AdvancedResolutionSettingsWindow::IsDroppingFrames() {
// a rather imprecise way of checking for frame drops.
// but it's mostly there to inform the player of large drops.
const short targetFPS = CVarGetInteger("gInterpolationFPS", 20);
const float threshold = targetFPS / 20.0f + 4.1f;
return ImGui::GetIO().Framerate < targetFPS - threshold;
}
bool AdvancedResolutionSettingsWindow::IsBoolArrayTrue(bool* foo) {
for (unsigned short i = 0; i < sizeof(&foo); i++)
if (&foo[i])
return true;
return false;
}
} // namespace AdvancedResolutionSettings
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <libultraship/libultraship.h>
namespace AdvancedResolutionSettings {
class AdvancedResolutionSettingsWindow : public LUS::GuiWindow {
private:
bool IsDroppingFrames();
protected:
bool IsBoolArrayTrue(bool*);
public:
using LUS::GuiWindow::GuiWindow;
void InitElement() override;
void DrawElement() override;
void UpdateElement() override;
};
} // namespace AdvancedResolutionSettings
File diff suppressed because it is too large Load Diff
+209
View File
@@ -0,0 +1,209 @@
#pragma once
#include <string>
#include <vector>
#include <span>
#include <stdint.h>
#include <ImGui/imgui.h>
#include <libultraship/libultraship.h>
namespace UIWidgets {
struct TextFilters {
static int FilterNumbers(ImGuiInputTextCallbackData* data) {
if (data->EventChar < 256 && strchr("1234567890", (char)data->EventChar)) {
return 0;
}
return 1;
}
static int FilterAlphaNum(ImGuiInputTextCallbackData* data) {
const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789";
if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) {
return 0;
}
return 1;
}
};
// MARK: - Enums
enum class CheckboxGraphics {
Cross,
Checkmark,
None
};
constexpr float maxSliderWidth = 260.0f;
#ifdef __SWITCH__
constexpr float sliderButtonWidth = 42.0f;
#elif defined(__WIIU__)
constexpr float sliderButtonWidth = 60.0f;
#else
constexpr float sliderButtonWidth = 30.0f;
#endif
char* WrappedText(const char* text, unsigned int charactersPerLine = 60);
char* WrappedText(const std::string& text, unsigned int charactersPerLine);
void SetLastItemHoverText(const std::string& text);
void SetLastItemHoverText(const char* text);
void InsertHelpHoverText(const std::string& text);
void InsertHelpHoverText(const char* text);
void Tooltip(const char* text);
void Spacer(float height);
void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, float extraVerticalBottomPadding = 0.0f);
void RenderCross(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz);
bool CustomCheckbox(const char* label, bool* v, bool disabled, CheckboxGraphics disabledGraphic);
void ReEnableComponent(const char* disabledTooltipText);
void DisableComponent(const float alpha);
bool EnhancementCheckbox(const char* text, const char* cvarName, bool disabled = false, const char* disabledTooltipText = "", CheckboxGraphics disabledGraphic = CheckboxGraphics::Cross, bool defaultValue = false);
bool PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "", CheckboxGraphics disabledGraphic = CheckboxGraphics::Cross, bool defaultValue = false);
bool EnhancementCombobox(const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, uint8_t defaultIndex, bool disabled = false, const char* disabledTooltipText = "", uint8_t disabledValue = -1);
bool LabeledRightAlignedEnhancementCombobox(const char* label, const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, uint8_t defaultIndex, bool disabled = false, const char* disabledTooltipText = "", uint8_t disabledValue = -1);
void PaddedText(const char* text, bool padTop = true, bool padBottom = true);
bool EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = true, bool disabled = false, const char* disabledTooltipText = "");
bool PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = true, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "");
bool EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = true, bool disabled = false, const char* disabledTooltipText = "");
bool PaddedEnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = true, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "");
bool EnhancementRadioButton(const char* text, const char* cvarName, int id);
bool DrawResetColorButton(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha);
bool DrawRandomizeColorButton(const char* cvarName, ImVec4* colors);
void DrawLockColorCheckbox(const char* cvarName);
void RainbowColor(const char* cvarName, ImVec4* colors);
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha);
bool EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha = false, bool TitleSameLine = false);
void DrawFlagArray32(const std::string& name, uint32_t& flags);
void DrawFlagArray16(const std::string& name, uint16_t& flags);
void DrawFlagArray8(const std::string& name, uint8_t& flags);
// V2
namespace Colors {
const ImVec4 White = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
const ImVec4 Gray = ImVec4(0.4f, 0.4f, 0.4f, 1.0f);
const ImVec4 DarkGray = ImVec4(0.1f, 0.1f, 0.1f, 1.0f);
const ImVec4 Indigo = ImVec4(0.24f, 0.31f, 0.71f, 1.0f);
const ImVec4 Red = ImVec4(0.5f, 0.0f, 0.0f, 1.0f);
const ImVec4 DarkRed = ImVec4(0.3f, 0.0f, 0.0f, 1.0f);
const ImVec4 LightGreen = ImVec4(0.0f, 0.7f, 0.0f, 1.0f);
const ImVec4 Green = ImVec4(0.0f, 0.5f, 0.0f, 1.0f);
const ImVec4 DarkGreen = ImVec4(0.0f, 0.3f, 0.0f, 1.0f);
const ImVec4 Yellow = ImVec4(1.0f, 0.627f, 0.0f, 1.0f);
};
namespace Sizes {
const ImVec2 Inline = ImVec2(0.0f, 0.0f);
const ImVec2 Fill = ImVec2(-1.0f, 0.0f);
}
enum LabelPosition {
Near,
Far,
Above,
None,
Within,
};
enum ComponentAlignment {
Left,
Right,
};
void PushStyleMenu(const ImVec4& color = Colors::Indigo);
void PopStyleMenu();
bool BeginMenu(const char* label, const ImVec4& color = Colors::Indigo);
void PushStyleMenuItem(const ImVec4& color = Colors::Indigo);
void PopStyleMenuItem();
bool MenuItem(const char* label, const char* shortcut = NULL, const ImVec4& color = Colors::Indigo);
struct ButtonOptions {
const ImVec4 color = Colors::Gray;
const ImVec2 size = Sizes::Fill;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
};
void PushStyleButton(const ImVec4& color = Colors::Gray);
void PopStyleButton();
bool Button(const char* label, const ButtonOptions& options = {});
bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<LUS::GuiWindow> windowPtr, const ButtonOptions& options = {});
struct CheckboxOptions {
const ImVec4 color = Colors::Indigo;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
bool defaultValue = false; // Only applicable to CVarCheckbox
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Near;
};
void PushStyleCheckbox(const ImVec4& color = Colors::Indigo);
void PopStyleCheckbox();
bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {});
bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options = {});
struct ComboboxOptions {
const ImVec4 color = Colors::Indigo;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
uint32_t defaultIndex = 0; // Only applicable to CVarCombobox
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
ImGuiComboFlags flags = 0;
};
void PushStyleCombobox(const ImVec4& color = Colors::Indigo);
void PopStyleCombobox();
bool Combobox(const char* label, uint8_t* value, std::span<const char*, std::dynamic_extent> comboArray, const ComboboxOptions& options = {});
bool CVarCombobox(const char* label, const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, const ComboboxOptions& options = {});
struct IntSliderOptions {
const ImVec4 color = Colors::Gray;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
bool showButtons = true;
ImGuiSliderFlags flags = 0;
const char* format = "%d";
const uint32_t step = 1;
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
};
struct FloatSliderOptions {
const ImVec4 color = Colors::Gray;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
bool showButtons = true;
ImGuiSliderFlags flags = 0;
const char* format = "%f";
const float step = 0.01f;
bool isPercentage = false; // Multiplies visual value by 100
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
};
void PushStyleSlider(const ImVec4& color = Colors::Indigo);
void PopStyleSlider();
bool SliderInt(const char* label, int32_t* value, int32_t min, int32_t max, const IntSliderOptions& options = {});
bool CVarSliderInt(const char* label, const char* cvarName, int32_t min, int32_t max, const int32_t defaultValue, const IntSliderOptions& options = {});
bool SliderFloat(const char* label, float* value, float min, float max, const FloatSliderOptions& options = {});
bool CVarSliderFloat(const char* label, const char* cvarName, float min, float max, const float defaultValue, const FloatSliderOptions& options = {});
}
+1 -1
View File
@@ -242,7 +242,7 @@ void Fault_ThreadEntry(void* arg0) {
func_8000762C(300, 10, "-");
gControllerPlugged[0] = 1;
while (var_s5 == 0) {
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_PRI_NORMAL);
osSendMesg(&gSerialThreadMsgQueue, OS_MESG_32(SI_READ_CONTROLLER), OS_MESG_PRI_NORMAL);
osRecvMesg(&gControllerMsgQueue, NULL, OS_MESG_BLOCK);
Controller_UpdateInput();
switch (var_s0) {
+12 -12
View File
@@ -63,7 +63,7 @@ void Controller_UpdateInput(void) {
s32 i;
for (i = 0; i < 4; i++) {
if (gControllerPlugged[i] == 1 && sNextController[i].errno == 0) {
if (gControllerPlugged[i] == 1 && sNextController[i].err_no == 0) {
sPrevController[i] = gControllerHold[i];
gControllerHold[i] = sNextController[i];
gControllerPress[i].button =
@@ -71,8 +71,8 @@ void Controller_UpdateInput(void) {
Controller_AddDeadZone(i);
} else {
gControllerHold[i].button = gControllerHold[i].stick_x = gControllerHold[i].stick_y =
gControllerHold[i].errno = gControllerPress[i].button = gControllerPress[i].stick_x =
gControllerPress[i].stick_y = gControllerPress[i].errno = 0;
gControllerHold[i].err_no = gControllerPress[i].button = gControllerPress[i].stick_x =
gControllerPress[i].stick_y = gControllerPress[i].err_no = 0;
}
}
}
@@ -84,41 +84,41 @@ void Controller_ReadData(void) {
gControllerLock--;
for (i = 0; i < 4; i++) {
sNextController[i].button = sNextController[i].stick_x = sNextController[i].stick_y =
sNextController[i].errno = 0;
sNextController[i].err_no = 0;
}
} else {
osContStartReadData(&gSerialEventQueue);
osRecvMesg(&gSerialEventQueue, NULL, OS_MESG_BLOCK);
osContGetReadData(sNextController);
}
osSendMesg(&gControllerMsgQueue, (OSMesg) SI_CONT_READ_DONE, OS_MESG_PRI_NORMAL);
osSendMesg(&gControllerMsgQueue, OS_MESG_32(SI_CONT_READ_DONE), OS_MESG_PRI_NORMAL);
}
void Save_ReadData(void) {
if ((gStartNMI == 0) && (Save_ReadEeprom(&gSaveIOBuffer) == 0)) {
osSendMesg(&gSaveMsgQueue, (OSMesg) SI_SAVE_SUCCESS, OS_MESG_PRI_NORMAL);
osSendMesg(&gSaveMsgQueue, OS_MESG_32(SI_SAVE_SUCCESS), OS_MESG_PRI_NORMAL);
return;
}
osSendMesg(&gSaveMsgQueue, (OSMesg) SI_SAVE_FAILED, OS_MESG_PRI_NORMAL);
osSendMesg(&gSaveMsgQueue, OS_MESG_32(SI_SAVE_FAILED), OS_MESG_PRI_NORMAL);
}
void Save_WriteData(void) {
if ((gStartNMI == 0) && (Save_WriteEeprom(&gSaveIOBuffer) == 0)) {
osSendMesg(&gSaveMsgQueue, (OSMesg) SI_SAVE_SUCCESS, OS_MESG_PRI_NORMAL);
osSendMesg(&gSaveMsgQueue, OS_MESG_32(SI_SAVE_SUCCESS), OS_MESG_PRI_NORMAL);
return;
}
osSendMesg(&gSaveMsgQueue, (OSMesg) SI_SAVE_FAILED, OS_MESG_PRI_NORMAL);
osSendMesg(&gSaveMsgQueue, OS_MESG_32(SI_SAVE_FAILED), OS_MESG_PRI_NORMAL);
}
void Controller_Rumble(void) {
s32 i;
osContStartQuery(&gSerialEventQueue);
// osContStartQuery(&gSerialEventQueue);
osRecvMesg(&gSerialEventQueue, NULL, OS_MESG_BLOCK);
osContGetQuery(sControllerStatus);
// osContGetQuery(sControllerStatus);
for (i = 0; i < 4; i++) {
if ((gControllerPlugged[i] != 0) && (sControllerStatus[i].errno == 0)) {
if ((gControllerPlugged[i] != 0) && (sControllerStatus[i].err_no == 0)) {
if (sControllerStatus[i].status & 1) {
if (gControllerRumble[i] == 0) {
if (osMotorInit(&gSerialEventQueue, &sControllerMotor[i], i)) {
+7 -6
View File
@@ -120,24 +120,25 @@ void Lib_DmaRead(void* src, void* dst, ptrdiff_t size) {
void Lib_FillScreen(u8 setFill) {
s32 i;
// TODO: Implement fill screen
gFillScreenColor |= 1;
if (setFill == true) {
if (gFillScreen == false) {
if (gFillScreenColor == 1) {
osViBlack(1);
// osViBlack(1);
} else {
for (i = 0; i < 3 * SCREEN_WIDTH; i++) {
gFillBuffer[i] = gFillScreenColor;
}
osWritebackDCacheAll();
osViSwapBuffer(&gFillBuffer[SCREEN_WIDTH]);
osViRepeatLine(1);
// osWritebackDCacheAll();
// osViSwapBuffer(&gFillBuffer[SCREEN_WIDTH]);
// osViRepeatLine(1);
}
gFillScreen = true;
}
} else if (gFillScreen == true) {
osViRepeatLine(0);
osViBlack(0);
// osViRepeatLine(0);
// osViBlack(0);
gFillScreen = false;
}
}
+109 -108
View File
@@ -108,46 +108,46 @@ void Audio_ThreadEntry(void* arg0) {
task = AudioThread_CreateTask();
if (task != NULL) {
task->msgQueue = &gAudioTaskMsgQueue;
task->msg = (OSMesg) TASK_MESG_1;
task->msg = OS_MESG_32(TASK_MESG_1);
osWritebackDCacheAll();
osSendMesg(&gTaskMsgQueue, task, OS_MESG_PRI_NORMAL);
osSendMesg(&gTaskMsgQueue, OS_MESG_PTR(task), OS_MESG_PRI_NORMAL);
}
while (1) {
task = AudioThread_CreateTask();
if (task != NULL) {
task->msgQueue = &gAudioTaskMsgQueue;
task->msg = (OSMesg) TASK_MESG_1;
task->msg = OS_MESG_32(TASK_MESG_1);
osWritebackDCacheAll();
}
osRecvMesg(&gAudioTaskMsgQueue, NULL, OS_MESG_NOBLOCK);
if (task != NULL) {
osSendMesg(&gTaskMsgQueue, task, OS_MESG_PRI_NORMAL);
osSendMesg(&gTaskMsgQueue, OS_MESG_PTR(task), OS_MESG_PRI_NORMAL);
}
osRecvMesg(&gAudioVImsgQueue, NULL, OS_MESG_BLOCK);
}
}
void Graphics_SetTask(void) {
gGfxTask->msgQueue = &gGfxTaskMsgQueue;
gGfxTask->msg = (OSMesg) TASK_MESG_2;
gGfxTask->task.t.type = M_GFXTASK;
gGfxTask->task.t.flags = 0;
gGfxTask->task.t.ucode_boot = rspbootTextStart;
gGfxTask->task.t.ucode_boot_size = (uintptr_t) rspbootTextEnd - (uintptr_t) rspbootTextStart;
gGfxTask->task.t.ucode = gspF3DEX_fifoTextStart;
gGfxTask->task.t.ucode_size = SP_UCODE_SIZE;
gGfxTask->task.t.ucode_data = (u64*) &gspF3DEX_fifoDataStart;
gGfxTask->task.t.ucode_data_size = SP_UCODE_DATA_SIZE;
gGfxTask->task.t.dram_stack = gDramStack;
gGfxTask->task.t.dram_stack_size = SP_DRAM_STACK_SIZE8;
gGfxTask->task.t.output_buff = (u64*) gTaskOutputBuffer;
gGfxTask->task.t.output_buff_size = (u64*) gAudioHeap;
gGfxTask->task.t.data_ptr = (u64*) gGfxPool->masterDL;
gGfxTask->task.t.data_size = (gMasterDisp - gGfxPool->masterDL) * sizeof(Gfx);
gGfxTask->task.t.yield_data_ptr = (u64*) &gOSYieldData;
gGfxTask->task.t.yield_data_size = OS_YIELD_DATA_SIZE;
osWritebackDCacheAll();
osSendMesg(&gTaskMsgQueue, gGfxTask, OS_MESG_PRI_NORMAL);
// gGfxTask->msgQueue = &gGfxTaskMsgQueue;
// gGfxTask->msg = (OSMesg) TASK_MESG_2;
// gGfxTask->task.t.type = M_GFXTASK;
// gGfxTask->task.t.flags = 0;
// gGfxTask->task.t.ucode_boot = rspbootTextStart;
// gGfxTask->task.t.ucode_boot_size = (uintptr_t) rspbootTextEnd - (uintptr_t) rspbootTextStart;
// gGfxTask->task.t.ucode = gspF3DEX_fifoTextStart;
// gGfxTask->task.t.ucode_size = SP_UCODE_SIZE;
// gGfxTask->task.t.ucode_data = (u64*) &gspF3DEX_fifoDataStart;
// gGfxTask->task.t.ucode_data_size = SP_UCODE_DATA_SIZE;
// gGfxTask->task.t.dram_stack = gDramStack;
// gGfxTask->task.t.dram_stack_size = SP_DRAM_STACK_SIZE8;
// gGfxTask->task.t.output_buff = (u64*) gTaskOutputBuffer;
// gGfxTask->task.t.output_buff_size = (u64*) gAudioHeap;
// gGfxTask->task.t.data_ptr = (u64*) gGfxPool->masterDL;
// gGfxTask->task.t.data_size = (gMasterDisp - gGfxPool->masterDL) * sizeof(Gfx);
// gGfxTask->task.t.yield_data_ptr = (u64*) &gOSYieldData;
// gGfxTask->task.t.yield_data_size = OS_YIELD_DATA_SIZE;
// osWritebackDCacheAll();
// osSendMesg(&gTaskMsgQueue, gGfxTask, OS_MESG_PRI_NORMAL);
}
void Graphics_InitializeTask(u32 frameCount) {
@@ -176,23 +176,23 @@ void Main_SetVIMode(void) {
(gControllerHold[3].button & R_TRIG) && (gControllerHold[3].button & Z_TRIG)) {
sGammaMode = 1 - sGammaMode;
}
switch (osTvType) {
case OS_TV_PAL:
osViSetMode(&osViModePalLan1);
break;
case OS_TV_MPAL:
osViSetMode(&osViModeMpalLan1);
break;
default:
case OS_TV_NTSC:
osViSetMode(&osViModeNtscLan1);
break;
}
if (sGammaMode != 0) {
osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_DIVOT_OFF | OS_VI_GAMMA_ON | OS_VI_GAMMA_DITHER_ON);
} else {
osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_DIVOT_OFF | OS_VI_GAMMA_OFF | OS_VI_GAMMA_DITHER_OFF);
}
// switch (osTvType) {
// case OS_TV_PAL:
// osViSetMode(&osViModePalLan1);
// break;
// case OS_TV_MPAL:
// osViSetMode(&osViModeMpalLan1);
// break;
// default:
// case OS_TV_NTSC:
// osViSetMode(&osViModeNtscLan1);
// break;
// }
// if (sGammaMode != 0) {
// osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_DIVOT_OFF | OS_VI_GAMMA_ON | OS_VI_GAMMA_DITHER_ON);
// } else {
// osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_DIVOT_OFF | OS_VI_GAMMA_OFF | OS_VI_GAMMA_DITHER_OFF);
// }
}
void SerialInterface_ThreadEntry(void* arg0) {
@@ -202,7 +202,7 @@ void SerialInterface_ThreadEntry(void* arg0) {
while (1) {
osRecvMesg(&gSerialThreadMsgQueue, &sp34, OS_MESG_BLOCK);
switch ((s32) sp34) {
switch (sp34.data32) {
case SI_READ_CONTROLLER:
Controller_ReadData();
break;
@@ -220,11 +220,11 @@ void SerialInterface_ThreadEntry(void* arg0) {
}
void Timer_ThreadEntry(void* arg0) {
void* sp24;
OSMesg sp24;
while (1) {
osRecvMesg(&gTimerTaskMsgQueue, &sp24, OS_MESG_BLOCK);
Timer_CompleteTask(sp24);
Timer_CompleteTask(sp24.ptr);
}
}
@@ -234,7 +234,7 @@ void Graphics_ThreadEntry(void* arg0) {
u8 var_v2;
Game_Initialize();
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_PRI_NORMAL);
osSendMesg(&gSerialThreadMsgQueue, OS_MESG_32(SI_READ_CONTROLLER), OS_MESG_PRI_NORMAL);
Graphics_InitializeTask(gSysFrameCount);
{
gSPSegment(gUnkDisp1++, 0, 0);
@@ -251,9 +251,9 @@ void Graphics_ThreadEntry(void* arg0) {
gSysFrameCount++;
Graphics_InitializeTask(gSysFrameCount);
osRecvMesg(&gControllerMsgQueue, NULL, OS_MESG_BLOCK);
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_RUMBLE, OS_MESG_PRI_NORMAL);
osSendMesg(&gSerialThreadMsgQueue, OS_MESG_32(SI_RUMBLE), OS_MESG_PRI_NORMAL);
Controller_UpdateInput();
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_PRI_NORMAL);
osSendMesg(&gSerialThreadMsgQueue, OS_MESG_32(SI_READ_CONTROLLER), OS_MESG_PRI_NORMAL);
if (gControllerPress[3].button & U_JPAD) {
Main_SetVIMode();
}
@@ -275,7 +275,7 @@ void Graphics_ThreadEntry(void* arg0) {
if (gFillScreen == 0) {
osViSwapBuffer(&gFrameBuffers[(gSysFrameCount - 1) % 3]);
}
func_80007FE4(&gFrameBuffers[(gSysFrameCount - 1) % 3], SCREEN_WIDTH, 16);
// func_80007FE4(&gFrameBuffers[(gSysFrameCount - 1) % 3], SCREEN_WIDTH, 16);
var_v1 = MIN(D_80137E78, 4);
var_v2 = MAX(var_v1, gGfxVImsgQueue.validCount + 1);
@@ -295,12 +295,12 @@ void Main_InitMesgQueues(void) {
osCreateMesgQueue(&gGfxVImsgQueue, sGfxVImsgBuff, ARRAY_COUNT(sGfxVImsgBuff));
osCreateMesgQueue(&gGfxTaskMsgQueue, sGfxTaskMsgBuff, ARRAY_COUNT(sGfxTaskMsgBuff));
osCreateMesgQueue(&gSerialEventQueue, sSerialEventBuff, ARRAY_COUNT(sSerialEventBuff));
osSetEventMesg(OS_EVENT_SI, &gSerialEventQueue, NULL);
osSetEventMesg(OS_EVENT_SI, &gSerialEventQueue, OS_MESG_PTR(NULL));
osCreateMesgQueue(&gMainThreadMsgQueue, sMainThreadMsgBuff, ARRAY_COUNT(sMainThreadMsgBuff));
osViSetEvent(&gMainThreadMsgQueue, (OSMesg) EVENT_MESG_VI, 1);
osSetEventMesg(OS_EVENT_SP, &gMainThreadMsgQueue, (OSMesg) EVENT_MESG_SP);
osSetEventMesg(OS_EVENT_DP, &gMainThreadMsgQueue, (OSMesg) EVENT_MESG_DP);
osSetEventMesg(OS_EVENT_PRENMI, &gMainThreadMsgQueue, (OSMesg) EVENT_MESG_PRENMI);
osViSetEvent(&gMainThreadMsgQueue, OS_MESG_32(EVENT_MESG_VI), 1);
osSetEventMesg(OS_EVENT_SP, &gMainThreadMsgQueue, OS_MESG_32(EVENT_MESG_SP));
osSetEventMesg(OS_EVENT_DP, &gMainThreadMsgQueue, OS_MESG_32(EVENT_MESG_DP));
osSetEventMesg(OS_EVENT_PRENMI, &gMainThreadMsgQueue, OS_MESG_32(EVENT_MESG_PRENMI));
osCreateMesgQueue(&gTimerTaskMsgQueue, sTimerTaskMsgBuff, ARRAY_COUNT(sTimerTaskMsgBuff));
osCreateMesgQueue(&gTimerWaitMsgQueue, sTimerWaitMsgBuff, ARRAY_COUNT(sTimerWaitMsgBuff));
osCreateMesgQueue(&gSerialThreadMsgQueue, sSerialThreadMsgBuff, ARRAY_COUNT(sSerialThreadMsgBuff));
@@ -323,22 +323,22 @@ void Main_HandleRDP(void) {
}
void Main_HandleRSP(void) {
SPTask* task = gCurrentTask;
gCurrentTask = NULL;
if (task->state == SPTASK_STATE_INTERRUPTED) {
if (osSpTaskYielded(&task->task) == 0) {
task->state = SPTASK_STATE_FINISHED;
}
} else {
task->state = SPTASK_STATE_FINISHED;
if (task->task.t.type == M_AUDTASK) {
if (task->msgQueue != NULL) {
osSendMesg(task->msgQueue, task->msg, OS_MESG_PRI_NORMAL);
}
sAudioTasks[0] = NULL;
}
}
// SPTask* task = gCurrentTask;
//
// gCurrentTask = NULL;
// if (task->state == SPTASK_STATE_INTERRUPTED) {
// if (osSpTaskYielded(&task->task) == 0) {
// task->state = SPTASK_STATE_FINISHED;
// }
// } else {
// task->state = SPTASK_STATE_FINISHED;
// if (task->task.t.type == M_AUDTASK) {
// if (task->msgQueue != NULL) {
// osSendMesg(task->msgQueue, task->msg, OS_MESG_PRI_NORMAL);
// }
// sAudioTasks[0] = NULL;
// }
// }
}
void Main_GetNewTasks(void) {
@@ -362,7 +362,7 @@ void Main_GetNewTasks(void) {
var_s0_2 = sNewAudioTasks;
var_s1_2 = sNewGfxTasks;
while (osRecvMesg(&gTaskMsgQueue, &sp40, OS_MESG_NOBLOCK) != MSG_QUEUE_EMPTY) {
sp3C = (SPTask*) sp40;
sp3C = (SPTask*) sp40.ptr;
sp3C->state = SPTASK_STATE_NOT_STARTED;
switch (sp3C->task.t.type) {
@@ -403,50 +403,50 @@ void Main_StartNextTask(void) {
if (gCurrentTask != NULL) {
if (gCurrentTask->task.t.type == M_GFXTASK) {
gCurrentTask->state = SPTASK_STATE_INTERRUPTED;
osSpTaskYield();
// osSpTaskYield();
}
} else {
gCurrentTask = sAudioTasks[0];
osSpTaskLoad(&gCurrentTask->task);
osSpTaskStartGo(&gCurrentTask->task);
// osSpTaskLoad(&gCurrentTask->task);
// osSpTaskStartGo(&gCurrentTask->task);
gCurrentTask->state = SPTASK_STATE_RUNNING;
}
} else if ((gCurrentTask == NULL) && (sGfxTasks[0] != NULL) && (sGfxTasks[0]->state != SPTASK_STATE_FINISHED)) {
gCurrentTask = sGfxTasks[0];
osDpSetStatus(DPC_CLR_TMEM_CTR | DPC_CLR_PIPE_CTR | DPC_CLR_CMD_CTR | DPC_CLR_CLOCK_CTR);
osSpTaskLoad(&gCurrentTask->task);
osSpTaskStartGo(&gCurrentTask->task);
// osDpSetStatus(DPC_CLR_TMEM_CTR | DPC_CLR_PIPE_CTR | DPC_CLR_CMD_CTR | DPC_CLR_CLOCK_CTR);
// osSpTaskLoad(&gCurrentTask->task);
// osSpTaskStartGo(&gCurrentTask->task);
gCurrentTask->state = SPTASK_STATE_RUNNING;
}
}
void Main_ThreadEntry(void* arg0) {
OSMesg ogMsg;
u8 mesg;
u32 mesg;
osCreateThread(&gAudioThread, THREAD_ID_AUDIO, Audio_ThreadEntry, arg0,
gAudioThreadStack + sizeof(gAudioThreadStack), 80);
osStartThread(&gAudioThread);
osCreateThread(&gGraphicsThread, THREAD_ID_GRAPHICS, Graphics_ThreadEntry, arg0,
gGraphicsThreadStack + sizeof(gGraphicsThreadStack), 40);
osStartThread(&gGraphicsThread);
osCreateThread(&gTimerThread, THREAD_ID_TIMER, Timer_ThreadEntry, arg0,
gTimerThreadStack + sizeof(gTimerThreadStack), 60);
osStartThread(&gTimerThread);
osCreateThread(&gSerialThread, THREAD_ID_SERIAL, SerialInterface_ThreadEntry, arg0,
gSerialThreadStack + sizeof(gSerialThreadStack), 20);
osStartThread(&gSerialThread);
// osCreateThread(&gAudioThread, THREAD_ID_AUDIO, Audio_ThreadEntry, arg0,
// gAudioThreadStack + sizeof(gAudioThreadStack), 80);
// osStartThread(&gAudioThread);
// osCreateThread(&gGraphicsThread, THREAD_ID_GRAPHICS, Graphics_ThreadEntry, arg0,
// gGraphicsThreadStack + sizeof(gGraphicsThreadStack), 40);
// osStartThread(&gGraphicsThread);
// osCreateThread(&gTimerThread, THREAD_ID_TIMER, Timer_ThreadEntry, arg0,
// gTimerThreadStack + sizeof(gTimerThreadStack), 60);
// osStartThread(&gTimerThread);
// osCreateThread(&gSerialThread, THREAD_ID_SERIAL, SerialInterface_ThreadEntry, arg0,
// gSerialThreadStack + sizeof(gSerialThreadStack), 20);
// osStartThread(&gSerialThread);
Main_InitMesgQueues();
while (true) {
osRecvMesg(&gMainThreadMsgQueue, &ogMsg, OS_MESG_BLOCK);
mesg = (u32) ogMsg;
mesg = ogMsg.data32;
switch (mesg) {
case EVENT_MESG_VI:
osSendMesg(&gAudioVImsgQueue, (OSMesg) EVENT_MESG_VI, OS_MESG_PRI_NORMAL);
osSendMesg(&gGfxVImsgQueue, (OSMesg) EVENT_MESG_VI, OS_MESG_PRI_NORMAL);
osSendMesg(&gAudioVImsgQueue, OS_MESG_32(EVENT_MESG_VI), OS_MESG_PRI_NORMAL);
osSendMesg(&gGfxVImsgQueue, OS_MESG_32(EVENT_MESG_VI), OS_MESG_PRI_NORMAL);
Main_GetNewTasks();
break;
case EVENT_MESG_SP:
@@ -466,24 +466,25 @@ void Main_ThreadEntry(void* arg0) {
}
void Idle_ThreadEntry(void* arg0) {
osCreateViManager(OS_PRIORITY_VIMGR);
Main_SetVIMode();
Lib_FillScreen(1);
osCreatePiManager(OS_PRIORITY_PIMGR, &gPiMgrCmdQueue, sPiMgrCmdBuff, ARRAY_COUNT(sPiMgrCmdBuff));
osCreateThread(&gMainThread, THREAD_ID_MAIN, &Main_ThreadEntry, arg0, sMainThreadStack + sizeof(sMainThreadStack),
100);
osStartThread(&gMainThread);
Fault_Init();
osSetThreadPri(NULL, OS_PRIORITY_IDLE);
loop_1:
goto loop_1;
// TODO: Implement idle thread
// osCreateViManager(OS_PRIORITY_VIMGR);
// Main_SetVIMode();
// Lib_FillScreen(1);
// osCreatePiManager(OS_PRIORITY_PIMGR, &gPiMgrCmdQueue, sPiMgrCmdBuff, ARRAY_COUNT(sPiMgrCmdBuff));
// osCreateThread(&gMainThread, THREAD_ID_MAIN, &Main_ThreadEntry, arg0, sMainThreadStack + sizeof(sMainThreadStack),
// 100);
// osStartThread(&gMainThread);
// Fault_Init();
// osSetThreadPri(NULL, OS_PRIORITY_IDLE);
// loop_1:
// goto loop_1;
}
void bootproc(void) {
RdRam_CheckIPL3();
osInitialize();
// RdRam_CheckIPL3();
// osInitialize();
Main_Initialize();
osCreateThread(&sIdleThread, THREAD_ID_IDLE, &Idle_ThreadEntry, NULL, sIdleThreadStack + sizeof(sIdleThreadStack),
255);
osStartThread(&sIdleThread);
// osCreateThread(&sIdleThread, THREAD_ID_IDLE, &Idle_ThreadEntry, NULL, sIdleThreadStack + sizeof(sIdleThreadStack),
// 255);
// osStartThread(&sIdleThread);
}
+22 -22
View File
@@ -1,19 +1,19 @@
#include "sys.h"
Mtx gIdentityMtx = { {
{
Mtx gIdentityMtx = {
.intPart = {
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 },
},
{
.fracPart = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
} };
};
Matrix gIdentityMatrix = { {
{ 1.0f, 0.0f, 0.0f, 0.0f },
@@ -332,8 +332,8 @@ void Matrix_RotateAxis(Matrix* mtx, f32 angle, f32 axisX, f32 axisY, f32 axisZ,
// Converts the current Gfx matrix to a Mtx
void Matrix_ToMtx(Mtx* dest) {
s32 intVal;
u16(*iPart)[4] = dest->u.i;
u16(*fPart)[4] = dest->u.f;
u16(*iPart)[4] = dest->intPart;
u16(*fPart)[4] = dest->fracPart;
Matrix* src = gGfxMatrix;
intVal = src->m[0][0] * 0x10000;
@@ -403,22 +403,22 @@ void Matrix_ToMtx(Mtx* dest) {
// Converts the Mtx src to a Matrix, putting the result in dest
void Matrix_FromMtx(Mtx* src, Matrix* dest) {
dest->m[0][0] = ((src->u.i[0][0] << 0x10) | src->u.f[0][0]) * (1.0f / 0x10000);
dest->m[0][1] = ((src->u.i[0][1] << 0x10) | src->u.f[0][1]) * (1.0f / 0x10000);
dest->m[0][2] = ((src->u.i[0][2] << 0x10) | src->u.f[0][2]) * (1.0f / 0x10000);
dest->m[0][3] = ((src->u.i[0][3] << 0x10) | src->u.f[0][3]) * (1.0f / 0x10000);
dest->m[1][0] = ((src->u.i[1][0] << 0x10) | src->u.f[1][0]) * (1.0f / 0x10000);
dest->m[1][1] = ((src->u.i[1][1] << 0x10) | src->u.f[1][1]) * (1.0f / 0x10000);
dest->m[1][2] = ((src->u.i[1][2] << 0x10) | src->u.f[1][2]) * (1.0f / 0x10000);
dest->m[1][3] = ((src->u.i[1][3] << 0x10) | src->u.f[1][3]) * (1.0f / 0x10000);
dest->m[2][0] = ((src->u.i[2][0] << 0x10) | src->u.f[2][0]) * (1.0f / 0x10000);
dest->m[2][1] = ((src->u.i[2][1] << 0x10) | src->u.f[2][1]) * (1.0f / 0x10000);
dest->m[2][2] = ((src->u.i[2][2] << 0x10) | src->u.f[2][2]) * (1.0f / 0x10000);
dest->m[2][3] = ((src->u.i[2][3] << 0x10) | src->u.f[2][3]) * (1.0f / 0x10000);
dest->m[3][0] = ((src->u.i[3][0] << 0x10) | src->u.f[3][0]) * (1.0f / 0x10000);
dest->m[3][1] = ((src->u.i[3][1] << 0x10) | src->u.f[3][1]) * (1.0f / 0x10000);
dest->m[3][2] = ((src->u.i[3][2] << 0x10) | src->u.f[3][2]) * (1.0f / 0x10000);
dest->m[3][3] = ((src->u.i[3][3] << 0x10) | src->u.f[3][3]) * (1.0f / 0x10000);
dest->m[0][0] = ((src->intPart[0][0] << 0x10) | src->fracPart[0][0]) * (1.0f / 0x10000);
dest->m[0][1] = ((src->intPart[0][1] << 0x10) | src->fracPart[0][1]) * (1.0f / 0x10000);
dest->m[0][2] = ((src->intPart[0][2] << 0x10) | src->fracPart[0][2]) * (1.0f / 0x10000);
dest->m[0][3] = ((src->intPart[0][3] << 0x10) | src->fracPart[0][3]) * (1.0f / 0x10000);
dest->m[1][0] = ((src->intPart[1][0] << 0x10) | src->fracPart[1][0]) * (1.0f / 0x10000);
dest->m[1][1] = ((src->intPart[1][1] << 0x10) | src->fracPart[1][1]) * (1.0f / 0x10000);
dest->m[1][2] = ((src->intPart[1][2] << 0x10) | src->fracPart[1][2]) * (1.0f / 0x10000);
dest->m[1][3] = ((src->intPart[1][3] << 0x10) | src->fracPart[1][3]) * (1.0f / 0x10000);
dest->m[2][0] = ((src->intPart[2][0] << 0x10) | src->fracPart[2][0]) * (1.0f / 0x10000);
dest->m[2][1] = ((src->intPart[2][1] << 0x10) | src->fracPart[2][1]) * (1.0f / 0x10000);
dest->m[2][2] = ((src->intPart[2][2] << 0x10) | src->fracPart[2][2]) * (1.0f / 0x10000);
dest->m[2][3] = ((src->intPart[2][3] << 0x10) | src->fracPart[2][3]) * (1.0f / 0x10000);
dest->m[3][0] = ((src->intPart[3][0] << 0x10) | src->fracPart[3][0]) * (1.0f / 0x10000);
dest->m[3][1] = ((src->intPart[3][1] << 0x10) | src->fracPart[3][1]) * (1.0f / 0x10000);
dest->m[3][2] = ((src->intPart[3][2] << 0x10) | src->fracPart[3][2]) * (1.0f / 0x10000);
dest->m[3][3] = ((src->intPart[3][3] << 0x10) | src->fracPart[3][3]) * (1.0f / 0x10000);
}
// Applies the transform matrix mtx to the vector src, putting the result in dest
+2 -2
View File
@@ -23,7 +23,7 @@ s32 Timer_CreateTask(u64 time, TimerAction action, s32* address, s32 value) {
task->action = action;
task->address = address;
task->value = value;
return osSetTimer(&task->timer, time, 0, &gTimerTaskMsgQueue, task);
return osSetTimer(&task->timer, time, 0, &gTimerTaskMsgQueue, OS_MESG_PTR(task));
}
void Timer_Increment(s32* address, s32 value) {
@@ -45,6 +45,6 @@ void Timer_Wait(u64 time) {
OSTimer timer;
OSMesg dummy;
osSetTimer(&timer, time, 0, &gTimerWaitMsgQueue, NULL);
osSetTimer(&timer, time, 0, &gTimerWaitMsgQueue, OS_MESG_PTR(NULL));
osRecvMesg(&gTimerWaitMsgQueue, &dummy, OS_MESG_BLOCK);
}