Reconcile with reference edition

This commit is contained in:
Alexander Batalov 2022-09-01 18:41:37 +03:00
parent 039ad65557
commit 629978d7a6
33 changed files with 1641 additions and 856 deletions

View File

@ -81,6 +81,7 @@ static int _action_melee(Attack* attack, int a2);
static int _action_ranged(Attack* attack, int a2); static int _action_ranged(Attack* attack, int a2);
static int _is_next_to(Object* a1, Object* a2); static int _is_next_to(Object* a1, Object* a2);
static int _action_climb_ladder(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 _pick_fall(Object* obj, int anim);
static int _report_explosion(Attack* attack, Object* a2); static int _report_explosion(Attack* attack, Object* a2);
static int _finished_explosion(Object* a1, Object* a2); static int _finished_explosion(Object* a1, Object* a2);
@ -1289,23 +1290,33 @@ int _action_skill_use(int skill)
return -1; 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 // skill_use
// 0x41255C // 0x41255C
int actionUseSkill(Object* a1, Object* a2, int skill) int actionUseSkill(Object* a1, Object* a2, int skill)
{ {
MessageListItem messageListItem;
switch (skill) { switch (skill) {
case SKILL_FIRST_AID: case SKILL_FIRST_AID:
case SKILL_DOCTOR: case SKILL_DOCTOR:
if (isInCombat()) { if (isInCombat()) {
if (a1 == gDude) { // NOTE: Uninline.
messageListItem.num = 902; return _action_use_skill_in_combat_error(a1);
if (messageListGetItem(&gProtoMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);
}
}
return -1;
} }
if (PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) { if (PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) {
@ -1314,13 +1325,8 @@ int actionUseSkill(Object* a1, Object* a2, int skill)
break; break;
case SKILL_LOCKPICK: case SKILL_LOCKPICK:
if (isInCombat()) { if (isInCombat()) {
if (a1 == gDude) { // NOTE: Uninline.
messageListItem.num = 902; return _action_use_skill_in_combat_error(a1);
if (messageListGetItem(&gProtoMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);
}
}
return -1;
} }
if (PID_TYPE(a2->pid) != OBJ_TYPE_ITEM && PID_TYPE(a2->pid) != OBJ_TYPE_SCENERY) { 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; break;
case SKILL_STEAL: case SKILL_STEAL:
if (isInCombat()) { if (isInCombat()) {
if (a1 == gDude) { // NOTE: Uninline.
messageListItem.num = 902; return _action_use_skill_in_combat_error(a1);
if (messageListGetItem(&gProtoMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);
}
}
return -1;
} }
if (PID_TYPE(a2->pid) != OBJ_TYPE_ITEM && PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) { 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; break;
case SKILL_TRAPS: case SKILL_TRAPS:
if (isInCombat()) { if (isInCombat()) {
if (a1 == gDude) { // NOTE: Uninline.
messageListItem.num = 902; return _action_use_skill_in_combat_error(a1);
if (messageListGetItem(&gProtoMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);
}
}
return -1;
} }
if (PID_TYPE(a2->pid) == OBJ_TYPE_CRITTER) { 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_SCIENCE:
case SKILL_REPAIR: case SKILL_REPAIR:
if (isInCombat()) { if (isInCombat()) {
if (a1 == gDude) { // NOTE: Uninline.
messageListItem.num = 902; return _action_use_skill_in_combat_error(a1);
if (messageListGetItem(&gProtoMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text);
}
}
return -1;
} }
if (PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) { if (PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) {

View File

@ -57,8 +57,8 @@ typedef enum AnimationKind {
ANIM_KIND_SET_FID = 17, ANIM_KIND_SET_FID = 17,
ANIM_KIND_TAKE_OUT_WEAPON = 18, ANIM_KIND_TAKE_OUT_WEAPON = 18,
ANIM_KIND_SET_LIGHT_DISTANCE = 19, ANIM_KIND_SET_LIGHT_DISTANCE = 19,
ANIM_KIND_20 = 20, ANIM_KIND_MOVE_ON_STAIRS = 20,
ANIM_KIND_23 = 23, ANIM_KIND_CHECK_FALLING = 23,
ANIM_KIND_TOGGLE_OUTLINE = 24, ANIM_KIND_TOGGLE_OUTLINE = 24,
ANIM_KIND_ANIMATE_FOREVER = 25, ANIM_KIND_ANIMATE_FOREVER = 25,
ANIM_KIND_26 = 26, ANIM_KIND_26 = 26,
@ -254,6 +254,7 @@ typedef struct AnimationSad {
} AnimationSad; } AnimationSad;
static int _anim_free_slot(int a1); static int _anim_free_slot(int a1);
static int _anim_preload(Object* object, int fid, CacheEntry** cacheEntryPtr);
static void _anim_cleanup(); static void _anim_cleanup();
static int _check_registry(Object* obj); static int _check_registry(Object* obj);
static int animationRunSequence(int a1); 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 int _anim_animate(Object* obj, int anim, int animationSequenceIndex, int flags);
static void _object_anim_compact(); static void _object_anim_compact();
static int actionRotate(Object* obj, int delta, int animationSequenceIndex); 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 _anim_change_fid(Object* obj, int animationSequenceIndex, int fid);
static int _check_gravity(int tile, int elevation); static int _check_gravity(int tile, int elevation);
static unsigned int animationComputeTicksPerFrame(Object* object, int fid); static unsigned int animationComputeTicksPerFrame(Object* object, int fid);
@ -501,6 +503,22 @@ int reg_anim_end()
return 0; 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 // 0x413D98
static void _anim_cleanup() 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); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return animationRegisterRotateToTile(owner, destination->tile); 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); int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1);
animationDescription->artCacheKey = NULL; // NOTE: Uninline.
if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) {
_anim_cleanup(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return animationRegisterRotateToTile(owner, destination->tile); return animationRegisterRotateToTile(owner, destination->tile);
} }
@ -713,17 +726,15 @@ int animationRegisterMoveToTile(Object* owner, int tile, int elevation, int acti
animationDescription->elevation = elevation; animationDescription->elevation = elevation;
animationDescription->actionPoints = actionPoints; animationDescription->actionPoints = actionPoints;
animationDescription->delay = delay; 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); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; 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); int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1);
animationDescription->artCacheKey = NULL; // NOTE: Uninline.
if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) {
_anim_cleanup(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -816,17 +824,15 @@ int animationRegisterMoveToTileStraight(Object* object, int tile, int elevation,
animationDescription->elevation = elevation; animationDescription->elevation = elevation;
animationDescription->anim = anim; animationDescription->anim = anim;
animationDescription->delay = delay; 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); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -852,17 +858,15 @@ int animationRegisterMoveToTileStraightAndWaitForComplete(Object* owner, int til
animationDescription->elevation = elevation; animationDescription->elevation = elevation;
animationDescription->anim = anim; animationDescription->anim = anim;
animationDescription->delay = delay; 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); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -882,17 +886,15 @@ int animationRegisterAnimate(Object* owner, int anim, int delay)
animationDescription->owner = owner; animationDescription->owner = owner;
animationDescription->anim = anim; animationDescription->anim = anim;
animationDescription->delay = delay; 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); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -915,14 +917,13 @@ int animationRegisterAnimateReversed(Object* owner, int anim, int delay)
animationDescription->artCacheKey = NULL; animationDescription->artCacheKey = NULL;
int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, animationDescription->anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -945,14 +946,13 @@ int animationRegisterAnimateAndHide(Object* owner, int anim, int delay)
animationDescription->artCacheKey = NULL; animationDescription->artCacheKey = NULL;
int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -1199,16 +1199,13 @@ int animationRegisterSetFid(Object* owner, int fid, int delay)
animationDescription->owner = owner; animationDescription->owner = owner;
animationDescription->fid = fid; animationDescription->fid = fid;
animationDescription->delay = delay; animationDescription->delay = delay;
animationDescription->artCacheKey = NULL;
if (artLock(fid, &(animationDescription->artCacheKey)) == NULL) { // NOTE: Uninline.
if (_anim_preload(owner, fid, &(animationDescription->artCacheKey)) == -1) {
_anim_cleanup(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -1236,14 +1233,13 @@ int animationRegisterTakeOutWeapon(Object* owner, int weaponAnimationCode, int d
animationDescription->weaponAnimationCode = weaponAnimationCode; animationDescription->weaponAnimationCode = weaponAnimationCode;
int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, ANIM_TAKE_OUT, weaponAnimationCode, owner->rotation + 1); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -1339,17 +1335,15 @@ int animationRegisterAnimateForever(Object* owner, int anim, int delay)
animationDescription->owner = owner; animationDescription->owner = owner;
animationDescription->anim = anim; animationDescription->anim = anim;
animationDescription->delay = delay; animationDescription->delay = delay;
animationDescription->artCacheKey = NULL;
int fid = buildFid(FID_TYPE(owner->fid), owner->fid & 0xFFF, anim, (owner->fid & 0xF000) >> 12, owner->rotation + 1); 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(); _anim_cleanup();
return -1; return -1;
} }
artUnlock(animationDescription->artCacheKey);
animationDescription->artCacheKey = NULL;
gAnimationDescriptionCurrentIndex++; gAnimationDescriptionCurrentIndex++;
return 0; return 0;
@ -1438,15 +1432,8 @@ static int animationRunSequence(int animationSequenceIndex)
case ANIM_KIND_ANIMATE_AND_HIDE: case ANIM_KIND_ANIMATE_AND_HIDE:
rc = _anim_animate(animationDescription->owner, animationDescription->anim, animationSequenceIndex, ANIM_SAD_HIDE_ON_END); rc = _anim_animate(animationDescription->owner, animationDescription->anim, animationSequenceIndex, ANIM_SAD_HIDE_ON_END);
if (rc == -1) { if (rc == -1) {
Rect rect; // NOTE: Uninline.
if (objectHide(animationDescription->owner, &rect) == 0) { rc = _anim_hide(animationDescription->owner, animationSequenceIndex);
tileWindowRefreshRect(&rect, animationDescription->elevation);
}
if (animationSequenceIndex != -1) {
_anim_set_continue(animationSequenceIndex, 0);
}
rc = 0;
} }
break; break;
case ANIM_KIND_ANIMATE_FOREVER: case ANIM_KIND_ANIMATE_FOREVER:
@ -1467,13 +1454,8 @@ static int animationRunSequence(int animationSequenceIndex)
rc = actionRotate(animationDescription->owner, -1, animationSequenceIndex); rc = actionRotate(animationDescription->owner, -1, animationSequenceIndex);
break; break;
case ANIM_KIND_HIDE: case ANIM_KIND_HIDE:
if (objectHide(animationDescription->owner, &rect) == 0) { // NOTE: Uninline.
tileWindowRefreshRect(&rect, animationDescription->owner->elevation); rc = _anim_hide(animationDescription->owner, animationSequenceIndex);
}
if (animationSequenceIndex != -1) {
_anim_set_continue(animationSequenceIndex, 0);
}
rc = 0;
break; break;
case ANIM_KIND_CALLBACK: case ANIM_KIND_CALLBACK:
rc = animationDescription->callback(animationDescription->param1, animationDescription->param2); rc = animationDescription->callback(animationDescription->param1, animationDescription->param2);
@ -1539,10 +1521,10 @@ static int animationRunSequence(int animationSequenceIndex)
tileWindowRefreshRect(&rect, animationDescription->owner->elevation); tileWindowRefreshRect(&rect, animationDescription->owner->elevation);
rc = _anim_set_continue(animationSequenceIndex, 0); rc = _anim_set_continue(animationSequenceIndex, 0);
break; 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); rc = _anim_move_on_stairs(animationDescription->owner, animationDescription->tile, animationDescription->elevation, animationDescription->anim, animationSequenceIndex);
break; break;
case ANIM_KIND_23: case ANIM_KIND_CHECK_FALLING:
rc = _check_for_falling(animationDescription->owner, animationDescription->anim, animationSequenceIndex); rc = _check_for_falling(animationDescription->owner, animationDescription->anim, animationSequenceIndex);
break; break;
case ANIM_KIND_TOGGLE_OUTLINE: case ANIM_KIND_TOGGLE_OUTLINE:
@ -2849,9 +2831,8 @@ void _object_animate()
artUnlock(cacheHandle); artUnlock(cacheHandle);
if ((sad->flags & ANIM_SAD_HIDE_ON_END) != 0) { if ((sad->flags & ANIM_SAD_HIDE_ON_END) != 0) {
if (objectHide(object, &tempRect) == 0) { // NOTE: Uninline.
tileWindowRefreshRect(&tempRect, object->elevation); _anim_hide(object, -1);
}
} }
_anim_set_continue(sad->animationSequenceIndex, 1); _anim_set_continue(sad->animationSequenceIndex, 1);
@ -3262,6 +3243,24 @@ static int actionRotate(Object* obj, int delta, int animationSequenceIndex)
return 0; 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 // 0x418660
static int _anim_change_fid(Object* obj, int animationSequenceIndex, int fid) static int _anim_change_fid(Object* obj, int animationSequenceIndex, int fid)
{ {

View File

@ -2917,7 +2917,7 @@ static void characterEditorDrawSkills(int a1)
int color; int color;
int y; int y;
int value; int value;
char valueString[12]; // TODO: Size might be wrong. char valueString[32];
if (characterEditorSelectedItem >= EDITOR_FIRST_SKILL && characterEditorSelectedItem < 79) { if (characterEditorSelectedItem >= EDITOR_FIRST_SKILL && characterEditorSelectedItem < 79) {
selectedSkill = characterEditorSelectedItem - EDITOR_FIRST_SKILL; selectedSkill = characterEditorSelectedItem - EDITOR_FIRST_SKILL;
@ -2950,7 +2950,6 @@ static void characterEditorDrawSkills(int a1)
str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 138); str = getmsg(&gCharacterEditorMessageList, &gCharacterEditorMessageListItem, 138);
fontDrawText(gCharacterEditorWindowBuffer + 640 * 233 + 422, str, 640, 640, _colorTable[18979]); fontDrawText(gCharacterEditorWindowBuffer + 640 * 233 + 422, str, 640, 640, _colorTable[18979]);
// TODO: Check.
if (a1 == 2 && !gCharacterEditorIsSkillsFirstDraw) { if (a1 == 2 && !gCharacterEditorIsSkillsFirstDraw) {
characterEditorDrawBigNumber(522, 228, ANIMATE, gCharacterEditorTaggedSkillCount, gCharacterEditorOldTaggedSkillCount, gCharacterEditorWindow); characterEditorDrawBigNumber(522, 228, ANIMATE, gCharacterEditorTaggedSkillCount, gCharacterEditorOldTaggedSkillCount, gCharacterEditorWindow);
} else { } else {
@ -2985,7 +2984,6 @@ static void characterEditorDrawSkills(int a1)
value = skillGetValue(gDude, i); value = skillGetValue(gDude, i);
sprintf(valueString, "%d%%", value); sprintf(valueString, "%d%%", value);
// TODO: Check text position.
fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 573, valueString, 640, 640, color); fontDrawText(gCharacterEditorWindowBuffer + 640 * y + 573, valueString, 640, 640, color);
y += fontGetLineHeight() + 1; y += fontGetLineHeight() + 1;

View File

@ -86,9 +86,12 @@ typedef struct DamageCalculationContext {
} DamageCalculationContext; } DamageCalculationContext;
static bool _combat_safety_invalidate_weapon_func(Object* critter, Object* weapon, int hitMode, Object* a4, int* a5, Object* a6); 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 aiInfoCopy(int srcIndex, int destIndex);
static int _combatAIInfoSetLastMove(Object* object, int move);
static void _combat_begin(Object* a1); static void _combat_begin(Object* a1);
static void _combat_begin_extra(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_over();
static void _combat_add_noncoms(); static void _combat_add_noncoms();
static int _compare_faster(const void* a1, const void* a2); 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 attackComputeCriticalHit(Attack* a1);
static int _attackFindInvalidFlags(Object* a1, Object* a2); static int _attackFindInvalidFlags(Object* a1, Object* a2);
static int attackComputeCriticalFailure(Attack* attack); 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 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 attackComputeDamage(Attack* attack, int ammoQuantity, int a3);
static void _check_for_death(Object* a1, int a2, 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; 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 // 0x421850
static int aiInfoCopy(int srcIndex, int destIndex) static int aiInfoCopy(int srcIndex, int destIndex)
{ {
@ -2521,6 +2540,28 @@ int aiInfoSetLastItem(Object* obj, Object* a2)
return 0; 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 // 0x421A34
static void _combat_begin(Object* a1) static void _combat_begin(Object* a1)
{ {
@ -2541,13 +2582,8 @@ static void _combat_begin(Object* a1)
return; return;
} }
for (int index = 0; index < _list_total; index++) { // NOTE: Uninline.
CombatAiInfo* aiInfo = &(_aiInfoList[index]); _combatInitAIInfoList();
aiInfo->friendlyDead = NULL;
aiInfo->lastTarget = NULL;
aiInfo->lastItem = NULL;
aiInfo->lastMove = 0;
}
Object* v1 = NULL; Object* v1 = NULL;
for (int index = 0; index < _list_total; index++) { for (int index = 0; index < _list_total; index++) {
@ -2559,10 +2595,8 @@ static void _combat_begin(Object* a1)
combatData->ap = 0; combatData->ap = 0;
critter->cid = index; critter->cid = index;
// NOTE: Not sure about this code, field_C is already reset. // NOTE: Uninline.
if (isInCombat() && critter != NULL && index != -1) { _combatAIInfoSetLastMove(critter, 0);
_aiInfoList[index].lastMove = 0;
}
scriptSetObjects(critter->sid, NULL, NULL); scriptSetObjects(critter->sid, NULL, NULL);
scriptSetFixedParam(critter->sid, 0); 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); 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. // Something with outlining.
// //
// 0x421D50 // 0x421D50
@ -3149,11 +3195,8 @@ static void _combat_set_move_all()
object->data.critter.combat.ap = actionPoints; object->data.critter.combat.ap = actionPoints;
if (isInCombat()) { // NOTE: Uninline.
if (object->cid != -1) { _combatAIInfoSetLastMove(object, 0);
_aiInfoList[object->cid].lastMove = 0;
}
}
} }
} }
@ -3211,9 +3254,8 @@ static int _combat_turn(Object* a1, bool a2)
interfaceBarEndButtonsRenderGreenLights(); interfaceBarEndButtonsRenderGreenLights();
for (int index = 0; index < _list_total; index++) { // NOTE: Uninline.
_combat_update_critter_outline_for_los(_combat_list[index], false); _combat_update_critters_in_los(false);
}
if (_combat_highlight != 0) { if (_combat_highlight != 0) {
_combat_outline_on(); _combat_outline_on();
@ -4075,22 +4117,8 @@ static int attackComputeCriticalHit(Attack* attack)
} }
if ((attack->defenderFlags & DAM_CRIP_RANDOM) != 0) { if ((attack->defenderFlags & DAM_CRIP_RANDOM) != 0) {
attack->defenderFlags &= ~DAM_CRIP_RANDOM; // NOTE: Uninline.
_do_random_cripple(&(attack->defenderFlags));
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;
}
} }
if (weaponGetPerk(attack->weapon) == PERK_WEAPON_ENHANCED_KNOCKOUT) { if (weaponGetPerk(attack->weapon) == PERK_WEAPON_ENHANCED_KNOCKOUT) {
@ -4195,22 +4223,8 @@ static int attackComputeCriticalFailure(Attack* attack)
} }
if ((attack->attackerFlags & DAM_CRIP_RANDOM) != 0) { if ((attack->attackerFlags & DAM_CRIP_RANDOM) != 0) {
attack->attackerFlags &= ~DAM_CRIP_RANDOM; // NOTE: Uninline.
_do_random_cripple(&(attack->attackerFlags));
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;
}
} }
if ((attack->attackerFlags & DAM_RANDOM_HIT) != 0) { if ((attack->attackerFlags & DAM_RANDOM_HIT) != 0) {
@ -4234,6 +4248,27 @@ static int attackComputeCriticalFailure(Attack* attack)
return 0; 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 // 0x42436C
int _determine_to_hit(Object* a1, Object* a2, int hitLocation, int hitMode) 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++) { // NOTE: Uninline.
_combat_update_critter_outline_for_los(_combat_list[index], 1); _combat_update_critters_in_los(true);
}
tileWindowRefresh(); tileWindowRefresh();
} }

View File

@ -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 int _ai_move_away(Object* a1, Object* a2, int a3);
static bool _ai_find_friend(Object* a1, int 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 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 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 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(Object* a1, Object* a2, int a3);
static Object* _ai_find_nearest_team_in_combat(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); 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 Object* _ai_retrieve_object(Object* a1, Object* a2);
static int _ai_pick_hit_mode(Object* a1, Object* a2, Object* a3); 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_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_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr);
static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile); static int _cai_retargetTileFromFriendlyFireSubFunc(AiRetargetData* aiRetargetData, int tile);
static bool _cai_attackWouldIntersect(Object* a1, Object* a2, Object* a3, int tile, int* distance); 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. // qsort compare function - melee then ranged.
// //
// 0x428B8C // 0x428B8C
@ -1270,6 +1283,14 @@ static int _compare_strength(const void* p1, const void* p2)
return 0; 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 // qsort compare unction - ranged then melee
// //
// 0x428BE4 // 0x428BE4
@ -1304,6 +1325,14 @@ static int _compare_weakness(const void* p1, const void* p2)
return 0; return 0;
} }
// NOTE: Inlined.
//
// 0x428C28
static void _ai_sort_list_weakness(Object** critterList, int length)
{
qsort(critterList, length, sizeof(*critterList), _compare_weakness);
}
// 0x428C3C // 0x428C3C
static Object* _ai_find_nearest_team(Object* a1, Object* a2, int a3) 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; return NULL;
} }
_combat_obj = a1; // NOTE: Uninline.
qsort(_curr_crit_list, _curr_crit_num, sizeof(*_curr_crit_list), _compare_nearer); _ai_sort_list_distance(_curr_crit_list, _curr_crit_num, a1);
for (i = 0; i < _curr_crit_num; i++) { for (i = 0; i < _curr_crit_num; i++) {
obj = _curr_crit_list[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; int team = a2->data.critter.combat.team;
_combat_obj = a1; // NOTE: Uninline.
qsort(_curr_crit_list, _curr_crit_num, sizeof(*_curr_crit_list), _compare_nearer); _ai_sort_list_distance(_curr_crit_list, _curr_crit_num, a1);
for (int index = 0; index < _curr_crit_num; index++) { for (int index = 0; index < _curr_crit_num; index++) {
Object* obj = _curr_crit_list[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; return 0;
} }
_combat_obj = a1; // NOTE: Uninline.
qsort(_curr_crit_list, _curr_crit_num, sizeof(*_curr_crit_list), _compare_nearer); _ai_sort_list_distance(_curr_crit_list, _curr_crit_num, a1);
int foundTargetCount = 0; int foundTargetCount = 0;
int team = a1->data.critter.combat.team; 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) { switch (attackWho) {
case ATTACK_WHO_STRONGEST: case ATTACK_WHO_STRONGEST:
compareProc = _compare_strength; // NOTE: Uninline.
_ai_sort_list_strength(targets, 4);
break; break;
case ATTACK_WHO_WEAKEST: case ATTACK_WHO_WEAKEST:
compareProc = _compare_weakness; // NOTE: Uninline.
_ai_sort_list_weakness(targets, 4);
break; break;
default: default:
compareProc = _compare_nearer; // NOTE: Uninline.
_combat_obj = a1; _ai_sort_list_distance(targets, 4, a1);
break; break;
} }
qsort(targets, 4, sizeof(*targets), compareProc);
for (int index = 0; index < 4; index++) { for (int index = 0; index < 4; index++) {
Object* candidate = targets[index]; Object* candidate = targets[index];
if (candidate != NULL && objectCanHearObject(a1, candidate)) { if (candidate != NULL && objectCanHearObject(a1, candidate)) {
@ -2022,8 +2050,8 @@ static Object* _ai_search_environ(Object* critter, int itemType)
return NULL; return NULL;
} }
_combat_obj = critter; // NOTE: Uninline.
qsort(objects, count, sizeof(*objects), _compare_nearer); _ai_sort_list_distance(objects, count, critter);
int perception = critterGetStat(critter, STAT_PERCEPTION) + 5; int perception = critterGetStat(critter, STAT_PERCEPTION) + 5;
Object* item2 = critterGetItem2(critter); Object* item2 = critterGetItem2(critter);
@ -2273,6 +2301,14 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
return 0; 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 // 0x42A1D4
static int _cai_retargetTileFromFriendlyFire(Object* source, Object* target, int* tilePtr) 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; // NOTE: Uninline.
_ai_sort_list_distance(aiRetargetData.critterList, aiRetargetData.critterCount, source);
qsort(aiRetargetData.critterList, aiRetargetData.critterCount, sizeof(*aiRetargetData.critterList), _compare_nearer);
if (_cai_retargetTileFromFriendlyFireSubFunc(&aiRetargetData, *tilePtr) == 0) { if (_cai_retargetTileFromFriendlyFireSubFunc(&aiRetargetData, *tilePtr) == 0) {
int minDistance = 99999; int minDistance = 99999;
@ -2650,7 +2685,8 @@ static int _ai_try_attack(Object* a1, Object* a2)
v38 = 0; v38 = 0;
} else { } else {
if (_ai_switch_weapons(a1, &hitMode, &weapon, a2) == -1 || weapon == NULL) { 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; return -1;
} }
} }
@ -2822,7 +2858,8 @@ int _cai_perform_distance_prefs(Object* a1, Object* a2)
break; break;
case DISTANCE_CHARGE: case DISTANCE_CHARGE:
if (a2 != NULL) { if (a2 != NULL) {
_ai_move_steps_closer(a1, a2, a1->data.critter.combat.ap, 1); // NOTE: Uninline.
_ai_move_closer(a1, a2, 1);
} }
break; break;
case DISTANCE_SNIPE: case DISTANCE_SNIPE:

View File

@ -68,6 +68,7 @@ typedef enum RadiationLevel {
} RadiationLevel; } RadiationLevel;
static int _get_rad_damage_level(Object* obj, void* data); static int _get_rad_damage_level(Object* obj, void* data);
static int critter_kill_count_clear();
static int _critterClearObjDrugs(Object* obj, void* data); static int _critterClearObjDrugs(Object* obj, void* data);
// 0x50141C // 0x50141C
@ -159,7 +160,8 @@ int critterInit()
{ {
dudeResetName(); dudeResetName();
memset(gKillsByType, 0, sizeof(gKillsByType)); // NOTE: Uninline;
critter_kill_count_clear();
if (!messageListInit(&gCritterMessageList)) { if (!messageListInit(&gCritterMessageList)) {
debugPrint("\nError: Initing critter name message file!"); debugPrint("\nError: Initing critter name message file!");
@ -181,7 +183,9 @@ int critterInit()
void critterReset() void critterReset()
{ {
dudeResetName(); dudeResetName();
memset(gKillsByType, 0, sizeof(gKillsByType));
// NOTE: Uninline;
critter_kill_count_clear();
} }
// 0x42D004 // 0x42D004
@ -680,6 +684,15 @@ int critterGetDamageType(Object* obj)
return proto->critter.data.damageType; return proto->critter.data.damageType;
} }
// NOTE: Inlined.
//
// 0x42D860
static int critter_kill_count_clear()
{
memset(gKillsByType, 0, sizeof(gKillsByType));
return 0;
}
// 0x42D878 // 0x42D878
int killsIncByType(int killType) int killsIncByType(int killType)
{ {

View File

@ -19,7 +19,8 @@ static void _debug_clear();
static int _debug_mono(char* string); static int _debug_mono(char* string);
static int _debug_log(char* string); static int _debug_log(char* string);
static int _debug_screen(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 // 0x51DEF8
static FILE* _fd = NULL; static FILE* _fd = NULL;
@ -174,7 +175,28 @@ static int _debug_puts(char* string)
// 0x4C6FAC // 0x4C6FAC
static void _debug_clear() 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 // 0x4C7004
@ -220,15 +242,72 @@ static int _debug_screen(char* string)
} }
// 0x4C709C // 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 // 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 // 0x4C71E8

View File

@ -5,7 +5,6 @@
#include "movie.h" #include "movie.h"
#include "platform_compat.h" #include "platform_compat.h"
#include "text_font.h" #include "text_font.h"
#include "widget.h"
#include "window_manager.h" #include "window_manager.h"
#include <string.h> #include <string.h>
@ -209,7 +208,7 @@ void _replyAddOption(const char* a1, const char* a2, int a3)
v18->field_C[v17].string = NULL; 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_1A = word_56DB60;
v18->field_C[v17].field_14 = a3; 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].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_1A = word_56DB60;
v5->field_C[v13].field_14 = a3; 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; int old_font;
Rect rect; Rect rect;
old_font = widgetGetFont(); old_font = windowGetFont();
widgetSetFont(font); windowSetFont(font);
_printStr(win, str, width, height, left, top, a8, a9, a10); _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.right = width + left;
rect.bottom = height + top; rect.bottom = height + top;
windowRefreshRect(win, &rect); windowRefreshRect(win, &rect);
widgetSetFont(old_font); windowSetFont(old_font);
} }
// 0x430D40 // 0x430D40

View File

@ -36,6 +36,7 @@
#define DISPLAY_MONITOR_BEEP_DELAY (500U) #define DISPLAY_MONITOR_BEEP_DELAY (500U)
static void display_clear();
static void displayMonitorRefresh(); static void displayMonitorRefresh();
static void displayMonitorScrollUpOnMouseDown(int btn, int keyCode); static void displayMonitorScrollUpOnMouseDown(int btn, int keyCode);
static void displayMonitorScrollDownOnMouseDown(int btn, int keyCode); static void displayMonitorScrollDownOnMouseDown(int btn, int keyCode);
@ -180,14 +181,8 @@ int displayMonitorInit()
gDisplayMonitorEnabled = true; gDisplayMonitorEnabled = true;
gDisplayMonitorInitialized = true; gDisplayMonitorInitialized = true;
for (int index = 0; index < gDisplayMonitorLinesCapacity; index++) { // NOTE: Uninline.
gDisplayMonitorLines[index][0] = '\0'; display_clear();
}
_disp_start = 0;
_disp_curr = 0;
displayMonitorRefresh();
// SFALL // SFALL
consoleFileInit(); consoleFileInit();
@ -199,18 +194,12 @@ int displayMonitorInit()
// 0x431800 // 0x431800
int displayMonitorReset() int displayMonitorReset()
{ {
if (gDisplayMonitorInitialized) { // NOTE: Uninline.
for (int index = 0; index < gDisplayMonitorLinesCapacity; index++) { display_clear();
gDisplayMonitorLines[index][0] = '\0';
}
_disp_start = 0;
_disp_curr = 0;
displayMonitorRefresh();
// SFALL // SFALL
consoleFileReset(); consoleFileReset();
}
return 0; return 0;
} }
@ -319,6 +308,24 @@ void displayMonitorAddMessage(char* str)
displayMonitorRefresh(); 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 // 0x431A78
static void displayMonitorRefresh() static void displayMonitorRefresh()
{ {

View File

@ -90,7 +90,7 @@ static char _aDec11199816543[] = VERSION_BUILD_TIME;
static bool gGameUiDisabled = false; static bool gGameUiDisabled = false;
// 0x5186B8 // 0x5186B8
static int _game_state_cur = 0; static int _game_state_cur = GAME_STATE_0;
// 0x5186BC // 0x5186BC
static bool gIsMapper = false; static bool gIsMapper = false;
@ -439,7 +439,8 @@ void gameExit()
// 0x442D44 // 0x442D44
int gameHandleKey(int eventCode, bool isInCombatMode) int gameHandleKey(int eventCode, bool isInCombatMode)
{ {
if (_game_state_cur == 5) { // NOTE: Uninline.
if (_game_state() == GAME_STATE_5) {
_gdialogSystemEnter(); _gdialogSystemEnter();
} }
@ -479,6 +480,8 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
if (mouseX == _scr_size.left || mouseX == _scr_size.right if (mouseX == _scr_size.left || mouseX == _scr_size.right
|| mouseY == _scr_size.top || mouseY == _scr_size.bottom) { || mouseY == _scr_size.top || mouseY == _scr_size.bottom) {
_gmouse_clicked_on_edge = true; _gmouse_clicked_on_edge = true;
} else {
_gmouse_clicked_on_edge = false;
} }
} }
} else { } else {
@ -501,6 +504,31 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
_intface_use_item(); _intface_use_item();
} }
break; 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_Q:
case KEY_CTRL_X: case KEY_CTRL_X:
case KEY_F10: case KEY_F10:
@ -746,14 +774,14 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
break; break;
case KEY_COMMA: case KEY_COMMA:
case KEY_LESS: case KEY_LESS:
if (reg_anim_begin(0) == 0) { if (reg_anim_begin(ANIMATION_REQUEST_RESERVED) == 0) {
animationRegisterRotateCounterClockwise(gDude); animationRegisterRotateCounterClockwise(gDude);
reg_anim_end(); reg_anim_end();
} }
break; break;
case KEY_DOT: case KEY_DOT:
case KEY_GREATER: case KEY_GREATER:
if (reg_anim_begin(0) == 0) { if (reg_anim_begin(ANIMATION_REQUEST_RESERVED) == 0) {
animationRegisterRotateClockwise(gDude); animationRegisterRotateClockwise(gDude);
reg_anim_end(); reg_anim_end();
} }
@ -868,8 +896,6 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
break; break;
} }
// TODO: Incomplete.
return 0; return 0;
} }
@ -1024,15 +1050,15 @@ int _game_state()
// 0x443E34 // 0x443E34
int _game_state_request(int a1) int _game_state_request(int a1)
{ {
if (a1 == 0) { if (a1 == GAME_STATE_0) {
a1 = 1; a1 = GAME_STATE_1;
} else if (a1 == 2) { } else if (a1 == GAME_STATE_2) {
a1 = 3; a1 = GAME_STATE_3;
} else if (a1 == 4) { } else if (a1 == GAME_STATE_4) {
a1 = 5; 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; _game_state_cur = a1;
return 0; return 0;
} }
@ -1047,14 +1073,14 @@ void _game_state_update()
v0 = _game_state_cur; v0 = _game_state_cur;
switch (_game_state_cur) { switch (_game_state_cur) {
case 1: case GAME_STATE_1:
v0 = 0; v0 = GAME_STATE_0;
break; break;
case 3: case GAME_STATE_3:
v0 = 2; v0 = GAME_STATE_2;
break; break;
case 5: case GAME_STATE_5:
v0 = 4; v0 = GAME_STATE_4;
} }
_game_state_cur = v0; _game_state_cur = v0;

View File

@ -4,6 +4,15 @@
#include "game_vars.h" #include "game_vars.h"
#include "message.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* gGameGlobalVars;
extern int gGameGlobalVarsLength; extern int gGameGlobalVarsLength;
extern const char* asc_5186C8; extern const char* asc_5186C8;

View File

@ -604,6 +604,8 @@ static int gGameDialogFidgetFrmCurrentFrame;
static int _gdialogReset(); static int _gdialogReset();
static void gameDialogEndLips(); static void gameDialogEndLips();
static int gdHide();
static int gdUnhide();
static int gameDialogAddMessageOption(int a1, int a2, int a3); static int gameDialogAddMessageOption(int a1, int a2, int a3);
static int gameDialogAddTextOption(int a1, const char* a2, int a3); static int gameDialogAddTextOption(int a1, const char* a2, int a3);
static int gameDialogReviewWindowInit(int* win); static int gameDialogReviewWindowInit(int* win);
@ -640,6 +642,7 @@ static void _gDialogRefreshOptionsRect(int win, Rect* drawRect);
static void gameDialogTicker(); 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 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_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 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 int _gdialog_barter_create_win();
static void _gdialog_barter_destroy_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 void gameDialogBarterButtonUpMouseUp(int btn, int a2);
static int _gdialog_window_create(); static int _gdialog_window_create();
static void _gdialog_window_destroy(); static void _gdialog_window_destroy();
static int talk_to_create_background_window();
static int gameDialogWindowRenderBackground(); static int gameDialogWindowRenderBackground();
static int _talkToRefreshDialogWindowRect(Rect* rect); 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); 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); _tile_scroll_to(gGameDialogOldCenterTile, 2);
} }
_game_state_request(2); _game_state_request(GAME_STATE_2);
_game_state_update(); _game_state_update();
} }
@ -1081,7 +1085,15 @@ void gameDialogRenderSupplementaryMessage(char* msg)
int lineHeight = fontGetLineHeight(); int lineHeight = fontGetLineHeight();
int a4 = 0; 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); windowUnhide(_gd_replyWin);
windowRefresh(gGameDialogReplyWindow); windowRefresh(gGameDialogReplyWindow);
@ -1222,6 +1234,24 @@ void _gdialogUpdatePartyStatus()
return; 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) { if (_gd_replyWin != -1) {
windowHide(_gd_replyWin); windowHide(_gd_replyWin);
} }
@ -1230,12 +1260,14 @@ void _gdialogUpdatePartyStatus()
windowHide(_gd_optionsWin); windowHide(_gd_optionsWin);
} }
_gdialog_window_destroy(); return 0;
}
gGameDialogSpeakerIsPartyMember = isPartyMember;
_gdialog_window_create();
// NOTE: Inlined.
//
// 0x445818
static int gdUnhide()
{
if (_gd_replyWin != -1) { if (_gd_replyWin != -1) {
windowUnhide(_gd_replyWin); windowUnhide(_gd_replyWin);
} }
@ -1243,6 +1275,8 @@ void _gdialogUpdatePartyStatus()
if (_gd_optionsWin != -1) { if (_gd_optionsWin != -1) {
windowUnhide(_gd_optionsWin); windowUnhide(_gd_optionsWin);
} }
return 0;
} }
// 0x44585C // 0x44585C
@ -1554,7 +1588,14 @@ void gameDialogReviewWindowUpdate(int win, int origin)
exit(1); 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 // SFALL: Cosmetic fix to the dialog review interface to prevent the
// player name from being displayed at the bottom of the window when 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); 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) { if (y >= 407) {
@ -2104,8 +2152,14 @@ void gameDialogOptionOnMouseEnter(int index)
} }
} }
unsigned char* windowBuffer = windowGetBuffer(gGameDialogOptionsWindow); // NOTE: Uninline.
gameDialogDrawText(windowBuffer, &_optionRect, dialogOptionEntry->text, NULL, fontGetLineHeight(), 393, color, 1); text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow),
&_optionRect,
dialogOptionEntry->text,
NULL,
fontGetLineHeight(),
393,
color);
_optionRect.left = 0; _optionRect.left = 0;
_optionRect.right = 391; _optionRect.right = 391;
@ -2146,8 +2200,14 @@ void gameDialogOptionOnMouseExit(int index)
_optionRect.left = 5; _optionRect.left = 5;
_optionRect.right = 388; _optionRect.right = 388;
unsigned char* windowBuffer = windowGetBuffer(gGameDialogOptionsWindow); // NOTE: Uninline.
gameDialogDrawText(windowBuffer, &_optionRect, dialogOptionEntry->text, NULL, fontGetLineHeight(), 393, color, 1); text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow),
&_optionRect,
dialogOptionEntry->text,
NULL,
fontGetLineHeight(),
393,
color);
_optionRect.right = 391; _optionRect.right = 391;
_optionRect.top = dialogOptionEntry->field_14; _optionRect.top = dialogOptionEntry->field_14;
@ -2168,16 +2228,14 @@ void gameDialogRenderReply()
_demo_copy_title(gGameDialogReplyWindow); _demo_copy_title(gGameDialogReplyWindow);
// Render reply. // NOTE: Uninline.
unsigned char* windowBuffer = windowGetBuffer(gGameDialogReplyWindow); text_to_rect_wrapped(windowGetBuffer(gGameDialogReplyWindow),
gameDialogDrawText(windowBuffer,
&_replyRect, &_replyRect,
gDialogReplyText, gDialogReplyText,
&dword_58F4E0, &dword_58F4E0,
fontGetLineHeight(), fontGetLineHeight(),
379, 379,
_colorTable[992] | 0x2000000, _colorTable[992] | 0x2000000);
1);
windowRefresh(gGameDialogReplyWindow); windowRefresh(gGameDialogReplyWindow);
} }
@ -2287,14 +2345,14 @@ void _gdProcessUpdate()
y = 0; y = 0;
} }
gameDialogDrawText(windowGetBuffer(gGameDialogOptionsWindow), // NOTE: Uninline.
text_to_rect_wrapped(windowGetBuffer(gGameDialogOptionsWindow),
&_optionRect, &_optionRect,
dialogOptionEntry->text, dialogOptionEntry->text,
NULL, NULL,
fontGetLineHeight(), fontGetLineHeight(),
393, 393,
color, color);
1);
_optionRect.top += 2; _optionRect.top += 2;
@ -2325,14 +2383,8 @@ int _gdCreateHeadWindow()
int windowWidth = GAME_DIALOG_WINDOW_WIDTH; int windowWidth = GAME_DIALOG_WINDOW_WIDTH;
int backgroundWindowX = (screenGetWidth() - GAME_DIALOG_WINDOW_WIDTH) / 2; // NOTE: Uninline.
int backgroundWindowY = (screenGetHeight() - GAME_DIALOG_WINDOW_HEIGHT) / 2; talk_to_create_background_window();
gGameDialogBackgroundWindow = windowCreate(backgroundWindowX,
backgroundWindowY,
windowWidth,
GAME_DIALOG_WINDOW_HEIGHT,
256,
WINDOW_FLAG_0x02);
gameDialogWindowRenderBackground(); gameDialogWindowRenderBackground();
unsigned char* buf = windowGetBuffer(gGameDialogBackgroundWindow); unsigned char* buf = windowGetBuffer(gGameDialogBackgroundWindow);
@ -2746,12 +2798,11 @@ void gameDialogTicker()
_dialogue_switch_mode = 0; _dialogue_switch_mode = 0;
_gdialog_barter_destroy_win(); _gdialog_barter_destroy_win();
_gdialog_window_create(); _gdialog_window_create();
if (_gd_replyWin != -1) {
windowUnhide(_gd_replyWin); // NOTE: Uninline.
} gdUnhide();
if (_gd_optionsWin != -1) { if (_gd_optionsWin != -1) {
windowUnhide(_gd_optionsWin);
// SFALL: Fix for the player's money not being displayed in the // SFALL: Fix for the player's money not being displayed in the
// dialog window after leaving the barter/combat control interface. // dialog window after leaving the barter/combat control interface.
gameDialogRenderCaps(); gameDialogRenderCaps();
@ -2966,6 +3017,14 @@ int _text_num_lines(const char* a1, int a2)
return v1; 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 // display_msg
// 0x447FA0 // 0x447FA0
int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4, int height, int pitch, int color, int a7) 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_switch_mode = 8;
_dialogue_state = 10; _dialogue_state = 10;
if (_gd_replyWin != -1) { // NOTE: Uninline.
windowHide(_gd_replyWin); gdHide();
}
if (_gd_optionsWin != -1) {
windowHide(_gd_optionsWin);
}
} }
// 0x4492D0 // 0x4492D0
@ -4226,13 +4280,8 @@ void gameDialogBarterButtonUpMouseUp(int btn, int keyCode)
_dialogue_switch_mode = 2; _dialogue_switch_mode = 2;
_dialogue_state = 4; _dialogue_state = 4;
if (_gd_replyWin != -1) { // NOTE: Uninline.
windowHide(_gd_replyWin); gdHide();
}
if (_gd_optionsWin != -1) {
windowHide(_gd_optionsWin);
}
} else { } else {
MessageListItem messageListItem; MessageListItem messageListItem;
// This person will not barter with you. // 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 // 0x44AB18
int gameDialogWindowRenderBackground() int gameDialogWindowRenderBackground()
{ {

View File

@ -309,6 +309,7 @@ static int gameMouseObjectsReset();
static void gameMouseObjectsFree(); static void gameMouseObjectsFree();
static int gameMouseActionMenuInit(); static int gameMouseActionMenuInit();
static void gameMouseActionMenuFree(); static void gameMouseActionMenuFree();
static int gmouse_3d_set_flat_fid(int fid, Rect* rect);
static int gameMouseUpdateHexCursorFid(Rect* rect); static int gameMouseUpdateHexCursorFid(Rect* rect);
static int _gmouse_3d_move_to(int x, int y, int elevation, Rect* a4); static int _gmouse_3d_move_to(int x, int y, int elevation, Rect* a4);
static int gameMouseHandleScrolling(int x, int y, int cursor); static int gameMouseHandleScrolling(int x, int y, int cursor);
@ -426,6 +427,14 @@ void _gmouse_disable_scrolling()
_gmouse_scrolling_enabled = 0; _gmouse_scrolling_enabled = 0;
} }
// NOTE: Inlined.
//
// 0x44B4E4
bool gmouse_scrolling_is_enabled()
{
return _gmouse_scrolling_enabled;
}
// 0x44B504 // 0x44B504
int _gmouse_get_click_to_scroll() int _gmouse_get_click_to_scroll()
{ {
@ -483,7 +492,8 @@ void gameMouseRefresh()
if (gGameMouseCursor >= FIRST_GAME_MOUSE_ANIMATED_CURSOR) { if (gGameMouseCursor >= FIRST_GAME_MOUSE_ANIMATED_CURSOR) {
_mouse_info(); _mouse_info();
if (_gmouse_scrolling_enabled) { // NOTE: Uninline.
if (gmouse_scrolling_is_enabled()) {
mouseGetPosition(&mouseX, &mouseY); mouseGetPosition(&mouseX, &mouseY);
int oldMouseCursor = gGameMouseCursor; int oldMouseCursor = gGameMouseCursor;
@ -525,7 +535,8 @@ void gameMouseRefresh()
} }
if (!_gmouse_enabled) { if (!_gmouse_enabled) {
if (_gmouse_scrolling_enabled) { // NOTE: Uninline.
if (gmouse_scrolling_is_enabled()) {
mouseGetPosition(&mouseX, &mouseY); mouseGetPosition(&mouseX, &mouseY);
int oldMouseCursor = gGameMouseCursor; 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) { if (gameMouseRenderPrimaryAction(mouseX, mouseY, primaryAction, _scr_size.right - _scr_size.left + 1, _scr_size.bottom - _scr_size.top - 99) == 0) {
Rect tmp; Rect tmp;
int fid = buildFid(OBJ_TYPE_INTERFACE, 282, 0, 0, 0); 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); tileWindowRefreshRect(&tmp, gElevation);
} }
} }
@ -763,7 +775,8 @@ void gameMouseRefresh()
if (gameMouseRenderAccuracy(formattedAccuracy, color) == 0) { if (gameMouseRenderAccuracy(formattedAccuracy, color) == 0) {
Rect tmp; Rect tmp;
int fid = buildFid(OBJ_TYPE_INTERFACE, 284, 0, 0, 0); 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); 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) { if (gameMouseRenderActionMenuItems(mouseX, mouseY, actionMenuItems, actionMenuItemsCount, _scr_size.right - _scr_size.left + 1, _scr_size.bottom - _scr_size.top - 99) == 0) {
Rect v43; Rect v43;
int fid = buildFid(OBJ_TYPE_INTERFACE, 283, 0, 0, 0); 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); tileWindowRefreshRect(&v43, gElevation);
isoDisable(); isoDisable();
@ -1339,7 +1353,8 @@ void gameMouseSetMode(int mode)
fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[mode], 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[mode], 0, 0, 0);
Rect rect; Rect rect;
if (objectSetFid(gGameMouseHexCursor, fid, &rect) == -1) { // NOTE: Uninline.
if (gmouse_3d_set_flat_fid(fid, &rect) == -1) {
return; return;
} }
@ -2148,6 +2163,18 @@ void gameMouseActionMenuFree()
gGameMouseActionPickFrmDataSize = 0; 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 // 0x44DF40
int gameMouseUpdateHexCursorFid(Rect* rect) int gameMouseUpdateHexCursorFid(Rect* rect)
{ {
@ -2156,7 +2183,8 @@ int gameMouseUpdateHexCursorFid(Rect* rect)
return -1; return -1;
} }
return objectSetFid(gGameMouseHexCursor, fid, rect); // NOTE: Uninline.
return gmouse_3d_set_flat_fid(fid, rect);
} }
// 0x44DF94 // 0x44DF94

View File

@ -78,6 +78,7 @@ void _gmouse_enable();
void _gmouse_disable(int a1); void _gmouse_disable(int a1);
void _gmouse_enable_scrolling(); void _gmouse_enable_scrolling();
void _gmouse_disable_scrolling(); void _gmouse_disable_scrolling();
bool gmouse_scrolling_is_enabled();
int _gmouse_is_scrolling(); int _gmouse_is_scrolling();
void gameMouseRefresh(); void gameMouseRefresh();
void _gmouse_handle_event(int mouseX, int mouseY, int mouseState); void _gmouse_handle_event(int mouseX, int mouseY, int mouseState);

View File

@ -13,7 +13,6 @@
#include "palette.h" #include "palette.h"
#include "platform_compat.h" #include "platform_compat.h"
#include "text_font.h" #include "text_font.h"
#include "widget.h"
#include "window_manager.h" #include "window_manager.h"
#include <stdio.h> #include <stdio.h>
@ -221,11 +220,11 @@ int gameMoviePlay(int movie, int flags)
colorPaletteLoad(subtitlesPaletteFilePath); colorPaletteLoad(subtitlesPaletteFilePath);
oldTextColor = widgetGetTextColor(); oldTextColor = windowGetTextColor();
widgetSetTextColor(1.0, 1.0, 1.0); windowSetTextColor(1.0, 1.0, 1.0);
oldFont = fontGetCurrent(); oldFont = fontGetCurrent();
widgetSetFont(101); windowSetFont(101);
} }
bool cursorWasHidden = cursorIsHidden(); bool cursorWasHidden = cursorIsHidden();
@ -278,12 +277,12 @@ int gameMoviePlay(int movie, int flags)
if (subtitlesEnabled) { if (subtitlesEnabled) {
colorPaletteLoad("color.pal"); colorPaletteLoad("color.pal");
widgetSetFont(oldFont); windowSetFont(oldFont);
float r = (float)((_Color2RGB_(oldTextColor) & 0x7C00) >> 10) * flt_50352A; float r = (float)((_Color2RGB_(oldTextColor) & 0x7C00) >> 10) * flt_50352A;
float g = (float)((_Color2RGB_(oldTextColor) & 0x3E0) >> 5) * flt_50352A; float g = (float)((_Color2RGB_(oldTextColor) & 0x3E0) >> 5) * flt_50352A;
float b = (float)(_Color2RGB_(oldTextColor) & 0x1F) * flt_50352A; float b = (float)(_Color2RGB_(oldTextColor) & 0x1F) * flt_50352A;
widgetSetTextColor(r, g, b); windowSetTextColor(r, g, b);
} }
windowDestroy(win); windowDestroy(win);

View File

@ -103,6 +103,7 @@ typedef struct InterfaceItemState {
static int _intface_redraw_items_callback(Object* a1, Object* a2); static int _intface_redraw_items_callback(Object* a1, Object* a2);
static int _intface_change_fid_callback(Object* a1, Object* a2); static int _intface_change_fid_callback(Object* a1, Object* a2);
static void interfaceBarSwapHandsAnimatePutAwayTakeOutSequence(int previousWeaponAnimationCode, int weaponAnimationCode); static void interfaceBarSwapHandsAnimatePutAwayTakeOutSequence(int previousWeaponAnimationCode, int weaponAnimationCode);
static int intface_init_items();
static int interfaceBarRefreshMainAction(); static int interfaceBarRefreshMainAction();
static int endTurnButtonInit(); static int endTurnButtonInit();
static int endTurnButtonFree(); static int endTurnButtonFree();
@ -111,6 +112,7 @@ static int endCombatButtonFree();
static void interfaceUpdateAmmoBar(int x, int ratio); static void interfaceUpdateAmmoBar(int x, int ratio);
static int _intface_item_reload(); static int _intface_item_reload();
static void interfaceRenderCounter(int x, int y, int previousValue, int value, int offset, int delay); 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 int indicatorBarInit();
static void interfaceBarFree(); static void interfaceBarFree();
static void indicatorBarReset(); static void indicatorBarReset();
@ -430,18 +432,21 @@ int interfaceInit()
gInterfaceBarWindow = windowCreate(interfaceBarWindowX, interfaceBarWindowY, INTERFACE_BAR_WIDTH, INTERFACE_BAR_HEIGHT, _colorTable[0], WINDOW_HIDDEN); gInterfaceBarWindow = windowCreate(interfaceBarWindowX, interfaceBarWindowY, INTERFACE_BAR_WIDTH, INTERFACE_BAR_HEIGHT, _colorTable[0], WINDOW_HIDDEN);
if (gInterfaceBarWindow == -1) { if (gInterfaceBarWindow == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
gInterfaceWindowBuffer = windowGetBuffer(gInterfaceBarWindow); gInterfaceWindowBuffer = windowGetBuffer(gInterfaceBarWindow);
if (gInterfaceWindowBuffer == NULL) { if (gInterfaceWindowBuffer == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 16, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 16, 0, 0, 0);
backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle); backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
if (backgroundFrmData == NULL) { 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); 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); fid = buildFid(OBJ_TYPE_INTERFACE, 47, 0, 0, 0);
gInventoryButtonUpFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonUpFrmHandle); gInventoryButtonUpFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonUpFrmHandle);
if (gInventoryButtonUpFrmData == NULL) { if (gInventoryButtonUpFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 46, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 46, 0, 0, 0);
gInventoryButtonDownFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonDownFrmHandle); gInventoryButtonDownFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonDownFrmHandle);
if (gInventoryButtonDownFrmData == NULL) { 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); gInventoryButton = buttonCreate(gInterfaceBarWindow, 211, 40, 32, 21, -1, -1, -1, KEY_LOWERCASE_I, gInventoryButtonUpFrmData, gInventoryButtonDownFrmData, NULL, 0);
if (gInventoryButton == -1) { if (gInventoryButton == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
buttonSetCallbacks(gInventoryButton, _gsound_med_butt_press, _gsound_med_butt_release); 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); fid = buildFid(OBJ_TYPE_INTERFACE, 18, 0, 0, 0);
gOptionsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonUpFrmHandle); gOptionsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonUpFrmHandle);
if (gOptionsButtonUpFrmData == NULL) { if (gOptionsButtonUpFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 17, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 17, 0, 0, 0);
gOptionsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonDownFrmHandle); gOptionsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonDownFrmHandle);
if (gOptionsButtonDownFrmData == NULL) { 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); gOptionsButton = buttonCreate(gInterfaceBarWindow, 210, 61, 34, 34, -1, -1, -1, KEY_LOWERCASE_O, gOptionsButtonUpFrmData, gOptionsButtonDownFrmData, NULL, 0);
if (gOptionsButton == -1) { if (gOptionsButton == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
buttonSetCallbacks(gOptionsButton, _gsound_med_butt_press, _gsound_med_butt_release); 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); fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
gSkilldexButtonUpFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonUpFrmHandle); gSkilldexButtonUpFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonUpFrmHandle);
if (gSkilldexButtonUpFrmData == NULL) { if (gSkilldexButtonUpFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0);
gSkilldexButtonDownFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonDownFrmHandle); gSkilldexButtonDownFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonDownFrmHandle);
if (gSkilldexButtonDownFrmData == NULL) { if (gSkilldexButtonDownFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
gSkilldexButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonMaskFrmHandle); gSkilldexButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonMaskFrmHandle);
if (gSkilldexButtonMaskFrmData == NULL) { 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); gSkilldexButton = buttonCreate(gInterfaceBarWindow, 523, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_S, gSkilldexButtonUpFrmData, gSkilldexButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
if (gSkilldexButton == -1) { if (gSkilldexButton == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
buttonSetMask(gSkilldexButton, gSkilldexButtonMaskFrmData); buttonSetMask(gSkilldexButton, gSkilldexButtonMaskFrmData);
@ -514,24 +529,28 @@ int interfaceInit()
fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0);
gMapButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMapButtonUpFrmHandle); gMapButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMapButtonUpFrmHandle);
if (gMapButtonUpFrmData == NULL) { if (gMapButtonUpFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 10, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 10, 0, 0, 0);
gMapButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMapButtonDownFrmHandle); gMapButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMapButtonDownFrmHandle);
if (gMapButtonDownFrmData == NULL) { if (gMapButtonDownFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0);
gMapButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gMapButtonMaskFrmHandle); gMapButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gMapButtonMaskFrmHandle);
if (gMapButtonMaskFrmData == NULL) { 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); gMapButton = buttonCreate(gInterfaceBarWindow, 526, 39, 41, 19, -1, -1, -1, KEY_TAB, gMapButtonUpFrmData, gMapButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
if (gMapButton == -1) { if (gMapButton == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
buttonSetMask(gMapButton, gMapButtonMaskFrmData); buttonSetMask(gMapButton, gMapButtonMaskFrmData);
@ -540,18 +559,21 @@ int interfaceInit()
fid = buildFid(OBJ_TYPE_INTERFACE, 59, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 59, 0, 0, 0);
gPipboyButtonUpFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonUpFrmHandle); gPipboyButtonUpFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonUpFrmHandle);
if (gPipboyButtonUpFrmData == NULL) { if (gPipboyButtonUpFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 58, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 58, 0, 0, 0);
gPipboyButtonDownFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonDownFrmHandle); gPipboyButtonDownFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonDownFrmHandle);
if (gPipboyButtonDownFrmData == NULL) { 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); gPipboyButton = buttonCreate(gInterfaceBarWindow, 526, 77, 41, 19, -1, -1, -1, KEY_LOWERCASE_P, gPipboyButtonUpFrmData, gPipboyButtonDownFrmData, NULL, 0);
if (gPipboyButton == -1) { if (gPipboyButton == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
buttonSetMask(gPipboyButton, gMapButtonMaskFrmData); buttonSetMask(gPipboyButton, gMapButtonMaskFrmData);
@ -560,18 +582,21 @@ int interfaceInit()
fid = buildFid(OBJ_TYPE_INTERFACE, 57, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 57, 0, 0, 0);
gCharacterButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonUpFrmHandle); gCharacterButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonUpFrmHandle);
if (gCharacterButtonUpFrmData == NULL) { if (gCharacterButtonUpFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 56, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 56, 0, 0, 0);
gCharacterButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonDownFrmHandle); gCharacterButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonDownFrmHandle);
if (gCharacterButtonDownFrmData == NULL) { 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); gCharacterButton = buttonCreate(gInterfaceBarWindow, 526, 58, 41, 19, -1, -1, -1, KEY_LOWERCASE_C, gCharacterButtonUpFrmData, gCharacterButtonDownFrmData, NULL, 0);
if (gCharacterButton == -1) { if (gCharacterButton == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
buttonSetMask(gCharacterButton, gMapButtonMaskFrmData); buttonSetMask(gCharacterButton, gMapButtonMaskFrmData);
@ -580,19 +605,22 @@ int interfaceInit()
fid = buildFid(OBJ_TYPE_INTERFACE, 32, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 32, 0, 0, 0);
gSingleAttackButtonUpData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonUpHandle); gSingleAttackButtonUpData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonUpHandle);
if (gSingleAttackButtonUpData == NULL) { if (gSingleAttackButtonUpData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 31, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 31, 0, 0, 0);
gSingleAttackButtonDownData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonDownHandle); gSingleAttackButtonDownData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonDownHandle);
if (gSingleAttackButtonDownData == NULL) { if (gSingleAttackButtonDownData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 73, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 73, 0, 0, 0);
_itemButtonDisabled = artLockFrameData(fid, 0, 0, &_itemButtonDisabledKey); _itemButtonDisabled = artLockFrameData(fid, 0, 0, &_itemButtonDisabledKey);
if (_itemButtonDisabled == NULL) { if (_itemButtonDisabled == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
memcpy(_itemButtonUp, gSingleAttackButtonUpData, sizeof(_itemButtonUp)); 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); gSingleAttackButton = buttonCreate(gInterfaceBarWindow, 267, 26, 188, 67, -1, -1, -1, -20, _itemButtonUp, _itemButtonDown, NULL, BUTTON_FLAG_TRANSPARENT);
if (gSingleAttackButton == -1) { if (gSingleAttackButton == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
buttonSetRightMouseCallbacks(gSingleAttackButton, -1, KEY_LOWERCASE_N, NULL, NULL); buttonSetRightMouseCallbacks(gSingleAttackButton, -1, KEY_LOWERCASE_N, NULL, NULL);
@ -609,25 +638,29 @@ int interfaceInit()
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
gChangeHandsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonUpFrmHandle); gChangeHandsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonUpFrmHandle);
if (gChangeHandsButtonUpFrmData == NULL) { if (gChangeHandsButtonUpFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0);
gChangeHandsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonDownFrmHandle); gChangeHandsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonDownFrmHandle);
if (gChangeHandsButtonDownFrmData == NULL) { if (gChangeHandsButtonDownFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
gChangeHandsButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonMaskFrmHandle); gChangeHandsButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonMaskFrmHandle);
if (gChangeHandsButtonMaskFrmData == NULL) { if (gChangeHandsButtonMaskFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
// Swap hands button // Swap hands button
gChangeHandsButton = buttonCreate(gInterfaceBarWindow, 218, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_B, gChangeHandsButtonUpFrmData, gChangeHandsButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT); gChangeHandsButton = buttonCreate(gInterfaceBarWindow, 218, 6, 22, 21, -1, -1, -1, KEY_LOWERCASE_B, gChangeHandsButtonUpFrmData, gChangeHandsButtonDownFrmData, NULL, BUTTON_FLAG_TRANSPARENT);
if (gChangeHandsButton == -1) { if (gChangeHandsButton == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
buttonSetMask(gChangeHandsButton, gChangeHandsButtonMaskFrmData); buttonSetMask(gChangeHandsButton, gChangeHandsButtonMaskFrmData);
@ -636,39 +669,42 @@ int interfaceInit()
fid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0);
gNumbersFrmData = artLockFrameData(fid, 0, 0, &gNumbersFrmHandle); gNumbersFrmData = artLockFrameData(fid, 0, 0, &gNumbersFrmHandle);
if (gNumbersFrmData == NULL) { if (gNumbersFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 83, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 83, 0, 0, 0);
gGreenLightFrmData = artLockFrameData(fid, 0, 0, &gGreenLightFrmHandle); gGreenLightFrmData = artLockFrameData(fid, 0, 0, &gGreenLightFrmHandle);
if (gGreenLightFrmData == NULL) { if (gGreenLightFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 84, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 84, 0, 0, 0);
gYellowLightFrmData = artLockFrameData(fid, 0, 0, &gYellowLightFrmHandle); gYellowLightFrmData = artLockFrameData(fid, 0, 0, &gYellowLightFrmHandle);
if (gYellowLightFrmData == NULL) { if (gYellowLightFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
fid = buildFid(OBJ_TYPE_INTERFACE, 85, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 85, 0, 0, 0);
gRedLightFrmData = artLockFrameData(fid, 0, 0, &gRedLightFrmHandle); gRedLightFrmData = artLockFrameData(fid, 0, 0, &gRedLightFrmHandle);
if (gRedLightFrmData == NULL) { if (gRedLightFrmData == NULL) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
blitBufferToBuffer(gInterfaceWindowBuffer + 640 * 14 + 316, 90, 5, 640, gInterfaceActionPointsBarBackground, 90); blitBufferToBuffer(gInterfaceWindowBuffer + 640 * 14 + 316, 90, 5, 640, gInterfaceActionPointsBarBackground, 90);
if (indicatorBarInit() == -1) { if (indicatorBarInit() == -1) {
goto err; // NOTE: Uninline.
return intface_fatal_error(-1);
} }
gInterfaceCurrentHand = HAND_LEFT; gInterfaceCurrentHand = HAND_LEFT;
// FIXME: For unknown reason these values initialized with -1. It's never // NOTE: Uninline.
// checked for -1, so I have no explanation for this. intface_init_items();
gInterfaceItemStates[HAND_LEFT].item = (Object*)-1;
gInterfaceItemStates[HAND_RIGHT].item = (Object*)-1;
displayMonitorInit(); displayMonitorInit();
@ -677,12 +713,6 @@ int interfaceInit()
_intfaceHidden = 1; _intfaceHidden = 1;
return 0; return 0;
err:
interfaceFree();
return -1;
} }
// 0x45E3D0 // 0x45E3D0
@ -690,10 +720,8 @@ void interfaceReset()
{ {
interfaceBarEnable(); interfaceBarEnable();
if (gInterfaceBarWindow != -1 && !_intfaceHidden) { // NOTE: Uninline.
windowHide(gInterfaceBarWindow); intface_hide();
_intfaceHidden = 1;
}
indicatorBarRefresh(); indicatorBarRefresh();
displayMonitorReset(); displayMonitorReset();
@ -925,11 +953,8 @@ int interfaceLoad(File* stream)
} }
if (v2) { if (v2) {
if (gInterfaceBarWindow != -1 && !_intfaceHidden) { // NOTE: Uninline.
windowHide(gInterfaceBarWindow); intface_hide();
_intfaceHidden = 1;
}
indicatorBarRefresh();
} else { } else {
_intface_show(); _intface_show();
} }
@ -975,6 +1000,20 @@ int interfaceSave(File* stream)
return 0; return 0;
} }
// NOTE: Inlined.
//
// 0x45E9E0
void intface_hide()
{
if (gInterfaceBarWindow != -1) {
if (!_intfaceHidden) {
windowHide(gInterfaceBarWindow);
_intfaceHidden = 1;
}
}
indicatorBarRefresh();
}
// 0x45EA10 // 0x45EA10
void _intface_show() 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 // 0x45FD88
static int interfaceBarRefreshMainAction() 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 // 0x461134
static int indicatorBarInit() static int indicatorBarInit()
{ {

View File

@ -37,6 +37,7 @@ void interfaceReset();
void interfaceFree(); void interfaceFree();
int interfaceLoad(File* stream); int interfaceLoad(File* stream);
int interfaceSave(File* stream); int interfaceSave(File* stream);
void intface_hide();
void _intface_show(); void _intface_show();
void interfaceBarEnable(); void interfaceBarEnable();
void interfaceBarDisable(); void interfaceBarDisable();

View File

@ -21,7 +21,7 @@ typedef struct ProgramListNode {
struct ProgramListNode* prev; // prev struct ProgramListNode* prev; // prev
} ProgramListNode; } ProgramListNode;
static int _defaultTimerFunc(); static unsigned int _defaultTimerFunc();
static char* _defaultFilename_(char* s); static char* _defaultFilename_(char* s);
static int _outputStr(char* a1); static int _outputStr(char* a1);
static int _checkWait(Program* program); 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 void stackPushInt32(unsigned char* a1, int* a2, int value);
static int stackPopInt32(unsigned char* a1, int* a2); static int stackPopInt32(unsigned char* a1, int* a2);
static opcode_t stackPopInt16(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 void programReturnStackPushInt16(Program* program, int value);
static opcode_t programReturnStackPopInt16(Program* program); static opcode_t programReturnStackPopInt16(Program* program);
static int programReturnStackPopInt32(Program* program); static int programReturnStackPopInt32(Program* program);
static void _detachProgram(Program* program); static void _detachProgram(Program* program);
static void _purgeProgram(Program* program); static void _purgeProgram(Program* program);
static void programFree(Program* program); static void programFree(Program* program);
static opcode_t _getOp(Program* program);
static void programMarkHeap(Program* program); static void programMarkHeap(Program* program);
static void opNoop(Program* program); static void opNoop(Program* program);
static void opPush(Program* program); static void opPush(Program* program);
@ -117,7 +119,9 @@ static void opExec(Program* program);
static void opCheckProcedureArgumentCount(Program* program); static void opCheckProcedureArgumentCount(Program* program);
static void opLookupStringProc(Program* program); static void opLookupStringProc(Program* program);
static void _setupCallWithReturnVal(Program* program, int address, int a3); 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 _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 _doEvents();
static void programListNodeFree(ProgramListNode* programListNode); static void programListNodeFree(ProgramListNode* programListNode);
static void interpreterPrintStats(); static void interpreterPrintStats();
@ -133,10 +137,10 @@ int _TimeOut = 0;
static int _Enabled = 1; static int _Enabled = 1;
// 0x519040 // 0x519040
static int (*_timerFunc)() = _defaultTimerFunc; InterpretTimerFunc* _timerFunc = _defaultTimerFunc;
// 0x519044 // 0x519044
static int _timerTick = 1000; static unsigned int _timerTick = 1000;
// 0x519048 // 0x519048
static char* (*_filenameFunc)(char*) = _defaultFilename_; static char* (*_filenameFunc)(char*) = _defaultFilename_;
@ -163,7 +167,7 @@ static int _suspendEvents;
static int _busy; static int _busy;
// 0x4670A0 // 0x4670A0
static int _defaultTimerFunc() static unsigned int _defaultTimerFunc()
{ {
return _get_time(); return _get_time();
} }
@ -189,7 +193,7 @@ static int _outputStr(char* a1)
// 0x4670C8 // 0x4670C8
static int _checkWait(Program* program) static int _checkWait(Program* program)
{ {
return 1000 * _timerFunc() / _timerTick <= program->field_70; return 1000 * _timerFunc() / _timerTick <= program->waitEnd;
} }
// 0x4670FC // 0x4670FC
@ -360,8 +364,18 @@ static opcode_t stackPopInt16(unsigned char* data, int* pointer)
return stackReadInt16(data, *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 // 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) { if (opcode == VALUE_TYPE_DYNAMIC_STRING) {
char* string = (char*)(program->dynamicStrings + 4 + value); char* string = (char*)(program->dynamicStrings + 4 + value);
@ -483,6 +497,20 @@ Program* programCreateByPath(const char* path)
return program; 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 // 0x4678E0
char* programGetString(Program* program, opcode_t opcode, int offset) char* programGetString(Program* program, opcode_t opcode, int offset)
{ {
@ -741,10 +769,10 @@ static void opWait(Program* program)
{ {
int data = programStackPopInteger(program); int data = programStackPopInteger(program);
program->field_74 = 1000 * _timerFunc() / _timerTick; program->waitStart = 1000 * _timerFunc() / _timerTick;
program->field_70 = program->field_74 + data; program->waitEnd = program->waitStart + data;
program->field_7C = _checkWait; program->checkWaitFunc = _checkWait;
program->flags |= PROGRAM_FLAG_0x10; program->flags |= PROGRAM_IS_WAITING;
} }
// 0x468218 // 0x468218
@ -809,13 +837,14 @@ static void opStore(Program* program)
ProgramValue oldValue = program->stackValues->at(pos); ProgramValue oldValue = program->stackValues->at(pos);
if (oldValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { if (oldValue.opcode == VALUE_TYPE_DYNAMIC_STRING) {
programPopString(program, oldValue.opcode, oldValue.integerValue); _interpretDecStringRef(program, oldValue.opcode, oldValue.integerValue);
} }
program->stackValues->at(pos) = value; program->stackValues->at(pos) = value;
if (value.opcode == VALUE_TYPE_DYNAMIC_STRING) { 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) static void op801F(Program* program)
{ {
program->windowId = programStackPopInteger(program); program->windowId = programStackPopInteger(program);
program->field_7C = (int (*)(Program*))programStackPopPointer(program); program->checkWaitFunc = (InterpretCheckWaitFunc*)programStackPopPointer(program);
program->flags = programStackPopInteger(program) & 0xFFFF; program->flags = programStackPopInteger(program) & 0xFFFF;
} }
@ -2041,7 +2070,7 @@ static void op8026(Program* program)
op801F(program); op801F(program);
Program* v1 = (Program*)programReturnStackPopPointer(program); Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->field_7C = (int (*)(Program*))programReturnStackPopPointer(program); v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
v1->flags = programReturnStackPopInteger(program); v1->flags = programReturnStackPopInteger(program);
program->instructionPointer = programReturnStackPopInteger(program); program->instructionPointer = programReturnStackPopInteger(program);
@ -2057,7 +2086,7 @@ static void op8022(Program* program)
op801F(program); op801F(program);
Program* v1 = (Program*)programReturnStackPopPointer(program); Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->field_7C = (int (*)(Program*))programReturnStackPopPointer(program); v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
v1->flags = programReturnStackPopInteger(program); v1->flags = programReturnStackPopInteger(program);
program->instructionPointer = programReturnStackPopInteger(program); program->instructionPointer = programReturnStackPopInteger(program);
@ -2069,7 +2098,7 @@ static void op8023(Program* program)
op801F(program); op801F(program);
Program* v1 = (Program*)programReturnStackPopPointer(program); Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->field_7C = (int (*)(Program*))programReturnStackPopPointer(program); v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
v1->flags = programReturnStackPopInteger(program); v1->flags = programReturnStackPopInteger(program);
program->instructionPointer = programReturnStackPopInteger(program); program->instructionPointer = programReturnStackPopInteger(program);
@ -2086,7 +2115,7 @@ static void op8024(Program* program)
op801F(program); op801F(program);
Program* v10 = (Program*)programReturnStackPopPointer(program); Program* v10 = (Program*)programReturnStackPopPointer(program);
v10->field_7C = (int (*)(Program*))programReturnStackPopPointer(program); v10->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
v10->flags = programReturnStackPopInteger(program); v10->flags = programReturnStackPopInteger(program);
if ((value.opcode & 0xF7FF) == VALUE_TYPE_STRING) { if ((value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
char* string = programGetString(program, value.opcode, value.integerValue); 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); ProgramValue oldValue = program->stackValues->at(program->basePointer + addr);
if (oldValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { 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; program->stackValues->at(program->basePointer + addr) = value;
if (value.opcode == VALUE_TYPE_DYNAMIC_STRING) { 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; program->flags |= PROGRAM_FLAG_0x20;
char* name = programStackPopString(program); char* name = programStackPopString(program);
name = _interpretMangleName(name);
program->child = programCreateByPath(name); // NOTE: Uninline.
program->child = runScript(name);
if (program->child == NULL) { if (program->child == NULL) {
char err[260]; char err[260];
sprintf(err, "Error spawning child %s", name); sprintf(err, "Error spawning child %s", name);
programFatalError(err); programFatalError(err);
} }
programListNodeCreate(program->child);
_interpret(program->child, 24);
program->child->parent = program; program->child->parent = program;
program->child->windowId = program->windowId; program->child->windowId = program->windowId;
} }
@ -2335,17 +2363,15 @@ static void opSpawn(Program* program)
program->flags |= PROGRAM_FLAG_0x0100; program->flags |= PROGRAM_FLAG_0x0100;
char* name = programStackPopString(program); char* name = programStackPopString(program);
name = _interpretMangleName(name);
program->child = programCreateByPath(name); // NOTE: Uninline.
program->child = runScript(name);
if (program->child == NULL) { if (program->child == NULL) {
char err[256]; char err[260];
sprintf(err, "Error spawning child %s", name); sprintf(err, "Error spawning child %s", name);
programFatalError(err); programFatalError(err);
} }
programListNodeCreate(program->child);
_interpret(program->child, 24);
program->child->parent = program; program->child->parent = program;
program->child->windowId = program->windowId; program->child->windowId = program->windowId;
@ -2360,8 +2386,7 @@ static void opSpawn(Program* program)
static Program* forkProgram(Program* program) static Program* forkProgram(Program* program)
{ {
char* name = programStackPopString(program); char* name = programStackPopString(program);
name = _interpretMangleName(name); Program* forked = runScript(name);
Program* forked = programCreateByPath(name);
if (forked == NULL) { if (forked == NULL) {
char err[256]; char err[256];
@ -2369,10 +2394,6 @@ static Program* forkProgram(Program* program)
programFatalError(err); programFatalError(err);
} }
programListNodeCreate(forked);
_interpret(forked, 24);
forked->windowId = program->windowId; forked->windowId = program->windowId;
return forked; return forked;
@ -2595,25 +2616,24 @@ void _interpret(Program* program, int a2)
break; break;
} }
if ((program->flags & PROGRAM_FLAG_0x10) != 0) { if ((program->flags & PROGRAM_IS_WAITING) != 0) {
_busy = 1; _busy = 1;
if (program->field_7C != NULL) { if (program->checkWaitFunc != NULL) {
if (!program->field_7C(program)) { if (!program->checkWaitFunc(program)) {
_busy = 0; _busy = 0;
continue; continue;
} }
} }
_busy = 0; _busy = 0;
program->field_7C = NULL; program->checkWaitFunc = NULL;
program->flags &= ~PROGRAM_FLAG_0x10; program->flags &= ~PROGRAM_IS_WAITING;
} }
int instructionPointer = program->instructionPointer; // NOTE: Uninline.
program->instructionPointer = instructionPointer + 2; opcode_t opcode = _getOp(program);
opcode_t opcode = stackReadInt16(program->data, instructionPointer);
// TODO: Replace with field_82 and field_80? // TODO: Replace with field_82 and field_80?
program->flags &= 0xFFFF; program->flags &= 0xFFFF;
program->flags |= (opcode << 16); program->flags |= (opcode << 16);
@ -2663,7 +2683,7 @@ static void _setupCallWithReturnVal(Program* program, int address, int returnAdd
// Save program flags // Save program flags
programStackPushInteger(program, program->flags & 0xFFFF); programStackPushInteger(program, program->flags & 0xFFFF);
programStackPushPointer(program, (void*)program->field_7C); programStackPushPointer(program, (void*)program->checkWaitFunc);
programStackPushInteger(program, program->windowId); programStackPushInteger(program, program->windowId);
@ -2671,6 +2691,15 @@ static void _setupCallWithReturnVal(Program* program, int address, int returnAdd
program->instructionPointer = address; program->instructionPointer = address;
} }
// NOTE: Inlined.
//
// 0x46CF78
static void _setupCall(Program* program, int address, int returnAddress)
{
_setupCallWithReturnVal(program, address, returnAddress);
programStackPushInteger(program, 0);
}
// 0x46CF9C // 0x46CF9C
static void _setupExternalCallWithReturnVal(Program* program1, Program* program2, int address, int a4) 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); programReturnStackPushInteger(program2, program1->flags & 0xFFFF);
programReturnStackPushPointer(program2, (void*)program1->field_7C); programReturnStackPushPointer(program2, (void*)program1->checkWaitFunc);
programReturnStackPushPointer(program2, program1); programReturnStackPushPointer(program2, program1);
@ -2686,7 +2715,7 @@ static void _setupExternalCallWithReturnVal(Program* program1, Program* program2
programStackPushInteger(program2, program2->flags & 0xFFFF); programStackPushInteger(program2, program2->flags & 0xFFFF);
programStackPushPointer(program2, (void*)program2->field_7C); programStackPushPointer(program2, (void*)program2->checkWaitFunc);
programStackPushInteger(program2, program2->windowId); programStackPushInteger(program2, program2->windowId);
@ -2697,66 +2726,66 @@ static void _setupExternalCallWithReturnVal(Program* program1, Program* program2
program1->flags |= PROGRAM_FLAG_0x20; program1->flags |= PROGRAM_FLAG_0x20;
} }
// 0x46DB58 // NOTE: Inlined.
void _executeProc(Program* program, int procedure_index) //
// 0x46D0B0
static void _setupExternalCall(Program* program1, Program* program2, int address, int a4)
{ {
Program* external_program; _setupExternalCallWithReturnVal(program1, program2, address, a4);
char* identifier; programStackPushInteger(program2, 0);
int address; }
int arguments_count;
unsigned char* procedure_ptr; // 0x46DB58
int flags; void _executeProc(Program* program, int procedureIndex)
{
unsigned char* procedurePtr;
char* procedureIdentifier;
int procedureAddress;
Program* externalProgram;
int externalProcedureAddress;
int externalProcedureArgumentCount;
int procedureFlags;
char err[256]; char err[256];
Program* context;
procedure_ptr = program->procedures + 4 + sizeof(Procedure) * procedure_index; procedurePtr = program->procedures + 4 + sizeof(Procedure) * procedureIndex;
flags = stackReadInt32(procedure_ptr, 4); procedureFlags = stackReadInt32(procedurePtr, 4);
if (!(flags & PROCEDURE_FLAG_IMPORTED)) { if ((procedureFlags & PROCEDURE_FLAG_IMPORTED) != 0) {
address = stackReadInt32(procedure_ptr, 16); procedureIdentifier = programGetIdentifier(program, stackReadInt32(procedurePtr, 0));
externalProgram = externalProcedureGetProgram(procedureIdentifier, &externalProcedureAddress, &externalProcedureArgumentCount);
_setupCallWithReturnVal(program, address, 20); if (externalProgram != NULL) {
if (externalProcedureArgumentCount == 0) {
programStackPushInteger(program, 0);
if (!(flags & PROCEDURE_FLAG_CRITICAL)) {
return;
}
program->flags |= PROGRAM_FLAG_CRITICAL_SECTION;
context = program;
} else { } 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;
}
if (arguments_count != 0) {
sprintf(err, "External procedure cannot take arguments in interrupt context"); sprintf(err, "External procedure cannot take arguments in interrupt context");
// TODO: Incomplete. _interpretOutput(err);
// _interpretOutput(err); }
return; } else {
sprintf(err, "External procedure %s not found\n", procedureIdentifier);
_interpretOutput(err);
} }
_setupExternalCallWithReturnVal(program, external_program, address, 28); // NOTE: Uninline.
_setupExternalCall(program, externalProgram, externalProcedureAddress, 28);
programStackPushInteger(external_program, 0); procedurePtr = externalProgram->procedures + 4 + sizeof(Procedure) * procedureIndex;
procedureFlags = stackReadInt32(procedurePtr, 4);
procedure_ptr = external_program->procedures + 4 + sizeof(Procedure) * procedure_index; if ((procedureFlags & PROCEDURE_FLAG_CRITICAL) != 0) {
flags = stackReadInt32(procedure_ptr, 4); // NOTE: Uninline.
opEnterCriticalSection(externalProgram);
if (!(flags & PROCEDURE_FLAG_CRITICAL)) { _interpret(externalProgram, 0);
return;
} }
} else {
procedureAddress = stackReadInt32(procedurePtr, 16);
external_program->flags |= PROGRAM_FLAG_CRITICAL_SECTION; // NOTE: Uninline.
context = external_program; _setupCall(program, procedureAddress, 20);
if ((procedureFlags & PROCEDURE_FLAG_CRITICAL) != 0) {
// NOTE: Uninline.
opEnterCriticalSection(program);
_interpret(program, 0);
}
} }
_interpret(context, 0);
} }
// Returns index of the procedure with specified name or -1 if no such // 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 // 0x46DD2C
void _executeProcedure(Program* program, int procedure_index) void _executeProcedure(Program* program, int procedureIndex)
{ {
Program* external_program; unsigned char* procedurePtr;
char* identifier; char* procedureIdentifier;
int address; int procedureAddress;
int arguments_count; Program* externalProgram;
unsigned char* procedure_ptr; int externalProcedureAddress;
int flags; int externalProcedureArgumentCount;
int procedureFlags;
char err[256]; char err[256];
jmp_buf jmp_buf; jmp_buf env;
Program* v13;
procedure_ptr = program->procedures + 4 + sizeof(Procedure) * procedure_index; procedurePtr = program->procedures + 4 + sizeof(Procedure) * procedureIndex;
flags = stackReadInt32(procedure_ptr, 4); procedureFlags = stackReadInt32(procedurePtr, 4);
if (flags & PROCEDURE_FLAG_IMPORTED) { if ((procedureFlags & PROCEDURE_FLAG_IMPORTED) != 0) {
identifier = programGetIdentifier(program, stackReadInt32(procedure_ptr, 0)); procedureIdentifier = programGetIdentifier(program, stackReadInt32(procedurePtr, 0));
external_program = externalProcedureGetProgram(identifier, &address, &arguments_count); externalProgram = externalProcedureGetProgram(procedureIdentifier, &externalProcedureAddress, &externalProcedureArgumentCount);
if (external_program == NULL) { if (externalProgram != NULL) {
sprintf(err, "External procedure %s not found\n", identifier); if (externalProcedureArgumentCount == 0) {
// TODO: Incomplete. // NOTE: Uninline.
// _interpretOutput(err); _setupExternalCall(program, externalProgram, externalProcedureAddress, 32);
return; memcpy(env, program->env, sizeof(env));
} _interpret(externalProgram, -1);
memcpy(externalProgram->env, env, sizeof(env));
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 { } else {
address = stackReadInt32(procedure_ptr, 16); sprintf(err, "External procedure cannot take arguments in interrupt context");
_interpretOutput(err);
_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;
} }
} else {
sprintf(err, "External procedure %s not found\n", procedureIdentifier);
_interpretOutput(err);
}
} else {
procedureAddress = stackReadInt32(procedurePtr, 16);
_interpret(v13, -1); // NOTE: Uninline.
_setupCall(program, procedureAddress, 24);
memcpy(v13->env, jmp_buf, sizeof(jmp_buf)); memcpy(env, program->env, sizeof(env));
_interpret(program, -1);
memcpy(program->env, env, sizeof(env));
}
} }
// 0x46DEE4 // 0x46DEE4
static void _doEvents() 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 // 0x46E10C
@ -2869,8 +2942,6 @@ static void programListNodeFree(ProgramListNode* programListNode)
// 0x46E154 // 0x46E154
void programListNodeCreate(Program* program) void programListNodeCreate(Program* program)
{ {
program->flags |= PROGRAM_FLAG_0x02;
ProgramListNode* programListNode = (ProgramListNode*)internal_malloc_safe(sizeof(*programListNode), __FILE__, __LINE__); // .\\int\\INTRPRET.C, 2907 ProgramListNode* programListNode = (ProgramListNode*)internal_malloc_safe(sizeof(*programListNode), __FILE__, __LINE__); // .\\int\\INTRPRET.C, 2907
programListNode->program = program; programListNode->program = program;
programListNode->next = gInterpreterProgramListHead; programListNode->next = gInterpreterProgramListHead;
@ -2883,6 +2954,33 @@ void programListNodeCreate(Program* program)
gInterpreterProgramListHead = programListNode; 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 // 0x46E1EC
void _updatePrograms() void _updatePrograms()
{ {
@ -2971,7 +3069,8 @@ void programStackPushValue(Program* program, ProgramValue& programValue)
program->stackValues->push_back(programValue); program->stackValues->push_back(programValue);
if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { 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(); program->stackValues->pop_back();
if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) {
programPopString(program, programValue.opcode, programValue.integerValue); _interpretDecStringRef(program, programValue.opcode, programValue.integerValue);
} }
return programValue; return programValue;
@ -3076,7 +3175,8 @@ void programReturnStackPushValue(Program* program, ProgramValue& programValue)
program->returnStackValues->push_back(programValue); program->returnStackValues->push_back(programValue);
if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { 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(); program->returnStackValues->pop_back();
if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) { if (programValue.opcode == VALUE_TYPE_DYNAMIC_STRING) {
programPopString(program, programValue.opcode, programValue.integerValue); _interpretDecStringRef(program, programValue.opcode, programValue.integerValue);
} }
return programValue; return programValue;

View File

@ -100,7 +100,9 @@ typedef enum ProgramFlags {
PROGRAM_FLAG_0x02 = 0x02, PROGRAM_FLAG_0x02 = 0x02,
PROGRAM_FLAG_0x04 = 0x04, PROGRAM_FLAG_0x04 = 0x04,
PROGRAM_FLAG_STOPPED = 0x08, 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_0x20 = 0x20,
PROGRAM_FLAG_0x40 = 0x40, PROGRAM_FLAG_0x40 = 0x40,
PROGRAM_FLAG_CRITICAL_SECTION = 0x80, PROGRAM_FLAG_CRITICAL_SECTION = 0x80,
@ -147,6 +149,9 @@ typedef struct ProgramValue {
typedef std::vector<ProgramValue> ProgramStack; typedef std::vector<ProgramValue> ProgramStack;
typedef struct Program Program;
typedef int(InterpretCheckWaitFunc)(Program* program);
// It's size in original code is 144 (0x8C) bytes due to the different // It's size in original code is 144 (0x8C) bytes due to the different
// size of `jmp_buf`. // size of `jmp_buf`.
typedef struct Program { typedef struct Program {
@ -162,10 +167,10 @@ typedef struct Program {
unsigned char* identifiers; unsigned char* identifiers;
unsigned char* procedures; unsigned char* procedures;
jmp_buf env; jmp_buf env;
int field_70; // end time of timer (field_74 + wait time) unsigned int waitEnd; // end time of timer (field_74 + wait time)
int field_74; // time when wait was called 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_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 flags; // flags
int windowId; int windowId;
bool exited; bool exited;
@ -173,6 +178,7 @@ typedef struct Program {
ProgramStack* returnStackValues; ProgramStack* returnStackValues;
} Program; } Program;
typedef unsigned int(InterpretTimerFunc)();
typedef void OpcodeHandler(Program* program); typedef void OpcodeHandler(Program* program);
extern int _TimeOut; extern int _TimeOut;
@ -181,7 +187,7 @@ char* _interpretMangleName(char* s);
void _interpretOutputFunc(int (*func)(char*)); void _interpretOutputFunc(int (*func)(char*));
int _interpretOutput(const char* format, ...); int _interpretOutput(const char* format, ...);
[[noreturn]] void programFatalError(const char* str, ...); [[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); Program* programCreateByPath(const char* path);
char* programGetString(Program* program, opcode_t opcode, int offset); char* programGetString(Program* program, opcode_t opcode, int offset);
char* programGetIdentifier(Program* program, int offset); char* programGetIdentifier(Program* program, int offset);
@ -189,10 +195,12 @@ int programPushString(Program* program, char* string);
void interpreterRegisterOpcodeHandlers(); void interpreterRegisterOpcodeHandlers();
void _interpretClose(); void _interpretClose();
void _interpret(Program* program, int a2); 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); 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 programListNodeCreate(Program* program);
void runProgram(Program* program);
Program* runScript(char* name);
void _updatePrograms(); void _updatePrograms();
void programListFree(); void programListFree();
void interpreterRegisterOpcode(int opcode, OpcodeHandler* handler); void interpreterRegisterOpcode(int opcode, OpcodeHandler* handler);

View File

@ -2025,7 +2025,7 @@ static void opMetarule3(Program* program)
} }
break; break;
case METARULE3_MARK_SUBTILE: case METARULE3_MARK_SUBTILE:
result.integerValue = _wmSubTileMarkRadiusVisited(param1.integerValue, param2.integerValue, param3.integerValue); result.integerValue = wmSubTileMarkRadiusVisited(param1.integerValue, param2.integerValue, param3.integerValue);
break; break;
case METARULE3_GET_KILL_COUNT: case METARULE3_GET_KILL_COUNT:
result.integerValue = killsGetByType(param1.integerValue); result.integerValue = killsGetByType(param1.integerValue);
@ -2694,7 +2694,7 @@ static void opGameDialogSystemEnter(Program* program)
return; return;
} }
if (_game_state_request(4) == -1) { if (_game_state_request(GAME_STATE_4) == -1) {
return; return;
} }

View File

@ -12,7 +12,6 @@
#include "select_file_list.h" #include "select_file_list.h"
#include "sound.h" #include "sound.h"
#include "text_font.h" #include "text_font.h"
#include "widget.h"
#include "window.h" #include "window.h"
#include "window_manager_private.h" #include "window_manager_private.h"
@ -33,7 +32,13 @@ static void opPrintRect(Program* program);
static void opSelect(Program* program); static void opSelect(Program* program);
static void opDisplay(Program* program); static void opDisplay(Program* program);
static void opDisplayRaw(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 opFadeIn(Program* program);
static void opFadeOut(Program* program); static void opFadeOut(Program* program);
static int intLibCheckMovie(Program* program); static int intLibCheckMovie(Program* program);
@ -60,6 +65,8 @@ static int intLibCheckDialog(Program* program);
static void opSayEnd(Program* program); static void opSayEnd(Program* program);
static void opSayGetLastPos(Program* program); static void opSayGetLastPos(Program* program);
static void opSayQuit(Program* program); static void opSayQuit(Program* program);
static int getTimeOut();
static void setTimeOut(int value);
static void opSayMessageTimeout(Program* program); static void opSayMessageTimeout(Program* program);
static void opSayMessage(Program* program); static void opSayMessage(Program* program);
static void opGotoXY(Program* program); static void opGotoXY(Program* program);
@ -388,9 +395,109 @@ void opDisplayRaw(Program* program)
} }
// 0x46222C // 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 // fadein
@ -403,7 +510,9 @@ void opFadeIn(Program* program)
_setSystemPalette(gIntLibFadePalette); _setSystemPalette(gIntLibFadePalette);
sub_46222C(gIntLibFadePalette, _cmap, 64, (float)data, 1); // NOTE: Uninline.
interpretFadeIn((float)data);
gIntLibIsPaletteFaded = true; gIntLibIsPaletteFaded = true;
program->flags &= ~PROGRAM_FLAG_0x20; program->flags &= ~PROGRAM_FLAG_0x20;
@ -420,7 +529,8 @@ void opFadeOut(Program* program)
bool cursorWasHidden = cursorIsHidden(); bool cursorWasHidden = cursorIsHidden();
mouseHideCursor(); mouseHideCursor();
sub_46222C(_getSystemPalette(), gIntLibFadePalette, 64, (float)data, 1); // NOTE: Uninline.
interpretFadeOut((float)data);
if (!cursorWasHidden) { if (!cursorWasHidden) {
mouseShowCursor(); mouseShowCursor();
@ -466,8 +576,8 @@ void opPlayMovie(Program* program)
_selectWindowID(program->windowId); _selectWindowID(program->windowId);
program->flags |= PROGRAM_FLAG_0x10; program->flags |= PROGRAM_IS_WAITING;
program->field_7C = intLibCheckMovie; program->checkWaitFunc = intLibCheckMovie;
char* mangledFileName = _interpretMangleName(gIntLibPlayMovieFileName); char* mangledFileName = _interpretMangleName(gIntLibPlayMovieFileName);
if (!_windowPlayMovie(mangledFileName)) { if (!_windowPlayMovie(mangledFileName)) {
@ -493,8 +603,8 @@ void opPlayMovieRect(Program* program)
_selectWindowID(program->windowId); _selectWindowID(program->windowId);
program->field_7C = intLibCheckMovie; program->checkWaitFunc = intLibCheckMovie;
program->flags |= PROGRAM_FLAG_0x10; program->flags |= PROGRAM_IS_WAITING;
char* mangledFileName = _interpretMangleName(gIntLibPlayMovieRectFileName); char* mangledFileName = _interpretMangleName(gIntLibPlayMovieRectFileName);
if (!_windowPlayMovieRect(mangledFileName, x, y, width, height)) { if (!_windowPlayMovieRect(mangledFileName, x, y, width, height)) {
@ -834,8 +944,8 @@ void opSayEnd(Program* program)
program->flags &= ~PROGRAM_FLAG_0x20; program->flags &= ~PROGRAM_FLAG_0x20;
if (rc == -2) { if (rc == -2) {
program->field_7C = intLibCheckDialog; program->checkWaitFunc = intLibCheckDialog;
program->flags |= PROGRAM_FLAG_0x10; 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 // saymessagetimeout
// 0x463838 // 0x463838
static void opSayMessageTimeout(Program* program) static void opSayMessageTimeout(Program* program)
@ -1307,7 +1433,7 @@ static void opSetFont(Program* program)
{ {
int data = programStackPopInteger(program); int data = programStackPopInteger(program);
if (!widgetSetFont(data)) { if (!windowSetFont(data)) {
programFatalError("Error setting font"); programFatalError("Error setting font");
} }
} }
@ -1318,7 +1444,7 @@ static void opSetTextFlags(Program* program)
{ {
int data = programStackPopInteger(program); int data = programStackPopInteger(program);
if (!widgetSetTextFlags(data)) { if (!windowSetTextFlags(data)) {
programFatalError("Error setting text flags"); programFatalError("Error setting text flags");
} }
} }
@ -1345,7 +1471,7 @@ static void opSetTextColor(Program* program)
float g = value[1].floatValue; float g = value[1].floatValue;
float b = value[0].floatValue; float b = value[0].floatValue;
if (!widgetSetTextColor(r, g, b)) { if (!windowSetTextColor(r, g, b)) {
programFatalError("Error setting text color"); programFatalError("Error setting text color");
} }
} }
@ -1426,7 +1552,7 @@ static void opSetHighlightColor(Program* program)
float g = value[1].floatValue; float g = value[1].floatValue;
float b = value[0].floatValue; float b = value[0].floatValue;
if (!widgetSetHighlightColor(r, g, b)) { if (!windowSetHighlightColor(r, g, b)) {
programFatalError("Error setting text highlight color"); programFatalError("Error setting text highlight color");
} }
} }

View File

@ -599,7 +599,7 @@ void inventoryOpen()
_display_body(-1, INVENTORY_WINDOW_TYPE_NORMAL); _display_body(-1, INVENTORY_WINDOW_TYPE_NORMAL);
if (_game_state() == 5) { if (_game_state() == GAME_STATE_5) {
break; break;
} }

View File

@ -70,7 +70,11 @@ typedef enum MainMenuOption {
} MainMenuOption; } MainMenuOption;
static bool falloutInit(int argc, char** argv); 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_load_new(char* fname);
static int main_loadgame_new();
static void main_unload_new();
static void mainLoop(FpsLimiter& fpsLimiter); static void mainLoop(FpsLimiter& fpsLimiter);
static void _main_selfrun_exit(); static void _main_selfrun_exit();
static void _main_selfrun_record(); static void _main_selfrun_record();
@ -85,6 +89,8 @@ static void mainMenuWindowHide(bool animate);
static void mainMenuWindowUnhide(bool animate); static void mainMenuWindowUnhide(bool animate);
static int _main_menu_is_enabled(); static int _main_menu_is_enabled();
static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter); static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter);
static int main_menu_fatal_error();
static void main_menu_play_sound(const char* fileName);
// 0x5194C8 // 0x5194C8
static char _mainMap[] = "artemple.map"; static char _mainMap[] = "artemple.map";
@ -236,9 +242,13 @@ int falloutMain(int argc, char** argv)
mainLoop(fpsLimiter); mainLoop(fpsLimiter);
paletteFadeTo(gPaletteWhite); paletteFadeTo(gPaletteWhite);
objectHide(gDude, NULL);
_map_exit(); // NOTE: Uninline.
gameReset(); main_unload_new();
// NOTE: Uninline.
main_reset_system();
if (_main_show_death_scene != 0) { if (_main_show_death_scene != 0) {
showDeath(); showDeath();
_main_show_death_scene = 0; _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); int win = windowCreate(0, 0, screenGetWidth(), screenGetHeight(), _colorTable[0], WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
mainMenuWindowHide(true); mainMenuWindowHide(true);
mainMenuWindowFree(); mainMenuWindowFree();
_game_user_wants_to_quit = 0;
gDude->flags &= ~OBJECT_FLAT; // NOTE: Uninline.
_main_show_death_scene = 0; main_loadgame_new();
objectShow(gDude, NULL);
mouseHideCursor();
_map_init();
gameMouseSetCursor(MOUSE_CURSOR_NONE);
mouseShowCursor();
colorPaletteLoad("color.pal"); colorPaletteLoad("color.pal");
paletteFadeTo(_cmap); paletteFadeTo(_cmap);
int loadGameRc = lsgLoadGame(LOAD_SAVE_MODE_FROM_MAIN_MENU); int loadGameRc = lsgLoadGame(LOAD_SAVE_MODE_FROM_MAIN_MENU);
@ -275,9 +281,13 @@ int falloutMain(int argc, char** argv)
if (win != -1) { if (win != -1) {
windowDestroy(win); windowDestroy(win);
} }
objectHide(gDude, NULL);
_map_exit(); // NOTE: Uninline.
gameReset(); main_unload_new();
// NOTE: Uninline.
main_reset_system();
if (_main_show_death_scene != 0) { if (_main_show_death_scene != 0) {
showDeath(); showDeath();
_main_show_death_scene = 0; _main_show_death_scene = 0;
@ -324,9 +334,8 @@ int falloutMain(int argc, char** argv)
} }
} }
backgroundSoundDelete(); // NOTE: Uninline.
_main_selfrun_exit(); main_exit_system();
gameExit();
autorunMutexClose(); autorunMutexClose();
@ -351,6 +360,29 @@ static bool falloutInit(int argc, char** argv)
return true; 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 // 0x480D4C
static int _main_load_new(char* mapFileName) static int _main_load_new(char* mapFileName)
{ {
@ -377,6 +409,34 @@ static int _main_load_new(char* mapFileName)
return 0; 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 // 0x480E48
static void mainLoop(FpsLimiter& fpsLimiter) static void mainLoop(FpsLimiter& fpsLimiter)
{ {
@ -461,14 +521,21 @@ static void _main_selfrun_record()
mainMenuWindowFree(); mainMenuWindowFree();
backgroundSoundDelete(); backgroundSoundDelete();
randomSeedPrerandom(0xBEEFFEED); randomSeedPrerandom(0xBEEFFEED);
gameReset();
// NOTE: Uninline.
main_reset_system();
_proto_dude_init("premade\\combat.gcd"); _proto_dude_init("premade\\combat.gcd");
_main_load_new(selfrunData.mapFileName); _main_load_new(selfrunData.mapFileName);
selfrunRecordingLoop(&selfrunData); selfrunRecordingLoop(&selfrunData);
paletteFadeTo(gPaletteWhite); paletteFadeTo(gPaletteWhite);
objectHide(gDude, NULL);
_map_exit(); // NOTE: Uninline.
gameReset(); main_unload_new();
// NOTE: Uninline.
main_reset_system();
mainMenuWindowInit(); mainMenuWindowInit();
if (_main_selfrun_list != NULL) { if (_main_selfrun_list != NULL) {
@ -491,14 +558,21 @@ static void _main_selfrun_play()
mainMenuWindowFree(); mainMenuWindowFree();
backgroundSoundDelete(); backgroundSoundDelete();
randomSeedPrerandom(0xBEEFFEED); randomSeedPrerandom(0xBEEFFEED);
gameReset();
// NOTE: Uninline.
main_reset_system();
_proto_dude_init("premade\\combat.gcd"); _proto_dude_init("premade\\combat.gcd");
_main_load_new(selfrunData.mapFileName); _main_load_new(selfrunData.mapFileName);
selfrunPlaybackLoop(&selfrunData); selfrunPlaybackLoop(&selfrunData);
paletteFadeTo(gPaletteWhite); paletteFadeTo(gPaletteWhite);
objectHide(gDude, NULL);
_map_exit(); // NOTE: Uninline.
gameReset(); main_unload_new();
// NOTE: Uninline.
main_reset_system();
mainMenuWindowInit(); mainMenuWindowInit();
} }
@ -747,8 +821,8 @@ static int mainMenuWindowInit()
0, 0,
WINDOW_HIDDEN | WINDOW_FLAG_0x04); WINDOW_HIDDEN | WINDOW_FLAG_0x04);
if (gMainMenuWindow == -1) { if (gMainMenuWindow == -1) {
mainMenuWindowFree(); // NOTE: Uninline.
return -1; return main_menu_fatal_error();
} }
gMainMenuWindowBuffer = windowGetBuffer(gMainMenuWindow); gMainMenuWindowBuffer = windowGetBuffer(gMainMenuWindow);
@ -757,8 +831,8 @@ static int mainMenuWindowInit()
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 140, 0, 0, 0); int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 140, 0, 0, 0);
gMainMenuBackgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &gMainMenuBackgroundFrmHandle); gMainMenuBackgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &gMainMenuBackgroundFrmHandle);
if (gMainMenuBackgroundFrmData == NULL) { if (gMainMenuBackgroundFrmData == NULL) {
mainMenuWindowFree(); // NOTE: Uninline.
return -1; return main_menu_fatal_error();
} }
blitBufferToBuffer(gMainMenuBackgroundFrmData, 640, 480, 640, gMainMenuWindowBuffer, 640); blitBufferToBuffer(gMainMenuBackgroundFrmData, 640, 480, 640, gMainMenuWindowBuffer, 640);
@ -803,16 +877,16 @@ static int mainMenuWindowInit()
fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0);
gMainMenuButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonUpFrmHandle); gMainMenuButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonUpFrmHandle);
if (gMainMenuButtonUpFrmData == NULL) { if (gMainMenuButtonUpFrmData == NULL) {
mainMenuWindowFree(); // NOTE: Uninline.
return -1; return main_menu_fatal_error();
} }
// menudown.frm // menudown.frm
fid = buildFid(OBJ_TYPE_INTERFACE, 300, 0, 0, 0); fid = buildFid(OBJ_TYPE_INTERFACE, 300, 0, 0, 0);
gMainMenuButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonDownFrmHandle); gMainMenuButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonDownFrmHandle);
if (gMainMenuButtonDownFrmData == NULL) { if (gMainMenuButtonDownFrmData == NULL) {
mainMenuWindowFree(); // NOTE: Uninline.
return -1; return main_menu_fatal_error();
} }
for (int index = 0; index < MAIN_MENU_BUTTON_COUNT; index++) { 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++) { 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); 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) { if (gMainMenuButtons[index] == -1) {
mainMenuWindowFree(); // NOTE: Uninline.
return -1; return main_menu_fatal_error();
} }
buttonSetMask(gMainMenuButtons[index], gMainMenuButtonUpFrmData); buttonSetMask(gMainMenuButtons[index], gMainMenuButtonUpFrmData);
@ -962,7 +1036,8 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter)
for (int buttonIndex = 0; buttonIndex < MAIN_MENU_BUTTON_COUNT; buttonIndex++) { for (int buttonIndex = 0; buttonIndex < MAIN_MENU_BUTTON_COUNT; buttonIndex++) {
if (keyCode == gMainMenuButtonKeyBindings[buttonIndex] || keyCode == toupper(gMainMenuButtonKeyBindings[buttonIndex])) { if (keyCode == gMainMenuButtonKeyBindings[buttonIndex] || keyCode == toupper(gMainMenuButtonKeyBindings[buttonIndex])) {
soundPlayFile("nmselec1"); // NOTE: Uninline.
main_menu_play_sound("nmselec1");
rc = _return_values[buttonIndex]; rc = _return_values[buttonIndex];
@ -987,7 +1062,8 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter)
continue; continue;
} else if (keyCode == 1111) { } else if (keyCode == 1111) {
if (!(mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT)) { if (!(mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT)) {
soundPlayFile("nmselec0"); // NOTE: Uninline.
main_menu_play_sound("nmselec0");
} }
continue; continue;
} }
@ -995,7 +1071,9 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter)
if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit == 3) { if (keyCode == KEY_ESCAPE || _game_user_wants_to_quit == 3) {
rc = MAIN_MENU_EXIT; rc = MAIN_MENU_EXIT;
soundPlayFile("nmselec1");
// NOTE: Uninline.
main_menu_play_sound("nmselec1");
break; break;
} else if (_game_user_wants_to_quit == 2) { } else if (_game_user_wants_to_quit == 2) {
_game_user_wants_to_quit = 0; _game_user_wants_to_quit = 0;
@ -1016,3 +1094,21 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter)
return rc; 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);
}

View File

@ -31,6 +31,7 @@ static void* memoryBlockMallocImpl(size_t size);
static void* memoryBlockReallocImpl(void* ptr, size_t size); static void* memoryBlockReallocImpl(void* ptr, size_t size);
static void memoryBlockFreeImpl(void* ptr); static void memoryBlockFreeImpl(void* ptr);
static void memoryBlockPrintStats(); static void memoryBlockPrintStats();
static void* mem_prep_block(void* block, size_t size);
static void memoryBlockValidate(void* block); static void memoryBlockValidate(void* block);
// 0x51DED0 // 0x51DED0
@ -81,12 +82,8 @@ static void* memoryBlockMallocImpl(size_t size)
unsigned char* block = (unsigned char*)malloc(size); unsigned char* block = (unsigned char*)malloc(size);
if (block != NULL) { if (block != NULL) {
MemoryBlockHeader* header = (MemoryBlockHeader*)block; // NOTE: Uninline.
header->size = size; ptr = mem_prep_block(block, size);
header->guard = MEMORY_BLOCK_HEADER_GUARD;
MemoryBlockFooter* footer = (MemoryBlockFooter*)(block + size - sizeof(MemoryBlockFooter));
footer->guard = MEMORY_BLOCK_FOOTER_GUARD;
gMemoryBlocksCurrentCount++; gMemoryBlocksCurrentCount++;
if (gMemoryBlocksCurrentCount > gMemoryBlockMaximumCount) { if (gMemoryBlocksCurrentCount > gMemoryBlockMaximumCount) {
@ -97,8 +94,6 @@ static void* memoryBlockMallocImpl(size_t size)
if (gMemoryBlocksCurrentSize > gMemoryBlocksMaximumSize) { if (gMemoryBlocksCurrentSize > gMemoryBlocksMaximumSize) {
gMemoryBlocksMaximumSize = gMemoryBlocksCurrentSize; 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); unsigned char* newBlock = (unsigned char*)realloc(block, size);
if (newBlock != NULL) { 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; gMemoryBlocksCurrentSize += size;
if (gMemoryBlocksCurrentSize > gMemoryBlocksMaximumSize) { if (gMemoryBlocksCurrentSize > gMemoryBlocksMaximumSize) {
gMemoryBlocksMaximumSize = gMemoryBlocksCurrentSize; gMemoryBlocksMaximumSize = gMemoryBlocksCurrentSize;
} }
ptr = newBlock + sizeof(MemoryBlockHeader); // NOTE: Uninline.
ptr = mem_prep_block(newBlock, size);
} else { } else {
if (size != 0) { if (size != 0) {
gMemoryBlocksCurrentSize += oldSize; 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. // Validates integrity of the memory block.
// //
// [block] is a pointer to the the memory block itself, not it's data. // [block] is a pointer to the the memory block itself, not it's data.

View File

@ -744,7 +744,7 @@ static void _script_chk_timed_events()
v1 = true; v1 = true;
} }
if (_game_state() != 4) { if (_game_state() != GAME_STATE_4) {
if (getTicksBetween(v0, _last_light_time) >= 30000) { if (getTicksBetween(v0, _last_light_time) >= 30000) {
_last_light_time = v0; _last_light_time = v0;
scriptsExecMapUpdateScripts(SCRIPT_PROC_MAP_UPDATE); scriptsExecMapUpdateScripts(SCRIPT_PROC_MAP_UPDATE);
@ -1308,7 +1308,8 @@ int scriptExecProc(int sid, int proc)
} }
script->action = 0; script->action = 0;
programListNodeCreate(program); // NOTE: Uninline.
runProgram(program);
_interpret(program, -1); _interpret(program, -1);
} }

View File

@ -48,6 +48,7 @@ typedef struct SkillDescription {
static void _show_skill_use_messages(Object* obj, int skill, Object* a3, int a4, int a5); static void _show_skill_use_messages(Object* obj, int skill, Object* a3, int a4, int a5);
static int skillGetFreeUsageSlot(int skill); static int skillGetFreeUsageSlot(int skill);
static int skill_use_slot_clear();
// Damage flags which can be repaired using "Repair" skill. // Damage flags which can be repaired using "Repair" skill.
// //
@ -152,7 +153,8 @@ int skillsInit()
gTaggedSkills[index] = -1; gTaggedSkills[index] = -1;
} }
memset(_timesSkillUsed, 0, sizeof(_timesSkillUsed)); // NOTE: Uninline.
skill_use_slot_clear();
return 0; return 0;
} }
@ -164,7 +166,8 @@ void skillsReset()
gTaggedSkills[index] = -1; gTaggedSkills[index] = -1;
} }
memset(_timesSkillUsed, 0, sizeof(_timesSkillUsed)); // NOTE: Uninline.
skill_use_slot_clear();
} }
// 0x4AA478 // 0x4AA478
@ -1172,6 +1175,15 @@ int skillUpdateLastUse(int skill)
return 0; return 0;
} }
// NOTE: Inlined.
//
// 0x4ABF24
int skill_use_slot_clear()
{
memset(_timesSkillUsed, 0, sizeof(_timesSkillUsed));
return 0;
}
// 0x4ABF3C // 0x4ABF3C
int skillsUsageSave(File* stream) int skillsUsageSave(File* stream)
{ {

View File

@ -1,17 +1,6 @@
#include "widget.h" #include "widget.h"
#include "color.h"
#include "text_font.h"
#include "window.h"
static void _showRegion(int a1); 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 // 0x66E6A0
static int _updateRegions[32]; static int _updateRegions[32];
@ -34,65 +23,6 @@ int _update_widgets()
return 1; 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 // 0x4B5998
void sub_4B5998(int win) void sub_4B5998(int win)
{ {

View File

@ -2,13 +2,6 @@
#define WIDGET_H #define WIDGET_H
int _update_widgets(); 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); void sub_4B5998(int win);
#endif /* WIDGET_H */ #endif /* WIDGET_H */

View File

@ -152,10 +152,10 @@ static int _yres;
// Highlight color (maybe r). // Highlight color (maybe r).
// //
// 0x672D8C // 0x672D8C
int _currentHighlightColorR; static int _currentHighlightColorR;
// 0x672D90 // 0x672D90
int gWidgetFont; static int gWidgetFont;
// 0x672D98 // 0x672D98
ButtonCallback* off_672D98; ButtonCallback* off_672D98;
@ -166,30 +166,101 @@ ButtonCallback* off_672D9C;
// Text color (maybe g). // Text color (maybe g).
// //
// 0x672DA0 // 0x672DA0
int _currentTextColorG; static int _currentTextColorG;
// text color (maybe b). // text color (maybe b).
// //
// 0x672DA4 // 0x672DA4
int _currentTextColorB; static int _currentTextColorB;
// 0x672DA8 // 0x672DA8
int gWidgetTextFlags; static int gWidgetTextFlags;
// Text color (maybe r) // Text color (maybe r)
// //
// 0x672DAC // 0x672DAC
int _currentTextColorR; static int _currentTextColorR;
// highlight color (maybe g) // highlight color (maybe g)
// //
// 0x672DB0 // 0x672DB0
int _currentHighlightColorG; static int _currentHighlightColorG;
// Highlight color (maybe b). // Highlight color (maybe b).
// //
// 0x672DB4 // 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 // 0x4B62E4
bool _checkRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent) 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 x = (int)(managedWindow->field_44 * managedWindow->field_54);
int y = (int)(managedWindow->field_48 * managedWindow->field_58); int y = (int)(managedWindow->field_48 * managedWindow->field_58);
// NOTE: Uses `add` at 0x4B810E, not bitwise `or`. // NOTE: Uses `add` at 0x4B810E, not bitwise `or`.
int flags = widgetGetTextColor() + widgetGetTextFlags(); int flags = windowGetTextColor() + windowGetTextFlags();
windowDrawText(managedWindow->window, string, 0, x, y, flags); windowDrawText(managedWindow->window, string, 0, x, y, flags);
return 1; return 1;
@ -1067,7 +1138,7 @@ bool _windowPrintRect(char* string, int a2, int textAlignment)
int height = windowGetHeight(managedWindow->window); int height = windowGetHeight(managedWindow->window);
int x = managedWindow->field_44; int x = managedWindow->field_44;
int y = managedWindow->field_48; int y = managedWindow->field_48;
int flags = widgetGetTextColor() | 0x2000000; int flags = windowGetTextColor() | 0x2000000;
_windowWrapLineWithSpacing(managedWindow->window, string, width, height, x, y, flags, textAlignment, 0); _windowWrapLineWithSpacing(managedWindow->window, string, width, height, x, y, flags, textAlignment, 0);
return true; 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) bool _windowFormatMessage(char* string, int x, int y, int width, int height, int textAlignment)
{ {
ManagedWindow* managedWindow = &(gManagedWindows[gCurrentManagedWindowIndex]); ManagedWindow* managedWindow = &(gManagedWindows[gCurrentManagedWindowIndex]);
int flags = widgetGetTextColor() | 0x2000000; int flags = windowGetTextColor() | 0x2000000;
_windowWrapLineWithSpacing(managedWindow->window, string, width, height, x, y, flags, textAlignment, 0); _windowWrapLineWithSpacing(managedWindow->window, string, width, height, x, y, flags, textAlignment, 0);
return true; return true;
@ -1812,7 +1883,7 @@ bool _windowAddButtonTextWithOffsets(const char* buttonName, const char* text, i
text, text,
normalImageWidth, normalImageWidth,
normalImageWidth, normalImageWidth,
widgetGetTextColor() + widgetGetTextFlags()); windowGetTextColor() + windowGetTextFlags());
blitBufferToBufferTrans(buffer, blitBufferToBufferTrans(buffer,
normalImageWidth, normalImageWidth,
@ -1860,7 +1931,7 @@ bool _windowAddButtonTextWithOffsets(const char* buttonName, const char* text, i
text, text,
pressedImageWidth, pressedImageWidth,
pressedImageWidth, pressedImageWidth,
widgetGetTextColor() + widgetGetTextFlags()); windowGetTextColor() + windowGetTextFlags());
blitBufferToBufferTrans(buffer, blitBufferToBufferTrans(buffer,
pressedImageWidth, pressedImageWidth,

View File

@ -34,15 +34,15 @@ typedef enum ManagedButtonRightMouseEvent {
MANAGED_BUTTON_RIGHT_MOUSE_EVENT_COUNT, MANAGED_BUTTON_RIGHT_MOUSE_EVENT_COUNT,
} ManagedButtonRightMouseEvent; } ManagedButtonRightMouseEvent;
extern int _currentHighlightColorR; int windowGetFont();
extern int gWidgetFont; int windowSetFont(int a1);
extern int _currentTextColorG; void windowResetTextAttributes();
extern int _currentTextColorB; int windowGetTextFlags();
extern int gWidgetTextFlags; int windowSetTextFlags(int a1);
extern int _currentTextColorR; unsigned char windowGetTextColor();
extern int _currentHighlightColorG; unsigned char windowGetHighlightColor();
extern int _currentHighlightColorB; 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 _checkRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent);
bool _windowCheckRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent); bool _windowCheckRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent);
bool _windowRefreshRegions(); bool _windowRefreshRegions();

View File

@ -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 int _GNW_check_buttons(Window* window, int* out_a2);
static bool _button_under_mouse(Button* button, Rect* rect); static bool _button_under_mouse(Button* button, Rect* rect);
static void buttonFree(Button* ptr); 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 _win_group_check_buttons(int a1, int* a2, int a3, void (*a4)(int));
static int _button_check_group(Button* button); static int _button_check_group(Button* button);
static void _button_draw(Button* button, Window* window, unsigned char* data, int a4, Rect* a5, int a6); 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; // NOTE: Uninline.
while (buttonGetButton(buttonId, NULL) != NULL) { int buttonId = button_new_id();
buttonId++;
}
button->id = buttonId; button->id = buttonId;
button->flags = flags; button->flags = flags;
@ -2183,6 +2182,21 @@ void buttonFree(Button* button)
internal_free(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 // 0x4D9474
int buttonEnable(int btn) int buttonEnable(int btn)
{ {

View File

@ -908,6 +908,7 @@ static int gEncounterTablesLength;
static bool gTownMapHotkeysFix; static bool gTownMapHotkeysFix;
static double gGameTimeIncRemainder = 0.0; static double gGameTimeIncRemainder = 0.0;
static void wmSetFlags(int* flagsPtr, int flag, int value);
static int _wmGenDataInit(); static int _wmGenDataInit();
static int _wmGenDataReset(); static int _wmGenDataReset();
static int _wmWorldMapSaveTempData(); 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 _wmMatchAreaFromMap(int a1, int* out_a2);
static int _wmWorldMapFunc(int a1); static int _wmWorldMapFunc(int a1);
static int _wmInterfaceCenterOnParty(); static int _wmInterfaceCenterOnParty();
static void wmCheckGameEvents();
static int _wmRndEncounterOccurred(); static int _wmRndEncounterOccurred();
static int _wmPartyFindCurSubTile(); static int _wmPartyFindCurSubTile();
static int _wmFindCurSubTileFromPos(int x, int y, SubtileInfo** subtile); 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 worldmapPerformTravel();
static void _wmInterfaceScrollTabsStart(int a1); static void _wmInterfaceScrollTabsStart(int a1);
static void _wmInterfaceScrollTabsStop(); static void _wmInterfaceScrollTabsStop();
static void wmInterfaceScrollTabsUpdate();
static int worldmapWindowInit(); static int worldmapWindowInit();
static int worldmapWindowFree(); 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 int worldmapWindowScroll(int a1, int a2, int a3, int a4, bool* a5, bool a6);
static void worldmapWindowHandleMouseScrolling(); 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 void _wmMarkSubTileRadiusVisited(int x, int y);
static int _wmTileGrabArt(int tile_index); static int _wmTileGrabArt(int tile_index);
static int worldmapWindowRefresh(); 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 worldmapWindowDimSubtile(TileInfo* tileInfo, int a2, int a3, int a4, int a5, int a6);
static int _wmDrawCursorStopped(); static int _wmDrawCursorStopped();
static bool _wmCursorIsVisible(); static bool _wmCursorIsVisible();
static int wmGetAreaName(CityInfo* city, char* name);
static int wmAreaMarkVisited(int cityIndex);
static void _wmMarkAllSubTiles(int a1); static void _wmMarkAllSubTiles(int a1);
static int worldmapCityMapViewSelect(int* mapIndexPtr); static int worldmapCityMapViewSelect(int* mapIndexPtr);
static int worldmapCityMapViewInit(); static int worldmapCityMapViewInit();
@ -993,7 +1001,9 @@ static void worldmapWindowRenderCarFuelBar();
static int worldmapRenderQuickDestinations(); static int worldmapRenderQuickDestinations();
static int _wmMakeTabsLabelList(int** out_cities, int* out_len); static int _wmMakeTabsLabelList(int** out_cities, int* out_len);
static int worldmapCompareCitiesByName(const void* a1, const void* a2); static int worldmapCompareCitiesByName(const void* a1, const void* a2);
static int wmFreeTabsLabelList(int** quickDestinationsListPtr, int* quickDestinationsLengthPtr);
static void worldmapWindowRenderDial(bool shouldRefreshWindow); static void worldmapWindowRenderDial(bool shouldRefreshWindow);
static void wmInterfaceDialSyncTime(bool shouldRefreshWindow);
static int _wmAreaFindFirstValidMap(int* out_a1); static int _wmAreaFindFirstValidMap(int* out_a1);
static inline bool cityIsValid(int city) static inline bool cityIsValid(int city)
@ -1001,6 +1011,16 @@ static inline bool cityIsValid(int city)
return city >= 0 && city < gCitiesLength; return city >= 0 && city < gCitiesLength;
} }
// 0x4BC890
static void wmSetFlags(int* flagsPtr, int flag, int value)
{
if (value) {
*flagsPtr |= flag;
} else {
*flagsPtr &= ~flag;
}
}
// wmWorldMap_init // wmWorldMap_init
// 0x4BC89C // 0x4BC89C
int worldmapInit() int worldmapInit()
@ -2906,11 +2926,8 @@ int _wmMapInit()
return -1; return -1;
} }
if (num) { // NOTE: Uninline.
map->flags |= MAP_SAVED; wmSetFlags(&(map->flags), MAP_SAVED, num);
} else {
map->flags &= ~MAP_SAVED;
}
} }
if (configGetString(&config, section, "dead_bodies_age", &str)) { if (configGetString(&config, section, "dead_bodies_age", &str)) {
@ -2918,11 +2935,8 @@ int _wmMapInit()
return -1; return -1;
} }
if (num) { // NOTE: Uninline.
map->flags |= MAP_DEAD_BODIES_AGE; wmSetFlags(&(map->flags), MAP_DEAD_BODIES_AGE, num);
} else {
map->flags &= ~MAP_DEAD_BODIES_AGE;
}
} }
if (configGetString(&config, section, "can_rest_here", &str)) { if (configGetString(&config, section, "can_rest_here", &str)) {
@ -2930,31 +2944,22 @@ int _wmMapInit()
return -1; return -1;
} }
if (num) { // NOTE: Uninline.
map->flags |= MAP_CAN_REST_ELEVATION_0; wmSetFlags(&(map->flags), MAP_CAN_REST_ELEVATION_0, num);
} else {
map->flags &= ~MAP_CAN_REST_ELEVATION_0;
}
if (strParseStrFromList(&str, &num, _wmYesNoStrs, 2) == -1) { if (strParseStrFromList(&str, &num, _wmYesNoStrs, 2) == -1) {
return -1; return -1;
} }
if (num) { // NOTE: Uninline.
map->flags |= MAP_CAN_REST_ELEVATION_1; wmSetFlags(&(map->flags), MAP_CAN_REST_ELEVATION_1, num);
} else {
map->flags &= ~MAP_CAN_REST_ELEVATION_1;
}
if (strParseStrFromList(&str, &num, _wmYesNoStrs, 2) == -1) { if (strParseStrFromList(&str, &num, _wmYesNoStrs, 2) == -1) {
return -1; return -1;
} }
if (num) { // NOTE: Uninline.
map->flags |= MAP_CAN_REST_ELEVATION_2; wmSetFlags(&(map->flags), MAP_CAN_REST_ELEVATION_2, num);
} else {
map->flags &= ~MAP_CAN_REST_ELEVATION_2;
}
} }
if (configGetString(&config, section, "pipboy_active", &str)) { if (configGetString(&config, section, "pipboy_active", &str)) {
@ -2962,11 +2967,8 @@ int _wmMapInit()
return -1; return -1;
} }
if (num) { // NOTE: Uninline.
map->flags |= MAP_PIPBOY_ACTIVE; wmSetFlags(&(map->flags), MAP_PIPBOY_ACTIVE, num);
} else {
map->flags &= ~MAP_PIPBOY_ACTIVE;
}
} }
// SFALL: Pip-boy automaps patch. // SFALL: Pip-boy automaps patch.
@ -3129,7 +3131,8 @@ int _wmMapMarkVisited(int mapIndex)
return -1; return -1;
} }
_wmAreaMarkVisitedState(cityIndex, 2); // NOTE: Uninline.
wmAreaMarkVisited(cityIndex);
return 0; return 0;
} }
@ -3257,7 +3260,8 @@ int _wmWorldMapFunc(int a1)
showQuitConfirmationDialog(); showQuitConfirmationDialog();
} }
_scriptsCheckGameEvents(NULL, gWorldmapWindow); // NOTE: Uninline.
wmCheckGameEvents();
if (_game_user_wants_to_quit != 0) { if (_game_user_wants_to_quit != 0) {
break; break;
@ -3420,20 +3424,8 @@ int _wmWorldMapFunc(int a1)
} }
} }
if (_tabsOffset) { // NOTE: Uninline.
_LastTabsYOffset += _tabsOffset; wmInterfaceScrollTabsUpdate();
worldmapWindowRenderChrome(true);
if (_tabsOffset > -1) {
if (dword_672F54 <= _LastTabsYOffset) {
_wmInterfaceScrollTabsStop();
}
} else {
if (dword_672F54 >= _LastTabsYOffset) {
_wmInterfaceScrollTabsStop();
}
}
}
if (keyCode == KEY_UPPERCASE_T || keyCode == KEY_LOWERCASE_T) { if (keyCode == KEY_UPPERCASE_T || keyCode == KEY_LOWERCASE_T) {
if (!gWorldmapIsTravelling && _WorldMapCurrArea != -1) { if (!gWorldmapIsTravelling && _WorldMapCurrArea != -1) {
@ -3455,13 +3447,17 @@ int _wmWorldMapFunc(int a1)
} else if (keyCode == KEY_HOME) { } else if (keyCode == KEY_HOME) {
_wmInterfaceCenterOnParty(); _wmInterfaceCenterOnParty();
} else if (keyCode == KEY_ARROW_UP) { } 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) { } 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) { } 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) { } 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) { } else if (keyCode == KEY_CTRL_ARROW_UP) {
_wmInterfaceScrollTabsStart(-27); _wmInterfaceScrollTabsStart(-27);
} else if (keyCode == KEY_CTRL_ARROW_DOWN) { } else if (keyCode == KEY_CTRL_ARROW_DOWN) {
@ -3564,6 +3560,14 @@ int _wmInterfaceCenterOnParty()
return 0; return 0;
} }
// NOTE: Inlined.
//
// 0x4C0624
static void wmCheckGameEvents()
{
_scriptsCheckGameEvents(NULL, gWorldmapWindow);
}
// 0x4C0634 // 0x4C0634
int _wmRndEncounterOccurred() int _wmRndEncounterOccurred()
{ {
@ -4442,14 +4446,8 @@ bool _wmGameTimeIncrement(int ticksToAdd)
gameTimeAddTicks(v1); gameTimeAddTicks(v1);
int hour = gameTimeGetHour() / 100; // NOTE: Uninline.
wmInterfaceDialSyncTime(true);
int frameCount = artGetFrameCount(gWorldmapDialFrm);
int frame = (hour + 12) % frameCount;
if (gWorldmapDialFrmCurrentFrame != frame) {
gWorldmapDialFrmCurrentFrame = frame;
worldmapWindowRenderDial(true);
}
worldmapWindowRenderDate(true); worldmapWindowRenderDate(true);
@ -4672,23 +4670,8 @@ void _wmInterfaceScrollTabsStart(int a1)
L11: L11:
if (!_tabsOffset) { // NOTE: Uninline.
return; wmInterfaceScrollTabsUpdate();
}
_LastTabsYOffset += _tabsOffset;
worldmapWindowRenderChrome(true);
if (_tabsOffset > -1) {
if (dword_672F54 > _LastTabsYOffset) {
return;
}
} else if (dword_672F54 < _LastTabsYOffset) {
return;
}
_wmInterfaceScrollTabsStop();
} }
// 0x4C2270 // 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 // 0x4C2324
int worldmapWindowInit() int worldmapWindowInit()
{ {
@ -5265,12 +5271,8 @@ int worldmapWindowFree()
fontSetCurrent(_fontnum); fontSetCurrent(_fontnum);
if (gQuickDestinations != NULL) { // NOTE: Uninline.
internal_free(gQuickDestinations); wmFreeTabsLabelList(&gQuickDestinations, &gQuickDestinationsLength);
gQuickDestinations = NULL;
}
gQuickDestinationsLength = 0;
_wmInterfaceWasInitialized = 0; _wmInterfaceWasInitialized = 0;
@ -5279,6 +5281,14 @@ int worldmapWindowFree()
return 0; 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 // 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 // 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 // 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(); unsigned int tick = _get_bk_time();
if (getTicksBetween(tick, _lastTime_2) > 50) { if (getTicksBetween(tick, _lastTime_2) > 50) {
_lastTime_2 = _get_bk_time(); _lastTime_2 = _get_bk_time();
worldmapWindowScroll(20, 20, dx, dy, &_couldScroll, true); // NOTE: Uninline.
wmInterfaceScroll(dx, dy, &_couldScroll);
} }
if (!_couldScroll) { if (!_couldScroll) {
@ -5424,59 +5435,75 @@ void worldmapWindowHandleMouseScrolling()
} }
} }
// 0x4C3434 // NOTE: Inlined.
int _wmMarkSubTileOffsetVisitedFunc(int a1, int a2, int a3, int a4, int a5, int a6) //
// 0x4C340C
static int wmMarkSubTileOffsetVisited(int tile, int subtileX, int subtileY, int offsetX, int offsetY)
{ {
int v7; return wmMarkSubTileOffsetVisitedFunc(tile, subtileX, subtileY, offsetX, offsetY, SUBTILE_STATE_VISITED);
int v8; }
int v9;
int* v;
v7 = a2 + a4; // NOTE: Inlined.
v8 = a1; //
v9 = a3 + a5; // 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) { // 0x4C3434
if (v7 >= 7) { static int wmMarkSubTileOffsetVisitedFunc(int tile, int subtileX, int subtileY, int offsetX, int offsetY, int subtileState)
if (a1 % gWorldmapGridWidth == gWorldmapGridWidth - 1) { {
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; return -1;
} }
v8 = a1 + 1; actualTile = tile + 1;
v7 %= 7; actualSubtileX %= SUBTILE_GRID_WIDTH;
} }
} else { } else {
if (!(a1 % gWorldmapGridWidth)) { if (!(tile % gWorldmapGridWidth)) {
return -1; return -1;
} }
v7 += 7; actualSubtileX += SUBTILE_GRID_WIDTH;
v8 = a1 - 1; actualTile = tile - 1;
} }
if (v9 >= 0) { if (actualSubtileY >= 0) {
if (v9 >= 6) { if (actualSubtileY >= SUBTILE_GRID_HEIGHT) {
if (v8 > gWorldmapTilesLength - gWorldmapGridWidth - 1) { if (actualTile > gWorldmapTilesLength - gWorldmapGridWidth - 1) {
return -1; return -1;
} }
v8 += gWorldmapGridWidth; actualTile += gWorldmapGridWidth;
v9 %= 6; actualSubtileY %= SUBTILE_GRID_HEIGHT;
} }
} else { } else {
if (v8 < gWorldmapGridWidth) { if (actualTile < gWorldmapGridWidth) {
return -1; return -1;
} }
v9 += 6; actualSubtileY += SUBTILE_GRID_HEIGHT;
v8 -= gWorldmapGridWidth; actualTile -= gWorldmapGridWidth;
} }
TileInfo* tile = &(gWorldmapTiles[v8]); tileInfo = &(gWorldmapTiles[actualTile]);
SubtileInfo* subtile = &(tile->subtiles[v9][v7]); subtileInfo = &(tileInfo->subtiles[actualSubtileY][actualSubtileX]);
v = &(subtile->state); if (subtileState != SUBTILE_STATE_KNOWN || subtileInfo->state == SUBTILE_STATE_UNKNOWN) {
if (a6 != 1 || *v == 0) { subtileInfo->state = subtileState;
*v = a6;
} }
return 0; return 0;
@ -5491,43 +5518,50 @@ void _wmMarkSubTileRadiusVisited(int x, int y)
radius = 2; radius = 2;
} }
_wmSubTileMarkRadiusVisited(x, y, radius); wmSubTileMarkRadiusVisited(x, y, radius);
} }
// Mark worldmap tile as visible?/visited?
//
// 0x4C35A8 // 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; tile = x / WM_TILE_WIDTH % gWorldmapGridWidth + y / WM_TILE_HEIGHT * gWorldmapGridWidth;
v4 = x % WM_TILE_WIDTH / WM_SUBTILE_SIZE; subtileX = x % WM_TILE_WIDTH / WM_SUBTILE_SIZE;
v5 = y % WM_TILE_HEIGHT / WM_SUBTILE_SIZE; subtileY = y % WM_TILE_HEIGHT / WM_SUBTILE_SIZE;
for (int i = -radius; i <= radius; i++) { for (offsetY = -radius; offsetY <= radius; offsetY++) {
for (int v6 = -radius; v6 <= radius; v6++) { for (offsetX = -radius; offsetX <= radius; offsetX++) {
_wmMarkSubTileOffsetVisitedFunc(tile, v4, v5, v6, i, SUBTILE_STATE_KNOWN); // 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; subtile->state = SUBTILE_STATE_VISITED;
switch (subtile->field_4) { switch (subtile->field_4) {
case 2: case 2:
while (v5-- > 0) { while (subtileY-- > 0) {
_wmMarkSubTileOffsetVisitedFunc(tile, v4, 0, v5, 0, SUBTILE_STATE_VISITED); // NOTE: Uninline.
wmMarkSubTileOffsetVisited(tile, subtileX, subtileY, 0, 0);
} }
break; break;
case 4: case 4:
while (v4-- > -1) { while (subtileX-- >= 0) {
_wmMarkSubTileOffsetVisitedFunc(tile, v4, 0, v5, 0, SUBTILE_STATE_VISITED); // NOTE: Uninline.
wmMarkSubTileOffsetVisited(tile, subtileX, subtileY, 0, 0);
} }
if (tile % gWorldmapGridWidth > 0) { if (tile % gWorldmapGridWidth > 0) {
for (int i = 0; i < 7; i++) { for (subtileX = 0; subtileX < SUBTILE_GRID_WIDTH; subtileX++) {
_wmMarkSubTileOffsetVisitedFunc(tile - 1, i + 1, v5, 0, 0, SUBTILE_STATE_VISITED); // NOTE: Uninline.
wmMarkSubTileOffsetVisited(tile - 1, subtileX, subtileY, 0, 0);
} }
} }
break; break;
@ -5818,18 +5852,20 @@ int worldmapWindowRenderCity(CityInfo* city, CitySizeDescription* citySizeDescri
int maxY = 464 - fontGetLineHeight(); int maxY = 464 - fontGetLineHeight();
if (nameY < maxY) { if (nameY < maxY) {
MessageListItem messageListItem; MessageListItem messageListItem;
const char* name; char name[40];
if (_wmAreaIsKnown(city->field_28)) { if (_wmAreaIsKnown(city->field_28)) {
name = getmsg(&gMapMessageList, &messageListItem, 1500 + city->field_28); // NOTE: Uninline.
wmGetAreaName(city, name);
} else { } else {
name = getmsg(&gWorldmapMessageList, &messageListItem, 1004); strncpy(name, getmsg(&gWorldmapMessageList, &messageListItem, 1004), 40);
} }
char text[40]; int width = fontGetStringWidth(name);
strncpy(text, name, 40); fontDrawText(dest + WM_WINDOW_WIDTH * nameY + x + citySizeDescription->width / 2 - width / 2,
name,
int width = fontGetStringWidth(text); width,
fontDrawText(dest + WM_WINDOW_WIDTH * nameY + x + citySizeDescription->width / 2 - width / 2, text, width, WM_WINDOW_WIDTH, _colorTable[992]); WM_WINDOW_WIDTH,
_colorTable[992]);
} }
return 0; return 0;
@ -5957,6 +5993,19 @@ bool _wmCursorIsVisible()
&& _world_ypos < gWorldmapOffsetY + WM_VIEW_HEIGHT; && _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. // Copy city short name.
// //
// 0x4C450C // 0x4C450C
@ -6027,6 +6076,12 @@ bool _wmMapIsKnown(int mapIndex)
return true; return true;
} }
// 0x4C4624
static int wmAreaMarkVisited(int cityIndex)
{
return _wmAreaMarkVisitedState(cityIndex, CITY_STATE_VISITED);
}
// 0x4C4634 // 0x4C4634
bool _wmAreaMarkVisitedState(int cityIndex, int a2) bool _wmAreaMarkVisitedState(int cityIndex, int a2)
{ {
@ -6569,15 +6624,8 @@ int worldmapWindowRenderChrome(bool shouldRefreshWindow)
worldmapRenderQuickDestinations(); worldmapRenderQuickDestinations();
int v1 = gameTimeGetHour(); // NOTE: Uninline.
v1 /= 100; wmInterfaceDialSyncTime(false);
int frameCount = artGetFrameCount(gWorldmapDialFrm);
int newFrame = (v1 + 12) % frameCount;
if (gWorldmapDialFrmCurrentFrame != newFrame) {
gWorldmapDialFrmCurrentFrame = newFrame;
worldmapWindowRenderDial(false);
}
worldmapWindowRenderDial(false); worldmapWindowRenderDial(false);
@ -6761,13 +6809,8 @@ int _wmMakeTabsLabelList(int** quickDestinationsPtr, int* quickDestinationsLengt
{ {
int* quickDestinations = *quickDestinationsPtr; int* quickDestinations = *quickDestinationsPtr;
if (quickDestinations != NULL) { // NOTE: Uninline.
internal_free(quickDestinations); wmFreeTabsLabelList(quickDestinationsPtr, quickDestinationsLengthPtr);
quickDestinations = NULL;
}
*quickDestinationsPtr = NULL;
*quickDestinationsLengthPtr = 0;
int capacity = 10; int capacity = 10;
@ -6816,6 +6859,21 @@ int worldmapCompareCitiesByName(const void* a1, const void* a2)
return compat_stricmp(city1->name, city2->name); 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 // 0x4C5734
void worldmapWindowRenderDial(bool shouldRefreshWindow) 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 // 0x4C5804
int _wmAreaFindFirstValidMap(int* out_a1) int _wmAreaFindFirstValidMap(int* out_a1)
{ {

View File

@ -246,7 +246,7 @@ void _wmWorldMap();
int _wmCheckGameAreaEvents(); int _wmCheckGameAreaEvents();
int worldmapSetupRandomEncounter(); int worldmapSetupRandomEncounter();
bool _wmEvalTileNumForPlacement(int tile); 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 _wmSubTileGetVisitedState(int a1, int a2, int* a3);
int _wmGetAreaIdxName(int index, char* name); int _wmGetAreaIdxName(int index, char* name);
bool _wmAreaIsKnown(int city_index); bool _wmAreaIsKnown(int city_index);