diff --git a/src/audio_file.cc b/src/audio_file.cc index d9001de..d4a507d 100644 --- a/src/audio_file.cc +++ b/src/audio_file.cc @@ -6,7 +6,6 @@ #include "sound.h" #include -#include #include #include @@ -100,7 +99,7 @@ int audioFileOpen(const char* fname, int flags, ...) audioFile->soundDecoder = soundDecoderInit(audioFileSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->field_14), &(audioFile->field_10), &(audioFile->fileSize)); audioFile->fileSize *= 2; } else { - audioFile->fileSize = filelength(fileno(stream)); + audioFile->fileSize = compat_filelength(fileno(stream)); } audioFile->position = 0; diff --git a/src/cache.cc b/src/cache.cc index e6ed0b3..e2c77f3 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -5,6 +5,7 @@ #include "sound.h" #include +#include // qsort #include #include 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/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/dfile.cc b/src/dfile.cc index 2332c46..9d71446 100644 --- a/src/dfile.cc +++ b/src/dfile.cc @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -32,7 +31,7 @@ DBase* dbaseOpen(const char* filePath) // Get file size, and reposition stream to read footer, which contains two // 32-bits ints. - int fileSize = filelength(fileno(stream)); + int fileSize = compat_filelength(fileno(stream)); if (fseek(stream, fileSize - sizeof(int) * 2, SEEK_SET) != 0) { goto err; } 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/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 */ diff --git a/src/game.cc b/src/game.cc index eeeb359..1cc632f 100644 --- a/src/game.cc +++ b/src/game.cc @@ -56,7 +56,12 @@ #include "window_manager.h" #include "world_map.h" +#ifdef _WIN32 #include +#else +#include // access +#endif + #include #define HELP_SCREEN_WIDTH (640) diff --git a/src/heap.cc b/src/heap.cc index 9028f7a..3bd9de3 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -227,6 +227,11 @@ bool heapHandleListInit(Heap* heap) // 0x452AD0 bool heapBlockAllocate(Heap* heap, int* handleIndexPtr, int size, int a4) { + HeapBlockHeader* blockHeader; + int state; + int blockSize; + HeapHandle* handle; + if (heap == NULL || handleIndexPtr == NULL || size == 0) { goto err; } @@ -240,16 +245,16 @@ bool heapBlockAllocate(Heap* heap, int* handleIndexPtr, int size, int a4) goto err; } - HeapBlockHeader* blockHeader = (HeapBlockHeader*)block; - int state = blockHeader->state; + blockHeader = (HeapBlockHeader*)block; + state = blockHeader->state; int handleIndex; if (!heapFindFreeHandle(heap, &handleIndex)) { goto err_no_handle; } - int blockSize = blockHeader->size; - HeapHandle* handle = &(heap->handles[handleIndex]); + blockSize = blockHeader->size; + handle = &(heap->handles[handleIndex]); if (state == HEAP_BLOCK_STATE_SYSTEM) { // Bind block to handle. @@ -591,6 +596,14 @@ bool heapFindFreeHandle(Heap* heap, int* handleIndexPtr) // 0x453588 bool heapFindFreeBlock(Heap* heap, int size, void** blockPtr, int a4) { + unsigned char* biggestFreeBlock; + HeapBlockHeader* biggestFreeBlockHeader; + int biggestFreeBlockSize; + HeapMoveableExtent* extent; + int reservedFreeBlockIndex; + HeapBlockHeader* blockHeader; + HeapBlockFooter* blockFooter; + if (!heapBuildFreeBlocksList(heap)) { goto system; } @@ -604,9 +617,9 @@ bool heapFindFreeBlock(Heap* heap, int size, void** blockPtr, int a4) } // Take last free block (the biggest one). - unsigned char* biggestFreeBlock = gHeapFreeBlocks[heap->freeBlocks - 1]; - HeapBlockHeader* biggestFreeBlockHeader = (HeapBlockHeader*)biggestFreeBlock; - int biggestFreeBlockSize = biggestFreeBlockHeader->size; + biggestFreeBlock = gHeapFreeBlocks[heap->freeBlocks - 1]; + biggestFreeBlockHeader = (HeapBlockHeader*)biggestFreeBlock; + biggestFreeBlockSize = biggestFreeBlockHeader->size; // Make sure it can encompass new block of given size. if (biggestFreeBlockSize >= size) { @@ -753,8 +766,8 @@ bool heapFindFreeBlock(Heap* heap, int size, void** blockPtr, int a4) goto system; } - HeapMoveableExtent* extent = &(gHeapMoveableExtents[extentIndex]); - int reservedFreeBlockIndex = 0; + extent = &(gHeapMoveableExtents[extentIndex]); + reservedFreeBlockIndex = 0; for (int moveableBlockIndex = 0; moveableBlockIndex < extent->moveableBlocksLength; moveableBlockIndex++) { unsigned char* moveableBlock = gHeapMoveableBlocks[moveableBlockIndex]; HeapBlockHeader* moveableBlockHeader = (HeapBlockHeader*)moveableBlock; @@ -807,13 +820,13 @@ bool heapFindFreeBlock(Heap* heap, int size, void** blockPtr, int a4) heap->freeSize += (extent->blocksLength - 1) * HEAP_BLOCK_OVERHEAD_SIZE; // Create one free block from entire moveable extent. - HeapBlockHeader* blockHeader = (HeapBlockHeader*)extent->data; + blockHeader = (HeapBlockHeader*)extent->data; blockHeader->guard = HEAP_BLOCK_HEADER_GUARD; blockHeader->size = extent->size + (extent->blocksLength - 1) * HEAP_BLOCK_OVERHEAD_SIZE; blockHeader->state = HEAP_BLOCK_STATE_FREE; blockHeader->handle_index = -1; - HeapBlockFooter* blockFooter = (HeapBlockFooter*)(extent->data + blockHeader->size + HEAP_BLOCK_HEADER_SIZE); + blockFooter = (HeapBlockFooter*)(extent->data + blockHeader->size + HEAP_BLOCK_HEADER_SIZE); blockFooter->guard = HEAP_BLOCK_FOOTER_GUARD; *blockPtr = extent->data; diff --git a/src/movie_effect.cc b/src/movie_effect.cc index 807310e..fc6ce73 100644 --- a/src/movie_effect.cc +++ b/src/movie_effect.cc @@ -103,6 +103,8 @@ int movieEffectsLoad(const char* filePath) strcpy(path + strlen(path), ".cfg"); + int* movieEffectFrameList; + if (!configRead(&config, path, true)) { goto out; } @@ -112,7 +114,7 @@ int movieEffectsLoad(const char* filePath) goto out; } - int* movieEffectFrameList = (int*)internal_malloc(sizeof(*movieEffectFrameList) * movieEffectsLength); + movieEffectFrameList = (int*)internal_malloc(sizeof(*movieEffectFrameList) * movieEffectsLength); if (movieEffectFrameList == NULL) { goto out; } diff --git a/src/platform_compat.cc b/src/platform_compat.cc index 67adaf4..2b9623f 100644 --- a/src/platform_compat.cc +++ b/src/platform_compat.cc @@ -1,6 +1,16 @@ #include "platform_compat.h" #include +#include + +#include + +#ifdef _WIN32 +#include +#include +#else +#include +#endif int compat_stricmp(const char* string1, const char* string2) { @@ -26,3 +36,64 @@ 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 +} + +long compat_filelength(int fd) +{ + long originalOffset = lseek(fd, 0, SEEK_CUR); + lseek(fd, 0, SEEK_SET); + long filesize = lseek(fd, 0, SEEK_END); + lseek(fd, originalOffset, SEEK_SET); + return filesize; +} diff --git a/src/platform_compat.h b/src/platform_compat.h index 8154913..1b63744 100644 --- a/src/platform_compat.h +++ b/src/platform_compat.h @@ -12,10 +12,18 @@ // 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); +long compat_filelength(int fd); #endif /* PLATFORM_COMPAT_H */ diff --git a/src/sound.cc b/src/sound.cc index 00ec98f..6718ccb 100644 --- a/src/sound.cc +++ b/src/sound.cc @@ -2,6 +2,7 @@ #include "debug.h" #include "memory.h" +#include "platform_compat.h" #include #include @@ -37,7 +38,7 @@ SoundFileIO gSoundDefaultFileIO = { write, lseek, tell, - filelength, + compat_filelength, -1, }; diff --git a/src/text_font.cc b/src/text_font.cc index e9facec..cd43447 100644 --- a/src/text_font.cc +++ b/src/text_font.cc @@ -120,6 +120,7 @@ int textFontLoad(int font) textFontDescriptor->glyphs = NULL; File* stream = fileOpen(path, "rb"); + int dataSize; if (stream == NULL) { goto out; } @@ -137,7 +138,7 @@ int textFontLoad(int font) goto out; } - int dataSize = textFontDescriptor->lineHeight * ((textFontDescriptor->glyphs[textFontDescriptor->glyphCount - 1].width + 7) >> 3) + textFontDescriptor->glyphs[textFontDescriptor->glyphCount - 1].dataOffset; + dataSize = textFontDescriptor->lineHeight * ((textFontDescriptor->glyphs[textFontDescriptor->glyphCount - 1].width + 7) >> 3) + textFontDescriptor->glyphs[textFontDescriptor->glyphCount - 1].dataOffset; textFontDescriptor->data = (unsigned char*)internal_malloc(dataSize); if (textFontDescriptor->data == NULL) { goto out; 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 diff --git a/src/xfile.cc b/src/xfile.cc index ed667ae..3a2f6e3 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] == '.') { @@ -418,7 +418,7 @@ long xfileGetSize(XFile* stream) fileSize = 0; break; default: - fileSize = filelength(fileno(stream->file)); + fileSize = compat_filelength(fileno(stream->file)); break; } @@ -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] == '.') {