diff --git a/include/xsystem4.h b/include/xsystem4.h index ebd17c3..050f05f 100644 --- a/include/xsystem4.h +++ b/include/xsystem4.h @@ -47,8 +47,10 @@ extern struct config config; // text to printf-like functions const char *display_sjis0(const char *sjis); const char *display_sjis1(const char *sjis); +const char *display_sjis2(const char *sjis); const char *display_utf0(const char *utf); const char *display_utf1(const char *utf); +const char *display_utf2(const char *utf); char *unix_path(const char *path); char *gamedir_path(const char *path); diff --git a/src/debugger_scm.c b/src/debugger_scm.c index 42f28be..7aa9544 100644 --- a/src/debugger_scm.c +++ b/src/debugger_scm.c @@ -20,6 +20,7 @@ #include #include +#include "system4/ain.h" #include "system4/file.h" #include "system4/instructions.h" #include "system4/string.h" diff --git a/src/hll/StoatSpriteEngine.c b/src/hll/StoatSpriteEngine.c index e129cc9..5d4c8d4 100644 --- a/src/hll/StoatSpriteEngine.c +++ b/src/hll/StoatSpriteEngine.c @@ -25,6 +25,7 @@ #include "system4/utfsjis.h" #include "hll.h" +#include "iarray.h" #include "audio.h" #include "input.h" #include "queue.h" @@ -295,14 +296,20 @@ static int StoatSpriteEngine_Init(void *imain_system, int cg_cache_size) return 1; } +static void multisprite_clear(void) +{ + for (int t = 0; t < NR_SP_TYPES; t++) { + for (int no = 0; no < sp_types[t].nr_sprites; no++) { + multisprite_free(sp_types[t].sprites[no]); + sp_types[t].sprites[no] = NULL; + } + } +} + static void StoatSpriteEngine_ModuleFini(void) { sact_ModuleFini(); - for (int i = 0; i < NR_SP_TYPES; i++) { - for (int j = 0; j < sp_types[i].nr_sprites; j++) { - multisprite_free(sp_types[i].sprites[j]); - } - } + multisprite_clear(); } static void multisprite_update_pos(struct multisprite *ms) @@ -707,17 +714,130 @@ HLL_WARN_UNIMPLEMENTED( , void, StoatSpriteEngine, MultiSprite_Rebuild); static bool StoatSpriteEngine_MultiSprite_Encode(struct page **data) { - NOTICE("MultiSprite_Encode"); - union vm_value dim = { .i = 1 }; + struct iarray_writer out; + iarray_init_writer(&out, "MSP"); + + int nr_sprites = 0; + unsigned nr_sprites_pos = iarray_writer_pos(&out); + iarray_write(&out, 0); + + for (int t = 0; t < NR_SP_TYPES; t++) { + if (!sp_types[t].nr_sprites) + continue; + for (int no = 0; no < sp_types[t].nr_sprites; no++) { + struct multisprite *sp = sp_types[t].sprites[no]; + if (!sp) + continue; + iarray_write(&out, sp->type); + iarray_write(&out, sp->no); + iarray_write(&out, sp->z); + iarray_write(&out, sp->pos.x); + iarray_write(&out, sp->pos.y); + iarray_write(&out, sp->default_pos.x); + iarray_write(&out, sp->default_pos.y); + iarray_write(&out, sp->origin_mode); + iarray_write(&out, sp->alpha); + iarray_write(&out, sp->cg); + iarray_write(&out, sp->moving); + iarray_write(&out, sp->move.start.x); + iarray_write(&out, sp->move.start.y); + iarray_write(&out, sp->move.end.x); + iarray_write(&out, sp->move.end.y); + iarray_write(&out, sp->move.start_alpha); + iarray_write(&out, sp->move.end_alpha); + iarray_write(&out, sp->move.begin_wait_time); + iarray_write(&out, sp->move.time); + iarray_write_float(&out, sp->move.move_accel); + iarray_write(&out, sp->trans.no); + iarray_write(&out, sp->trans.time); + iarray_write(&out, sp->linked_message_frame); + iarray_write(&out, sp->tm.color.r); + iarray_write(&out, sp->tm.color.g); + iarray_write(&out, sp->tm.color.b); + iarray_write(&out, sp->tm.color.a); + iarray_write(&out, sp->tm.outline_color.r); + iarray_write(&out, sp->tm.outline_color.g); + iarray_write(&out, sp->tm.outline_color.b); + iarray_write(&out, sp->tm.outline_color.a); + iarray_write(&out, sp->tm.size); + iarray_write(&out, sp->tm.weight); + iarray_write(&out, sp->tm.face); + iarray_write(&out, sp->tm.outline_left); + iarray_write(&out, sp->tm.outline_up); + iarray_write(&out, sp->tm.outline_right); + iarray_write(&out, sp->tm.outline_down); + iarray_write(&out, sp->char_space); + nr_sprites++; + } + } + iarray_write_at(&out, nr_sprites_pos, nr_sprites); + if (*data) { delete_page_vars(*data); free_page(*data); } - *data = alloc_array(1, &dim, AIN_ARRAY_INT, 0, false); + *data = iarray_to_page(&out); + iarray_free_writer(&out); return true; } -HLL_WARN_UNIMPLEMENTED(true, bool, StoatSpriteEngine, MultiSprite_Decode, struct page **data); +static bool StoatSpriteEngine_MultiSprite_Decode(struct page **data) +{ + struct iarray_reader in; + if (!iarray_init_reader(&in, *data, "MSP")) { + WARNING("MultiSprite_Decode: invalid data"); + return false; + } + + multisprite_clear(); + + int nr_sprites = iarray_read(&in); + for (int i = 0; i < nr_sprites; i++) { + int type = iarray_read(&in); + int no = iarray_read(&in); + struct multisprite *sp = multisprite_get(type, no); + sp->z = iarray_read(&in); + sp->pos.x = iarray_read(&in); + sp->pos.y = iarray_read(&in); + sp->default_pos.x = iarray_read(&in); + sp->default_pos.y = iarray_read(&in); + sp->origin_mode = iarray_read(&in); + sp->alpha = iarray_read(&in); + sp->cg = iarray_read(&in); + sp->cg_dirty = true; + sp->moving = iarray_read(&in); + sp->move.start.x = iarray_read(&in); + sp->move.start.y = iarray_read(&in); + sp->move.end.x = iarray_read(&in); + sp->move.end.y = iarray_read(&in); + sp->move.start_alpha = iarray_read(&in); + sp->move.end_alpha = iarray_read(&in); + sp->move.begin_wait_time = iarray_read(&in); + sp->move.time = iarray_read(&in); + sp->move.move_accel = iarray_read_float(&in); + sp->trans.no = iarray_read(&in); + sp->trans.time = iarray_read(&in); + sp->linked_message_frame = iarray_read(&in); + sp->tm.color.r = iarray_read(&in); + sp->tm.color.g = iarray_read(&in); + sp->tm.color.b = iarray_read(&in); + sp->tm.color.a = iarray_read(&in); + sp->tm.outline_color.r = iarray_read(&in); + sp->tm.outline_color.g = iarray_read(&in); + sp->tm.outline_color.b = iarray_read(&in); + sp->tm.outline_color.a = iarray_read(&in); + sp->tm.size = iarray_read(&in); + sp->tm.weight = iarray_read(&in); + sp->tm.face = iarray_read(&in); + sp->tm.outline_left = iarray_read(&in); + sp->tm.outline_up = iarray_read(&in); + sp->tm.outline_right = iarray_read(&in); + sp->tm.outline_down = iarray_read(&in); + sp->char_space = iarray_read(&in); + } + + return !in.error; +} int StoatSpriteEngine_SYSTEM_IsResetOnce(void) { diff --git a/src/hll/iarray.c b/src/hll/iarray.c index 178e3e7..d55fc0f 100644 --- a/src/hll/iarray.c +++ b/src/hll/iarray.c @@ -61,6 +61,14 @@ void iarray_write(struct iarray_writer *w, int data) w->data[w->size++] = data; } + +void iarray_write_at(struct iarray_writer *w, unsigned pos, int data) +{ + if (pos >= w->size) + VM_ERROR("iarray_write_at: invalid index"); + w->data[pos] = data; +} + void iarray_write_float(struct iarray_writer *w, float data) { union { float f; int i; } cast = { .f = data }; diff --git a/src/hll/iarray.h b/src/hll/iarray.h index bfa7e39..3fb4eb2 100644 --- a/src/hll/iarray.h +++ b/src/hll/iarray.h @@ -34,11 +34,17 @@ struct iarray_writer { void iarray_init_writer(struct iarray_writer *w, const char *header); void iarray_free_writer(struct iarray_writer *w); void iarray_write(struct iarray_writer *w, int data); +void iarray_write_at(struct iarray_writer *w, unsigned pos, int data); void iarray_write_float(struct iarray_writer *w, float data); void iarray_write_string(struct iarray_writer *w, struct string *s); void iarray_write_struct(struct iarray_writer *w, struct page *page); void iarray_write_array(struct iarray_writer *w, struct page *page); +static inline unsigned iarray_writer_pos(struct iarray_writer *w) +{ + return w->size; +} + struct page *iarray_to_page(struct iarray_writer *w); struct iarray_reader { diff --git a/src/util.c b/src/util.c index 4c014d0..8e307ca 100644 --- a/src/util.c +++ b/src/util.c @@ -54,6 +54,18 @@ const char *display_sjis1(const char *sjis) #endif } +const char *display_sjis2(const char *sjis) +{ +#ifdef NATIVE_SJIS + return sjis; +#else + static char *utf = NULL; + free(utf); + utf = sjis2utf(sjis, 0); + return utf; +#endif +} + const char *display_utf0(const char *utf) { #ifdef NATIVE_SJIS @@ -78,6 +90,18 @@ const char *display_utf1(const char *utf) #endif } +const char *display_utf2(const char *utf) +{ +#ifdef NATIVE_SJIS + static char *sjis = NULL; + free(sjis); + sjis = utf2sjis(utf, 0); + return sjis; +#else + return utf; +#endif +} + char *unix_path(const char *path) { char *utf = sjis2utf(path, strlen(path));