diff --git a/src/hll/ACXLoader.c b/src/hll/ACXLoader.c index c2203fe..8983225 100644 --- a/src/hll/ACXLoader.c +++ b/src/hll/ACXLoader.c @@ -26,17 +26,50 @@ #include "vm/page.h" #include "xsystem4.h" +union acx_value { + int32_t i; + struct string *s; +}; + struct acx_file { int compressed_size; - int size; int nr_columns; int nr_lines; - uint8_t *data_raw; - uint8_t *data; + int32_t *column_types; + union acx_value *lines; }; static struct acx_file acx; +static void acx_read(uint8_t *data_raw) +{ + acx.nr_columns = LittleEndian_getDW(data_raw, 0); + acx.nr_lines = LittleEndian_getDW(data_raw, 4 + acx.nr_columns * 4); + uint8_t *data = data_raw + (8 + acx.nr_columns * 4); + + acx.column_types = xcalloc(acx.nr_columns, sizeof(int32_t)); + for (int i = 0; i < acx.nr_columns; i++) { + acx.column_types[i] = LittleEndian_getDW(data_raw, 4 + 4*i); + } + + int ptr = 0; + acx.lines = xcalloc(acx.nr_lines * acx.nr_columns, sizeof(union acx_value)); + for (int line = 0; line < acx.nr_lines; line++) { + for (int col = 0; col < acx.nr_columns; col++) { + if (acx.column_types[col] == 2) { + int old_ptr = ptr; + while (data[ptr]) + ptr++; + acx.lines[line*acx.nr_columns + col].s = make_string((char*)data+old_ptr, ptr-old_ptr); + ptr++; + } else { + acx.lines[line*acx.nr_columns + col].i = LittleEndian_getDW(data, ptr); + ptr += 4; + } + } + } +} + //bool Load(string pIFileName) bool ACXLoader_Load(struct string *filename) { @@ -68,28 +101,35 @@ bool ACXLoader_Load(struct string *filename) return false; } - acx.compressed_size = LittleEndian_getDW(buf, 8); - acx.size = LittleEndian_getDW(buf, 12); - acx.data_raw = xmalloc(acx.size); + int compressed_size = LittleEndian_getDW(buf, 8); + unsigned long size = LittleEndian_getDW(buf, 12); + uint8_t *data_raw = xmalloc(size); - unsigned long size = acx.size; - if (Z_OK != uncompress(acx.data_raw, &size, buf+16, len-16)) { + if (Z_OK != uncompress(data_raw, &size, buf+16, compressed_size)) { WARNING("ACXLoader.Load: uncompress failed"); free(buf); + free(data_raw); return false; } - acx.nr_columns = LittleEndian_getDW(acx.data_raw, 0); - acx.nr_lines = LittleEndian_getDW(acx.data_raw, 4 + acx.nr_columns * 4); - acx.data = acx.data_raw + (8 + acx.nr_columns * 4); + acx_read(data_raw); free(buf); + free(data_raw); return true; } void ACXLoader_Release(void) { - free(acx.data_raw); + for (int col = 0; col < acx.nr_columns; col++) { + if (acx.column_types[col] != 2) + continue; + for (int line = 0; line < acx.nr_lines; line++) { + free_string(acx.lines[line*acx.nr_columns+col].s); + } + } + free(acx.lines); + free(acx.column_types); memset(&acx, 0, sizeof(struct acx_file)); } @@ -105,17 +145,21 @@ int ACXLoader_GetNumofColumn(void) bool ACXLoader_GetDataInt(int line, int col, int *ptr) { - if (line < 0 || line >= acx.nr_lines || col < 0 || col >= acx.nr_columns) return false; - uint8_t *data = acx.data + (line * acx.nr_columns * 4) + (col * 4); - *ptr = LittleEndian_getDW(data, 0); - + *ptr = acx.lines[line*acx.nr_columns + col].i; return true; } -HLL_UNIMPLEMENTED(bool, ACXLoader, GetDataString, int line, int col, struct string *data); +bool ACXLoader_GetDataString(int line, int col, struct string **ptr) +{ + if (line < 0 || line >= acx.nr_lines || col < 0 || col >= acx.nr_columns) + return false; + + *ptr = string_ref(acx.lines[line*acx.nr_columns + col].s); + return true; +} bool ACXLoader_GetDataStruct(int line, struct page **page) { @@ -124,9 +168,12 @@ bool ACXLoader_GetDataStruct(int line, struct page **page) if (line >= acx.nr_lines) return false; - uint8_t *data = acx.data + (line * acx.nr_columns * 4); for (int i = 0; i < acx.nr_columns; i++) { - s[i].i = LittleEndian_getDW(data, i*4); + if (acx.column_types[i] == 2) { + s[i].i = vm_string_ref(acx.lines[line*acx.nr_columns + i].s); + } else { + s[i].i = acx.lines[line*acx.nr_columns + i].i; + } } return true; diff --git a/src/hll/Confirm2.c b/src/hll/Confirm2.c index 7ff24c6..3d0614a 100644 --- a/src/hll/Confirm2.c +++ b/src/hll/Confirm2.c @@ -14,6 +14,7 @@ * along with this program; if not, see . */ +#include "system4/string.h" #include "hll.h" HLL_WARN_UNIMPLEMENTED( , void, Confirm2, Init, void *imainsystem); @@ -21,8 +22,17 @@ HLL_WARN_UNIMPLEMENTED(1, int, Confirm2, ExistKeyFile, struct string *filename, HLL_UNIMPLEMENTED(int, Confirm2, CheckProtectFile, struct string *filename, int keynum); HLL_UNIMPLEMENTED(int, Confirm2, CreateKeyFile, struct string *filename, int keynum); + +void Confirm2_ExistKeyFile2(possibly_unused struct string *pIFileName, possibly_unused int nKeyNum, struct string **pIResult) +{ + // XXX: this is the magic value for Yokubori Saboten + // need to check if this works for other games + *pIResult = make_string("moke-", 5); +} + HLL_LIBRARY(Confirm2, HLL_EXPORT(Init, Confirm2_Init), HLL_EXPORT(ExistKeyFile, Confirm2_ExistKeyFile), HLL_EXPORT(CheckProtectFile, Confirm2_CheckProtectFile), - HLL_EXPORT(CreateKeyFile, Confirm2_CreateKeyFile)); + HLL_EXPORT(CreateKeyFile, Confirm2_CreateKeyFile), + HLL_EXPORT(ExistKeyFile2, Confirm2_ExistKeyFile2));