Provide x64 compatibility (#62)

This commit is contained in:
Alexander Batalov 2022-07-05 11:00:55 +03:00 committed by GitHub
parent 599e8292f9
commit 8e1291b1d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1556 additions and 4598 deletions

View File

@ -238,6 +238,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/fps_limiter.h"
"src/platform_compat.cc"
"src/platform_compat.h"
"src/pointer_registry.cc"
"src/pointer_registry.h"
"src/sfall_config.cc"
"src/sfall_config.h"
)

View File

@ -21,6 +21,30 @@
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
},
{
"name": "x64-Debug",
"generator": "Visual Studio 16 2019 Win64",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": []
},
{
"name": "x64-Release",
"generator": "Visual Studio 16 2019 Win64",
"configurationType": "Release",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": []
}
]
}

View File

@ -3,6 +3,7 @@
#include "db.h"
#include "debug.h"
#include "memory_manager.h"
#include "pointer_registry.h"
#include "sound.h"
#include <assert.h>
@ -35,7 +36,7 @@ static bool _defaultCompressionFunc(char* filePath)
// 0x41A2D0
static int audioSoundDecoderReadHandler(int fileHandle, void* buffer, unsigned int size)
{
return fileRead(buffer, 1, size, (File*)fileHandle);
return fileRead(buffer, 1, size, (File*)intToPtr(fileHandle));
}
// AudioOpen
@ -97,7 +98,7 @@ int audioOpen(const char* fname, int flags, ...)
AudioFile* audioFile = &(gAudioList[index]);
audioFile->flags = AUDIO_FILE_IN_USE;
audioFile->fileHandle = (int)stream;
audioFile->fileHandle = ptrToInt(stream);
if (compression == 2) {
audioFile->flags |= AUDIO_FILE_COMPRESSED;
@ -116,7 +117,7 @@ int audioOpen(const char* fname, int flags, ...)
int audioClose(int fileHandle)
{
AudioFile* audioFile = &(gAudioList[fileHandle - 1]);
fileClose((File*)audioFile->fileHandle);
fileClose((File*)intToPtr(audioFile->fileHandle, true));
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
soundDecoderFree(audioFile->soundDecoder);
@ -136,7 +137,7 @@ int audioRead(int fileHandle, void* buffer, unsigned int size)
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
bytesRead = soundDecoderDecode(audioFile->soundDecoder, buffer, size);
} else {
bytesRead = fileRead(buffer, 1, size, (File*)audioFile->fileHandle);
bytesRead = fileRead(buffer, 1, size, (File*)intToPtr(audioFile->fileHandle));
}
audioFile->position += bytesRead;
@ -170,7 +171,7 @@ long audioSeek(int fileHandle, long offset, int origin)
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
if (pos < audioFile->position) {
soundDecoderFree(audioFile->soundDecoder);
fileSeek((File*)audioFile->fileHandle, 0, SEEK_SET);
fileSeek((File*)intToPtr(audioFile->fileHandle), 0, SEEK_SET);
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->field_14), &(audioFile->field_10), &(audioFile->fileSize));
audioFile->position = 0;
audioFile->fileSize *= 2;
@ -205,7 +206,7 @@ long audioSeek(int fileHandle, long offset, int origin)
return audioFile->position;
} else {
return fileSeek((File*)audioFile->fileHandle, offset, origin);
return fileSeek((File*)intToPtr(audioFile->fileHandle), offset, origin);
}
}

View File

