Merge branch 'main' into InterfaceBar
This commit is contained in:
commit
7ce28efb61
|
@ -1396,7 +1396,7 @@ int actionUseSkill(Object* a1, Object* a2, int skill)
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
case SKILL_SNEAK:
|
case SKILL_SNEAK:
|
||||||
dudeToggleState(0);
|
dudeToggleState(DUDE_STATE_SNEAKING);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
debugPrint("\nskill_use: invalid skill used.");
|
debugPrint("\nskill_use: invalid skill used.");
|
||||||
|
|
|
@ -690,7 +690,7 @@ int animationRegisterRunToObject(Object* owner, Object* destination, int actionP
|
||||||
animationDescription->destination = destination;
|
animationDescription->destination = destination;
|
||||||
|
|
||||||
if ((FID_TYPE(owner->fid) == OBJ_TYPE_CRITTER && (owner->data.critter.combat.results & DAM_CRIP_LEG_ANY) != 0)
|
if ((FID_TYPE(owner->fid) == OBJ_TYPE_CRITTER && (owner->data.critter.combat.results & DAM_CRIP_LEG_ANY) != 0)
|
||||||
|| (owner == gDude && dudeHasState(0) && !perkGetRank(gDude, PERK_SILENT_RUNNING))
|
|| (owner == gDude && dudeHasState(DUDE_STATE_SNEAKING) && !perkGetRank(gDude, PERK_SILENT_RUNNING))
|
||||||
|| !artExists(buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, ANIM_RUNNING, 0, owner->rotation + 1))) {
|
|| !artExists(buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, ANIM_RUNNING, 0, owner->rotation + 1))) {
|
||||||
animationDescription->anim = ANIM_WALK;
|
animationDescription->anim = ANIM_WALK;
|
||||||
} else {
|
} else {
|
||||||
|
@ -786,7 +786,7 @@ int animationRegisterRunToTile(Object* owner, int tile, int elevation, int actio
|
||||||
animationDescription->elevation = elevation;
|
animationDescription->elevation = elevation;
|
||||||
|
|
||||||
if ((FID_TYPE(owner->fid) == OBJ_TYPE_CRITTER && (owner->data.critter.combat.results & DAM_CRIP_LEG_ANY) != 0)
|
if ((FID_TYPE(owner->fid) == OBJ_TYPE_CRITTER && (owner->data.critter.combat.results & DAM_CRIP_LEG_ANY) != 0)
|
||||||
|| (owner == gDude && dudeHasState(0) && !perkGetRank(gDude, PERK_SILENT_RUNNING))
|
|| (owner == gDude && dudeHasState(DUDE_STATE_SNEAKING) && !perkGetRank(gDude, PERK_SILENT_RUNNING))
|
||||||
|| !artExists(buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, ANIM_RUNNING, 0, owner->rotation + 1))) {
|
|| !artExists(buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, ANIM_RUNNING, 0, owner->rotation + 1))) {
|
||||||
animationDescription->anim = ANIM_WALK;
|
animationDescription->anim = ANIM_WALK;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3043,7 +3043,7 @@ int _dude_run(int a1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!perkGetRank(gDude, PERK_SILENT_RUNNING)) {
|
if (!perkGetRank(gDude, PERK_SILENT_RUNNING)) {
|
||||||
dudeDisableState(0);
|
dudeDisableState(DUDE_STATE_SNEAKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||||
|
|
|
@ -1186,8 +1186,8 @@ int characterEditorShow(bool isCreationMode)
|
||||||
characterEditorRestorePlayer();
|
characterEditorRestorePlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dudeHasState(0x03)) {
|
if (dudeHasState(DUDE_STATE_LEVEL_UP_AVAILABLE)) {
|
||||||
dudeDisableState(0x03);
|
dudeDisableState(DUDE_STATE_LEVEL_UP_AVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaceRenderHitPoints(false);
|
interfaceRenderHitPoints(false);
|
||||||
|
|
|
@ -338,7 +338,7 @@ int fileReadInt32(File* stream, int* valuePtr)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*valuePtr = ((value >> 24) & 0xFF) | ((value >> 8) & 0xFF00) | ((value << 8) & 0xFF0000) | ((value << 24) & 0xFF000000);
|
*valuePtr = ((value & 0xFF000000) >> 24) | ((value & 0xFF0000) >> 8) | ((value & 0xFF00) << 8) | ((value & 0xFF) << 24);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -511,7 +511,7 @@ int fileReadInt32List(File* stream, int* arr, int count)
|
||||||
|
|
||||||
for (int index = 0; index < count; index++) {
|
for (int index = 0; index < count; index++) {
|
||||||
int value = arr[index];
|
int value = arr[index];
|
||||||
arr[index] = ((value >> 24) & 0xFF) | ((value >> 8) & 0xFF00) | ((value << 8) & 0xFF0000) | ((value << 24) & 0xFF000000);
|
arr[index] = ((value & 0xFF000000) >> 24) | ((value & 0xFF0000) >> 8) | ((value & 0xFF00) << 8) | ((value & 0xFF) << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
13
src/debug.cc
13
src/debug.cc
|
@ -5,10 +5,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#include <SDL.h>
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "platform_compat.h"
|
#include "platform_compat.h"
|
||||||
|
@ -148,13 +145,7 @@ int debugPrint(const char* format, ...)
|
||||||
rc = gDebugPrintProc(string);
|
rc = gDebugPrintProc(string);
|
||||||
} else {
|
} else {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
char string[260];
|
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, format, args);
|
||||||
vsprintf(string, format, args);
|
|
||||||
#ifdef _WIN32
|
|
||||||
OutputDebugStringA(string);
|
|
||||||
#else
|
|
||||||
printf("%s", string);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,60 +123,85 @@ static int interfaceFontLoad(int font_index)
|
||||||
|
|
||||||
File* stream = fileOpen(path, "rb");
|
File* stream = fileOpen(path, "rb");
|
||||||
if (stream == NULL) {
|
if (stream == NULL) {
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fileSize = fileGetSize(stream);
|
int fileSize = fileGetSize(stream);
|
||||||
|
|
||||||
int sig;
|
int sig;
|
||||||
if (fileRead(&sig, 4, 1, stream) != 1) goto err;
|
if (fileRead(&sig, 4, 1, stream) != 1) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
interfaceFontByteSwapInt32(&sig);
|
interfaceFontByteSwapInt32(&sig);
|
||||||
if (sig != 0x41414646) goto err;
|
if (sig != 0x41414646) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (fileRead(&(fontDescriptor->maxHeight), 2, 1, stream) != 1) goto err;
|
if (fileRead(&(fontDescriptor->maxHeight), 2, 1, stream) != 1) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
interfaceFontByteSwapInt16(&(fontDescriptor->maxHeight));
|
interfaceFontByteSwapInt16(&(fontDescriptor->maxHeight));
|
||||||
|
|
||||||
if (fileRead(&(fontDescriptor->letterSpacing), 2, 1, stream) != 1) goto err;
|
if (fileRead(&(fontDescriptor->letterSpacing), 2, 1, stream) != 1) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
interfaceFontByteSwapInt16(&(fontDescriptor->letterSpacing));
|
interfaceFontByteSwapInt16(&(fontDescriptor->letterSpacing));
|
||||||
|
|
||||||
if (fileRead(&(fontDescriptor->wordSpacing), 2, 1, stream) != 1) goto err;
|
if (fileRead(&(fontDescriptor->wordSpacing), 2, 1, stream) != 1) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
interfaceFontByteSwapInt16(&(fontDescriptor->wordSpacing));
|
interfaceFontByteSwapInt16(&(fontDescriptor->wordSpacing));
|
||||||
|
|
||||||
if (fileRead(&(fontDescriptor->lineSpacing), 2, 1, stream) != 1) goto err;
|
if (fileRead(&(fontDescriptor->lineSpacing), 2, 1, stream) != 1) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
interfaceFontByteSwapInt16(&(fontDescriptor->lineSpacing));
|
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]);
|
||||||
|
|
||||||
if (fileRead(&(glyph->width), 2, 1, stream) != 1) goto err;
|
if (fileRead(&(glyph->width), 2, 1, stream) != 1) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
interfaceFontByteSwapInt16(&(glyph->width));
|
interfaceFontByteSwapInt16(&(glyph->width));
|
||||||
|
|
||||||
if (fileRead(&(glyph->height), 2, 1, stream) != 1) goto err;
|
if (fileRead(&(glyph->height), 2, 1, stream) != 1) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
interfaceFontByteSwapInt16(&(glyph->height));
|
interfaceFontByteSwapInt16(&(glyph->height));
|
||||||
|
|
||||||
if (fileRead(&(glyph->offset), 4, 1, stream) != 1) goto err;
|
if (fileRead(&(glyph->offset), 4, 1, stream) != 1) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
interfaceFontByteSwapInt32(&(glyph->offset));
|
interfaceFontByteSwapInt32(&(glyph->offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
fileSize -= sizeof(InterfaceFontDescriptor);
|
int glyphDataSize = fileSize - 2060;
|
||||||
|
|
||||||
fontDescriptor->data = (unsigned char*)internal_malloc_safe(fileSize, __FILE__, __LINE__); // FONTMGR.C, 259
|
fontDescriptor->data = (unsigned char*)internal_malloc_safe(glyphDataSize, __FILE__, __LINE__); // FONTMGR.C, 259
|
||||||
if (fontDescriptor->data == NULL) goto err;
|
if (fontDescriptor->data == NULL) {
|
||||||
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (fileRead(fontDescriptor->data, fileSize, 1, stream) != 1) {
|
if (fileRead(fontDescriptor->data, glyphDataSize, 1, stream) != 1) {
|
||||||
internal_free_safe(fontDescriptor->data, __FILE__, __LINE__); // FONTMGR.C, 268
|
internal_free_safe(fontDescriptor->data, __FILE__, __LINE__); // FONTMGR.C, 268
|
||||||
goto err;
|
fileClose(stream);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileClose(stream);
|
fileClose(stream);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
|
||||||
fileClose(stream);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x442120
|
// 0x442120
|
||||||
|
@ -211,26 +236,22 @@ static int interfaceFontGetStringWidthImpl(const char* string)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* pch = string;
|
int stringWidth = 0;
|
||||||
int width = 0;
|
|
||||||
|
|
||||||
while (*pch != '\0') {
|
while (*string != '\0') {
|
||||||
int v3;
|
unsigned char ch = static_cast<unsigned char>(*string++);
|
||||||
int v4;
|
|
||||||
|
|
||||||
if (*pch == ' ') {
|
int characterWidth;
|
||||||
v3 = gCurrentInterfaceFontDescriptor->letterSpacing;
|
if (ch == ' ') {
|
||||||
v4 = gCurrentInterfaceFontDescriptor->wordSpacing;
|
characterWidth = gCurrentInterfaceFontDescriptor->wordSpacing;
|
||||||
} else {
|
} else {
|
||||||
v3 = gCurrentInterfaceFontDescriptor->glyphs[*pch & 0xFF].width;
|
characterWidth = gCurrentInterfaceFontDescriptor->glyphs[ch].width;
|
||||||
v4 = gCurrentInterfaceFontDescriptor->letterSpacing;
|
|
||||||
}
|
|
||||||
width += v3 + v4;
|
|
||||||
|
|
||||||
pch++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return width;
|
stringWidth += characterWidth + gCurrentInterfaceFontDescriptor->letterSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4421DC
|
// 0x4421DC
|
||||||
|
@ -322,13 +343,13 @@ static void interfaceFontDrawImpl(unsigned char* buf, const char* string, int le
|
||||||
|
|
||||||
unsigned char* ptr = buf;
|
unsigned char* ptr = buf;
|
||||||
while (*string != '\0') {
|
while (*string != '\0') {
|
||||||
char ch = *string++;
|
unsigned char ch = static_cast<unsigned char>(*string++);
|
||||||
|
|
||||||
int characterWidth;
|
int characterWidth;
|
||||||
if (ch == ' ') {
|
if (ch == ' ') {
|
||||||
characterWidth = gCurrentInterfaceFontDescriptor->wordSpacing;
|
characterWidth = gCurrentInterfaceFontDescriptor->wordSpacing;
|
||||||
} else {
|
} else {
|
||||||
characterWidth = gCurrentInterfaceFontDescriptor->glyphs[ch & 0xFF].width;
|
characterWidth = gCurrentInterfaceFontDescriptor->glyphs[ch].width;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* end;
|
unsigned char* end;
|
||||||
|
@ -343,7 +364,7 @@ static void interfaceFontDrawImpl(unsigned char* buf, const char* string, int le
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
InterfaceFontGlyph* glyph = &(gCurrentInterfaceFontDescriptor->glyphs[ch & 0xFF]);
|
InterfaceFontGlyph* glyph = &(gCurrentInterfaceFontDescriptor->glyphs[ch]);
|
||||||
unsigned char* glyphDataPtr = gCurrentInterfaceFontDescriptor->data + glyph->offset;
|
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).
|
||||||
|
|
|
@ -693,7 +693,7 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gIsMapper) {
|
if (gIsMapper) {
|
||||||
tileSetCenter(gDude->tile, TILE_SET_CENTER_FLAG_0x01);
|
tileSetCenter(gDude->tile, TILE_SET_CENTER_REFRESH_WINDOW);
|
||||||
} else {
|
} else {
|
||||||
_tile_scroll_to(gDude->tile, 2);
|
_tile_scroll_to(gDude->tile, 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3498,7 +3498,7 @@ void partyMemberControlWindowUpdate()
|
||||||
|
|
||||||
FrmImage backgroundFrmImage;
|
FrmImage backgroundFrmImage;
|
||||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
|
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
|
||||||
if (!backgroundFrmImage.lock(backgroundFid)) {
|
if (backgroundFrmImage.lock(backgroundFid)) {
|
||||||
int width = backgroundFrmImage.getWidth();
|
int width = backgroundFrmImage.getWidth();
|
||||||
unsigned char* buffer = backgroundFrmImage.getData();
|
unsigned char* buffer = backgroundFrmImage.getData();
|
||||||
|
|
||||||
|
@ -4104,10 +4104,7 @@ int _gdCustomSelect(int a1)
|
||||||
sharedFpsLimiter.mark();
|
sharedFpsLimiter.mark();
|
||||||
|
|
||||||
int keyCode = inputGetInput();
|
int keyCode = inputGetInput();
|
||||||
if (keyCode == -1) {
|
if (keyCode != -1) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyCode == KEY_CTRL_Q || keyCode == KEY_CTRL_X || keyCode == KEY_F10) {
|
if (keyCode == KEY_CTRL_Q || keyCode == KEY_CTRL_X || keyCode == KEY_F10) {
|
||||||
showQuitConfirmationDialog();
|
showQuitConfirmationDialog();
|
||||||
}
|
}
|
||||||
|
@ -4124,26 +4121,17 @@ int _gdCustomSelect(int a1)
|
||||||
} else if (keyCode == KEY_ESCAPE) {
|
} else if (keyCode == KEY_ESCAPE) {
|
||||||
done = true;
|
done = true;
|
||||||
} else if (keyCode == -2) {
|
} else if (keyCode == -2) {
|
||||||
if ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_UP) == 0) {
|
if ((mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_UP) != 0) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No need to use mouseHitTestInWindow as these values are already
|
// No need to use mouseHitTestInWindow as these values are already
|
||||||
// in screen coordinates.
|
// in screen coordinates.
|
||||||
if (!_mouse_click_in(minX, minY, maxX, maxY)) {
|
if (_mouse_click_in(minX, minY, maxX, maxY)) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mouseX;
|
int mouseX;
|
||||||
int mouseY;
|
int mouseY;
|
||||||
mouseGetPosition(&mouseX, &mouseY);
|
mouseGetPosition(&mouseX, &mouseY);
|
||||||
|
|
||||||
int lineHeight = fontGetLineHeight();
|
int lineHeight = fontGetLineHeight();
|
||||||
int newValue = (mouseY - minY) / lineHeight;
|
int newValue = (mouseY - minY) / lineHeight;
|
||||||
if (newValue >= 6) {
|
if (newValue < 6) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int timestamp = getTicks();
|
unsigned int timestamp = getTicks();
|
||||||
if (newValue == value) {
|
if (newValue == value) {
|
||||||
if (getTicksBetween(timestamp, v53) < 250) {
|
if (getTicksBetween(timestamp, v53) < 250) {
|
||||||
|
@ -4185,6 +4173,10 @@ int _gdCustomSelect(int a1)
|
||||||
}
|
}
|
||||||
v53 = timestamp;
|
v53 = timestamp;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderPresent();
|
renderPresent();
|
||||||
sharedFpsLimiter.throttle();
|
sharedFpsLimiter.throttle();
|
||||||
|
|
|
@ -284,6 +284,10 @@ int gameMoviePlay(int movie, int flags)
|
||||||
|
|
||||||
windowDestroy(win);
|
windowDestroy(win);
|
||||||
|
|
||||||
|
// CE: Destroying a window redraws only content it was covering (centered
|
||||||
|
// 640x480). This leads to everything outside this rect to remain black.
|
||||||
|
windowRefreshAll(&_scr_size);
|
||||||
|
|
||||||
if ((flags & GAME_MOVIE_PAUSE_MUSIC) != 0) {
|
if ((flags & GAME_MOVIE_PAUSE_MUSIC) != 0) {
|
||||||
backgroundSoundResume();
|
backgroundSoundResume();
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,6 +307,8 @@ bool heapBlockAllocate(Heap* heap, int* handleIndexPtr, int size, int a4)
|
||||||
int blockSize;
|
int blockSize;
|
||||||
HeapHandle* handle;
|
HeapHandle* handle;
|
||||||
|
|
||||||
|
size += 4 - size % 4;
|
||||||
|
|
||||||
if (heap == NULL || handleIndexPtr == NULL || size == 0) {
|
if (heap == NULL || handleIndexPtr == NULL || size == 0) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1127,6 +1127,16 @@ static void opConditionalOperatorLessThanEquals(Program* program)
|
||||||
assert(false && "Should be unreachable");
|
assert(false && "Should be unreachable");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
// Nevada folks tend to use "object <= 0" to test objects for nulls.
|
||||||
|
case VALUE_TYPE_PTR:
|
||||||
|
switch (value[0].opcode) {
|
||||||
|
case VALUE_TYPE_INT:
|
||||||
|
result = (intptr_t)value[1].pointerValue <= (intptr_t)value[0].integerValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false && "Should be unreachable");
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false && "Should be unreachable");
|
assert(false && "Should be unreachable");
|
||||||
}
|
}
|
||||||
|
|
|
@ -545,7 +545,7 @@ static void opSetMapStart(Program* program)
|
||||||
}
|
}
|
||||||
|
|
||||||
int tile = 200 * y + x;
|
int tile = 200 * y + x;
|
||||||
if (tileSetCenter(tile, TILE_SET_CENTER_FLAG_0x01 | TILE_SET_CENTER_FLAG_0x02) != 0) {
|
if (tileSetCenter(tile, TILE_SET_CENTER_REFRESH_WINDOW | TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS) != 0) {
|
||||||
scriptError("\nScript Error: %s: op_set_map_start: tile_set_center failed", program->name);
|
scriptError("\nScript Error: %s: op_set_map_start: tile_set_center failed", program->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -584,7 +584,7 @@ static void opOverrideMapStart(Program* program)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tileSetCenter(tile, TILE_SET_CENTER_FLAG_0x01);
|
tileSetCenter(tile, TILE_SET_CENTER_REFRESH_WINDOW);
|
||||||
tileWindowRefresh();
|
tileWindowRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +866,7 @@ static void opMoveTo(Program* program)
|
||||||
Rect rect;
|
Rect rect;
|
||||||
newTile = objectSetLocation(object, tile, elevation, &rect);
|
newTile = objectSetLocation(object, tile, elevation, &rect);
|
||||||
if (newTile != -1) {
|
if (newTile != -1) {
|
||||||
tileSetCenter(object->tile, TILE_SET_CENTER_FLAG_0x01);
|
tileSetCenter(object->tile, TILE_SET_CENTER_REFRESH_WINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tileLimitingEnabled) {
|
if (tileLimitingEnabled) {
|
||||||
|
@ -2061,7 +2061,7 @@ static void opMetarule3(Program* program)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case METARULE3_TILE_SET_CENTER:
|
case METARULE3_TILE_SET_CENTER:
|
||||||
result.integerValue = tileSetCenter(param1.integerValue, TILE_SET_CENTER_FLAG_0x01);
|
result.integerValue = tileSetCenter(param1.integerValue, TILE_SET_CENTER_REFRESH_WINDOW);
|
||||||
break;
|
break;
|
||||||
case METARULE3_109:
|
case METARULE3_109:
|
||||||
result.integerValue = aiGetChemUse(static_cast<Object*>(param1.pointerValue));
|
result.integerValue = aiGetChemUse(static_cast<Object*>(param1.pointerValue));
|
||||||
|
@ -3158,7 +3158,7 @@ static void opFloatMessage(Program* program)
|
||||||
color = _colorTable[31744];
|
color = _colorTable[31744];
|
||||||
a5 = _colorTable[0];
|
a5 = _colorTable[0];
|
||||||
font = 103;
|
font = 103;
|
||||||
tileSetCenter(gDude->tile, TILE_SET_CENTER_FLAG_0x01);
|
tileSetCenter(gDude->tile, TILE_SET_CENTER_REFRESH_WINDOW);
|
||||||
break;
|
break;
|
||||||
case FLOATING_MESSAGE_TYPE_NORMAL:
|
case FLOATING_MESSAGE_TYPE_NORMAL:
|
||||||
case FLOATING_MESSAGE_TYPE_YELLOW:
|
case FLOATING_MESSAGE_TYPE_YELLOW:
|
||||||
|
|
|
@ -1465,8 +1465,9 @@ static void opSetTextColor(Program* program)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int arg = 0; arg < 3; arg++) {
|
for (int arg = 0; arg < 3; arg++) {
|
||||||
if (((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT && (value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_INT)
|
if ((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT
|
||||||
|| value[arg].floatValue == 0.0) {
|
&& (value[arg].opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT
|
||||||
|
&& value[arg].integerValue != 0) {
|
||||||
programFatalError("Invalid type given to settextcolor");
|
programFatalError("Invalid type given to settextcolor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1492,8 +1493,9 @@ static void opSayOptionColor(Program* program)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int arg = 0; arg < 3; arg++) {
|
for (int arg = 0; arg < 3; arg++) {
|
||||||
if (((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT && (value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_INT)
|
if ((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT
|
||||||
|| value[arg].floatValue == 0.0) {
|
&& (value[arg].opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT
|
||||||
|
&& value[arg].integerValue != 0) {
|
||||||
programFatalError("Invalid type given to sayoptioncolor");
|
programFatalError("Invalid type given to sayoptioncolor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1519,8 +1521,9 @@ static void opSayReplyColor(Program* program)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int arg = 0; arg < 3; arg++) {
|
for (int arg = 0; arg < 3; arg++) {
|
||||||
if (((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT && (value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_INT)
|
if ((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT
|
||||||
|| value[arg].floatValue == 0.0) {
|
&& (value[arg].opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT
|
||||||
|
&& value[arg].integerValue != 0) {
|
||||||
programFatalError("Invalid type given to sayreplycolor");
|
programFatalError("Invalid type given to sayreplycolor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1546,8 +1549,9 @@ static void opSetHighlightColor(Program* program)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int arg = 0; arg < 3; arg++) {
|
for (int arg = 0; arg < 3; arg++) {
|
||||||
if (((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT && (value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_INT)
|
if ((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT
|
||||||
|| value[arg].floatValue == 0.0) {
|
&& (value[arg].opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT
|
||||||
|
&& value[arg].integerValue != 0) {
|
||||||
programFatalError("Invalid type given to sayreplycolor");
|
programFatalError("Invalid type given to sayreplycolor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2434,13 +2434,13 @@ static int _SlotMap2Game(File* stream)
|
||||||
{
|
{
|
||||||
debugPrint("LOADSAVE: in SlotMap2Game\n");
|
debugPrint("LOADSAVE: in SlotMap2Game\n");
|
||||||
|
|
||||||
int v2;
|
int fileNameListLength;
|
||||||
if (fileReadInt32(stream, &v2) == 1) {
|
if (fileReadInt32(stream, &fileNameListLength) == -1) {
|
||||||
debugPrint("LOADSAVE: returning 1\n");
|
debugPrint("LOADSAVE: returning 1\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v2 == 0) {
|
if (fileNameListLength == 0) {
|
||||||
debugPrint("LOADSAVE: returning 2\n");
|
debugPrint("LOADSAVE: returning 2\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2467,13 +2467,12 @@ static int _SlotMap2Game(File* stream)
|
||||||
sprintf(_str0, "%s\\%s\\%s", _patches, "MAPS", "AUTOMAP.DB");
|
sprintf(_str0, "%s\\%s\\%s", _patches, "MAPS", "AUTOMAP.DB");
|
||||||
compat_remove(_str0);
|
compat_remove(_str0);
|
||||||
|
|
||||||
if (gPartyMemberDescriptionsLength > 1) {
|
|
||||||
for (int index = 1; index < gPartyMemberDescriptionsLength; index += 1) {
|
for (int index = 1; index < gPartyMemberDescriptionsLength; index += 1) {
|
||||||
int pid = gPartyMemberPids[index];
|
int pid = gPartyMemberPids[index];
|
||||||
if (pid != -2) {
|
if (pid != -2) {
|
||||||
char protoPath[COMPAT_MAX_PATH];
|
char protoPath[COMPAT_MAX_PATH];
|
||||||
if (_proto_list_str(pid, protoPath) == 0) {
|
if (_proto_list_str(pid, protoPath) == 0) {
|
||||||
const char* basePath = pid >> 24 == OBJ_TYPE_CRITTER
|
const char* basePath = PID_TYPE(pid) == OBJ_TYPE_CRITTER
|
||||||
? PROTO_DIR_NAME "\\" CRITTERS_DIR_NAME
|
? PROTO_DIR_NAME "\\" CRITTERS_DIR_NAME
|
||||||
: PROTO_DIR_NAME "\\" ITEMS_DIR_NAME;
|
: PROTO_DIR_NAME "\\" ITEMS_DIR_NAME;
|
||||||
sprintf(_str0, "%s\\%s\\%s", _patches, basePath, protoPath);
|
sprintf(_str0, "%s\\%s\\%s", _patches, basePath, protoPath);
|
||||||
|
@ -2486,27 +2485,24 @@ static int _SlotMap2Game(File* stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (v2 > 0) {
|
for (int index = 0; index < fileNameListLength; index += 1) {
|
||||||
for (int index = 0; index < v2; index += 1) {
|
char fileName[COMPAT_MAX_PATH];
|
||||||
char v11[64]; // TODO: Size is probably wrong.
|
if (_mygets(fileName, stream) == -1) {
|
||||||
if (_mygets(v11, stream) == -1) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(_str0, "%s\\%s\\%s%.2d\\%s", _patches, "SAVEGAME", "SLOT", _slot_cursor + 1, v11);
|
sprintf(_str0, "%s\\%s\\%s%.2d\\%s", _patches, "SAVEGAME", "SLOT", _slot_cursor + 1, fileName);
|
||||||
sprintf(_str1, "%s\\%s\\%s", _patches, "MAPS", v11);
|
sprintf(_str1, "%s\\%s\\%s", _patches, "MAPS", fileName);
|
||||||
|
|
||||||
if (_gzdecompress_file(_str0, _str1) == -1) {
|
if (_gzdecompress_file(_str0, _str1) == -1) {
|
||||||
debugPrint("LOADSAVE: returning 7\n");
|
debugPrint("LOADSAVE: returning 7\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const char* v9 = _strmfe(_str1, "AUTOMAP.DB", "SAV");
|
const char* automapFileName = _strmfe(_str1, "AUTOMAP.DB", "SAV");
|
||||||
sprintf(_str0, "%s\\%s\\%s%.2d\\%s", _patches, "SAVEGAME", "SLOT", _slot_cursor + 1, v9);
|
sprintf(_str0, "%s\\%s\\%s%.2d\\%s", _patches, "SAVEGAME", "SLOT", _slot_cursor + 1, automapFileName);
|
||||||
sprintf(_str1, "%s\\%s\\%s", _patches, "MAPS", "AUTOMAP.DB");
|
sprintf(_str1, "%s\\%s\\%s", _patches, "MAPS", "AUTOMAP.DB");
|
||||||
if (fileCopyDecompressed(_str0, _str1) == -1) {
|
if (fileCopyDecompressed(_str0, _str1) == -1) {
|
||||||
debugPrint("LOADSAVE: returning 8\n");
|
debugPrint("LOADSAVE: returning 8\n");
|
||||||
|
|
|
@ -707,7 +707,7 @@ int mapSetEnteringLocation(int elevation, int tile_num, int orientation)
|
||||||
void mapNewMap()
|
void mapNewMap()
|
||||||
{
|
{
|
||||||
mapSetElevation(0);
|
mapSetElevation(0);
|
||||||
tileSetCenter(20100, TILE_SET_CENTER_FLAG_0x02);
|
tileSetCenter(20100, TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS);
|
||||||
memset(&gMapTransition, 0, sizeof(gMapTransition));
|
memset(&gMapTransition, 0, sizeof(gMapTransition));
|
||||||
gMapHeader.enteringElevation = 0;
|
gMapHeader.enteringElevation = 0;
|
||||||
gMapHeader.enteringRotation = 0;
|
gMapHeader.enteringRotation = 0;
|
||||||
|
@ -894,7 +894,7 @@ static int mapLoad(File* stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
error = "Error setting tile center";
|
error = "Error setting tile center";
|
||||||
if (tileSetCenter(gEnteringTile, TILE_SET_CENTER_FLAG_0x02) != 0) {
|
if (tileSetCenter(gEnteringTile, TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS) != 0) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1240,7 +1240,7 @@ int mapHandleTransition()
|
||||||
objectSetRotation(gDude, gMapTransition.rotation, NULL);
|
objectSetRotation(gDude, gMapTransition.rotation, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tileSetCenter(gDude->tile, TILE_SET_CENTER_FLAG_0x01) == -1) {
|
if (tileSetCenter(gDude->tile, TILE_SET_CENTER_REFRESH_WINDOW) == -1) {
|
||||||
debugPrint("\nError: map: attempt to center out-of-bounds!");
|
debugPrint("\nError: map: attempt to center out-of-bounds!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ static void* memoryBlockMallocImpl(size_t size)
|
||||||
|
|
||||||
if (size != 0) {
|
if (size != 0) {
|
||||||
size += sizeof(MemoryBlockHeader) + sizeof(MemoryBlockFooter);
|
size += sizeof(MemoryBlockHeader) + sizeof(MemoryBlockFooter);
|
||||||
|
size += sizeof(int) - size % sizeof(int);
|
||||||
|
|
||||||
unsigned char* block = (unsigned char*)malloc(size);
|
unsigned char* block = (unsigned char*)malloc(size);
|
||||||
if (block != NULL) {
|
if (block != NULL) {
|
||||||
|
@ -123,6 +124,7 @@ static void* memoryBlockReallocImpl(void* ptr, size_t size)
|
||||||
|
|
||||||
if (size != 0) {
|
if (size != 0) {
|
||||||
size += sizeof(MemoryBlockHeader) + sizeof(MemoryBlockFooter);
|
size += sizeof(MemoryBlockHeader) + sizeof(MemoryBlockFooter);
|
||||||
|
size += sizeof(int) - size % sizeof(int);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* newBlock = (unsigned char*)realloc(block, size);
|
unsigned char* newBlock = (unsigned char*)realloc(block, size);
|
||||||
|
|
|
@ -185,7 +185,7 @@ static int _obj_last_roof_y = -1;
|
||||||
static int _obj_last_elev = -1;
|
static int _obj_last_elev = -1;
|
||||||
|
|
||||||
// 0x51977C
|
// 0x51977C
|
||||||
static int _obj_last_is_empty = 1;
|
static bool _obj_last_is_empty = true;
|
||||||
|
|
||||||
// 0x519780
|
// 0x519780
|
||||||
unsigned char* _wallBlendTable = NULL;
|
unsigned char* _wallBlendTable = NULL;
|
||||||
|
@ -1492,21 +1492,24 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
||||||
// NOTE: Uninline.
|
// NOTE: Uninline.
|
||||||
obj_set_seen(tile);
|
obj_set_seen(tile);
|
||||||
|
|
||||||
int v14 = tile % 200 / 2;
|
int roofX = tile % 200 / 2;
|
||||||
int v15 = tile / 200 / 2;
|
int roofY = tile / 200 / 2;
|
||||||
if (v14 != _obj_last_roof_x || v15 != _obj_last_roof_y || elevation != _obj_last_elev) {
|
if (roofX != _obj_last_roof_x || roofY != _obj_last_roof_y || elevation != _obj_last_elev) {
|
||||||
int v16 = _square[elevation]->field_0[v14 + 100 * v15];
|
int currentSquare = _square[elevation]->field_0[roofX + 100 * roofY];
|
||||||
int v31 = buildFid(OBJ_TYPE_TILE, (v16 >> 16) & 0xFFF, 0, 0, 0);
|
int currentSquareFid = buildFid(OBJ_TYPE_TILE, (currentSquare >> 16) & 0xFFF, 0, 0, 0);
|
||||||
int v32 = _square[elevation]->field_0[_obj_last_roof_x + 100 * _obj_last_roof_y];
|
// CE: Add additional checks for -1 to prevent array lookup at index -101.
|
||||||
int v34 = buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0) == v31;
|
int previousSquare = _obj_last_roof_x != -1 && _obj_last_roof_y != -1
|
||||||
|
? _square[elevation]->field_0[_obj_last_roof_x + 100 * _obj_last_roof_y]
|
||||||
|
: 0;
|
||||||
|
bool isEmpty = buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0) == currentSquareFid;
|
||||||
|
|
||||||
if (v34 != _obj_last_is_empty || (((v16 >> 16) & 0xF000) >> 12) != (((v32 >> 16) & 0xF000) >> 12)) {
|
if (isEmpty != _obj_last_is_empty || (((currentSquare >> 16) & 0xF000) >> 12) != (((previousSquare >> 16) & 0xF000) >> 12)) {
|
||||||
if (_obj_last_is_empty == 0) {
|
if (!_obj_last_is_empty) {
|
||||||
_tile_fill_roof(_obj_last_roof_x, _obj_last_roof_y, elevation, 1);
|
_tile_fill_roof(_obj_last_roof_x, _obj_last_roof_y, elevation, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v34 == 0) {
|
if (!isEmpty) {
|
||||||
_tile_fill_roof(v14, v15, elevation, 0);
|
_tile_fill_roof(roofX, roofY, elevation, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rect != NULL) {
|
if (rect != NULL) {
|
||||||
|
@ -1514,10 +1517,10 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_obj_last_roof_x = v14;
|
_obj_last_roof_x = roofX;
|
||||||
_obj_last_roof_y = v15;
|
_obj_last_roof_y = roofY;
|
||||||
_obj_last_elev = elevation;
|
_obj_last_elev = elevation;
|
||||||
_obj_last_is_empty = v34;
|
_obj_last_is_empty = isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rect != NULL) {
|
if (rect != NULL) {
|
||||||
|
@ -1530,7 +1533,7 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
||||||
|
|
||||||
if (elevation != oldElevation) {
|
if (elevation != oldElevation) {
|
||||||
mapSetElevation(elevation);
|
mapSetElevation(elevation);
|
||||||
tileSetCenter(tile, TILE_SET_CENTER_FLAG_0x01 | TILE_SET_CENTER_FLAG_0x02);
|
tileSetCenter(tile, TILE_SET_CENTER_REFRESH_WINDOW | TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS);
|
||||||
if (isInCombat()) {
|
if (isInCombat()) {
|
||||||
_game_user_wants_to_quit = 1;
|
_game_user_wants_to_quit = 1;
|
||||||
}
|
}
|
||||||
|
@ -2183,7 +2186,7 @@ void _obj_remove_all()
|
||||||
|
|
||||||
_obj_last_roof_y = -1;
|
_obj_last_roof_y = -1;
|
||||||
_obj_last_elev = -1;
|
_obj_last_elev = -1;
|
||||||
_obj_last_is_empty = 1;
|
_obj_last_is_empty = true;
|
||||||
_obj_last_roof_x = -1;
|
_obj_last_roof_x = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3335,7 +3338,7 @@ static int _obj_offset_table_init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tileSetCenter(gCenterTile + 1, 2) == -1) {
|
if (tileSetCenter(gCenterTile + 1, TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS) == -1) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3753,7 +3756,7 @@ int _obj_load_dude(File* stream)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tileSetCenter(tile, TILE_SET_CENTER_FLAG_0x01 | TILE_SET_CENTER_FLAG_0x02);
|
tileSetCenter(tile, TILE_SET_CENTER_REFRESH_WINDOW | TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,6 @@ typedef enum PreferencesWindowFrm {
|
||||||
PREFERENCES_WINDOW_FRM_COUNT,
|
PREFERENCES_WINDOW_FRM_COUNT,
|
||||||
} PreferencesWindowFrm;
|
} PreferencesWindowFrm;
|
||||||
|
|
||||||
#pragma pack(2)
|
|
||||||
typedef struct PreferenceDescription {
|
typedef struct PreferenceDescription {
|
||||||
// The number of options.
|
// The number of options.
|
||||||
short valuesCount;
|
short valuesCount;
|
||||||
|
@ -129,7 +128,6 @@ typedef struct PreferenceDescription {
|
||||||
double maxValue;
|
double maxValue;
|
||||||
int* valuePtr;
|
int* valuePtr;
|
||||||
} PreferenceDescription;
|
} PreferenceDescription;
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
static int optionsWindowInit();
|
static int optionsWindowInit();
|
||||||
static int optionsWindowFree();
|
static int optionsWindowFree();
|
||||||
|
@ -496,7 +494,7 @@ int showOptionsWithInitialKeyCode(int initialKeyCode)
|
||||||
case KEY_UPPERCASE_S:
|
case KEY_UPPERCASE_S:
|
||||||
case KEY_LOWERCASE_S:
|
case KEY_LOWERCASE_S:
|
||||||
case 500:
|
case 500:
|
||||||
if (lsgSaveGame(1) != 1) {
|
if (lsgSaveGame(LOAD_SAVE_MODE_NORMAL) == 1) {
|
||||||
rc = 1;
|
rc = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -239,7 +239,7 @@ int _proto_list_str(int pid, char* proto_path)
|
||||||
*pch = '\0';
|
*pch = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
pch = strchr(string, '\n');
|
pch = strpbrk(string, "\r\n");
|
||||||
if (pch != NULL) {
|
if (pch != NULL) {
|
||||||
*pch = '\0';
|
*pch = '\0';
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "platform_compat.h"
|
#include "platform_compat.h"
|
||||||
#include "scripts.h"
|
#include "scripts.h"
|
||||||
|
@ -37,7 +39,7 @@ static int _idum;
|
||||||
void randomInit()
|
void randomInit()
|
||||||
{
|
{
|
||||||
unsigned int randomSeed = randomGetSeed();
|
unsigned int randomSeed = randomGetSeed();
|
||||||
srand(randomSeed);
|
std::srand(randomSeed);
|
||||||
|
|
||||||
int pseudorandomSeed = randomInt32();
|
int pseudorandomSeed = randomInt32();
|
||||||
randomSeedPrerandomInternal(pseudorandomSeed);
|
randomSeedPrerandomInternal(pseudorandomSeed);
|
||||||
|
@ -183,10 +185,7 @@ void randomSeedPrerandom(int seed)
|
||||||
// 0x4A31C4
|
// 0x4A31C4
|
||||||
static int randomInt32()
|
static int randomInt32()
|
||||||
{
|
{
|
||||||
int high = rand() << 16;
|
return std::rand();
|
||||||
int low = rand();
|
|
||||||
|
|
||||||
return (high + low) & INT_MAX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4A31E0
|
// 0x4A31E0
|
||||||
|
|
|
@ -2354,6 +2354,11 @@ int _scr_remove_all()
|
||||||
} else {
|
} else {
|
||||||
next = scriptListExtent->next;
|
next = scriptListExtent->next;
|
||||||
scriptRemove(script->sid);
|
scriptRemove(script->sid);
|
||||||
|
|
||||||
|
// CE: Current extent is freed in |scriptRemove|. Break
|
||||||
|
// to prevent next iteration which needs to dereference
|
||||||
|
// extent to obtain it's length.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace fallout {
|
||||||
#define SFALL_CONFIG_GAME_DIALOG_FIX_KEY "DialogueFix"
|
#define SFALL_CONFIG_GAME_DIALOG_FIX_KEY "DialogueFix"
|
||||||
#define SFALL_CONFIG_TWEAKS_FILE_KEY "TweaksFile"
|
#define SFALL_CONFIG_TWEAKS_FILE_KEY "TweaksFile"
|
||||||
#define SFALL_CONFIG_GAME_DIALOG_GENDER_WORDS_KEY "DialogGenderWords"
|
#define SFALL_CONFIG_GAME_DIALOG_GENDER_WORDS_KEY "DialogGenderWords"
|
||||||
#define SFALL_CONFIG_TOWN_MAP_HOTKEYS_FIX "TownMapHotkeysFix"
|
#define SFALL_CONFIG_TOWN_MAP_HOTKEYS_FIX_KEY "TownMapHotkeysFix"
|
||||||
|
|
||||||
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER 1
|
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER 1
|
||||||
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR 3
|
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR 3
|
||||||
|
|
32
src/tile.cc
32
src/tile.cc
|
@ -207,7 +207,7 @@ static Rect gTileWindowRect;
|
||||||
static unsigned char _tile_grid[32 * 16];
|
static unsigned char _tile_grid[32 * 16];
|
||||||
|
|
||||||
// 0x66BDE4
|
// 0x66BDE4
|
||||||
static int _square_rect;
|
static int _square_y;
|
||||||
|
|
||||||
// 0x66BDE8
|
// 0x66BDE8
|
||||||
static int _square_x;
|
static int _square_x;
|
||||||
|
@ -433,7 +433,7 @@ int tileInit(TileData** a1, int squareGridWidth, int squareGridHeight, int hexGr
|
||||||
gTileWindowWidth = ORIGINAL_ISO_WINDOW_WIDTH;
|
gTileWindowWidth = ORIGINAL_ISO_WINDOW_WIDTH;
|
||||||
gTileWindowHeight = ORIGINAL_ISO_WINDOW_HEIGHT;
|
gTileWindowHeight = ORIGINAL_ISO_WINDOW_HEIGHT;
|
||||||
|
|
||||||
tileSetCenter(hexGridWidth * (hexGridHeight / 2) + hexGridWidth / 2, 2);
|
tileSetCenter(hexGridWidth * (hexGridHeight / 2) + hexGridWidth / 2, TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS);
|
||||||
tileSetBorder(windowWidth, windowHeight, hexGridWidth, hexGridHeight);
|
tileSetBorder(windowWidth, windowHeight, hexGridWidth, hexGridHeight);
|
||||||
|
|
||||||
// Restore actual window size and set center one more time to calculate
|
// Restore actual window size and set center one more time to calculate
|
||||||
|
@ -442,7 +442,7 @@ int tileInit(TileData** a1, int squareGridWidth, int squareGridHeight, int hexGr
|
||||||
gTileWindowWidth = windowWidth;
|
gTileWindowWidth = windowWidth;
|
||||||
gTileWindowHeight = windowHeight;
|
gTileWindowHeight = windowHeight;
|
||||||
|
|
||||||
tileSetCenter(hexGridWidth * (hexGridHeight / 2) + hexGridWidth / 2, 2);
|
tileSetCenter(hexGridWidth * (hexGridHeight / 2) + hexGridWidth / 2, TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS);
|
||||||
|
|
||||||
if (compat_stricmp(settings.system.executable.c_str(), "mapper") == 0) {
|
if (compat_stricmp(settings.system.executable.c_str(), "mapper") == 0) {
|
||||||
gTileWindowRefreshElevationProc = tileRefreshMapper;
|
gTileWindowRefreshElevationProc = tileRefreshMapper;
|
||||||
|
@ -533,7 +533,8 @@ int tileSetCenter(int tile, int flags)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gTileScrollLimitingEnabled & ((flags & TILE_SET_CENTER_FLAG_0x02) == 0)) != 0) {
|
if ((flags & TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS) == 0) {
|
||||||
|
if (gTileScrollLimitingEnabled) {
|
||||||
int tileScreenX;
|
int tileScreenX;
|
||||||
int tileScreenY;
|
int tileScreenY;
|
||||||
tileToScreenXY(tile, &tileScreenX, &tileScreenY, gElevation);
|
tileToScreenXY(tile, &tileScreenX, &tileScreenY, gElevation);
|
||||||
|
@ -553,11 +554,12 @@ int tileSetCenter(int tile, int flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gTileScrollBlockingEnabled & ((flags & TILE_SET_CENTER_FLAG_0x02) == 0)) != 0) {
|
if (gTileScrollBlockingEnabled) {
|
||||||
if (_obj_scroll_blocking_at(tile, gElevation) == 0) {
|
if (_obj_scroll_blocking_at(tile, gElevation) == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int tile_x = gHexGridWidth - 1 - tile % gHexGridWidth;
|
int tile_x = gHexGridWidth - 1 - tile % gHexGridWidth;
|
||||||
int tile_y = tile / gHexGridWidth;
|
int tile_y = tile / gHexGridWidth;
|
||||||
|
@ -579,7 +581,7 @@ int tileSetCenter(int tile, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
_square_x = _tile_x / 2;
|
_square_x = _tile_x / 2;
|
||||||
_square_rect = _tile_y / 2;
|
_square_y = _tile_y / 2;
|
||||||
_square_offx = _tile_offx - 16;
|
_square_offx = _tile_offx - 16;
|
||||||
_square_offy = _tile_offy - 2;
|
_square_offy = _tile_offy - 2;
|
||||||
|
|
||||||
|
@ -590,7 +592,7 @@ int tileSetCenter(int tile, int flags)
|
||||||
|
|
||||||
gCenterTile = tile;
|
gCenterTile = tile;
|
||||||
|
|
||||||
if (flags & TILE_SET_CENTER_FLAG_0x01) {
|
if ((flags & TILE_SET_CENTER_REFRESH_WINDOW) != 0) {
|
||||||
// NOTE: Uninline.
|
// NOTE: Uninline.
|
||||||
tileWindowRefresh();
|
tileWindowRefresh();
|
||||||
}
|
}
|
||||||
|
@ -1080,7 +1082,7 @@ int squareTileToScreenXY(int squareTile, int* coordX, int* coordY, int elevation
|
||||||
*coordX += 48 * v8;
|
*coordX += 48 * v8;
|
||||||
*coordY -= 12 * v8;
|
*coordY -= 12 * v8;
|
||||||
|
|
||||||
v9 = v6 - _square_rect;
|
v9 = v6 - _square_y;
|
||||||
*coordX += 32 * v9;
|
*coordX += 32 * v9;
|
||||||
*coordY += 24 * v9;
|
*coordY += 24 * v9;
|
||||||
|
|
||||||
|
@ -1111,7 +1113,7 @@ int squareTileToRoofScreenXY(int squareTile, int* screenX, int* screenY, int ele
|
||||||
*screenX += 48 * v8;
|
*screenX += 48 * v8;
|
||||||
*screenY -= 12 * v8;
|
*screenY -= 12 * v8;
|
||||||
|
|
||||||
v9 = v6 - _square_rect;
|
v9 = v6 - _square_y;
|
||||||
*screenX += 32 * v9;
|
*screenX += 32 * v9;
|
||||||
v10 = 24 * v9 + *screenY;
|
v10 = 24 * v9 + *screenY;
|
||||||
*screenY = v10;
|
*screenY = v10;
|
||||||
|
@ -1149,12 +1151,10 @@ void squareTileScreenToCoord(int screenX, int screenY, int elevation, int* coord
|
||||||
*coordX = v6 >= 0 ? (v6 / 192) : ((v6 + 1) / 192 - 1);
|
*coordX = v6 >= 0 ? (v6 / 192) : ((v6 + 1) / 192 - 1);
|
||||||
|
|
||||||
v8 = 4 * v5 + v4;
|
v8 = 4 * v5 + v4;
|
||||||
*coordY = v8 >= 0
|
*coordY = v8 >= 0 ? (v8 / 128) : ((v8 + 1) / 128 - 1);
|
||||||
? ((v8 - ((v8 >> 31) << 7)) >> 7)
|
|
||||||
: ((((v8 + 1) - (((v8 + 1) >> 31) << 7)) >> 7) - 1);
|
|
||||||
|
|
||||||
*coordX += _square_x;
|
*coordX += _square_x;
|
||||||
*coordY += _square_rect;
|
*coordY += _square_y;
|
||||||
|
|
||||||
*coordX = gSquareGridWidth - 1 - *coordX;
|
*coordX = gSquareGridWidth - 1 - *coordX;
|
||||||
}
|
}
|
||||||
|
@ -1174,12 +1174,10 @@ void squareTileScreenToCoordRoof(int screenX, int screenY, int elevation, int* c
|
||||||
*coordX = (v6 >= 0) ? (v6 / 192) : ((v6 + 1) / 192 - 1);
|
*coordX = (v6 >= 0) ? (v6 / 192) : ((v6 + 1) / 192 - 1);
|
||||||
|
|
||||||
v8 = 4 * v5 + v4;
|
v8 = 4 * v5 + v4;
|
||||||
*coordY = (v8 >= 0)
|
*coordY = v8 >= 0 ? (v8 / 128) : ((v8 + 1) / 128 - 1);
|
||||||
? ((v8 - ((v8 >> 31) << 7)) >> 7)
|
|
||||||
: ((((v8 + 1) - (((v8 + 1) >> 31) << 7)) >> 7) - 1);
|
|
||||||
|
|
||||||
*coordX += _square_x;
|
*coordX += _square_x;
|
||||||
*coordY += _square_rect;
|
*coordY += _square_y;
|
||||||
|
|
||||||
*coordX = gSquareGridWidth - 1 - *coordX;
|
*coordX = gSquareGridWidth - 1 - *coordX;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
namespace fallout {
|
namespace fallout {
|
||||||
|
|
||||||
#define TILE_SET_CENTER_FLAG_0x01 0x01
|
#define TILE_SET_CENTER_REFRESH_WINDOW 0x01
|
||||||
#define TILE_SET_CENTER_FLAG_0x02 0x02
|
#define TILE_SET_CENTER_FLAG_IGNORE_SCROLL_RESTRICTIONS 0x02
|
||||||
|
|
||||||
typedef void(TileWindowRefreshProc)(Rect* rect);
|
typedef void(TileWindowRefreshProc)(Rect* rect);
|
||||||
typedef void(TileWindowRefreshElevationProc)(Rect* rect, int elevation);
|
typedef void(TileWindowRefreshElevationProc)(Rect* rect, int elevation);
|
||||||
|
|
|
@ -887,7 +887,7 @@ int _selectWindow(const char* windowName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_selectWindowID(index)) {
|
if (_selectWindowID(index)) {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1725,7 +1725,7 @@ bool _windowAddButtonGfx(const char* buttonName, char* pressedFileName, char* no
|
||||||
// 0x4BA11C
|
// 0x4BA11C
|
||||||
bool _windowAddButtonProc(const char* buttonName, Program* program, int mouseEnterProc, int mouseExitProc, int mouseDownProc, int mouseUpProc)
|
bool _windowAddButtonProc(const char* buttonName, Program* program, int mouseEnterProc, int mouseExitProc, int mouseDownProc, int mouseUpProc)
|
||||||
{
|
{
|
||||||
if (gCurrentManagedWindowIndex != -1) {
|
if (gCurrentManagedWindowIndex == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -847,7 +847,16 @@ int wmWorldMap_init()
|
||||||
|
|
||||||
// SFALL
|
// SFALL
|
||||||
gTownMapHotkeysFix = true;
|
gTownMapHotkeysFix = true;
|
||||||
configGetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_TOWN_MAP_HOTKEYS_FIX, &gTownMapHotkeysFix);
|
configGetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_TOWN_MAP_HOTKEYS_FIX_KEY, &gTownMapHotkeysFix);
|
||||||
|
|
||||||
|
// CE: City size fids should be initialized during startup. They are used
|
||||||
|
// during |wmTeleportToArea| to calculate worldmap position when jumping
|
||||||
|
// from Temple to Arroyo - before giving a chance to |wmInterfaceInit| to
|
||||||
|
// initialize it.
|
||||||
|
for (int citySize = 0; citySize < CITY_SIZE_COUNT; citySize++) {
|
||||||
|
CitySizeDescription* citySizeDescription = &(wmSphereData[citySize]);
|
||||||
|
citySizeDescription->fid = buildFid(OBJ_TYPE_INTERFACE, 336 + citySize, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1397,7 +1406,17 @@ static int wmParseEncounterTableIndex(EncounterEntry* entry, char* string)
|
||||||
|
|
||||||
if (strstr(string, "special")) {
|
if (strstr(string, "special")) {
|
||||||
entry->flags |= ENCOUNTER_ENTRY_SPECIAL;
|
entry->flags |= ENCOUNTER_ENTRY_SPECIAL;
|
||||||
string += 8;
|
|
||||||
|
// CE: Original code unconditionally consumes 8 characters, which is
|
||||||
|
// right when "special" is followed by conditions (separated with
|
||||||
|
// comma). However when "special" is the last keyword (which I guess
|
||||||
|
// is wrong, but present in worldmap.txt), consuming 8 characters
|
||||||
|
// sets pointer past NULL terminator, which can lead to many bad
|
||||||
|
// things (UB).
|
||||||
|
string += 7;
|
||||||
|
if (*string != '\0') {
|
||||||
|
string++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string != NULL) {
|
if (string != NULL) {
|
||||||
|
@ -4459,11 +4478,7 @@ static int wmInterfaceInit()
|
||||||
|
|
||||||
for (int citySize = 0; citySize < CITY_SIZE_COUNT; citySize++) {
|
for (int citySize = 0; citySize < CITY_SIZE_COUNT; citySize++) {
|
||||||
CitySizeDescription* citySizeDescription = &(wmSphereData[citySize]);
|
CitySizeDescription* citySizeDescription = &(wmSphereData[citySize]);
|
||||||
|
if (!citySizeDescription->frmImage.lock(citySizeDescription->fid)) {
|
||||||
fid = buildFid(OBJ_TYPE_INTERFACE, 336 + citySize, 0, 0, 0);
|
|
||||||
citySizeDescription->fid = fid;
|
|
||||||
|
|
||||||
if (!citySizeDescription->frmImage.lock(fid)) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6530,9 +6545,21 @@ int wmTeleportToArea(int areaIdx)
|
||||||
// locations.
|
// locations.
|
||||||
// CE: See `wmWorldMapFunc` for explanation.
|
// CE: See `wmWorldMapFunc` for explanation.
|
||||||
CitySizeDescription* citySizeDescription = &(wmSphereData[city->size]);
|
CitySizeDescription* citySizeDescription = &(wmSphereData[city->size]);
|
||||||
|
|
||||||
|
// CE: This function might be called outside |wmWorldmapFunc|, so it's
|
||||||
|
// image might not be locked.
|
||||||
|
bool wasLocked = citySizeDescription->frmImage.isLocked();
|
||||||
|
if (!wasLocked) {
|
||||||
|
citySizeDescription->frmImage.lock(citySizeDescription->fid);
|
||||||
|
}
|
||||||
|
|
||||||
wmGenData.worldPosX = city->x + citySizeDescription->frmImage.getWidth() / 2 - WM_VIEW_X;
|
wmGenData.worldPosX = city->x + citySizeDescription->frmImage.getWidth() / 2 - WM_VIEW_X;
|
||||||
wmGenData.worldPosY = city->y + citySizeDescription->frmImage.getHeight() / 2 - WM_VIEW_Y;
|
wmGenData.worldPosY = city->y + citySizeDescription->frmImage.getHeight() / 2 - WM_VIEW_Y;
|
||||||
|
|
||||||
|
if (!wasLocked) {
|
||||||
|
citySizeDescription->frmImage.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue