Skip to content

Commit

Permalink
[jak3] Avoid language 255 issue (#3818)
Browse files Browse the repository at this point in the history
In Jak 3, the default PC settings file would have a language of 255
because it runs before the first settings update. This would cause the
game to crash the second time it is started.

I also added this simple imgui window to see the names of streams in the
"SPU" memory, which has been useful for debugging

![image](https://github.com/user-attachments/assets/0a9d6af7-c423-4d8a-a461-faf45e350f33)

---------

Co-authored-by: water111 <awaterford1111445@gmail.com>
  • Loading branch information
water111 and water111 authored Jan 4, 2025
1 parent ea61985 commit 266b423
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 1 deletion.
17 changes: 17 additions & 0 deletions game/graphics/opengl_renderer/debug_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "game/graphics/display.h"
#include "game/graphics/gfx.h"
#include "game/graphics/screenshot.h"
#include "game/overlord/jak3/dma.h"
#include "game/system/hid/sdl_util.h"

#include "fmt/core.h"
Expand Down Expand Up @@ -104,6 +105,7 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) {
ImGui::MenuItem("Profiler", nullptr, &m_draw_profiler);
ImGui::MenuItem("Small Profiler", nullptr, &small_profiler);
ImGui::MenuItem("Loader", nullptr, &m_draw_loader);
ImGui::MenuItem("Overlord", nullptr, &m_draw_overlord);
if (ImGui::MenuItem("Reboot In Debug Mode!")) {
want_reboot_in_debug = true;
}
Expand Down Expand Up @@ -215,4 +217,19 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) {
if (m_draw_frame_time) {
m_frame_timer.draw_window(dma_stats);
}

if (should_draw_overlord_debug()) {
draw_overlord_debug_menu();
}
}

void OpenGlDebugGui::draw_overlord_debug_menu() {
ImGui::Begin("Overlord");

for (int stream_idx = 0; stream_idx < 6; stream_idx++) {
auto& stream = jak3::g_overlord_stream_memory.infos[stream_idx];

ImGui::Text("%30s [%3d] | %30s [%3d]", stream[0].name.chars, stream[0].idx,
stream[1].name.chars, stream[1].idx);
}
}
3 changes: 3 additions & 0 deletions game/graphics/opengl_renderer/debug_gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class OpenGlDebugGui {
bool should_draw_subtitle_editor() const { return master_enable && m_subtitle_editor; }
bool should_draw_filters_menu() const { return master_enable && m_filters_menu; }
bool should_draw_loader_menu() const { return master_enable && m_draw_loader; }
bool should_draw_overlord_debug() const { return master_enable && m_draw_overlord; }

bool should_advance_frame() { return m_frame_timer.should_advance_frame(); }
bool should_gl_finish() const { return m_frame_timer.do_gl_finish; }
Expand All @@ -72,11 +73,13 @@ class OpenGlDebugGui {
bool master_enable = false;

private:
void draw_overlord_debug_menu();
FrameTimeRecorder m_frame_timer;
bool m_draw_frame_time = false;
bool m_draw_profiler = false;
bool m_draw_debug = false;
bool m_draw_loader = false;
bool m_draw_overlord = false;
bool m_subtitle_editor = false;
bool m_filters_menu = false;
bool m_want_screenshot = false;
Expand Down
74 changes: 74 additions & 0 deletions game/overlord/jak3/dma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define VOICE_BIT(voice) (1 << ((voice) >> 1))

namespace jak3 {
OverlordStreamMemory g_overlord_stream_memory;
using namespace iop;
namespace {

Expand Down Expand Up @@ -51,6 +52,8 @@ struct DmaInterruptHandlerHack {
bool pending = false;
} g_DmaInterruptHack;

const char* g_current_stream_name = 0;

} // namespace

void jak3_overlord_init_globals_dma() {
Expand Down Expand Up @@ -139,10 +142,74 @@ int voice_trans_wrapper(s16 chan, u32 mode, const void* iop_addr, u32 spu_addr,
} else {
g_voiceTransRunning = true;
g_voiceTransTime = GetSystemTimeLow();

switch (spu_addr) {
case 0x5040:
g_overlord_stream_memory.update_name(g_current_stream_name, 0, 0);
break;
case 0x7040:
g_overlord_stream_memory.update_name(g_current_stream_name, 0, 1);
break;
case 0x9080:
g_overlord_stream_memory.update_name(g_current_stream_name, 1, 0);
break;
case 0xb080:
g_overlord_stream_memory.update_name(g_current_stream_name, 1, 1);
break;
case 0xd0c0:
g_overlord_stream_memory.update_name(g_current_stream_name, 2, 0);
break;
case 0xf0c0:
g_overlord_stream_memory.update_name(g_current_stream_name, 2, 1);
break;
case 0x11100:
g_overlord_stream_memory.update_name(g_current_stream_name, 3, 0);
break;
case 0x13100:
g_overlord_stream_memory.update_name(g_current_stream_name, 3, 1);
break;
case 0x15140:
g_overlord_stream_memory.update_name(g_current_stream_name, 4, 0);
break;
case 0x17140:
g_overlord_stream_memory.update_name(g_current_stream_name, 4, 1);
break;
case 0x19180:
g_overlord_stream_memory.update_name(g_current_stream_name, 5, 0);
break;
case 0x1b180:
g_overlord_stream_memory.update_name(g_current_stream_name, 5, 1);
break;
}
return sceSdVoiceTrans(chan, mode, iop_addr, spu_addr, size);
}
}

OverlordStreamMemory::OverlordStreamMemory() {
for (auto& x : infos) {
for (auto& y : x) {
y.idx = 0;
strcpy(y.name.chars, "Uninitialized");
}
}
}

void OverlordStreamMemory::update_name(const char* input, int stream, int side) {
auto& info = infos[stream][side];
if (!input) {
strcpy(info.name.chars, "???");
info.idx = 0;
} else {
if (strcmp(input, info.name.chars) == 0) {
info.idx++;
} else {
info.idx = 0;
strncpy(info.name.chars, input, 48);
info.name.chars[47] = 0;
}
}
}

u32 read_rate_calc(u32 pitch) {
u64 pitch1 = (pitch >> 3);
u64 mult_result = pitch1 * 0x2492'4925ull;
Expand Down Expand Up @@ -464,6 +531,13 @@ int DMA_SendToSPUAndSync(const u8* iop_mem,
ovrld_log(LogCategory::SPU_DMA_STR,
"DMA to SPU requested for {}, {} bytes to 0x{:x}, currently busy? {}",
cmd ? cmd->name : "NO-CMD", length, spu_addr, g_bSpuDmaBusy);
if (cmd) {
g_current_stream_name = cmd->name;
} else {
const static char* unknown = "unknown";
g_current_stream_name = unknown;
}

if (g_bSpuDmaBusy == 0) {
// not busy, we can actually start dma now.
g_nSpuDmaChannel = snd_GetFreeSPUDMA();
Expand Down
16 changes: 16 additions & 0 deletions game/overlord/jak3/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "common/common_types.h"

#include "game/overlord/jak3/rpc_interface.h"

namespace jak3 {
void jak3_overlord_init_globals_dma();
struct ISO_VAGCommand;
Expand Down Expand Up @@ -29,4 +31,18 @@ struct DmaQueueEntry {
u32 num_isobuffered_chunks = 0;
};
void dma_intr_hack();

struct OverlordStreamMemory {
struct Info {
SoundStreamName name;
int idx = 0;
};
Info infos[6][2];

OverlordStreamMemory();
void update_name(const char* input, int stream, int side);
};

extern OverlordStreamMemory g_overlord_stream_memory;

} // namespace jak3
8 changes: 7 additions & 1 deletion goal_src/jak3/pc/pckernel.gc
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,13 @@
)

(defmethod get-game-language ((obj pc-settings-jak3))
(get-current-language)
;; if the language is unintialized, return the default
(let ((lang (get-current-language)))
(if (= lang 255)
(scf-get-language)
lang
)
)
)


Expand Down

0 comments on commit 266b423

Please sign in to comment.