@ -3,6 +3,7 @@
#include "debug.h"
#include "memory_manager.h"
#include "platform_compat.h"
#include "pointer_registry.h"
#include "sound.h"
#include <assert.h>
@ -35,7 +36,7 @@ static bool _defaultCompressionFunc__(char* filePath)
// 0x41A870
static int audioFileSoundDecoderReadHandler(int fileHandle, void* buffer, unsigned int size)
{
return fread(buffer, 1, size, (FILE*)fileHandle);
return fread(buffer, 1, size, (FILE*)intToPtr(fileHandle));
}
// 0x41A88C
@ -95,7 +96,7 @@ int audioFileOpen(const char* fname, int flags, ...)
AudioFile* audioFile = &(gAudioFileList[index]);
audioFile->flags = AUDIO_FILE_IN_USE;
audioFile->fileHandle = (int)stream;
audioFile->fileHandle = ptrToInt(stream);
if (compression == 2) {
audioFile->flags |= AUDIO_FILE_COMPRESSED;
@ -114,7 +115,7 @@ int audioFileOpen(const char* fname, int flags, ...)
int audioFileClose(int fileHandle)
{
AudioFile* audioFile = &(gAudioFileList[fileHandle - 1]);
fclose((FILE*)audioFile->fileHandle);
fclose((FILE*)intToPtr(audioFile->fileHandle, true));
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
soundDecoderFree(audioFile->soundDecoder);
@ -136,7 +137,7 @@ int audioFileRead(int fileHandle, void* buffer, unsigned int size)
if ((ptr->flags & AUDIO_FILE_COMPRESSED) != 0) {
bytesRead = soundDecoderDecode(ptr->soundDecoder, buffer, size);
} else {
bytesRead = fread(buffer, 1, size, (FILE*)ptr->fileHandle);
bytesRead = fread(buffer, 1, size, (FILE*)intToPtr(ptr->fileHandle));
}
ptr->position += bytesRead;
@ -171,7 +172,7 @@ long audioFileSeek(int fileHandle, long offset, int origin)
if (a4 <= audioFile->position) {
soundDecoderFree(audioFile->soundDecoder);
fseek((FILE*)audioFile->fileHandle, 0, 0);
fseek((FILE*)intToPtr(audioFile->fileHandle), 0, 0);
audioFile->soundDecoder = soundDecoderInit(audioFileSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->field_14), &(audioFile->field_10), &(audioFile->fileSize));
audioFile->fileSize *= 2;
@ -203,7 +204,7 @@ long audioFileSeek(int fileHandle, long offset, int origin)
return audioFile->position;
}
return fseek((FILE*)audioFile->fileHandle, offset, origin);
return fseek((FILE*)intToPtr(audioFile->fileHandle), offset, origin);
}
// 0x41AD20

View File

@ -10,11 +10,8 @@
typedef struct ExternalVariable {
char name[32];
char* programName;
opcode_t type;
union {
int value;
char* stringValue;
};
ProgramValue value;
char* stringValue;
} ExternalVariable;
typedef struct ExternalProcedure {
@ -172,47 +169,46 @@ ExternalVariable* externalVariableAdd(const char* identifier)
}
// 0x44127C
int externalVariableSetValue(Program* program, const char* name, opcode_t opcode, int data)
int externalVariableSetValue(Program* program, const char* name, ProgramValue& programValue)
{
ExternalVariable* exportedVariable = externalVariableFind(name);
if (exportedVariable == NULL) {
return 1;
}
if ((exportedVariable->type & 0xF7FF) == VALUE_TYPE_STRING) {
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 169
}
if ((opcode & 0xF7FF) == VALUE_TYPE_STRING) {
if ((programValue.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
if (program != NULL) {
const char* stringValue = programGetString(program, opcode, data);
exportedVariable->type = VALUE_TYPE_DYNAMIC_STRING;
const char* stringValue = programGetString(program, programValue.opcode, programValue.integerValue);
exportedVariable->value.opcode = VALUE_TYPE_DYNAMIC_STRING;
exportedVariable->stringValue = (char*)internal_malloc_safe(strlen(stringValue) + 1, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 175
strcpy(exportedVariable->stringValue, stringValue);
}
} else {
exportedVariable->value = data;
exportedVariable->type = opcode;
exportedVariable->value = programValue;
}
return 0;
}
// 0x4413D4
int externalVariableGetValue(Program* program, const char* name, opcode_t* opcodePtr, int* dataPtr)
int externalVariableGetValue(Program* program, const char* name, ProgramValue& value)
{
ExternalVariable* exportedVariable = externalVariableFind(name);
if (exportedVariable == NULL) {
return 1;
}
*opcodePtr = exportedVariable->type;
if ((exportedVariable->type & 0xF7FF) == VALUE_TYPE_STRING) {
*dataPtr = programPushString(program, exportedVariable->stringValue);
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
value.opcode = exportedVariable->value.opcode;
value.integerValue = programPushString(program, exportedVariable->stringValue);
} else {
*dataPtr = exportedVariable->value;
value = exportedVariable->value;
}
return 0;
@ -229,7 +225,7 @@ int externalVariableCreate(Program* program, const char* identifier)
return 1;
}
if ((exportedVariable->type & 0xF7FF) == VALUE_TYPE_STRING) {
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 234
}
} else {
@ -244,8 +240,8 @@ int externalVariableCreate(Program* program, const char* identifier)
strcpy(exportedVariable->programName, programName);
}
exportedVariable->type = VALUE_TYPE_INT;
exportedVariable->value = 0;
exportedVariable->value.opcode = VALUE_TYPE_INT;
exportedVariable->value.integerValue = 0;
return 0;
}
@ -278,7 +274,7 @@ void externalVariablesClear()
internal_free_safe(exportedVariable->programName, __FILE__, __LINE__); // ..\\int\\EXPORT.C, 274
}
if (exportedVariable->type == VALUE_TYPE_DYNAMIC_STRING) {
if (exportedVariable->value.opcode == VALUE_TYPE_DYNAMIC_STRING) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // ..\\int\\EXPORT.C, 276
}
}
@ -332,7 +328,7 @@ void _exportClearAllVariables()
for (int index = 0; index < 1013; index++) {
ExternalVariable* exportedVariable = &(gExternalVariables[index]);
if (exportedVariable->name[0] != '\0') {
if ((exportedVariable->type & 0xF7FF) == VALUE_TYPE_STRING) {
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
if (exportedVariable->stringValue != NULL) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 387
}
@ -344,7 +340,7 @@ void _exportClearAllVariables()
}
exportedVariable->name[0] = '\0';
exportedVariable->type = 0;
exportedVariable->value.opcode = 0;
}
}
}

