diff --git a/game/fake_iso.txt b/game/fake_iso.txt index 7316dfcb8..e6eeab6b9 100644 --- a/game/fake_iso.txt +++ b/game/fake_iso.txt @@ -10,5 +10,6 @@ TWEAKVAL.MUS resources/TWEAKVAL.MUS VAGDIR.AYB resources/VAGDIR.AYB SCREEN1.USA resources/SCREEN1.USA 0COMMON.TXT out/iso/0COMMON.TXT +5COMMON.TXT out/iso/5COMMON.TXT 0TEST.TXT out/iso/0TEST.TXT VI1.DGO out/iso/VI1.DGO \ No newline at end of file diff --git a/game/graphics/dma/gs.h b/game/graphics/dma/gs.h index 343176f16..f234bb157 100644 --- a/game/graphics/dma/gs.h +++ b/game/graphics/dma/gs.h @@ -250,7 +250,22 @@ struct GsTex0 { u32 tbp0() const { return data & 0b11'1111'1111'1111; } u32 tbw() const { return (data >> 14) & 0b111111; } - u32 psm() const { return (data >> 20) & 0b111111; } + enum class PSM { + PSMCT32 = 0, + PSMCT24 = 1, + PSMCT16 = 2, + PSMCT16S = 0b1010, + PSMT8 = 0b10011, + PSMT4 = 0b10100, + PSMT8H = 0b011011, + PSMT4HL = 0b100100, + PSMT4HH = 0b101100, + PSMZ32 = 0b110000, + PSMZ24 = 0b110001, + PSMZ16 = 0b110010, + PSMZ16S = 0b111010 + }; + PSM psm() const { return (PSM)((data >> 20) & 0b111111); } u32 tw() const { return (data >> 26) & 0b1111; } u32 th() const { return (data >> 30) & 0b1111; } enum class TextureFunction : u8 { diff --git a/game/graphics/gfx.cpp b/game/graphics/gfx.cpp index b8669be7e..f26655470 100644 --- a/game/graphics/gfx.cpp +++ b/game/graphics/gfx.cpp @@ -105,9 +105,9 @@ void texture_upload_now(const u8* tpage, int mode, u32 s7_ptr) { } } -void texture_relocate(u32 destination, u32 source) { +void texture_relocate(u32 destination, u32 source, u32 format) { if (g_settings.renderer) { - g_settings.renderer->texture_relocate(destination, source); + g_settings.renderer->texture_relocate(destination, source, format); } } diff --git a/game/graphics/gfx.h b/game/graphics/gfx.h index 1467ad903..985ed182c 100644 --- a/game/graphics/gfx.h +++ b/game/graphics/gfx.h @@ -29,7 +29,7 @@ struct GfxRendererModule { std::function sync_path; std::function send_chain; std::function texture_upload_now; - std::function texture_relocate; + std::function texture_relocate; GfxPipeline pipeline; const char* name; @@ -74,6 +74,6 @@ u32 vsync(); u32 sync_path(); void send_chain(const void* data, u32 offset); void texture_upload_now(const u8* tpage, int mode, u32 s7_ptr); -void texture_relocate(u32 destination, u32 source); +void texture_relocate(u32 destination, u32 source, u32 format); } // namespace Gfx diff --git a/game/graphics/opengl_renderer/DirectRenderer.cpp b/game/graphics/opengl_renderer/DirectRenderer.cpp index 0bcb603e4..c1f2ec873 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.cpp +++ b/game/graphics/opengl_renderer/DirectRenderer.cpp @@ -180,7 +180,12 @@ void DirectRenderer::upload_texture(TextureRecord* tex) { } void DirectRenderer::update_gl_texture(SharedRenderState* render_state) { - auto tex = render_state->texture_pool->lookup(m_texture_state.texture_base_ptr); + TextureRecord* tex = nullptr; + if (m_texture_state.using_mt4hh) { + tex = render_state->texture_pool->lookup_mt4hh(m_texture_state.texture_base_ptr); + } else { + tex = render_state->texture_pool->lookup(m_texture_state.texture_base_ptr); + } assert(tex); // fmt::print("Successful texture lookup! {} {}\n", tex->page_name, tex->name); @@ -475,6 +480,7 @@ void DirectRenderer::handle_tex0_1(u64 val, SharedRenderState* render_state) { if (m_texture_state.current_register != reg) { flush_pending(render_state); m_texture_state.texture_base_ptr = reg.tbp0(); + m_texture_state.using_mt4hh = reg.psm() == GsTex0::PSM::PSMT4HH; m_prim_gl_state_needs_gl_update = true; m_texture_state.current_register = reg; } diff --git a/game/graphics/opengl_renderer/DirectRenderer.h b/game/graphics/opengl_renderer/DirectRenderer.h index f8fd87dcb..b9848cb75 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.h +++ b/game/graphics/opengl_renderer/DirectRenderer.h @@ -120,6 +120,7 @@ class DirectRenderer : public BucketRenderer { struct TextureState { GsTex0 current_register; u32 texture_base_ptr = 0; + bool using_mt4hh = false; } m_texture_state; // state set through the prim/rgbaq register that doesn't require changing GL stuff diff --git a/game/graphics/pipelines/opengl.cpp b/game/graphics/pipelines/opengl.cpp index b89b49fb4..2f9c69cf4 100644 --- a/game/graphics/pipelines/opengl.cpp +++ b/game/graphics/pipelines/opengl.cpp @@ -257,9 +257,9 @@ void gl_texture_upload_now(const u8* tpage, int mode, u32 s7_ptr) { } } -void gl_texture_relocate(u32 destination, u32 source) { +void gl_texture_relocate(u32 destination, u32 source, u32 format) { if (g_gfx_data) { - g_gfx_data->texture_pool->relocate(destination, source); + g_gfx_data->texture_pool->relocate(destination, source, format); } } diff --git a/game/graphics/texture/TexturePool.cpp b/game/graphics/texture/TexturePool.cpp index 80b29adba..185f019e3 100644 --- a/game/graphics/texture/TexturePool.cpp +++ b/game/graphics/texture/TexturePool.cpp @@ -160,7 +160,11 @@ void TexturePool::handle_upload_now(const u8* tpage, int mode, const u8* memory_ tex_idx, tex_name, mip_idx), texture_record->data.data(), ww, hh); } - set_texture(tex.dest[mip_idx], std::move(texture_record)); + if (tex.psm == 44) { + set_mt4hh_texture(tex.dest[mip_idx], std::move(texture_record)); + } else { + set_texture(tex.dest[mip_idx], std::move(texture_record)); + } } } else { // texture was #f, skip it. @@ -174,23 +178,28 @@ void TexturePool::handle_upload_now(const u8* tpage, int mode, const u8* memory_ * Store a texture in the pool. Location is specified like TBP. */ void TexturePool::set_texture(u32 location, std::unique_ptr&& record) { - if (m_textures.at(location)) { - m_garbage_textures.push_back(std::move(m_textures[location])); + if (m_textures.at(location).normal_texture) { + m_garbage_textures.push_back(std::move(m_textures[location].normal_texture)); } - m_textures[location] = std::move(record); + m_textures[location].normal_texture = std::move(record); +} + +void TexturePool::set_mt4hh_texture(u32 location, std::unique_ptr&& record) { + if (m_textures.at(location).mt4hh_texture) { + m_garbage_textures.push_back(std::move(m_textures[location].mt4hh_texture)); + } + m_textures[location].mt4hh_texture = std::move(record); } /*! * Move a texture. */ -void TexturePool::relocate(u32 destination, u32 source) { - if (m_textures.at(source)) { - if (m_textures.at(destination)) { - return; // HACK - } - m_textures.at(destination) = std::move(m_textures.at(source)); - fmt::print("Relocated a texture: {}\n", m_textures[destination]->name); +void TexturePool::relocate(u32 destination, u32 source, u32 format) { + auto& src = m_textures.at(source).normal_texture; + assert(src); + if (format == 44) { + m_textures.at(destination).mt4hh_texture = std::move(src); } else { - assert(false); + m_textures.at(destination).normal_texture = std::move(src); } -} \ No newline at end of file +} diff --git a/game/graphics/texture/TexturePool.h b/game/graphics/texture/TexturePool.h index b65091e50..cc18334fa 100644 --- a/game/graphics/texture/TexturePool.h +++ b/game/graphics/texture/TexturePool.h @@ -17,25 +17,39 @@ struct TextureRecord { bool on_gpu = false; }; +struct TextureData { + std::unique_ptr normal_texture; + std::unique_ptr mt4hh_texture; +}; + class TexturePool { public: void handle_upload_now(const u8* tpage, int mode, const u8* memory_base, u32 s7_ptr); void set_texture(u32 location, std::unique_ptr&& record); + void set_mt4hh_texture(u32 location, std::unique_ptr&& record); TextureRecord* lookup(u32 location) { - if (m_textures.at(location)) { - return m_textures[location].get(); + if (m_textures.at(location).normal_texture) { + return m_textures[location].normal_texture.get(); } else { return nullptr; } } - void relocate(u32 destination, u32 source); + TextureRecord* lookup_mt4hh(u32 location) { + if (m_textures.at(location).mt4hh_texture) { + return m_textures[location].mt4hh_texture.get(); + } else { + return nullptr; + } + } + + void relocate(u32 destination, u32 source, u32 format); private: TextureConverter m_tex_converter; // uses tex.dest[mip] indexing. (bytes / 256). Currently only sets the base of a texture. - std::array, 1024 * 1024 * 4 / 256> m_textures; + std::array m_textures; // textures that the game overwrote, but may be still allocated on the GPU. // TODO: free these periodically. diff --git a/game/kernel/kboot.cpp b/game/kernel/kboot.cpp index 197c346e9..c7e6bbeb9 100644 --- a/game/kernel/kboot.cpp +++ b/game/kernel/kboot.cpp @@ -105,6 +105,9 @@ s32 goal_main(int argc, const char* const* argv) { masterConfig.language = (u16)Language::German; } else if (masterConfig.language == SCE_ITALIAN_LANGUAGE) { masterConfig.language = (u16)Language::Italian; + } else if (masterConfig.language == SCE_JAPANESE_LANGUAGE) { + // Note: this case was added so it is easier to test Japanese fonts. + masterConfig.language = (u16)Language::Japanese; } else { // pick english by default, if language is not supported. masterConfig.language = (u16)Language::English; diff --git a/game/kernel/kmachine.cpp b/game/kernel/kmachine.cpp index 63072850b..7743d90e5 100644 --- a/game/kernel/kmachine.cpp +++ b/game/kernel/kmachine.cpp @@ -449,8 +449,8 @@ void pc_texture_upload_now(u32 page, u32 mode) { Gfx::texture_upload_now(Ptr(page).c(), mode, s7.offset); } -void pc_texture_relocate(u32 dst, u32 src) { - Gfx::texture_relocate(dst, src); +void pc_texture_relocate(u32 dst, u32 src, u32 format) { + Gfx::texture_relocate(dst, src, format); } /*! diff --git a/goal_src/engine/gfx/texture.gc b/goal_src/engine/gfx/texture.gc index 696ebbbf8..92bd1b8e6 100644 --- a/goal_src/engine/gfx/texture.gc +++ b/goal_src/engine/gfx/texture.gc @@ -1809,7 +1809,7 @@ (#when PC_PORT ;; as far as I know this is only used for fonts which have 1 mip level. - (__pc-texture-relocate (/ dest-loc 64) (-> tex dest 0)) + (__pc-texture-relocate (/ dest-loc 64) (-> tex dest 0) dest-fmt) ) ;; loop over mips diff --git a/goal_src/kernel-defs.gc b/goal_src/kernel-defs.gc index b72d89652..1715ce523 100644 --- a/goal_src/kernel-defs.gc +++ b/goal_src/kernel-defs.gc @@ -183,7 +183,7 @@ (define-extern __mem-move (function pointer pointer uint none)) (define-extern __send-gfx-dma-chain (function object object none)) (define-extern __pc-texture-upload-now (function object object none)) -(define-extern __pc-texture-relocate (function object object none)) +(define-extern __pc-texture-relocate (function object object object none)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ksound - InitSoundScheme