Reconcile with reference edition

This commit is contained in:
Alexander Batalov 2022-08-06 13:48:16 +03:00
parent 17382d7c7e
commit ef067cd954
3 changed files with 94 additions and 92 deletions

View File

@ -12,15 +12,15 @@
typedef struct InterfaceFontGlyph { typedef struct InterfaceFontGlyph {
short width; short width;
short field_2; short height;
int field_4; int offset;
} InterfaceFontGlyph; } InterfaceFontGlyph;
typedef struct InterfaceFontDescriptor { typedef struct InterfaceFontDescriptor {
short field_0; short maxHeight;
short letterSpacing; short letterSpacing;
short wordSpacing; short wordSpacing;
short field_6; short lineSpacing;
short field_8; short field_8;
short field_A; short field_A;
InterfaceFontGlyph glyphs[256]; InterfaceFontGlyph glyphs[256];
@ -79,7 +79,7 @@ int interfaceFontsInit()
for (int font = 0; font < INTERFACE_FONT_MAX; font++) { for (int font = 0; font < INTERFACE_FONT_MAX; font++) {
if (interfaceFontLoad(font) == -1) { if (interfaceFontLoad(font) == -1) {
gInterfaceFontDescriptors[font].field_0 = 0; gInterfaceFontDescriptors[font].maxHeight = 0;
gInterfaceFontDescriptors[font].data = NULL; gInterfaceFontDescriptors[font].data = NULL;
} else { } else {
++gInterfaceFontsLength; ++gInterfaceFontsLength;
@ -132,8 +132,8 @@ static int interfaceFontLoad(int font_index)
interfaceFontByteSwapInt32(&sig); interfaceFontByteSwapInt32(&sig);
if (sig != 0x41414646) goto err; if (sig != 0x41414646) goto err;
if (fileRead(&(fontDescriptor->field_0), 2, 1, stream) != 1) goto err; if (fileRead(&(fontDescriptor->maxHeight), 2, 1, stream) != 1) goto err;
interfaceFontByteSwapInt16(&(fontDescriptor->field_0)); interfaceFontByteSwapInt16(&(fontDescriptor->maxHeight));
if (fileRead(&(fontDescriptor->letterSpacing), 2, 1, stream) != 1) goto err; if (fileRead(&(fontDescriptor->letterSpacing), 2, 1, stream) != 1) goto err;
interfaceFontByteSwapInt16(&(fontDescriptor->letterSpacing)); interfaceFontByteSwapInt16(&(fontDescriptor->letterSpacing));
@ -141,8 +141,8 @@ static int interfaceFontLoad(int font_index)
if (fileRead(&(fontDescriptor->wordSpacing), 2, 1, stream) != 1) goto err; if (fileRead(&(fontDescriptor->wordSpacing), 2, 1, stream) != 1) goto err;
interfaceFontByteSwapInt16(&(fontDescriptor->wordSpacing)); interfaceFontByteSwapInt16(&(fontDescriptor->wordSpacing));
if (fileRead(&(fontDescriptor->field_6), 2, 1, stream) != 1) goto err; if (fileRead(&(fontDescriptor->lineSpacing), 2, 1, stream) != 1) goto err;
interfaceFontByteSwapInt16(&(fontDescriptor->field_6)); interfaceFontByteSwapInt16(&(fontDescriptor->lineSpacing));
for (int index = 0; index < 256; index++) { for (int index = 0; index < 256; index++) {
InterfaceFontGlyph* glyph = &(fontDescriptor->glyphs[index]); InterfaceFontGlyph* glyph = &(fontDescriptor->glyphs[index]);
@ -150,11 +150,11 @@ static int interfaceFontLoad(int font_index)
if (fileRead(&(glyph->width), 2, 1, stream) != 1) goto err; if (fileRead(&(glyph->width), 2, 1, stream) != 1) goto err;
interfaceFontByteSwapInt16(&(glyph->width)); interfaceFontByteSwapInt16(&(glyph->width));
if (fileRead(&(glyph->field_2), 2, 1, stream) != 1) goto err; if (fileRead(&(glyph->height), 2, 1, stream) != 1) goto err;
interfaceFontByteSwapInt16(&(glyph->field_2)); interfaceFontByteSwapInt16(&(glyph->height));
if (fileRead(&(glyph->field_4), 4, 1, stream) != 1) goto err; if (fileRead(&(glyph->offset), 4, 1, stream) != 1) goto err;
interfaceFontByteSwapInt32(&(glyph->field_4)); interfaceFontByteSwapInt32(&(glyph->offset));
} }
fileSize -= sizeof(InterfaceFontDescriptor); fileSize -= sizeof(InterfaceFontDescriptor);
@ -199,7 +199,7 @@ static int interfaceFontGetLineHeightImpl()
return 0; return 0;
} }
return gCurrentInterfaceFontDescriptor->field_6 + gCurrentInterfaceFontDescriptor->field_0; return gCurrentInterfaceFontDescriptor->lineSpacing + gCurrentInterfaceFontDescriptor->maxHeight;
} }
// 0x442188 // 0x442188
@ -288,12 +288,12 @@ static int interfaceFontGetMonospacedCharacterWidthImpl()
int v1; int v1;
if (gCurrentInterfaceFontDescriptor->wordSpacing <= gCurrentInterfaceFontDescriptor->field_8) { if (gCurrentInterfaceFontDescriptor->wordSpacing <= gCurrentInterfaceFontDescriptor->field_8) {
v1 = gCurrentInterfaceFontDescriptor->field_6; v1 = gCurrentInterfaceFontDescriptor->lineSpacing;
} else { } else {
v1 = gCurrentInterfaceFontDescriptor->letterSpacing; v1 = gCurrentInterfaceFontDescriptor->letterSpacing;
} }
return v1 + gCurrentInterfaceFontDescriptor->field_0; return v1 + gCurrentInterfaceFontDescriptor->maxHeight;
} }
// 0x4422B4 // 0x4422B4
@ -342,12 +342,12 @@ static void interfaceFontDrawImpl(unsigned char* buf, const char* string, int le
} }
InterfaceFontGlyph* glyph = &(gCurrentInterfaceFontDescriptor->glyphs[ch & 0xFF]); InterfaceFontGlyph* glyph = &(gCurrentInterfaceFontDescriptor->glyphs[ch & 0xFF]);
unsigned char* glyphDataPtr = gCurrentInterfaceFontDescriptor->data + glyph->field_4; unsigned char* glyphDataPtr = gCurrentInterfaceFontDescriptor->data + glyph->offset;
// Skip blank pixels (difference between font's line height and glyph height). // Skip blank pixels (difference between font's line height and glyph height).
ptr += (gCurrentInterfaceFontDescriptor->field_0 - glyph->field_2) * pitch; ptr += (gCurrentInterfaceFontDescriptor->maxHeight - glyph->height) * pitch;
for (int y = 0; y < glyph->field_2; y++) { for (int y = 0; y < glyph->height; y++) {
for (int x = 0; x < glyph->width; x++) { for (int x = 0; x < glyph->width; x++) {
unsigned char byte = *glyphDataPtr++; unsigned char byte = *glyphDataPtr++;
@ -362,7 +362,7 @@ static void interfaceFontDrawImpl(unsigned char* buf, const char* string, int le
if ((color & FONT_UNDERLINE) != 0) { if ((color & FONT_UNDERLINE) != 0) {
int length = ptr - buf; int length = ptr - buf;
unsigned char* underlinePtr = buf + pitch * (gCurrentInterfaceFontDescriptor->field_0 - 1); unsigned char* underlinePtr = buf + pitch * (gCurrentInterfaceFontDescriptor->maxHeight - 1);
for (int index = 0; index < length; index++) { for (int index = 0; index < length; index++) {
*underlinePtr++ = color & 0xFF; *underlinePtr++ = color & 0xFF;
} }

View File

@ -19,21 +19,23 @@
#include <SDL.h> #include <SDL.h>
#define SOUND_FLAG_SOUND_IS_DONE (0x01)
#define SOUND_FLAG_SOUND_IS_PLAYING (0x02) #define SOUND_FLAG_SOUND_IS_PLAYING (0x02)
#define SOUND_FLAG_SOUND_IS_FADING (0x04)
#define SOUND_FLAG_SOUND_IS_PAUSED (0x08) #define SOUND_FLAG_SOUND_IS_PAUSED (0x08)
typedef char*(SoundFileNameMangler)(char*); typedef char*(SoundFileNameMangler)(char*);
typedef struct STRUCT_51D478 { typedef struct FadeSound {
Sound* field_0; Sound* sound;
int field_4; int deltaVolume;
int field_8; int targetVolume;
int field_C; int initialVolume;
int field_10; int currentVolume;
int field_14; int field_14;
struct STRUCT_51D478* prev; struct FadeSound* prev;
struct STRUCT_51D478* next; struct FadeSound* next;
} STRUCT_51D478; } FadeSound;
static void* soundMallocProcDefaultImpl(size_t size); static void* soundMallocProcDefaultImpl(size_t size);
static void* soundReallocProcDefaultImpl(void* ptr, size_t size); static void* soundReallocProcDefaultImpl(void* ptr, size_t size);
@ -49,15 +51,15 @@ static int _soundGetVolume(Sound* sound);
static void soundDeleteInternal(Sound* sound); static void soundDeleteInternal(Sound* sound);
static Uint32 _doTimerEvent(Uint32 interval, void* param); static Uint32 _doTimerEvent(Uint32 interval, void* param);
static void _removeTimedEvent(SDL_TimerID* timerId); static void _removeTimedEvent(SDL_TimerID* timerId);
static void _removeFadeSound(STRUCT_51D478* a1); static void _removeFadeSound(FadeSound* fadeSound);
static void _fadeSounds(); static void _fadeSounds();
static int _internalSoundFade(Sound* sound, int a2, int a3, int a4); static int _internalSoundFade(Sound* sound, int duration, int targetVolume, int a4);
// 0x51D478 // 0x51D478
static STRUCT_51D478* _fadeHead = NULL; static FadeSound* _fadeHead = NULL;
// 0x51D47C // 0x51D47C
static STRUCT_51D478* _fadeFreeList = NULL; static FadeSound* _fadeFreeList = NULL;
// 0x51D488 // 0x51D488
static MallocProc* gSoundMallocProc = soundMallocProcDefaultImpl; static MallocProc* gSoundMallocProc = soundMallocProcDefaultImpl;
@ -405,7 +407,7 @@ void soundExit()
} }
while (_fadeFreeList != NULL) { while (_fadeFreeList != NULL) {
STRUCT_51D478* next = _fadeFreeList->next; FadeSound* next = _fadeFreeList->next;
gSoundFreeProc(_fadeFreeList); gSoundFreeProc(_fadeFreeList);
_fadeFreeList = next; _fadeFreeList = next;
} }
@ -586,7 +588,7 @@ int _soundRewind(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
sound->field_40 &= ~(0x01); sound->field_40 &= ~SOUND_FLAG_SOUND_IS_DONE;
gSoundLastError = SOUND_NO_ERROR; gSoundLastError = SOUND_NO_ERROR;
return gSoundLastError; return gSoundLastError;
@ -665,7 +667,7 @@ int soundPlay(Sound* sound)
} }
// TODO: Check. // TODO: Check.
if (sound->field_40 & 0x01) { if (sound->field_40 & SOUND_FLAG_SOUND_IS_DONE) {
_soundRewind(sound); _soundRewind(sound);
} }
@ -772,7 +774,7 @@ int soundContinue(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
if (sound->field_40 & 0x01) { if (sound->field_40 & SOUND_FLAG_SOUND_IS_DONE) {
gSoundLastError = SOUND_UNKNOWN_ERROR; gSoundLastError = SOUND_UNKNOWN_ERROR;
return gSoundLastError; return gSoundLastError;
} }
@ -799,15 +801,15 @@ int soundContinue(Sound* sound)
sound->callback = NULL; sound->callback = NULL;
soundDelete(sound); soundDelete(sound);
} else { } else {
sound->field_40 |= 0x01; sound->field_40 |= SOUND_FLAG_SOUND_IS_DONE;
if (sound->field_40 & 0x02) { if (sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) {
--_numSounds; --_numSounds;
} }
soundStop(sound); soundStop(sound);
sound->field_40 &= ~(0x03); sound->field_40 &= ~(SOUND_FLAG_SOUND_IS_DONE | SOUND_FLAG_SOUND_IS_PLAYING);
} }
} }
@ -1189,15 +1191,15 @@ int soundSetFileIO(Sound* sound, SoundOpenProc* openProc, SoundCloseProc* closeP
// 0x4AE378 // 0x4AE378
void soundDeleteInternal(Sound* sound) void soundDeleteInternal(Sound* sound)
{ {
STRUCT_51D478* curr; FadeSound* curr;
Sound* v10; Sound* v10;
Sound* v11; Sound* v11;
if (sound->field_40 & 0x04) { if (sound->field_40 & SOUND_FLAG_SOUND_IS_FADING) {
curr = _fadeHead; curr = _fadeHead;
while (curr != NULL) { while (curr != NULL) {
if (sound == curr->field_0) { if (sound == curr->sound) {
break; break;
} }
@ -1368,70 +1370,70 @@ int _soundSetPosition(Sound* sound, int a2)
} }
// 0x4AE830 // 0x4AE830
void _removeFadeSound(STRUCT_51D478* a1) void _removeFadeSound(FadeSound* fadeSound)
{ {
STRUCT_51D478* prev; FadeSound* prev;
STRUCT_51D478* next; FadeSound* next;
STRUCT_51D478* tmp; FadeSound* tmp;
if (a1 == NULL) { if (fadeSound == NULL) {
return; return;
} }
if (a1->field_0 == NULL) { if (fadeSound->sound == NULL) {
return; return;
} }
if (!(a1->field_0->field_40 & 0x04)) { if (!(fadeSound->sound->field_40 & SOUND_FLAG_SOUND_IS_FADING)) {
return; return;
} }
prev = a1->prev; prev = fadeSound->prev;
if (prev != NULL) { if (prev != NULL) {
prev->next = a1->next; prev->next = fadeSound->next;
} else { } else {
_fadeHead = a1->next; _fadeHead = fadeSound->next;
} }
next = a1->next; next = fadeSound->next;
if (next != NULL) { if (next != NULL) {
next->prev = a1->prev; next->prev = fadeSound->prev;
} }
a1->field_0->field_40 &= ~(0x04); fadeSound->sound->field_40 &= ~SOUND_FLAG_SOUND_IS_FADING;
a1->field_0 = NULL; fadeSound->sound = NULL;
tmp = _fadeFreeList; tmp = _fadeFreeList;
_fadeFreeList = a1; _fadeFreeList = fadeSound;
a1->next = tmp; fadeSound->next = tmp;
} }
// 0x4AE8B0 // 0x4AE8B0
void _fadeSounds() void _fadeSounds()
{ {
STRUCT_51D478* ptr; FadeSound* ptr;
ptr = _fadeHead; ptr = _fadeHead;
while (ptr != NULL) { while (ptr != NULL) {
if ((ptr->field_10 > ptr->field_8 || ptr->field_10 + ptr->field_4 < ptr->field_8) && (ptr->field_10 < ptr->field_8 || ptr->field_10 + ptr->field_4 > ptr->field_8)) { if ((ptr->currentVolume > ptr->targetVolume || ptr->currentVolume + ptr->deltaVolume < ptr->targetVolume) && (ptr->currentVolume < ptr->targetVolume || ptr->currentVolume + ptr->deltaVolume > ptr->targetVolume)) {
ptr->field_10 += ptr->field_4; ptr->currentVolume += ptr->deltaVolume;
soundSetVolume(ptr->field_0, ptr->field_10); soundSetVolume(ptr->sound, ptr->currentVolume);
} else { } else {
if (ptr->field_8 == 0) { if (ptr->targetVolume == 0) {
if (ptr->field_14) { if (ptr->field_14) {
soundPause(ptr->field_0); soundPause(ptr->sound);
soundSetVolume(ptr->field_0, ptr->field_C); soundSetVolume(ptr->sound, ptr->initialVolume);
} else { } else {
if (ptr->field_0->field_44 & 0x04) { if (ptr->sound->field_44 & 0x04) {
soundDelete(ptr->field_0); soundDelete(ptr->sound);
} else { } else {
soundStop(ptr->field_0); soundStop(ptr->sound);
ptr->field_C = ptr->field_8; ptr->initialVolume = ptr->targetVolume;
ptr->field_10 = ptr->field_8; ptr->currentVolume = ptr->targetVolume;
ptr->field_4 = 0; ptr->deltaVolume = 0;
soundSetVolume(ptr->field_0, ptr->field_8); soundSetVolume(ptr->sound, ptr->targetVolume);
} }
} }
} }
@ -1447,9 +1449,9 @@ void _fadeSounds()
} }
// 0x4AE988 // 0x4AE988
int _internalSoundFade(Sound* sound, int a2, int a3, int a4) int _internalSoundFade(Sound* sound, int duration, int targetVolume, int a4)
{ {
STRUCT_51D478* ptr; FadeSound* ptr;
if (!_deviceInit) { if (!_deviceInit) {
gSoundLastError = SOUND_NOT_INITIALIZED; gSoundLastError = SOUND_NOT_INITIALIZED;
@ -1462,10 +1464,10 @@ int _internalSoundFade(Sound* sound, int a2, int a3, int a4)
} }
ptr = NULL; ptr = NULL;
if (sound->field_40 & 0x04) { if (sound->field_40 & SOUND_FLAG_SOUND_IS_FADING) {
ptr = _fadeHead; ptr = _fadeHead;
while (ptr != NULL) { while (ptr != NULL) {
if (ptr->field_0 == sound) { if (ptr->sound == sound) {
break; break;
} }
@ -1478,7 +1480,7 @@ int _internalSoundFade(Sound* sound, int a2, int a3, int a4)
ptr = _fadeFreeList; ptr = _fadeFreeList;
_fadeFreeList = _fadeFreeList->next; _fadeFreeList = _fadeFreeList->next;
} else { } else {
ptr = (STRUCT_51D478*)gSoundMallocProc(sizeof(STRUCT_51D478)); ptr = (FadeSound*)gSoundMallocProc(sizeof(FadeSound));
} }
if (ptr != NULL) { if (ptr != NULL) {
@ -1486,7 +1488,7 @@ int _internalSoundFade(Sound* sound, int a2, int a3, int a4)
_fadeHead->prev = ptr; _fadeHead->prev = ptr;
} }
ptr->field_0 = sound; ptr->sound = sound;
ptr->prev = NULL; ptr->prev = NULL;
ptr->next = _fadeHead; ptr->next = _fadeHead;
_fadeHead = ptr; _fadeHead = ptr;
@ -1498,29 +1500,29 @@ int _internalSoundFade(Sound* sound, int a2, int a3, int a4)
return gSoundLastError; return gSoundLastError;
} }
ptr->field_8 = a3; ptr->targetVolume = targetVolume;
ptr->field_C = _soundGetVolume(sound); ptr->initialVolume = _soundGetVolume(sound);
ptr->field_10 = ptr->field_C; ptr->currentVolume = ptr->initialVolume;
ptr->field_14 = a4; ptr->field_14 = a4;
// TODO: Check. // TODO: Check.
ptr->field_4 = 8 * (125 * (a3 - ptr->field_C)) / (40 * a2); ptr->deltaVolume = 8 * (125 * (targetVolume - ptr->initialVolume)) / (40 * duration);
sound->field_40 |= 0x04; sound->field_40 |= SOUND_FLAG_SOUND_IS_FADING;
bool v14; bool shouldPlay;
if (gSoundInitialized) { if (gSoundInitialized) {
if (sound->soundBuffer != -1) { if (sound->soundBuffer != -1) {
v14 = (sound->field_40 & 0x02) == 0; shouldPlay = (sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) == 0;
} else { } else {
gSoundLastError = SOUND_NO_SOUND; gSoundLastError = SOUND_NO_SOUND;
v14 = true; shouldPlay = true;
} }
} else { } else {
gSoundLastError = SOUND_NOT_INITIALIZED; gSoundLastError = SOUND_NOT_INITIALIZED;
v14 = true; shouldPlay = true;
} }
if (v14) { if (shouldPlay) {
soundPlay(sound); soundPlay(sound);
} }
@ -1540,9 +1542,9 @@ int _internalSoundFade(Sound* sound, int a2, int a3, int a4)
} }
// 0x4AEB0C // 0x4AEB0C
int _soundFade(Sound* sound, int a2, int a3) int _soundFade(Sound* sound, int duration, int targetVolume)
{ {
return _internalSoundFade(sound, a2, a3, 0); return _internalSoundFade(sound, duration, targetVolume, 0);
} }
// 0x4AEB54 // 0x4AEB54

View File

@ -128,7 +128,7 @@ int soundSetFileIO(Sound* sound, SoundOpenProc* openProc, SoundCloseProc* closeP
int _soundSetMasterVolume(int value); int _soundSetMasterVolume(int value);
int _soundGetPosition(Sound* sound); int _soundGetPosition(Sound* sound);
int _soundSetPosition(Sound* sound, int a2); int _soundSetPosition(Sound* sound, int a2);
int _soundFade(Sound* sound, int a2, int a3); int _soundFade(Sound* sound, int duration, int targetVolume);
void soundDeleteAll(); void soundDeleteAll();
void soundContinueAll(); void soundContinueAll();
int soundSetDefaultFileIO(SoundOpenProc* openProc, SoundCloseProc* closeProc, SoundReadProc* readProc, SoundWriteProc* writeProc, SoundSeekProc* seekProc, SoundTellProc* tellProc, SoundFileLengthProc* fileLengthProc); int soundSetDefaultFileIO(SoundOpenProc* openProc, SoundCloseProc* closeProc, SoundReadProc* readProc, SoundWriteProc* writeProc, SoundSeekProc* seekProc, SoundTellProc* tellProc, SoundFileLengthProc* fileLengthProc);