View File

@ -3,8 +3,8 @@
#include "interpreter.h"
int externalVariableSetValue(Program* program, const char* identifier, opcode_t opcode, int data);
int externalVariableGetValue(Program* program, const char* name, opcode_t* opcodePtr, int* dataPtr);
int externalVariableSetValue(Program* program, const char* identifier, ProgramValue& value);
int externalVariableGetValue(Program* program, const char* name, ProgramValue& value);
int externalVariableCreate(Program* program, const char* identifier);
void _initExport();
void externalVariablesClear();

View File

@ -12,6 +12,7 @@
#include "memory.h"
#include "movie.h"
#include "object.h"
#include "pointer_registry.h"
#include "proto.h"
#include "queue.h"
#include "random.h"
@ -1564,7 +1565,7 @@ int gameSoundFileOpen(const char* fname, int flags, ...)
return -1;
}
return (int)stream;
return ptrToInt(stream);
}
// NOTE: Collapsed.
@ -1599,7 +1600,7 @@ int gameSoundFileClose(int fileHandle)
return -1;
}
return fileClose((File*)fileHandle);
return fileClose((File*)intToPtr(fileHandle, true));
}
// 0x451A30
@ -1609,7 +1610,7 @@ int gameSoundFileRead(int fileHandle, void* buffer, unsigned int size)
return -1;
}
return fileRead(buffer, 1, size, (File*)fileHandle);
return fileRead(buffer, 1, size, (File*)intToPtr(fileHandle));
}
// 0x451A4C
@ -1619,11 +1620,11 @@ long gameSoundFileSeek(int fileHandle, long offset, int origin)
return -1;
}
if (fileSeek((File*)fileHandle, offset, origin) != 0) {
if (fileSeek((File*)intToPtr(fileHandle), offset, origin) != 0) {
return -1;
}
return fileTell((File*)fileHandle);
return fileTell((File*)intToPtr(fileHandle));
}
// 0x451A70
@ -1633,7 +1634,7 @@ long gameSoundFileTell(int handle)
return -1;
}
return fileTell((File*)handle);
return fileTell((File*)intToPtr(handle));
}
// 0x451A7C
@ -1643,7 +1644,7 @@ long gameSoundFileGetSize(int handle)
return -1;
}
return fileGetSize((File*)handle);
return fileGetSize((File*)intToPtr(handle));
}
// 0x451A88

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,8 @@
#include <setjmp.h>
#include <vector>
// The maximum number of opcodes.
#define OPCODE_MAX_COUNT (342)
@ -119,6 +121,7 @@ enum RawValueType {
#define VALUE_TYPE_FLOAT 0xA001
#define VALUE_TYPE_STRING 0x9001
#define VALUE_TYPE_DYNAMIC_STRING 0x9801
#define VALUE_TYPE_PTR 0xE001
typedef unsigned short opcode_t;
@ -131,6 +134,19 @@ typedef struct Procedure {
int field_14;
} Procedure;
typedef struct ProgramValue {
opcode_t opcode;
union {
int integerValue;
float floatValue;
void* pointerValue;
};
bool isEmpty();
} ProgramValue;
typedef std::vector<ProgramValue> ProgramStack;
// It's size in original code is 144 (0x8C) bytes due to the different
// size of `jmp_buf`.
typedef struct Program {
@ -141,10 +157,6 @@ typedef struct Program {
int instructionPointer; // current pos in data
int framePointer; // saved stack 1 pos - probably beginning of local variables - probably called base
int basePointer; // saved stack 1 pos - probably beginning of global variables
unsigned char* stack; // stack 1 (4096 bytes)
unsigned char* returnStack; // stack 2 (4096 bytes)
int stackPointer; // stack pointer 1
int returnStackPointer; // stack pointer 2
unsigned char* staticStrings; // static strings table
unsigned char* dynamicStrings; // dynamic strings table
unsigned char* identifiers;
@ -157,6 +169,8 @@ typedef struct Program {
int flags; // flags
int field_84;
bool exited;
ProgramStack* stackValues;
ProgramStack* returnStackValues;
} Program;
typedef void OpcodeHandler(Program* program);
@ -168,10 +182,6 @@ void _interpretOutputFunc(int (*func)(char*));
int _interpretOutput(const char* format, ...);
[[noreturn]] void programFatalError(const char* str, ...);
void programPopString(Program* program, opcode_t a2, int a3);
void programStackPushInt16(Program* program, int value);
void programStackPushInt32(Program* program, int value);
opcode_t programStackPopInt16(Program* program);
int programStackPopInt32(Program* program);
Program* programCreateByPath(const char* path);
char* programGetString(Program* program, opcode_t opcode, int offset);
char* programGetIdentifier(Program* program, int offset);
@ -187,4 +197,24 @@ void _updatePrograms();
void programListFree();
void interpreterRegisterOpcode(int opcode, OpcodeHandler* handler);
void programStackPushValue(Program* program, ProgramValue& programValue);
void programStackPushInteger(Program* program, int value);
void programStackPushFloat(Program* program, float value);
void programStackPushString(Program* program, char* string);
void programStackPushPointer(Program* program, void* value);
ProgramValue programStackPopValue(Program* program);
int programStackPopInteger(Program* program);
float programStackPopFloat(Program* program);
char* programStackPopString(Program* program);
void* programStackPopPointer(Program* program);
void programReturnStackPushValue(Program* program, ProgramValue& programValue);
void programReturnStackPushInteger(Program* program, int value);
void programReturnStackPushPointer(Program* program, void* value);
ProgramValue programReturnStackPopValue(Program* program);
int programReturnStackPopInteger(Program* program);
void* programReturnStackPopPointer(Program* program);
#endif /* INTERPRETER_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@
#include "movie_effect.h"
#include "movie_lib.h"
#include "platform_compat.h"
#include "pointer_registry.h"
#include "sound.h"
#include "text_font.h"
#include "window_manager.h"
@ -172,6 +173,7 @@ static File* _alphaHandle;
static unsigned char* _alphaBuf;
static SDL_Surface* gMovieSdlSurface = NULL;
static int gMovieFileStreamPointerKey = 0;
// 0x4865FC
static void* movieMallocImpl(size_t size)
@ -188,7 +190,7 @@ static void movieFreeImpl(void* ptr)
// 0x48662C
static bool movieReadImpl(int fileHandle, void* buf, int count)
{
return fileRead(buf, 1, count, (File*)fileHandle) == count;
return fileRead(buf, 1, count, (File*)intToPtr(fileHandle)) == count;
}
// 0x486654
@ -704,6 +706,8 @@ static int _movieStart(int win, char* filePath, int (*a3)())
return 1;
}
gMovieFileStreamPointerKey = ptrToInt(gMovieFileStream);
gMovieWindow = win;
_running = 1;
gMovieFlags &= ~MOVIE_EXTENDED_FLAG_0x01;
@ -731,7 +735,7 @@ static int _movieStart(int win, char* filePath, int (*a3)())
v15 = 0;
}
_MVE_rmPrepMovie((int)gMovieFileStream, v15, v16, v17);
_MVE_rmPrepMovie(gMovieFileStreamPointerKey, v15, v16, v17);
if (_movieScaleFlag) {
debugPrint("scaled\n");

41
src/pointer_registry.cc Normal file
View File

@ -0,0 +1,41 @@
#include "pointer_registry.h"
PointerRegistry* PointerRegistry::shared()
{
static PointerRegistry* shared = new PointerRegistry();
return shared;
}
PointerRegistry::PointerRegistry()
{
// 0 is reserved for nullptr, so start with 1.
_next = 1;
}
int PointerRegistry::store(void* ptr)
{
if (ptr == nullptr) return 0;
int ref = _next++;
_map[ref] = ptr;
return ref;
}
void* PointerRegistry::fetch(int ref, bool remove)
{
if (ref == 0) return nullptr;
void* ptr = _map[ref];
if (remove) {
_map.erase(ref);
}
return ptr;
}
int ptrToInt(void* ptr)
{
return PointerRegistry::shared()->store(ptr);
}
void* intToPtr(int ref, bool remove)
{
return PointerRegistry::shared()->fetch(ref, remove);
}

23
src/pointer_registry.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef POINTER_REGISTRY_H
#define POINTER_REGISTRY_H
#include <unordered_map>
class PointerRegistry {
public:
static PointerRegistry* shared();
PointerRegistry();
int store(void* ptr);
void* fetch(int ref, bool remove = false);
private:
std::unordered_map<int, void*> _map;
int _next;
};
int ptrToInt(void* ptr);
void* intToPtr(int ref, bool remove = false);
#endif /* POINTER_REGISTRY_H */

View File

@ -193,7 +193,7 @@ static int _ReadBand_Fmt3_16_(SoundDecoder* soundDecoder, int offset, int bits)
int v14;
short* base = (short*)_AudioDecoder_scale0;
base += UINT_MAX << (bits - 1);
base += (int)(UINT_MAX << (bits - 1));
int* p = (int*)soundDecoder->field_34;
p += offset;

View File

@ -4,6 +4,7 @@
#include "debug.h"
#include "memory.h"
#include "platform_compat.h"
#include "pointer_registry.h"
#include "sound_decoder.h"
#include <limits.h>
@ -421,13 +422,16 @@ static int soundEffectsListPopulateFileSizes()
return 1;
}
int fileHandle = ptrToInt((void*)stream);
int v1;
int v2;
int v3;
SoundDecoder* soundDecoder = soundDecoderInit(_sfxl_ad_reader, (int)stream, &v1, &v2, &v3);
SoundDecoder* soundDecoder = soundDecoderInit(_sfxl_ad_reader, fileHandle, &v1, &v2, &v3);
entry->dataSize = 2 * v3;
soundDecoderFree(soundDecoder);
fileClose(stream);
intToPtr(fileHandle, true);
}
break;
default:
@ -464,5 +468,5 @@ static int soundEffectsListCompareByName(const void* a1, const void* a2)
// read via xfile
static int _sfxl_ad_reader(int fileHandle, void* buf, unsigned int size)
{
return fileRead(buf, 1, size, (File*)fileHandle);
return fileRead(buf, 1, size, (File*)intToPtr(fileHandle));
}

View File

@ -5,6 +5,8 @@
#include "debug.h"
#include "draw.h"
#include "memory.h"
#include "palette.h"
#include "pointer_registry.h"
#include "text_font.h"
#include "win32.h"
#include "window_manager_private.h"
@ -1311,7 +1313,7 @@ int paletteOpenFileImpl(const char* path, int flags)
File* stream = fileOpen(path, mode);
if (stream != NULL) {
return (int)stream;
return ptrToInt(stream);
}
return -1;
@ -1322,7 +1324,7 @@ int paletteOpenFileImpl(const char* path, int flags)
// 0x4D81E8
int paletteReadFileImpl(int fd, void* buf, size_t count)
{
return fileRead(buf, 1, count, (File*)fd);
return fileRead(buf, 1, count, (File*)intToPtr(fd));
}
// [close] implementation for palette file operations backed by [XFile].
@ -1330,7 +1332,7 @@ int paletteReadFileImpl(int fd, void* buf, size_t count)
// 0x4D81E0
int paletteCloseFileImpl(int fd)
{
return fileClose((File*)fd);
return fileClose((File*)intToPtr(fd));
}
// 0x4D8200