diff --git a/core/hw/modem/modem.cpp b/core/hw/modem/modem.cpp index e1242ae8d..c11f473c2 100644 --- a/core/hw/modem/modem.cpp +++ b/core/hw/modem/modem.cpp @@ -740,3 +740,26 @@ void ModemWriteMem_A0_006(u32 addr, u32 data, u32 size) LOG("modem reg %03X write %X -- wtf is it?",reg,data); } + +void ModemSerialize(void **data, unsigned int *total_size) +{ + REICAST_S(modem_regs); + REICAST_S(dspram); + REICAST_S(state); + REICAST_S(connect_state); + REICAST_S(last_dial_time); + REICAST_S(data_sent); +} + +void ModemDeserialize(void **data, unsigned int *total_size, serialize_version_enum version) +{ + if (version >= V20) + { + REICAST_US(modem_regs); + REICAST_US(dspram); + REICAST_US(state); + REICAST_US(connect_state); + REICAST_US(last_dial_time); + REICAST_US(data_sent); + } +} diff --git a/core/hw/modem/modem.h b/core/hw/modem/modem.h index 32a72cc60..4563b288f 100644 --- a/core/hw/modem/modem.h +++ b/core/hw/modem/modem.h @@ -28,3 +28,5 @@ void ModemInit(); void ModemTerm(); u32 ModemReadMem_A0_006(u32 addr,u32 size); void ModemWriteMem_A0_006(u32 addr,u32 data,u32 size); +void ModemSerialize(void **data, unsigned int *total_size); +void ModemDeserialize(void **data, unsigned int *total_size, serialize_version_enum version); diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp index ed711de6f..74bed2d4c 100644 --- a/core/hw/naomi/naomi.cpp +++ b/core/hw/naomi/naomi.cpp @@ -678,6 +678,9 @@ void naomi_Serialize(void **data, unsigned int *total_size) REICAST_S(reg_dimm_parameterh); REICAST_S(reg_dimm_status); REICAST_S(aw_maple_devs); + REICAST_S(coin_chute_time); + REICAST_S(aw_ram_test_skipped); + // TODO serialize m3comm? } void naomi_Unserialize(void **data, unsigned int *total_size, serialize_version_enum version) @@ -709,5 +712,9 @@ void naomi_Unserialize(void **data, unsigned int *total_size, serialize_version_ REICAST_SKIP(1); // NaomiDataRead else if (version >= V14) REICAST_US(aw_maple_devs); - + if (version >= V20) + { + REICAST_US(coin_chute_time); + REICAST_US(aw_ram_test_skipped); + } } diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index 12ef4e2fb..3f9784602 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -380,9 +380,9 @@ void rend_start_render() ctx->rend.fog_clamp_max = FOG_CLAMP_MAX; } + palette_update(); if (QueueRender(ctx)) { - palette_update(); pend_rend = true; if (!config::ThreadedRendering) rend_single_frame(true); @@ -488,3 +488,27 @@ void rend_start_rollback() { vramRollback.Wait(); } + +void rend_serialize(void **data, unsigned int *total_size) +{ + REICAST_S(fb_w_cur); + REICAST_S(render_called); + REICAST_S(fb_dirty); + REICAST_S(fb_watch_addr_start); + REICAST_S(fb_watch_addr_end); +} + +void rend_deserialize(void **data, unsigned int *total_size, serialize_version_enum version) +{ + if ((version >= V12_LIBRETRO && version < V5) || version >= V12) + REICAST_US(fb_w_cur); + else + fb_w_cur = 1; + if (version >= V20) + { + REICAST_US(render_called); + REICAST_US(fb_dirty); + REICAST_US(fb_watch_addr_start); + REICAST_US(fb_watch_addr_end); + } +} diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index 0ffc9b9c5..4e19b9863 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -18,6 +18,8 @@ void rend_reset(); void rend_disable_rollback(); void rend_start_rollback(); void rend_allow_rollback(); +void rend_serialize(void **data, unsigned int *total_size); +void rend_deserialize(void **data, unsigned int *total_size, serialize_version_enum version); /////// extern TA_context* _pvrrc; diff --git a/core/hw/pvr/ta_ctx.cpp b/core/hw/pvr/ta_ctx.cpp index 9411bb4ca..768a1dae1 100644 --- a/core/hw/pvr/ta_ctx.cpp +++ b/core/hw/pvr/ta_ctx.cpp @@ -73,7 +73,6 @@ void SetCurrentTARC(u32 addr) } } -static std::mutex mtx_rqueue; TA_context* rqueue; cResetEvent frame_finished; @@ -105,45 +104,31 @@ bool QueueRender(TA_context* ctx) // disable net rollbacks until the render thread has processed the frame rend_disable_rollback(); frame_finished.Reset(); - mtx_rqueue.lock(); - TA_context* old = rqueue; - rqueue=ctx; - mtx_rqueue.unlock(); + verify(rqueue == nullptr); + rqueue = ctx; - verify(!old); return true; } TA_context* DequeueRender() { - mtx_rqueue.lock(); - TA_context* rv = rqueue; - mtx_rqueue.unlock(); - - if (rv) + if (rqueue != nullptr) FrameCount++; - return rv; + return rqueue; } bool rend_framePending() { - mtx_rqueue.lock(); - TA_context* rv = rqueue; - mtx_rqueue.unlock(); - - return rv != 0; + return rqueue != nullptr; } void FinishRender(TA_context* ctx) { - if (ctx != NULL) + if (ctx != nullptr) { verify(rqueue == ctx); - mtx_rqueue.lock(); - rqueue = NULL; - mtx_rqueue.unlock(); - + rqueue = nullptr; tactx_Recycle(ctx); } frame_finished.Set(); @@ -256,54 +241,80 @@ void tactx_Term() const u32 NULL_CONTEXT = ~0u; -void SerializeTAContext(void **data, unsigned int *total_size) +static void serializeContext(void **data, unsigned int *total_size, const TA_context *ctx) { - if (ta_ctx == nullptr) + if (ctx == nullptr) { REICAST_S(NULL_CONTEXT); return; } - REICAST_S(ta_ctx->Address); - const u32 taSize = ta_tad.thd_data - ta_tad.thd_root; + REICAST_S(ctx->Address); + const tad_context& tad = ctx == ::ta_ctx ? ta_tad : ctx->tad; + const u32 taSize = tad.thd_data - tad.thd_root; REICAST_S(taSize); if (*data == nullptr) { // Maximum size - REICAST_SKIP(TA_DATA_SIZE + 4 + ARRAY_SIZE(ta_tad.render_passes) * 4); + REICAST_SKIP(TA_DATA_SIZE + 4 + ARRAY_SIZE(tad.render_passes) * 4); return; } - REICAST_SA(ta_tad.thd_root, taSize); - REICAST_S(ta_tad.render_pass_count); - for (u32 i = 0; i < ta_tad.render_pass_count; i++) + REICAST_SA(tad.thd_root, taSize); + REICAST_S(tad.render_pass_count); + for (u32 i = 0; i < tad.render_pass_count; i++) { - u32 offset = (u32)(ta_tad.render_passes[i] - ta_tad.thd_root); + u32 offset = (u32)(tad.render_passes[i] - tad.thd_root); REICAST_S(offset); } } -void UnserializeTAContext(void **data, unsigned int *total_size, serialize_version_enum version) +static void deserializeContext(void **data, unsigned int *total_size, serialize_version_enum version, TA_context **pctx) { u32 address; REICAST_US(address); if (address == NULL_CONTEXT) + { + *pctx = nullptr; return; - SetCurrentTARC(address); + } + *pctx = tactx_Find(address, true); u32 size; REICAST_US(size); - REICAST_USA(ta_tad.thd_root, size); - ta_tad.thd_data = ta_tad.thd_root + size; + tad_context& tad = (*pctx)->tad; + REICAST_USA(tad.thd_root, size); + tad.thd_data = tad.thd_root + size; if (version >= V12 || (version >= V12_LIBRETRO && version < V5)) { - REICAST_US(ta_tad.render_pass_count); - for (u32 i = 0; i < ta_tad.render_pass_count; i++) + REICAST_US(tad.render_pass_count); + for (u32 i = 0; i < tad.render_pass_count; i++) { u32 offset; REICAST_US(offset); - ta_tad.render_passes[i] = ta_tad.thd_root + offset; + tad.render_passes[i] = tad.thd_root + offset; } } else { - ta_tad.render_pass_count = 0; + tad.render_pass_count = 0; } } + +void SerializeTAContext(void **data, unsigned int *total_size) +{ + serializeContext(data, total_size, ta_ctx); + if (TA_CURRENT_CTX != CORE_CURRENT_CTX) + serializeContext(data, total_size, tactx_Find(TA_CURRENT_CTX, false)); + else + serializeContext(data, total_size, nullptr); +} + +void UnserializeTAContext(void **data, unsigned int *total_size, serialize_version_enum version) +{ + if (::ta_ctx != nullptr) + SetCurrentTARC(TACTX_NONE); + TA_context *ta_cur_ctx; + deserializeContext(data, total_size, version, &ta_cur_ctx); + if (ta_cur_ctx != nullptr) + SetCurrentTARC(ta_cur_ctx->Address); + if (version >= V20) + deserializeContext(data, total_size, version, &ta_cur_ctx); +} diff --git a/core/serialize.cpp b/core/serialize.cpp index a0e2c5d4a..0760c276c 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -9,6 +9,7 @@ #include "hw/gdrom/gdromv3.h" #include "hw/gdrom/gdrom_if.h" #include "hw/maple/maple_cfg.h" +#include "hw/modem/modem.h" #include "hw/pvr/Renderer_if.h" #include "hw/pvr/pvr_mem.h" #include "hw/pvr/spg.h" @@ -341,8 +342,7 @@ bool dc_serialize(void **data, unsigned int *total_size, bool rollback) REICAST_SA(pvr_regs,pvr_RegSize); spg_Serialize(data, total_size); - - REICAST_S(fb_w_cur); + rend_serialize(data, total_size); REICAST_S(ta_fsm[2048]); REICAST_S(ta_fsm_cl); @@ -423,6 +423,7 @@ bool dc_serialize(void **data, unsigned int *total_size, bool rollback) REICAST_S(sch_list[modem_sched].start); REICAST_S(sch_list[modem_sched].end); } + ModemSerialize(data, total_size); REICAST_S(SCIF_SCFSR2); REICAST_S(SCIF_SCSCR2); @@ -616,10 +617,8 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size, seria REICAST_SKIP(4 * 256); // ta_type_lut REICAST_SKIP(2048); // ta_fsm } - if (version >= V12_LIBRETRO) - REICAST_US(fb_w_cur); - else - fb_w_cur = 1; + rend_deserialize(data, total_size, version); + REICAST_US(ta_fsm[2048]); REICAST_US(ta_fsm_cl); if (version < V9_LIBRETRO) @@ -1012,10 +1011,8 @@ bool dc_unserialize(void **data, unsigned int *total_size, bool rollback) REICAST_SKIP(4 * 256); REICAST_SKIP(2048); // ta_fsm } - if (version >= V12) - REICAST_US(fb_w_cur); - else - fb_w_cur = 1; + rend_deserialize(data, total_size, version); + REICAST_US(ta_fsm[2048]); REICAST_US(ta_fsm_cl); @@ -1131,6 +1128,7 @@ bool dc_unserialize(void **data, unsigned int *total_size, bool rollback) REICAST_US(sch_list[modem_sched].start); REICAST_US(sch_list[modem_sched].end); } + ModemDeserialize(data, total_size, version); REICAST_US(SCIF_SCFSR2); if (version < V8) diff --git a/core/types.h b/core/types.h index a1f6c818a..447310d8c 100644 --- a/core/types.h +++ b/core/types.h @@ -478,5 +478,6 @@ enum serialize_version_enum { V17 = 812, V18 = 813, V19 = 814, - VCUR_FLYCAST = V19, + V20 = 815, + VCUR_FLYCAST = V20, }; diff --git a/tests/src/serialize_test.cpp b/tests/src/serialize_test.cpp index fa4e2dbd7..d3598cc3a 100644 --- a/tests/src/serialize_test.cpp +++ b/tests/src/serialize_test.cpp @@ -31,7 +31,7 @@ TEST_F(SerializeTest, SizeTest) unsigned int total_size = 0; void *data = nullptr; ASSERT_TRUE(dc_serialize(&data, &total_size)); - ASSERT_EQ(28187891u, total_size); + ASSERT_EQ(28192084u, total_size); }