From 220fb1a196ac960f8265224ae8944c4e5738a844 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 28 May 2022 21:39:47 +0300 Subject: [PATCH 1/3] Decompile interface font byte swap functions See #17 --- src/font_manager.cc | 51 ++++++++++++++++++++++++++++++++++++++------- src/font_manager.h | 4 ++++ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/font_manager.cc b/src/font_manager.cc index fc69afc..e3fd510 100644 --- a/src/font_manager.cc +++ b/src/font_manager.cc @@ -94,32 +94,32 @@ int interfaceFontLoad(int font_index) int sig; if (fileRead(&sig, 4, 1, stream) != 1) goto err; - sig = _byteswap_ulong(sig); + interfaceFontByteSwapInt32(&sig); if (sig != 0x41414646) goto err; if (fileRead(&(fontDescriptor->field_0), 2, 1, stream) != 1) goto err; - fontDescriptor->field_0 = _byteswap_ushort(fontDescriptor->field_0); + interfaceFontByteSwapInt16(&(fontDescriptor->field_0)); if (fileRead(&(fontDescriptor->letterSpacing), 2, 1, stream) != 1) goto err; - fontDescriptor->letterSpacing = _byteswap_ushort(fontDescriptor->letterSpacing); + interfaceFontByteSwapInt16(&(fontDescriptor->letterSpacing)); if (fileRead(&(fontDescriptor->wordSpacing), 2, 1, stream) != 1) goto err; - fontDescriptor->wordSpacing = _byteswap_ushort(fontDescriptor->wordSpacing); + interfaceFontByteSwapInt16(&(fontDescriptor->wordSpacing)); if (fileRead(&(fontDescriptor->field_6), 2, 1, stream) != 1) goto err; - fontDescriptor->field_6 = _byteswap_ushort(fontDescriptor->field_6); + interfaceFontByteSwapInt16(&(fontDescriptor->field_6)); for (int index = 0; index < 256; index++) { InterfaceFontGlyph* glyph = &(fontDescriptor->glyphs[index]); if (fileRead(&(glyph->width), 2, 1, stream) != 1) goto err; - glyph->width = _byteswap_ushort(glyph->width); + interfaceFontByteSwapInt16(&(glyph->width)); if (fileRead(&(glyph->field_2), 2, 1, stream) != 1) goto err; - glyph->field_2 = _byteswap_ushort(glyph->field_2); + interfaceFontByteSwapInt16(&(glyph->field_2)); if (fileRead(&(glyph->field_4), 4, 1, stream) != 1) goto err; - glyph->field_4 = _byteswap_ulong(glyph->field_4); + interfaceFontByteSwapInt32(&(glyph->field_4)); } fileSize -= sizeof(InterfaceFontDescriptor); @@ -335,3 +335,38 @@ void interfaceFontDrawImpl(unsigned char* buf, const char* string, int length, i _freeColorBlendTable(color & 0xFF); } + +// NOTE: Inlined. +// +// 0x442520 +void interfaceFontByteSwapUInt32(unsigned int* value) +{ + unsigned int swapped = *value; + unsigned short high = swapped >> 16; + // NOTE: Uninline. + interfaceFontByteSwapUInt16(&high); + unsigned short low = swapped & 0xFFFF; + // NOTE: Uninline. + interfaceFontByteSwapUInt16(&low); + *value = (low << 16) | high; +} + +// NOTE: 0x442520 with different signature. +void interfaceFontByteSwapInt32(int* value) +{ + interfaceFontByteSwapUInt32((unsigned int*)value); +} + +// 0x442568 +void interfaceFontByteSwapUInt16(unsigned short* value) +{ + unsigned short swapped = *value; + swapped = (swapped >> 8) | (swapped << 8); + *value = swapped; +} + +// NOTE: 0x442568 with different signature. +void interfaceFontByteSwapInt16(short* value) +{ + interfaceFontByteSwapUInt16((unsigned short*)value); +} diff --git a/src/font_manager.h b/src/font_manager.h index 42b1230..7720b4a 100644 --- a/src/font_manager.h +++ b/src/font_manager.h @@ -43,5 +43,9 @@ int interfaceFontGetLetterSpacingImpl(); int interfaceFontGetBufferSizeImpl(const char* string); int interfaceFontGetMonospacedCharacterWidthImpl(); void interfaceFontDrawImpl(unsigned char* buf, const char* string, int length, int pitch, int color); +void interfaceFontByteSwapUInt32(unsigned int* value); +void interfaceFontByteSwapInt32(int* value); +void interfaceFontByteSwapUInt16(unsigned short* value); +void interfaceFontByteSwapInt16(short* value); #endif /* FONT_MANAGER_H */ From 5ce83bc29debf4b05786a9848241c60e6f739775 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 28 May 2022 21:46:58 +0300 Subject: [PATCH 2/3] Reorganize includes --- src/core.cc | 1 + src/core.h | 1 - src/dinput.h | 2 -- src/text_object.cc | 2 ++ src/window_manager.cc | 1 + 5 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core.cc b/src/core.cc index 983aa7c..6807ee8 100644 --- a/src/core.cc +++ b/src/core.cc @@ -8,6 +8,7 @@ #include "memory.h" #include "mmx.h" #include "text_font.h" +#include "win32.h" #include "window_manager.h" #include "window_manager_private.h" diff --git a/src/core.h b/src/core.h index 04dd262..38b877f 100644 --- a/src/core.h +++ b/src/core.h @@ -465,7 +465,6 @@ extern InputEvent gInputEventQueue[40]; extern STRUCT_6ABF50 _GNW95_key_time_stamps[SDL_NUM_SCANCODES]; extern int _input_mx; extern int _input_my; -extern HHOOK _GNW95_keyboardHandle; extern bool gPaused; extern int gScreenshotKeyCode; extern int _using_msec_timer; diff --git a/src/dinput.h b/src/dinput.h index 299b3b7..113e998 100644 --- a/src/dinput.h +++ b/src/dinput.h @@ -1,8 +1,6 @@ #ifndef DINPUT_H #define DINPUT_H -#include "win32.h" - typedef struct MouseData { int x; int y; diff --git a/src/text_object.cc b/src/text_object.cc index 39c749b..31e2b5d 100644 --- a/src/text_object.cc +++ b/src/text_object.cc @@ -10,6 +10,8 @@ #include "tile.h" #include "word_wrap.h" +#include + // 0x51D944 int gTextObjectsCount = 0; diff --git a/src/window_manager.cc b/src/window_manager.cc index e4d55b5..d4c20cf 100644 --- a/src/window_manager.cc +++ b/src/window_manager.cc @@ -8,6 +8,7 @@ #include "memory.h" #include "palette.h" #include "text_font.h" +#include "win32.h" #include "window_manager_private.h" #include From 442e0a17ab8bba2fa5be1072c3b317d3ec4fa068 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sat, 28 May 2022 23:17:48 +0300 Subject: [PATCH 3/3] Provide splitpath/makepath compatibility layer See #17 --- src/db.cc | 8 +++--- src/platform_compat.cc | 55 ++++++++++++++++++++++++++++++++++++++++++ src/platform_compat.h | 7 ++++++ src/xfile.cc | 30 +++++++++++------------ 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/db.cc b/src/db.cc index 7964cad..b00d767 100644 --- a/src/db.cc +++ b/src/db.cc @@ -635,10 +635,10 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a for (int index = 0; index < fileNamesLength; index += 1) { const char* name = xlist->fileNames[index]; - char dir[_MAX_DIR]; - char fileName[_MAX_FNAME]; - char extension[_MAX_EXT]; - _splitpath(name, NULL, dir, fileName, extension); + char dir[COMPAT_MAX_DIR]; + char fileName[COMPAT_MAX_FNAME]; + char extension[COMPAT_MAX_EXT]; + compat_splitpath(name, NULL, dir, fileName, extension); bool v2 = false; if (v1) { diff --git a/src/platform_compat.cc b/src/platform_compat.cc index 67adaf4..7429292 100644 --- a/src/platform_compat.cc +++ b/src/platform_compat.cc @@ -1,6 +1,9 @@ #include "platform_compat.h" #include +#include + +#include int compat_stricmp(const char* string1, const char* string2) { @@ -26,3 +29,55 @@ char* compat_itoa(int value, char* buffer, int radix) { return SDL_itoa(value, buffer, radix); } + +void compat_splitpath(const char* path, char* drive, char* dir, char* fname, char* ext) +{ +#if defined(_WIN32) + _splitpath(path, drive, dir, fname, ext); +#else + std::filesystem::path p(path); + + if (drive != NULL) { + strcpy(drive, p.root_name().string().substr(0, COMPAT_MAX_DRIVE - 1).c_str()); + } + + if (dir != NULL) { + strcpy(dir, p.parent_path().string().substr(0, COMPAT_MAX_DIR - 1).c_str()); + } + + if (fname != NULL) { + strcpy(fname, p.stem().string().substr(0, COMPAT_MAX_FNAME - 1).c_str()); + } + + if (ext != NULL) { + strcpy(ext, p.extension().string().substr(0, COMPAT_MAX_EXT - 1).c_str()); + } +#endif +} + +void compat_makepath(char* path, const char* drive, const char* dir, const char* fname, const char* ext) +{ +#if defined(_WIN32) + _makepath(path, drive, dir, fname, ext); +#else + std::filesystem::path p; + + if (drive != NULL) { + p.append(drive); + } + + if (dir != NULL) { + p.append(dir); + } + + if (fname != NULL) { + p.append(fname); + } + + if (ext != NULL) { + p.replace_extension(ext); + } + + strcpy(path, p.string().substr(0, COMPAT_MAX_PATH - 1).c_str()); +#endif +} diff --git a/src/platform_compat.h b/src/platform_compat.h index 8154913..a46bfd7 100644 --- a/src/platform_compat.h +++ b/src/platform_compat.h @@ -12,10 +12,17 @@ // represent paths across the codebase. #define COMPAT_MAX_PATH 260 +#define COMPAT_MAX_DRIVE 3 +#define COMPAT_MAX_DIR 256 +#define COMPAT_MAX_FNAME 256 +#define COMPAT_MAX_EXT 256 + int compat_stricmp(const char* string1, const char* string2); int compat_strnicmp(const char* string1, const char* string2, size_t size); char* compat_strupr(char* string); char* compat_strlwr(char* string); char* compat_itoa(int value, char* buffer, int radix); +void compat_splitpath(const char* path, char* drive, char* dir, char* fname, char* ext); +void compat_makepath(char* path, const char* drive, const char* dir, const char* fname, const char* ext); #endif /* PLATFORM_COMPAT_H */ diff --git a/src/xfile.cc b/src/xfile.cc index ed667ae..5524b91 100644 --- a/src/xfile.cc +++ b/src/xfile.cc @@ -55,9 +55,9 @@ XFile* xfileOpen(const char* filePath, const char* mode) memset(stream, 0, sizeof(*stream)); // NOTE: Compiled code uses different lengths. - char drive[_MAX_DRIVE]; - char dir[_MAX_DIR]; - _splitpath(filePath, drive, dir, NULL, NULL); + char drive[COMPAT_MAX_DRIVE]; + char dir[COMPAT_MAX_DIR]; + compat_splitpath(filePath, drive, dir, NULL, NULL); char path[COMPAT_MAX_PATH]; if (drive[0] != '\0' || dir[0] == '\\' || dir[0] == '/' || dir[0] == '.') { @@ -541,11 +541,11 @@ bool xlistEnumerate(const char* pattern, XListEnumerationHandler* handler, XList context.xlist = xlist; - char drive[_MAX_DRIVE]; - char dir[_MAX_DIR]; - char fileName[_MAX_FNAME]; - char extension[_MAX_EXT]; - _splitpath(pattern, drive, dir, fileName, extension); + char drive[COMPAT_MAX_DRIVE]; + char dir[COMPAT_MAX_DIR]; + char fileName[COMPAT_MAX_FNAME]; + char extension[COMPAT_MAX_EXT]; + compat_splitpath(pattern, drive, dir, fileName, extension); if (drive[0] != '\0' || dir[0] == '\\' || dir[0] == '/' || dir[0] == '.') { if (fileFindFirst(pattern, &directoryFileFindData)) { do { @@ -562,7 +562,7 @@ bool xlistEnumerate(const char* pattern, XListEnumerationHandler* handler, XList context.type = XFILE_ENUMERATION_ENTRY_TYPE_FILE; } - _makepath(context.name, drive, dir, entryName, NULL); + compat_makepath(context.name, drive, dir, entryName, NULL); if (!handler(&context)) { break; @@ -607,7 +607,7 @@ bool xlistEnumerate(const char* pattern, XListEnumerationHandler* handler, XList context.type = XFILE_ENUMERATION_ENTRY_TYPE_FILE; } - _makepath(context.name, drive, dir, entryName, NULL); + compat_makepath(context.name, drive, dir, entryName, NULL); if (!handler(&context)) { break; @@ -619,7 +619,7 @@ bool xlistEnumerate(const char* pattern, XListEnumerationHandler* handler, XList xbase = xbase->next; } - _splitpath(pattern, drive, dir, fileName, extension); + compat_splitpath(pattern, drive, dir, fileName, extension); if (fileFindFirst(pattern, &directoryFileFindData)) { do { bool isDirectory = fileFindIsDirectory(&directoryFileFindData); @@ -635,7 +635,7 @@ bool xlistEnumerate(const char* pattern, XListEnumerationHandler* handler, XList context.type = XFILE_ENUMERATION_ENTRY_TYPE_FILE; } - _makepath(context.name, drive, dir, entryName, NULL); + compat_makepath(context.name, drive, dir, entryName, NULL); if (!handler(&context)) { break; @@ -678,9 +678,9 @@ int xbaseMakeDirectory(const char* filePath) return -1; } - char drive[_MAX_DRIVE]; - char dir[_MAX_DIR]; - _splitpath(filePath, drive, dir, NULL, NULL); + char drive[COMPAT_MAX_DRIVE]; + char dir[COMPAT_MAX_DIR]; + compat_splitpath(filePath, drive, dir, NULL, NULL); char path[COMPAT_MAX_PATH]; if (drive[0] != '\0' || dir[0] == '\\' || dir[0] == '/' || dir[0] == '.') {