From 629978d7a6acc865ef2cebf0628882abd21bdd4e Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Thu, 1 Sep 2022 18:41:37 +0300 Subject: [PATCH] Reconcile with reference edition --- src/actions.cc | 65 +++---- src/animation.cc | 157 ++++++++------- src/character_editor.cc | 4 +- src/combat.cc | 142 ++++++++------ src/combat_ai.cc | 77 ++++++-- src/critter.cc | 17 +- src/debug.cc | 91 ++++++++- src/dialog.cc | 11 +- src/display_monitor.cc | 43 +++-- src/game.cc | 64 ++++-- src/game.h | 9 + src/game_dialog.cc | 164 +++++++++++----- src/game_mouse.cc | 42 +++- src/game_mouse.h | 1 + src/game_movie.cc | 11 +- src/interface.cc | 172 +++++++++++------ src/interface.h | 1 + src/interpreter.cc | 408 ++++++++++++++++++++++++--------------- src/interpreter.h | 22 ++- src/interpreter_extra.cc | 4 +- src/interpreter_lib.cc | 158 +++++++++++++-- src/inventory.cc | 2 +- src/main.cc | 172 +++++++++++++---- src/memory.cc | 39 ++-- src/scripts.cc | 5 +- src/skill.cc | 16 +- src/widget.cc | 70 ------- src/widget.h | 7 - src/window.cc | 97 ++++++++-- src/window.h | 18 +- src/window_manager.cc | 22 ++- src/world_map.cc | 384 +++++++++++++++++++++--------------- src/world_map.h | 2 +- 33 files changed, 1641 insertions(+), 856 deletions(-) diff --git a/src/actions.cc b/src/actions.cc index 598d4c6..7a88bbc 100644 --- a/src/actions.cc +++ b/src/actions.cc @@ -81,6 +81,7 @@ static int _action_melee(Attack* attack, int a2); static int _action_ranged(Attack* attack, int a2); static int _is_next_to(Object* a1, Object* a2); static int _action_climb_ladder(Object* a1, Object* a2); +static int _action_use_skill_in_combat_error(Object* critter); static int _pick_fall(Object* obj, int anim); static int _report_explosion(Attack* attack, Object* a2); static int _finished_explosion(Object* a1, Object* a2); @@ -1289,23 +1290,33 @@ int _action_skill_use(int skill) return -1; } +// NOTE: Inlined. +// +// 0x412500 +static int _action_use_skill_in_combat_error(Object* critter) +{ + MessageListItem messageListItem; + + if (critter == gDude) { + messageListItem.num = 902; + if (messageListGetItem(&gProtoMessageList, &messageListItem) == 1) { + displayMonitorAddMessage(messageListItem.text); + } + } + + return -1; +} + // skill_use // 0x41255C int actionUseSkill(Object* a1, Object* a2, int skill) { - MessageListItem messageListItem; - switch (skill) { case SKILL_FIRST_AID: case SKILL_DOCTOR: if (isInCombat()) { - if (a1 == gDude) { - messageListItem.num = 902; - if (messageListGetItem(&gProtoMessageList, &messageListItem)) { - displayMonitorAddMessage(messageListItem.text); - } - } - return -1; + // NOTE: Uninline. + return _action_use_skill_in_combat_error(a1); } if (PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) { @@ -1314,13 +1325,8 @@ int actionUseSkill(Object* a1, Object* a2, int skill) break; case SKILL_LOCKPICK: if (isInCombat()) { - if (a1 == gDude) { - messageListItem.num = 902; - if (messageListGetItem(&gProtoMessageList, &messageListItem)) { - displayMonitorAddMessage(messageListItem.text); - } - } - return -1; + // NOTE: Uninline. + return _action_use_skill_in_combat_error(a1); } if (PID_TYPE(a2->pid) != OBJ_TYPE_ITEM && PID_TYPE(a2->pid) != OBJ_TYPE_SCENERY) { @@ -1330,13 +1336,8 @@ int actionUseSkill(Object* a1, Object* a2, int skill) break; case SKILL_STEAL: if (isInCombat()) { - if (a1 == gDude) { - messageListItem.num = 902; - if (messageListGetItem(&gProtoMessageList, &messageListItem)) { - displayMonitorAddMessage(messageListItem.text); - } - } - return -1; + // NOTE: Uninline. + return _action_use_skill_in_combat_error(a1); } if (PID_TYPE(a2->pid) != OBJ_TYPE_ITEM && PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) { @@ -1350,13 +1351,8 @@ int actionUseSkill(Object* a1, Object* a2, int skill) break; case SKILL_TRAPS: if (isInCombat()) { - if (a1 == gDude) { - messageListItem.num = 902; - if (messageListGetItem(&gProtoMessageList, &messageListItem)) { - displayMonitorAddMessage(messageListItem.text); - } - } - return -1; + // NOTE: Uninline. + return _action_use_skill_in_combat_error(a1); } if (PID_TYPE(a2->pid) == OBJ_TYPE_CRITTER) { @@ -1367,13 +1363,8 @@ int actionUseSkill(Object* a1, Object* a2, int skill) case SKILL_SCIENCE: case SKILL_REPAIR: if (isInCombat()) { - if (a1 == gDude) { - messageListItem.num = 902; - if (messageListGetItem(&gProtoMessageList, &messageListItem)) { - displayMonitorAddMessage(messageListItem.text); - } - } - return -1; + // NOTE: Uninline. + return _action_use_skill_in_combat_error(a1); } if (PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) { diff --git a/src/animation.cc b/src/animation.cc index ab555e4..426ad43 100644 --- a/src/animation.cc +++ b/src/animation.cc @@ -57,8 +57,8 @@ typedef enum AnimationKind { ANIM_KIND_SET_FID = 17, ANIM_KIND_TAKE_OUT_WEAPON = 18, ANIM_KIND_SET_LIGHT_DISTANCE = 19, - ANIM_KIND_20 = 20, - ANIM_KIND_23 = 23, + ANIM_KIND_MOVE_ON_STAIRS = 20, + ANIM_KIND_CHECK_FALLING = 23, ANIM_KIND_TOGGLE_OUTLINE = 24, ANIM_KIND_ANIMATE_FOREVER = 25, ANIM_KIND_26 = 26, @@ -254,6 +254,7 @@ typedef struct AnimationSad { } AnimationSad; static int _anim_free_slot(int a1); +static int _anim_preload(Object* object, int fid, CacheEntry** cacheEntryPtr); static void _anim_cleanup(); static int _check_registry(Object* obj); static int animationRunSequence(int a1); @@ -273,6 +274,7 @@ static void _object_straight_move(int index); static int _anim_animate(Object* obj, int anim, int animationSequenceIndex, int flags); static void _object_anim_compact(); static int actionRotate(Object* obj, int delta, int animationSequenceIndex); +static int _anim_hide(Object* object, int animationSequenceIndex); static int _anim_change_fid(Object* obj, int animationSequenceIndex, int fid); static int _check_gravity(int tile, int elevation); static unsigned int animationComputeTicksPerFrame(Object* object, int fid); @@ -501,6 +503,22 @@ int reg_anim_end() return 0; } +// NOTE: Inlined. +// +// 0x413D6C +static int _anim_preload(Object* object, int fid, CacheEntry** cacheEntryPtr) +{ + *cacheEntryPtr = NULL; + + if (artLock(fid, cacheEntryPtr) != NULL) { + artUnlock(*cacheEntryPtr); + *cacheEntryPtr = NULL; + return 0; + } + + return -1; +} + // 0x413D98 static void _anim_cleanup() { @@ -618,14 +636,12 @@ int animationRegisterMoveToObject(Object* owner, Object* destination, int action int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return animationRegisterRotateToTile(owner, destination->tile); @@ -680,15 +696,12 @@ int animationRegisterRunToObject(Object* owner, Object* destination, int actionP int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - animationDescription->artCacheKey = NULL; - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return animationRegisterRotateToTile(owner, destination->tile); } @@ -713,17 +726,15 @@ int animationRegisterMoveToTile(Object* owner, int tile, int elevation, int acti animationDescription->elevation = elevation; animationDescription->actionPoints = actionPoints; animationDescription->delay = delay; - animationDescription->artCacheKey = NULL; int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -781,15 +792,12 @@ int animationRegisterRunToTile(Object* owner, int tile, int elevation, int actio int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - animationDescription->artCacheKey = NULL; - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -816,17 +824,15 @@ int animationRegisterMoveToTileStraight(Object* object, int tile, int elevation, animationDescription->elevation = elevation; animationDescription->anim = anim; animationDescription->delay = delay; - animationDescription->artCacheKey = NULL; int fid = buildFid(FID_TYPE(object->fid), object->fid & 0xFFF, animationDescription->anim, (object->fid & 0xF000) >> 12, object->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + + // NOTE: Uninline. + if (_anim_preload(object, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -852,17 +858,15 @@ int animationRegisterMoveToTileStraightAndWaitForComplete(Object* owner, int til animationDescription->elevation = elevation; animationDescription->anim = anim; animationDescription->delay = delay; - animationDescription->artCacheKey = NULL; int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -882,17 +886,15 @@ int animationRegisterAnimate(Object* owner, int anim, int delay) animationDescription->owner = owner; animationDescription->anim = anim; animationDescription->delay = delay; - animationDescription->artCacheKey = NULL; int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -915,14 +917,13 @@ int animationRegisterAnimateReversed(Object* owner, int anim, int delay) animationDescription->artCacheKey = NULL; int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -945,14 +946,13 @@ int animationRegisterAnimateAndHide(Object* owner, int anim, int delay) animationDescription->artCacheKey = NULL; int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -1199,16 +1199,13 @@ int animationRegisterSetFid(Object* owner, int fid, int delay) animationDescription->owner = owner; animationDescription->fid = fid; animationDescription->delay = delay; - animationDescription->artCacheKey = NULL; - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -1236,14 +1233,13 @@ int animationRegisterTakeOutWeapon(Object* owner, int weaponAnimationCode, int d animationDescription->weaponAnimationCode = weaponAnimationCode; int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, ANIM_TAKE_OUT, weaponAnimationCode, owner->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -1339,17 +1335,15 @@ int animationRegisterAnimateForever(Object* owner, int anim, int delay) animationDescription->owner = owner; animationDescription->anim = anim; animationDescription->delay = delay; - animationDescription->artCacheKey = NULL; int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); - if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { + + // NOTE: Uninline. + if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) { _anim_cleanup(); return -1; } - artUnlock(animationDescription->artCacheKey); - animationDescription->artCacheKey = NULL; - gAnimationDescriptionCurrentIndex++; return 0; @@ -1438,15 +1432,8 @@ static int animationRunSequence(int animationSequenceIndex) case ANIM_KIND_ANIMATE_AND_HIDE: rc = _anim_animate(animationDescription->owner, animationDescription->anim, animationSequenceIndex, ANIM_SAD_HIDE_ON_END); if (rc == -1) { - Rect rect; - if (objectHide(animationDescription->owner, &rect) == 0) { - tileWindowRefreshRect(&rect, animationDescription->elevation); - } - - if (animationSequenceIndex != -1) { - _anim_set_continue(animationSequenceIndex, 0); - } - rc = 0; + // NOTE: Uninline. + rc = _anim_hide(animationDescription->owner, animationSequenceIndex); } break; case ANIM_KIND_ANIMATE_FOREVER: @@ -1467,13 +1454,8 @@ static int animationRunSequence(int animationSequenceIndex) rc = actionRotate(animationDescription->owner, -1, animationSequenceIndex); break; case ANIM_KIND_HIDE: - if (objectHide(animationDescription->owner, &rect) == 0) { - tileWindowRefreshRect(&rect, animationDescription->owner->elevation); - } - if (animationSequenceIndex != -1) { - _anim_set_continue(animationSequenceIndex, 0); - } - rc = 0; + // NOTE: Uninline. + rc = _anim_hide(animationDescription->owner, animationSequenceIndex); break; case ANIM_KIND_CALLBACK: rc = animationDescription->callback(animationDescription->param1, animationDescription->param2); @@ -1539,10 +1521,10 @@ static int animationRunSequence(int animationSequenceIndex) tileWindowRefreshRect(&rect, animationDescription->owner->elevation); rc = _anim_set_continue(animationSequenceIndex, 0); break; - case ANIM_KIND_20: + case ANIM_KIND_MOVE_ON_STAIRS: rc = _anim_move_on_stairs(animationDescription->owner, animationDescription->tile, animationDescription->elevation, animationDescription->anim, animationSequenceIndex); break; - case ANIM_KIND_23: + case ANIM_KIND_CHECK_FALLING: rc = _check_for_falling(animationDescription->owner, animationDescription->anim, animationSequenceIndex); break; case ANIM_KIND_TOGGLE_OUTLINE: @@ -2849,9 +2831,8 @@ void _object_animate() artUnlock(cacheHandle); if ((sad->flags & ANIM_SAD_HIDE_ON_END) != 0) { - if (objectHide(object, &tempRect) == 0) { - tileWindowRefreshRect(&tempRect, object->elevation); - } + // NOTE: Uninline. + _anim_hide(object, -1); } _anim_set_continue(sad->animationSequenceIndex, 1); @@ -3262,6 +3243,24 @@ static int actionRotate(Object* obj, int delta, int animationSequenceIndex) return 0; } +// NOTE: Inlined. +// +// 0x41862C +static int _anim_hide(Object* object, int animationSequenceIndex) +{ + Rect rect; + + if (objectHide(object, &rect) == 0) { + tileWindowRefreshRect(&rect, object->elevation); + } + + if (animationSequenceIndex != -1) { + _anim_set_continue(animationSequenceIndex, 0); + } + + return 0; +} + // 0x418660 static int _anim_change_fid(Object* obj, int animationSequenceIndex, int fid) { diff --git a/src/character_editor.cc b/src/character_editor.cc index 9827b92..bfc1dd3 100644 --- a/src/character_editor.cc +++ b/src/character_editor.cc @@ -2917,7 +2917,7 @@ static void characterEditorDrawSkills(int a1) int color; int y; int value; - char valueString[12]; // TODO: Size might be wrong. + char valueString[32]; if (characterEditorSelectedItem >= EDITOR_FIRST_SKILL && characterEditorSelectedItem < 79) { selectedSkill = characterEditorSelectedItem - EDITOR_FIRST_SKILL; @@ -2950,7 +2950,6 @@ static void characterEditorDrawSkills(int a1) str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 138); fontDrawText(gCharacterEditorWindowBuffer + 640 * 233 + 422, str, 640, 640, _colorTable[18979]); - // TODO: Check. if (a1 == 2 && !gCharacterEditorIsSkillsFirstDraw) { characterEditorDrawBigNumber(522, 228, ANIMATE, gCharacterEditorTaggedSkillCount, gCharacterEditorOldTaggedSkillCount, gCharacterEditorWindow); } else { @@ -2985,7 +2984,6 @@ static void characterEditorDrawSkills(int a1) value = skillGetValue(gDude, i); sprintf(valueString, "%d%%", value); - // TODO: Check text position. fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 573, valueString, 640, 640, color); y += fontGetLineHeight() + 1; diff --git a/src/combat.cc b/src/combat.cc index abedb8e..8de1521 100644 --- a/src/combat.cc +++ b/src/combat.cc @@ -86,9 +86,12 @@ typedef struct DamageCalculationContext { } DamageCalculationContext; static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapon, int hitMode, Object* a4, int* a5, Object* a6); +static void _combatInitAIInfoList(); static int aiInfoCopy(int srcIndex, int destIndex); +static int _combatAIInfoSetLastMove(Object* object, int move); static void _combat_begin(Object* a1); static void _combat_begin_extra(Object* a1); +static void _combat_update_critters_in_los(bool a1); static void _combat_over(); static void _combat_add_noncoms(); static int _compare_faster(const void* a1, const void* a2); @@ -107,6 +110,7 @@ static int attackCompute(Attack* attack); static int attackComputeCriticalHit(Attack* a1); static int _attackFindInvalidFlags(Object* a1, Object* a2); static int attackComputeCriticalFailure(Attack* attack); +static void _do_random_cripple(int* flagsPtr); static int attackDetermineToHit(Object* attacker, int tile, Object* defender, int hitLocation, int hitMode, bool a6); static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3); static void _check_for_death(Object* a1, int a2, int* a3); @@ -2375,6 +2379,21 @@ void _combat_data_init(Object* obj) obj->data.critter.combat.results = 0; } +// NOTE: Inlined. +// +// 0x4217FC +static void _combatInitAIInfoList() +{ + int index; + + for (index = 0; index < _list_total; index++) { + _aiInfoList[index].friendlyDead = NULL; + _aiInfoList[index].lastTarget = NULL; + _aiInfoList[index].lastItem = NULL; + _aiInfoList[index].lastMove = 0; + } +} + // 0x421850 static int aiInfoCopy(int srcIndex, int destIndex) { @@ -2521,6 +2540,28 @@ int aiInfoSetLastItem(Object* obj, Object* a2) return 0; } +// NOTE: Inlined. +// +// 0x421A00 +static int _combatAIInfoSetLastMove(Object* object, int move) +{ + if (!isInCombat()) { + return 0; + } + + if (object == NULL) { + return -1; + } + + if (object->cid == -1) { + return -1; + } + + _aiInfoList[object->cid].lastMove = move; + + return 0; +} + // 0x421A34 static void _combat_begin(Object* a1) { @@ -2541,13 +2582,8 @@ static void _combat_begin(Object* a1) return; } - for (int index = 0; index < _list_total; index++) { - CombatAiInfo* aiInfo = &(_aiInfoList[index]); - aiInfo->friendlyDead = NULL; - aiInfo->lastTarget = NULL; - aiInfo->lastItem = NULL; - aiInfo->lastMove = 0; - } + // NOTE: Uninline. + _combatInitAIInfoList(); Object* v1 = NULL; for (int index = 0; index < _list_total; index++) { @@ -2559,10 +2595,8 @@ static void _combat_begin(Object* a1) combatData->ap = 0; critter->cid = index; - // NOTE: Not sure about this code, field_C is already reset. - if (isInCombat() && critter != NULL && index != -1) { - _aiInfoList[index].lastMove = 0; - } + // NOTE: Uninline. + _combatAIInfoSetLastMove(critter, 0); scriptSetObjects(critter->sid, NULL, NULL); scriptSetFixedParam(critter->sid, 0); @@ -2621,6 +2655,18 @@ static void _combat_begin_extra(Object* a1) configGetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_TARGET_HIGHLIGHT_KEY, &_combat_highlight); } +// NOTE: Inlined. +// +// 0x421D18 +static void _combat_update_critters_in_los(bool a1) +{ + int index; + + for (index = 0; index < _list_total; index++) { + _combat_update_critter_outline_for_los(_combat_list[index], a1); + } +} + // Something with outlining. // // 0x421D50 @@ -3149,11 +3195,8 @@ static void _combat_set_move_all() object->data.critter.combat.ap = actionPoints; - if (isInCombat()) { - if (object->cid != -1) { - _aiInfoList[object->cid].lastMove = 0; - } - } + // NOTE: Uninline. + _combatAIInfoSetLastMove(object, 0); } } @@ -3211,9 +3254,8 @@ static int _combat_turn(Object* a1, bool a2) interfaceBarEndButtonsRenderGreenLights(); - for (int index = 0; index < _list_total; index++) { - _combat_update_critter_outline_for_los(_combat_list[index], false); - } + // NOTE: Uninline. + _combat_update_critters_in_los(false); if (_combat_highlight != 0) { _combat_outline_on(); @@ -4075,22 +4117,8 @@ static int attackComputeCriticalHit(Attack* attack) } if ((attack->defenderFlags & DAM_CRIP_RANDOM) != 0) { - attack->defenderFlags &= ~DAM_CRIP_RANDOM; - - switch (randomBetween(0, 3)) { - case 0: - attack->defenderFlags |= DAM_CRIP_LEG_LEFT; - break; - case 1: - attack->defenderFlags |= DAM_CRIP_LEG_RIGHT; - break; - case 2: - attack->defenderFlags |= DAM_CRIP_ARM_LEFT; - break; - case 3: - attack->defenderFlags |= DAM_CRIP_ARM_RIGHT; - break; - } + // NOTE: Uninline. + _do_random_cripple(&(attack->defenderFlags)); } if (weaponGetPerk(attack->weapon) == PERK_WEAPON_ENHANCED_KNOCKOUT) { @@ -4195,22 +4223,8 @@ static int attackComputeCriticalFailure(Attack* attack) } if ((attack->attackerFlags & DAM_CRIP_RANDOM) != 0) { - attack->attackerFlags &= ~DAM_CRIP_RANDOM; - - switch (randomBetween(0, 3)) { - case 0: - attack->attackerFlags |= DAM_CRIP_LEG_LEFT; - break; - case 1: - attack->attackerFlags |= DAM_CRIP_LEG_RIGHT; - break; - case 2: - attack->attackerFlags |= DAM_CRIP_ARM_LEFT; - break; - case 3: - attack->attackerFlags |= DAM_CRIP_ARM_RIGHT; - break; - } + // NOTE: Uninline. + _do_random_cripple(&(attack->attackerFlags)); } if ((attack->attackerFlags & DAM_RANDOM_HIT) != 0) { @@ -4234,6 +4248,27 @@ static int attackComputeCriticalFailure(Attack* attack) return 0; } +// 0x42432C +static void _do_random_cripple(int* flagsPtr) +{ + *flagsPtr &= ~DAM_CRIP_RANDOM; + + switch (randomBetween(0, 3)) { + case 0: + *flagsPtr |= DAM_CRIP_LEG_LEFT; + break; + case 1: + *flagsPtr |= DAM_CRIP_LEG_RIGHT; + break; + case 2: + *flagsPtr |= DAM_CRIP_ARM_LEFT; + break; + case 3: + *flagsPtr |= DAM_CRIP_ARM_RIGHT; + break; + } +} + // 0x42436C int _determine_to_hit(Object* a1, Object* a2, int hitLocation, int hitMode) { @@ -5781,9 +5816,8 @@ void _combat_outline_on() } } - for (int index = 0; index < _list_total; index++) { - _combat_update_critter_outline_for_los(_combat_list[index], 1); - } + // NOTE: Uninline. + _combat_update_critters_in_los(true); tileWindowRefresh(); } diff --git a/src/combat_ai.cc b/src/combat_ai.cc index 640d0b2..ab6892a 100644 --- a/src/combat_ai.cc +++ b/src/combat_ai.cc @@ -99,8 +99,11 @@ static void _ai_run_away(Object* a1, Object* a2); static int _ai_move_away(Object* a1, Object* a2, int a3); static bool _ai_find_friend(Object* a1, int a2, int a3); static int _compare_nearer(const void* a1, const void* a2); +static void _ai_sort_list_distance(Object** critterList, int length, Object* origin); static int _compare_strength(const void* p1, const void* p2); +static void _ai_sort_list_strength(Object** critterList, int length); static int _compare_weakness(const void* p1, const void* p2); +static void _ai_sort_list_weakness(Object** critterList, int length); static Object* _ai_find_nearest_team(Object* a1, Object* a2, int a3); static Object* _ai_find_nearest_team_in_combat(Object* a1, Object* a2, int a3); static int _ai_find_attackers(Object* a1, Object** a2, Object** a3, Object** a4); @@ -114,6 +117,7 @@ static Object* _ai_search_environ(Object* critter, int itemType); static Object* _ai_retrieve_object(Object* a1, Object* a2); static int _ai_pick_hit_mode(Object* a1, Object* a2, Object* a3); static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a4); +static int _ai_move_closer(Object* a1, Object* a2, int a3); static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr); static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile); static bool _cai_attackWouldIntersect(Object* a1, Object* a2, Object* a3, int tile, int* distance); @@ -1236,6 +1240,15 @@ static int _compare_nearer(const void* a1, const void* a2) } } +// NOTE: Inlined. +// +// 0x428B74 +static void _ai_sort_list_distance(Object** critterList, int length, Object* origin) +{ + _combat_obj = origin; + qsort(critterList, length, sizeof(*critterList), _compare_nearer); +} + // qsort compare function - melee then ranged. // // 0x428B8C @@ -1270,6 +1283,14 @@ static int _compare_strength(const void* p1, const void* p2) return 0; } +// NOTE: Inlined. +// +// 0x428BD0 +static void _ai_sort_list_strength(Object** critterList, int length) +{ + qsort(critterList, length, sizeof(*critterList), _compare_strength); +} + // qsort compare unction - ranged then melee // // 0x428BE4 @@ -1304,6 +1325,14 @@ static int _compare_weakness(const void* p1, const void* p2) return 0; } +// NOTE: Inlined. +// +// 0x428C28 +static void _ai_sort_list_weakness(Object** critterList, int length) +{ + qsort(critterList, length, sizeof(*critterList), _compare_weakness); +} + // 0x428C3C static Object* _ai_find_nearest_team(Object* a1, Object* a2, int a3) { @@ -1318,8 +1347,8 @@ static Object* _ai_find_nearest_team(Object* a1, Object* a2, int a3) return NULL; } - _combat_obj = a1; - qsort(_curr_crit_list, _curr_crit_num, sizeof(*_curr_crit_list), _compare_nearer); + // NOTE: Uninline. + _ai_sort_list_distance(_curr_crit_list, _curr_crit_num, a1); for (i = 0; i < _curr_crit_num; i++) { obj = _curr_crit_list[i]; @@ -1344,8 +1373,8 @@ static Object* _ai_find_nearest_team_in_combat(Object* a1, Object* a2, int a3) int team = a2->data.critter.combat.team; - _combat_obj = a1; - qsort(_curr_crit_list, _curr_crit_num, sizeof(*_curr_crit_list), _compare_nearer); + // NOTE: Uninline. + _ai_sort_list_distance(_curr_crit_list, _curr_crit_num, a1); for (int index = 0; index < _curr_crit_num; index++) { Object* obj = _curr_crit_list[index]; @@ -1381,8 +1410,8 @@ static int _ai_find_attackers(Object* a1, Object** a2, Object** a3, Object** a4) return 0; } - _combat_obj = a1; - qsort(_curr_crit_list, _curr_crit_num, sizeof(*_curr_crit_list), _compare_nearer); + // NOTE: Uninline. + _ai_sort_list_distance(_curr_crit_list, _curr_crit_num, a1); int foundTargetCount = 0; int team = a1->data.critter.combat.team; @@ -1521,22 +1550,21 @@ static Object* _ai_danger_source(Object* a1) } } - int (*compareProc)(const void*, const void*); switch (attackWho) { case ATTACK_WHO_STRONGEST: - compareProc = _compare_strength; + // NOTE: Uninline. + _ai_sort_list_strength(targets, 4); break; case ATTACK_WHO_WEAKEST: - compareProc = _compare_weakness; + // NOTE: Uninline. + _ai_sort_list_weakness(targets, 4); break; default: - compareProc = _compare_nearer; - _combat_obj = a1; + // NOTE: Uninline. + _ai_sort_list_distance(targets, 4, a1); break; } - qsort(targets, 4, sizeof(*targets), compareProc); - for (int index = 0; index < 4; index++) { Object* candidate = targets[index]; if (candidate != NULL && objectCanHearObject(a1, candidate)) { @@ -2022,8 +2050,8 @@ static Object* _ai_search_environ(Object* critter, int itemType) return NULL; } - _combat_obj = critter; - qsort(objects, count, sizeof(*objects), _compare_nearer); + // NOTE: Uninline. + _ai_sort_list_distance(objects, count, critter); int perception = critterGetStat(critter, STAT_PERCEPTION) + 5; Object* item2 = critterGetItem2(critter); @@ -2273,6 +2301,14 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a return 0; } +// NOTE: Inlined. +// +// 0x42A1C0 +static int _ai_move_closer(Object* a1, Object* a2, int a3) +{ + return _ai_move_steps_closer(a1, a2, a1->data.critter.combat.ap, a3); +} + // 0x42A1D4 static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr) { @@ -2328,9 +2364,8 @@ static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int } } - _combat_obj = source; - - qsort(aiRetargetData.critterList, aiRetargetData.critterCount, sizeof(*aiRetargetData.critterList), _compare_nearer); + // NOTE: Uninline. + _ai_sort_list_distance(aiRetargetData.critterList, aiRetargetData.critterCount, source); if (_cai_retargetTileFromFriendlyFireSubFunc(&aiRetargetData, *tilePtr) == 0) { int minDistance = 99999; @@ -2650,7 +2685,8 @@ static int _ai_try_attack(Object* a1, Object* a2) v38 = 0; } else { if (_ai_switch_weapons(a1, &hitMode, &weapon, a2) == -1 || weapon == NULL) { - if (_ai_move_steps_closer(a1, a2, a1->data.critter.combat.ap, v38) == -1) { + // NOTE: Uninline. + if (_ai_move_closer(a1, a2, v38) == -1) { return -1; } } @@ -2822,7 +2858,8 @@ int _cai_perform_distance_prefs(Object* a1, Object* a2) break; case DISTANCE_CHARGE: if (a2 != NULL) { - _ai_move_steps_closer(a1, a2, a1->data.critter.combat.ap, 1); + // NOTE: Uninline. + _ai_move_closer(a1, a2, 1); } break; case DISTANCE_SNIPE: diff --git a/src/critter.cc b/src/critter.cc index 9d98601..27ae14b 100644 --- a/src/critter.cc +++ b/src/critter.cc @@ -68,6 +68,7 @@ typedef enum RadiationLevel { } RadiationLevel; static int _get_rad_damage_level(Object* obj, void* data); +static int critter_kill_count_clear(); static int _critterClearObjDrugs(Object* obj, void* data); // 0x50141C @@ -159,7 +160,8 @@ int critterInit() { dudeResetName(); - memset(gKillsByType, 0, sizeof(gKillsByType)); + // NOTE: Uninline; + critter_kill_count_clear(); if (!messageListInit(&gCritterMessageList)) { debugPrint("\nError: Initing critter name message file!"); @@ -181,7 +183,9 @@ int critterInit() void critterReset() { dudeResetName(); - memset(gKillsByType, 0, sizeof(gKillsByType)); + + // NOTE: Uninline; + critter_kill_count_clear(); } // 0x42D004 @@ -680,6 +684,15 @@ int critterGetDamageType(Object* obj) return proto->critter.data.damageType; } +// NOTE: Inlined. +// +// 0x42D860 +static int critter_kill_count_clear() +{ + memset(gKillsByType, 0, sizeof(gKillsByType)); + return 0; +} + // 0x42D878 int killsIncByType(int killType) { diff --git a/src/debug.cc b/src/debug.cc index 661bf76..e6b5aa6 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -19,7 +19,8 @@ static void _debug_clear(); static int _debug_mono(char* string); static int _debug_log(char* string); static int _debug_screen(char* string); -static void _debug_putc(char ch); +static void _debug_putc(int ch); +static void _debug_scroll(); // 0x51DEF8 static FILE* _fd = NULL; @@ -174,7 +175,28 @@ static int _debug_puts(char* string) // 0x4C6FAC static void _debug_clear() { - // TODO: Something with segments. + char* buffer; + int x; + int y; + + buffer = NULL; + + if (gDebugPrintProc == _debug_mono) { + buffer = (char*)0xB0000; + } else if (gDebugPrintProc == _debug_screen) { + buffer = (char*)0xB8000; + } + + if (buffer != NULL) { + for (y = 0; y < 25; y++) { + for (x = 0; x < 80; x++) { + *buffer++ = ' '; + *buffer++ = 7; + } + } + _cury = 0; + _curx = 0; + } } // 0x4C7004 @@ -220,15 +242,72 @@ static int _debug_screen(char* string) } // 0x4C709C -static void _debug_putc(char ch) +static void _debug_putc(int ch) { - // TODO: Something with segments. + char* buffer; + + buffer = (char*)0xB0000; + + switch (ch) { + case 7: + printf("\x07"); + return; + case 8: + if (_curx > 0) { + _curx--; + buffer += 2 * _curx + 2 * 80 * _cury; + *buffer++ = ' '; + *buffer = 7; + } + return; + case 9: + do { + _debug_putc(' '); + } while ((_curx - 1) % 4 != 0); + return; + case 13: + _curx = 0; + return; + default: + buffer += 2 * _curx + 2 * 80 * _cury; + *buffer++ = ch; + *buffer = 7; + _curx++; + if (_curx < 80) { + return; + } + // FALLTHROUGH + case 10: + _curx = 0; + _cury++; + if (_cury > 24) { + _cury = 24; + _debug_scroll(); + } + return; + } } // 0x4C71AC -void _debug_scroll() +static void _debug_scroll() { - // TODO: Something with segments. + char* buffer; + int x; + int y; + + buffer = (char*)0xB0000; + + for (y = 0; y < 24; y++) { + for (x = 0; x < 80 * 2; x++) { + buffer[0] = buffer[80 * 2]; + buffer++; + } + } + + for (x = 0; x < 80; x++) { + *buffer++ = ' '; + *buffer++ = 7; + } } // 0x4C71E8 diff --git a/src/dialog.cc b/src/dialog.cc index dc5d666..85a5eff 100644 --- a/src/dialog.cc +++ b/src/dialog.cc @@ -5,7 +5,6 @@ #include "movie.h" #include "platform_compat.h" #include "text_font.h" -#include "widget.h" #include "window_manager.h" #include @@ -209,7 +208,7 @@ void _replyAddOption(const char* a1, const char* a2, int a3) v18->field_C[v17].string = NULL; } - v18->field_C[v17].field_18 = widgetGetFont(); + v18->field_C[v17].field_18 = windowGetFont(); v18->field_C[v17].field_1A = word_56DB60; v18->field_C[v17].field_14 = a3; } @@ -236,7 +235,7 @@ void _replyAddOptionProc(const char* a1, int a2, int a3) v5->field_C[v13].proc = a2; - v5->field_C[v13].field_18 = widgetGetFont(); + v5->field_C[v13].field_18 = windowGetFont(); v5->field_C[v13].field_1A = word_56DB60; v5->field_C[v13].field_14 = a3; } @@ -388,8 +387,8 @@ void _drawStr(int win, char* str, int font, int width, int height, int left, int int old_font; Rect rect; - old_font = widgetGetFont(); - widgetSetFont(font); + old_font = windowGetFont(); + windowSetFont(font); _printStr(win, str, width, height, left, top, a8, a9, a10); @@ -398,7 +397,7 @@ void _drawStr(int win, char* str, int font, int width, int height, int left, int rect.right = width + left; rect.bottom = height + top; windowRefreshRect(win, &rect); - widgetSetFont(old_font); + windowSetFont(old_font); } // 0x430D40 diff --git a/src/display_monitor.cc b/src/display_monitor.cc index eadca6a..fcac2c0 100644 --- a/src/display_monitor.cc +++ b/src/display_monitor.cc @@ -36,6 +36,7 @@ #define DISPLAY_MONITOR_BEEP_DELAY (500U) +static void display_clear(); static void displayMonitorRefresh(); static void displayMonitorScrollUpOnMouseDown(int btn, int keyCode); static void displayMonitorScrollDownOnMouseDown(int btn, int keyCode); @@ -180,14 +181,8 @@ int displayMonitorInit() gDisplayMonitorEnabled = true; gDisplayMonitorInitialized = true; - for (int index = 0; index < gDisplayMonitorLinesCapacity; index++) { - gDisplayMonitorLines[index][0] = '\0'; - } - - _disp_start = 0; - _disp_curr = 0; - - displayMonitorRefresh(); + // NOTE: Uninline. + display_clear(); // SFALL consoleFileInit(); @@ -199,18 +194,12 @@ int displayMonitorInit() // 0x431800 int displayMonitorReset() { - if (gDisplayMonitorInitialized) { - for (int index = 0; index < gDisplayMonitorLinesCapacity; index++) { - gDisplayMonitorLines[index][0] = '\0'; - } + // NOTE: Uninline. + display_clear(); - _disp_start = 0; - _disp_curr = 0; - displayMonitorRefresh(); + // SFALL + consoleFileReset(); - // SFALL - consoleFileReset(); - } return 0; } @@ -319,6 +308,24 @@ void displayMonitorAddMessage(char* str) displayMonitorRefresh(); } +// NOTE: Inlined. +// +// 0x431A2C +static void display_clear() +{ + int index; + + if (gDisplayMonitorInitialized) { + for (index = 0; index < gDisplayMonitorLinesCapacity; index++) { + gDisplayMonitorLines[index][0] = '\0'; + } + + _disp_start = 0; + _disp_curr = 0; + displayMonitorRefresh(); + } +} + // 0x431A78 static void displayMonitorRefresh() { diff --git a/src/game.cc b/src/game.cc index 5368c73..9162235 100644 --- a/src/game.cc +++ b/src/game.cc @@ -90,7 +90,7 @@ static char _aDec11199816543[] = VERSION_BUILD_TIME; static bool gGameUiDisabled = false; // 0x5186B8 -static int _game_state_cur = 0; +static int _game_state_cur = GAME_STATE_0; // 0x5186BC static bool gIsMapper = false; @@ -439,7 +439,8 @@ void gameExit() // 0x442D44 int gameHandleKey(int eventCode, bool isInCombatMode) { - if (_game_state_cur == 5) { + // NOTE: Uninline. + if (_game_state() == GAME_STATE_5) { _gdialogSystemEnter(); } @@ -479,6 +480,8 @@ int gameHandleKey(int eventCode, bool isInCombatMode) if (mouseX == _scr_size.left || mouseX == _scr_size.right || mouseY == _scr_size.top || mouseY == _scr_size.bottom) { _gmouse_clicked_on_edge = true; + } else { + _gmouse_clicked_on_edge = false; } } } else { @@ -501,6 +504,31 @@ int gameHandleKey(int eventCode, bool isInCombatMode) _intface_use_item(); } break; + case -2: + if (1) { + int mouseEvent = mouseGetEvent(); + int mouseX; + int mouseY; + mouseGetPosition(&mouseX, &mouseY); + + if ((mouseEvent & MOUSE_EVENT_LEFT_BUTTON_DOWN) != 0) { + if ((mouseEvent & MOUSE_EVENT_LEFT_BUTTON_REPEAT) == 0) { + if (mouseX == _scr_size.left || mouseX == _scr_size.right + || mouseY == _scr_size.top || mouseY == _scr_size.bottom) { + _gmouse_clicked_on_edge = true; + } else { + _gmouse_clicked_on_edge = false; + } + } + } else { + if ((mouseEvent & MOUSE_EVENT_LEFT_BUTTON_UP) != 0) { + _gmouse_clicked_on_edge = false; + } + } + + _gmouse_handle_event(mouseX, mouseY, mouseEvent); + } + break; case KEY_CTRL_Q: case KEY_CTRL_X: case KEY_F10: @@ -746,14 +774,14 @@ int gameHandleKey(int eventCode, bool isInCombatMode) break; case KEY_COMMA: case KEY_LESS: - if (reg_anim_begin(0) == 0) { + if (reg_anim_begin(ANIMATION_REQUEST_RESERVED) == 0) { animationRegisterRotateCounterClockwise(gDude); reg_anim_end(); } break; case KEY_DOT: case KEY_GREATER: - if (reg_anim_begin(0) == 0) { + if (reg_anim_begin(ANIMATION_REQUEST_RESERVED) == 0) { animationRegisterRotateClockwise(gDude); reg_anim_end(); } @@ -868,8 +896,6 @@ int gameHandleKey(int eventCode, bool isInCombatMode) break; } - // TODO: Incomplete. - return 0; } @@ -1024,15 +1050,15 @@ int _game_state() // 0x443E34 int _game_state_request(int a1) { - if (a1 == 0) { - a1 = 1; - } else if (a1 == 2) { - a1 = 3; - } else if (a1 == 4) { - a1 = 5; + if (a1 == GAME_STATE_0) { + a1 = GAME_STATE_1; + } else if (a1 == GAME_STATE_2) { + a1 = GAME_STATE_3; + } else if (a1 == GAME_STATE_4) { + a1 = GAME_STATE_5; } - if (_game_state_cur != 4 || a1 != 5) { + if (_game_state_cur != GAME_STATE_4 || a1 != GAME_STATE_5) { _game_state_cur = a1; return 0; } @@ -1047,14 +1073,14 @@ void _game_state_update() v0 = _game_state_cur; switch (_game_state_cur) { - case 1: - v0 = 0; + case GAME_STATE_1: + v0 = GAME_STATE_0; break; - case 3: - v0 = 2; + case GAME_STATE_3: + v0 = GAME_STATE_2; break; - case 5: - v0 = 4; + case GAME_STATE_5: + v0 = GAME_STATE_4; } _game_state_cur = v0; diff --git a/src/game.h b/src/game.h index ea6111e..27a1178 100644 --- a/src/game.h +++ b/src/game.h @@ -4,6 +4,15 @@ #include "game_vars.h" #include "message.h" +typedef enum GameState { + GAME_STATE_0, + GAME_STATE_1, + GAME_STATE_2, + GAME_STATE_3, + GAME_STATE_4, + GAME_STATE_5, +} GameState; + extern int* gGameGlobalVars; extern int gGameGlobalVarsLength; extern const char* asc_5186C8; diff --git a/src/game_dialog.cc b/src/game_dialog.cc index ede0587..c6d7333 100644 --- a/src/game_dialog.cc +++ b/src/game_dialog.cc @@ -604,6 +604,8 @@ static int gGameDialogFidgetFrmCurrentFrame; static int _gdialogReset(); static void gameDialogEndLips(); +static int gdHide(); +static int gdUnhide(); static int gameDialogAddMessageOption(int a1, int a2, int a3); static int gameDialogAddTextOption(int a1, const char* a2, int a3); static int gameDialogReviewWindowInit(int* win); @@ -640,6 +642,7 @@ static void _gDialogRefreshOptionsRect(int win, Rect* drawRect); static void gameDialogTicker(); static void _gdialog_scroll_subwin(int a1, int a2, unsigned char* a3, unsigned char* a4, unsigned char* a5, int a6, int a7); static int _text_num_lines(const char* a1, int a2); +static int text_to_rect_wrapped(unsigned char* buffer, Rect* rect, char* string, int* a4, int height, int pitch, int color); static int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4, int height, int pitch, int color, int a7); static int _gdialog_barter_create_win(); static void _gdialog_barter_destroy_win(); @@ -661,6 +664,7 @@ static void _gdCustomUpdateSetting(int option, int value); static void gameDialogBarterButtonUpMouseUp(int btn, int a2); static int _gdialog_window_create(); static void _gdialog_window_destroy(); +static int talk_to_create_background_window(); static int gameDialogWindowRenderBackground(); static int _talkToRefreshDialogWindowRect(Rect* rect); static void gameDialogRenderHighlight(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int x, int y, int destPitch, unsigned char* a9, unsigned char* a10); @@ -854,7 +858,7 @@ void _gdialogSystemEnter() _tile_scroll_to(gGameDialogOldCenterTile, 2); } - _game_state_request(2); + _game_state_request(GAME_STATE_2); _game_state_update(); } @@ -1081,7 +1085,15 @@ void gameDialogRenderSupplementaryMessage(char* msg) int lineHeight = fontGetLineHeight(); int a4 = 0; - gameDialogDrawText(windowBuffer, &_replyRect, msg, &a4, lineHeight, 379, _colorTable[992] | 0x2000000, 1); + + // NOTE: Uninline. + text_to_rect_wrapped(windowBuffer, + &_replyRect, + msg, + &a4, + lineHeight, + 379, + _colorTable[992] | 0x2000000); windowUnhide(_gd_replyWin); windowRefresh(gGameDialogReplyWindow); @@ -1222,6 +1234,24 @@ void _gdialogUpdatePartyStatus() return; } + // NOTE: Uninline. + gdHide(); + + _gdialog_window_destroy(); + + gGameDialogSpeakerIsPartyMember = isPartyMember; + + _gdialog_window_create(); + + // NOTE: Uninline. + gdUnhide(); +} + +// NOTE: Inlined. +// +// 0x4457EC +static int gdHide() +{ if (_gd_replyWin != -1) { windowHide(_gd_replyWin); } @@ -1230,12 +1260,14 @@ void _gdialogUpdatePartyStatus() windowHide(_gd_optionsWin); } - _gdialog_window_destroy(); - - gGameDialogSpeakerIsPartyMember = isPartyMember; - - _gdialog_window_create(); + return 0; +} +// NOTE: Inlined. +// +// 0x445818 +static int gdUnhide() +{ if (_gd_replyWin != -1) { windowUnhide(_gd_replyWin); } @@ -1243,6 +1275,8 @@ void _gdialogUpdatePartyStatus() if (_gd_optionsWin != -1) { windowUnhide(_gd_optionsWin); } + + return 0; } // 0x44585C @@ -1554,7 +1588,14 @@ void gameDialogReviewWindowUpdate(int win, int origin) exit(1); } - y = gameDialogDrawText(windowBuffer + 113, &entriesRect, replyText, NULL, fontGetLineHeight(), 640, _colorTable[768] | 0x2000000, 1); + // NOTE: Uninline. + y = text_to_rect_wrapped(windowBuffer + 113, + &entriesRect, + replyText, + NULL, + fontGetLineHeight(), + 640, + _colorTable[768] | 0x2000000); // SFALL: Cosmetic fix to the dialog review interface to prevent the // player name from being displayed at the bottom of the window when the @@ -1580,7 +1621,14 @@ void gameDialogReviewWindowUpdate(int win, int origin) exit(1); } - y = gameDialogDrawText(windowBuffer + 113, &entriesRect, optionText, NULL, fontGetLineHeight(), 640, _colorTable[15855] | 0x2000000, 1); + // NOTE: Uninline. + y = text_to_rect_wrapped(windowBuffer + 113, + &entriesRect, + optionText, + NULL, + fontGetLineHeight(), + 640, + _colorTable[15855] | 0x2000000); } if (y >= 407) { @@ -2104,8 +2152,14 @@ void gameDialogOptionOnMouseEnter(int index) } } - unsigned char* windowBuffer = windowGetBuffer(gGameDialogOptionsWindow); - gameDialogDrawText(windowBuffer, &_optionRect, dialogOptionEntry->text, NULL, fontGetLineHeight(), 393, color, 1); + // NOTE: Uninline. + text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow), + &_optionRect, + dialogOptionEntry->text, + NULL, + fontGetLineHeight(), + 393, + color); _optionRect.left = 0; _optionRect.right = 391; @@ -2146,8 +2200,14 @@ void gameDialogOptionOnMouseExit(int index) _optionRect.left = 5; _optionRect.right = 388; - unsigned char* windowBuffer = windowGetBuffer(gGameDialogOptionsWindow); - gameDialogDrawText(windowBuffer, &_optionRect, dialogOptionEntry->text, NULL, fontGetLineHeight(), 393, color, 1); + // NOTE: Uninline. + text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow), + &_optionRect, + dialogOptionEntry->text, + NULL, + fontGetLineHeight(), + 393, + color); _optionRect.right = 391; _optionRect.top = dialogOptionEntry->field_14; @@ -2168,16 +2228,14 @@ void gameDialogRenderReply() _demo_copy_title(gGameDialogReplyWindow); - // Render reply. - unsigned char* windowBuffer = windowGetBuffer(gGameDialogReplyWindow); - gameDialogDrawText(windowBuffer, + // NOTE: Uninline. + text_to_rect_wrapped(windowGetBuffer(gGameDialogReplyWindow), &_replyRect, gDialogReplyText, &dword_58F4E0, fontGetLineHeight(), 379, - _colorTable[992] | 0x2000000, - 1); + _colorTable[992] | 0x2000000); windowRefresh(gGameDialogReplyWindow); } @@ -2287,14 +2345,14 @@ void _gdProcessUpdate() y = 0; } - gameDialogDrawText(windowGetBuffer(gGameDialogOptionsWindow), + // NOTE: Uninline. + text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow), &_optionRect, dialogOptionEntry->text, NULL, fontGetLineHeight(), 393, - color, - 1); + color); _optionRect.top += 2; @@ -2325,14 +2383,8 @@ int _gdCreateHeadWindow() int windowWidth = GAME_DIALOG_WINDOW_WIDTH; - int backgroundWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2; - int backgroundWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2; - gGameDialogBackgroundWindow = windowCreate(backgroundWindowX, - backgroundWindowY, - windowWidth, - GAME_DIALOG_WINDOW_HEIGHT, - 256, - WINDOW_FLAG_0x02); + // NOTE: Uninline. + talk_to_create_background_window(); gameDialogWindowRenderBackground(); unsigned char* buf = windowGetBuffer(gGameDialogBackgroundWindow); @@ -2746,12 +2798,11 @@ void gameDialogTicker() _dialogue_switch_mode = 0; _gdialog_barter_destroy_win(); _gdialog_window_create(); - if (_gd_replyWin != -1) { - windowUnhide(_gd_replyWin); - } + + // NOTE: Uninline. + gdUnhide(); if (_gd_optionsWin != -1) { - windowUnhide(_gd_optionsWin); // SFALL: Fix for the player's money not being displayed in the // dialog window after leaving the barter/combat control interface. gameDialogRenderCaps(); @@ -2966,6 +3017,14 @@ int _text_num_lines(const char* a1, int a2) return v1; } +// NOTE: Inlined. +// +// 0x447F80 +static int text_to_rect_wrapped(unsigned char* buffer, Rect* rect, char* string, int* a4, int height, int pitch, int color) +{ + return gameDialogDrawText(buffer, rect, string, a4, height, pitch, color, 1); +} + // display_msg // 0x447FA0 int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4, int height, int pitch, int color, int a7) @@ -3573,13 +3632,8 @@ void gameDialogCombatControlButtonOnMouseUp(int btn, int keyCode) _dialogue_switch_mode = 8; _dialogue_state = 10; - if (_gd_replyWin != -1) { - windowHide(_gd_replyWin); - } - - if (_gd_optionsWin != -1) { - windowHide(_gd_optionsWin); - } + // NOTE: Uninline. + gdHide(); } // 0x4492D0 @@ -4226,13 +4280,8 @@ void gameDialogBarterButtonUpMouseUp(int btn, int keyCode) _dialogue_switch_mode = 2; _dialogue_state = 4; - if (_gd_replyWin != -1) { - windowHide(_gd_replyWin); - } - - if (_gd_optionsWin != -1) { - windowHide(_gd_optionsWin); - } + // NOTE: Uninline. + gdHide(); } else { MessageListItem messageListItem; // This person will not barter with you. @@ -4395,6 +4444,27 @@ void _gdialog_window_destroy() } } +// NOTE: Inlined. +// +// 0x44AAD8 +static int talk_to_create_background_window() +{ + int backgroundWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2; + int backgroundWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2; + gGameDialogBackgroundWindow = windowCreate(backgroundWindowX, + backgroundWindowY, + GAME_DIALOG_WINDOW_WIDTH, + GAME_DIALOG_WINDOW_HEIGHT, + 256, + WINDOW_FLAG_0x02); + + if (gGameDialogBackgroundWindow != -1) { + return 0; + } + + return -1; +} + // 0x44AB18 int gameDialogWindowRenderBackground() { diff --git a/src/game_mouse.cc b/src/game_mouse.cc index 1cd3c23..c95e953 100644 --- a/src/game_mouse.cc +++ b/src/game_mouse.cc @@ -309,6 +309,7 @@ static int gameMouseObjectsReset(); static void gameMouseObjectsFree(); static int gameMouseActionMenuInit(); static void gameMouseActionMenuFree(); +static int gmouse_3d_set_flat_fid(int fid, Rect* rect); static int gameMouseUpdateHexCursorFid(Rect* rect); static int _gmouse_3d_move_to(int x, int y, int elevation, Rect* a4); static int gameMouseHandleScrolling(int x, int y, int cursor); @@ -426,6 +427,14 @@ void _gmouse_disable_scrolling() _gmouse_scrolling_enabled = 0; } +// NOTE: Inlined. +// +// 0x44B4E4 +bool gmouse_scrolling_is_enabled() +{ + return _gmouse_scrolling_enabled; +} + // 0x44B504 int _gmouse_get_click_to_scroll() { @@ -483,7 +492,8 @@ void gameMouseRefresh() if (gGameMouseCursor >= FIRST_GAME_MOUSE_ANIMATED_CURSOR) { _mouse_info(); - if (_gmouse_scrolling_enabled) { + // NOTE: Uninline. + if (gmouse_scrolling_is_enabled()) { mouseGetPosition(&mouseX, &mouseY); int oldMouseCursor = gGameMouseCursor; @@ -525,7 +535,8 @@ void gameMouseRefresh() } if (!_gmouse_enabled) { - if (_gmouse_scrolling_enabled) { + // NOTE: Uninline. + if (gmouse_scrolling_is_enabled()) { mouseGetPosition(&mouseX, &mouseY); int oldMouseCursor = gGameMouseCursor; @@ -700,7 +711,8 @@ void gameMouseRefresh() if (gameMouseRenderPrimaryAction(mouseX, mouseY, primaryAction, _scr_size.right - _scr_size.left + 1, _scr_size.bottom - _scr_size.top - 99) == 0) { Rect tmp; int fid = buildFid(OBJ_TYPE_INTERFACE, 282, 0, 0, 0); - if (objectSetFid(gGameMouseHexCursor, fid, &tmp) == 0) { + // NOTE: Uninline. + if (gmouse_3d_set_flat_fid(fid, &tmp) == 0) { tileWindowRefreshRect(&tmp, gElevation); } } @@ -763,7 +775,8 @@ void gameMouseRefresh() if (gameMouseRenderAccuracy(formattedAccuracy, color) == 0) { Rect tmp; int fid = buildFid(OBJ_TYPE_INTERFACE, 284, 0, 0, 0); - if (objectSetFid(gGameMouseHexCursor, fid, &tmp) == 0) { + // NOTE: Uninline. + if (gmouse_3d_set_flat_fid(fid, &tmp) == 0) { tileWindowRefreshRect(&tmp, gElevation); } } @@ -1115,7 +1128,8 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState) if (gameMouseRenderActionMenuItems(mouseX, mouseY, actionMenuItems, actionMenuItemsCount, _scr_size.right - _scr_size.left + 1, _scr_size.bottom - _scr_size.top - 99) == 0) { Rect v43; int fid = buildFid(OBJ_TYPE_INTERFACE, 283, 0, 0, 0); - if (objectSetFid(gGameMouseHexCursor, fid, &v43) == 0 && _gmouse_3d_move_to(mouseX, mouseY, gElevation, &v43) == 0) { + // NOTE: Uninline. + if (gmouse_3d_set_flat_fid(fid, &v43) == 0 && _gmouse_3d_move_to(mouseX, mouseY, gElevation, &v43) == 0) { tileWindowRefreshRect(&v43, gElevation); isoDisable(); @@ -1339,7 +1353,8 @@ void gameMouseSetMode(int mode) fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[mode], 0, 0, 0); Rect rect; - if (objectSetFid(gGameMouseHexCursor, fid, &rect) == -1) { + // NOTE: Uninline. + if (gmouse_3d_set_flat_fid(fid, &rect) == -1) { return; } @@ -2148,6 +2163,18 @@ void gameMouseActionMenuFree() gGameMouseActionPickFrmDataSize = 0; } +// NOTE: Inlined. +// +// 0x44DF1C +static int gmouse_3d_set_flat_fid(int fid, Rect* rect) +{ + if (objectSetFid(gGameMouseHexCursor, fid, rect) == 0) { + return 0; + } + + return -1; +} + // 0x44DF40 int gameMouseUpdateHexCursorFid(Rect* rect) { @@ -2156,7 +2183,8 @@ int gameMouseUpdateHexCursorFid(Rect* rect) return -1; } - return objectSetFid(gGameMouseHexCursor, fid, rect); + // NOTE: Uninline. + return gmouse_3d_set_flat_fid(fid, rect); } // 0x44DF94 diff --git a/src/game_mouse.h b/src/game_mouse.h index 1553d45..b546e78 100644 --- a/src/game_mouse.h +++ b/src/game_mouse.h @@ -78,6 +78,7 @@ void _gmouse_enable(); void _gmouse_disable(int a1); void _gmouse_enable_scrolling(); void _gmouse_disable_scrolling(); +bool gmouse_scrolling_is_enabled(); int _gmouse_is_scrolling(); void gameMouseRefresh(); void _gmouse_handle_event(int mouseX, int mouseY, int mouseState); diff --git a/src/game_movie.cc b/src/game_movie.cc index 1376667..a2ea826 100644 --- a/src/game_movie.cc +++ b/src/game_movie.cc @@ -13,7 +13,6 @@ #include "palette.h" #include "platform_compat.h" #include "text_font.h" -#include "widget.h" #include "window_manager.h" #include @@ -221,11 +220,11 @@ int gameMoviePlay(int movie, int flags) colorPaletteLoad(subtitlesPaletteFilePath); - oldTextColor = widgetGetTextColor(); - widgetSetTextColor(1.0, 1.0, 1.0); + oldTextColor = windowGetTextColor(); + windowSetTextColor(1.0, 1.0, 1.0); oldFont = fontGetCurrent(); - widgetSetFont(101); + windowSetFont(101); } bool cursorWasHidden = cursorIsHidden(); @@ -278,12 +277,12 @@ int gameMoviePlay(int movie, int flags) if (subtitlesEnabled) { colorPaletteLoad("color.pal"); - widgetSetFont(oldFont); + windowSetFont(oldFont); float r = (float)((_Color2RGB_(oldTextColor) & 0x7C00) >> 10) * flt_50352A; float g = (float)((_Color2RGB_(oldTextColor) & 0x3E0) >> 5) * flt_50352A; float b = (float)(_Color2RGB_(oldTextColor) & 0x1F) * flt_50352A; - widgetSetTextColor(r, g, b); + windowSetTextColor(r, g, b); } windowDestroy(win); diff --git a/src/interface.cc b/src/interface.cc index c2c5f1c..04a7e77 100644 --- a/src/interface.cc +++ b/src/interface.cc @@ -103,6 +103,7 @@ typedef struct InterfaceItemState { static int _intface_redraw_items_callback(Object* a1, Object* a2); static int _intface_change_fid_callback(Object* a1, Object* a2); static void interfaceBarSwapHandsAnimatePutAwayTakeOutSequence(int previousWeaponAnimationCode, int weaponAnimationCode); +static int intface_init_items(); static int interfaceBarRefreshMainAction(); static int endTurnButtonInit(); static int endTurnButtonFree(); @@ -111,6 +112,7 @@ static int endCombatButtonFree(); static void interfaceUpdateAmmoBar(int x, int ratio); static int _intface_item_reload(); static void interfaceRenderCounter(int x, int y, int previousValue, int value, int offset, int delay); +static int intface_fatal_error(int rc); static int indicatorBarInit(); static void interfaceBarFree(); static void indicatorBarReset(); @@ -430,18 +432,21 @@ int interfaceInit() gInterfaceBarWindow = windowCreate(interfaceBarWindowX, interfaceBarWindowY, INTERFACE_BAR_WIDTH, INTERFACE_BAR_HEIGHT, _colorTable[0], WINDOW_HIDDEN); if (gInterfaceBarWindow == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } gInterfaceWindowBuffer = windowGetBuffer(gInterfaceBarWindow); if (gInterfaceWindowBuffer == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 16, 0, 0, 0); backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle); if (backgroundFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } blitBufferToBuffer(backgroundFrmData, INTERFACE_BAR_WIDTH, INTERFACE_BAR_HEIGHT - 1, INTERFACE_BAR_WIDTH, gInterfaceWindowBuffer, 640); @@ -450,18 +455,21 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 47, 0, 0, 0); gInventoryButtonUpFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonUpFrmHandle); if (gInventoryButtonUpFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 46, 0, 0, 0); gInventoryButtonDownFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonDownFrmHandle); if (gInventoryButtonDownFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } gInventoryButton = buttonCreate(gInterfaceBarWindow, 211, 40, 32, 21, -1, -1, -1, KEY_LOWERCASE_I, gInventoryButtonUpFrmData, gInventoryButtonDownFrmData, NULL, 0); if (gInventoryButton == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } buttonSetCallbacks(gInventoryButton, _gsound_med_butt_press, _gsound_med_butt_release); @@ -469,18 +477,21 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 18, 0, 0, 0); gOptionsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonUpFrmHandle); if (gOptionsButtonUpFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 17, 0, 0, 0); gOptionsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonDownFrmHandle); if (gOptionsButtonDownFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } gOptionsButton = buttonCreate(gInterfaceBarWindow, 210, 61, 34, 34, -1, -1, -1, KEY_LOWERCASE_O, gOptionsButtonUpFrmData, gOptionsButtonDownFrmData, NULL, 0); if (gOptionsButton == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } buttonSetCallbacks(gOptionsButton, _gsound_med_butt_press, _gsound_med_butt_release); @@ -488,24 +499,28 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0); gSkilldexButtonUpFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonUpFrmHandle); if (gSkilldexButtonUpFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0); gSkilldexButtonDownFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonDownFrmHandle); if (gSkilldexButtonDownFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0); gSkilldexButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonMaskFrmHandle); if (gSkilldexButtonMaskFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } gSkilldexButton = buttonCreate(gInterfaceBarWindow, 523, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_S, gSkilldexButtonUpFrmData, gSkilldexButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT); if (gSkilldexButton == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } buttonSetMask(gSkilldexButton, gSkilldexButtonMaskFrmData); @@ -514,24 +529,28 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0); gMapButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMapButtonUpFrmHandle); if (gMapButtonUpFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 10, 0, 0, 0); gMapButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMapButtonDownFrmHandle); if (gMapButtonDownFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0); gMapButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gMapButtonMaskFrmHandle); if (gMapButtonMaskFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } gMapButton = buttonCreate(gInterfaceBarWindow, 526, 39, 41, 19, -1, -1, -1, KEY_TAB, gMapButtonUpFrmData, gMapButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT); if (gMapButton == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } buttonSetMask(gMapButton, gMapButtonMaskFrmData); @@ -540,18 +559,21 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 59, 0, 0, 0); gPipboyButtonUpFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonUpFrmHandle); if (gPipboyButtonUpFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 58, 0, 0, 0); gPipboyButtonDownFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonDownFrmHandle); if (gPipboyButtonDownFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } gPipboyButton = buttonCreate(gInterfaceBarWindow, 526, 77, 41, 19, -1, -1, -1, KEY_LOWERCASE_P, gPipboyButtonUpFrmData, gPipboyButtonDownFrmData, NULL, 0); if (gPipboyButton == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } buttonSetMask(gPipboyButton, gMapButtonMaskFrmData); @@ -560,18 +582,21 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 57, 0, 0, 0); gCharacterButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonUpFrmHandle); if (gCharacterButtonUpFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 56, 0, 0, 0); gCharacterButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonDownFrmHandle); if (gCharacterButtonDownFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } gCharacterButton = buttonCreate(gInterfaceBarWindow, 526, 58, 41, 19, -1, -1, -1, KEY_LOWERCASE_C, gCharacterButtonUpFrmData, gCharacterButtonDownFrmData, NULL, 0); if (gCharacterButton == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } buttonSetMask(gCharacterButton, gMapButtonMaskFrmData); @@ -580,19 +605,22 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 32, 0, 0, 0); gSingleAttackButtonUpData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonUpHandle); if (gSingleAttackButtonUpData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 31, 0, 0, 0); gSingleAttackButtonDownData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonDownHandle); if (gSingleAttackButtonDownData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 73, 0, 0, 0); _itemButtonDisabled = artLockFrameData(fid, 0, 0, &_itemButtonDisabledKey); if (_itemButtonDisabled == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } memcpy(_itemButtonUp, gSingleAttackButtonUpData, sizeof(_itemButtonUp)); @@ -600,7 +628,8 @@ int interfaceInit() gSingleAttackButton = buttonCreate(gInterfaceBarWindow, 267, 26, 188, 67, -1, -1, -1, -20, _itemButtonUp, _itemButtonDown, NULL, BUTTON_FLAG_TRANSPARENT); if (gSingleAttackButton == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } buttonSetRightMouseCallbacks(gSingleAttackButton, -1, KEY_LOWERCASE_N, NULL, NULL); @@ -609,25 +638,29 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0); gChangeHandsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonUpFrmHandle); if (gChangeHandsButtonUpFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0); gChangeHandsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonDownFrmHandle); if (gChangeHandsButtonDownFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0); gChangeHandsButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonMaskFrmHandle); if (gChangeHandsButtonMaskFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } // Swap hands button gChangeHandsButton = buttonCreate(gInterfaceBarWindow, 218, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_B, gChangeHandsButtonUpFrmData, gChangeHandsButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT); if (gChangeHandsButton == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } buttonSetMask(gChangeHandsButton, gChangeHandsButtonMaskFrmData); @@ -636,39 +669,42 @@ int interfaceInit() fid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0); gNumbersFrmData = artLockFrameData(fid, 0, 0, &gNumbersFrmHandle); if (gNumbersFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 83, 0, 0, 0); gGreenLightFrmData = artLockFrameData(fid, 0, 0, &gGreenLightFrmHandle); if (gGreenLightFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 84, 0, 0, 0); gYellowLightFrmData = artLockFrameData(fid, 0, 0, &gYellowLightFrmHandle); if (gYellowLightFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } fid = buildFid(OBJ_TYPE_INTERFACE, 85, 0, 0, 0); gRedLightFrmData = artLockFrameData(fid, 0, 0, &gRedLightFrmHandle); if (gRedLightFrmData == NULL) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } blitBufferToBuffer(gInterfaceWindowBuffer + 640 * 14 + 316, 90, 5, 640, gInterfaceActionPointsBarBackground, 90); if (indicatorBarInit() == -1) { - goto err; + // NOTE: Uninline. + return intface_fatal_error(-1); } gInterfaceCurrentHand = HAND_LEFT; - // FIXME: For unknown reason these values initialized with -1. It's never - // checked for -1, so I have no explanation for this. - gInterfaceItemStates[HAND_LEFT].item = (Object*)-1; - gInterfaceItemStates[HAND_RIGHT].item = (Object*)-1; + // NOTE: Uninline. + intface_init_items(); displayMonitorInit(); @@ -677,12 +713,6 @@ int interfaceInit() _intfaceHidden = 1; return 0; - -err: - - interfaceFree(); - - return -1; } // 0x45E3D0 @@ -690,10 +720,8 @@ void interfaceReset() { interfaceBarEnable(); - if (gInterfaceBarWindow != -1 && !_intfaceHidden) { - windowHide(gInterfaceBarWindow); - _intfaceHidden = 1; - } + // NOTE: Uninline. + intface_hide(); indicatorBarRefresh(); displayMonitorReset(); @@ -925,11 +953,8 @@ int interfaceLoad(File* stream) } if (v2) { - if (gInterfaceBarWindow != -1 && !_intfaceHidden) { - windowHide(gInterfaceBarWindow); - _intfaceHidden = 1; - } - indicatorBarRefresh(); + // NOTE: Uninline. + intface_hide(); } else { _intface_show(); } @@ -975,6 +1000,20 @@ int interfaceSave(File* stream) return 0; } +// NOTE: Inlined. +// +// 0x45E9E0 +void intface_hide() +{ + if (gInterfaceBarWindow != -1) { + if (!_intfaceHidden) { + windowHide(gInterfaceBarWindow); + _intfaceHidden = 1; + } + } + indicatorBarRefresh(); +} + // 0x45EA10 void _intface_show() { @@ -1708,6 +1747,19 @@ void interfaceBarEndButtonsRenderRedLights() } } +// NOTE: Inlined. +// +// 0x45FD2C +static int intface_init_items() +{ + // FIXME: For unknown reason these values initialized with -1. It's never + // checked for -1, so I have no explanation for this. + gInterfaceItemStates[HAND_LEFT].item = (Object*)-1; + gInterfaceItemStates[HAND_RIGHT].item = (Object*)-1; + + return 0; +} + // 0x45FD88 static int interfaceBarRefreshMainAction() { @@ -2358,6 +2410,16 @@ static void interfaceRenderCounter(int x, int y, int previousValue, int value, i } } +// NOTE: Inlined. +// +// 0x461128 +static int intface_fatal_error(int rc) +{ + interfaceFree(); + + return rc; +} + // 0x461134 static int indicatorBarInit() { diff --git a/src/interface.h b/src/interface.h index ccff557..08382f5 100644 --- a/src/interface.h +++ b/src/interface.h @@ -37,6 +37,7 @@ void interfaceReset(); void interfaceFree(); int interfaceLoad(File* stream); int interfaceSave(File* stream); +void intface_hide(); void _intface_show(); void interfaceBarEnable(); void interfaceBarDisable(); diff --git a/src/interpreter.cc b/src/interpreter.cc index 7e96d74..ef2a7a8 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -21,7 +21,7 @@ typedef struct ProgramListNode { struct ProgramListNode* prev; // prev } ProgramListNode; -static int _defaultTimerFunc(); +static unsigned int _defaultTimerFunc(); static char* _defaultFilename_(char* s); static int _outputStr(char* a1); static int _checkWait(Program* program); @@ -34,12 +34,14 @@ static void stackPushInt16(unsigned char* a1, int* a2, int value); static void stackPushInt32(unsigned char* a1, int* a2, int value); static int stackPopInt32(unsigned char* a1, int* a2); static opcode_t stackPopInt16(unsigned char* a1, int* a2); +static void _interpretIncStringRef(Program* program, opcode_t opcode, int value); static void programReturnStackPushInt16(Program* program, int value); static opcode_t programReturnStackPopInt16(Program* program); static int programReturnStackPopInt32(Program* program); static void _detachProgram(Program* program); static void _purgeProgram(Program* program); static void programFree(Program* program); +static opcode_t _getOp(Program* program); static void programMarkHeap(Program* program); static void opNoop(Program* program); static void opPush(Program* program); @@ -117,7 +119,9 @@ static void opExec(Program* program); static void opCheckProcedureArgumentCount(Program* program); static void opLookupStringProc(Program* program); static void _setupCallWithReturnVal(Program* program, int address, int a3); +static void _setupCall(Program* program, int address, int returnAddress); static void _setupExternalCallWithReturnVal(Program* program1, Program* program2, int address, int a4); +static void _setupExternalCall(Program* program1, Program* program2, int address, int a4); static void _doEvents(); static void programListNodeFree(ProgramListNode* programListNode); static void interpreterPrintStats(); @@ -133,10 +137,10 @@ int _TimeOut = 0; static int _Enabled = 1; // 0x519040 -static int (*_timerFunc)() = _defaultTimerFunc; +InterpretTimerFunc* _timerFunc = _defaultTimerFunc; // 0x519044 -static int _timerTick = 1000; +static unsigned int _timerTick = 1000; // 0x519048 static char* (*_filenameFunc)(char*) = _defaultFilename_; @@ -163,7 +167,7 @@ static int _suspendEvents; static int _busy; // 0x4670A0 -static int _defaultTimerFunc() +static unsigned int _defaultTimerFunc() { return _get_time(); } @@ -189,7 +193,7 @@ static int _outputStr(char* a1) // 0x4670C8 static int _checkWait(Program* program) { - return 1000 * _timerFunc() / _timerTick <= program->field_70; + return 1000 * _timerFunc() / _timerTick <= program->waitEnd; } // 0x4670FC @@ -360,8 +364,18 @@ static opcode_t stackPopInt16(unsigned char* data, int* pointer) return stackReadInt16(data, *pointer); } +// NOTE: Inlined. +// +// 0x467424 +static void _interpretIncStringRef(Program* program, opcode_t opcode, int value) +{ + if (opcode == VALUE_TYPE_DYNAMIC_STRING) { + *(short*)(program->dynamicStrings + 4 + value - 2) += 1; + } +} + // 0x467440 -void programPopString(Program* program, opcode_t opcode, int value) +void _interpretDecStringRef(Program* program, opcode_t opcode, int value) { if (opcode == VALUE_TYPE_DYNAMIC_STRING) { char* string = (char*)(program->dynamicStrings + 4 + value); @@ -483,6 +497,20 @@ Program* programCreateByPath(const char* path) return program; } +// NOTE: Inlined. +// +// 0x4678BC +opcode_t _getOp(Program* program) +{ + int instructionPointer; + + instructionPointer = program->instructionPointer; + program->instructionPointer = instructionPointer + 2; + + // NOTE: Uninline. + return stackReadInt16(program->data, instructionPointer); +} + // 0x4678E0 char* programGetString(Program* program, opcode_t opcode, int offset) { @@ -741,10 +769,10 @@ static void opWait(Program* program) { int data = programStackPopInteger(program); - program->field_74 = 1000 * _timerFunc() / _timerTick; - program->field_70 = program->field_74 + data; - program->field_7C = _checkWait; - program->flags |= PROGRAM_FLAG_0x10; + program->waitStart = 1000 * _timerFunc() / _timerTick; + program->waitEnd = program->waitStart + data; + program->checkWaitFunc = _checkWait; + program->flags |= PROGRAM_IS_WAITING; } // 0x468218 @@ -809,13 +837,14 @@ static void opStore(Program* program) ProgramValue oldValue = program->stackValues->at(pos); if (oldValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { - programPopString(program, oldValue.opcode, oldValue.integerValue); + _interpretDecStringRef(program, oldValue.opcode, oldValue.integerValue); } program->stackValues->at(pos) = value; if (value.opcode == VALUE_TYPE_DYNAMIC_STRING) { - *(short*)(program->dynamicStrings + 4 + value.integerValue - 2) += 1; + // NOTE: Uninline. + _interpretIncStringRef(program, VALUE_TYPE_DYNAMIC_STRING, value.integerValue); } } @@ -1988,7 +2017,7 @@ static void opCall(Program* program) static void op801F(Program* program) { program->windowId = programStackPopInteger(program); - program->field_7C = (int (*)(Program*))programStackPopPointer(program); + program->checkWaitFunc = (InterpretCheckWaitFunc*)programStackPopPointer(program); program->flags = programStackPopInteger(program) & 0xFFFF; } @@ -2041,7 +2070,7 @@ static void op8026(Program* program) op801F(program); Program* v1 = (Program*)programReturnStackPopPointer(program); - v1->field_7C = (int (*)(Program*))programReturnStackPopPointer(program); + v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program); v1->flags = programReturnStackPopInteger(program); program->instructionPointer = programReturnStackPopInteger(program); @@ -2057,7 +2086,7 @@ static void op8022(Program* program) op801F(program); Program* v1 = (Program*)programReturnStackPopPointer(program); - v1->field_7C = (int (*)(Program*))programReturnStackPopPointer(program); + v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program); v1->flags = programReturnStackPopInteger(program); program->instructionPointer = programReturnStackPopInteger(program); @@ -2069,7 +2098,7 @@ static void op8023(Program* program) op801F(program); Program* v1 = (Program*)programReturnStackPopPointer(program); - v1->field_7C = (int (*)(Program*))programReturnStackPopPointer(program); + v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program); v1->flags = programReturnStackPopInteger(program); program->instructionPointer = programReturnStackPopInteger(program); @@ -2086,7 +2115,7 @@ static void op8024(Program* program) op801F(program); Program* v10 = (Program*)programReturnStackPopPointer(program); - v10->field_7C = (int (*)(Program*))programReturnStackPopPointer(program); + v10->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program); v10->flags = programReturnStackPopInteger(program); if ((value.opcode & 0xF7FF) == VALUE_TYPE_STRING) { char* string = programGetString(program, value.opcode, value.integerValue); @@ -2155,13 +2184,14 @@ static void opStoreGlobalVariable(Program* program) ProgramValue oldValue = program->stackValues->at(program->basePointer + addr); if (oldValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { - programPopString(program, oldValue.opcode, oldValue.integerValue); + _interpretDecStringRef(program, oldValue.opcode, oldValue.integerValue); } program->stackValues->at(program->basePointer + addr) = value; if (value.opcode == VALUE_TYPE_DYNAMIC_STRING) { - *(short*)(program->dynamicStrings + 4 + value.integerValue - 2) += 1; + // NOTE: Uninline. + _interpretIncStringRef(program, VALUE_TYPE_DYNAMIC_STRING, value.integerValue); } } @@ -2309,17 +2339,15 @@ static void opCallStart(Program* program) program->flags |= PROGRAM_FLAG_0x20; char* name = programStackPopString(program); - name = _interpretMangleName(name); - program->child = programCreateByPath(name); + + // NOTE: Uninline. + program->child = runScript(name); if (program->child == NULL) { char err[260]; sprintf(err, "Error spawning child %s", name); programFatalError(err); } - programListNodeCreate(program->child); - _interpret(program->child, 24); - program->child->parent = program; program->child->windowId = program->windowId; } @@ -2335,17 +2363,15 @@ static void opSpawn(Program* program) program->flags |= PROGRAM_FLAG_0x0100; char* name = programStackPopString(program); - name = _interpretMangleName(name); - program->child = programCreateByPath(name); + + // NOTE: Uninline. + program->child = runScript(name); if (program->child == NULL) { - char err[256]; + char err[260]; sprintf(err, "Error spawning child %s", name); programFatalError(err); } - programListNodeCreate(program->child); - _interpret(program->child, 24); - program->child->parent = program; program->child->windowId = program->windowId; @@ -2360,8 +2386,7 @@ static void opSpawn(Program* program) static Program* forkProgram(Program* program) { char* name = programStackPopString(program); - name = _interpretMangleName(name); - Program* forked = programCreateByPath(name); + Program* forked = runScript(name); if (forked == NULL) { char err[256]; @@ -2369,10 +2394,6 @@ static Program* forkProgram(Program* program) programFatalError(err); } - programListNodeCreate(forked); - - _interpret(forked, 24); - forked->windowId = program->windowId; return forked; @@ -2595,25 +2616,24 @@ void _interpret(Program* program, int a2) break; } - if ((program->flags & PROGRAM_FLAG_0x10) != 0) { + if ((program->flags & PROGRAM_IS_WAITING) != 0) { _busy = 1; - if (program->field_7C != NULL) { - if (!program->field_7C(program)) { + if (program->checkWaitFunc != NULL) { + if (!program->checkWaitFunc(program)) { _busy = 0; continue; } } _busy = 0; - program->field_7C = NULL; - program->flags &= ~PROGRAM_FLAG_0x10; + program->checkWaitFunc = NULL; + program->flags &= ~PROGRAM_IS_WAITING; } - int instructionPointer = program->instructionPointer; - program->instructionPointer = instructionPointer + 2; + // NOTE: Uninline. + opcode_t opcode = _getOp(program); - opcode_t opcode = stackReadInt16(program->data, instructionPointer); // TODO: Replace with field_82 and field_80? program->flags &= 0xFFFF; program->flags |= (opcode << 16); @@ -2663,7 +2683,7 @@ static void _setupCallWithReturnVal(Program* program, int address, int returnAdd // Save program flags programStackPushInteger(program, program->flags & 0xFFFF); - programStackPushPointer(program, (void*)program->field_7C); + programStackPushPointer(program, (void*)program->checkWaitFunc); programStackPushInteger(program, program->windowId); @@ -2671,6 +2691,15 @@ static void _setupCallWithReturnVal(Program* program, int address, int returnAdd program->instructionPointer = address; } +// NOTE: Inlined. +// +// 0x46CF78 +static void _setupCall(Program* program, int address, int returnAddress) +{ + _setupCallWithReturnVal(program, address, returnAddress); + programStackPushInteger(program, 0); +} + // 0x46CF9C static void _setupExternalCallWithReturnVal(Program* program1, Program* program2, int address, int a4) { @@ -2678,7 +2707,7 @@ static void _setupExternalCallWithReturnVal(Program* program1, Program* program2 programReturnStackPushInteger(program2, program1->flags & 0xFFFF); - programReturnStackPushPointer(program2, (void*)program1->field_7C); + programReturnStackPushPointer(program2, (void*)program1->checkWaitFunc); programReturnStackPushPointer(program2, program1); @@ -2686,7 +2715,7 @@ static void _setupExternalCallWithReturnVal(Program* program1, Program* program2 programStackPushInteger(program2, program2->flags & 0xFFFF); - programStackPushPointer(program2, (void*)program2->field_7C); + programStackPushPointer(program2, (void*)program2->checkWaitFunc); programStackPushInteger(program2, program2->windowId); @@ -2697,66 +2726,66 @@ static void _setupExternalCallWithReturnVal(Program* program1, Program* program2 program1->flags |= PROGRAM_FLAG_0x20; } -// 0x46DB58 -void _executeProc(Program* program, int procedure_index) +// NOTE: Inlined. +// +// 0x46D0B0 +static void _setupExternalCall(Program* program1, Program* program2, int address, int a4) { - Program* external_program; - char* identifier; - int address; - int arguments_count; - unsigned char* procedure_ptr; - int flags; + _setupExternalCallWithReturnVal(program1, program2, address, a4); + programStackPushInteger(program2, 0); +} + +// 0x46DB58 +void _executeProc(Program* program, int procedureIndex) +{ + unsigned char* procedurePtr; + char* procedureIdentifier; + int procedureAddress; + Program* externalProgram; + int externalProcedureAddress; + int externalProcedureArgumentCount; + int procedureFlags; char err[256]; - Program* context; - procedure_ptr = program->procedures + 4 + sizeof(Procedure) * procedure_index; - flags = stackReadInt32(procedure_ptr, 4); - if (!(flags & PROCEDURE_FLAG_IMPORTED)) { - address = stackReadInt32(procedure_ptr, 16); - - _setupCallWithReturnVal(program, address, 20); - - programStackPushInteger(program, 0); - - if (!(flags & PROCEDURE_FLAG_CRITICAL)) { - return; + procedurePtr = program->procedures + 4 + sizeof(Procedure) * procedureIndex; + procedureFlags = stackReadInt32(procedurePtr, 4); + if ((procedureFlags & PROCEDURE_FLAG_IMPORTED) != 0) { + procedureIdentifier = programGetIdentifier(program, stackReadInt32(procedurePtr, 0)); + externalProgram = externalProcedureGetProgram(procedureIdentifier, &externalProcedureAddress, &externalProcedureArgumentCount); + if (externalProgram != NULL) { + if (externalProcedureArgumentCount == 0) { + } else { + sprintf(err, "External procedure cannot take arguments in interrupt context"); + _interpretOutput(err); + } + } else { + sprintf(err, "External procedure %s not found\n", procedureIdentifier); + _interpretOutput(err); } - program->flags |= PROGRAM_FLAG_CRITICAL_SECTION; - context = program; + // NOTE: Uninline. + _setupExternalCall(program, externalProgram, externalProcedureAddress, 28); + + procedurePtr = externalProgram->procedures + 4 + sizeof(Procedure) * procedureIndex; + procedureFlags = stackReadInt32(procedurePtr, 4); + + if ((procedureFlags & PROCEDURE_FLAG_CRITICAL) != 0) { + // NOTE: Uninline. + opEnterCriticalSection(externalProgram); + _interpret(externalProgram, 0); + } } else { - identifier = programGetIdentifier(program, stackReadInt32(procedure_ptr, 0)); - external_program = externalProcedureGetProgram(identifier, &address, &arguments_count); - if (external_program == NULL) { - sprintf(err, "External procedure %s not found\n", identifier); - // TODO: Incomplete. - // _interpretOutput(err); - return; + procedureAddress = stackReadInt32(procedurePtr, 16); + + // NOTE: Uninline. + _setupCall(program, procedureAddress, 20); + + if ((procedureFlags & PROCEDURE_FLAG_CRITICAL) != 0) { + // NOTE: Uninline. + opEnterCriticalSection(program); + _interpret(program, 0); } - - if (arguments_count != 0) { - sprintf(err, "External procedure cannot take arguments in interrupt context"); - // TODO: Incomplete. - // _interpretOutput(err); - return; - } - - _setupExternalCallWithReturnVal(program, external_program, address, 28); - - programStackPushInteger(external_program, 0); - - procedure_ptr = external_program->procedures + 4 + sizeof(Procedure) * procedure_index; - flags = stackReadInt32(procedure_ptr, 4); - - if (!(flags & PROCEDURE_FLAG_CRITICAL)) { - return; - } - - external_program->flags |= PROGRAM_FLAG_CRITICAL_SECTION; - context = external_program; } - - _interpret(context, 0); } // Returns index of the procedure with specified name or -1 if no such @@ -2781,68 +2810,112 @@ int programFindProcedure(Program* program, const char* name) } // 0x46DD2C -void _executeProcedure(Program* program, int procedure_index) +void _executeProcedure(Program* program, int procedureIndex) { - Program* external_program; - char* identifier; - int address; - int arguments_count; - unsigned char* procedure_ptr; - int flags; + unsigned char* procedurePtr; + char* procedureIdentifier; + int procedureAddress; + Program* externalProgram; + int externalProcedureAddress; + int externalProcedureArgumentCount; + int procedureFlags; char err[256]; - jmp_buf jmp_buf; - Program* v13; + jmp_buf env; - procedure_ptr = program->procedures + 4 + sizeof(Procedure) * procedure_index; - flags = stackReadInt32(procedure_ptr, 4); + procedurePtr = program->procedures + 4 + sizeof(Procedure) * procedureIndex; + procedureFlags = stackReadInt32(procedurePtr, 4); - if (flags & PROCEDURE_FLAG_IMPORTED) { - identifier = programGetIdentifier(program, stackReadInt32(procedure_ptr, 0)); - external_program = externalProcedureGetProgram(identifier, &address, &arguments_count); - if (external_program == NULL) { - sprintf(err, "External procedure %s not found\n", identifier); - // TODO: Incomplete. - // _interpretOutput(err); - return; + if ((procedureFlags & PROCEDURE_FLAG_IMPORTED) != 0) { + procedureIdentifier = programGetIdentifier(program, stackReadInt32(procedurePtr, 0)); + externalProgram = externalProcedureGetProgram(procedureIdentifier, &externalProcedureAddress, &externalProcedureArgumentCount); + if (externalProgram != NULL) { + if (externalProcedureArgumentCount == 0) { + // NOTE: Uninline. + _setupExternalCall(program, externalProgram, externalProcedureAddress, 32); + memcpy(env, program->env, sizeof(env)); + _interpret(externalProgram, -1); + memcpy(externalProgram->env, env, sizeof(env)); + } else { + sprintf(err, "External procedure cannot take arguments in interrupt context"); + _interpretOutput(err); + } + } else { + sprintf(err, "External procedure %s not found\n", procedureIdentifier); + _interpretOutput(err); } - - if (arguments_count != 0) { - sprintf(err, "External procedure cannot take arguments in interrupt context"); - // TODO: Incomplete. - // _interpretOutput(err); - return; - } - - _setupExternalCallWithReturnVal(program, external_program, address, 32); - - programStackPushInteger(external_program, 0); - - memcpy(jmp_buf, program->env, sizeof(jmp_buf)); - - v13 = external_program; } else { - address = stackReadInt32(procedure_ptr, 16); + procedureAddress = stackReadInt32(procedurePtr, 16); - _setupCallWithReturnVal(program, address, 24); - - // Push number of arguments. It's always zero for built-in procs. This - // number is consumed by 0x802B. - programStackPushInteger(program, 0); - - memcpy(jmp_buf, program->env, sizeof(jmp_buf)); - - v13 = program; + // NOTE: Uninline. + _setupCall(program, procedureAddress, 24); + memcpy(env, program->env, sizeof(env)); + _interpret(program, -1); + memcpy(program->env, env, sizeof(env)); } - - _interpret(v13, -1); - - memcpy(v13->env, jmp_buf, sizeof(jmp_buf)); } // 0x46DEE4 static void _doEvents() { - // TODO: Incomplete. + ProgramListNode* programListNode; + unsigned int time; + int procedureCount; + int procedureIndex; + unsigned char* procedurePtr; + int procedureFlags; + int oldProgramFlags; + int oldInstructionPointer; + int data; + jmp_buf env; + + if (_suspendEvents) { + return; + } + + programListNode = gInterpreterProgramListHead; + time = 1000 * _timerFunc() / _timerTick; + + while (programListNode != NULL) { + procedureCount = stackReadInt32(programListNode->program->procedures, 0); + + procedurePtr = programListNode->program->procedures + 4; + for (procedureIndex = 0; procedureIndex < procedureCount; procedureIndex++) { + procedureFlags = stackReadInt32(procedurePtr, 4); + if ((procedureFlags & PROCEDURE_FLAG_CONDITIONAL) != 0) { + memcpy(env, programListNode->program, sizeof(env)); + oldProgramFlags = programListNode->program->flags; + oldInstructionPointer = programListNode->program->instructionPointer; + + programListNode->program->flags = 0; + programListNode->program->instructionPointer = stackReadInt32(procedurePtr, 12); + _interpret(programListNode->program, -1); + + if ((programListNode->program->flags & PROGRAM_FLAG_0x04) == 0) { + data = programStackPopInteger(programListNode->program); + + programListNode->program->flags = oldProgramFlags; + programListNode->program->instructionPointer = oldInstructionPointer; + + if (data != 0) { + // NOTE: Uninline. + stackWriteInt32(0, procedurePtr, 4); + _executeProc(programListNode->program, procedureIndex); + } + } + + memcpy(programListNode->program, env, sizeof(env)); + } else if ((procedureFlags & PROCEDURE_FLAG_TIMED) != 0) { + if ((unsigned int)stackReadInt32(procedurePtr, 8) < time) { + // NOTE: Uninline. + stackWriteInt32(0, procedurePtr, 4); + _executeProc(programListNode->program, procedureIndex); + } + } + procedurePtr += sizeof(Procedure); + } + + programListNode = programListNode->next; + } } // 0x46E10C @@ -2869,8 +2942,6 @@ static void programListNodeFree(ProgramListNode* programListNode) // 0x46E154 void programListNodeCreate(Program* program) { - program->flags |= PROGRAM_FLAG_0x02; - ProgramListNode* programListNode = (ProgramListNode*)internal_malloc_safe(sizeof(*programListNode), __FILE__, __LINE__); // .\\int\\INTRPRET.C, 2907 programListNode->program = program; programListNode->next = gInterpreterProgramListHead; @@ -2883,6 +2954,33 @@ void programListNodeCreate(Program* program) gInterpreterProgramListHead = programListNode; } +// NOTE: Inlined. +// +// 0x46E15C +void runProgram(Program* program) +{ + program->flags |= PROGRAM_FLAG_0x02; + programListNodeCreate(program); +} + +// NOTE: Inlined. +// +// 0x46E19C +Program* runScript(char* name) +{ + Program* program; + + // NOTE: Uninline. + program = programCreateByPath(_interpretMangleName(name)); + if (program != NULL) { + // NOTE: Uninline. + runProgram(program); + _interpret(program, 24); + } + + return program; +} + // 0x46E1EC void _updatePrograms() { @@ -2971,7 +3069,8 @@ void programStackPushValue(Program* program, ProgramValue& programValue) program->stackValues->push_back(programValue); if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { - *(short*)(program->dynamicStrings + 4 + programValue.integerValue - 2) += 1; + // NOTE: Uninline. + _interpretIncStringRef(program, VALUE_TYPE_DYNAMIC_STRING, programValue.integerValue); } } @@ -3017,7 +3116,7 @@ ProgramValue programStackPopValue(Program* program) program->stackValues->pop_back(); if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { - programPopString(program, programValue.opcode, programValue.integerValue); + _interpretDecStringRef(program, programValue.opcode, programValue.integerValue); } return programValue; @@ -3076,7 +3175,8 @@ void programReturnStackPushValue(Program* program, ProgramValue& programValue) program->returnStackValues->push_back(programValue); if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { - *(short*)(program->dynamicStrings + 4 + programValue.integerValue - 2) += 1; + // NOTE: Uninline. + _interpretIncStringRef(program, VALUE_TYPE_DYNAMIC_STRING, programValue.integerValue); } } @@ -3106,7 +3206,7 @@ ProgramValue programReturnStackPopValue(Program* program) program->returnStackValues->pop_back(); if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { - programPopString(program, programValue.opcode, programValue.integerValue); + _interpretDecStringRef(program, programValue.opcode, programValue.integerValue); } return programValue; diff --git a/src/interpreter.h b/src/interpreter.h index e52e966..ae0dc32 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -100,7 +100,9 @@ typedef enum ProgramFlags { PROGRAM_FLAG_0x02 = 0x02, PROGRAM_FLAG_0x04 = 0x04, PROGRAM_FLAG_STOPPED = 0x08, - PROGRAM_FLAG_0x10 = 0x10, + + // Program is in waiting state with `checkWaitFunc` set. + PROGRAM_IS_WAITING = 0x10, PROGRAM_FLAG_0x20 = 0x20, PROGRAM_FLAG_0x40 = 0x40, PROGRAM_FLAG_CRITICAL_SECTION = 0x80, @@ -147,6 +149,9 @@ typedef struct ProgramValue { typedef std::vector ProgramStack; +typedef struct Program Program; +typedef int(InterpretCheckWaitFunc)(Program* program); + // It's size in original code is 144 (0x8C) bytes due to the different // size of `jmp_buf`. typedef struct Program { @@ -162,10 +167,10 @@ typedef struct Program { unsigned char* identifiers; unsigned char* procedures; jmp_buf env; - int field_70; // end time of timer (field_74 + wait time) - int field_74; // time when wait was called + unsigned int waitEnd; // end time of timer (field_74 + wait time) + unsigned int waitStart; // time when wait was called int field_78; // time when program begin execution (for the first time)?, -1 - program never executed - int (*field_7C)(struct Program* s); // proc to check timer + InterpretCheckWaitFunc* checkWaitFunc; int flags; // flags int windowId; bool exited; @@ -173,6 +178,7 @@ typedef struct Program { ProgramStack* returnStackValues; } Program; +typedef unsigned int(InterpretTimerFunc)(); typedef void OpcodeHandler(Program* program); extern int _TimeOut; @@ -181,7 +187,7 @@ char* _interpretMangleName(char* s); 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 _interpretDecStringRef(Program* program, opcode_t a2, int a3); Program* programCreateByPath(const char* path); char* programGetString(Program* program, opcode_t opcode, int offset); char* programGetIdentifier(Program* program, int offset); @@ -189,10 +195,12 @@ int programPushString(Program* program, char* string); void interpreterRegisterOpcodeHandlers(); void _interpretClose(); void _interpret(Program* program, int a2); -void _executeProc(Program* program, int procedure_index); +void _executeProc(Program* program, int procedureIndex); int programFindProcedure(Program* prg, const char* name); -void _executeProcedure(Program* program, int procedure_index); +void _executeProcedure(Program* program, int procedureIndex); void programListNodeCreate(Program* program); +void runProgram(Program* program); +Program* runScript(char* name); void _updatePrograms(); void programListFree(); void interpreterRegisterOpcode(int opcode, OpcodeHandler* handler); diff --git a/src/interpreter_extra.cc b/src/interpreter_extra.cc index 6824ea1..b700ad7 100644 --- a/src/interpreter_extra.cc +++ b/src/interpreter_extra.cc @@ -2025,7 +2025,7 @@ static void opMetarule3(Program* program) } break; case METARULE3_MARK_SUBTILE: - result.integerValue = _wmSubTileMarkRadiusVisited(param1.integerValue, param2.integerValue, param3.integerValue); + result.integerValue = wmSubTileMarkRadiusVisited(param1.integerValue, param2.integerValue, param3.integerValue); break; case METARULE3_GET_KILL_COUNT: result.integerValue = killsGetByType(param1.integerValue); @@ -2694,7 +2694,7 @@ static void opGameDialogSystemEnter(Program* program) return; } - if (_game_state_request(4) == -1) { + if (_game_state_request(GAME_STATE_4) == -1) { return; } diff --git a/src/interpreter_lib.cc b/src/interpreter_lib.cc index 5a37925..a47dd12 100644 --- a/src/interpreter_lib.cc +++ b/src/interpreter_lib.cc @@ -12,7 +12,6 @@ #include "select_file_list.h" #include "sound.h" #include "text_font.h" -#include "widget.h" #include "window.h" #include "window_manager_private.h" @@ -33,7 +32,13 @@ static void opPrintRect(Program* program); static void opSelect(Program* program); static void opDisplay(Program* program); static void opDisplayRaw(Program* program); -static void sub_46222C(unsigned char* a1, unsigned char* a2, int a3, float a4, int a5); +static void _interpretFadePaletteBK(unsigned char* oldPalette, unsigned char* newPalette, int a3, float duration, bool shouldProcessBk); +static void interpretFadePalette(unsigned char* oldPalette, unsigned char* newPalette, int a3, float duration); +static int intlibGetFadeIn(); +static void interpretFadeOut(float duration); +static void interpretFadeIn(float duration); +static void interpretFadeOutNoBK(float duration); +static void interpretFadeInNoBK(float duration); static void opFadeIn(Program* program); static void opFadeOut(Program* program); static int intLibCheckMovie(Program* program); @@ -60,6 +65,8 @@ static int intLibCheckDialog(Program* program); static void opSayEnd(Program* program); static void opSayGetLastPos(Program* program); static void opSayQuit(Program* program); +static int getTimeOut(); +static void setTimeOut(int value); static void opSayMessageTimeout(Program* program); static void opSayMessage(Program* program); static void opGotoXY(Program* program); @@ -388,9 +395,109 @@ void opDisplayRaw(Program* program) } // 0x46222C -void sub_46222C(unsigned char* a1, unsigned char* a2, int a3, float a4, int a5) +static void _interpretFadePaletteBK(unsigned char* oldPalette, unsigned char* newPalette, int a3, float duration, int shouldProcessBk) { - // TODO: Incomplete. + unsigned int time; + unsigned int previousTime; + unsigned int delta; + int step; + int steps; + int index; + unsigned char palette[256 * 3]; + + time = _get_time(); + previousTime = time; + steps = (int)duration; + step = 0; + delta = 0; + + if (duration != 0.0) { + while (step < steps) { + if (delta != 0) { + for (index = 0; index < 768; index++) { + palette[index] = oldPalette[index] - (oldPalette[index] - newPalette[index]) * step / steps; + } + + _setSystemPalette(palette); + + previousTime = time; + step += delta; + } + + if (shouldProcessBk) { + _process_bk(); + } + + time = _get_time(); + delta = time - previousTime; + } + } + + _setSystemPalette(newPalette); +} + +// NOTE: Unused. +// +// 0x462330 +static void interpretFadePalette(unsigned char* oldPalette, unsigned char* newPalette, int a3, float duration) +{ + _interpretFadePaletteBK(oldPalette, newPalette, a3, duration, 1); +} + +// NOTE: Unused. +static int intlibGetFadeIn() +{ + return gIntLibIsPaletteFaded; +} + +// NOTE: Inlined. +// +// 0x462348 +static void interpretFadeOut(float duration) +{ + int cursorWasHidden; + + cursorWasHidden = cursorIsHidden(); + mouseHideCursor(); + + _interpretFadePaletteBK(_getSystemPalette(), gIntLibFadePalette, 64, duration, 1); + + if (!cursorWasHidden) { + mouseShowCursor(); + } +} + +// NOTE: Inlined. +// +// 0x462380 +static void interpretFadeIn(float duration) +{ + _interpretFadePaletteBK(gIntLibFadePalette, _cmap, 64, duration, 1); +} + +// NOTE: Unused. +// +// 0x4623A4 +static void interpretFadeOutNoBK(float duration) +{ + int cursorWasHidden; + + cursorWasHidden = cursorIsHidden(); + mouseHideCursor(); + + _interpretFadePaletteBK(_getSystemPalette(), gIntLibFadePalette, 64, duration, 0); + + if (!cursorWasHidden) { + mouseShowCursor(); + } +} + +// NOTE: Unused. +// +// 0x4623DC +static void interpretFadeInNoBK(float duration) +{ + _interpretFadePaletteBK(gIntLibFadePalette, _cmap, 64, duration, 0); } // fadein @@ -403,7 +510,9 @@ void opFadeIn(Program* program) _setSystemPalette(gIntLibFadePalette); - sub_46222C(gIntLibFadePalette, _cmap, 64, (float)data, 1); + // NOTE: Uninline. + interpretFadeIn((float)data); + gIntLibIsPaletteFaded = true; program->flags &= ~PROGRAM_FLAG_0x20; @@ -420,7 +529,8 @@ void opFadeOut(Program* program) bool cursorWasHidden = cursorIsHidden(); mouseHideCursor(); - sub_46222C(_getSystemPalette(), gIntLibFadePalette, 64, (float)data, 1); + // NOTE: Uninline. + interpretFadeOut((float)data); if (!cursorWasHidden) { mouseShowCursor(); @@ -466,8 +576,8 @@ void opPlayMovie(Program* program) _selectWindowID(program->windowId); - program->flags |= PROGRAM_FLAG_0x10; - program->field_7C = intLibCheckMovie; + program->flags |= PROGRAM_IS_WAITING; + program->checkWaitFunc = intLibCheckMovie; char* mangledFileName = _interpretMangleName(gIntLibPlayMovieFileName); if (!_windowPlayMovie(mangledFileName)) { @@ -493,8 +603,8 @@ void opPlayMovieRect(Program* program) _selectWindowID(program->windowId); - program->field_7C = intLibCheckMovie; - program->flags |= PROGRAM_FLAG_0x10; + program->checkWaitFunc = intLibCheckMovie; + program->flags |= PROGRAM_IS_WAITING; char* mangledFileName = _interpretMangleName(gIntLibPlayMovieRectFileName); if (!_windowPlayMovieRect(mangledFileName, x, y, width, height)) { @@ -834,8 +944,8 @@ void opSayEnd(Program* program) program->flags &= ~PROGRAM_FLAG_0x20; if (rc == -2) { - program->field_7C = intLibCheckDialog; - program->flags |= PROGRAM_FLAG_0x10; + program->checkWaitFunc = intLibCheckDialog; + program->flags |= PROGRAM_IS_WAITING; } } @@ -856,6 +966,22 @@ static void opSayQuit(Program* program) } } +// NOTE: Unused. +// +// 0x463828 +static int getTimeOut() +{ + return _TimeOut; +} + +// NOTE: Unused. +// +// 0x463830 +static void setTimeOut(int value) +{ + _TimeOut = value; +} + // saymessagetimeout // 0x463838 static void opSayMessageTimeout(Program* program) @@ -1307,7 +1433,7 @@ static void opSetFont(Program* program) { int data = programStackPopInteger(program); - if (!widgetSetFont(data)) { + if (!windowSetFont(data)) { programFatalError("Error setting font"); } } @@ -1318,7 +1444,7 @@ static void opSetTextFlags(Program* program) { int data = programStackPopInteger(program); - if (!widgetSetTextFlags(data)) { + if (!windowSetTextFlags(data)) { programFatalError("Error setting text flags"); } } @@ -1345,7 +1471,7 @@ static void opSetTextColor(Program* program) float g = value[1].floatValue; float b = value[0].floatValue; - if (!widgetSetTextColor(r, g, b)) { + if (!windowSetTextColor(r, g, b)) { programFatalError("Error setting text color"); } } @@ -1426,7 +1552,7 @@ static void opSetHighlightColor(Program* program) float g = value[1].floatValue; float b = value[0].floatValue; - if (!widgetSetHighlightColor(r, g, b)) { + if (!windowSetHighlightColor(r, g, b)) { programFatalError("Error setting text highlight color"); } } diff --git a/src/inventory.cc b/src/inventory.cc index 7663727..f002a9b 100644 --- a/src/inventory.cc +++ b/src/inventory.cc @@ -599,7 +599,7 @@ void inventoryOpen() _display_body(-1, INVENTORY_WINDOW_TYPE_NORMAL); - if (_game_state() == 5) { + if (_game_state() == GAME_STATE_5) { break; } diff --git a/src/main.cc b/src/main.cc index ffee147..8e30686 100644 --- a/src/main.cc +++ b/src/main.cc @@ -70,7 +70,11 @@ typedef enum MainMenuOption { } MainMenuOption; static bool falloutInit(int argc, char** argv); +static int main_reset_system(); +static void main_exit_system(); static int _main_load_new(char* fname); +static int main_loadgame_new(); +static void main_unload_new(); static void mainLoop(FpsLimiter& fpsLimiter); static void _main_selfrun_exit(); static void _main_selfrun_record(); @@ -85,6 +89,8 @@ static void mainMenuWindowHide(bool animate); static void mainMenuWindowUnhide(bool animate); static int _main_menu_is_enabled(); static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter); +static int main_menu_fatal_error(); +static void main_menu_play_sound(const char* fileName); // 0x5194C8 static char _mainMap[] = "artemple.map"; @@ -236,9 +242,13 @@ int falloutMain(int argc, char** argv) mainLoop(fpsLimiter); paletteFadeTo(gPaletteWhite); - objectHide(gDude, NULL); - _map_exit(); - gameReset(); + + // NOTE: Uninline. + main_unload_new(); + + // NOTE: Uninline. + main_reset_system(); + if (_main_show_death_scene != 0) { showDeath(); _main_show_death_scene = 0; @@ -253,14 +263,10 @@ int falloutMain(int argc, char** argv) int win = windowCreate(0, 0, screenGetWidth(), screenGetHeight(), _colorTable[0], WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04); mainMenuWindowHide(true); mainMenuWindowFree(); - _game_user_wants_to_quit = 0; - gDude->flags &= ~OBJECT_FLAT; - _main_show_death_scene = 0; - objectShow(gDude, NULL); - mouseHideCursor(); - _map_init(); - gameMouseSetCursor(MOUSE_CURSOR_NONE); - mouseShowCursor(); + + // NOTE: Uninline. + main_loadgame_new(); + colorPaletteLoad("color.pal"); paletteFadeTo(_cmap); int loadGameRc = lsgLoadGame(LOAD_SAVE_MODE_FROM_MAIN_MENU); @@ -275,9 +281,13 @@ int falloutMain(int argc, char** argv) if (win != -1) { windowDestroy(win); } - objectHide(gDude, NULL); - _map_exit(); - gameReset(); + + // NOTE: Uninline. + main_unload_new(); + + // NOTE: Uninline. + main_reset_system(); + if (_main_show_death_scene != 0) { showDeath(); _main_show_death_scene = 0; @@ -324,9 +334,8 @@ int falloutMain(int argc, char** argv) } } - backgroundSoundDelete(); - _main_selfrun_exit(); - gameExit(); + // NOTE: Uninline. + main_exit_system(); autorunMutexClose(); @@ -351,6 +360,29 @@ static bool falloutInit(int argc, char** argv) return true; } +// NOTE: Inlined. +// +// 0x480D0C +static int main_reset_system() +{ + gameReset(); + + return 1; +} + +// NOTE: Inlined. +// +// 0x480D18 +static void main_exit_system() +{ + backgroundSoundDelete(); + + // NOTE: Uninline. + _main_selfrun_exit(); + + gameExit(); +} + // 0x480D4C static int _main_load_new(char* mapFileName) { @@ -377,6 +409,34 @@ static int _main_load_new(char* mapFileName) return 0; } +// NOTE: Inlined. +// +// 0x480DF8 +static int main_loadgame_new() +{ + _game_user_wants_to_quit = 0; + _main_show_death_scene = 0; + + gDude->flags &= ~OBJECT_FLAT; + + objectShow(gDude, NULL); + mouseHideCursor(); + + _map_init(); + + gameMouseSetCursor(MOUSE_CURSOR_NONE); + mouseShowCursor(); + + return 0; +} + +// 0x480E34 +static void main_unload_new() +{ + objectHide(gDude, NULL); + _map_exit(); +} + // 0x480E48 static void mainLoop(FpsLimiter& fpsLimiter) { @@ -461,14 +521,21 @@ static void _main_selfrun_record() mainMenuWindowFree(); backgroundSoundDelete(); randomSeedPrerandom(0xBEEFFEED); - gameReset(); + + // NOTE: Uninline. + main_reset_system(); + _proto_dude_init("premade\\combat.gcd"); _main_load_new(selfrunData.mapFileName); selfrunRecordingLoop(&selfrunData); paletteFadeTo(gPaletteWhite); - objectHide(gDude, NULL); - _map_exit(); - gameReset(); + + // NOTE: Uninline. + main_unload_new(); + + // NOTE: Uninline. + main_reset_system(); + mainMenuWindowInit(); if (_main_selfrun_list != NULL) { @@ -491,14 +558,21 @@ static void _main_selfrun_play() mainMenuWindowFree(); backgroundSoundDelete(); randomSeedPrerandom(0xBEEFFEED); - gameReset(); + + // NOTE: Uninline. + main_reset_system(); + _proto_dude_init("premade\\combat.gcd"); _main_load_new(selfrunData.mapFileName); selfrunPlaybackLoop(&selfrunData); paletteFadeTo(gPaletteWhite); - objectHide(gDude, NULL); - _map_exit(); - gameReset(); + + // NOTE: Uninline. + main_unload_new(); + + // NOTE: Uninline. + main_reset_system(); + mainMenuWindowInit(); } @@ -747,8 +821,8 @@ static int mainMenuWindowInit() 0, WINDOW_HIDDEN | WINDOW_FLAG_0x04); if (gMainMenuWindow == -1) { - mainMenuWindowFree(); - return -1; + // NOTE: Uninline. + return main_menu_fatal_error(); } gMainMenuWindowBuffer = windowGetBuffer(gMainMenuWindow); @@ -757,8 +831,8 @@ static int mainMenuWindowInit() int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 140, 0, 0, 0); gMainMenuBackgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &gMainMenuBackgroundFrmHandle); if (gMainMenuBackgroundFrmData == NULL) { - mainMenuWindowFree(); - return -1; + // NOTE: Uninline. + return main_menu_fatal_error(); } blitBufferToBuffer(gMainMenuBackgroundFrmData, 640, 480, 640, gMainMenuWindowBuffer, 640); @@ -803,16 +877,16 @@ static int mainMenuWindowInit() fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0); gMainMenuButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonUpFrmHandle); if (gMainMenuButtonUpFrmData == NULL) { - mainMenuWindowFree(); - return -1; + // NOTE: Uninline. + return main_menu_fatal_error(); } // menudown.frm fid = buildFid(OBJ_TYPE_INTERFACE, 300, 0, 0, 0); gMainMenuButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonDownFrmHandle); if (gMainMenuButtonDownFrmData == NULL) { - mainMenuWindowFree(); - return -1; + // NOTE: Uninline. + return main_menu_fatal_error(); } for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) { @@ -827,8 +901,8 @@ static int mainMenuWindowInit() for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) { gMainMenuButtons[index] = buttonCreate(gMainMenuWindow, offsetX + 30, offsetY + 19 + index * 42 - index, 26, 26, -1, -1, 1111, gMainMenuButtonKeyBindings[index], gMainMenuButtonUpFrmData, gMainMenuButtonDownFrmData, 0, 32); if (gMainMenuButtons[index] == -1) { - mainMenuWindowFree(); - return -1; + // NOTE: Uninline. + return main_menu_fatal_error(); } buttonSetMask(gMainMenuButtons[index], gMainMenuButtonUpFrmData); @@ -962,7 +1036,8 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter) for (int buttonIndex = 0; buttonIndex < MAIN_MENU_BUTTON_COUNT; buttonIndex++) { if (keyCode == gMainMenuButtonKeyBindings[buttonIndex] || keyCode == toupper(gMainMenuButtonKeyBindings[buttonIndex])) { - soundPlayFile("nmselec1"); + // NOTE: Uninline. + main_menu_play_sound("nmselec1"); rc = _return_values[buttonIndex]; @@ -987,7 +1062,8 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter) continue; } else if (keyCode == 1111) { if (!(mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT)) { - soundPlayFile("nmselec0"); + // NOTE: Uninline. + main_menu_play_sound("nmselec0"); } continue; } @@ -995,7 +1071,9 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter) if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit == 3) { rc = MAIN_MENU_EXIT; - soundPlayFile("nmselec1"); + + // NOTE: Uninline. + main_menu_play_sound("nmselec1"); break; } else if (_game_user_wants_to_quit == 2) { _game_user_wants_to_quit = 0; @@ -1016,3 +1094,21 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter) return rc; } + +// NOTE: Inlined. +// +// 0x481C88 +static int main_menu_fatal_error() +{ + mainMenuWindowFree(); + + return -1; +} + +// NOTE: Inlined. +// +// 0x481C94 +static void main_menu_play_sound(const char* fileName) +{ + soundPlayFile(fileName); +} diff --git a/src/memory.cc b/src/memory.cc index 7da705c..b91ffd0 100644 --- a/src/memory.cc +++ b/src/memory.cc @@ -31,6 +31,7 @@ static void* memoryBlockMallocImpl(size_t size); static void* memoryBlockReallocImpl(void* ptr, size_t size); static void memoryBlockFreeImpl(void* ptr); static void memoryBlockPrintStats(); +static void* mem_prep_block(void* block, size_t size); static void memoryBlockValidate(void* block); // 0x51DED0 @@ -81,12 +82,8 @@ static void* memoryBlockMallocImpl(size_t size) unsigned char* block = (unsigned char*)malloc(size); if (block != NULL) { - MemoryBlockHeader* header = (MemoryBlockHeader*)block; - header->size = size; - header->guard = MEMORY_BLOCK_HEADER_GUARD; - - MemoryBlockFooter* footer = (MemoryBlockFooter*)(block + size - sizeof(MemoryBlockFooter)); - footer->guard = MEMORY_BLOCK_FOOTER_GUARD; + // NOTE: Uninline. + ptr = mem_prep_block(block, size); gMemoryBlocksCurrentCount++; if (gMemoryBlocksCurrentCount > gMemoryBlockMaximumCount) { @@ -97,8 +94,6 @@ static void* memoryBlockMallocImpl(size_t size) if (gMemoryBlocksCurrentSize > gMemoryBlocksMaximumSize) { gMemoryBlocksMaximumSize = gMemoryBlocksCurrentSize; } - - ptr = block + sizeof(MemoryBlockHeader); } } @@ -130,19 +125,13 @@ static void* memoryBlockReallocImpl(void* ptr, size_t size) unsigned char* newBlock = (unsigned char*)realloc(block, size); if (newBlock != NULL) { - MemoryBlockHeader* newHeader = (MemoryBlockHeader*)newBlock; - newHeader->size = size; - newHeader->guard = MEMORY_BLOCK_HEADER_GUARD; - - MemoryBlockFooter* newFooter = (MemoryBlockFooter*)(newBlock + size - sizeof(MemoryBlockFooter)); - newFooter->guard = MEMORY_BLOCK_FOOTER_GUARD; - gMemoryBlocksCurrentSize += size; if (gMemoryBlocksCurrentSize > gMemoryBlocksMaximumSize) { gMemoryBlocksMaximumSize = gMemoryBlocksCurrentSize; } - ptr = newBlock + sizeof(MemoryBlockHeader); + // NOTE: Uninline. + ptr = mem_prep_block(newBlock, size); } else { if (size != 0) { gMemoryBlocksCurrentSize += oldSize; @@ -194,6 +183,24 @@ static void memoryBlockPrintStats() } } +// NOTE: Inlined. +// +// 0x4C5CC4 +static void* mem_prep_block(void* block, size_t size) +{ + MemoryBlockHeader* header; + MemoryBlockFooter* footer; + + header = (MemoryBlockHeader*)block; + header->guard = MEMORY_BLOCK_HEADER_GUARD; + header->size = size; + + footer = (MemoryBlockFooter*)((unsigned char*)block + size - sizeof(*footer)); + footer->guard = MEMORY_BLOCK_FOOTER_GUARD; + + return (unsigned char*)block + sizeof(*header); +} + // Validates integrity of the memory block. // // [block] is a pointer to the the memory block itself, not it's data. diff --git a/src/scripts.cc b/src/scripts.cc index dd31748..c94c657 100644 --- a/src/scripts.cc +++ b/src/scripts.cc @@ -744,7 +744,7 @@ static void _script_chk_timed_events() v1 = true; } - if (_game_state() != 4) { + if (_game_state() != GAME_STATE_4) { if (getTicksBetween(v0, _last_light_time) >= 30000) { _last_light_time = v0; scriptsExecMapUpdateScripts(SCRIPT_PROC_MAP_UPDATE); @@ -1308,7 +1308,8 @@ int scriptExecProc(int sid, int proc) } script->action = 0; - programListNodeCreate(program); + // NOTE: Uninline. + runProgram(program); _interpret(program, -1); } diff --git a/src/skill.cc b/src/skill.cc index d3ea37f..8158b9a 100644 --- a/src/skill.cc +++ b/src/skill.cc @@ -48,6 +48,7 @@ typedef struct SkillDescription { static void _show_skill_use_messages(Object* obj, int skill, Object* a3, int a4, int a5); static int skillGetFreeUsageSlot(int skill); +static int skill_use_slot_clear(); // Damage flags which can be repaired using "Repair" skill. // @@ -152,7 +153,8 @@ int skillsInit() gTaggedSkills[index] = -1; } - memset(_timesSkillUsed, 0, sizeof(_timesSkillUsed)); + // NOTE: Uninline. + skill_use_slot_clear(); return 0; } @@ -164,7 +166,8 @@ void skillsReset() gTaggedSkills[index] = -1; } - memset(_timesSkillUsed, 0, sizeof(_timesSkillUsed)); + // NOTE: Uninline. + skill_use_slot_clear(); } // 0x4AA478 @@ -1172,6 +1175,15 @@ int skillUpdateLastUse(int skill) return 0; } +// NOTE: Inlined. +// +// 0x4ABF24 +int skill_use_slot_clear() +{ + memset(_timesSkillUsed, 0, sizeof(_timesSkillUsed)); + return 0; +} + // 0x4ABF3C int skillsUsageSave(File* stream) { diff --git a/src/widget.cc b/src/widget.cc index b74eada..34db14d 100644 --- a/src/widget.cc +++ b/src/widget.cc @@ -1,17 +1,6 @@ #include "widget.h" -#include "color.h" -#include "text_font.h" -#include "window.h" - static void _showRegion(int a1); -static unsigned char widgetGetHighlightColor(); - -// 0x50EB1C -static const float flt_50EB1C = 31.0f; - -// 0x50EB20 -static const float flt_50EB20 = 31.0f; // 0x66E6A0 static int _updateRegions[32]; @@ -34,65 +23,6 @@ int _update_widgets() return 1; } -// 0x4B6120 -int widgetGetFont() -{ - return gWidgetFont; -} - -// 0x4B6128 -int widgetSetFont(int a1) -{ - gWidgetFont = a1; - fontSetCurrent(a1); - return 1; -} - -// 0x4B6160 -int widgetGetTextFlags() -{ - return gWidgetTextFlags; -} - -// 0x4B6168 -int widgetSetTextFlags(int a1) -{ - gWidgetTextFlags = a1; - return 1; -} - -// 0x4B6174 -unsigned char widgetGetTextColor() -{ - return _colorTable[_currentTextColorB | (_currentTextColorG << 5) | (_currentTextColorR << 10)]; -} - -// 0x4B6198 -unsigned char widgetGetHighlightColor() -{ - return _colorTable[_currentHighlightColorB | (_currentHighlightColorG << 5) | (_currentHighlightColorR << 10)]; -} - -// 0x4B61BC -int widgetSetTextColor(float a1, float a2, float a3) -{ - _currentTextColorR = (int)(a1 * flt_50EB1C); - _currentTextColorG = (int)(a2 * flt_50EB1C); - _currentTextColorB = (int)(a3 * flt_50EB1C); - - return 1; -} - -// 0x4B6208 -int widgetSetHighlightColor(float a1, float a2, float a3) -{ - _currentHighlightColorR = (int)(a1 * flt_50EB20); - _currentHighlightColorG = (int)(a2 * flt_50EB20); - _currentHighlightColorB = (int)(a3 * flt_50EB20); - - return 1; -} - // 0x4B5998 void sub_4B5998(int win) { diff --git a/src/widget.h b/src/widget.h index 6d18e2b..4edae67 100644 --- a/src/widget.h +++ b/src/widget.h @@ -2,13 +2,6 @@ #define WIDGET_H int _update_widgets(); -int widgetGetFont(); -int widgetSetFont(int a1); -int widgetGetTextFlags(); -int widgetSetTextFlags(int a1); -unsigned char widgetGetTextColor(); -int widgetSetTextColor(float a1, float a2, float a3); -int widgetSetHighlightColor(float a1, float a2, float a3); void sub_4B5998(int win); #endif /* WIDGET_H */ diff --git a/src/window.cc b/src/window.cc index 6d1fabd..b7c2c64 100644 --- a/src/window.cc +++ b/src/window.cc @@ -152,10 +152,10 @@ static int _yres; // Highlight color (maybe r). // // 0x672D8C -int _currentHighlightColorR; +static int _currentHighlightColorR; // 0x672D90 -int gWidgetFont; +static int gWidgetFont; // 0x672D98 ButtonCallback* off_672D98; @@ -166,30 +166,101 @@ ButtonCallback* off_672D9C; // Text color (maybe g). // // 0x672DA0 -int _currentTextColorG; +static int _currentTextColorG; // text color (maybe b). // // 0x672DA4 -int _currentTextColorB; +static int _currentTextColorB; // 0x672DA8 -int gWidgetTextFlags; +static int gWidgetTextFlags; // Text color (maybe r) // // 0x672DAC -int _currentTextColorR; +static int _currentTextColorR; // highlight color (maybe g) // // 0x672DB0 -int _currentHighlightColorG; +static int _currentHighlightColorG; // Highlight color (maybe b). // // 0x672DB4 -int _currentHighlightColorB; +static int _currentHighlightColorB; + +// 0x4B6120 +int windowGetFont() +{ + return gWidgetFont; +} + +// 0x4B6128 +int windowSetFont(int a1) +{ + gWidgetFont = a1; + fontSetCurrent(a1); + return 1; +} + +// NOTE: Unused. +// +// 0x4B6138 +void windowResetTextAttributes() +{ + // NOTE: Uninline. + windowSetTextColor(1.0, 1.0, 1.0); + + // NOTE: Uninline. + windowSetTextFlags(0x2000000 | 0x10000); +} + +// 0x4B6160 +int windowGetTextFlags() +{ + return gWidgetTextFlags; +} + +// 0x4B6168 +int windowSetTextFlags(int a1) +{ + gWidgetTextFlags = a1; + return 1; +} + +// 0x4B6174 +unsigned char windowGetTextColor() +{ + return _colorTable[_currentTextColorB | (_currentTextColorG << 5) | (_currentTextColorR << 10)]; +} + +// 0x4B6198 +unsigned char windowGetHighlightColor() +{ + return _colorTable[_currentHighlightColorB | (_currentHighlightColorG << 5) | (_currentHighlightColorR << 10)]; +} + +// 0x4B61BC +int windowSetTextColor(float r, float g, float b) +{ + _currentTextColorR = (int)(r * 31.0); + _currentTextColorG = (int)(g * 31.0); + _currentTextColorB = (int)(b * 31.0); + + return 1; +} + +// 0x4B6208 +int windowSetHighlightColor(float r, float g, float b) +{ + _currentHighlightColorR = (int)(r * 31.0); + _currentHighlightColorG = (int)(g * 31.0); + _currentHighlightColorB = (int)(b * 31.0); + + return 1; +} // 0x4B62E4 bool _checkRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent) @@ -750,7 +821,7 @@ int _windowOutput(char* string) int x = (int)(managedWindow->field_44 * managedWindow->field_54); int y = (int)(managedWindow->field_48 * managedWindow->field_58); // NOTE: Uses `add` at 0x4B810E, not bitwise `or`. - int flags = widgetGetTextColor() + widgetGetTextFlags(); + int flags = windowGetTextColor() + windowGetTextFlags(); windowDrawText(managedWindow->window, string, 0, x, y, flags); return 1; @@ -1067,7 +1138,7 @@ bool _windowPrintRect(char* string, int a2, int textAlignment) int height = windowGetHeight(managedWindow->window); int x = managedWindow->field_44; int y = managedWindow->field_48; - int flags = widgetGetTextColor() | 0x2000000; + int flags = windowGetTextColor() | 0x2000000; _windowWrapLineWithSpacing(managedWindow->window, string, width, height, x, y, flags, textAlignment, 0); return true; @@ -1077,7 +1148,7 @@ bool _windowPrintRect(char* string, int a2, int textAlignment) bool _windowFormatMessage(char* string, int x, int y, int width, int height, int textAlignment) { ManagedWindow* managedWindow = &(gManagedWindows[gCurrentManagedWindowIndex]); - int flags = widgetGetTextColor() | 0x2000000; + int flags = windowGetTextColor() | 0x2000000; _windowWrapLineWithSpacing(managedWindow->window, string, width, height, x, y, flags, textAlignment, 0); return true; @@ -1812,7 +1883,7 @@ bool _windowAddButtonTextWithOffsets(const char* buttonName, const char* text, i text, normalImageWidth, normalImageWidth, - widgetGetTextColor() + widgetGetTextFlags()); + windowGetTextColor() + windowGetTextFlags()); blitBufferToBufferTrans(buffer, normalImageWidth, @@ -1860,7 +1931,7 @@ bool _windowAddButtonTextWithOffsets(const char* buttonName, const char* text, i text, pressedImageWidth, pressedImageWidth, - widgetGetTextColor() + widgetGetTextFlags()); + windowGetTextColor() + windowGetTextFlags()); blitBufferToBufferTrans(buffer, pressedImageWidth, diff --git a/src/window.h b/src/window.h index 9f890b4..2799d6e 100644 --- a/src/window.h +++ b/src/window.h @@ -34,15 +34,15 @@ typedef enum ManagedButtonRightMouseEvent { MANAGED_BUTTON_RIGHT_MOUSE_EVENT_COUNT, } ManagedButtonRightMouseEvent; -extern int _currentHighlightColorR; -extern int gWidgetFont; -extern int _currentTextColorG; -extern int _currentTextColorB; -extern int gWidgetTextFlags; -extern int _currentTextColorR; -extern int _currentHighlightColorG; -extern int _currentHighlightColorB; - +int windowGetFont(); +int windowSetFont(int a1); +void windowResetTextAttributes(); +int windowGetTextFlags(); +int windowSetTextFlags(int a1); +unsigned char windowGetTextColor(); +unsigned char windowGetHighlightColor(); +int windowSetTextColor(float a1, float a2, float a3); +int windowSetHighlightColor(float a1, float a2, float a3); bool _checkRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent); bool _windowCheckRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent); bool _windowRefreshRegions(); diff --git a/src/window_manager.cc b/src/window_manager.cc index 5411ab1..0b7adfd 100644 --- a/src/window_manager.cc +++ b/src/window_manager.cc @@ -35,6 +35,7 @@ static Button* buttonCreateInternal(int win, int x, int y, int width, int height static int _GNW_check_buttons(Window* window, int* out_a2); static bool _button_under_mouse(Button* button, Rect* rect); static void buttonFree(Button* ptr); +static int button_new_id(); static int _win_group_check_buttons(int a1, int* a2, int a3, void (*a4)(int)); static int _button_check_group(Button* button); static void _button_draw(Button* button, Window* window, unsigned char* data, int a4, Rect* a5, int a6); @@ -1642,10 +1643,8 @@ Button* buttonCreateInternal(int win, int x, int y, int width, int height, int m } } - int buttonId = 1; - while (buttonGetButton(buttonId, NULL) != NULL) { - buttonId++; - } + // NOTE: Uninline. + int buttonId = button_new_id(); button->id = buttonId; button->flags = flags; @@ -2183,6 +2182,21 @@ void buttonFree(Button* button) internal_free(button); } +// NOTE: Inlined. +// +// 0x4D9458 +static int button_new_id() +{ + int btn; + + btn = 1; + while (buttonGetButton(btn, NULL) != NULL) { + btn++; + } + + return btn; +} + // 0x4D9474 int buttonEnable(int btn) { diff --git a/src/world_map.cc b/src/world_map.cc index b679c4e..07438ee 100644 --- a/src/world_map.cc +++ b/src/world_map.cc @@ -908,6 +908,7 @@ static int gEncounterTablesLength; static bool gTownMapHotkeysFix; static double gGameTimeIncRemainder = 0.0; +static void wmSetFlags(int* flagsPtr, int flag, int value); static int _wmGenDataInit(); static int _wmGenDataReset(); static int _wmWorldMapSaveTempData(); @@ -950,6 +951,7 @@ static int _wmMatchEntranceElevFromMap(int cityIndex, int map, int elevation, in static int _wmMatchAreaFromMap(int a1, int* out_a2); static int _wmWorldMapFunc(int a1); static int _wmInterfaceCenterOnParty(); +static void wmCheckGameEvents(); static int _wmRndEncounterOccurred(); static int _wmPartyFindCurSubTile(); static int _wmFindCurSubTileFromPos(int x, int y, SubtileInfo** subtile); @@ -967,11 +969,15 @@ static void _wmPartyInitWalking(int x, int y); static void worldmapPerformTravel(); static void _wmInterfaceScrollTabsStart(int a1); static void _wmInterfaceScrollTabsStop(); +static void wmInterfaceScrollTabsUpdate(); static int worldmapWindowInit(); static int worldmapWindowFree(); +static int wmInterfaceScroll(int dx, int dy, bool* successPtr); static int worldmapWindowScroll(int a1, int a2, int a3, int a4, bool* a5, bool a6); static void worldmapWindowHandleMouseScrolling(); -static int _wmMarkSubTileOffsetVisitedFunc(int a1, int a2, int a3, int a4, int a5, int a6); +static int wmMarkSubTileOffsetVisited(int tile, int subtileX, int subtileY, int offsetX, int offsetY); +static int wmMarkSubTileOffsetKnown(int tile, int subtileX, int subtileY, int offsetX, int offsetY); +static int wmMarkSubTileOffsetVisitedFunc(int tile, int subtileX, int subtileY, int offsetX, int offsetY, int subtileState); static void _wmMarkSubTileRadiusVisited(int x, int y); static int _wmTileGrabArt(int tile_index); static int worldmapWindowRefresh(); @@ -982,6 +988,8 @@ static void worldmapWindowDimRect(unsigned char* dest, int width, int height, in static int worldmapWindowDimSubtile(TileInfo* tileInfo, int a2, int a3, int a4, int a5, int a6); static int _wmDrawCursorStopped(); static bool _wmCursorIsVisible(); +static int wmGetAreaName(CityInfo* city, char* name); +static int wmAreaMarkVisited(int cityIndex); static void _wmMarkAllSubTiles(int a1); static int worldmapCityMapViewSelect(int* mapIndexPtr); static int worldmapCityMapViewInit(); @@ -993,7 +1001,9 @@ static void worldmapWindowRenderCarFuelBar(); static int worldmapRenderQuickDestinations(); static int _wmMakeTabsLabelList(int** out_cities, int* out_len); static int worldmapCompareCitiesByName(const void* a1, const void* a2); +static int wmFreeTabsLabelList(int** quickDestinationsListPtr, int* quickDestinationsLengthPtr); static void worldmapWindowRenderDial(bool shouldRefreshWindow); +static void wmInterfaceDialSyncTime(bool shouldRefreshWindow); static int _wmAreaFindFirstValidMap(int* out_a1); static inline bool cityIsValid(int city) @@ -1001,6 +1011,16 @@ static inline bool cityIsValid(int city) return city >= 0 && city < gCitiesLength; } +// 0x4BC890 +static void wmSetFlags(int* flagsPtr, int flag, int value) +{ + if (value) { + *flagsPtr |= flag; + } else { + *flagsPtr &= ~flag; + } +} + // wmWorldMap_init // 0x4BC89C int worldmapInit() @@ -2906,11 +2926,8 @@ int _wmMapInit() return -1; } - if (num) { - map->flags |= MAP_SAVED; - } else { - map->flags &= ~MAP_SAVED; - } + // NOTE: Uninline. + wmSetFlags(&(map->flags), MAP_SAVED, num); } if (configGetString(&config, section, "dead_bodies_age", &str)) { @@ -2918,11 +2935,8 @@ int _wmMapInit() return -1; } - if (num) { - map->flags |= MAP_DEAD_BODIES_AGE; - } else { - map->flags &= ~MAP_DEAD_BODIES_AGE; - } + // NOTE: Uninline. + wmSetFlags(&(map->flags), MAP_DEAD_BODIES_AGE, num); } if (configGetString(&config, section, "can_rest_here", &str)) { @@ -2930,31 +2944,22 @@ int _wmMapInit() return -1; } - if (num) { - map->flags |= MAP_CAN_REST_ELEVATION_0; - } else { - map->flags &= ~MAP_CAN_REST_ELEVATION_0; - } + // NOTE: Uninline. + wmSetFlags(&(map->flags), MAP_CAN_REST_ELEVATION_0, num); if (strParseStrFromList(&str, &num, _wmYesNoStrs, 2) == -1) { return -1; } - if (num) { - map->flags |= MAP_CAN_REST_ELEVATION_1; - } else { - map->flags &= ~MAP_CAN_REST_ELEVATION_1; - } + // NOTE: Uninline. + wmSetFlags(&(map->flags), MAP_CAN_REST_ELEVATION_1, num); if (strParseStrFromList(&str, &num, _wmYesNoStrs, 2) == -1) { return -1; } - if (num) { - map->flags |= MAP_CAN_REST_ELEVATION_2; - } else { - map->flags &= ~MAP_CAN_REST_ELEVATION_2; - } + // NOTE: Uninline. + wmSetFlags(&(map->flags), MAP_CAN_REST_ELEVATION_2, num); } if (configGetString(&config, section, "pipboy_active", &str)) { @@ -2962,11 +2967,8 @@ int _wmMapInit() return -1; } - if (num) { - map->flags |= MAP_PIPBOY_ACTIVE; - } else { - map->flags &= ~MAP_PIPBOY_ACTIVE; - } + // NOTE: Uninline. + wmSetFlags(&(map->flags), MAP_PIPBOY_ACTIVE, num); } // SFALL: Pip-boy automaps patch. @@ -3129,7 +3131,8 @@ int _wmMapMarkVisited(int mapIndex) return -1; } - _wmAreaMarkVisitedState(cityIndex, 2); + // NOTE: Uninline. + wmAreaMarkVisited(cityIndex); return 0; } @@ -3257,7 +3260,8 @@ int _wmWorldMapFunc(int a1) showQuitConfirmationDialog(); } - _scriptsCheckGameEvents(NULL, gWorldmapWindow); + // NOTE: Uninline. + wmCheckGameEvents(); if (_game_user_wants_to_quit != 0) { break; @@ -3420,20 +3424,8 @@ int _wmWorldMapFunc(int a1) } } - if (_tabsOffset) { - _LastTabsYOffset += _tabsOffset; - worldmapWindowRenderChrome(true); - - if (_tabsOffset > -1) { - if (dword_672F54 <= _LastTabsYOffset) { - _wmInterfaceScrollTabsStop(); - } - } else { - if (dword_672F54 >= _LastTabsYOffset) { - _wmInterfaceScrollTabsStop(); - } - } - } + // NOTE: Uninline. + wmInterfaceScrollTabsUpdate(); if (keyCode == KEY_UPPERCASE_T || keyCode == KEY_LOWERCASE_T) { if (!gWorldmapIsTravelling && _WorldMapCurrArea != -1) { @@ -3455,13 +3447,17 @@ int _wmWorldMapFunc(int a1) } else if (keyCode == KEY_HOME) { _wmInterfaceCenterOnParty(); } else if (keyCode == KEY_ARROW_UP) { - worldmapWindowScroll(20, 20, 0, -1, 0, 1); + // NOTE: Uninline. + wmInterfaceScroll(0, -1, NULL); } else if (keyCode == KEY_ARROW_LEFT) { - worldmapWindowScroll(20, 20, -1, 0, 0, 1); + // NOTE: Uninline. + wmInterfaceScroll(-1, 0, NULL); } else if (keyCode == KEY_ARROW_DOWN) { - worldmapWindowScroll(20, 20, 0, 1, 0, 1); + // NOTE: Uninline. + wmInterfaceScroll(0, 1, NULL); } else if (keyCode == KEY_ARROW_RIGHT) { - worldmapWindowScroll(20, 20, 1, 0, 0, 1); + // NOTE: Uninline. + wmInterfaceScroll(1, 0, NULL); } else if (keyCode == KEY_CTRL_ARROW_UP) { _wmInterfaceScrollTabsStart(-27); } else if (keyCode == KEY_CTRL_ARROW_DOWN) { @@ -3564,6 +3560,14 @@ int _wmInterfaceCenterOnParty() return 0; } +// NOTE: Inlined. +// +// 0x4C0624 +static void wmCheckGameEvents() +{ + _scriptsCheckGameEvents(NULL, gWorldmapWindow); +} + // 0x4C0634 int _wmRndEncounterOccurred() { @@ -4442,14 +4446,8 @@ bool _wmGameTimeIncrement(int ticksToAdd) gameTimeAddTicks(v1); - int hour = gameTimeGetHour() / 100; - - int frameCount = artGetFrameCount(gWorldmapDialFrm); - int frame = (hour + 12) % frameCount; - if (gWorldmapDialFrmCurrentFrame != frame) { - gWorldmapDialFrmCurrentFrame = frame; - worldmapWindowRenderDial(true); - } + // NOTE: Uninline. + wmInterfaceDialSyncTime(true); worldmapWindowRenderDate(true); @@ -4672,23 +4670,8 @@ void _wmInterfaceScrollTabsStart(int a1) L11: - if (!_tabsOffset) { - return; - } - - _LastTabsYOffset += _tabsOffset; - - worldmapWindowRenderChrome(true); - - if (_tabsOffset > -1) { - if (dword_672F54 > _LastTabsYOffset) { - return; - } - } else if (dword_672F54 < _LastTabsYOffset) { - return; - } - - _wmInterfaceScrollTabsStop(); + // NOTE: Uninline. + wmInterfaceScrollTabsUpdate(); } // 0x4C2270 @@ -4703,6 +4686,29 @@ void _wmInterfaceScrollTabsStop() } } +// NOTE: Inlined. +// +// 0x4C2290 +static void wmInterfaceScrollTabsUpdate() +{ + if (_tabsOffset != 0) { + _LastTabsYOffset += _tabsOffset; + worldmapWindowRenderChrome(1); + + if (_tabsOffset >= 0) { + if (dword_672F54 <= _LastTabsYOffset) { + // NOTE: Uninline. + _wmInterfaceScrollTabsStop(); + } + } else { + if (dword_672F54 >= _LastTabsYOffset) { + // NOTE: Uninline. + _wmInterfaceScrollTabsStop(); + } + } + } +} + // 0x4C2324 int worldmapWindowInit() { @@ -5265,12 +5271,8 @@ int worldmapWindowFree() fontSetCurrent(_fontnum); - if (gQuickDestinations != NULL) { - internal_free(gQuickDestinations); - gQuickDestinations = NULL; - } - - gQuickDestinationsLength = 0; + // NOTE: Uninline. + wmFreeTabsLabelList(&gQuickDestinations, &gQuickDestinationsLength); _wmInterfaceWasInitialized = 0; @@ -5279,6 +5281,14 @@ int worldmapWindowFree() return 0; } +// NOTE: Inlined. +// +// 0x4C31E8 +static int wmInterfaceScroll(int dx, int dy, bool* successPtr) +{ + return worldmapWindowScroll(20, 20, dx, dy, successPtr, 1); +} + // FIXME: There is small bug in this function. There is [success] flag returned // by reference so that calling code can update scrolling mouse cursor to invalid // range. It works OK on straight directions. But in diagonals when scrolling in @@ -5407,7 +5417,8 @@ void worldmapWindowHandleMouseScrolling() unsigned int tick = _get_bk_time(); if (getTicksBetween(tick, _lastTime_2) > 50) { _lastTime_2 = _get_bk_time(); - worldmapWindowScroll(20, 20, dx, dy, &_couldScroll, true); + // NOTE: Uninline. + wmInterfaceScroll(dx, dy, &_couldScroll); } if (!_couldScroll) { @@ -5424,59 +5435,75 @@ void worldmapWindowHandleMouseScrolling() } } -// 0x4C3434 -int _wmMarkSubTileOffsetVisitedFunc(int a1, int a2, int a3, int a4, int a5, int a6) +// NOTE: Inlined. +// +// 0x4C340C +static int wmMarkSubTileOffsetVisited(int tile, int subtileX, int subtileY, int offsetX, int offsetY) { - int v7; - int v8; - int v9; - int* v; + return wmMarkSubTileOffsetVisitedFunc(tile, subtileX, subtileY, offsetX, offsetY, SUBTILE_STATE_VISITED); +} - v7 = a2 + a4; - v8 = a1; - v9 = a3 + a5; +// NOTE: Inlined. +// +// 0x4C3420 +static int wmMarkSubTileOffsetKnown(int tile, int subtileX, int subtileY, int offsetX, int offsetY) +{ + return wmMarkSubTileOffsetVisitedFunc(tile, subtileX, subtileY, offsetX, offsetY, SUBTILE_STATE_KNOWN); +} - if (v7 >= 0) { - if (v7 >= 7) { - if (a1 % gWorldmapGridWidth == gWorldmapGridWidth - 1) { +// 0x4C3434 +static int wmMarkSubTileOffsetVisitedFunc(int tile, int subtileX, int subtileY, int offsetX, int offsetY, int subtileState) +{ + int actualTile; + int actualSubtileX; + int actualSubtileY; + TileInfo* tileInfo; + SubtileInfo* subtileInfo; + + actualSubtileX = subtileX + offsetX; + actualTile = tile; + actualSubtileY = subtileY + offsetY; + + if (actualSubtileX >= 0) { + if (actualSubtileX >= SUBTILE_GRID_WIDTH) { + if (tile % gWorldmapGridWidth == gWorldmapGridWidth - 1) { return -1; } - v8 = a1 + 1; - v7 %= 7; + actualTile = tile + 1; + actualSubtileX %= SUBTILE_GRID_WIDTH; } } else { - if (!(a1 % gWorldmapGridWidth)) { + if (!(tile % gWorldmapGridWidth)) { return -1; } - v7 += 7; - v8 = a1 - 1; + actualSubtileX += SUBTILE_GRID_WIDTH; + actualTile = tile - 1; } - if (v9 >= 0) { - if (v9 >= 6) { - if (v8 > gWorldmapTilesLength - gWorldmapGridWidth - 1) { + if (actualSubtileY >= 0) { + if (actualSubtileY >= SUBTILE_GRID_HEIGHT) { + if (actualTile > gWorldmapTilesLength - gWorldmapGridWidth - 1) { return -1; } - v8 += gWorldmapGridWidth; - v9 %= 6; + actualTile += gWorldmapGridWidth; + actualSubtileY %= SUBTILE_GRID_HEIGHT; } } else { - if (v8 < gWorldmapGridWidth) { + if (actualTile < gWorldmapGridWidth) { return -1; } - v9 += 6; - v8 -= gWorldmapGridWidth; + actualSubtileY += SUBTILE_GRID_HEIGHT; + actualTile -= gWorldmapGridWidth; } - TileInfo* tile = &(gWorldmapTiles[v8]); - SubtileInfo* subtile = &(tile->subtiles[v9][v7]); - v = &(subtile->state); - if (a6 != 1 || *v == 0) { - *v = a6; + tileInfo = &(gWorldmapTiles[actualTile]); + subtileInfo = &(tileInfo->subtiles[actualSubtileY][actualSubtileX]); + if (subtileState != SUBTILE_STATE_KNOWN || subtileInfo->state == SUBTILE_STATE_UNKNOWN) { + subtileInfo->state = subtileState; } return 0; @@ -5491,43 +5518,50 @@ void _wmMarkSubTileRadiusVisited(int x, int y) radius = 2; } - _wmSubTileMarkRadiusVisited(x, y, radius); + wmSubTileMarkRadiusVisited(x, y, radius); } -// Mark worldmap tile as visible?/visited? -// // 0x4C35A8 -int _wmSubTileMarkRadiusVisited(int x, int y, int radius) +int wmSubTileMarkRadiusVisited(int x, int y, int radius) { - int v4, v5; + int tile; + int subtileX; + int subtileY; + int offsetX; + int offsetY; + SubtileInfo* subtile; - int tile = x / WM_TILE_WIDTH % gWorldmapGridWidth + y / WM_TILE_HEIGHT * gWorldmapGridWidth; - v4 = x % WM_TILE_WIDTH / WM_SUBTILE_SIZE; - v5 = y % WM_TILE_HEIGHT / WM_SUBTILE_SIZE; + tile = x / WM_TILE_WIDTH % gWorldmapGridWidth + y / WM_TILE_HEIGHT * gWorldmapGridWidth; + subtileX = x % WM_TILE_WIDTH / WM_SUBTILE_SIZE; + subtileY = y % WM_TILE_HEIGHT / WM_SUBTILE_SIZE; - for (int i = -radius; i <= radius; i++) { - for (int v6 = -radius; v6 <= radius; v6++) { - _wmMarkSubTileOffsetVisitedFunc(tile, v4, v5, v6, i, SUBTILE_STATE_KNOWN); + for (offsetY = -radius; offsetY <= radius; offsetY++) { + for (offsetX = -radius; offsetX <= radius; offsetX++) { + // NOTE: Uninline. + wmMarkSubTileOffsetKnown(tile, subtileX, subtileY, offsetX, offsetY); } } - SubtileInfo* subtile = &(gWorldmapTiles[tile].subtiles[v5][v4]); + subtile = &(gWorldmapTiles[tile].subtiles[subtileY][subtileX]); subtile->state = SUBTILE_STATE_VISITED; switch (subtile->field_4) { case 2: - while (v5-- > 0) { - _wmMarkSubTileOffsetVisitedFunc(tile, v4, 0, v5, 0, SUBTILE_STATE_VISITED); + while (subtileY-- > 0) { + // NOTE: Uninline. + wmMarkSubTileOffsetVisited(tile, subtileX, subtileY, 0, 0); } break; case 4: - while (v4-- > -1) { - _wmMarkSubTileOffsetVisitedFunc(tile, v4, 0, v5, 0, SUBTILE_STATE_VISITED); + while (subtileX-- >= 0) { + // NOTE: Uninline. + wmMarkSubTileOffsetVisited(tile, subtileX, subtileY, 0, 0); } if (tile % gWorldmapGridWidth > 0) { - for (int i = 0; i < 7; i++) { - _wmMarkSubTileOffsetVisitedFunc(tile - 1, i + 1, v5, 0, 0, SUBTILE_STATE_VISITED); + for (subtileX = 0; subtileX < SUBTILE_GRID_WIDTH; subtileX++) { + // NOTE: Uninline. + wmMarkSubTileOffsetVisited(tile - 1, subtileX, subtileY, 0, 0); } } break; @@ -5818,18 +5852,20 @@ int worldmapWindowRenderCity(CityInfo* city, CitySizeDescription* citySizeDescri int maxY = 464 - fontGetLineHeight(); if (nameY < maxY) { MessageListItem messageListItem; - const char* name; + char name[40]; if (_wmAreaIsKnown(city->field_28)) { - name = getmsg(&gMapMessageList, &messageListItem, 1500 + city->field_28); + // NOTE: Uninline. + wmGetAreaName(city, name); } else { - name = getmsg(&gWorldmapMessageList, &messageListItem, 1004); + strncpy(name, getmsg(&gWorldmapMessageList, &messageListItem, 1004), 40); } - char text[40]; - strncpy(text, name, 40); - - int width = fontGetStringWidth(text); - fontDrawText(dest + WM_WINDOW_WIDTH * nameY + x + citySizeDescription->width / 2 - width / 2, text, width, WM_WINDOW_WIDTH, _colorTable[992]); + int width = fontGetStringWidth(name); + fontDrawText(dest + WM_WINDOW_WIDTH * nameY + x + citySizeDescription->width / 2 - width / 2, + name, + width, + WM_WINDOW_WIDTH, + _colorTable[992]); } return 0; @@ -5957,6 +5993,19 @@ bool _wmCursorIsVisible() && _world_ypos < gWorldmapOffsetY + WM_VIEW_HEIGHT; } +// NOTE: Inlined. +// +// 0x4C44D8 +static int wmGetAreaName(CityInfo* city, char* name) +{ + MessageListItem messageListItem; + + getmsg(&gMapMessageList, &messageListItem, city->field_28 + 1500); + strncpy(name, messageListItem.text, 40); + + return 0; +} + // Copy city short name. // // 0x4C450C @@ -6027,6 +6076,12 @@ bool _wmMapIsKnown(int mapIndex) return true; } +// 0x4C4624 +static int wmAreaMarkVisited(int cityIndex) +{ + return _wmAreaMarkVisitedState(cityIndex, CITY_STATE_VISITED); +} + // 0x4C4634 bool _wmAreaMarkVisitedState(int cityIndex, int a2) { @@ -6569,15 +6624,8 @@ int worldmapWindowRenderChrome(bool shouldRefreshWindow) worldmapRenderQuickDestinations(); - int v1 = gameTimeGetHour(); - v1 /= 100; - - int frameCount = artGetFrameCount(gWorldmapDialFrm); - int newFrame = (v1 + 12) % frameCount; - if (gWorldmapDialFrmCurrentFrame != newFrame) { - gWorldmapDialFrmCurrentFrame = newFrame; - worldmapWindowRenderDial(false); - } + // NOTE: Uninline. + wmInterfaceDialSyncTime(false); worldmapWindowRenderDial(false); @@ -6761,13 +6809,8 @@ int _wmMakeTabsLabelList(int** quickDestinationsPtr, int* quickDestinationsLengt { int* quickDestinations = *quickDestinationsPtr; - if (quickDestinations != NULL) { - internal_free(quickDestinations); - quickDestinations = NULL; - } - - *quickDestinationsPtr = NULL; - *quickDestinationsLengthPtr = 0; + // NOTE: Uninline. + wmFreeTabsLabelList(quickDestinationsPtr, quickDestinationsLengthPtr); int capacity = 10; @@ -6816,6 +6859,21 @@ int worldmapCompareCitiesByName(const void* a1, const void* a2) return compat_stricmp(city1->name, city2->name); } +// NOTE: Inlined. +// +// 0x4C5710 +static int wmFreeTabsLabelList(int** quickDestinationsListPtr, int* quickDestinationsLengthPtr) +{ + if (*quickDestinationsListPtr != NULL) { + internal_free(*quickDestinationsListPtr); + *quickDestinationsListPtr = NULL; + } + + *quickDestinationsLengthPtr = 0; + + return 0; +} + // 0x4C5734 void worldmapWindowRenderDial(bool shouldRefreshWindow) { @@ -6837,6 +6895,22 @@ void worldmapWindowRenderDial(bool shouldRefreshWindow) } } +// NOTE: Inlined. +// +// 0x4C57BC +static void wmInterfaceDialSyncTime(bool shouldRefreshWindow) +{ + int gameHour; + int frame; + + gameHour = gameTimeGetHour(); + frame = (gameHour / 100 + 12) % artGetFrameCount(gWorldmapDialFrm); + if (frame != gWorldmapDialFrmCurrentFrame) { + gWorldmapDialFrmCurrentFrame = frame; + worldmapWindowRenderDial(shouldRefreshWindow); + } +} + // 0x4C5804 int _wmAreaFindFirstValidMap(int* out_a1) { diff --git a/src/world_map.h b/src/world_map.h index 4922aa7..dcb9fbf 100644 --- a/src/world_map.h +++ b/src/world_map.h @@ -246,7 +246,7 @@ void _wmWorldMap(); int _wmCheckGameAreaEvents(); int worldmapSetupRandomEncounter(); bool _wmEvalTileNumForPlacement(int tile); -int _wmSubTileMarkRadiusVisited(int x, int y, int radius); +int wmSubTileMarkRadiusVisited(int x, int y, int radius); int _wmSubTileGetVisitedState(int a1, int a2, int* a3); int _wmGetAreaIdxName(int index, char* name); bool _wmAreaIsKnown(int city_index);