Reconcile with reference edition (#100)
This commit is contained in:
parent
39057fd1fb
commit
e41a4b8e16
|
@ -170,6 +170,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
|
|||
"src/palette.h"
|
||||
"src/party_member.cc"
|
||||
"src/party_member.h"
|
||||
"src/pcx.cc"
|
||||
"src/pcx.h"
|
||||
"src/perk_defs.h"
|
||||
"src/perk.cc"
|
||||
"src/perk.h"
|
||||
|
|
505
src/actions.cc
505
src/actions.cc
File diff suppressed because it is too large
Load Diff
|
@ -16,7 +16,7 @@ bool _can_see(Object* a1, Object* a2);
|
|||
bool _action_explode_running();
|
||||
int actionExplode(int tile, int elevation, int minDamage, int maxDamage, Object* a5, bool a6);
|
||||
int actionTalk(Object* a1, Object* a2);
|
||||
void _action_dmg(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor);
|
||||
void actionDamage(int tile, int elevation, int minDamage, int maxDamage, int damageType, bool animated, bool bypassArmor);
|
||||
bool actionCheckPush(Object* a1, Object* a2);
|
||||
int actionPush(Object* a1, Object* a2);
|
||||
int _action_can_talk_to(Object* a1, Object* a2);
|
||||
|
|
1348
src/animation.cc
1348
src/animation.cc
File diff suppressed because it is too large
Load Diff
|
@ -3,36 +3,14 @@
|
|||
|
||||
#include "combat_defs.h"
|
||||
#include "obj_types.h"
|
||||
#include "sound.h"
|
||||
|
||||
typedef enum AnimKind {
|
||||
ANIM_KIND_OBJ_MOVE_TO_OBJ = 0,
|
||||
ANIM_KIND_OBJ_MOVE_TO_TILE = 1,
|
||||
ANIM_KIND_2 = 2,
|
||||
ANIM_KIND_KNOCKDOWN = 3,
|
||||
ANIM_KIND_ANIMATE = 4,
|
||||
ANIM_KIND_ANIMATE_REVERSE = 5,
|
||||
ANIM_KIND_6 = 6,
|
||||
ANIM_KIND_SET_ROTATION_TO_TILE = 7,
|
||||
ANIM_KIND_ROTATE_CLOCKWISE = 8,
|
||||
ANIM_KIND_ROTATE_COUNTER_CLOCKWISE = 9,
|
||||
ANIM_KIND_HIDE = 10,
|
||||
ANIM_KIND_EXEC = 11,
|
||||
ANIM_KIND_EXEC_2 = 12,
|
||||
ANIM_KIND_14 = 14,
|
||||
ANIM_KIND_15 = 15,
|
||||
ANIM_KIND_16 = 16,
|
||||
ANIM_KIND_17 = 17,
|
||||
ANIM_KIND_18 = 18,
|
||||
ANIM_KIND_19 = 19,
|
||||
ANIM_KIND_20 = 20,
|
||||
ANIM_KIND_23 = 23,
|
||||
ANIM_KIND_24 = 24,
|
||||
ANIM_KIND_ANIMATE_FOREVER = 25,
|
||||
ANIM_KIND_26 = 26,
|
||||
ANIM_KIND_27 = 27,
|
||||
ANIM_KIND_28 = 28,
|
||||
} AnimKind;
|
||||
typedef enum AnimationRequestOptions {
|
||||
ANIMATION_REQUEST_UNRESERVED = 0x01,
|
||||
ANIMATION_REQUEST_RESERVED = 0x02,
|
||||
ANIMATION_REQUEST_NO_STAND = 0x04,
|
||||
ANIMATION_REQUEST_0x100 = 0x100,
|
||||
ANIMATION_REQUEST_INSIGNIFICANT = 0x200,
|
||||
} AnimationRequestOptions;
|
||||
|
||||
// Basic animations: 0-19
|
||||
// Knockdown and death: 20-35
|
||||
|
@ -112,9 +90,13 @@ typedef enum AnimationType {
|
|||
LAST_SF_DEATH_ANIM = ANIM_FALL_FRONT_BLOOD_SF,
|
||||
} AnimationType;
|
||||
|
||||
typedef int AnimationProc(Object*, Object*);
|
||||
typedef int AnimationSoundProc(Sound*);
|
||||
typedef int AnimationProc2(Object*, Object*, void*);
|
||||
#define FID_ANIM_TYPE(value) ((value) & 0xFF0000) >> 16
|
||||
|
||||
// Signature of animation callback accepting 2 parameters.
|
||||
typedef int(AnimationCallback)(void* a1, void* a2);
|
||||
|
||||
// Signature of animation callback accepting 3 parameters.
|
||||
typedef int(AnimationCallback3)(void* a1, void* a2, void* a3);
|
||||
|
||||
typedef struct STRUCT_530014_28 {
|
||||
int tile;
|
||||
|
@ -133,28 +115,31 @@ int _register_priority(int a1);
|
|||
int reg_anim_clear(Object* a1);
|
||||
int reg_anim_end();
|
||||
int animationIsBusy(Object* a1);
|
||||
int reg_anim_obj_move_to_obj(Object* a1, Object* a2, int actionPoints, int delay);
|
||||
int reg_anim_obj_run_to_obj(Object* owner, Object* destination, int actionPoints, int delay);
|
||||
int reg_anim_obj_move_to_tile(Object* obj, int tile_num, int elev, int actionPoints, int delay);
|
||||
int reg_anim_obj_run_to_tile(Object* obj, int tile_num, int elev, int actionPoints, int delay);
|
||||
int reg_anim_2(Object* obj, int tile_num, int elev, int a4, int a5);
|
||||
int reg_anim_knockdown(Object* obj, int tile, int elev, int anim, int delay);
|
||||
int reg_anim_animate(Object* obj, int anim, int delay);
|
||||
int reg_anim_animate_reverse(Object* obj, int anim, int delay);
|
||||
int reg_anim_6(Object* obj, int anim, int delay);
|
||||
int reg_anim_set_rotation_to_tile(Object* owner, int tile);
|
||||
int reg_anim_rotate_clockwise(Object* obj);
|
||||
int reg_anim_rotate_counter_clockwise(Object* obj);
|
||||
int reg_anim_hide(Object* obj);
|
||||
int reg_anim_11_0(Object* a1, Object* a2, AnimationProc* proc, int delay);
|
||||
int reg_anim_12(Object* a1, Object* a2, void* a3, AnimationProc2* proc, int delay);
|
||||
int reg_anim_11_1(Object* a1, Object* a2, AnimationProc* proc, int delay);
|
||||
int reg_anim_15(Object* obj, int a2, int a3);
|
||||
int reg_anim_17(Object* obj, int fid, int a3);
|
||||
int reg_anim_18(Object* obj, int a2, int a3);
|
||||
int reg_anim_update_light(Object* obj, int fid, int a3);
|
||||
int reg_anim_play_sfx(Object* obj, const char* a2, int a3);
|
||||
int reg_anim_animate_forever(Object* obj, int a2, int a3);
|
||||
int animationRegisterMoveToObject(Object* owner, Object* destination, int actionPoints, int delay);
|
||||
int animationRegisterRunToObject(Object* owner, Object* destination, int actionPoints, int delay);
|
||||
int animationRegisterMoveToTile(Object* owner, int tile, int elevation, int actionPoints, int delay);
|
||||
int animationRegisterRunToTile(Object* owner, int tile, int elevation, int actionPoints, int delay);
|
||||
int animationRegisterMoveToTileStraight(Object* object, int tile, int elevation, int anim, int delay);
|
||||
int animationRegisterMoveToTileStraightAndWaitForComplete(Object* owner, int tile, int elev, int anim, int delay);
|
||||
int animationRegisterAnimate(Object* owner, int anim, int delay);
|
||||
int animationRegisterAnimateReversed(Object* owner, int anim, int delay);
|
||||
int animationRegisterAnimateAndHide(Object* owner, int anim, int delay);
|
||||
int animationRegisterRotateToTile(Object* owner, int tile);
|
||||
int animationRegisterRotateClockwise(Object* owner);
|
||||
int animationRegisterRotateCounterClockwise(Object* owner);
|
||||
int animationRegisterHideObject(Object* object);
|
||||
int animationRegisterHideObjectForced(Object* object);
|
||||
int animationRegisterCallback(void* a1, void* a2, AnimationCallback* proc, int delay);
|
||||
int animationRegisterCallback3(void* a1, void* a2, void* a3, AnimationCallback3* proc, int delay);
|
||||
int animationRegisterCallbackForced(void* a1, void* a2, AnimationCallback* proc, int delay);
|
||||
int animationRegisterSetFlag(Object* object, int flag, int delay);
|
||||
int animationRegisterUnsetFlag(Object* object, int flag, int delay);
|
||||
int animationRegisterSetFid(Object* owner, int fid, int delay);
|
||||
int animationRegisterTakeOutWeapon(Object* owner, int weaponAnimationCode, int delay);
|
||||
int animationRegisterSetLightDistance(Object* owner, int lightDistance, int delay);
|
||||
int animationRegisterToggleOutline(Object* object, bool outline, int delay);
|
||||
int animationRegisterPlaySoundEffect(Object* owner, const char* soundEffectName, int delay);
|
||||
int animationRegisterAnimateForever(Object* owner, int anim, int delay);
|
||||
int reg_anim_26(int a1, int a2);
|
||||
int _make_path(Object* object, int from, int to, unsigned char* a4, int a5);
|
||||
int pathfinderFindPath(Object* object, int from, int to, unsigned char* rotations, int a5, PathBuilderCallback* callback);
|
||||
|
|
457
src/art.cc
457
src/art.cc
|
@ -3,6 +3,7 @@
|
|||
#include "animation.h"
|
||||
#include "debug.h"
|
||||
#include "draw.h"
|
||||
#include "game.h"
|
||||
#include "game_config.h"
|
||||
#include "memory.h"
|
||||
#include "object.h"
|
||||
|
@ -126,10 +127,8 @@ static int* gArtCritterFidShoudRunData;
|
|||
int artInit()
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
int i;
|
||||
File* stream;
|
||||
char str[200];
|
||||
char *ptr, *curr;
|
||||
char string[200];
|
||||
|
||||
int cacheSize;
|
||||
if (!configGetInt(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_ART_CACHE_SIZE_KEY, &cacheSize)) {
|
||||
|
@ -147,20 +146,20 @@ int artInit()
|
|||
gArtLanguageInitialized = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < 11; i++) {
|
||||
gArtListDescriptions[i].flags = 0;
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[i].name, gArtListDescriptions[i].name);
|
||||
for (int objectType = 0; objectType < OBJ_TYPE_COUNT; objectType++) {
|
||||
gArtListDescriptions[objectType].flags = 0;
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[objectType].name, gArtListDescriptions[objectType].name);
|
||||
|
||||
if (artReadList(path, &(gArtListDescriptions[i].fileNames), &(gArtListDescriptions[i].fileNamesLength)) != 0) {
|
||||
if (artReadList(path, &(gArtListDescriptions[objectType].fileNames), &(gArtListDescriptions[objectType].fileNamesLength)) != 0) {
|
||||
debugPrint("art_read_lst failed in art_init\n");
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
_anon_alias = (int*)internal_malloc(sizeof(*_anon_alias) * gArtListDescriptions[1].fileNamesLength);
|
||||
_anon_alias = (int*)internal_malloc(sizeof(*_anon_alias) * gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength);
|
||||
if (_anon_alias == NULL) {
|
||||
gArtListDescriptions[1].fileNamesLength = 0;
|
||||
gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength = 0;
|
||||
debugPrint("Out of memory for anon_alias in art_init\n");
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
|
@ -168,17 +167,17 @@ int artInit()
|
|||
|
||||
gArtCritterFidShoudRunData = (int*)internal_malloc(sizeof(*gArtCritterFidShoudRunData) * gArtListDescriptions[1].fileNamesLength);
|
||||
if (gArtCritterFidShoudRunData == NULL) {
|
||||
gArtListDescriptions[1].fileNamesLength = 0;
|
||||
gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength = 0;
|
||||
debugPrint("Out of memory for artCritterFidShouldRunData in art_init\n");
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < gArtListDescriptions[1].fileNamesLength; i++) {
|
||||
gArtCritterFidShoudRunData[i] = 0;
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
gArtCritterFidShoudRunData[critterIndex] = 0;
|
||||
}
|
||||
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[1].name, gArtListDescriptions[1].name);
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_CRITTER].name, gArtListDescriptions[OBJ_TYPE_CRITTER].name);
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
|
@ -206,75 +205,70 @@ int artInit()
|
|||
tribalMaleFileName = gDefaultTribalMaleFileName;
|
||||
}
|
||||
|
||||
char *tribalFemaleFileName = NULL;
|
||||
char* tribalFemaleFileName = NULL;
|
||||
configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_DUDE_NATIVE_LOOK_TRIBAL_FEMALE_KEY, &tribalFemaleFileName);
|
||||
if (tribalFemaleFileName == NULL || tribalFemaleFileName[0] == '\0') {
|
||||
tribalFemaleFileName = gDefaultTribalFemaleFileName;
|
||||
}
|
||||
|
||||
ptr = gArtListDescriptions[1].fileNames;
|
||||
for (i = 0; i < gArtListDescriptions[1].fileNamesLength; i++) {
|
||||
if (compat_stricmp(ptr, jumpsuitMaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE] = i;
|
||||
} else if (compat_stricmp(ptr, jumpsuitFemaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_FEMALE] = i;
|
||||
char* critterFileNames = gArtListDescriptions[OBJ_TYPE_CRITTER].fileNames;
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
if (compat_stricmp(critterFileNames, "hmjmps") == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_MALE] = critterIndex;
|
||||
} else if (compat_stricmp(critterFileNames, "hfjmps") == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_JUMPSUIT][GENDER_FEMALE] = critterIndex;
|
||||
}
|
||||
|
||||
if (compat_stricmp(ptr, tribalMaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_MALE] = i;
|
||||
_art_vault_guy_num = i;
|
||||
} else if (compat_stricmp(ptr, tribalFemaleFileName) == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_FEMALE] = i;
|
||||
if (compat_stricmp(critterFileNames, "hmwarr") == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_MALE] = critterIndex;
|
||||
_art_vault_guy_num = critterIndex;
|
||||
} else if (compat_stricmp(critterFileNames, "hfprim") == 0) {
|
||||
_art_vault_person_nums[DUDE_NATIVE_LOOK_TRIBAL][GENDER_FEMALE] = critterIndex;
|
||||
}
|
||||
|
||||
ptr += 13;
|
||||
critterFileNames += 13;
|
||||
}
|
||||
|
||||
for (i = 0; i < gArtListDescriptions[1].fileNamesLength; i++) {
|
||||
if (!fileReadString(str, sizeof(str), stream)) {
|
||||
for (int critterIndex = 0; critterIndex < gArtListDescriptions[OBJ_TYPE_CRITTER].fileNamesLength; critterIndex++) {
|
||||
if (!fileReadString(string, sizeof(string), stream)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = str;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
}
|
||||
char* sep1 = strchr(string, ',');
|
||||
if (sep1 != NULL) {
|
||||
_anon_alias[critterIndex] = atoi(sep1 + 1);
|
||||
|
||||
if (*curr != '\0') {
|
||||
_anon_alias[i] = atoi(curr + 1);
|
||||
|
||||
ptr = curr + 1;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
char* sep2 = strchr(sep1 + 1, ',');
|
||||
if (sep2 != NULL) {
|
||||
gArtCritterFidShoudRunData[critterIndex] = atoi(sep2 + 1);
|
||||
} else {
|
||||
gArtCritterFidShoudRunData[critterIndex] = 0;
|
||||
}
|
||||
|
||||
gArtCritterFidShoudRunData[i] = *curr != '\0' ? atoi(ptr) : 0;
|
||||
} else {
|
||||
_anon_alias[i] = _art_vault_guy_num;
|
||||
gArtCritterFidShoudRunData[i] = 1;
|
||||
_anon_alias[critterIndex] = _art_vault_guy_num;
|
||||
gArtCritterFidShoudRunData[critterIndex] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
ptr = gArtListDescriptions[4].fileNames;
|
||||
for (i = 0; i < gArtListDescriptions[4].fileNamesLength; i++) {
|
||||
if (compat_stricmp(ptr, "grid001.frm") == 0) {
|
||||
_art_mapper_blank_tile = i;
|
||||
char* tileFileNames = gArtListDescriptions[OBJ_TYPE_TILE].fileNames;
|
||||
for (int tileIndex = 0; tileIndex < gArtListDescriptions[OBJ_TYPE_TILE].fileNamesLength; tileIndex++) {
|
||||
if (compat_stricmp(tileFileNames, "grid001.frm") == 0) {
|
||||
_art_mapper_blank_tile = tileIndex;
|
||||
}
|
||||
tileFileNames += 13;
|
||||
}
|
||||
|
||||
gHeadDescriptions = (HeadDescription*)internal_malloc(sizeof(HeadDescription) * gArtListDescriptions[8].fileNamesLength);
|
||||
gHeadDescriptions = (HeadDescription*)internal_malloc(sizeof(*gHeadDescriptions) * gArtListDescriptions[OBJ_TYPE_HEAD].fileNamesLength);
|
||||
if (gHeadDescriptions == NULL) {
|
||||
gArtListDescriptions[8].fileNamesLength = 0;
|
||||
gArtListDescriptions[OBJ_TYPE_HEAD].fileNamesLength = 0;
|
||||
debugPrint("Out of memory for head_info in art_init\n");
|
||||
cacheFree(&gArtCache);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[8].name, gArtListDescriptions[8].name);
|
||||
sprintf(path, "%s%s%s\\%s.lst", _cd_path_base, "art\\", gArtListDescriptions[OBJ_TYPE_HEAD].name, gArtListDescriptions[OBJ_TYPE_HEAD].name);
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
|
@ -283,46 +277,42 @@ int artInit()
|
|||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < gArtListDescriptions[8].fileNamesLength; i++) {
|
||||
if (!fileReadString(str, sizeof(str), stream)) {
|
||||
for (int headIndex = 0; headIndex < gArtListDescriptions[OBJ_TYPE_HEAD].fileNamesLength; headIndex++) {
|
||||
if (!fileReadString(string, sizeof(string), stream)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = str;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
char* sep1 = strchr(string, ',');
|
||||
if (sep1 != NULL) {
|
||||
*sep1 = '\0';
|
||||
} else {
|
||||
sep1 = string;
|
||||
}
|
||||
|
||||
if (*curr != '\0') {
|
||||
ptr = curr + 1;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
}
|
||||
|
||||
if (*curr != '\0') {
|
||||
gHeadDescriptions[i].goodFidgetCount = atoi(ptr);
|
||||
|
||||
ptr = curr + 1;
|
||||
curr = ptr;
|
||||
while (*curr != '\0' && *curr != ',') {
|
||||
curr++;
|
||||
}
|
||||
|
||||
if (*curr != '\0') {
|
||||
gHeadDescriptions[i].neutralFidgetCount = atoi(ptr);
|
||||
|
||||
ptr = curr + 1;
|
||||
curr = strpbrk(ptr, " ,;\t\n");
|
||||
if (curr != NULL) {
|
||||
*curr = '\0';
|
||||
}
|
||||
|
||||
gHeadDescriptions[i].badFidgetCount = atoi(ptr);
|
||||
}
|
||||
}
|
||||
char* sep2 = strchr(sep1, ',');
|
||||
if (sep2 != NULL) {
|
||||
*sep2 = '\0';
|
||||
} else {
|
||||
sep2 = sep1;
|
||||
}
|
||||
|
||||
gHeadDescriptions[headIndex].goodFidgetCount = atoi(sep1 + 1);
|
||||
|
||||
char* sep3 = strchr(sep2, ',');
|
||||
if (sep3 != NULL) {
|
||||
*sep3 = '\0';
|
||||
} else {
|
||||
sep3 = sep2;
|
||||
}
|
||||
|
||||
gHeadDescriptions[headIndex].neutralFidgetCount = atoi(sep2 + 1);
|
||||
|
||||
char* sep4 = strpbrk(sep3 + 1, " ,;\t\n");
|
||||
if (sep4 != NULL) {
|
||||
*sep4 = '\0';
|
||||
}
|
||||
|
||||
gHeadDescriptions[headIndex].badFidgetCount = atoi(sep3 + 1);
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
@ -357,19 +347,19 @@ void artExit()
|
|||
// 0x418F1C
|
||||
char* artGetObjectTypeName(int objectType)
|
||||
{
|
||||
return objectType >= 0 && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].name : NULL;
|
||||
return objectType >= OBJ_TYPE_ITEM && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].name : NULL;
|
||||
}
|
||||
|
||||
// 0x418F34
|
||||
int artIsObjectTypeHidden(int objectType)
|
||||
{
|
||||
return objectType >= 0 && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].flags & 1 : 0;
|
||||
return objectType >= OBJ_TYPE_ITEM && objectType < OBJ_TYPE_COUNT ? gArtListDescriptions[objectType].flags & 1 : 0;
|
||||
}
|
||||
|
||||
// 0x418F7C
|
||||
int artGetFidgetCount(int headFid)
|
||||
{
|
||||
if ((headFid & 0xF000000) >> 24 != OBJ_TYPE_HEAD) {
|
||||
if (FID_TYPE(headFid) != OBJ_TYPE_HEAD) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -522,15 +512,15 @@ int artCacheFlush()
|
|||
}
|
||||
|
||||
// 0x4192B0
|
||||
int artCopyFileName(int type, int id, char* dest)
|
||||
int artCopyFileName(int objectType, int id, char* dest)
|
||||
{
|
||||
ArtListDescription* ptr;
|
||||
|
||||
if (type < 0 && type >= 11) {
|
||||
if (objectType < OBJ_TYPE_ITEM && objectType >= OBJ_TYPE_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = &(gArtListDescriptions[type]);
|
||||
ptr = &(gArtListDescriptions[objectType]);
|
||||
|
||||
if (id >= ptr->fileNamesLength) {
|
||||
return -1;
|
||||
|
@ -622,7 +612,7 @@ char* artBuildFilePath(int fid)
|
|||
|
||||
v10 = (fid & 0x70000000) >> 28;
|
||||
|
||||
v1 = _art_alias_fid(fid);
|
||||
v1 = artAliasFid(fid);
|
||||
if (v1 != -1) {
|
||||
v2 = v1;
|
||||
}
|
||||
|
@ -630,15 +620,15 @@ char* artBuildFilePath(int fid)
|
|||
*_art_name = '\0';
|
||||
|
||||
v3 = v2 & 0xFFF;
|
||||
v4 = (v2 & 0xFF0000) >> 16;
|
||||
v4 = FID_ANIM_TYPE(v2);
|
||||
v5 = (v2 & 0xF000) >> 12;
|
||||
type = (v2 & 0xF000000) >> 24;
|
||||
type = FID_TYPE(v2);
|
||||
|
||||
if (v3 >= gArtListDescriptions[type].fileNamesLength) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (type < 0 || type >= 11) {
|
||||
if (type < OBJ_TYPE_ITEM || type >= OBJ_TYPE_COUNT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -669,44 +659,40 @@ char* artBuildFilePath(int fid)
|
|||
|
||||
// art_read_lst
|
||||
// 0x419664
|
||||
static int artReadList(const char* path, char** out_arr, int* out_count)
|
||||
static int artReadList(const char* path, char** artListPtr, int* artListSizePtr)
|
||||
{
|
||||
File* stream;
|
||||
char str[200];
|
||||
char* arr;
|
||||
int count;
|
||||
char* brk;
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
File* stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
int count = 0;
|
||||
char string[200];
|
||||
while (fileReadString(string, sizeof(string), stream)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
fileSeek(stream, 0, SEEK_SET);
|
||||
|
||||
*out_count = count;
|
||||
*artListSizePtr = count;
|
||||
|
||||
arr = (char*)internal_malloc(13 * count);
|
||||
*out_arr = arr;
|
||||
if (arr == NULL) {
|
||||
goto err;
|
||||
char* artList = (char*)internal_malloc(13 * count);
|
||||
*artListPtr = artList;
|
||||
if (artList == NULL) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
brk = strpbrk(str, " ,;\r\t\n");
|
||||
while (fileReadString(string, sizeof(string), stream)) {
|
||||
char* brk = strpbrk(string, " ,;\r\t\n");
|
||||
if (brk != NULL) {
|
||||
*brk = '\0';
|
||||
}
|
||||
|
||||
strncpy(arr, str, 12);
|
||||
arr[12] = '\0';
|
||||
strncpy(artList, string, 12);
|
||||
artList[12] = '\0';
|
||||
|
||||
arr += 13;
|
||||
artList += 13;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
@ -864,34 +850,24 @@ ArtFrame* artGetFrame(Art* art, int frame, int rotation)
|
|||
// 0x4198C8
|
||||
bool artExists(int fid)
|
||||
{
|
||||
int v3;
|
||||
bool result;
|
||||
bool result = false;
|
||||
int oldDb = -1;
|
||||
|
||||
v3 = -1;
|
||||
result = false;
|
||||
|
||||
if ((fid & 0xF000000) >> 24 == 1) {
|
||||
v3 = _db_current(1);
|
||||
// _db_current(_critter_db_handle);
|
||||
_db_current(0);
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current(1);
|
||||
_db_current(_critter_db_handle);
|
||||
}
|
||||
|
||||
char* filePath = artBuildFilePath(fid);
|
||||
if (filePath == NULL) {
|
||||
goto out;
|
||||
if (filePath != NULL) {
|
||||
int fileSize;
|
||||
if (dbGetFileSize(filePath, &fileSize) != -1) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
int fileSize;
|
||||
if (dbGetFileSize(filePath, &fileSize) == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = true;
|
||||
|
||||
out:
|
||||
|
||||
if (v3 != -1) {
|
||||
_db_current(v3);
|
||||
if (oldDb != -1) {
|
||||
_db_current(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -923,7 +899,7 @@ int _art_alias_num(int index)
|
|||
// 0x4199AC
|
||||
int artCritterFidShouldRun(int fid)
|
||||
{
|
||||
if ((fid & 0xF000000) >> 24 == 1) {
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
return gArtCritterFidShoudRunData[fid & 0xFFF];
|
||||
}
|
||||
|
||||
|
@ -931,64 +907,61 @@ int artCritterFidShouldRun(int fid)
|
|||
}
|
||||
|
||||
// 0x4199D4
|
||||
int _art_alias_fid(int fid)
|
||||
int artAliasFid(int fid)
|
||||
{
|
||||
int v2;
|
||||
int v3;
|
||||
int result;
|
||||
int type = FID_TYPE(fid);
|
||||
int anim = FID_ANIM_TYPE(fid);
|
||||
if (type == OBJ_TYPE_CRITTER) {
|
||||
if (anim == ANIM_ELECTRIFY
|
||||
|| anim == ANIM_BURNED_TO_NOTHING
|
||||
|| anim == ANIM_ELECTRIFIED_TO_NOTHING
|
||||
|| anim == ANIM_ELECTRIFY_SF
|
||||
|| anim == ANIM_BURNED_TO_NOTHING_SF
|
||||
|| anim == ANIM_ELECTRIFIED_TO_NOTHING_SF
|
||||
|| anim == ANIM_FIRE_DANCE
|
||||
|| anim == ANIM_CALLED_SHOT_PIC) {
|
||||
// NOTE: Original code is slightly different. It uses many mutually
|
||||
// mirrored bitwise operators. Probably result of some macros for
|
||||
// getting/setting individual bits on fid.
|
||||
return (fid & 0x70000000) | ((anim << 16) & 0xFF0000) | 0x1000000 | (fid & 0xF000) | (_anon_alias[fid & 0xFFF] & 0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
v2 = (fid & 0xF000000) >> 24;
|
||||
v3 = (fid & 0xFF0000) >> 16;
|
||||
|
||||
if (v2 != 1 || v3 != 27 && v3 != 29 && v3 != 30 && v3 != 55 && v3 != 57 && v3 != 58 && v3 != 33 && v3 != 64)
|
||||
result = -1;
|
||||
else
|
||||
result = ((fid & 0x70000000) >> 28 << 28) & 0x70000000 | (v3 << 16) & 0xFF0000 | 0x1000000 | (((fid & 0xF000) >> 12) << 12) & 0xF000 | _anon_alias[fid & 0xFFF] & 0xFFF;
|
||||
|
||||
return result;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 0x419A78
|
||||
static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
||||
{
|
||||
int v4;
|
||||
char* str;
|
||||
char* ptr;
|
||||
int result;
|
||||
char path[COMPAT_MAX_PATH];
|
||||
bool loaded;
|
||||
int fileSize;
|
||||
int oldDb = -1;
|
||||
int result = -1;
|
||||
|
||||
v4 = -1;
|
||||
result = -1;
|
||||
|
||||
if ((fid & 0xF000000) >> 24 == 1) {
|
||||
v4 = _db_current(1);
|
||||
// _db_current(_critter_db_handle);
|
||||
_db_current(0);
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current(1);
|
||||
_db_current(_critter_db_handle);
|
||||
}
|
||||
|
||||
str = artBuildFilePath(fid);
|
||||
if (str != NULL) {
|
||||
loaded = false;
|
||||
char* artFilePath = artBuildFilePath(fid);
|
||||
if (artFilePath != NULL) {
|
||||
int fileSize;
|
||||
bool loaded = false;
|
||||
|
||||
if (gArtLanguageInitialized) {
|
||||
ptr = str;
|
||||
while (*ptr != '\0' && *ptr != '\\') {
|
||||
ptr++;
|
||||
char* pch = strchr(artFilePath, '\\');
|
||||
if (pch == NULL) {
|
||||
pch = artFilePath;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
ptr = str;
|
||||
}
|
||||
char localizedPath[COMPAT_MAX_PATH];
|
||||
sprintf(localizedPath, "art\\%s\\%s", gArtLanguage, pch);
|
||||
|
||||
sprintf(path, "art\\%s\\%s", gArtLanguage, ptr);
|
||||
if (dbGetFileSize(path, &fileSize) == 0) {
|
||||
if (dbGetFileSize(localizedPath, &fileSize) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
if (dbGetFileSize(str, &fileSize) == 0) {
|
||||
if (dbGetFileSize(artFilePath, &fileSize) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
@ -999,8 +972,8 @@ static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
|||
}
|
||||
}
|
||||
|
||||
if (v4 != -1) {
|
||||
_db_current(v4);
|
||||
if (oldDb != -1) {
|
||||
_db_current(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1009,43 +982,33 @@ static int artCacheGetFileSizeImpl(int fid, int* sizePtr)
|
|||
// 0x419B78
|
||||
static int artCacheReadDataImpl(int fid, int* sizePtr, unsigned char* data)
|
||||
{
|
||||
int v4;
|
||||
char* str;
|
||||
char* ptr;
|
||||
int result;
|
||||
char path[COMPAT_MAX_PATH];
|
||||
bool loaded;
|
||||
int oldDb = -1;
|
||||
int result = -1;
|
||||
|
||||
v4 = -1;
|
||||
result = -1;
|
||||
|
||||
if ((fid & 0xF000000) >> 24 == 1) {
|
||||
v4 = _db_current(1);
|
||||
// _db_current(_critter_db_handle);
|
||||
_db_current(0);
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_CRITTER) {
|
||||
oldDb = _db_current(1);
|
||||
_db_current(_critter_db_handle);
|
||||
}
|
||||
|
||||
str = artBuildFilePath(fid);
|
||||
if (str != NULL) {
|
||||
loaded = false;
|
||||
char* artFileName = artBuildFilePath(fid);
|
||||
if (artFileName != NULL) {
|
||||
bool loaded = false;
|
||||
if (gArtLanguageInitialized) {
|
||||
ptr = str;
|
||||
while (*ptr != '\0' && *ptr != '\\') {
|
||||
ptr++;
|
||||
char* pch = strchr(artFileName, '\\');
|
||||
if (pch == NULL) {
|
||||
pch = artFileName;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
ptr = str;
|
||||
}
|
||||
char localizedPath[COMPAT_MAX_PATH];
|
||||
sprintf(localizedPath, "art\\%s\\%s", gArtLanguage, pch);
|
||||
|
||||
sprintf(path, "art\\%s\\%s", gArtLanguage, ptr);
|
||||
if (artRead(str, data) == 0) {
|
||||
if (artRead(localizedPath, data) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
if (artRead(str, data) == 0) {
|
||||
if (artRead(artFileName, data) == 0) {
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
@ -1057,8 +1020,8 @@ static int artCacheReadDataImpl(int fid, int* sizePtr, unsigned char* data)
|
|||
}
|
||||
}
|
||||
|
||||
if (v4 != -1) {
|
||||
_db_current(v4);
|
||||
if (oldDb != -1) {
|
||||
_db_current(oldDb);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1071,7 +1034,7 @@ static void artCacheFreeImpl(void* ptr)
|
|||
}
|
||||
|
||||
// 0x419C88
|
||||
int buildFid(int objectType, int a2, int anim, int a3, int rotation)
|
||||
int buildFid(int objectType, int frmId, int animType, int a3, int rotation)
|
||||
{
|
||||
int v7, v8, v9, v10;
|
||||
|
||||
|
@ -1081,13 +1044,13 @@ int buildFid(int objectType, int a2, int anim, int a3, int rotation)
|
|||
goto zero;
|
||||
}
|
||||
|
||||
if (anim == 33 || anim < 20 || anim > 35) {
|
||||
if (animType == ANIM_FIRE_DANCE || animType < ANIM_FALL_BACK || animType > ANIM_FALL_FRONT_BLOOD) {
|
||||
goto zero;
|
||||
}
|
||||
|
||||
v7 = ((a3 << 12) & 0xF000) | (anim << 16) & 0xFF0000 | 0x1000000;
|
||||
v7 = ((a3 << 12) & 0xF000) | (animType << 16) & 0xFF0000 | 0x1000000;
|
||||
v8 = (rotation << 28) & 0x70000000 | v7;
|
||||
v9 = a2 & 0xFFF;
|
||||
v9 = frmId & 0xFFF;
|
||||
|
||||
if (artExists(v9 | v8) != 0) {
|
||||
goto out;
|
||||
|
@ -1108,7 +1071,7 @@ zero:
|
|||
|
||||
out:
|
||||
|
||||
return (v10 << 28) & 0x70000000 | (objectType << 24) | (anim << 16) & 0xFF0000 | (a3 << 12) & 0xF000 | a2 & 0xFFF;
|
||||
return (v10 << 28) & 0x70000000 | (objectType << 24) | (animType << 16) & 0xFF0000 | (a3 << 12) & 0xF000 | frmId & 0xFFF;
|
||||
}
|
||||
|
||||
// 0x419D60
|
||||
|
@ -1172,3 +1135,75 @@ int artRead(const char* path, unsigned char* data)
|
|||
fileClose(stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x41A070
|
||||
int artWriteFrameData(unsigned char* data, File* stream, int count)
|
||||
{
|
||||
unsigned char* ptr = data;
|
||||
for (int index = 0; index < count; index++) {
|
||||
ArtFrame* frame = (ArtFrame*)ptr;
|
||||
|
||||
if (fileWriteInt16(stream, frame->width) == -1) return -1;
|
||||
if (fileWriteInt16(stream, frame->height) == -1) return -1;
|
||||
if (fileWriteInt32(stream, frame->size) == -1) return -1;
|
||||
if (fileWriteInt16(stream, frame->x) == -1) return -1;
|
||||
if (fileWriteInt16(stream, frame->y) == -1) return -1;
|
||||
if (fileWrite(ptr + sizeof(ArtFrame), frame->size, 1, stream) != 1) return -1;
|
||||
|
||||
ptr += sizeof(ArtFrame) + frame->size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x41A138
|
||||
int artWriteHeader(Art* art, File* stream)
|
||||
{
|
||||
if (fileWriteInt32(stream, art->field_0) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->framesPerSecond) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->actionFrame) == -1) return -1;
|
||||
if (fileWriteInt16(stream, art->frameCount) == -1) return -1;
|
||||
if (fileWriteInt16List(stream, art->xOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt16List(stream, art->yOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt32List(stream, art->dataOffsets, ROTATION_COUNT) == -1) return -1;
|
||||
if (fileWriteInt32(stream, art->field_3A) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x41A1E8
|
||||
int artWrite(const char* path, unsigned char* data)
|
||||
{
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
File* stream = fileOpen(path, "wb");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Art* art = (Art*)data;
|
||||
if (artWriteHeader(art, stream) == -1) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < ROTATION_COUNT; index++) {
|
||||
if (index == 0 || art->dataOffsets[index - 1] != art->dataOffsets[index]) {
|
||||
if (artWriteFrameData(data + sizeof(Art) + art->dataOffsets[index], stream, art->frameCount) != 0) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ unsigned char* artLockFrameData(int fid, int frame, int direction, CacheEntry**
|
|||
unsigned char* artLockFrameDataReturningSize(int fid, CacheEntry** out_cache_entry, int* widthPtr, int* heightPtr);
|
||||
int artUnlock(CacheEntry* cache_entry);
|
||||
int artCacheFlush();
|
||||
int artCopyFileName(int a1, int a2, char* a3);
|
||||
int artCopyFileName(int objectType, int a2, char* a3);
|
||||
int _art_get_code(int a1, int a2, char* a3, char* a4);
|
||||
char* artBuildFilePath(int a1);
|
||||
int artGetFramesPerSecond(Art* art);
|
||||
|
@ -144,8 +144,9 @@ bool artExists(int fid);
|
|||
bool _art_fid_valid(int fid);
|
||||
int _art_alias_num(int a1);
|
||||
int artCritterFidShouldRun(int a1);
|
||||
int _art_alias_fid(int a1);
|
||||
int buildFid(int a1, int a2, int a3, int a4, int a5);
|
||||
int artAliasFid(int fid);
|
||||
int buildFid(int objectType, int frmId, int animType, int a4, int rotation);
|
||||
int artRead(const char* path, unsigned char* data);
|
||||
int artWrite(const char* path, unsigned char* data);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -302,7 +302,7 @@ void automapShow(bool isInGame, bool isUsingScanner)
|
|||
unsigned char* frmData[AUTOMAP_FRM_COUNT];
|
||||
CacheEntry* frmHandle[AUTOMAP_FRM_COUNT];
|
||||
for (int index = 0; index < AUTOMAP_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, frmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmIds[index], 0, 0, 0);
|
||||
frmData[index] = artLockFrameData(fid, 0, 0, &(frmHandle[index]));
|
||||
if (frmData[index] == NULL) {
|
||||
while (--index >= 0) {
|
||||
|
@ -482,7 +482,7 @@ static void automapRenderInMapWindow(int window, int elevation, unsigned char* b
|
|||
continue;
|
||||
}
|
||||
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
unsigned char objectColor;
|
||||
|
||||
if ((flags & AUTOMAP_IN_GAME) != 0) {
|
||||
|
@ -1048,7 +1048,7 @@ static void _decode_map_data(int elevation)
|
|||
if (object->tile != -1 && (object->flags & OBJECT_SEEN) != 0) {
|
||||
int contentType;
|
||||
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
if (objectType == OBJ_TYPE_SCENERY && object->pid != PROTO_ID_0x2000158) {
|
||||
contentType = 2;
|
||||
} else if (objectType == OBJ_TYPE_WALL) {
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include "sound.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// The initial number of cache entries in new cache.
|
||||
|
|
|
@ -1275,7 +1275,7 @@ static int characterEditorWindowInit()
|
|||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, (gCharacterEditorIsCreationMode ? 169 : 177), 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, (gCharacterEditorIsCreationMode ? 169 : 177), 0, 0, 0);
|
||||
gCharacterEditorWindowBackgroundBuffer = artLockFrameDataReturningSize(fid, &gCharacterEditorWindowBackgroundHandle, &(gCharacterEditorFrmSize[0].width), &(gCharacterEditorFrmSize[0].height));
|
||||
if (gCharacterEditorWindowBackgroundBuffer == NULL) {
|
||||
messageListFree(&gCharacterEditorMessageList);
|
||||
|
@ -1296,7 +1296,7 @@ static int characterEditorWindowInit()
|
|||
soundContinueAll();
|
||||
|
||||
for (i = 0; i < EDITOR_GRAPHIC_COUNT; i++) {
|
||||
fid = buildFid(6, gCharacterEditorFrmIds[i], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gCharacterEditorFrmIds[i], 0, 0, 0);
|
||||
gCharacterEditorFrmData[i] = artLockFrameDataReturningSize(fid, &(gCharacterEditorFrmHandle[i]), &(gCharacterEditorFrmSize[i].width), &(gCharacterEditorFrmSize[i].height));
|
||||
if (gCharacterEditorFrmData[i] == NULL) {
|
||||
break;
|
||||
|
@ -4892,7 +4892,7 @@ static int characterEditorDrawCardWithOptions(int graphicId, const char* name, c
|
|||
short beginnings[WORD_WRAP_MAX_COUNT];
|
||||
short beginningsCount;
|
||||
|
||||
fid = buildFid(10, graphicId, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_SKILLDEX, graphicId, 0, 0, 0);
|
||||
buf = artLockFrameDataReturningSize(fid, &graphicHandle, &(size.width), &(size.height));
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
|
@ -5744,7 +5744,7 @@ static int perkDialogShow()
|
|||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundWidth;
|
||||
int backgroundHeight;
|
||||
int fid = buildFid(6, 86, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 86, 0, 0, 0);
|
||||
gPerkDialogBackgroundBuffer = artLockFrameDataReturningSize(fid, &backgroundFrmHandle, &backgroundWidth, &backgroundHeight);
|
||||
if (gPerkDialogBackgroundBuffer == NULL) {
|
||||
debugPrint("\n *** Error running perks dialog window ***\n");
|
||||
|
@ -5956,7 +5956,7 @@ static int perkDialogHandleInput(int count, void (*refreshProc)())
|
|||
soundPlayFile("ib1p1xx1");
|
||||
rc = 1;
|
||||
} else if (keyCode == 501) {
|
||||
mouseGetPositionInWindow(gPerkDialogWindow , &gCharacterEditorMouseX, &gCharacterEditorMouseY);
|
||||
mouseGetPositionInWindow(gPerkDialogWindow, &gCharacterEditorMouseX, &gCharacterEditorMouseY);
|
||||
gPerkDialogCurrentLine = (gCharacterEditorMouseY - PERK_WINDOW_LIST_Y) / v16;
|
||||
if (gPerkDialogCurrentLine >= 0) {
|
||||
if (count - 1 < gPerkDialogCurrentLine)
|
||||
|
@ -6526,7 +6526,7 @@ static int perkDialogOptionCompare(const void* a1, const void* a2)
|
|||
// 0x43DB54
|
||||
static int perkDialogDrawCard(int frmId, const char* name, const char* rank, char* description)
|
||||
{
|
||||
int fid = buildFid(10, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_SKILLDEX, frmId, 0, 0, 0);
|
||||
|
||||
CacheEntry* handle;
|
||||
int width;
|
||||
|
@ -6611,7 +6611,7 @@ static int perkDialogDrawCard(int frmId, const char* name, const char* rank, cha
|
|||
strcpy(gPerkDialogCardTitle, name);
|
||||
gPerkDialogCardFrmId = frmId;
|
||||
gPerkDialogCardDrawn = true;
|
||||
|
||||
|
||||
artUnlock(handle);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -299,7 +299,7 @@ static bool characterSelectorWindowInit()
|
|||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
backgroundFid = buildFid(6, 174, 0, 0, 0);
|
||||
backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 174, 0, 0, 0);
|
||||
backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -328,13 +328,13 @@ static bool characterSelectorWindowInit()
|
|||
int fid;
|
||||
|
||||
// Setup "Previous" button.
|
||||
fid = buildFid(6, 122, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 122, 0, 0, 0);
|
||||
gCharacterSelectorWindowPreviousButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowPreviousButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowPreviousButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 123, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 123, 0, 0, 0);
|
||||
gCharacterSelectorWindowPreviousButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowPreviousButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowPreviousButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -360,13 +360,13 @@ static bool characterSelectorWindowInit()
|
|||
buttonSetCallbacks(gCharacterSelectorWindowPreviousButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
// Setup "Next" button.
|
||||
fid = buildFid(6, 124, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 124, 0, 0, 0);
|
||||
gCharacterSelectorWindowNextButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowNextButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowNextButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 125, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 125, 0, 0, 0);
|
||||
gCharacterSelectorWindowNextButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowNextButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowNextButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -392,13 +392,13 @@ static bool characterSelectorWindowInit()
|
|||
buttonSetCallbacks(gCharacterSelectorWindowNextButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
// Setup "Take" button.
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
gCharacterSelectorWindowTakeButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowTakeButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowTakeButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gCharacterSelectorWindowTakeButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowTakeButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowTakeButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -424,12 +424,12 @@ static bool characterSelectorWindowInit()
|
|||
buttonSetCallbacks(gCharacterSelectorWindowTakeButton, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
|
||||
// Setup "Modify" button.
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
gCharacterSelectorWindowModifyButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowModifyButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowModifyButtonUpFrmData == NULL)
|
||||
goto err;
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gCharacterSelectorWindowModifyButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowModifyButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowModifyButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -455,13 +455,13 @@ static bool characterSelectorWindowInit()
|
|||
buttonSetCallbacks(gCharacterSelectorWindowModifyButton, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
|
||||
// Setup "Create" button.
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
gCharacterSelectorWindowCreateButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowCreateButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowCreateButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gCharacterSelectorWindowCreateButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowCreateButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowCreateButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -487,13 +487,13 @@ static bool characterSelectorWindowInit()
|
|||
buttonSetCallbacks(gCharacterSelectorWindowCreateButton, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
|
||||
// Setup "Back" button.
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
gCharacterSelectorWindowBackButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowBackButtonUpFrmHandle);
|
||||
if (gCharacterSelectorWindowBackButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gCharacterSelectorWindowBackButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterSelectorWindowBackButtonDownFrmHandle);
|
||||
if (gCharacterSelectorWindowBackButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -688,7 +688,7 @@ static bool characterSelectorWindowRenderFace()
|
|||
bool success = false;
|
||||
|
||||
CacheEntry* faceFrmHandle;
|
||||
int faceFid = buildFid(6, gPremadeCharacterDescriptions[gCurrentPremadeCharacter].face, 0, 0, 0);
|
||||
int faceFid = buildFid(OBJ_TYPE_INTERFACE, gPremadeCharacterDescriptions[gCurrentPremadeCharacter].face, 0, 0, 0);
|
||||
Art* frm = artLock(faceFid, &faceFrmHandle);
|
||||
if (frm != NULL) {
|
||||
unsigned char* data = artGetFrameData(frm, 0, 0);
|
||||
|
|
82
src/color.cc
82
src/color.cc
|
@ -2,11 +2,19 @@
|
|||
|
||||
#include "core.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define COLOR_PALETTE_STACK_CAPACITY 16
|
||||
|
||||
typedef struct ColorPaletteStackEntry {
|
||||
unsigned char mappedColors[256];
|
||||
unsigned char cmap[768];
|
||||
unsigned char colorTable[32768];
|
||||
} ColorPaletteStackEntry;
|
||||
|
||||
static int colorPaletteFileOpen(const char* filePath, int flags);
|
||||
static int colorPaletteFileRead(int fd, void* buffer, size_t size);
|
||||
static int colorPaletteFileClose(int fd);
|
||||
|
@ -25,6 +33,12 @@ static char _aColor_cNoError[] = "color.c: No errors\n";
|
|||
// 0x50F95C
|
||||
static char _aColor_cColorTa[] = "color.c: color table not found\n";
|
||||
|
||||
// 0x50F984
|
||||
static char _aColor_cColorpa[] = "color.c: colorpalettestack overflow";
|
||||
|
||||
// 0x50F9AC
|
||||
static char aColor_cColor_0[] = "color.c: colorpalettestack underflow";
|
||||
|
||||
// 0x51DF10
|
||||
static char* _errorStr = _aColor_cNoError;
|
||||
|
||||
|
@ -54,6 +68,9 @@ unsigned char _cmap[768] = {
|
|||
0x3F, 0x3F, 0x3F
|
||||
};
|
||||
|
||||
// 0x673050
|
||||
static ColorPaletteStackEntry* gColorPaletteStack[COLOR_PALETTE_STACK_CAPACITY];
|
||||
|
||||
// 0x673090
|
||||
unsigned char _systemCmap[256 * 3];
|
||||
|
||||
|
@ -78,6 +95,9 @@ unsigned char _colorMixMulTable[65536];
|
|||
// 0x6A38D0
|
||||
unsigned char _colorTable[32768];
|
||||
|
||||
// 0x6AB8D0
|
||||
static int gColorPaletteStackSize;
|
||||
|
||||
// 0x6AB928
|
||||
static ColorPaletteFileReadProc* gColorPaletteFileReadProc;
|
||||
|
||||
|
@ -572,6 +592,60 @@ void colorSetBrightness(double value)
|
|||
_setSystemPalette(_systemCmap);
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4C8828
|
||||
bool colorPushColorPalette()
|
||||
{
|
||||
if (gColorPaletteStackSize >= COLOR_PALETTE_STACK_CAPACITY) {
|
||||
_errorStr = _aColor_cColorpa;
|
||||
return false;
|
||||
}
|
||||
|
||||
ColorPaletteStackEntry* entry = (ColorPaletteStackEntry*)malloc(sizeof(*entry));
|
||||
gColorPaletteStack[gColorPaletteStackSize] = entry;
|
||||
|
||||
memcpy(entry->mappedColors, _mappedColor, sizeof(_mappedColor));
|
||||
memcpy(entry->cmap, _cmap, sizeof(_cmap));
|
||||
memcpy(entry->colorTable, _colorTable, sizeof(_colorTable));
|
||||
|
||||
gColorPaletteStackSize++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4C88E0
|
||||
bool colorPopColorPalette()
|
||||
{
|
||||
if (gColorPaletteStackSize == 0) {
|
||||
_errorStr = aColor_cColor_0;
|
||||
return false;
|
||||
}
|
||||
|
||||
gColorPaletteStackSize--;
|
||||
|
||||
ColorPaletteStackEntry* entry = gColorPaletteStack[gColorPaletteStackSize];
|
||||
|
||||
memcpy(_mappedColor, entry->mappedColors, sizeof(_mappedColor));
|
||||
memcpy(_cmap, entry->cmap, sizeof(_cmap));
|
||||
memcpy(_colorTable, entry->colorTable, sizeof(_colorTable));
|
||||
|
||||
free(entry);
|
||||
gColorPaletteStack[gColorPaletteStackSize] = NULL;
|
||||
|
||||
_setIntensityTables();
|
||||
|
||||
for (int index = 0; index < 256; index++) {
|
||||
_setMixTableColor(index);
|
||||
}
|
||||
|
||||
_rebuildColorBlendTables();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4C89CC
|
||||
bool _initColors()
|
||||
{
|
||||
|
@ -599,5 +673,9 @@ void _colorsClose()
|
|||
_freeColorBlendTable(index);
|
||||
}
|
||||
|
||||
// TODO: Incomplete.
|
||||
for (int index = 0; index < gColorPaletteStackSize; index++) {
|
||||
free(gColorPaletteStack[index]);
|
||||
}
|
||||
|
||||
gColorPaletteStackSize = 0;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ unsigned char* _getColorBlendTable(int ch);
|
|||
void _freeColorBlendTable(int a1);
|
||||
void colorPaletteSetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc);
|
||||
void colorSetBrightness(double value);
|
||||
bool colorPushColorPalette();
|
||||
bool colorPopColorPalette();
|
||||
bool _initColors();
|
||||
void _colorsClose();
|
||||
|
||||
|
|
194
src/combat.cc
194
src/combat.cc
|
@ -96,7 +96,7 @@ int _combatNumTurns = 0;
|
|||
unsigned int gCombatState = COMBAT_STATE_0x02;
|
||||
|
||||
// 0x510948
|
||||
static STRUCT_510948* _aiInfoList = NULL;
|
||||
static CombatAIInfo* _aiInfoList = NULL;
|
||||
|
||||
// 0x51094C
|
||||
static STRUCT_664980* _gcsd = NULL;
|
||||
|
@ -1989,7 +1989,7 @@ int _find_cid(int a1, int cid, Object** critterList, int critterListLength)
|
|||
int combatLoad(File* stream)
|
||||
{
|
||||
int v14;
|
||||
STRUCT_510948* ptr;
|
||||
CombatAIInfo* ptr;
|
||||
int a2;
|
||||
Object* obj;
|
||||
int v24;
|
||||
|
@ -2001,7 +2001,7 @@ int combatLoad(File* stream)
|
|||
if (!isInCombat()) {
|
||||
obj = objectFindFirst();
|
||||
while (obj != NULL) {
|
||||
if (obj->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (obj->data.critter.combat.whoHitMeCid == -1) {
|
||||
obj->data.critter.combat.whoHitMe = NULL;
|
||||
}
|
||||
|
@ -2071,7 +2071,7 @@ int combatLoad(File* stream)
|
|||
internal_free(_aiInfoList);
|
||||
}
|
||||
|
||||
_aiInfoList = (STRUCT_510948*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
|
||||
_aiInfoList = (CombatAIInfo*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
|
||||
if (_aiInfoList == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -2082,31 +2082,31 @@ int combatLoad(File* stream)
|
|||
if (fileReadInt32(stream, &a2) == -1) return -1;
|
||||
|
||||
if (a2 == -1) {
|
||||
ptr->field_0 = 0;
|
||||
ptr->friendlyDead = NULL;
|
||||
} else {
|
||||
ptr->field_0 = objectFindById(a2);
|
||||
if (ptr->field_0 == NULL) return -1;
|
||||
ptr->friendlyDead = objectFindById(a2);
|
||||
if (ptr->friendlyDead == NULL) return -1;
|
||||
}
|
||||
|
||||
if (fileReadInt32(stream, &a2) == -1) return -1;
|
||||
|
||||
if (a2 == -1) {
|
||||
ptr->field_4 = 0;
|
||||
ptr->lastTarget = NULL;
|
||||
} else {
|
||||
ptr->field_4 = objectFindById(a2);
|
||||
if (ptr->field_4 == NULL) return -1;
|
||||
ptr->lastTarget = objectFindById(a2);
|
||||
if (ptr->lastTarget == NULL) return -1;
|
||||
}
|
||||
|
||||
if (fileReadInt32(stream, &a2) == -1) return -1;
|
||||
|
||||
if (a2 == -1) {
|
||||
ptr->field_8 = 0;
|
||||
ptr->lastItem = NULL;
|
||||
} else {
|
||||
ptr->field_8 = objectFindById(a2);
|
||||
if (ptr->field_8 == NULL) return -1;
|
||||
ptr->lastItem = objectFindById(a2);
|
||||
if (ptr->lastItem == NULL) return -1;
|
||||
}
|
||||
|
||||
if (fileReadInt32(stream, &(ptr->field_C)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->lastMove)) == -1) return -1;
|
||||
}
|
||||
|
||||
_combat_begin_extra(gDude);
|
||||
|
@ -2138,12 +2138,12 @@ int combatSave(File* stream)
|
|||
}
|
||||
|
||||
for (int index = 0; index < _list_total; index++) {
|
||||
STRUCT_510948* ptr = &(_aiInfoList[index]);
|
||||
CombatAIInfo* ptr = &(_aiInfoList[index]);
|
||||
|
||||
if (fileWriteInt32(stream, ptr->field_0 != NULL ? ptr->field_0->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_4 != NULL ? ptr->field_4->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_8 != NULL ? ptr->field_8->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_C) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->friendlyDead != NULL ? ptr->friendlyDead->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->lastTarget != NULL ? ptr->lastTarget->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->lastItem != NULL ? ptr->lastItem->id : -1) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->lastMove) == -1) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2285,16 +2285,16 @@ void _combat_data_init(Object* obj)
|
|||
// 0x421850
|
||||
static int _combatCopyAIInfo(int a1, int a2)
|
||||
{
|
||||
STRUCT_510948* v3;
|
||||
STRUCT_510948* v4;
|
||||
CombatAIInfo* v3;
|
||||
CombatAIInfo* v4;
|
||||
|
||||
v3 = &_aiInfoList[a1];
|
||||
v4 = &_aiInfoList[a2];
|
||||
|
||||
v4->field_0 = v3->field_0;
|
||||
v4->field_4 = v3->field_4;
|
||||
v4->field_8 = v3->field_8;
|
||||
v4->field_C = v3->field_C;
|
||||
v4->friendlyDead = v3->friendlyDead;
|
||||
v4->lastTarget = v3->lastTarget;
|
||||
v4->lastItem = v3->lastItem;
|
||||
v4->lastMove = v3->lastMove;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2314,7 +2314,7 @@ Object* _combatAIInfoGetFriendlyDead(Object* obj)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return _aiInfoList[obj->cid].field_0;
|
||||
return _aiInfoList[obj->cid].friendlyDead;
|
||||
}
|
||||
|
||||
// 0x4218AC
|
||||
|
@ -2336,7 +2336,7 @@ int _combatAIInfoSetFriendlyDead(Object* a1, Object* a2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
_aiInfoList[a1->cid].field_0 = a2;
|
||||
_aiInfoList[a1->cid].friendlyDead = a2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2356,7 +2356,7 @@ Object* _combatAIInfoGetLastTarget(Object* obj)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return _aiInfoList[obj->cid].field_4;
|
||||
return _aiInfoList[obj->cid].lastTarget;
|
||||
}
|
||||
|
||||
// 0x421918
|
||||
|
@ -2382,7 +2382,7 @@ int _combatAIInfoSetLastTarget(Object* a1, Object* a2)
|
|||
a2 = NULL;
|
||||
}
|
||||
|
||||
_aiInfoList[a1->cid].field_4 = a2;
|
||||
_aiInfoList[a1->cid].lastTarget = a2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2405,7 +2405,7 @@ Object* _combatAIInfoGetLastItem(Object* obj)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return _aiInfoList[v1].field_8;
|
||||
return _aiInfoList[v1].lastItem;
|
||||
}
|
||||
|
||||
// 0x421998
|
||||
|
@ -2426,7 +2426,7 @@ int _combatAIInfoSetLastItem(Object* obj, Object* a2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
_aiInfoList[v2].field_8 = NULL;
|
||||
_aiInfoList[v2].lastItem = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2446,24 +2446,24 @@ static void _combat_begin(Object* a1)
|
|||
_list_total = objectListCreate(-1, _combat_elev, OBJ_TYPE_CRITTER, &_combat_list);
|
||||
_list_noncom = _list_total;
|
||||
_list_com = 0;
|
||||
_aiInfoList = (STRUCT_510948*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
|
||||
_aiInfoList = (CombatAIInfo*)internal_malloc(sizeof(*_aiInfoList) * _list_total);
|
||||
if (_aiInfoList == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = 0; index < _list_total; index++) {
|
||||
STRUCT_510948* ptr = &(_aiInfoList[index]);
|
||||
ptr->field_0 = NULL;
|
||||
ptr->field_4 = NULL;
|
||||
ptr->field_8 = NULL;
|
||||
ptr->field_C = 0;
|
||||
CombatAIInfo* ptr = &(_aiInfoList[index]);
|
||||
ptr->friendlyDead = NULL;
|
||||
ptr->lastTarget = NULL;
|
||||
ptr->lastItem = NULL;
|
||||
ptr->lastMove = 0;
|
||||
}
|
||||
|
||||
Object* v1 = NULL;
|
||||
for (int index = 0; index < _list_total; index++) {
|
||||
Object* critter = _combat_list[index];
|
||||
CritterCombatData* combatData = &(critter->data.critter.combat);
|
||||
combatData->maneuver &= 0x01;
|
||||
combatData->maneuver &= CRITTER_MANEUVER_0x01;
|
||||
combatData->damageLastTurn = 0;
|
||||
combatData->whoHitMe = NULL;
|
||||
combatData->ap = 0;
|
||||
|
@ -2471,7 +2471,7 @@ static void _combat_begin(Object* a1)
|
|||
|
||||
// NOTE: Not sure about this code, field_C is already reset.
|
||||
if (isInCombat() && critter != NULL && index != -1) {
|
||||
_aiInfoList[index].field_C = 0;
|
||||
_aiInfoList[index].lastMove = 0;
|
||||
}
|
||||
|
||||
scriptSetObjects(critter->sid, NULL, NULL);
|
||||
|
@ -2495,16 +2495,16 @@ static void _combat_begin(Object* a1)
|
|||
_gmouse_enable_scrolling();
|
||||
|
||||
if (v1 != NULL && !_isLoadingGame()) {
|
||||
int fid = buildFid((v1->fid & 0xF000000) >> 24,
|
||||
int fid = buildFid(FID_TYPE(v1->fid),
|
||||
100,
|
||||
(v1->fid & 0xFF0000) >> 16,
|
||||
FID_ANIM_TYPE(v1->fid),
|
||||
(v1->fid & 0xF000) >> 12,
|
||||
(v1->fid & 0x70000000) >> 28);
|
||||
|
||||
reg_anim_clear(v1);
|
||||
reg_anim_begin(2);
|
||||
reg_anim_animate(v1, 6, -1);
|
||||
reg_anim_17(v1, fid, -1);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterAnimate(v1, ANIM_UP_STAIRS_RIGHT, -1);
|
||||
animationRegisterSetFid(v1, fid, -1);
|
||||
reg_anim_end();
|
||||
|
||||
while (animationIsBusy(v1)) {
|
||||
|
@ -2536,7 +2536,7 @@ static void _combat_begin_extra(Object* a1)
|
|||
// 0x421D50
|
||||
void _combat_update_critter_outline_for_los(Object* critter, bool a2)
|
||||
{
|
||||
if (critter->pid >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2636,7 +2636,7 @@ static void _combat_over()
|
|||
for (int index = 0; index < _list_noncom + _list_com; index++) {
|
||||
Object* critter = _combat_list[index];
|
||||
critter->data.critter.combat.damageLastTurn = 0;
|
||||
critter->data.critter.combat.maneuver = 0;
|
||||
critter->data.critter.combat.maneuver = CRITTER_MANEUVER_NONE;
|
||||
}
|
||||
|
||||
for (int index = 0; index < _list_total; index++) {
|
||||
|
@ -2649,15 +2649,15 @@ static void _combat_over()
|
|||
scriptSetFixedParam(critter->sid, 0);
|
||||
|
||||
if (critter->pid == 0x1000098 && !critterIsDead(critter) && !_isLoadingGame()) {
|
||||
int fid = buildFid((critter->fid & 0xF000000) >> 24,
|
||||
int fid = buildFid(FID_TYPE(critter->fid),
|
||||
99,
|
||||
(critter->fid & 0xFF0000) >> 16,
|
||||
FID_ANIM_TYPE(critter->fid),
|
||||
(critter->fid & 0xF000) >> 12,
|
||||
(critter->fid & 0x70000000) >> 28);
|
||||
reg_anim_clear(critter);
|
||||
reg_anim_begin(2);
|
||||
reg_anim_animate(critter, 6, -1);
|
||||
reg_anim_17(critter, fid, -1);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterAnimate(critter, ANIM_UP_STAIRS_RIGHT, -1);
|
||||
animationRegisterSetFid(critter, fid, -1);
|
||||
reg_anim_end();
|
||||
|
||||
while (animationIsBusy(critter)) {
|
||||
|
@ -2766,7 +2766,7 @@ static void _combat_add_noncoms()
|
|||
for (int index = _list_com; index < _list_com + _list_noncom; index++) {
|
||||
Object* obj = _combat_list[index];
|
||||
if (_combatai_want_to_join(obj)) {
|
||||
obj->data.critter.combat.maneuver = 0;
|
||||
obj->data.critter.combat.maneuver = CRITTER_MANEUVER_NONE;
|
||||
|
||||
Object** objectPtr1 = &(_combat_list[index]);
|
||||
Object** objectPtr2 = &(_combat_list[_list_com]);
|
||||
|
@ -3056,7 +3056,7 @@ static void _combat_set_move_all()
|
|||
|
||||
if (isInCombat()) {
|
||||
if (object->cid != -1) {
|
||||
_aiInfoList[object->cid].field_C = 0;
|
||||
_aiInfoList[object->cid].lastMove = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3330,7 +3330,7 @@ void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode,
|
|||
int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation)
|
||||
{
|
||||
if (a1 != gDude && hitMode == HIT_MODE_PUNCH && randomBetween(1, 4) == 1) {
|
||||
int fid = buildFid(1, a1->fid & 0xFFF, ANIM_KICK_LEG, (a1->fid & 0xF000) >> 12, (a1->fid & 0x70000000) >> 28);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, a1->fid & 0xFFF, ANIM_KICK_LEG, (a1->fid & 0xF000) >> 12, (a1->fid & 0x70000000) >> 28);
|
||||
if (artExists(fid)) {
|
||||
hitMode = HIT_MODE_KICK;
|
||||
}
|
||||
|
@ -3422,7 +3422,7 @@ static bool _check_ranged_miss(Attack* attack)
|
|||
_make_straight_path_func(attack->attacker, curr, to, NULL, &critter, 32, _obj_shoot_blocking_at);
|
||||
if (critter != NULL) {
|
||||
if ((critter->flags & OBJECT_SHOOT_THRU) == 0) {
|
||||
if ((critter->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
|
||||
roll = ROLL_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
@ -3479,7 +3479,7 @@ static int _shoot_along_path(Attack* attack, int a2, int a3, int anim)
|
|||
_make_straight_path_func(attack->attacker, v7, a2, NULL, &critter, 32, _obj_shoot_blocking_at);
|
||||
|
||||
if (critter != NULL) {
|
||||
if (((critter->fid & 0xF000000) >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3809,7 +3809,7 @@ static int attackCompute(Attack* attack)
|
|||
|
||||
// compute_explosion_on_extras
|
||||
// 0x423C10
|
||||
void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
||||
void _compute_explosion_on_extras(Attack* attack, int a2, bool isGrenade, int a4)
|
||||
{
|
||||
Object* attacker;
|
||||
|
||||
|
@ -3852,9 +3852,9 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
|||
}
|
||||
} else {
|
||||
v22++;
|
||||
if (a3 && _item_w_grenade_dmg_radius(attack->weapon) < v22) {
|
||||
if (isGrenade && _item_w_grenade_dmg_radius(attack->weapon) < v22) {
|
||||
v5 = -1;
|
||||
} else if (a3 || _item_w_rocket_dmg_radius(attack->weapon) >= v22) {
|
||||
} else if (isGrenade || _item_w_rocket_dmg_radius(attack->weapon) >= v22) {
|
||||
v5 = tileGetTileInDirection(v19, ROTATION_NE, 1);
|
||||
} else {
|
||||
v5 = -1;
|
||||
|
@ -3869,13 +3869,13 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
|||
break;
|
||||
}
|
||||
|
||||
Object* v11 = _obj_blocking_at(attacker, v5, attack->attacker->elevation);
|
||||
if (v11 != NULL
|
||||
&& (v11->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER
|
||||
&& (v11->data.critter.combat.results & DAM_DEAD) == 0
|
||||
&& (v11->flags & OBJECT_SHOOT_THRU) == 0
|
||||
&& !_combat_is_shot_blocked(v11, v11->tile, tile, NULL, NULL)) {
|
||||
if (v11 == attack->attacker) {
|
||||
Object* obstacle = _obj_blocking_at(attacker, v5, attack->attacker->elevation);
|
||||
if (obstacle != NULL
|
||||
&& FID_TYPE(obstacle->fid) == OBJ_TYPE_CRITTER
|
||||
&& (obstacle->data.critter.combat.results & DAM_DEAD) == 0
|
||||
&& (obstacle->flags & OBJECT_SHOOT_THRU) == 0
|
||||
&& !_combat_is_shot_blocked(obstacle, obstacle->tile, tile, NULL, NULL)) {
|
||||
if (obstacle == attack->attacker) {
|
||||
attack->attackerFlags &= ~DAM_HIT;
|
||||
attackComputeDamage(attack, 1, 2);
|
||||
attack->attackerFlags |= DAM_HIT;
|
||||
|
@ -3883,15 +3883,15 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
|||
} else {
|
||||
int index;
|
||||
for (index = 0; index < attack->extrasLength; index++) {
|
||||
if (attack->extras[index] == v11) {
|
||||
if (attack->extras[index] == obstacle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == attack->extrasLength) {
|
||||
attack->extrasHitLocation[index] = HIT_LOCATION_TORSO;
|
||||
attack->extras[index] = v11;
|
||||
attackInit(&_explosion_ctd, attack->attacker, v11, attack->hitMode, HIT_LOCATION_TORSO);
|
||||
attack->extras[index] = obstacle;
|
||||
attackInit(&_explosion_ctd, attack->attacker, obstacle, attack->hitMode, HIT_LOCATION_TORSO);
|
||||
if (!a4) {
|
||||
_explosion_ctd.attackerFlags |= DAM_HIT;
|
||||
attackComputeDamage(&_explosion_ctd, 1, 2);
|
||||
|
@ -3911,11 +3911,11 @@ void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4)
|
|||
static int attackComputeCriticalHit(Attack* attack)
|
||||
{
|
||||
Object* defender = attack->defender;
|
||||
if (defender != NULL && _critter_flag_check(defender->pid, 1024)) {
|
||||
if (defender != NULL && _critter_flag_check(defender->pid, CRITTER_FLAG_0x400)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (defender != NULL && (defender->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (defender != NULL && PID_TYPE(defender->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -3999,7 +3999,7 @@ static int _attackFindInvalidFlags(Object* critter, Object* item)
|
|||
{
|
||||
int flags = 0;
|
||||
|
||||
if (critter != NULL && (critter->pid >> 24) == OBJ_TYPE_CRITTER && _critter_flag_check(critter->pid, 64)) {
|
||||
if (critter != NULL && PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER && _critter_flag_check(critter->pid, CRITTER_FLAG_0x40)) {
|
||||
flags |= DAM_DROP;
|
||||
}
|
||||
|
||||
|
@ -4015,7 +4015,7 @@ static int attackComputeCriticalFailure(Attack* attack)
|
|||
{
|
||||
attack->attackerFlags |= DAM_HIT;
|
||||
|
||||
if (attack->attacker != NULL && _critter_flag_check(attack->attacker->pid, 1024)) {
|
||||
if (attack->attacker != NULL && _critter_flag_check(attack->attacker->pid, CRITTER_FLAG_0x400)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4141,7 +4141,7 @@ static int attackDetermineToHit(Object* attacker, int tile, Object* defender, in
|
|||
Object* weapon = critterGetWeaponForHitMode(attacker, hitMode);
|
||||
|
||||
bool targetIsCritter = defender != NULL
|
||||
? ((defender->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER
|
||||
? FID_TYPE(defender->fid) == OBJ_TYPE_CRITTER
|
||||
: false;
|
||||
|
||||
bool isRangedWeapon = false;
|
||||
|
@ -4323,7 +4323,7 @@ static int attackDetermineToHit(Object* attacker, int tile, Object* defender, in
|
|||
}
|
||||
|
||||
// 0x4247B8
|
||||
static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
||||
static void attackComputeDamage(Attack* attack, int ammoQuantity, int bonusDamageMultiplier)
|
||||
{
|
||||
int* damagePtr;
|
||||
Object* critter;
|
||||
|
@ -4344,7 +4344,7 @@ static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
|||
|
||||
*damagePtr = 0;
|
||||
|
||||
if ((critter->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4398,7 +4398,7 @@ static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
|||
damageResistance = 0;
|
||||
}
|
||||
|
||||
int damageMultiplier = a3 * weaponGetAmmoDamageMultiplier(attack->weapon);
|
||||
int damageMultiplier = bonusDamageMultiplier * weaponGetAmmoDamageMultiplier(attack->weapon);
|
||||
int damageDivisor = weaponGetAmmoDamageDivisor(attack->weapon);
|
||||
|
||||
for (int index = 0; index < ammoQuantity; index++) {
|
||||
|
@ -4447,8 +4447,8 @@ static void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
|
|||
if (knockbackDistancePtr != NULL
|
||||
&& (critter->flags & OBJECT_MULTIHEX) == 0
|
||||
&& (damageType == DAMAGE_TYPE_EXPLOSION || attack->weapon == NULL || weaponGetAttackTypeForHitMode(attack->weapon, attack->hitMode) == ATTACK_TYPE_MELEE)
|
||||
&& (critter->pid >> 24) == OBJ_TYPE_CRITTER
|
||||
&& _critter_flag_check(critter->pid, 0x4000) == 0) {
|
||||
&& PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER
|
||||
&& _critter_flag_check(critter->pid, CRITTER_FLAG_0x4000) == 0) {
|
||||
bool shouldKnockback = true;
|
||||
bool hasStonewall = false;
|
||||
if (critter == gDude) {
|
||||
|
@ -4488,7 +4488,7 @@ void attackComputeDeathFlags(Attack* attack)
|
|||
void _apply_damage(Attack* attack, bool animated)
|
||||
{
|
||||
Object* attacker = attack->attacker;
|
||||
bool attackerIsCritter = attacker != NULL && (attacker->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER;
|
||||
bool attackerIsCritter = attacker != NULL && FID_TYPE(attacker->fid) == OBJ_TYPE_CRITTER;
|
||||
bool v5 = attack->defender != attack->oops;
|
||||
|
||||
if (attackerIsCritter && (attacker->data.critter.combat.results & DAM_DEAD) != 0) {
|
||||
|
@ -4503,7 +4503,7 @@ void _apply_damage(Attack* attack, bool animated)
|
|||
}
|
||||
|
||||
Object* defender = attack->defender;
|
||||
bool defenderIsCritter = defender != NULL && (defender->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER;
|
||||
bool defenderIsCritter = defender != NULL && FID_TYPE(defender->fid) == OBJ_TYPE_CRITTER;
|
||||
|
||||
if (!defenderIsCritter && !v5) {
|
||||
bool v9 = objectIsPartyMember(attack->defender) && objectIsPartyMember(attack->attacker) ? false : true;
|
||||
|
@ -4549,7 +4549,7 @@ void _apply_damage(Attack* attack, bool animated)
|
|||
|
||||
for (int index = 0; index < attack->extrasLength; index++) {
|
||||
Object* obj = attack->extras[index];
|
||||
if ((obj->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER && (obj->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_CRITTER && (obj->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||
_set_new_results(obj, attack->extrasFlags[index]);
|
||||
|
||||
if (defenderIsCritter) {
|
||||
|
@ -4579,8 +4579,8 @@ void _apply_damage(Attack* attack, bool animated)
|
|||
// 0x424EE8
|
||||
static void _check_for_death(Object* object, int damage, int* flags)
|
||||
{
|
||||
if (object == NULL || !_critter_flag_check(object->pid, 0x0400)) {
|
||||
if (object == NULL || (object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (object == NULL || !_critter_flag_check(object->pid, CRITTER_FLAG_0x400)) {
|
||||
if (object == NULL || PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (damage > 0) {
|
||||
if (critterGetHitPoints(object) - damage <= 0) {
|
||||
*flags |= DAM_DEAD;
|
||||
|
@ -4597,15 +4597,15 @@ static void _set_new_results(Object* critter, int flags)
|
|||
return;
|
||||
}
|
||||
|
||||
if (((critter->fid & 0xF000000) >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(critter->fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_critter_flag_check(critter->pid, 0x0400)) {
|
||||
if (_critter_flag_check(critter->pid, CRITTER_FLAG_0x400)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4635,11 +4635,11 @@ static void _damage_object(Object* a1, int damage, bool animated, int a4, Object
|
|||
return;
|
||||
}
|
||||
|
||||
if ((a1->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(a1->fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_critter_flag_check(a1->pid, 1024)) {
|
||||
if (_critter_flag_check(a1->pid, CRITTER_FLAG_0x400)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4764,7 +4764,7 @@ void _combat_display(Attack* attack)
|
|||
&& attack->oops != NULL
|
||||
&& attack->defender != attack->oops
|
||||
&& (attack->attackerFlags & DAM_HIT) != 0) {
|
||||
if ((attack->defender->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(attack->defender->fid) == OBJ_TYPE_CRITTER) {
|
||||
if (attack->oops == gDude) {
|
||||
// 608 (male) - Oops! %s was hit instead of you!
|
||||
// 708 (female) - Oops! %s was hit instead of you!
|
||||
|
@ -4820,7 +4820,7 @@ void _combat_display(Attack* attack)
|
|||
if (v21 != NULL && (v21->data.critter.combat.results & DAM_DEAD) == 0) {
|
||||
text[0] = '\0';
|
||||
|
||||
if ((v21->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(v21->fid) == OBJ_TYPE_CRITTER) {
|
||||
if (attack->defenderHitLocation == HIT_LOCATION_TORSO) {
|
||||
if ((attack->attackerFlags & DAM_CRITICAL) != 0) {
|
||||
switch (attack->defenderDamage) {
|
||||
|
@ -5233,7 +5233,7 @@ static void _combat_standup(Object* a1)
|
|||
static void _print_tohit(unsigned char* dest, int destPitch, int accuracy)
|
||||
{
|
||||
CacheEntry* numbersFrmHandle;
|
||||
int numbersFrmFid = buildFid(6, 82, 0, 0, 0);
|
||||
int numbersFrmFid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0);
|
||||
unsigned char* numbersFrmData = artLockFrameData(numbersFrmFid, 0, 0, &numbersFrmHandle);
|
||||
if (numbersFrmData == NULL) {
|
||||
return;
|
||||
|
@ -5325,7 +5325,7 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
|
|||
|
||||
unsigned char* windowBuffer = windowGetBuffer(gCalledShotWindow);
|
||||
|
||||
fid = buildFid(6, 118, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 118, 0, 0, 0);
|
||||
data = artLockFrameData(fid, 0, 0, &handle);
|
||||
if (data == NULL) {
|
||||
windowDestroy(gCalledShotWindow);
|
||||
|
@ -5335,14 +5335,14 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
|
|||
blitBufferToBuffer(data, CALLED_SHOT_WINDOW_WIDTH, CALLED_SHOT_WINDOW_HEIGHT, CALLED_SHOT_WINDOW_WIDTH, windowBuffer, CALLED_SHOT_WINDOW_WIDTH);
|
||||
artUnlock(handle);
|
||||
|
||||
fid = buildFid(1, critter->fid & 0xFFF, ANIM_CALLED_SHOT_PIC, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_CALLED_SHOT_PIC, 0, 0);
|
||||
data = artLockFrameData(fid, 0, 0, &handle);
|
||||
if (data != NULL) {
|
||||
blitBufferToBuffer(data, 170, 225, 170, windowBuffer + CALLED_SHOT_WINDOW_WIDTH * 31 + 168, CALLED_SHOT_WINDOW_WIDTH);
|
||||
artUnlock(handle);
|
||||
}
|
||||
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
|
||||
CacheEntry* upHandle;
|
||||
unsigned char* up = artLockFrameData(fid, 0, 0, &upHandle);
|
||||
|
@ -5351,7 +5351,7 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
|
|||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
|
||||
CacheEntry* downHandle;
|
||||
unsigned char* down = artLockFrameData(fid, 0, 0, &downHandle);
|
||||
|
@ -5710,7 +5710,7 @@ bool _combat_is_shot_blocked(Object* a1, int from, int to, Object* a4, int* a5)
|
|||
while (obstacle != NULL && current != to) {
|
||||
_make_straight_path_func(a1, current, to, 0, &obstacle, 32, _obj_shoot_blocking_at);
|
||||
if (obstacle != NULL) {
|
||||
if ((obstacle->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER && obstacle != a4) {
|
||||
if (FID_TYPE(obstacle->fid) != OBJ_TYPE_CRITTER && obstacle != a4) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef COMBAT_H
|
||||
#define COMBAT_H
|
||||
|
||||
#include "db.h"
|
||||
#include "combat_defs.h"
|
||||
#include "db.h"
|
||||
#include "obj_types.h"
|
||||
#include "proto_types.h"
|
||||
|
||||
|
@ -35,7 +35,7 @@ void _combat(STRUCT_664980* attack);
|
|||
void attackInit(Attack* attack, Object* a2, Object* a3, int a4, int a5);
|
||||
int _combat_attack(Object* a1, Object* a2, int a3, int a4);
|
||||
int _combat_bullet_start(const Object* a1, const Object* a2);
|
||||
void _compute_explosion_on_extras(Attack* attack, int a2, int a3, int a4);
|
||||
void _compute_explosion_on_extras(Attack* attack, int a2, bool isGrenade, int a4);
|
||||
int _determine_to_hit(Object* a1, Object* a2, int hitLocation, int hitMode);
|
||||
int _determine_to_hit_no_range(Object* a1, Object* a2, int a3, int a4, unsigned char* a5);
|
||||
int _determine_to_hit_from_tile(Object* a1, int a2, Object* a3, int a4, int a5);
|
||||
|
|
|
@ -568,7 +568,7 @@ int aiLoad(File* stream)
|
|||
{
|
||||
for (int index = 0; index < gPartyMemberDescriptionsLength; index++) {
|
||||
int pid = gPartyMemberPids[index];
|
||||
if (pid != -1 && (pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (pid != -1 && PID_TYPE(pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(pid, &proto) == -1) {
|
||||
return -1;
|
||||
|
@ -589,7 +589,7 @@ int aiSave(File* stream)
|
|||
{
|
||||
for (int index = 0; index < gPartyMemberDescriptionsLength; index++) {
|
||||
int pid = gPartyMemberPids[index];
|
||||
if (pid != -1 && (pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (pid != -1 && PID_TYPE(pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(pid, &proto) == -1) {
|
||||
return -1;
|
||||
|
@ -897,9 +897,9 @@ int aiSetDisposition(Object* obj, int disposition)
|
|||
// 0x428398
|
||||
static int _ai_magic_hands(Object* critter, Object* item, int num)
|
||||
{
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
reg_anim_animate(critter, ANIM_MAGIC_HANDS_MIDDLE, 0);
|
||||
animationRegisterAnimate(critter, ANIM_MAGIC_HANDS_MIDDLE, 0);
|
||||
|
||||
if (reg_anim_end() == 0) {
|
||||
if (isInCombat()) {
|
||||
|
@ -1128,9 +1128,9 @@ static void _ai_run_away(Object* a1, Object* a2)
|
|||
}
|
||||
|
||||
if (actionPoints > 0) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
_combatai_msg(a1, NULL, AI_MESSAGE_TYPE_RUN, 0);
|
||||
reg_anim_obj_run_to_tile(a1, destination, a1->elevation, combatData->ap, 0);
|
||||
animationRegisterRunToTile(a1, destination, a1->elevation, combatData->ap, 0);
|
||||
if (reg_anim_end() == 0) {
|
||||
_combat_turn_run();
|
||||
}
|
||||
|
@ -1175,8 +1175,8 @@ static int _ai_move_away(Object* a1, Object* a2, int a3)
|
|||
}
|
||||
|
||||
if (actionPoints > 0) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_obj_move_to_tile(a1, destination, a1->elevation, actionPoints, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterMoveToTile(a1, destination, a1->elevation, actionPoints, 0);
|
||||
if (reg_anim_end() == 0) {
|
||||
_combat_turn_run();
|
||||
}
|
||||
|
@ -1560,8 +1560,8 @@ int _caiSetupTeamCombat(Object* a1, Object* a2)
|
|||
|
||||
obj = objectFindFirstAtElevation(a1->elevation);
|
||||
while (obj != NULL) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER && obj != gDude) {
|
||||
obj->data.critter.combat.maneuver |= 0x01;
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER && obj != gDude) {
|
||||
obj->data.critter.combat.maneuver |= CRITTER_MANEUVER_0x01;
|
||||
}
|
||||
obj = objectFindNextAtElevation();
|
||||
}
|
||||
|
@ -1719,7 +1719,7 @@ static Object* _ai_best_weapon(Object* attacker, Object* weapon1, Object* weapon
|
|||
avgDamage1 = (maxDamage - minDamage) / 2;
|
||||
if (_item_w_area_damage_radius(weapon1, HIT_MODE_RIGHT_WEAPON_PRIMARY) > 0 && defender != NULL) {
|
||||
attack.weapon = weapon1;
|
||||
_compute_explosion_on_extras(&attack, 0, _item_w_is_grenade(weapon1), 1);
|
||||
_compute_explosion_on_extras(&attack, 0, weaponIsGrenade(weapon1), 1);
|
||||
avgDamage1 *= attack.extrasLength + 1;
|
||||
}
|
||||
|
||||
|
@ -1763,7 +1763,7 @@ static Object* _ai_best_weapon(Object* attacker, Object* weapon1, Object* weapon
|
|||
avgDamage2 = (maxDamage - minDamage) / 2;
|
||||
if (_item_w_area_damage_radius(weapon2, HIT_MODE_RIGHT_WEAPON_PRIMARY) > 0 && defender != NULL) {
|
||||
attack.weapon = weapon2;
|
||||
_compute_explosion_on_extras(&attack, 0, _item_w_is_grenade(weapon2), 1);
|
||||
_compute_explosion_on_extras(&attack, 0, weaponIsGrenade(weapon2), 1);
|
||||
avgDamage2 *= attack.extrasLength + 1;
|
||||
}
|
||||
|
||||
|
@ -1842,7 +1842,7 @@ static bool _ai_can_use_weapon(Object* critter, Object* weapon, int hitMode)
|
|||
int rotation = critter->rotation + 1;
|
||||
int animationCode = weaponGetAnimationCode(weapon);
|
||||
int v9 = weaponGetAnimationForHitMode(weapon, hitMode);
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, v9, animationCode, rotation);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, v9, animationCode, rotation);
|
||||
if (!artExists(fid)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2194,7 +2194,7 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
|
|||
return -1;
|
||||
}
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
if (a4) {
|
||||
_combatai_msg(a1, NULL, AI_MESSAGE_TYPE_MOVE, 0);
|
||||
|
@ -2214,7 +2214,7 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
|
|||
_moveBlockObj = NULL;
|
||||
if (pathfinderFindPath(a1, a1->tile, a2->tile, NULL, 0, _obj_ai_blocking_at) == 0
|
||||
&& _moveBlockObj != NULL
|
||||
&& (_moveBlockObj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
&& PID_TYPE(_moveBlockObj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (shouldUnhide) {
|
||||
a2->flags &= ~OBJECT_HIDDEN;
|
||||
}
|
||||
|
@ -2240,15 +2240,15 @@ static int _ai_move_steps_closer(Object* a1, Object* a2, int actionPoints, int a
|
|||
|
||||
if (actionPoints >= critterGetStat(a1, STAT_MAXIMUM_ACTION_POINTS) / 2 && artCritterFidShouldRun(a1->fid)) {
|
||||
if ((a2->flags & OBJECT_MULTIHEX) != 0) {
|
||||
reg_anim_obj_run_to_obj(a1, a2, actionPoints, 0);
|
||||
animationRegisterRunToObject(a1, a2, actionPoints, 0);
|
||||
} else {
|
||||
reg_anim_obj_run_to_tile(a1, tile, a1->elevation, actionPoints, 0);
|
||||
animationRegisterRunToTile(a1, tile, a1->elevation, actionPoints, 0);
|
||||
}
|
||||
} else {
|
||||
if ((a2->flags & OBJECT_MULTIHEX) != 0) {
|
||||
reg_anim_obj_move_to_obj(a1, a2, actionPoints, 0);
|
||||
animationRegisterMoveToObject(a1, a2, actionPoints, 0);
|
||||
} else {
|
||||
reg_anim_obj_move_to_tile(a1, tile, a1->elevation, actionPoints, 0);
|
||||
animationRegisterMoveToTile(a1, tile, a1->elevation, actionPoints, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2490,8 +2490,8 @@ static int _ai_attack(Object* a1, Object* a2, int a3)
|
|||
return -1;
|
||||
}
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_set_rotation_to_tile(a1, a2->tile);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterRotateToTile(a1, a2->tile);
|
||||
reg_anim_end();
|
||||
_combat_turn_run();
|
||||
|
||||
|
@ -2527,7 +2527,7 @@ static int _ai_try_attack(Object* a1, Object* a2)
|
|||
if (weapon == NULL) {
|
||||
if (critterGetBodyType(a2) != BODY_TYPE_BIPED
|
||||
|| ((a2->fid & 0xF000) >> 12 != 0)
|
||||
|| !artExists(buildFid(1, a1->fid & 0xFFF, ANIM_THROW_PUNCH, 0, a1->rotation + 1))
|
||||
|| !artExists(buildFid(OBJ_TYPE_CRITTER, a1->fid & 0xFFF, ANIM_THROW_PUNCH, 0, a1->rotation + 1))
|
||||
|| _combat_safety_invalidate_weapon(a1, weapon, HIT_MODE_RIGHT_WEAPON_PRIMARY, a2, &v31)) {
|
||||
_ai_switch_weapons(a1, &hitMode, &weapon, a2);
|
||||
}
|
||||
|
@ -2813,8 +2813,8 @@ int _cai_perform_distance_prefs(Object* a1, Object* a2)
|
|||
|
||||
int tile = a1->tile;
|
||||
if (_cai_retargetTileFromFriendlyFire(a1, a2, &tile) == 0 && tile != a1->tile) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_obj_move_to_tile(a1, tile, a1->elevation, a1->data.critter.combat.ap, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterMoveToTile(a1, tile, a1->elevation, a1->data.critter.combat.ap, 0);
|
||||
if (reg_anim_end() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -3017,7 +3017,7 @@ bool _combatai_want_to_stop(Object* a1)
|
|||
// 0x42B504
|
||||
int critterSetTeam(Object* obj, int team)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3065,7 +3065,7 @@ int critterSetTeam(Object* obj, int team)
|
|||
// 0x42B5D4
|
||||
int critterSetAiPacket(Object* object, int aiPacket)
|
||||
{
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3087,7 +3087,7 @@ int critterSetAiPacket(Object* object, int aiPacket)
|
|||
// 0x42B634
|
||||
int _combatai_msg(Object* a1, Attack* attack, int type, int delay)
|
||||
{
|
||||
if ((a1->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a1->pid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3162,7 +3162,7 @@ int _combatai_msg(Object* a1, Attack* attack, int type, int delay)
|
|||
strncpy(string, messageListItem.text, 259);
|
||||
|
||||
// TODO: Get rid of casts.
|
||||
return reg_anim_11_0(a1, (Object*)type, (AnimationProc*)_ai_print_msg, delay);
|
||||
return animationRegisterCallback(a1, (void*)type, (AnimationCallback*)_ai_print_msg, delay);
|
||||
}
|
||||
|
||||
// 0x42B80C
|
||||
|
@ -3245,7 +3245,7 @@ static int _combatai_rating(Object* obj)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ((obj->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(obj->fid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,12 +84,12 @@ typedef enum HitLocation {
|
|||
HIT_LOCATION_SPECIFIC_COUNT = HIT_LOCATION_COUNT - 1,
|
||||
} HitLocation;
|
||||
|
||||
typedef struct STRUCT_510948 {
|
||||
Object* field_0;
|
||||
Object* field_4;
|
||||
Object* field_8;
|
||||
int field_C;
|
||||
} STRUCT_510948;
|
||||
typedef struct CombatAIInfo {
|
||||
Object* friendlyDead;
|
||||
Object* lastTarget;
|
||||
Object* lastItem;
|
||||
int lastMove;
|
||||
} CombatAIInfo;
|
||||
|
||||
typedef struct STRUCT_664980 {
|
||||
Object* attacker;
|
||||
|
|
|
@ -81,25 +81,20 @@ bool configParseCommandLineArguments(Config* config, int argc, char** argv)
|
|||
}
|
||||
|
||||
for (int arg = 0; arg < argc; arg++) {
|
||||
char* pch = argv[arg];
|
||||
char* pch;
|
||||
char* string = argv[arg];
|
||||
|
||||
// Find opening bracket.
|
||||
while (*pch != '\0' && *pch != '[') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == '\0') {
|
||||
pch = strchr(string, '[');
|
||||
if (pch == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char* sectionKey = pch + 1;
|
||||
|
||||
// Find closing bracket.
|
||||
while (*pch != '\0' && *pch != ']') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == '\0') {
|
||||
pch = strchr(sectionKey, ']');
|
||||
if (pch == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -189,7 +184,7 @@ bool configSetString(Config* config, const char* sectionKey, const char* key, co
|
|||
}
|
||||
|
||||
// 0x42C05C
|
||||
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr, unsigned char base /* = 0 */ )
|
||||
bool configGetInt(Config* config, const char* sectionKey, const char* key, int* valuePtr, unsigned char base /* = 0 */)
|
||||
{
|
||||
if (valuePtr == NULL) {
|
||||
return false;
|
||||
|
@ -233,36 +228,30 @@ bool configGetIntList(Config* config, const char* sectionKey, const char* key, i
|
|||
}
|
||||
|
||||
char temp[CONFIG_FILE_MAX_LINE_LENGTH];
|
||||
strncpy(temp, string, CONFIG_FILE_MAX_LINE_LENGTH - 1);
|
||||
string = strncpy(temp, string, CONFIG_FILE_MAX_LINE_LENGTH - 1);
|
||||
|
||||
char* beginning = temp;
|
||||
char* pch = beginning;
|
||||
while (*pch != '\0') {
|
||||
if (*pch == ',') {
|
||||
*pch = '\0';
|
||||
|
||||
*arr++ = atoi(beginning);
|
||||
|
||||
*pch = ',';
|
||||
|
||||
pch++;
|
||||
beginning = pch;
|
||||
|
||||
count--;
|
||||
|
||||
if (count < 0) {
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
char* pch = strchr(string, ',');
|
||||
if (pch == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
pch++;
|
||||
count--;
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
*pch = '\0';
|
||||
*arr++ = atoi(string);
|
||||
string = pch + 1;
|
||||
}
|
||||
|
||||
if (count <= 1) {
|
||||
*arr = atoi(beginning);
|
||||
*arr = atoi(string);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0x42C160
|
||||
|
@ -383,30 +372,19 @@ static bool configParseLine(Config* config, char* string)
|
|||
char* pch;
|
||||
|
||||
// Find comment marker and truncate the string.
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != ';') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, ';');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
// Find opening bracket.
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != '[') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == '[') {
|
||||
pch = strchr(string, '[');
|
||||
if (pch != NULL) {
|
||||
char* sectionKey = pch + 1;
|
||||
|
||||
// Find closing bracket.
|
||||
while (*pch != '\0' && *pch != ']') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == ']') {
|
||||
pch = strchr(sectionKey, ']');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
strcpy(gConfigLastSectionKey, sectionKey);
|
||||
return configTrimString(gConfigLastSectionKey);
|
||||
|
@ -435,12 +413,8 @@ static bool configParseKeyValue(char* string, char* key, char* value)
|
|||
}
|
||||
|
||||
// Find equals character.
|
||||
char* pch = string;
|
||||
while (*pch != '\0' && *pch != '=') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch == '\0') {
|
||||
char* pch = strchr(string, '=');
|
||||
if (pch == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
513
src/core.cc
513
src/core.cc
|
@ -1,8 +1,8 @@
|
|||
#include "core.h"
|
||||
|
||||
#include "audio_engine.h"
|
||||
#include "config.h"
|
||||
#include "color.h"
|
||||
#include "config.h"
|
||||
#include "dinput.h"
|
||||
#include "draw.h"
|
||||
#include "interface.h"
|
||||
|
@ -13,9 +13,9 @@
|
|||
#include "window_manager.h"
|
||||
#include "window_manager_private.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
// NOT USED.
|
||||
void (*_idle_func)() = NULL;
|
||||
|
@ -116,39 +116,48 @@ int gModifierKeysState = 0;
|
|||
int (*_kb_scan_to_ascii)() = keyboardDequeueLogicalKeyCode;
|
||||
|
||||
// 0x51E2F0
|
||||
STRUCT_51E2F0* _vcr_buffer = NULL;
|
||||
VcrEntry* _vcr_buffer = NULL;
|
||||
|
||||
// number of entries in _vcr_buffer
|
||||
// 0x51E2F4
|
||||
int _vcr_buffer_index = 0;
|
||||
|
||||
// 0x51E2F8
|
||||
int _vcr_state = 2;
|
||||
unsigned int gVcrState = VCR_STATE_TURNED_OFF;
|
||||
|
||||
// 0x51E2FC
|
||||
int _vcr_time = 0;
|
||||
unsigned int _vcr_time = 0;
|
||||
|
||||
// 0x51E300
|
||||
int _vcr_counter = 0;
|
||||
unsigned int _vcr_counter = 0;
|
||||
|
||||
// 0x51E304
|
||||
int _vcr_terminate_flags = 0;
|
||||
unsigned int gVcrTerminateFlags = 0;
|
||||
|
||||
// 0x51E308
|
||||
int _vcr_terminated_condition = 0;
|
||||
int gVcrPlaybackCompletionReason = VCR_PLAYBACK_COMPLETION_REASON_NONE;
|
||||
|
||||
// 0x51E30C
|
||||
int _vcr_start_time = 0;
|
||||
unsigned int _vcr_start_time = 0;
|
||||
|
||||
// 0x51E310
|
||||
int _vcr_registered_atexit = 0;
|
||||
|
||||
// 0x51E314
|
||||
File* _vcr_file = NULL;
|
||||
File* gVcrFile = NULL;
|
||||
|
||||
// 0x51E318
|
||||
int _vcr_buffer_end = 0;
|
||||
|
||||
// 0x51E31C
|
||||
VcrPlaybackCompletionCallback* gVcrPlaybackCompletionCallback = NULL;
|
||||
|
||||
// 0x51E320
|
||||
unsigned int gVcrRequestedTerminationFlags = 0;
|
||||
|
||||
// 0x51E324
|
||||
int gVcrOldKeyboardLayout = 0;
|
||||
|
||||
// A map of SDL_SCANCODE_* constants normalized for QWERTY keyboard.
|
||||
//
|
||||
// 0x6ABC70
|
||||
|
@ -355,6 +364,9 @@ int gKeyboardLayout;
|
|||
// 0x6AD93C
|
||||
unsigned char gPressedPhysicalKeysCount;
|
||||
|
||||
// 0x6AD940
|
||||
VcrEntry stru_6AD940;
|
||||
|
||||
SDL_Window* gSdlWindow = NULL;
|
||||
SDL_Surface* gSdlSurface = NULL;
|
||||
SDL_Renderer* gSdlRenderer = NULL;
|
||||
|
@ -446,7 +458,7 @@ void _process_bk()
|
|||
|
||||
tickersExecute();
|
||||
|
||||
if (_vcr_update() != 3) {
|
||||
if (vcrUpdate() != 3) {
|
||||
_mouse_info();
|
||||
}
|
||||
|
||||
|
@ -629,31 +641,37 @@ void pauseGame()
|
|||
// 0x4C8E38
|
||||
int pauseHandlerDefaultImpl()
|
||||
{
|
||||
int len;
|
||||
int v1;
|
||||
int v2;
|
||||
int win;
|
||||
unsigned char* buf;
|
||||
int v6;
|
||||
int v7;
|
||||
int windowWidth = fontGetStringWidth("Paused") + 32;
|
||||
int windowHeight = 3 * fontGetLineHeight() + 16;
|
||||
|
||||
len = fontGetStringWidth("Paused") + 32;
|
||||
v1 = fontGetLineHeight();
|
||||
v2 = 3 * v1 + 16;
|
||||
|
||||
win = windowCreate((_scr_size.right - _scr_size.left + 1 - len) / 2, (_scr_size.bottom - _scr_size.top + 1 - v2) / 2, len, v2, 256, 20);
|
||||
int win = windowCreate((rectGetWidth(&_scr_size) - windowWidth) / 2,
|
||||
(rectGetHeight(&_scr_size) - windowHeight) / 2,
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
256,
|
||||
WINDOW_FLAG_0x10 | WINDOW_FLAG_0x04);
|
||||
if (win == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
windowDrawBorder(win);
|
||||
buf = windowGetBuffer(win);
|
||||
fontDrawText(buf + 8 * len + 16, "Paused", len, len, _colorTable[31744]);
|
||||
|
||||
v6 = v2 - 8 - v1;
|
||||
v7 = fontGetStringWidth("Done");
|
||||
// TODO: Incomplete.
|
||||
// _win_register_text_button(win, (len - v7 - 16) / 2, v6 - 6, -1, -1, -1, 27, "Done", 0);
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
fontDrawText(windowBuffer + 8 * windowWidth + 16,
|
||||
"Paused",
|
||||
windowWidth,
|
||||
windowWidth,
|
||||
_colorTable[31744]);
|
||||
|
||||
_win_register_text_button(win,
|
||||
(windowWidth - fontGetStringWidth("Done") - 16) / 2,
|
||||
windowHeight - 8 - fontGetLineHeight() - 6,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
"Done",
|
||||
0);
|
||||
|
||||
windowRefresh(win);
|
||||
|
||||
|
@ -720,7 +738,7 @@ int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, uns
|
|||
|
||||
for (index = 0; index < 100000; index++) {
|
||||
sprintf(fileName, "scr%.5d.bmp", index);
|
||||
|
||||
|
||||
stream = compat_fopen(fileName, "rb");
|
||||
if (stream == NULL) {
|
||||
break;
|
||||
|
@ -784,7 +802,7 @@ int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, uns
|
|||
// biCompression
|
||||
intValue = 0;
|
||||
fwrite(&intValue, sizeof(intValue), 1, stream);
|
||||
|
||||
|
||||
// biSizeImage
|
||||
intValue = 0;
|
||||
fwrite(&intValue, sizeof(intValue), 1, stream);
|
||||
|
@ -1324,10 +1342,10 @@ void _GNW95_process_key(KeyboardData* data)
|
|||
{
|
||||
data->key = gNormalizedQwertyKeys[data->key];
|
||||
|
||||
if (_vcr_state == 1) {
|
||||
if (_vcr_terminate_flags & 1) {
|
||||
_vcr_terminated_condition = 2;
|
||||
_vcr_stop();
|
||||
if (gVcrState == VCR_STATE_PLAYING) {
|
||||
if ((gVcrTerminateFlags & VCR_TERMINATE_ON_KEY_PRESS) != 0) {
|
||||
gVcrPlaybackCompletionReason = VCR_PLAYBACK_COMPLETION_REASON_TERMINATED;
|
||||
vcrStop();
|
||||
}
|
||||
} else {
|
||||
STRUCT_6ABF50* ptr = &(_GNW95_key_time_stamps[data->key]);
|
||||
|
@ -1643,10 +1661,11 @@ void _mouse_info()
|
|||
x = (int)(x * gMouseSensitivity);
|
||||
y = (int)(y * gMouseSensitivity);
|
||||
|
||||
if (_vcr_state == 1) {
|
||||
if (((_vcr_terminate_flags & 4) && buttons) || ((_vcr_terminate_flags & 2) && (x || y))) {
|
||||
_vcr_terminated_condition = 2;
|
||||
_vcr_stop();
|
||||
if (gVcrState == VCR_STATE_PLAYING) {
|
||||
if (((gVcrTerminateFlags & VCR_TERMINATE_ON_MOUSE_PRESS) != 0 && buttons != 0)
|
||||
|| ((gVcrTerminateFlags & VCR_TERMINATE_ON_MOUSE_MOVE) != 0 && (x != 0 || y != 0))) {
|
||||
gVcrPlaybackCompletionReason = VCR_PLAYBACK_COMPLETION_REASON_TERMINATED;
|
||||
vcrStop();
|
||||
return;
|
||||
}
|
||||
x = 0;
|
||||
|
@ -1665,18 +1684,18 @@ void _mouse_simulate_input(int delta_x, int delta_y, int buttons)
|
|||
}
|
||||
|
||||
if (delta_x || delta_y || buttons != gMouseButtonsState) {
|
||||
if (_vcr_state == 0) {
|
||||
if (_vcr_buffer_index == 4095) {
|
||||
_vcr_dump_buffer();
|
||||
if (gVcrState == 0) {
|
||||
if (_vcr_buffer_index == VCR_BUFFER_CAPACITY - 1) {
|
||||
vcrDump();
|
||||
}
|
||||
|
||||
STRUCT_51E2F0* ptr = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
ptr->type = 3;
|
||||
ptr->field_4 = _vcr_time;
|
||||
ptr->field_8 = _vcr_counter;
|
||||
ptr->dx = delta_x;
|
||||
ptr->dy = delta_y;
|
||||
ptr->buttons = buttons;
|
||||
VcrEntry* vcrEntry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
vcrEntry->type = VCR_ENTRY_TYPE_MOUSE_EVENT;
|
||||
vcrEntry->time = _vcr_time;
|
||||
vcrEntry->counter = _vcr_counter;
|
||||
vcrEntry->mouseEvent.dx = delta_x;
|
||||
vcrEntry->mouseEvent.dy = delta_y;
|
||||
vcrEntry->mouseEvent.buttons = buttons;
|
||||
|
||||
_vcr_buffer_index++;
|
||||
}
|
||||
|
@ -1996,10 +2015,10 @@ int _GNW95_init_mode_ex(int width, int height, int bpp)
|
|||
_zero_mem = _GNW95_zero_vid_mem;
|
||||
_mouse_blit = _GNW95_ShowRect;
|
||||
} else {
|
||||
_zero_mem = NULL;
|
||||
_mouse_blit = _GNW95_MouseShowRect16;
|
||||
_mouse_blit_trans = _GNW95_MouseShowTransRect16;
|
||||
_scr_blit = _GNW95_ShowRect16;
|
||||
_zero_mem = NULL;
|
||||
_mouse_blit = _GNW95_MouseShowRect16;
|
||||
_mouse_blit_trans = _GNW95_MouseShowTransRect16;
|
||||
_scr_blit = _GNW95_ShowRect16;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2036,7 +2055,7 @@ int _GNW95_init_window(int width, int height, bool fullscreen)
|
|||
if (gSdlRenderer == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
if (SDL_RenderSetLogicalSize(gSdlRenderer, width, height) != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
@ -2214,7 +2233,7 @@ void directDrawSetPaletteInRange(unsigned char* palette, int start, int count)
|
|||
void directDrawSetPalette(unsigned char* palette)
|
||||
{
|
||||
if (gSdlSurface != NULL && gSdlSurface->format->palette != NULL) {
|
||||
SDL_Color colors[256];
|
||||
SDL_Color colors[256];
|
||||
|
||||
for (int index = 0; index < 256; index++) {
|
||||
colors[index].r = palette[index * 3] << 2;
|
||||
|
@ -2251,7 +2270,6 @@ void directDrawSetPalette(unsigned char* palette)
|
|||
windowRefreshAll(&_scr_size);
|
||||
}
|
||||
|
||||
|
||||
if (_update_palette_func != NULL) {
|
||||
_update_palette_func();
|
||||
}
|
||||
|
@ -2555,13 +2573,14 @@ int keyboardGetLayout()
|
|||
// TODO: Key type is likely short.
|
||||
void _kb_simulate_key(KeyboardData* data)
|
||||
{
|
||||
if (_vcr_state == 0) {
|
||||
if (_vcr_buffer_index != 4095) {
|
||||
STRUCT_51E2F0* ptr = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
ptr->type = 2;
|
||||
ptr->type_2_field_C = data->key & 0xFFFF;
|
||||
ptr->field_4 = _vcr_time;
|
||||
ptr->field_8 = _vcr_counter;
|
||||
if (gVcrState == 0) {
|
||||
if (_vcr_buffer_index != VCR_BUFFER_CAPACITY - 1) {
|
||||
VcrEntry* vcrEntry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
vcrEntry->type = VCR_ENTRY_TYPE_KEYBOARD_EVENT;
|
||||
vcrEntry->keyboardEvent.key = data->key & 0xFFFF;
|
||||
vcrEntry->time = _vcr_time;
|
||||
vcrEntry->counter = _vcr_counter;
|
||||
|
||||
_vcr_buffer_index++;
|
||||
}
|
||||
}
|
||||
|
@ -4359,9 +4378,9 @@ int keyboardPeekEvent(int index, KeyboardEvent** keyboardEventPtr)
|
|||
}
|
||||
|
||||
// 0x4D2680
|
||||
bool _vcr_record(const char* fileName)
|
||||
bool vcrRecord(const char* fileName)
|
||||
{
|
||||
if (_vcr_state != 2) {
|
||||
if (gVcrState != VCR_STATE_TURNED_OFF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4369,77 +4388,260 @@ bool _vcr_record(const char* fileName)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (_vcr_buffer != NULL) {
|
||||
// NOTE: Uninline.
|
||||
if (!vcrInitBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_vcr_buffer = (STRUCT_51E2F0*)internal_malloc(sizeof(*_vcr_buffer) * 4096);
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_vcr_clear_buffer();
|
||||
|
||||
_vcr_file = fileOpen(fileName, "wb");
|
||||
if (_vcr_file == NULL) {
|
||||
if (_vcr_buffer != NULL) {
|
||||
_vcr_clear_buffer();
|
||||
internal_free(_vcr_buffer);
|
||||
_vcr_buffer = NULL;
|
||||
}
|
||||
gVcrFile = fileOpen(fileName, "wb");
|
||||
if (gVcrFile == NULL) {
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_vcr_registered_atexit == 0) {
|
||||
_vcr_registered_atexit = atexit(_vcr_stop);
|
||||
_vcr_registered_atexit = atexit(vcrStop);
|
||||
}
|
||||
|
||||
STRUCT_51E2F0* entry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
entry->type = 1;
|
||||
entry->field_4 = 0;
|
||||
entry->field_8 = 0;
|
||||
entry->type_1_field_14 = keyboardGetLayout();
|
||||
VcrEntry* vcrEntry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
vcrEntry->type = VCR_ENTRY_TYPE_INITIAL_STATE;
|
||||
vcrEntry->time = 0;
|
||||
vcrEntry->counter = 0;
|
||||
vcrEntry->initial.keyboardLayout = keyboardGetLayout();
|
||||
|
||||
while (mouseGetEvent() != 0) {
|
||||
_mouse_info();
|
||||
}
|
||||
|
||||
mouseGetPosition(&(entry->type_1_field_C), &(entry->type_1_field_10));
|
||||
mouseGetPosition(&(vcrEntry->initial.mouseX), &(vcrEntry->initial.mouseY));
|
||||
|
||||
_vcr_counter = 1;
|
||||
_vcr_buffer_index++;
|
||||
_vcr_start_time = _get_time();
|
||||
keyboardReset();
|
||||
_vcr_state = 0;
|
||||
|
||||
gVcrState = VCR_STATE_RECORDING;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D27EC
|
||||
bool vcrPlay(const char* fileName, unsigned int terminationFlags, VcrPlaybackCompletionCallback* callback)
|
||||
{
|
||||
if (gVcrState != VCR_STATE_TURNED_OFF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileName == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
if (!vcrInitBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gVcrFile = fileOpen(fileName, "rb");
|
||||
if (gVcrFile == NULL) {
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vcrLoad()) {
|
||||
fileClose(gVcrFile);
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
while (mouseGetEvent() != 0) {
|
||||
_mouse_info();
|
||||
}
|
||||
|
||||
keyboardReset();
|
||||
|
||||
gVcrRequestedTerminationFlags = terminationFlags;
|
||||
gVcrPlaybackCompletionCallback = callback;
|
||||
gVcrPlaybackCompletionReason = VCR_PLAYBACK_COMPLETION_REASON_COMPLETED;
|
||||
gVcrTerminateFlags = 0;
|
||||
_vcr_counter = 0;
|
||||
_vcr_time = 0;
|
||||
_vcr_start_time = _get_time();
|
||||
gVcrState = VCR_STATE_PLAYING;
|
||||
stru_6AD940.time = 0;
|
||||
stru_6AD940.counter = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D28F4
|
||||
void _vcr_stop()
|
||||
void vcrStop()
|
||||
{
|
||||
if (_vcr_state == 0 || _vcr_state == 1) {
|
||||
_vcr_state |= 0x80000000;
|
||||
if (gVcrState == VCR_STATE_RECORDING || gVcrState == VCR_STATE_PLAYING) {
|
||||
gVcrState |= VCR_STATE_STOP_REQUESTED;
|
||||
}
|
||||
|
||||
keyboardReset();
|
||||
}
|
||||
|
||||
// 0x4D2918
|
||||
int _vcr_status()
|
||||
int vcrGetState()
|
||||
{
|
||||
return _vcr_state;
|
||||
return gVcrState;
|
||||
}
|
||||
|
||||
// 0x4D2930
|
||||
int _vcr_update()
|
||||
int vcrUpdate()
|
||||
{
|
||||
// TODO: Incomplete.
|
||||
if ((gVcrState & VCR_STATE_STOP_REQUESTED) != 0) {
|
||||
gVcrState &= ~VCR_STATE_STOP_REQUESTED;
|
||||
|
||||
switch (gVcrState) {
|
||||
case VCR_STATE_RECORDING:
|
||||
vcrDump();
|
||||
|
||||
fileClose(gVcrFile);
|
||||
gVcrFile = NULL;
|
||||
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
|
||||
break;
|
||||
case VCR_STATE_PLAYING:
|
||||
fileClose(gVcrFile);
|
||||
gVcrFile = NULL;
|
||||
|
||||
// NOTE: Uninline.
|
||||
vcrFreeBuffer();
|
||||
|
||||
keyboardSetLayout(gVcrOldKeyboardLayout);
|
||||
|
||||
if (gVcrPlaybackCompletionCallback != NULL) {
|
||||
gVcrPlaybackCompletionCallback(gVcrPlaybackCompletionReason);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
gVcrState = VCR_STATE_TURNED_OFF;
|
||||
}
|
||||
|
||||
switch (gVcrState) {
|
||||
case VCR_STATE_RECORDING:
|
||||
_vcr_counter++;
|
||||
_vcr_time = getTicksSince(_vcr_start_time);
|
||||
if (_vcr_buffer_index == VCR_BUFFER_CAPACITY - 1) {
|
||||
vcrDump();
|
||||
}
|
||||
break;
|
||||
case VCR_STATE_PLAYING:
|
||||
if (_vcr_buffer_index < _vcr_buffer_end || vcrLoad()) {
|
||||
VcrEntry* vcrEntry = &(_vcr_buffer[_vcr_buffer_index]);
|
||||
if (stru_6AD940.counter < vcrEntry->counter) {
|
||||
if (vcrEntry->time > stru_6AD940.time) {
|
||||
unsigned int delay = stru_6AD940.time;
|
||||
delay += (_vcr_counter - stru_6AD940.counter)
|
||||
* (vcrEntry->time - stru_6AD940.time)
|
||||
/ (vcrEntry->counter - stru_6AD940.counter);
|
||||
|
||||
while (getTicksSince(_vcr_start_time) < delay) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_vcr_counter++;
|
||||
|
||||
int rc = 0;
|
||||
while (_vcr_counter >= _vcr_buffer[_vcr_buffer_index].counter) {
|
||||
_vcr_time = getTicksSince(_vcr_start_time);
|
||||
if (_vcr_time > _vcr_buffer[_vcr_buffer_index].time + 5
|
||||
|| _vcr_time < _vcr_buffer[_vcr_buffer_index].time - 5) {
|
||||
_vcr_start_time += _vcr_time - _vcr_buffer[_vcr_buffer_index].time;
|
||||
}
|
||||
|
||||
switch (_vcr_buffer[_vcr_buffer_index].type) {
|
||||
case VCR_ENTRY_TYPE_INITIAL_STATE:
|
||||
gVcrState = VCR_STATE_TURNED_OFF;
|
||||
gVcrOldKeyboardLayout = keyboardGetLayout();
|
||||
keyboardSetLayout(_vcr_buffer[_vcr_buffer_index].initial.keyboardLayout);
|
||||
while (mouseGetEvent() != 0) {
|
||||
_mouse_info();
|
||||
}
|
||||
gVcrState = VCR_ENTRY_TYPE_INITIAL_STATE;
|
||||
mouseHideCursor();
|
||||
_mouse_set_position(_vcr_buffer[_vcr_buffer_index].initial.mouseX, _vcr_buffer[_vcr_buffer_index].initial.mouseY);
|
||||
mouseShowCursor();
|
||||
keyboardReset();
|
||||
gVcrTerminateFlags = gVcrRequestedTerminationFlags;
|
||||
_vcr_start_time = _get_time();
|
||||
_vcr_counter = 0;
|
||||
break;
|
||||
case VCR_ENTRY_TYPE_KEYBOARD_EVENT:
|
||||
if (1) {
|
||||
KeyboardData keyboardData;
|
||||
keyboardData.key = _vcr_buffer[_vcr_buffer_index].keyboardEvent.key;
|
||||
_kb_simulate_key(&keyboardData);
|
||||
}
|
||||
break;
|
||||
case VCR_ENTRY_TYPE_MOUSE_EVENT:
|
||||
rc = 3;
|
||||
_mouse_simulate_input(_vcr_buffer[_vcr_buffer_index].mouseEvent.dx, _vcr_buffer[_vcr_buffer_index].mouseEvent.dy, _vcr_buffer[_vcr_buffer_index].mouseEvent.buttons);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(&stru_6AD940, &(_vcr_buffer[_vcr_buffer_index]), sizeof(stru_6AD940));
|
||||
_vcr_buffer_index++;
|
||||
}
|
||||
|
||||
return rc;
|
||||
} else {
|
||||
// NOTE: Uninline.
|
||||
vcrStop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Inlined.
|
||||
//
|
||||
// 0x4D2C64
|
||||
bool vcrInitBuffer()
|
||||
{
|
||||
if (_vcr_buffer == NULL) {
|
||||
_vcr_buffer = (VcrEntry*)internal_malloc(sizeof(*_vcr_buffer) * VCR_BUFFER_CAPACITY);
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
vcrClear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: Inlined.
|
||||
//
|
||||
// 0x4D2C98
|
||||
bool vcrFreeBuffer()
|
||||
{
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
vcrClear();
|
||||
|
||||
internal_free(_vcr_buffer);
|
||||
_vcr_buffer = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D2CD0
|
||||
bool _vcr_clear_buffer()
|
||||
bool vcrClear()
|
||||
{
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
|
@ -4451,81 +4653,104 @@ bool _vcr_clear_buffer()
|
|||
}
|
||||
|
||||
// 0x4D2CF0
|
||||
int _vcr_dump_buffer()
|
||||
bool vcrDump()
|
||||
{
|
||||
if (!_vcr_buffer || !_vcr_file) {
|
||||
return 0;
|
||||
if (_vcr_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gVcrFile == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index = 0; index < _vcr_buffer_index; index++) {
|
||||
if (_vcr_save_record(&(_vcr_buffer[index]), _vcr_file)) {
|
||||
_vcr_buffer_index = 0;
|
||||
return 1;
|
||||
if (!vcrWriteEntry(&(_vcr_buffer[index]), gVcrFile)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
// NOTE: Uninline.
|
||||
if (!vcrClear()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D2D74
|
||||
bool vcrLoad()
|
||||
{
|
||||
if (gVcrFile == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
if (!vcrClear()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (_vcr_buffer_end = 0; _vcr_buffer_end < VCR_BUFFER_CAPACITY; _vcr_buffer_end++) {
|
||||
if (!vcrReadEntry(&(_vcr_buffer[_vcr_buffer_end]), gVcrFile)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_vcr_buffer_end == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x4D2E00
|
||||
bool _vcr_save_record(STRUCT_51E2F0* ptr, File* stream)
|
||||
bool vcrWriteEntry(VcrEntry* vcrEntry, File* stream)
|
||||
{
|
||||
if (_db_fwriteLong(stream, ptr->type) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->field_4) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->field_8) == -1) goto err;
|
||||
|
||||
switch (ptr->type) {
|
||||
case 1:
|
||||
if (_db_fwriteLong(stream, ptr->type_1_field_C) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->type_1_field_10) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->type_1_field_14) == -1) goto err;
|
||||
if (fileWriteUInt32(stream, vcrEntry->type) == -1) return false;
|
||||
if (fileWriteUInt32(stream, vcrEntry->time) == -1) return false;
|
||||
if (fileWriteUInt32(stream, vcrEntry->counter) == -1) return false;
|
||||
|
||||
switch (vcrEntry->type) {
|
||||
case VCR_ENTRY_TYPE_INITIAL_STATE:
|
||||
if (fileWriteInt32(stream, vcrEntry->initial.mouseX) == -1) return false;
|
||||
if (fileWriteInt32(stream, vcrEntry->initial.mouseY) == -1) return false;
|
||||
if (fileWriteInt32(stream, vcrEntry->initial.keyboardLayout) == -1) return false;
|
||||
return true;
|
||||
case 2:
|
||||
if (fileWriteInt16(stream, ptr->type_2_field_C) == -1) goto err;
|
||||
|
||||
case VCR_ENTRY_TYPE_KEYBOARD_EVENT:
|
||||
if (fileWriteInt16(stream, vcrEntry->keyboardEvent.key) == -1) return false;
|
||||
return true;
|
||||
case 3:
|
||||
if (_db_fwriteLong(stream, ptr->dx) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->dy) == -1) goto err;
|
||||
if (_db_fwriteLong(stream, ptr->buttons) == -1) goto err;
|
||||
|
||||
case VCR_ENTRY_TYPE_MOUSE_EVENT:
|
||||
if (fileWriteInt32(stream, vcrEntry->mouseEvent.dx) == -1) return false;
|
||||
if (fileWriteInt32(stream, vcrEntry->mouseEvent.dy) == -1) return false;
|
||||
if (fileWriteInt32(stream, vcrEntry->mouseEvent.buttons) == -1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
err:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0x4D2EE4
|
||||
bool _vcr_load_record(STRUCT_51E2F0* ptr, File* stream)
|
||||
bool vcrReadEntry(VcrEntry* vcrEntry, File* stream)
|
||||
{
|
||||
if (_db_freadInt(stream, &(ptr->type)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->field_4)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->field_8)) == -1) goto err;
|
||||
|
||||
switch (ptr->type) {
|
||||
case 1:
|
||||
if (_db_freadInt(stream, &(ptr->type_1_field_C)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->type_1_field_10)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->type_1_field_14)) == -1) goto err;
|
||||
if (fileReadUInt32(stream, &(vcrEntry->type)) == -1) return false;
|
||||
if (fileReadUInt32(stream, &(vcrEntry->time)) == -1) return false;
|
||||
if (fileReadUInt32(stream, &(vcrEntry->counter)) == -1) return false;
|
||||
|
||||
switch (vcrEntry->type) {
|
||||
case VCR_ENTRY_TYPE_INITIAL_STATE:
|
||||
if (fileReadInt32(stream, &(vcrEntry->initial.mouseX)) == -1) return false;
|
||||
if (fileReadInt32(stream, &(vcrEntry->initial.mouseY)) == -1) return false;
|
||||
if (fileReadInt32(stream, &(vcrEntry->initial.keyboardLayout)) == -1) return false;
|
||||
return true;
|
||||
case 2:
|
||||
if (fileReadInt16(stream, &(ptr->type_2_field_C)) == -1) goto err;
|
||||
|
||||
case VCR_ENTRY_TYPE_KEYBOARD_EVENT:
|
||||
if (fileReadInt16(stream, &(vcrEntry->keyboardEvent.key)) == -1) return false;
|
||||
return true;
|
||||
case 3:
|
||||
if (_db_freadInt(stream, &(ptr->dx)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->dy)) == -1) goto err;
|
||||
if (_db_freadInt(stream, &(ptr->buttons)) == -1) goto err;
|
||||
|
||||
case VCR_ENTRY_TYPE_MOUSE_EVENT:
|
||||
if (fileReadInt32(stream, &(vcrEntry->mouseEvent.dx)) == -1) return false;
|
||||
if (fileReadInt32(stream, &(vcrEntry->mouseEvent.dy)) == -1) return false;
|
||||
if (fileReadInt32(stream, &(vcrEntry->mouseEvent.buttons)) == -1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
err:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
103
src/core.h
103
src/core.h
|
@ -360,6 +360,44 @@ typedef enum KeyboardLayout {
|
|||
KEYBOARD_LAYOUT_SPANISH,
|
||||
} KeyboardLayout;
|
||||
|
||||
#define VCR_BUFFER_CAPACITY 4096
|
||||
|
||||
typedef enum VcrState {
|
||||
VCR_STATE_RECORDING,
|
||||
VCR_STATE_PLAYING,
|
||||
VCR_STATE_TURNED_OFF,
|
||||
} VcrState;
|
||||
|
||||
#define VCR_STATE_STOP_REQUESTED 0x80000000
|
||||
|
||||
typedef enum VcrTerminationFlags {
|
||||
// Specifies that VCR playback should stop if any key is pressed.
|
||||
VCR_TERMINATE_ON_KEY_PRESS = 0x01,
|
||||
|
||||
// Specifies that VCR playback should stop if mouse is mouved.
|
||||
VCR_TERMINATE_ON_MOUSE_MOVE = 0x02,
|
||||
|
||||
// Specifies that VCR playback should stop if any mouse button is pressed.
|
||||
VCR_TERMINATE_ON_MOUSE_PRESS = 0x04,
|
||||
} VcrTerminationFlags;
|
||||
|
||||
typedef enum VcrPlaybackCompletionReason {
|
||||
VCR_PLAYBACK_COMPLETION_REASON_NONE = 0,
|
||||
|
||||
// Indicates that VCR playback completed normally.
|
||||
VCR_PLAYBACK_COMPLETION_REASON_COMPLETED = 1,
|
||||
|
||||
// Indicates that VCR playback terminated according to termination flags.
|
||||
VCR_PLAYBACK_COMPLETION_REASON_TERMINATED = 2,
|
||||
} VcrPlaybackCompletionReason;
|
||||
|
||||
typedef enum VcrEntryType {
|
||||
VCR_ENTRY_TYPE_NONE = 0,
|
||||
VCR_ENTRY_TYPE_INITIAL_STATE = 1,
|
||||
VCR_ENTRY_TYPE_KEYBOARD_EVENT = 2,
|
||||
VCR_ENTRY_TYPE_MOUSE_EVENT = 3,
|
||||
} VcrEntryType;
|
||||
|
||||
typedef struct STRUCT_6ABF50 {
|
||||
// Time when appropriate key was pressed down or -1 if it's up.
|
||||
int tick;
|
||||
|
@ -383,26 +421,26 @@ typedef struct TickerListNode {
|
|||
struct TickerListNode* next;
|
||||
} TickerListNode;
|
||||
|
||||
typedef struct STRUCT_51E2F0 {
|
||||
int type;
|
||||
int field_4;
|
||||
int field_8;
|
||||
typedef struct VcrEntry {
|
||||
unsigned int type;
|
||||
unsigned int time;
|
||||
unsigned int counter;
|
||||
union {
|
||||
struct {
|
||||
int type_1_field_C; // mouse x
|
||||
int type_1_field_10; // mouse y
|
||||
int type_1_field_14; // keyboard layout
|
||||
};
|
||||
int mouseX;
|
||||
int mouseY;
|
||||
int keyboardLayout;
|
||||
} initial;
|
||||
struct {
|
||||
short type_2_field_C;
|
||||
};
|
||||
short key;
|
||||
} keyboardEvent;
|
||||
struct {
|
||||
int dx;
|
||||
int dy;
|
||||
int buttons;
|
||||
};
|
||||
} mouseEvent;
|
||||
};
|
||||
} STRUCT_51E2F0;
|
||||
} VcrEntry;
|
||||
|
||||
typedef struct LogicalKeyEntry {
|
||||
short field_0;
|
||||
|
@ -420,6 +458,7 @@ typedef struct KeyboardEvent {
|
|||
|
||||
typedef int(PauseHandler)();
|
||||
typedef int(ScreenshotHandler)(int width, int height, unsigned char* buffer, unsigned char* palette);
|
||||
typedef void(VcrPlaybackCompletionCallback)(int reason);
|
||||
|
||||
extern void (*_idle_func)();
|
||||
extern void (*_focus_func)(int);
|
||||
|
@ -448,17 +487,20 @@ extern int gKeyboardEventQueueReadIndex;
|
|||
extern short word_51E2E8;
|
||||
extern int gModifierKeysState;
|
||||
extern int (*_kb_scan_to_ascii)();
|
||||
extern STRUCT_51E2F0* _vcr_buffer;
|
||||
extern VcrEntry* _vcr_buffer;
|
||||
extern int _vcr_buffer_index;
|
||||
extern int _vcr_state;
|
||||
extern int _vcr_time;
|
||||
extern int _vcr_counter;
|
||||
extern int _vcr_terminate_flags;
|
||||
extern int _vcr_terminated_condition;
|
||||
extern int _vcr_start_time;
|
||||
extern unsigned int gVcrState;
|
||||
extern unsigned int _vcr_time;
|
||||
extern unsigned int _vcr_counter;
|
||||
extern unsigned int gVcrTerminateFlags;
|
||||
extern int gVcrPlaybackCompletionReason;
|
||||
extern unsigned int _vcr_start_time;
|
||||
extern int _vcr_registered_atexit;
|
||||
extern File* _vcr_file;
|
||||
extern File* gVcrFile;
|
||||
extern int _vcr_buffer_end;
|
||||
extern VcrPlaybackCompletionCallback* gVcrPlaybackCompletionCallback;
|
||||
extern unsigned int gVcrRequestedTerminationFlags;
|
||||
extern int gVcrOldKeyboardLayout;
|
||||
|
||||
extern int gNormalizedQwertyKeys[SDL_NUM_SCANCODES];
|
||||
extern InputEvent gInputEventQueue[40];
|
||||
|
@ -520,6 +562,7 @@ extern unsigned int _kb_idle_start_time;
|
|||
extern KeyboardEvent gLastKeyboardEvent;
|
||||
extern int gKeyboardLayout;
|
||||
extern unsigned char gPressedPhysicalKeysCount;
|
||||
extern VcrEntry stru_6AD940;
|
||||
|
||||
extern SDL_Window* gSdlWindow;
|
||||
extern SDL_Surface* gSdlSurface;
|
||||
|
@ -621,14 +664,18 @@ void keyboardBuildItalianConfiguration();
|
|||
void keyboardBuildSpanishConfiguration();
|
||||
void _kb_init_lock_status();
|
||||
int keyboardPeekEvent(int index, KeyboardEvent** keyboardEventPtr);
|
||||
bool _vcr_record(const char* fileName);
|
||||
void _vcr_stop();
|
||||
int _vcr_status();
|
||||
int _vcr_update();
|
||||
bool _vcr_clear_buffer();
|
||||
int _vcr_dump_buffer();
|
||||
bool _vcr_save_record(STRUCT_51E2F0* ptr, File* stream);
|
||||
bool _vcr_load_record(STRUCT_51E2F0* ptr, File* stream);
|
||||
bool vcrRecord(const char* fileName);
|
||||
bool vcrPlay(const char* fileName, unsigned int terminationFlags, VcrPlaybackCompletionCallback* callback);
|
||||
void vcrStop();
|
||||
int vcrGetState();
|
||||
int vcrUpdate();
|
||||
bool vcrInitBuffer();
|
||||
bool vcrFreeBuffer();
|
||||
bool vcrClear();
|
||||
bool vcrDump();
|
||||
bool vcrLoad();
|
||||
bool vcrWriteEntry(VcrEntry* ptr, File* stream);
|
||||
bool vcrReadEntry(VcrEntry* ptr, File* stream);
|
||||
|
||||
int screenGetWidth();
|
||||
int screenGetHeight();
|
||||
|
|
|
@ -276,18 +276,18 @@ void dudeResetName()
|
|||
// 0x42D18C
|
||||
int critterGetHitPoints(Object* critter)
|
||||
{
|
||||
return (critter->pid >> 24) == OBJ_TYPE_CRITTER ? critter->data.critter.hp : 0;
|
||||
return PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER ? critter->data.critter.hp : 0;
|
||||
}
|
||||
|
||||
// 0x42D1A4
|
||||
int critterAdjustHitPoints(Object* critter, int a2)
|
||||
int critterAdjustHitPoints(Object* critter, int hp)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maximumHp = critterGetStat(critter, STAT_MAXIMUM_HIT_POINTS);
|
||||
int newHp = critter->data.critter.hp + a2;
|
||||
int newHp = critter->data.critter.hp + hp;
|
||||
|
||||
critter->data.critter.hp = newHp;
|
||||
if (maximumHp >= newHp) {
|
||||
|
@ -304,7 +304,7 @@ int critterAdjustHitPoints(Object* critter, int a2)
|
|||
// 0x42D1F8
|
||||
int critterGetPoison(Object* critter)
|
||||
{
|
||||
return (critter->pid >> 24) == OBJ_TYPE_CRITTER ? critter->data.critter.poison : 0;
|
||||
return PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER ? critter->data.critter.poison : 0;
|
||||
}
|
||||
|
||||
// Adjust critter's current poison by specified amount.
|
||||
|
@ -396,7 +396,7 @@ int poisonEventProcess(Object* obj, void* data)
|
|||
// 0x42D38C
|
||||
int critterGetRadiation(Object* obj)
|
||||
{
|
||||
return (obj->pid >> 24) == OBJ_TYPE_CRITTER ? obj->data.critter.radiation : 0;
|
||||
return PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER ? obj->data.critter.radiation : 0;
|
||||
}
|
||||
|
||||
// 0x42D3A4
|
||||
|
@ -416,7 +416,7 @@ int critterAdjustRadiation(Object* obj, int amount)
|
|||
}
|
||||
|
||||
if (amount > 0) {
|
||||
proto->critter.data.flags |= 0x02;
|
||||
proto->critter.data.flags |= CRITTER_FLAG_0x2;
|
||||
}
|
||||
|
||||
if (amount > 0) {
|
||||
|
@ -483,7 +483,7 @@ int _critter_check_rads(Object* obj)
|
|||
|
||||
Proto* proto;
|
||||
protoGetProto(obj->pid, &proto);
|
||||
if ((proto->critter.data.flags & 0x02) == 0) {
|
||||
if ((proto->critter.data.flags & CRITTER_FLAG_0x2) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -521,10 +521,10 @@ int _critter_check_rads(Object* obj)
|
|||
|
||||
radiationEvent->radiationLevel = radiationLevel;
|
||||
radiationEvent->isHealing = 0;
|
||||
queueAddEvent(36000 * randomBetween(4, 18), obj, radiationEvent, EVENT_TYPE_RADIATION);
|
||||
queueAddEvent(GAME_TIME_TICKS_PER_HOUR * randomBetween(4, 18), obj, radiationEvent, EVENT_TYPE_RADIATION);
|
||||
}
|
||||
|
||||
proto->critter.data.flags &= ~(0x02);
|
||||
proto->critter.data.flags &= ~(CRITTER_FLAG_0x2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -657,7 +657,7 @@ int radiationEventWrite(File* stream, void* data)
|
|||
// 0x42D82C
|
||||
int critterGetDamageType(Object* obj)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -723,7 +723,7 @@ int critterGetKillType(Object* obj)
|
|||
return KILL_TYPE_MAN;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -766,7 +766,7 @@ char* killTypeGetDescription(int killType)
|
|||
// 0x42D9F4
|
||||
int _critter_heal_hours(Object* critter, int a2)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -788,7 +788,7 @@ static int _critterClearObjDrugs(Object* obj, void* data)
|
|||
// 0x42DA64
|
||||
void critterKill(Object* critter, int anim, bool a3)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -800,20 +800,20 @@ void critterKill(Object* critter, int anim, bool a3)
|
|||
bool shouldChangeFid = false;
|
||||
int fid;
|
||||
if (_critter_is_prone(critter)) {
|
||||
int current = (critter->fid & 0xFF0000) >> 16;
|
||||
int current = FID_ANIM_TYPE(critter->fid);
|
||||
if (current == ANIM_FALL_BACK || current == ANIM_FALL_FRONT) {
|
||||
bool back = false;
|
||||
if (current == ANIM_FALL_BACK) {
|
||||
back = true;
|
||||
} else {
|
||||
fid = buildFid(1, critter->fid & 0xFFF, ANIM_FALL_FRONT_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_FALL_FRONT_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
if (!artExists(fid)) {
|
||||
back = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (back) {
|
||||
fid = buildFid(1, critter->fid & 0xFFF, ANIM_FALL_BACK_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_FALL_BACK_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
}
|
||||
|
||||
shouldChangeFid = true;
|
||||
|
@ -828,12 +828,12 @@ void critterKill(Object* critter, int anim, bool a3)
|
|||
anim = LAST_SF_DEATH_ANIM;
|
||||
}
|
||||
|
||||
fid = buildFid(1, critter->fid & 0xFFF, anim, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, anim, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
_obj_fix_violence_settings(&fid);
|
||||
if (!artExists(fid)) {
|
||||
debugPrint("\nError: Critter Kill: Can't match fid!");
|
||||
|
||||
fid = buildFid(1, critter->fid & 0xFFF, ANIM_FALL_BACK_BLOOD_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_FALL_BACK_BLOOD_SF, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
_obj_fix_violence_settings(&fid);
|
||||
}
|
||||
|
||||
|
@ -850,7 +850,7 @@ void critterKill(Object* critter, int anim, bool a3)
|
|||
rectUnion(&updatedRect, &tempRect, &updatedRect);
|
||||
}
|
||||
|
||||
if (!_critter_flag_check(critter->pid, 2048)) {
|
||||
if (!_critter_flag_check(critter->pid, CRITTER_FLAG_0x800)) {
|
||||
critter->flags |= OBJECT_NO_BLOCK;
|
||||
_obj_toggle_flat(critter, &tempRect);
|
||||
}
|
||||
|
@ -902,7 +902,7 @@ bool critterIsActive(Object* critter)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -924,7 +924,7 @@ bool critterIsDead(Object* critter)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -946,7 +946,7 @@ bool critterIsCrippled(Object* critter)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -960,11 +960,11 @@ bool _critter_is_prone(Object* critter)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int anim = (critter->fid & 0xFF0000) >> 16;
|
||||
int anim = FID_ANIM_TYPE(critter->fid);
|
||||
|
||||
return (critter->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN)) != 0
|
||||
|| anim >= FIRST_KNOCKDOWN_AND_DEATH_ANIM && anim <= LAST_KNOCKDOWN_AND_DEATH_ANIM
|
||||
|
@ -980,7 +980,7 @@ int critterGetBodyType(Object* critter)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1236,7 +1236,7 @@ int knockoutEventProcess(Object* obj, void* data)
|
|||
// 0x42E460
|
||||
int _critter_wake_clear(Object* obj, void* data)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1246,7 +1246,7 @@ int _critter_wake_clear(Object* obj, void* data)
|
|||
|
||||
obj->data.critter.combat.results &= ~(DAM_KNOCKED_OUT | DAM_KNOCKED_DOWN);
|
||||
|
||||
int fid = buildFid((obj->fid & 0xF000000) >> 24, obj->fid & 0xFFF, ANIM_STAND, (obj->fid & 0xF000) >> 12, obj->rotation + 1);
|
||||
int fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_STAND, (obj->fid & 0xF000) >> 12, obj->rotation + 1);
|
||||
objectSetFid(obj, fid, 0);
|
||||
|
||||
return 0;
|
||||
|
@ -1259,11 +1259,11 @@ int _critter_set_who_hit_me(Object* a1, Object* a2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (a2 != NULL && ((a2->fid & 0xF000000) >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (a2 != NULL && FID_TYPE(a2->fid) != OBJ_TYPE_CRITTER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((a1->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a1->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (a2 == NULL || a1->data.critter.combat.team != a2->data.critter.combat.team || statRoll(a1, STAT_INTELLIGENCE, -1, NULL) < 2 && (!objectIsPartyMember(a1) || !objectIsPartyMember(a2))) {
|
||||
a1->data.critter.combat.whoHitMe = a2;
|
||||
if (a2 == gDude) {
|
||||
|
@ -1319,7 +1319,7 @@ bool _critter_can_obj_dude_rest()
|
|||
// 0x42E62C
|
||||
int critterGetMovementPointCostAdjustedForCrippledLegs(Object* critter, int actionPoints)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1358,7 +1358,7 @@ bool _critter_flag_check(int pid, int flag)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ void critterProtoDataCopy(CritterProtoData* dest, CritterProtoData* src);
|
|||
int dudeSetName(const char* name);
|
||||
void dudeResetName();
|
||||
int critterGetHitPoints(Object* critter);
|
||||
int critterAdjustHitPoints(Object* critter, int amount);
|
||||
int critterAdjustHitPoints(Object* critter, int hp);
|
||||
int critterGetPoison(Object* critter);
|
||||
int critterAdjustPoison(Object* obj, int amount);
|
||||
int poisonEventProcess(Object* obj, void* data);
|
||||
|
|
191
src/datafile.cc
191
src/datafile.cc
|
@ -1,10 +1,195 @@
|
|||
#include "datafile.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "db.h"
|
||||
#include "memory_manager.h"
|
||||
#include "pcx.h"
|
||||
#include "platform_compat.h"
|
||||
|
||||
// 0x5184AC
|
||||
DatafileLoader* gDatafileLoader = NULL;
|
||||
|
||||
// 0x5184B0
|
||||
DatafileNameMangler* gDatafileNameMangler = datafileDefaultNameManglerImpl;
|
||||
|
||||
// 0x56D7E0
|
||||
unsigned char _pal[768];
|
||||
unsigned char gDatafilePalette[768];
|
||||
|
||||
// 0x42EE70
|
||||
char* datafileDefaultNameManglerImpl(char* path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42EE74
|
||||
void datafileSetNameMangler(DatafileNameMangler* mangler)
|
||||
{
|
||||
gDatafileNameMangler = mangler;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42EE7C
|
||||
void datafileSetLoader(DatafileLoader* loader)
|
||||
{
|
||||
gDatafileLoader = loader;
|
||||
}
|
||||
|
||||
// 0x42EE84
|
||||
void sub_42EE84(unsigned char* data, unsigned char* palette, int width, int height)
|
||||
{
|
||||
unsigned char indexedPalette[256];
|
||||
|
||||
indexedPalette[0] = 0;
|
||||
for (int index = 1; index < 256; index++) {
|
||||
// TODO: Check.
|
||||
int r = palette[index * 3 + 2] >> 3;
|
||||
int g = palette[index * 3 + 1] >> 3;
|
||||
int b = palette[index * 3] >> 3;
|
||||
int colorTableIndex = (r << 10) | (g << 5) | b;
|
||||
indexedPalette[index] = _colorTable[colorTableIndex];
|
||||
}
|
||||
|
||||
int size = width * height;
|
||||
for (int index = 0; index < size; index++) {
|
||||
data[index] = indexedPalette[data[index]];
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42EEF8
|
||||
void sub_42EEF8(unsigned char* data, unsigned char* palette, int width, int height)
|
||||
{
|
||||
unsigned char indexedPalette[256];
|
||||
|
||||
indexedPalette[0] = 0;
|
||||
for (int index = 1; index < 256; index++) {
|
||||
// TODO: Check.
|
||||
int r = palette[index * 3 + 2] >> 1;
|
||||
int g = palette[index * 3 + 1] >> 1;
|
||||
int b = palette[index * 3] >> 1;
|
||||
int colorTableIndex = (r << 10) | (g << 5) | b;
|
||||
indexedPalette[index] = _colorTable[colorTableIndex];
|
||||
}
|
||||
|
||||
int size = width * height;
|
||||
for (int index = 0; index < size; index++) {
|
||||
data[index] = indexedPalette[data[index]];
|
||||
}
|
||||
}
|
||||
|
||||
// 0x42EF60
|
||||
unsigned char* datafileReadRaw(char* path, int* widthPtr, int* heightPtr)
|
||||
{
|
||||
char* mangledPath = gDatafileNameMangler(path);
|
||||
char* dot = strrchr(mangledPath, '.');
|
||||
if (dot != NULL) {
|
||||
if (compat_stricmp(dot + 1, "pcx")) {
|
||||
return pcxRead(mangledPath, widthPtr, heightPtr, gDatafilePalette);
|
||||
}
|
||||
}
|
||||
|
||||
if (gDatafileLoader != NULL) {
|
||||
return gDatafileLoader(mangledPath, gDatafilePalette, widthPtr, heightPtr);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 0x42EFCC
|
||||
unsigned char* datafileRead(char* path, int* widthPtr, int* heightPtr)
|
||||
{
|
||||
unsigned char* v1 = datafileReadRaw(path, widthPtr, heightPtr);
|
||||
if (v1 != NULL) {
|
||||
sub_42EE84(v1, gDatafilePalette, *widthPtr, *heightPtr);
|
||||
}
|
||||
return v1;
|
||||
}
|
||||
|
||||
// NOTE: Unused
|
||||
//
|
||||
// 0x42EFF4
|
||||
unsigned char* sub_42EFF4(char* path)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
unsigned char* v3 = datafileReadRaw(path, &width, &height);
|
||||
if (v3 != NULL) {
|
||||
internal_free_safe(v3, __FILE__, __LINE__); // "..\\int\\DATAFILE.C", 148
|
||||
return gDatafilePalette;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42F024
|
||||
void sub_42F024(unsigned char* data, int* widthPtr, int* heightPtr)
|
||||
{
|
||||
int width = *widthPtr;
|
||||
int height = *heightPtr;
|
||||
unsigned char* temp = (unsigned char*)internal_malloc_safe(width * height, __FILE__, __LINE__); // "..\\int\\DATAFILE.C", 157
|
||||
|
||||
// NOTE: Original code does not initialize `x`.
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
unsigned char* src1 = data;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
if (*src1 == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned char* src2 = src1;
|
||||
for (x = 0; x < width; x++) {
|
||||
if (*src2 == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
*temp++ = *src2++;
|
||||
}
|
||||
|
||||
src1 += width;
|
||||
}
|
||||
|
||||
memcpy(data, temp, x * y);
|
||||
internal_free_safe(temp, __FILE__, __LINE__); // // "..\\int\\DATAFILE.C", 171
|
||||
}
|
||||
|
||||
// 0x42F0E4
|
||||
unsigned char* _datafileGetPalette()
|
||||
unsigned char* datafileGetPalette()
|
||||
{
|
||||
return _pal;
|
||||
return gDatafilePalette;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x42F0EC
|
||||
unsigned char* datafileLoad(char* path, int* sizePtr)
|
||||
{
|
||||
const char* mangledPath = gDatafileNameMangler(path);
|
||||
File* stream = fileOpen(mangledPath, "rb");
|
||||
if (stream == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int size = fileGetSize(stream);
|
||||
unsigned char* data = (unsigned char*)internal_malloc_safe(size, __FILE__, __LINE__); // "..\\int\\DATAFILE.C", 185
|
||||
if (data == NULL) {
|
||||
// NOTE: This code is unreachable, internal_malloc_safe never fails.
|
||||
// Otherwise it leaks stream.
|
||||
*sizePtr = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fileRead(data, 1, size, stream);
|
||||
fileClose(stream);
|
||||
*sizePtr = size;
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
#ifndef DATAFILE_H
|
||||
#define DATAFILE_H
|
||||
|
||||
extern unsigned char _pal[768];
|
||||
typedef unsigned char*(DatafileLoader)(char* path, unsigned char* palette, int* widthPtr, int* heightPtr);
|
||||
typedef char*(DatafileNameMangler)(char* path);
|
||||
|
||||
unsigned char* _datafileGetPalette();
|
||||
extern DatafileLoader* gDatafileLoader;
|
||||
extern DatafileNameMangler* gDatafileNameMangler;
|
||||
|
||||
extern unsigned char gDatafilePalette[768];
|
||||
|
||||
char* datafileDefaultNameManglerImpl(char* path);
|
||||
void datafileSetNameMangler(DatafileNameMangler* mangler);
|
||||
void datafileSetLoader(DatafileLoader* loader);
|
||||
void sub_42EE84(unsigned char* data, unsigned char* palette, int width, int height);
|
||||
void sub_42EEF8(unsigned char* data, unsigned char* palette, int width, int height);
|
||||
unsigned char* datafileReadRaw(char* path, int* widthPtr, int* heightPtr);
|
||||
unsigned char* datafileRead(char* path, int* widthPtr, int* heightPtr);
|
||||
unsigned char* sub_42EFF4(char* path);
|
||||
void sub_42F024(unsigned char* data, int* widthPtr, int* heightPtr);
|
||||
unsigned char* datafileGetPalette();
|
||||
unsigned char* datafileLoad(char* path, int* sizePtr);
|
||||
|
||||
#endif /* DATAFILE_H */
|
||||
|
|
13
src/db.cc
13
src/db.cc
|
@ -638,7 +638,7 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a
|
|||
}
|
||||
}
|
||||
|
||||
bool v1 = *pattern == '*';
|
||||
bool isWildcard = *pattern == '*';
|
||||
|
||||
for (int index = 0; index < fileNamesLength; index += 1) {
|
||||
const char* name = xlist->fileNames[index];
|
||||
|
@ -647,16 +647,7 @@ int fileNameListInit(const char* pattern, char*** fileNameListPtr, int a3, int a
|
|||
char extension[COMPAT_MAX_EXT];
|
||||
compat_splitpath(name, NULL, dir, fileName, extension);
|
||||
|
||||
bool v2 = false;
|
||||
if (v1) {
|
||||
char* pch = dir;
|
||||
while (*pch != '\0' && *pch != '\\') {
|
||||
pch++;
|
||||
}
|
||||
v2 = *pch != '\0';
|
||||
}
|
||||
|
||||
if (!v2) {
|
||||
if (!isWildcard || *dir == '\0' || strchr(dir, '\\') == NULL) {
|
||||
// NOTE: Quick and dirty fix to buffer overflow. See RE to
|
||||
// understand the problem.
|
||||
char path[COMPAT_MAX_PATH];
|
||||
|
|
23
src/dbox.cc
23
src/dbox.cc
|
@ -196,7 +196,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
|||
CacheEntry* backgroundHandle;
|
||||
int backgroundWidth;
|
||||
int backgroundHeight;
|
||||
int fid = buildFid(6, gDialogBoxBackgroundFrmIds[dialogType], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gDialogBoxBackgroundFrmIds[dialogType], 0, 0, 0);
|
||||
unsigned char* background = artLockFrameDataReturningSize(fid, &backgroundHandle, &backgroundWidth, &backgroundHeight);
|
||||
if (background == NULL) {
|
||||
fontSetCurrent(savedFont);
|
||||
|
@ -230,7 +230,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
|||
unsigned char* upButton = NULL;
|
||||
|
||||
if ((flags & DIALOG_BOX_0x20) == 0) {
|
||||
int doneBoxFid = buildFid(6, 209, 0, 0, 0);
|
||||
int doneBoxFid = buildFid(OBJ_TYPE_INTERFACE, 209, 0, 0, 0);
|
||||
doneBox = artLockFrameDataReturningSize(doneBoxFid, &doneBoxHandle, &doneBoxWidth, &doneBoxHeight);
|
||||
if (doneBox == NULL) {
|
||||
artUnlock(backgroundHandle);
|
||||
|
@ -239,7 +239,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
|||
return -1;
|
||||
}
|
||||
|
||||
int downButtonFid = buildFid(6, 9, 0, 0, 0);
|
||||
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
downButton = artLockFrameDataReturningSize(downButtonFid, &downButtonHandle, &downButtonWidth, &downButtonHeight);
|
||||
if (downButton == NULL) {
|
||||
artUnlock(doneBoxHandle);
|
||||
|
@ -249,7 +249,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
|||
return -1;
|
||||
}
|
||||
|
||||
int upButtonFid = buildFid(6, 8, 0, 0, 0);
|
||||
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
upButton = artLockFrameData(upButtonFid, 0, 0, &upButtonHandle);
|
||||
if (upButton == NULL) {
|
||||
artUnlock(downButtonHandle);
|
||||
|
@ -331,7 +331,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
|||
buttonSetCallbacks(btn, _gsound_red_butt_press, _gsound_red_butt_release);
|
||||
}
|
||||
} else {
|
||||
int doneBoxFid = buildFid(6, 209, 0, 0, 0);
|
||||
int doneBoxFid = buildFid(OBJ_TYPE_INTERFACE, 209, 0, 0, 0);
|
||||
unsigned char* doneBox = artLockFrameDataReturningSize(doneBoxFid, &doneBoxHandle, &doneBoxWidth, &doneBoxHeight);
|
||||
if (doneBox == NULL) {
|
||||
artUnlock(backgroundHandle);
|
||||
|
@ -340,7 +340,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
|||
return -1;
|
||||
}
|
||||
|
||||
int downButtonFid = buildFid(6, 9, 0, 0, 0);
|
||||
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
unsigned char* downButton = artLockFrameDataReturningSize(downButtonFid, &downButtonHandle, &downButtonWidth, &downButtonHeight);
|
||||
if (downButton == NULL) {
|
||||
artUnlock(doneBoxHandle);
|
||||
|
@ -350,7 +350,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
|||
return -1;
|
||||
}
|
||||
|
||||
int upButtonFid = buildFid(6, 8, 0, 0, 0);
|
||||
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
unsigned char* upButton = artLockFrameData(upButtonFid, 0, 0, &upButtonHandle);
|
||||
if (upButton == NULL) {
|
||||
artUnlock(downButtonHandle);
|
||||
|
@ -517,7 +517,7 @@ int showDialogBox(const char* title, const char** body, int bodyLength, int x, i
|
|||
}
|
||||
|
||||
// 0x41DE90
|
||||
int showLoadFileDialog(char *title, char** fileList, char* dest, int fileListLength, int x, int y, int flags)
|
||||
int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLength, int x, int y, int flags)
|
||||
{
|
||||
int oldFont = fontGetCurrent();
|
||||
|
||||
|
@ -541,7 +541,7 @@ int showLoadFileDialog(char *title, char** fileList, char* dest, int fileListLen
|
|||
Size frmSizes[FILE_DIALOG_FRM_COUNT];
|
||||
|
||||
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gLoadFileDialogFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gLoadFileDialogFrmIds[index], 0, 0, 0);
|
||||
frmBuffers[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
|
||||
if (frmBuffers[index] == NULL) {
|
||||
while (--index >= 0) {
|
||||
|
@ -551,7 +551,6 @@ int showLoadFileDialog(char *title, char** fileList, char* dest, int fileListLen
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int backgroundWidth = frmSizes[FILE_DIALOG_FRM_BACKGROUND].width;
|
||||
int backgroundHeight = frmSizes[FILE_DIALOG_FRM_BACKGROUND].height;
|
||||
|
||||
|
@ -922,7 +921,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
|
|||
Size frmSizes[FILE_DIALOG_FRM_COUNT];
|
||||
|
||||
for (int index = 0; index < FILE_DIALOG_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gSaveFileDialogFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gSaveFileDialogFrmIds[index], 0, 0, 0);
|
||||
frmBuffers[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
|
||||
if (frmBuffers[index] == NULL) {
|
||||
while (--index >= 0) {
|
||||
|
@ -1090,7 +1089,7 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
|
|||
|
||||
char fileNameCopy[32];
|
||||
strncpy(fileNameCopy, dest, 32);
|
||||
|
||||
|
||||
int fileNameCopyLength = strlen(fileNameCopy);
|
||||
fileNameCopy[fileNameCopyLength + 1] = '\0';
|
||||
fileNameCopy[fileNameCopyLength] = ' ';
|
||||
|
|
|
@ -76,7 +76,7 @@ int dword_56DB6C;
|
|||
int dword_56DB70;
|
||||
|
||||
// 0x56DB74
|
||||
int _rand2plus;
|
||||
char* off_56DB74;
|
||||
|
||||
// 0x56DB7C
|
||||
int dword_56DB7C;
|
||||
|
@ -91,7 +91,7 @@ int dword_56DB84;
|
|||
int dword_56DB88;
|
||||
|
||||
// 0x56DB8C
|
||||
int dword_56DB8C;
|
||||
char* off_56DB8C;
|
||||
|
||||
// 0x56DB90
|
||||
int _replyPlaying;
|
||||
|
@ -127,16 +127,16 @@ int dword_56DBB8;
|
|||
int dword_56DBBC;
|
||||
|
||||
// 0x56DBC0
|
||||
void* off_56DBC0;
|
||||
char* off_56DBC0;
|
||||
|
||||
// 0x56DBC4
|
||||
void* off_56DBC4;
|
||||
char* off_56DBC4;
|
||||
|
||||
// 0x56DBC8
|
||||
void* off_56DBC8;
|
||||
char* off_56DBC8;
|
||||
|
||||
// 0x56DBCC
|
||||
void* off_56DBCC;
|
||||
char* off_56DBCC;
|
||||
|
||||
// 0x56DBD0
|
||||
char* gDialogReplyTitle;
|
||||
|
@ -151,16 +151,16 @@ int dword_56DBD8;
|
|||
int dword_56DBDC;
|
||||
|
||||
// 0x56DBE0
|
||||
void* off_56DBE0;
|
||||
char* off_56DBE0;
|
||||
|
||||
// 0x56DBE4
|
||||
void* off_56DBE4;
|
||||
char* off_56DBE4;
|
||||
|
||||
// 0x56DBE8
|
||||
void* off_56DBE8;
|
||||
char* off_56DBE8;
|
||||
|
||||
// 0x56DBEC
|
||||
void* off_56DBEC;
|
||||
char* off_56DBEC;
|
||||
|
||||
// 0x42F434
|
||||
STRUCT_56DAE0_FIELD_4* _getReply()
|
||||
|
@ -191,7 +191,7 @@ void _replyAddOption(const char* a1, const char* a2, int a3)
|
|||
|
||||
v18 = _getReply();
|
||||
v17 = v18->field_14 - 1;
|
||||
v18->field_C[v17].field_8 = 2;
|
||||
v18->field_C[v17].kind = 2;
|
||||
|
||||
if (a1 != NULL) {
|
||||
v14 = (char*)internal_malloc_safe(strlen(a1) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 805
|
||||
|
@ -204,9 +204,9 @@ void _replyAddOption(const char* a1, const char* a2, int a3)
|
|||
if (a2 != NULL) {
|
||||
v15 = (char*)internal_malloc_safe(strlen(a2) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 810
|
||||
strcpy(v15, a2);
|
||||
v18->field_C[v17].field_4 = v15;
|
||||
v18->field_C[v17].string = v15;
|
||||
} else {
|
||||
v18->field_C[v17].field_4 = NULL;
|
||||
v18->field_C[v17].string = NULL;
|
||||
}
|
||||
|
||||
v18->field_C[v17].field_18 = widgetGetFont();
|
||||
|
@ -215,7 +215,7 @@ void _replyAddOption(const char* a1, const char* a2, int a3)
|
|||
}
|
||||
|
||||
// 0x42F624
|
||||
void _replyAddOptionProc(const char* a1, const char* a2, int a3)
|
||||
void _replyAddOptionProc(const char* a1, int a2, int a3)
|
||||
{
|
||||
STRUCT_56DAE0_FIELD_4* v5;
|
||||
int v13;
|
||||
|
@ -224,7 +224,7 @@ void _replyAddOptionProc(const char* a1, const char* a2, int a3)
|
|||
v5 = _getReply();
|
||||
v13 = v5->field_14 - 1;
|
||||
|
||||
v5->field_C[v13].field_8 = 1;
|
||||
v5->field_C[v13].kind = 1;
|
||||
|
||||
if (a1 != NULL) {
|
||||
v11 = (char*)internal_malloc_safe(strlen(a1) + 1, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 830
|
||||
|
@ -234,7 +234,7 @@ void _replyAddOptionProc(const char* a1, const char* a2, int a3)
|
|||
v5->field_C[v13].field_0 = NULL;
|
||||
}
|
||||
|
||||
v5->field_C[v13].field_4 = (char*)a2;
|
||||
v5->field_C[v13].proc = a2;
|
||||
|
||||
v5->field_C[v13].field_18 = widgetGetFont();
|
||||
v5->field_C[v13].field_1A = word_56DB60;
|
||||
|
@ -248,9 +248,9 @@ void _optionFree(STRUCT_56DAE0_FIELD_4_FIELD_C* a1)
|
|||
internal_free_safe(a1->field_0, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 844
|
||||
}
|
||||
|
||||
if (a1->field_8 == 2) {
|
||||
if (a1->field_4 != NULL) {
|
||||
internal_free_safe(a1->field_4, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 846
|
||||
if (a1->kind == 2) {
|
||||
if (a1->string != NULL) {
|
||||
internal_free_safe(a1->string, __FILE__, __LINE__); // "..\\int\\DIALOG.C", 846
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ int _dialogOption(const char* a1, const char* a2)
|
|||
}
|
||||
|
||||
// 0x430F38
|
||||
int _dialogOptionProc(const char* a1, const char* a2)
|
||||
int _dialogOptionProc(const char* a1, int a2)
|
||||
{
|
||||
if (_dialog[_tods].field_C == -1) {
|
||||
return 1;
|
||||
|
@ -514,6 +514,20 @@ int _dialogOptionProc(const char* a1, const char* a2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// 0x430FD4
|
||||
int sub_430FD4(const char* a1, const char* a2, int timeout)
|
||||
{
|
||||
// TODO: Incomplete.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 0x431088
|
||||
int sub_431088(int a1)
|
||||
{
|
||||
// TODO: Incomplete.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 0x431184
|
||||
int _dialogGetExitPoint()
|
||||
{
|
||||
|
@ -533,24 +547,24 @@ int _dialogQuit()
|
|||
}
|
||||
|
||||
// 0x4311B8
|
||||
int dialogSetOptionWindow(int a1, int a2, int a3, int a4, int a5)
|
||||
int dialogSetOptionWindow(int a1, int a2, int a3, int a4, char* a5)
|
||||
{
|
||||
dword_56DB6C = a1;
|
||||
dword_56DB70 = a2;
|
||||
dword_56DB64 = a3;
|
||||
dword_56DB68 = a4;
|
||||
_rand2plus = a5;
|
||||
off_56DB74 = a5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4311E0
|
||||
int dialogSetReplyWindow(int a1, int a2, int a3, int a4, int a5)
|
||||
int dialogSetReplyWindow(int a1, int a2, int a3, int a4, char* a5)
|
||||
{
|
||||
dword_56DB84 = a1;
|
||||
dword_56DB88 = a2;
|
||||
dword_56DB7C = a3;
|
||||
dword_56DB80 = a4;
|
||||
dword_56DB8C = a5;
|
||||
off_56DB8C = a5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -565,7 +579,7 @@ int dialogSetBorder(int a1, int a2)
|
|||
}
|
||||
|
||||
// 0x431218
|
||||
int _dialogSetScrollUp(int a1, int a2, void* a3, void* a4, void* a5, void* a6, int a7)
|
||||
int _dialogSetScrollUp(int a1, int a2, char* a3, char* a4, char* a5, char* a6, int a7)
|
||||
{
|
||||
_upButton = a1;
|
||||
dword_56DBD8 = a2;
|
||||
|
@ -596,7 +610,7 @@ int _dialogSetScrollUp(int a1, int a2, void* a3, void* a4, void* a5, void* a6, i
|
|||
}
|
||||
|
||||
// 0x4312C0
|
||||
int _dialogSetScrollDown(int a1, int a2, void* a3, void* a4, void* a5, void* a6, int a7)
|
||||
int _dialogSetScrollDown(int a1, int a2, char* a3, char* a4, char* a5, char* a6, int a7)
|
||||
{
|
||||
_downButton = a1;
|
||||
dword_56DBB8 = a2;
|
||||
|
@ -666,6 +680,11 @@ int _dialogSetOptionFlags(int flags)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// 0x431430
|
||||
void dialogInit()
|
||||
{
|
||||
}
|
||||
|
||||
// 0x431434
|
||||
void _dialogClose()
|
||||
{
|
||||
|
|
42
src/dialog.h
42
src/dialog.h
|
@ -8,8 +8,11 @@ typedef void DialogFunc2(int win);
|
|||
|
||||
typedef struct STRUCT_56DAE0_FIELD_4_FIELD_C {
|
||||
char* field_0;
|
||||
char* field_4;
|
||||
int field_8;
|
||||
union {
|
||||
int proc;
|
||||
char* string;
|
||||
};
|
||||
int kind;
|
||||
int field_C;
|
||||
int field_10;
|
||||
int field_14;
|
||||
|
@ -60,12 +63,12 @@ extern int dword_56DB64;
|
|||
extern int dword_56DB68;
|
||||
extern int dword_56DB6C;
|
||||
extern int dword_56DB70;
|
||||
extern int _rand2plus;
|
||||
extern char* off_56DB74;
|
||||
extern int dword_56DB7C;
|
||||
extern int dword_56DB80;
|
||||
extern int dword_56DB84;
|
||||
extern int dword_56DB88;
|
||||
extern int dword_56DB8C;
|
||||
extern char* off_56DB8C;
|
||||
extern int _replyPlaying;
|
||||
extern int _replyWin;
|
||||
extern int gDialogReplyColorG;
|
||||
|
@ -77,22 +80,22 @@ extern int gDialogOptionColorR;
|
|||
extern int _downButton;
|
||||
extern int dword_56DBB8;
|
||||
extern int dword_56DBBC;
|
||||
extern void* off_56DBC0;
|
||||
extern void* off_56DBC4;
|
||||
extern void* off_56DBC8;
|
||||
extern void* off_56DBCC;
|
||||
extern char* off_56DBC0;
|
||||
extern char* off_56DBC4;
|
||||
extern char* off_56DBC8;
|
||||
extern char* off_56DBCC;
|
||||
extern char* gDialogReplyTitle;
|
||||
extern int _upButton;
|
||||
extern int dword_56DBD8;
|
||||
extern int dword_56DBDC;
|
||||
extern void* off_56DBE0;
|
||||
extern void* off_56DBE4;
|
||||
extern void* off_56DBE8;
|
||||
extern void* off_56DBEC;
|
||||
extern char* off_56DBE0;
|
||||
extern char* off_56DBE4;
|
||||
extern char* off_56DBE8;
|
||||
extern char* off_56DBEC;
|
||||
|
||||
STRUCT_56DAE0_FIELD_4* _getReply();
|
||||
void _replyAddOption(const char* a1, const char* a2, int a3);
|
||||
void _replyAddOptionProc(const char* a1, const char* a2, int a3);
|
||||
void _replyAddOptionProc(const char* a1, int a2, int a3);
|
||||
void _optionFree(STRUCT_56DAE0_FIELD_4_FIELD_C* a1);
|
||||
void _replyFree();
|
||||
int _endDialog();
|
||||
|
@ -107,18 +110,21 @@ int _dialogGotoReply(const char* a1);
|
|||
int dialogSetReplyTitle(const char* a1);
|
||||
int _dialogReply(const char* a1, const char* a2);
|
||||
int _dialogOption(const char* a1, const char* a2);
|
||||
int _dialogOptionProc(const char* a1, const char* a2);
|
||||
int _dialogOptionProc(const char* a1, int a2);
|
||||
int sub_430FD4(const char* a1, const char* a2, int timeout);
|
||||
int sub_431088(int a1);
|
||||
int _dialogGetExitPoint();
|
||||
int _dialogQuit();
|
||||
int dialogSetOptionWindow(int a1, int a2, int a3, int a4, int a5);
|
||||
int dialogSetReplyWindow(int a1, int a2, int a3, int a4, int a5);
|
||||
int dialogSetOptionWindow(int a1, int a2, int a3, int a4, char* a5);
|
||||
int dialogSetReplyWindow(int a1, int a2, int a3, int a4, char* a5);
|
||||
int dialogSetBorder(int a1, int a2);
|
||||
int _dialogSetScrollUp(int a1, int a2, void* a3, void* a4, void* a5, void* a6, int a7);
|
||||
int _dialogSetScrollDown(int a1, int a2, void* a3, void* a4, void* a5, void* a6, int a7);
|
||||
int _dialogSetScrollUp(int a1, int a2, char* a3, char* a4, char* a5, char* a6, int a7);
|
||||
int _dialogSetScrollDown(int a1, int a2, char* a3, char* a4, char* a5, char* a6, int a7);
|
||||
int dialogSetOptionSpacing(int value);
|
||||
int dialogSetOptionColor(float a1, float a2, float a3);
|
||||
int dialogSetReplyColor(float a1, float a2, float a3);
|
||||
int _dialogSetOptionFlags(int flags);
|
||||
void dialogInit();
|
||||
void _dialogClose();
|
||||
int _dialogGetDialogDepth();
|
||||
void _dialogRegisterWinDrawCallbacks(DialogFunc1* a1, DialogFunc2* a2);
|
||||
|
|
|
@ -44,24 +44,19 @@ static void dictionaryFreeDefaultImpl(void* ptr)
|
|||
}
|
||||
|
||||
// 0x4D9BA8
|
||||
int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize, void* a4)
|
||||
int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize, DictionaryIO* io)
|
||||
{
|
||||
dictionary->entriesCapacity = initialCapacity;
|
||||
dictionary->valueSize = valueSize;
|
||||
dictionary->entriesLength = 0;
|
||||
|
||||
if (a4 != NULL) {
|
||||
// NOTE: There is some structure pointed by [a4] with 5 fields. They are
|
||||
// either memcopied or assigned one by one into field_10 - field_20
|
||||
// respectively. This parameter is always NULL, so I doubt it's possible
|
||||
// to understand it's meaning. There are some hints in the unused
|
||||
// functions though.
|
||||
assert(false && "Not implemented");
|
||||
if (io != NULL) {
|
||||
memcpy(&(dictionary->io), io, sizeof(*io));
|
||||
} else {
|
||||
dictionary->field_10 = 0;
|
||||
dictionary->field_14 = 0;
|
||||
dictionary->field_18 = 0;
|
||||
dictionary->field_1C = 0;
|
||||
dictionary->io.readProc = NULL;
|
||||
dictionary->io.writeProc = NULL;
|
||||
dictionary->io.field_8 = 0;
|
||||
dictionary->io.field_C = 0;
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
|
@ -302,6 +297,248 @@ int dictionaryRemoveValue(Dictionary* dictionary, const char* key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4D9F84
|
||||
int dictionaryCopy(Dictionary* dest, Dictionary* src)
|
||||
{
|
||||
if (src->marker != DICTIONARY_MARKER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionaryInit(dest, src->entriesCapacity, src->valueSize, &(src->io)) != 0) {
|
||||
// FIXME: Should return -1, as we were unable to initialize dictionary.
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int index = 0; index < src->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(src->entries[index]);
|
||||
if (dictionaryAddValue(dest, entry->key, entry->value) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA090
|
||||
int dictionaryReadInt(FILE* stream, int* valuePtr)
|
||||
{
|
||||
int ch;
|
||||
int value;
|
||||
|
||||
ch = fgetc(stream);
|
||||
if (ch == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (ch & 0xFF);
|
||||
|
||||
ch = fgetc(stream);
|
||||
if (ch == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (value << 8) | (ch & 0xFF);
|
||||
|
||||
ch = fgetc(stream);
|
||||
if (ch == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (value << 8) | (ch & 0xFF);
|
||||
|
||||
ch = fgetc(stream);
|
||||
if (ch == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (value << 8) | (ch & 0xFF);
|
||||
|
||||
*valuePtr = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA0F4
|
||||
int dictionaryReadHeader(FILE* stream, Dictionary* dictionary)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (dictionaryReadInt(stream, &value) != 0) return -1;
|
||||
dictionary->entriesLength = value;
|
||||
|
||||
if (dictionaryReadInt(stream, &value) != 0) return -1;
|
||||
dictionary->entriesCapacity = value;
|
||||
|
||||
if (dictionaryReadInt(stream, &value) != 0) return -1;
|
||||
dictionary->valueSize = value;
|
||||
|
||||
// NOTE: Originally reads `values` pointer.
|
||||
if (dictionaryReadInt(stream, &value) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA158
|
||||
int dictionaryLoad(FILE* stream, Dictionary* dictionary, int a3)
|
||||
{
|
||||
if (dictionary->marker != DICTIONARY_MARKER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < dictionary->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(dictionary->entries[index]);
|
||||
if (entry->key != NULL) {
|
||||
gDictionaryFreeProc(entry->key);
|
||||
}
|
||||
|
||||
if (entry->value != NULL) {
|
||||
gDictionaryFreeProc(entry->value);
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionary->entries != NULL) {
|
||||
gDictionaryFreeProc(dictionary->entries);
|
||||
}
|
||||
|
||||
if (dictionaryReadHeader(stream, dictionary) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dictionary->entries = NULL;
|
||||
|
||||
if (dictionary->entriesCapacity <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dictionary->entries = (DictionaryEntry*)gDictionaryMallocProc(sizeof(*dictionary->entries) * dictionary->entriesCapacity);
|
||||
if (dictionary->entries == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < dictionary->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(dictionary->entries[index]);
|
||||
entry->key = NULL;
|
||||
entry->value = NULL;
|
||||
}
|
||||
|
||||
if (dictionary->entriesLength <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int index = 0; index < dictionary->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(dictionary->entries[index]);
|
||||
int keyLength = fgetc(stream);
|
||||
if (keyLength == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry->key = (char*)gDictionaryMallocProc(keyLength + 1);
|
||||
if (entry->key == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fgets(entry->key, keyLength, stream) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionary->valueSize != 0) {
|
||||
entry->value = gDictionaryMallocProc(dictionary->valueSize);
|
||||
if (entry->value == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionary->io.readProc != NULL) {
|
||||
if (dictionary->io.readProc(stream, entry->value, dictionary->valueSize, a3) != 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (fread(entry->value, dictionary->valueSize, 1, stream) != 1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA2EC
|
||||
int dictionaryWriteInt(FILE* stream, int value)
|
||||
{
|
||||
if (fputc((value >> 24) & 0xFF, stream) == -1) return -1;
|
||||
if (fputc((value >> 16) & 0xFF, stream) == -1) return -1;
|
||||
if (fputc((value >> 8) & 0xFF, stream) == -1) return -1;
|
||||
if (fputc(value & 0xFF, stream) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA360
|
||||
int dictionaryWriteHeader(FILE* stream, Dictionary* dictionary)
|
||||
{
|
||||
if (dictionaryWriteInt(stream, dictionary->entriesLength) != 0) return -1;
|
||||
if (dictionaryWriteInt(stream, dictionary->entriesCapacity) != 0) return -1;
|
||||
if (dictionaryWriteInt(stream, dictionary->valueSize) != 0) return -1;
|
||||
// NOTE: Originally writes `entries` pointer.
|
||||
if (dictionaryWriteInt(stream, 0) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4DA3A4
|
||||
int dictionaryWrite(FILE* stream, Dictionary* dictionary, int a3)
|
||||
{
|
||||
if (dictionary->marker != DICTIONARY_MARKER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionaryWriteHeader(stream, dictionary) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < dictionary->entriesLength; index++) {
|
||||
DictionaryEntry* entry = &(dictionary->entries[index]);
|
||||
int keyLength = strlen(entry->key);
|
||||
if (fputc(keyLength, stream) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fputs(entry->key, stream) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dictionary->io.writeProc != NULL) {
|
||||
if (dictionary->valueSize != 0) {
|
||||
if (dictionary->io.writeProc(stream, entry->value, dictionary->valueSize, a3) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dictionary->valueSize != 0) {
|
||||
if (fwrite(entry->value, dictionary->valueSize, 1, stream) != 1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4DA498
|
||||
void dictionarySetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,20 @@
|
|||
|
||||
#include "memory_defs.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef int(DictionaryReadProc)(FILE* stream, void* buffer, unsigned int size, int a4);
|
||||
typedef int(DictionaryWriteProc)(FILE* stream, void* buffer, unsigned int size, int a4);
|
||||
|
||||
// NOTE: Last unnamed fields are likely seek, tell, and filelength.
|
||||
typedef struct DictionaryIO {
|
||||
DictionaryReadProc* readProc;
|
||||
DictionaryWriteProc* writeProc;
|
||||
int field_8;
|
||||
int field_C;
|
||||
int field_10;
|
||||
} DictionaryIO;
|
||||
|
||||
// A tuple containing individual key-value pair of a dictionary.
|
||||
typedef struct DictionaryEntry {
|
||||
char* key;
|
||||
|
@ -27,22 +41,26 @@ typedef struct Dictionary {
|
|||
// The size of the dictionary values in bytes.
|
||||
size_t valueSize;
|
||||
|
||||
int field_10;
|
||||
int field_14;
|
||||
int field_18;
|
||||
int field_1C;
|
||||
int field_20;
|
||||
// IO callbacks.
|
||||
DictionaryIO io;
|
||||
|
||||
// The array of key-value pairs.
|
||||
DictionaryEntry* entries;
|
||||
} Dictionary;
|
||||
|
||||
int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize, void* a4);
|
||||
int dictionaryInit(Dictionary* dictionary, int initialCapacity, size_t valueSize, DictionaryIO* io);
|
||||
int dictionarySetCapacity(Dictionary* dictionary, int newCapacity);
|
||||
int dictionaryFree(Dictionary* dictionary);
|
||||
int dictionaryGetIndexByKey(Dictionary* dictionary, const char* key);
|
||||
int dictionaryAddValue(Dictionary* dictionary, const char* key, const void* value);
|
||||
int dictionaryRemoveValue(Dictionary* dictionary, const char* key);
|
||||
int dictionaryCopy(Dictionary* dest, Dictionary* src);
|
||||
int dictionaryReadInt(FILE* stream, int* valuePtr);
|
||||
int dictionaryReadHeader(FILE* stream, Dictionary* dictionary);
|
||||
int dictionaryLoad(FILE* stream, Dictionary* dictionary, int a3);
|
||||
int dictionaryWriteInt(FILE* stream, int value);
|
||||
int dictionaryWriteHeader(FILE* stream, Dictionary* dictionary);
|
||||
int dictionaryWrite(FILE* stream, Dictionary* dictionary, int a3);
|
||||
void dictionarySetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc);
|
||||
|
||||
#endif /* DICTIONARY_H */
|
||||
|
|
|
@ -105,7 +105,7 @@ int displayMonitorInit()
|
|||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 16, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 16, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
internal_free(gDisplayMonitorBackgroundFrmData);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef DRAW_H
|
||||
#define DRAW_H
|
||||
|
||||
void bufferDrawLine(unsigned char* buf, int pitch, int left, int top, int right, int bottom, int color);
|
||||
void bufferDrawLine(unsigned char* buf, int pitch, int left, int top, int right, int bottom, int color);
|
||||
void bufferDrawRect(unsigned char* buf, int a2, int a3, int a4, int a5, int a6, int a7);
|
||||
void bufferDrawRectShadowed(unsigned char* buf, int a2, int a3, int a4, int a5, int a6, int a7, int a8);
|
||||
void blitBufferToBufferStretch(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* dest, int destWidth, int destHeight, int destPitch);
|
||||
|
|
|
@ -503,7 +503,7 @@ static int elevatorWindowInit(int elevator)
|
|||
|
||||
int index;
|
||||
for (index = 0; index < ELEVATOR_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gElevatorFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gElevatorFrmIds[index], 0, 0, 0);
|
||||
gElevatorFrmData[index] = artLockFrameDataReturningSize(fid, &(gElevatorFrmHandles[index]), &(gElevatorFrmSizes[index].width), &(gElevatorFrmSizes[index].height));
|
||||
if (gElevatorFrmData[index] == NULL) {
|
||||
break;
|
||||
|
@ -530,11 +530,11 @@ static int elevatorWindowInit(int elevator)
|
|||
const ElevatorBackground* elevatorBackground = &(gElevatorBackgrounds[elevator]);
|
||||
bool backgroundsLoaded = true;
|
||||
|
||||
int backgroundFid = buildFid(6, elevatorBackground->backgroundFrmId, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, elevatorBackground->backgroundFrmId, 0, 0, 0);
|
||||
gElevatorBackgroundFrmData = artLockFrameDataReturningSize(backgroundFid, &gElevatorBackgroundFrmHandle, &gElevatorBackgroundFrmWidth, &gElevatorBackgroundFrmHeight);
|
||||
if (gElevatorBackgroundFrmData != NULL) {
|
||||
if (elevatorBackground->panelFrmId != -1) {
|
||||
int panelFid = buildFid(6, elevatorBackground->panelFrmId, 0, 0, 0);
|
||||
int panelFid = buildFid(OBJ_TYPE_INTERFACE, elevatorBackground->panelFrmId, 0, 0, 0);
|
||||
gElevatorPanelFrmData = artLockFrameDataReturningSize(panelFid, &gElevatorPanelFrmHandle, &gElevatorPanelFrmWidth, &gElevatorPanelFrmHeight);
|
||||
if (gElevatorPanelFrmData == NULL) {
|
||||
gElevatorPanelFrmData = ELEVATOR_BACKGROUND_NULL;
|
||||
|
|
|
@ -217,7 +217,7 @@ void endgamePlaySlideshow()
|
|||
if (ending->art_num == 327) {
|
||||
endgameEndingRenderPanningScene(ending->direction, ending->voiceOverBaseName);
|
||||
} else {
|
||||
int fid = buildFid(6, ending->art_num, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, ending->art_num, 0, 0, 0);
|
||||
endgameEndingRenderStaticScene(fid, ending->voiceOverBaseName);
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ static int endgameEndingHandleContinuePlaying()
|
|||
// 0x43FBDC
|
||||
static void endgameEndingRenderPanningScene(int direction, const char* narratorFileName)
|
||||
{
|
||||
int fid = buildFid(6, 327, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 327, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
Art* background = artLock(fid, &backgroundHandle);
|
||||
|
@ -441,7 +441,7 @@ static void endgameEndingRenderStaticScene(int fid, const char* narratorFileName
|
|||
blitBufferToBuffer(backgroundData, ENDGAME_ENDING_WINDOW_WIDTH, ENDGAME_ENDING_WINDOW_HEIGHT, ENDGAME_ENDING_WINDOW_WIDTH, gEndgameEndingSlideshowWindowBuffer, ENDGAME_ENDING_WINDOW_WIDTH);
|
||||
windowRefresh(gEndgameEndingSlideshowWindow);
|
||||
|
||||
endgameEndingLoadPalette((fid & 0xF000000) >> 24, fid & 0xFFF);
|
||||
endgameEndingLoadPalette(FID_TYPE(fid), fid & 0xFFF);
|
||||
|
||||
endgameEndingVoiceOverInit(narratorFileName);
|
||||
|
||||
|
@ -746,23 +746,15 @@ static int endgameEndingSubtitlesLoad(const char* filePath)
|
|||
char* pch;
|
||||
|
||||
// Find and clamp string at EOL.
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != '\n') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, '\n');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
// Find separator. The value before separator is ignored (as opposed to
|
||||
// movie subtitles, where the value before separator is a timing).
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != ':') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, ':');
|
||||
if (pch != NULL) {
|
||||
if (gEndgameEndingSubtitlesLength < ENDGAME_ENDING_MAX_SUBTITLES) {
|
||||
gEndgameEndingSubtitles[gEndgameEndingSubtitlesLength] = internal_strdup(pch + 1);
|
||||
gEndgameEndingSubtitlesLength++;
|
||||
|
|
|
@ -176,12 +176,11 @@ int externalVariableSetValue(Program* program, const char* name, ProgramValue& p
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 169
|
||||
}
|
||||
|
||||
if ((programValue.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((programValue.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
if (program != NULL) {
|
||||
const char* stringValue = programGetString(program, programValue.opcode, programValue.integerValue);
|
||||
exportedVariable->value.opcode = VALUE_TYPE_DYNAMIC_STRING;
|
||||
|
@ -204,7 +203,7 @@ int externalVariableGetValue(Program* program, const char* name, ProgramValue& v
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
value.opcode = exportedVariable->value.opcode;
|
||||
value.integerValue = programPushString(program, exportedVariable->stringValue);
|
||||
} else {
|
||||
|
@ -225,7 +224,7 @@ int externalVariableCreate(Program* program, const char* identifier)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 234
|
||||
}
|
||||
} else {
|
||||
|
@ -261,7 +260,7 @@ void _removeProgramReferences(Program* program)
|
|||
// 0x44152C
|
||||
void _initExport()
|
||||
{
|
||||
_interpretRegisterProgramDeleteCallback(_removeProgramReferences);
|
||||
intLibRegisterProgramDeleteCallback(_removeProgramReferences);
|
||||
}
|
||||
|
||||
// 0x441538
|
||||
|
@ -328,7 +327,7 @@ void _exportClearAllVariables()
|
|||
for (int index = 0; index < 1013; index++) {
|
||||
ExternalVariable* exportedVariable = &(gExternalVariables[index]);
|
||||
if (exportedVariable->name[0] != '\0') {
|
||||
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
||||
if ((exportedVariable->value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
||||
if (exportedVariable->stringValue != NULL) {
|
||||
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 387
|
||||
}
|
||||
|
|
62
src/game.cc
62
src/game.cc
|
@ -720,14 +720,14 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
|
|||
case KEY_COMMA:
|
||||
case KEY_LESS:
|
||||
if (reg_anim_begin(0) == 0) {
|
||||
reg_anim_rotate_counter_clockwise(gDude);
|
||||
animationRegisterRotateCounterClockwise(gDude);
|
||||
reg_anim_end();
|
||||
}
|
||||
break;
|
||||
case KEY_DOT:
|
||||
case KEY_GREATER:
|
||||
if (reg_anim_begin(0) == 0) {
|
||||
reg_anim_rotate_clockwise(gDude);
|
||||
animationRegisterRotateClockwise(gDude);
|
||||
reg_anim_end();
|
||||
}
|
||||
break;
|
||||
|
@ -930,68 +930,56 @@ static int gameLoadGlobalVars()
|
|||
}
|
||||
|
||||
// 0x443CE8
|
||||
int globalVarsRead(const char* path, const char* section, int* out_vars_num, int** out_vars)
|
||||
int globalVarsRead(const char* path, const char* section, int* variablesListLengthPtr, int** variablesListPtr)
|
||||
{
|
||||
File* stream;
|
||||
char str[258];
|
||||
char* ch;
|
||||
|
||||
_inven_reset_dude();
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
File* stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*out_vars_num != 0) {
|
||||
internal_free(*out_vars);
|
||||
*out_vars = NULL;
|
||||
*out_vars_num = 0;
|
||||
if (*variablesListLengthPtr != 0) {
|
||||
internal_free(*variablesListPtr);
|
||||
*variablesListPtr = NULL;
|
||||
*variablesListLengthPtr = 0;
|
||||
}
|
||||
|
||||
char string[260];
|
||||
if (section != NULL) {
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
if (strncmp(str, section, 16) == 0) {
|
||||
while (fileReadString(string, 258, stream)) {
|
||||
if (strncmp(string, section, 16) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
if (str[0] == '\n') {
|
||||
while (fileReadString(string, 258, stream)) {
|
||||
if (string[0] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str[0] == '/' && str[1] == '/') {
|
||||
if (string[0] == '/' && string[1] == '/') {
|
||||
continue;
|
||||
}
|
||||
|
||||
ch = str;
|
||||
|
||||
while (*ch != '\0' && *ch != ';') {
|
||||
ch++;
|
||||
char* semicolon = strchr(string, ';');
|
||||
if (semicolon != NULL) {
|
||||
*semicolon = '\0';
|
||||
}
|
||||
|
||||
if (*ch != '\0') {
|
||||
*ch = '\0';
|
||||
}
|
||||
*variablesListLengthPtr = *variablesListLengthPtr + 1;
|
||||
*variablesListPtr = (int*)internal_realloc(*variablesListPtr, sizeof(int) * *variablesListLengthPtr);
|
||||
|
||||
*out_vars_num = *out_vars_num + 1;
|
||||
*out_vars = (int*)internal_realloc(*out_vars, sizeof(int) * *out_vars_num);
|
||||
|
||||
if (*out_vars == NULL) {
|
||||
if (*variablesListPtr == NULL) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ch = str;
|
||||
while (*ch != '\0' && *ch != '=') {
|
||||
ch++;
|
||||
}
|
||||
|
||||
if (*ch != '\0') {
|
||||
sscanf(ch + 1, "%d", *out_vars + *out_vars_num - 1);
|
||||
char* equals = strchr(string, '=');
|
||||
if (equals != NULL) {
|
||||
sscanf(equals + 1, "%d", *variablesListPtr + *variablesListLengthPtr - 1);
|
||||
} else {
|
||||
*out_vars[*out_vars_num - 1] = 0;
|
||||
*variablesListPtr[*variablesListLengthPtr - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1098,7 +1086,7 @@ static void showHelp()
|
|||
if (win != -1) {
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
if (windowBuffer != NULL) {
|
||||
int backgroundFid = buildFid(6, 297, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 297, 0, 0, 0);
|
||||
CacheEntry* backgroundHandle;
|
||||
unsigned char* backgroundData = artLockFrameData(backgroundFid, 0, 0, &backgroundHandle);
|
||||
if (backgroundData != NULL) {
|
||||
|
|
|
@ -22,7 +22,7 @@ void gameUiEnable();
|
|||
bool gameUiIsDisabled();
|
||||
int gameGetGlobalVar(int var);
|
||||
int gameSetGlobalVar(int var, int value);
|
||||
int globalVarsRead(const char* path, const char* section, int* out_vars_num, int** out_vars);
|
||||
int globalVarsRead(const char* path, const char* section, int* variablesListLengthPtr, int** variablesListPtr);
|
||||
int _game_state();
|
||||
int _game_state_request(int a1);
|
||||
void _game_state_update();
|
||||
|
|
|
@ -717,7 +717,7 @@ void gameDialogEnter(Object* a1, int a2)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((a1->pid >> 24) != OBJ_TYPE_ITEM && (a1->sid >> 24) != SCRIPT_TYPE_SPATIAL) {
|
||||
if (PID_TYPE(a1->pid) != OBJ_TYPE_ITEM && SID_TYPE(a1->sid) != SCRIPT_TYPE_SPATIAL) {
|
||||
MessageListItem messageListItem;
|
||||
|
||||
int rc = _action_can_talk_to(gDude, a1);
|
||||
|
@ -915,9 +915,9 @@ int _gdialogInitFromScript(int headFid, int reaction)
|
|||
gGameDialogSpeakerIsPartyMember = objectIsPartyMember(gGameDialogSpeaker);
|
||||
_oldFont = fontGetCurrent();
|
||||
fontSetCurrent(101);
|
||||
dialogSetReplyWindow(135, 225, 379, 58, 0);
|
||||
dialogSetReplyWindow(135, 225, 379, 58, NULL);
|
||||
dialogSetReplyColor(0.3f, 0.3f, 0.3f);
|
||||
dialogSetOptionWindow(127, 335, 393, 117, 0);
|
||||
dialogSetOptionWindow(127, 335, 393, 117, NULL);
|
||||
dialogSetOptionColor(0.2f, 0.2f, 0.2f);
|
||||
dialogSetReplyTitle(NULL);
|
||||
_dialogRegisterWinDrawCallbacks(_demo_copy_title, _demo_copy_options);
|
||||
|
@ -930,7 +930,7 @@ int _gdialogInitFromScript(int headFid, int reaction)
|
|||
gameMouseSetCursor(MOUSE_CURSOR_ARROW);
|
||||
textObjectsReset();
|
||||
|
||||
if ((gGameDialogSpeaker->pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(gGameDialogSpeaker->pid) != OBJ_TYPE_ITEM) {
|
||||
_tile_scroll_to(gGameDialogSpeaker->tile, 2);
|
||||
}
|
||||
|
||||
|
@ -970,7 +970,7 @@ int _gdialogExitFromScript()
|
|||
dialogReviewEntriesClear();
|
||||
tickersRemove(gameDialogTicker);
|
||||
|
||||
if (gGameDialogSpeaker->pid >> 24 != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(gGameDialogSpeaker->pid) != OBJ_TYPE_ITEM) {
|
||||
if (gGameDialogOldDudeTile != gDude->tile) {
|
||||
gGameDialogOldCenterTile = gDude->tile;
|
||||
}
|
||||
|
@ -1298,7 +1298,7 @@ int gameDialogReviewWindowInit(int* win)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, 102, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 102, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &_reviewBackKey);
|
||||
if (backgroundFrmData == NULL) {
|
||||
windowDestroy(*win);
|
||||
|
@ -1318,10 +1318,10 @@ int gameDialogReviewWindowInit(int* win)
|
|||
_reviewBackKey = INVALID_CACHE_ENTRY;
|
||||
|
||||
unsigned char* buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT];
|
||||
|
||||
|
||||
int index;
|
||||
for (index = 0; index < GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gGameDialogReviewWindowButtonFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameDialogReviewWindowButtonFrmIds[index], 0, 0, 0);
|
||||
buttonFrmData[index] = artLockFrameData(fid, 0, 0, &(gGameDialogReviewWindowButtonFrmHandles[index]));
|
||||
if (buttonFrmData[index] == NULL) {
|
||||
break;
|
||||
|
@ -1360,11 +1360,11 @@ int gameDialogReviewWindowInit(int* win)
|
|||
gGameDialogReviewWindowButtonHeights[GAME_DIALOG_REVIEW_WINDOW_BUTTON_SCROLL_DOWN],
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_ARROW_DOWN,
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_NORMAL],
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_PRESSED],
|
||||
NULL,
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_ARROW_DOWN_PRESSED],
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
if (downBtn == -1) {
|
||||
gameDialogReviewWindowFree(win);
|
||||
|
@ -1373,18 +1373,18 @@ int gameDialogReviewWindowInit(int* win)
|
|||
|
||||
buttonSetCallbacks(downBtn, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
int doneBtn = buttonCreate(*win,
|
||||
499,
|
||||
398,
|
||||
gGameDialogReviewWindowButtonWidths[GAME_DIALOG_REVIEW_WINDOW_BUTTON_DONE],
|
||||
int doneBtn = buttonCreate(*win,
|
||||
499,
|
||||
398,
|
||||
gGameDialogReviewWindowButtonWidths[GAME_DIALOG_REVIEW_WINDOW_BUTTON_DONE],
|
||||
gGameDialogReviewWindowButtonHeights[GAME_DIALOG_REVIEW_WINDOW_BUTTON_DONE],
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_NORMAL],
|
||||
-1,
|
||||
-1,
|
||||
KEY_ESCAPE,
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_NORMAL],
|
||||
buttonFrmData[GAME_DIALOG_REVIEW_WINDOW_BUTTON_FRM_DONE_PRESSED],
|
||||
NULL,
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
if (doneBtn == -1) {
|
||||
gameDialogReviewWindowFree(win);
|
||||
|
@ -1399,7 +1399,7 @@ int gameDialogReviewWindowInit(int* win)
|
|||
|
||||
tickersRemove(gameDialogTicker);
|
||||
|
||||
int backgroundFid = buildFid(6, 102, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 102, 0, 0, 0);
|
||||
gGameDialogReviewWindowBackgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &gGameDialogReviewWindowBackgroundFrmHandle);
|
||||
if (gGameDialogReviewWindowBackgroundFrmData == NULL) {
|
||||
gameDialogReviewWindowFree(win);
|
||||
|
@ -1691,7 +1691,7 @@ int gameDialogSetReviewOptionText(const char* string)
|
|||
// 0x446288
|
||||
int _gdProcessInit()
|
||||
{
|
||||
int upBtn;
|
||||
int upBtn;
|
||||
int downBtn;
|
||||
int optionsWindowX;
|
||||
int optionsWindowY;
|
||||
|
@ -1735,14 +1735,14 @@ int _gdProcessInit()
|
|||
}
|
||||
|
||||
// di_rdbt2.frm - dialog red button down
|
||||
fid = buildFid(6, 96, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 96, 0, 0, 0);
|
||||
gGameDialogRedButtonUpFrmData = artLockFrameData(fid, 0, 0, &gGameDialogRedButtonUpFrmHandle);
|
||||
if (gGameDialogRedButtonUpFrmData == NULL) {
|
||||
goto err_3;
|
||||
}
|
||||
|
||||
// di_rdbt1.frm - dialog red button up
|
||||
fid = buildFid(6, 95, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 95, 0, 0, 0);
|
||||
gGameDialogRedButtonDownFrmData = artLockFrameData(fid, 0, 0, &gGameDialogRedButtonDownFrmHandle);
|
||||
if (gGameDialogRedButtonDownFrmData == NULL) {
|
||||
goto err_3;
|
||||
|
@ -3010,7 +3010,7 @@ int gameDialogDrawText(unsigned char* buffer, Rect* rect, char* string, int* a4,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (*end == ' ') {
|
||||
*end = '\0';
|
||||
}
|
||||
|
@ -3127,7 +3127,7 @@ int _gdialog_barter_create_win()
|
|||
frmId = 111;
|
||||
}
|
||||
|
||||
int backgroundFid = buildFid(6, frmId, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
CacheEntry* backgroundHandle;
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
|
@ -3236,7 +3236,7 @@ void _gdialog_barter_destroy_win()
|
|||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int fid = buildFid(6, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
|
||||
|
@ -3287,7 +3287,7 @@ void _gdialog_barter_cleanup_tables()
|
|||
int partyMemberControlWindowInit()
|
||||
{
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 390, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
return -1;
|
||||
|
@ -3359,7 +3359,7 @@ int partyMemberControlWindowInit()
|
|||
GameDialogButtonData* buttonData = &(gGameDialogDispositionButtonsData[index]);
|
||||
int fid;
|
||||
|
||||
fid = buildFid(6, buttonData->upFrmId, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->upFrmId, 0, 0, 0);
|
||||
Art* upButtonFrm = artLock(fid, &(buttonData->upFrmHandle));
|
||||
if (upButtonFrm == NULL) {
|
||||
partyMemberControlWindowFree();
|
||||
|
@ -3370,7 +3370,7 @@ int partyMemberControlWindowInit()
|
|||
int height = artGetHeight(upButtonFrm, 0, 0);
|
||||
unsigned char* upButtonFrmData = artGetFrameData(upButtonFrm, 0, 0);
|
||||
|
||||
fid = buildFid(6, buttonData->downFrmId, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->downFrmId, 0, 0, 0);
|
||||
Art* downButtonFrm = artLock(fid, &(buttonData->downFrmHandle));
|
||||
if (downButtonFrm == NULL) {
|
||||
partyMemberControlWindowFree();
|
||||
|
@ -3379,7 +3379,7 @@ int partyMemberControlWindowInit()
|
|||
|
||||
unsigned char* downButtonFrmData = artGetFrameData(downButtonFrm, 0, 0);
|
||||
|
||||
fid = buildFid(6, buttonData->disabledFrmId, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, buttonData->disabledFrmId, 0, 0, 0);
|
||||
Art* disabledButtonFrm = artLock(fid, &(buttonData->disabledFrmHandle));
|
||||
if (disabledButtonFrm == NULL) {
|
||||
partyMemberControlWindowFree();
|
||||
|
@ -3394,14 +3394,14 @@ int partyMemberControlWindowInit()
|
|||
buttonData->x,
|
||||
buttonData->y,
|
||||
width,
|
||||
height,
|
||||
height,
|
||||
-1,
|
||||
-1,
|
||||
buttonData->keyCode,
|
||||
-1,
|
||||
upButtonFrmData,
|
||||
-1,
|
||||
buttonData->keyCode,
|
||||
-1,
|
||||
upButtonFrmData,
|
||||
downButtonFrmData,
|
||||
NULL,
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT | BUTTON_FLAG_0x04 | BUTTON_FLAG_0x01);
|
||||
if (_gdialog_buttons[v21] == -1) {
|
||||
partyMemberControlWindowFree();
|
||||
|
@ -3463,7 +3463,7 @@ void partyMemberControlWindowFree()
|
|||
|
||||
// control.frm - party member control interface
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 390, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmData, windowGetBuffer(gGameDialogWindow), windowGetBuffer(gGameDialogBackgroundWindow) + (GAME_DIALOG_WINDOW_WIDTH) * (480 - _dialogue_subwin_len), _dialogue_subwin_len, 0);
|
||||
|
@ -3484,7 +3484,7 @@ void partyMemberControlWindowUpdate()
|
|||
int windowWidth = windowGetWidth(gGameDialogWindow);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
int backgroundFid = buildFid(6, 390, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 390, 0, 0, 0);
|
||||
Art* background = artLock(backgroundFid, &backgroundHandle);
|
||||
if (background != NULL) {
|
||||
int width = artGetWidth(background, 0, 0);
|
||||
|
@ -3523,7 +3523,7 @@ void partyMemberControlWindowUpdate()
|
|||
|
||||
// Render preview.
|
||||
CacheEntry* previewHandle;
|
||||
int previewFid = buildFid((gGameDialogSpeaker->fid & 0xF000000) >> 24, gGameDialogSpeaker->fid & 0xFFF, ANIM_STAND, (gGameDialogSpeaker->fid & 0xF000) >> 12, ROTATION_SW);
|
||||
int previewFid = buildFid(FID_TYPE(gGameDialogSpeaker->fid), gGameDialogSpeaker->fid & 0xFFF, ANIM_STAND, (gGameDialogSpeaker->fid & 0xF000) >> 12, ROTATION_SW);
|
||||
Art* preview = artLock(previewFid, &previewHandle);
|
||||
if (preview != NULL) {
|
||||
int width = artGetWidth(preview, 0, ROTATION_SW);
|
||||
|
@ -3603,7 +3603,7 @@ int _gdPickAIUpdateMsg(Object* critter)
|
|||
// 0x449330
|
||||
int _gdCanBarter()
|
||||
{
|
||||
if ((gGameDialogSpeaker->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(gGameDialogSpeaker->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3612,7 +3612,7 @@ int _gdCanBarter()
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (proto->critter.data.flags & 0x02) {
|
||||
if (proto->critter.data.flags & CRITTER_FLAG_0x2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3724,7 +3724,7 @@ int partyMemberCustomizationWindowInit()
|
|||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 391, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
return -1;
|
||||
|
@ -3778,7 +3778,7 @@ int partyMemberCustomizationWindowInit()
|
|||
for (int index = 0; index < PARTY_MEMBER_CUSTOMIZATION_OPTION_COUNT; index++) {
|
||||
GameDialogButtonData* buttonData = &(_custom_button_info[index]);
|
||||
|
||||
int upButtonFid = buildFid(6, buttonData->upFrmId, 0, 0, 0);
|
||||
int upButtonFid = buildFid(OBJ_TYPE_INTERFACE, buttonData->upFrmId, 0, 0, 0);
|
||||
Art* upButtonFrm = artLock(upButtonFid, &(buttonData->upFrmHandle));
|
||||
if (upButtonFrm == NULL) {
|
||||
partyMemberCustomizationWindowFree();
|
||||
|
@ -3789,7 +3789,7 @@ int partyMemberCustomizationWindowInit()
|
|||
int height = artGetHeight(upButtonFrm, 0, 0);
|
||||
unsigned char* upButtonFrmData = artGetFrameData(upButtonFrm, 0, 0);
|
||||
|
||||
int downButtonFid = buildFid(6, buttonData->downFrmId, 0, 0, 0);
|
||||
int downButtonFid = buildFid(OBJ_TYPE_INTERFACE, buttonData->downFrmId, 0, 0, 0);
|
||||
Art* downButtonFrm = artLock(downButtonFid, &(buttonData->downFrmHandle));
|
||||
if (downButtonFrm == NULL) {
|
||||
partyMemberCustomizationWindowFree();
|
||||
|
@ -3867,7 +3867,7 @@ void partyMemberCustomizationWindowFree()
|
|||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
// custom.frm - party member control interface
|
||||
int fid = buildFid(6, 391, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
_gdialog_scroll_subwin(gGameDialogWindow, 0, backgroundFrmData, windowGetBuffer(gGameDialogWindow), windowGetBuffer(gGameDialogBackgroundWindow) + (GAME_DIALOG_WINDOW_WIDTH) * (480 - _dialogue_subwin_len), _dialogue_subwin_len, 0);
|
||||
|
@ -3917,7 +3917,7 @@ void partyMemberCustomizationWindowUpdate()
|
|||
int windowWidth = windowGetWidth(gGameDialogWindow);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
int backgroundFid = buildFid(6, 391, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 391, 0, 0, 0);
|
||||
Art* background = artLock(backgroundFid, &backgroundHandle);
|
||||
if (background == NULL) {
|
||||
return;
|
||||
|
@ -4025,7 +4025,7 @@ int _gdCustomSelect(int a1)
|
|||
int oldFont = fontGetCurrent();
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 419, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 419, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
return -1;
|
||||
|
@ -4208,7 +4208,7 @@ void _gdCustomUpdateSetting(int option, int value)
|
|||
// 0x44A52C
|
||||
void gameDialogBarterButtonUpMouseUp(int btn, int keyCode)
|
||||
{
|
||||
if ((gGameDialogSpeaker->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(gGameDialogSpeaker->pid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4219,7 +4219,7 @@ void gameDialogBarterButtonUpMouseUp(int btn, int keyCode)
|
|||
|
||||
Proto* proto;
|
||||
protoGetProto(gGameDialogSpeaker->pid, &proto);
|
||||
if (proto->critter.data.flags & 2) {
|
||||
if (proto->critter.data.flags & CRITTER_FLAG_0x2) {
|
||||
if (gGameDialogLipSyncStarted) {
|
||||
if (soundIsPlaying(gLipsData.sound)) {
|
||||
gameDialogEndLips();
|
||||
|
@ -4269,7 +4269,7 @@ int _gdialog_window_create()
|
|||
CacheEntry* backgroundFrmHandle;
|
||||
// 389 - di_talkp.frm - dialog screen subwindow (party members)
|
||||
// 99 - di_talk.frm - dialog screen subwindow (NPC's)
|
||||
int backgroundFid = buildFid(6, gGameDialogSpeakerIsPartyMember ? 389 : 99, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, gGameDialogSpeakerIsPartyMember ? 389 : 99, 0, 0, 0);
|
||||
Art* backgroundFrm = artLock(backgroundFid, &backgroundFrmHandle);
|
||||
if (backgroundFrm == NULL) {
|
||||
return -1;
|
||||
|
@ -4306,11 +4306,11 @@ int _gdialog_window_create()
|
|||
buttonSetCallbacks(_gdialog_buttons[0], _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
// di_rest1.frm - dialog rest button up
|
||||
int upFid = buildFid(6, 97, 0, 0, 0);
|
||||
int upFid = buildFid(OBJ_TYPE_INTERFACE, 97, 0, 0, 0);
|
||||
unsigned char* reviewButtonUpData = artLockFrameData(upFid, 0, 0, &gGameDialogReviewButtonUpFrmHandle);
|
||||
if (reviewButtonUpData != NULL) {
|
||||
// di_rest2.frm - dialog rest button down
|
||||
int downFid = buildFid(6, 98, 0, 0, 0);
|
||||
int downFid = buildFid(OBJ_TYPE_INTERFACE, 98, 0, 0, 0);
|
||||
unsigned char* reivewButtonDownData = artLockFrameData(downFid, 0, 0, &gGameDialogReviewButtonDownFrmHandle);
|
||||
if (reivewButtonDownData != NULL) {
|
||||
// REVIEW
|
||||
|
@ -4386,7 +4386,7 @@ void _gdialog_window_destroy()
|
|||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int fid = buildFid(6, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
unsigned char* windowBuffer = windowGetBuffer(gGameDialogWindow);
|
||||
|
@ -4403,7 +4403,7 @@ int gameDialogWindowRenderBackground()
|
|||
{
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
// alltlk.frm - dialog screen background
|
||||
int fid = buildFid(6, 103, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 103, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData == NULL) {
|
||||
return -1;
|
||||
|
@ -4434,7 +4434,7 @@ int _talkToRefreshDialogWindowRect(Rect* rect)
|
|||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int fid = buildFid(6, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData == NULL) {
|
||||
return -1;
|
||||
|
@ -4550,7 +4550,7 @@ void gameDialogRenderTalkingHead(Art* headFrm, int frame)
|
|||
unsigned char* src = windowGetBuffer(gIsoWindow);
|
||||
|
||||
// Usually rendering functions use `screenGetWidth`/`screenGetHeight` to
|
||||
// determine rendering position. However in this case `windowGetHeight`
|
||||
// determine rendering position. However in this case `windowGetHeight`
|
||||
// is a must because isometric window's height can either include
|
||||
// interface bar or not. Offset is updated accordingly (332 -> 232, the
|
||||
// missing 100 is interface bar height, which is already accounted for
|
||||
|
@ -4612,13 +4612,13 @@ void gameDialogPrepareHighlights()
|
|||
_dark_BlendTable = _getColorBlendTable(_colorTable[22187]);
|
||||
|
||||
// hilight1.frm - dialogue upper hilight
|
||||
int upperHighlightFid = buildFid(6, 115, 0, 0, 0);
|
||||
int upperHighlightFid = buildFid(OBJ_TYPE_INTERFACE, 115, 0, 0, 0);
|
||||
gGameDialogUpperHighlightFrm = artLock(upperHighlightFid, &gGameDialogUpperHighlightFrmHandle);
|
||||
gGameDialogUpperHighlightFrmWidth = artGetWidth(gGameDialogUpperHighlightFrm, 0, 0);
|
||||
gGameDialogUpperHighlightFrmHeight = artGetHeight(gGameDialogUpperHighlightFrm, 0, 0);
|
||||
|
||||
// hilight2.frm - dialogue lower hilight
|
||||
int lowerHighlightFid = buildFid(6, 116, 0, 0, 0);
|
||||
int lowerHighlightFid = buildFid(OBJ_TYPE_INTERFACE, 116, 0, 0, 0);
|
||||
gGameDialogLowerHighlightFrm = artLock(lowerHighlightFid, &gGameDialogLowerHighlightFrmHandle);
|
||||
gGameDialogLowerHighlightFrmWidth = artGetWidth(gGameDialogLowerHighlightFrm, 0, 0);
|
||||
gGameDialogLowerHighlightFrmHeight = artGetHeight(gGameDialogLowerHighlightFrm, 0, 0);
|
||||
|
|
|
@ -648,7 +648,7 @@ void gameMouseRefresh()
|
|||
if (pointedObject != NULL) {
|
||||
int primaryAction = -1;
|
||||
|
||||
switch ((pointedObject->fid & 0xF000000) >> 24) {
|
||||
switch (FID_TYPE(pointedObject->fid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
if (gGameMouseItemHighlightEnabled) {
|
||||
|
@ -670,7 +670,7 @@ void gameMouseRefresh()
|
|||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_TALK;
|
||||
}
|
||||
} else {
|
||||
if (_critter_flag_check(pointedObject->pid, 32)) {
|
||||
if (_critter_flag_check(pointedObject->pid, CRITTER_FLAG_0x20)) {
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_LOOK;
|
||||
} else {
|
||||
primaryAction = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
|
@ -693,7 +693,7 @@ void gameMouseRefresh()
|
|||
if (primaryAction != -1) {
|
||||
if (gameMouseRenderPrimaryAction(mouseX, mouseY, primaryAction, _scr_size.right - _scr_size.left + 1, _scr_size.bottom - _scr_size.top - 99) == 0) {
|
||||
Rect tmp;
|
||||
int fid = buildFid(6, 282, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 282, 0, 0, 0);
|
||||
if (objectSetFid(gGameMouseHexCursor, fid, &tmp) == 0) {
|
||||
tileWindowRefreshRect(&tmp, gElevation);
|
||||
}
|
||||
|
@ -715,7 +715,7 @@ void gameMouseRefresh()
|
|||
}
|
||||
|
||||
if (pointedObject != NULL) {
|
||||
bool pointedObjectIsCritter = (pointedObject->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER;
|
||||
bool pointedObjectIsCritter = FID_TYPE(pointedObject->fid) == OBJ_TYPE_CRITTER;
|
||||
|
||||
int combatLooks = 0;
|
||||
configGetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_COMBAT_LOOKS_KEY, &combatLooks);
|
||||
|
@ -756,7 +756,7 @@ void gameMouseRefresh()
|
|||
|
||||
if (gameMouseRenderAccuracy(formattedAccuracy, color) == 0) {
|
||||
Rect tmp;
|
||||
int fid = buildFid(6, 284, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 284, 0, 0, 0);
|
||||
if (objectSetFid(gGameMouseHexCursor, fid, &tmp) == 0) {
|
||||
tileWindowRefreshRect(&tmp, gElevation);
|
||||
}
|
||||
|
@ -825,7 +825,7 @@ void gameMouseRefresh()
|
|||
gGameMouseLastY = mouseY;
|
||||
|
||||
if (!_gmouse_mapper_mode) {
|
||||
int fid = buildFid(6, 0, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
gameMouseSetBouncingCursorFid(fid);
|
||||
}
|
||||
|
||||
|
@ -936,13 +936,13 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
|||
if (gGameMouseMode == GAME_MOUSE_MODE_ARROW) {
|
||||
Object* v5 = gameMouseGetObjectUnderCursor(-1, true, gElevation);
|
||||
if (v5 != NULL) {
|
||||
switch ((v5->fid & 0xF000000) >> 24) {
|
||||
switch (FID_TYPE(v5->fid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
actionPickUp(gDude, v5);
|
||||
break;
|
||||
case OBJ_TYPE_CRITTER:
|
||||
if (v5 == gDude) {
|
||||
if (((gDude->fid & 0xFF0000) >> 16) == ANIM_STAND) {
|
||||
if (FID_ANIM_TYPE(gDude->fid) == ANIM_STAND) {
|
||||
Rect a1;
|
||||
if (objectRotateClockwise(v5, &a1) == 0) {
|
||||
tileWindowRefreshRect(&a1, v5->elevation);
|
||||
|
@ -1053,7 +1053,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
|||
if (v16 != NULL) {
|
||||
int actionMenuItemsCount = 0;
|
||||
int actionMenuItems[6];
|
||||
switch ((v16->fid & 0xF000000) >> 24) {
|
||||
switch (FID_TYPE(v16->fid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
actionMenuItems[actionMenuItemsCount++] = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
actionMenuItems[actionMenuItemsCount++] = GAME_MOUSE_ACTION_MENU_ITEM_LOOK;
|
||||
|
@ -1072,7 +1072,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
|||
actionMenuItems[actionMenuItemsCount++] = GAME_MOUSE_ACTION_MENU_ITEM_TALK;
|
||||
}
|
||||
} else {
|
||||
if (!_critter_flag_check(v16->pid, 32)) {
|
||||
if (!_critter_flag_check(v16->pid, CRITTER_FLAG_0x20)) {
|
||||
actionMenuItems[actionMenuItemsCount++] = GAME_MOUSE_ACTION_MENU_ITEM_USE;
|
||||
}
|
||||
}
|
||||
|
@ -1108,7 +1108,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
|||
|
||||
if (gameMouseRenderActionMenuItems(mouseX, mouseY, actionMenuItems, actionMenuItemsCount, _scr_size.right - _scr_size.left + 1, _scr_size.bottom - _scr_size.top - 99) == 0) {
|
||||
Rect v43;
|
||||
int fid = buildFid(6, 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) {
|
||||
tileWindowRefreshRect(&v43, gElevation);
|
||||
isoDisable();
|
||||
|
@ -1171,7 +1171,7 @@ void _gmouse_handle_event(int mouseX, int mouseY, int mouseState)
|
|||
actionTalk(gDude, v16);
|
||||
break;
|
||||
case GAME_MOUSE_ACTION_MENU_ITEM_USE:
|
||||
switch ((v16->fid & 0xF000000) >> 24) {
|
||||
switch (FID_TYPE(v16->fid)) {
|
||||
case OBJ_TYPE_SCENERY:
|
||||
_action_use_an_object(gDude, v16);
|
||||
break;
|
||||
|
@ -1242,7 +1242,7 @@ int gameMouseSetCursor(int cursor)
|
|||
}
|
||||
|
||||
CacheEntry* mouseCursorFrmHandle;
|
||||
int fid = buildFid(6, gGameMouseCursorFrmIds[cursor], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseCursorFrmIds[cursor], 0, 0, 0);
|
||||
Art* mouseCursorFrm = artLock(fid, &mouseCursorFrmHandle);
|
||||
if (mouseCursorFrm == NULL) {
|
||||
return -1;
|
||||
|
@ -1327,10 +1327,10 @@ void gameMouseSetMode(int mode)
|
|||
return;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, 0, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
gameMouseSetBouncingCursorFid(fid);
|
||||
|
||||
fid = buildFid(6, gGameMouseModeFrmIds[mode], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[mode], 0, 0, 0);
|
||||
|
||||
Rect rect;
|
||||
if (objectSetFid(gGameMouseHexCursor, fid, &rect) == -1) {
|
||||
|
@ -1472,7 +1472,7 @@ int gameMouseSetBouncingCursorFid(int fid)
|
|||
// 0x44CD0C
|
||||
void gameMouseResetBouncingCursorFid()
|
||||
{
|
||||
int fid = buildFid(6, 0, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
gameMouseSetBouncingCursorFid(fid);
|
||||
}
|
||||
|
||||
|
@ -1601,7 +1601,7 @@ Object* gameMouseGetObjectUnderCursor(int objectType, bool a2, int elevation)
|
|||
v4 = ptr->object;
|
||||
if ((ptr->flags & 0x01) != 0) {
|
||||
if ((ptr->flags & 0x04) == 0) {
|
||||
if ((ptr->object->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER || (ptr->object->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_DEAD)) == 0) {
|
||||
if (FID_TYPE(ptr->object->fid) != OBJ_TYPE_CRITTER || (ptr->object->data.critter.combat.results & (DAM_KNOCKED_OUT | DAM_DEAD)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1620,14 +1620,14 @@ Object* gameMouseGetObjectUnderCursor(int objectType, bool a2, int elevation)
|
|||
int gameMouseRenderPrimaryAction(int x, int y, int menuItem, int width, int height)
|
||||
{
|
||||
CacheEntry* menuItemFrmHandle;
|
||||
int menuItemFid = buildFid(6, gGameMouseActionMenuItemFrmIds[menuItem], 0, 0, 0);
|
||||
int menuItemFid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[menuItem], 0, 0, 0);
|
||||
Art* menuItemFrm = artLock(menuItemFid, &menuItemFrmHandle);
|
||||
if (menuItemFrm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
CacheEntry* arrowFrmHandle;
|
||||
int arrowFid = buildFid(6, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
|
||||
int arrowFid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
|
||||
Art* arrowFrm = artLock(arrowFid, &arrowFrmHandle);
|
||||
if (arrowFrm == NULL) {
|
||||
artUnlock(menuItemFrmHandle);
|
||||
|
@ -1666,7 +1666,7 @@ int gameMouseRenderPrimaryAction(int x, int y, int menuItem, int width, int heig
|
|||
} else {
|
||||
artUnlock(arrowFrmHandle);
|
||||
|
||||
arrowFid = buildFid(6, 285, 0, 0, 0);
|
||||
arrowFid = buildFid(OBJ_TYPE_INTERFACE, 285, 0, 0, 0);
|
||||
arrowFrm = artLock(arrowFid, &arrowFrmHandle);
|
||||
arrowFrmData = artGetFrameData(arrowFrm, 0, 0);
|
||||
arrowFrmDest += menuItemFrmWidth;
|
||||
|
@ -1725,7 +1725,7 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
|
|||
frmId -= 1;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, frmId, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
|
||||
menuItemFrms[index] = artLock(fid, &(menuItemFrmHandles[index]));
|
||||
if (menuItemFrms[index] == NULL) {
|
||||
|
@ -1736,7 +1736,7 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
|
|||
}
|
||||
}
|
||||
|
||||
int fid = buildFid(6, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_ARROW], 0, 0, 0);
|
||||
CacheEntry* arrowFrmHandle;
|
||||
Art* arrowFrm = artLock(fid, &arrowFrmHandle);
|
||||
if (arrowFrm == NULL) {
|
||||
|
@ -1772,7 +1772,7 @@ int gameMouseRenderActionMenuItems(int x, int y, const int* menuItems, int menuI
|
|||
}
|
||||
} else {
|
||||
// Mirrored arrow (from left to right).
|
||||
fid = buildFid(6, 285, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 285, 0, 0, 0);
|
||||
arrowFrm = artLock(fid, &arrowFrmHandle);
|
||||
arrowData = artGetFrameData(arrowFrm, 0, 0);
|
||||
gGameMouseActionMenuFrm->xOffsets[0] = -gGameMouseActionMenuFrm->xOffsets[0];
|
||||
|
@ -1820,7 +1820,7 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex)
|
|||
}
|
||||
|
||||
CacheEntry* handle;
|
||||
int fid = buildFid(6, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[gGameMouseActionMenuHighlightedItemIndex]], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[gGameMouseActionMenuHighlightedItemIndex]], 0, 0, 0);
|
||||
Art* art = artLock(fid, &handle);
|
||||
if (art == NULL) {
|
||||
return -1;
|
||||
|
@ -1832,7 +1832,7 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex)
|
|||
blitBufferToBuffer(data, width, height, width, _gmouse_3d_menu_actions_start + gGameMouseActionMenuFrmWidth * height * gGameMouseActionMenuHighlightedItemIndex, gGameMouseActionMenuFrmWidth);
|
||||
artUnlock(handle);
|
||||
|
||||
fid = buildFid(6, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[menuItemIndex]] - 1, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseActionMenuItemFrmIds[gGameMouseActionMenuItems[menuItemIndex]] - 1, 0, 0, 0);
|
||||
art = artLock(fid, &handle);
|
||||
if (art == NULL) {
|
||||
return -1;
|
||||
|
@ -1851,7 +1851,7 @@ int gameMouseHighlightActionMenuItemAtIndex(int menuItemIndex)
|
|||
int gameMouseRenderAccuracy(const char* string, int color)
|
||||
{
|
||||
CacheEntry* crosshairFrmHandle;
|
||||
int fid = buildFid(6, gGameMouseModeFrmIds[GAME_MOUSE_MODE_CROSSHAIR], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[GAME_MOUSE_MODE_CROSSHAIR], 0, 0, 0);
|
||||
Art* crosshairFrm = artLock(fid, &crosshairFrmHandle);
|
||||
if (crosshairFrm == NULL) {
|
||||
return -1;
|
||||
|
@ -1910,7 +1910,7 @@ int gameMouseRenderActionPoints(const char* string, int color)
|
|||
|
||||
fontSetCurrent(oldFont);
|
||||
|
||||
int fid = buildFid(6, 1, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 1, 0, 0, 0);
|
||||
gameMouseSetBouncingCursorFid(fid);
|
||||
|
||||
return 0;
|
||||
|
@ -1934,12 +1934,12 @@ int gameMouseObjectsInit()
|
|||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 0, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
if (objectCreateWithFidPid(&gGameMouseBouncingCursor, fid, -1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 1, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 1, 0, 0, 0);
|
||||
if (objectCreateWithFidPid(&gGameMouseHexCursor, fid, -1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -2031,35 +2031,35 @@ int gameMouseActionMenuInit()
|
|||
int fid;
|
||||
|
||||
// actmenu.frm - action menu
|
||||
fid = buildFid(6, 283, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 283, 0, 0, 0);
|
||||
gGameMouseActionMenuFrm = artLock(fid, &gGameMouseActionMenuFrmHandle);
|
||||
if (gGameMouseActionMenuFrm == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// actpick.frm - action pick
|
||||
fid = buildFid(6, 282, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 282, 0, 0, 0);
|
||||
gGameMouseActionPickFrm = artLock(fid, &gGameMouseActionPickFrmHandle);
|
||||
if (gGameMouseActionPickFrm == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// acttohit.frm - action to hit
|
||||
fid = buildFid(6, 284, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 284, 0, 0, 0);
|
||||
gGameMouseActionHitFrm = artLock(fid, &gGameMouseActionHitFrmHandle);
|
||||
if (gGameMouseActionHitFrm == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// blank.frm - used be mset000.frm for top of bouncing mouse cursor
|
||||
fid = buildFid(6, 0, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 0, 0, 0, 0);
|
||||
gGameMouseBouncingCursorFrm = artLock(fid, &gGameMouseBouncingCursorFrmHandle);
|
||||
if (gGameMouseBouncingCursorFrm == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// msef000.frm - hex mouse cursor
|
||||
fid = buildFid(6, 1, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 1, 0, 0, 0);
|
||||
gGameMouseHexCursorFrm = artLock(fid, &gGameMouseHexCursorFrmHandle);
|
||||
if (gGameMouseHexCursorFrm == NULL) {
|
||||
goto err;
|
||||
|
@ -2145,7 +2145,7 @@ void gameMouseActionMenuFree()
|
|||
// 0x44DF40
|
||||
int gameMouseUpdateHexCursorFid(Rect* rect)
|
||||
{
|
||||
int fid = buildFid(6, gGameMouseModeFrmIds[gGameMouseMode], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gGameMouseModeFrmIds[gGameMouseMode], 0, 0, 0);
|
||||
if (gGameMouseHexCursor->fid == fid) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -2210,7 +2210,7 @@ int _gmouse_3d_move_to(int x, int y, int elevation, Rect* a4)
|
|||
int y1 = 0;
|
||||
|
||||
int fid = gGameMouseBouncingCursor->fid;
|
||||
if ((fid & 0xF000000) >> 24 == OBJ_TYPE_TILE) {
|
||||
if (FID_TYPE(fid) == OBJ_TYPE_TILE) {
|
||||
int squareTile = squareTileFromScreenXY(x, y, elevation);
|
||||
if (squareTile == -1) {
|
||||
tile = HEX_GRID_WIDTH * (2 * (squareTile / SQUARE_GRID_WIDTH) + 1) + 2 * (squareTile % SQUARE_GRID_WIDTH) + 1;
|
||||
|
@ -2398,7 +2398,7 @@ int objectIsDoor(Object* object)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_SCENERY) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_SCENERY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ int gameMoviePlay(int movie, int flags)
|
|||
int gameMovieWindowY = (screenGetHeight() - GAME_MOVIE_WINDOW_HEIGHT) / 2;
|
||||
int win = windowCreate(gameMovieWindowX,
|
||||
gameMovieWindowY,
|
||||
GAME_MOVIE_WINDOW_WIDTH,
|
||||
GAME_MOVIE_WINDOW_WIDTH,
|
||||
GAME_MOVIE_WINDOW_HEIGHT,
|
||||
0,
|
||||
WINDOW_FLAG_0x10);
|
||||
|
|
|
@ -1118,7 +1118,7 @@ Sound* soundEffectLoad(const char* name, Object* object)
|
|||
}
|
||||
|
||||
if (object != NULL) {
|
||||
if ((object->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER && (name[0] == 'H' || name[0] == 'N')) {
|
||||
if (FID_TYPE(object->fid) == OBJ_TYPE_CRITTER && (name[0] == 'H' || name[0] == 'N')) {
|
||||
char v9 = name[1];
|
||||
if (v9 == 'A' || v9 == 'F' || v9 == 'M') {
|
||||
if (v9 == 'A') {
|
||||
|
@ -1230,7 +1230,7 @@ void soundEffectDelete(Sound* sound)
|
|||
}
|
||||
|
||||
// 0x4514F0
|
||||
int _gsnd_anim_sound(Sound* sound)
|
||||
int _gsnd_anim_sound(Sound* sound, void* a2)
|
||||
{
|
||||
if (!gGameSoundInitialized) {
|
||||
return 0;
|
||||
|
@ -1287,7 +1287,7 @@ int _gsound_compute_relative_volume(Object* obj)
|
|||
v3 = 0x7FFF;
|
||||
|
||||
if (obj) {
|
||||
type = (obj->fid & 0xF000000) >> 24;
|
||||
type = FID_TYPE(obj->fid);
|
||||
if (type == 0 || type == 1 || type == 2) {
|
||||
v7 = objectGetOwner(obj);
|
||||
if (!v7) {
|
||||
|
@ -1325,7 +1325,7 @@ char* sfxBuildCharName(Object* a1, int anim, int extra)
|
|||
char v8;
|
||||
char v9;
|
||||
|
||||
if (artCopyFileName((a1->fid & 0xF000000) >> 24, a1->fid & 0xFFF, v7) == -1) {
|
||||
if (artCopyFileName(FID_TYPE(a1->fid), a1->fid & 0xFFF, v7) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1399,12 +1399,10 @@ char* sfxBuildWeaponName(int effectType, Object* weapon, int hitMode, Object* ta
|
|||
v6 = 1;
|
||||
}
|
||||
|
||||
int damageType = weaponGetDamageType(NULL, weapon);
|
||||
// TODO: Check damageType conditions.
|
||||
if (effectTypeCode != 'H' || target == NULL || damageType == DAMAGE_TYPE_EXPLOSION || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP) {
|
||||
if (effectTypeCode != 'H' || target == NULL || weaponIsGrenade(weapon)) {
|
||||
materialCode = 'X';
|
||||
} else {
|
||||
const int type = (target->fid & 0xF000000) >> 24;
|
||||
const int type = FID_TYPE(target->fid);
|
||||
int material;
|
||||
switch (type) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
|
@ -1466,7 +1464,7 @@ char* sfxBuildSceneryName(int actionType, int action, const char* name)
|
|||
// 0x4518D
|
||||
char* sfxBuildOpenName(Object* object, int action)
|
||||
{
|
||||
if ((object->fid & 0xF000000) >> 24 == OBJ_TYPE_SCENERY) {
|
||||
if (FID_TYPE(object->fid) == OBJ_TYPE_SCENERY) {
|
||||
char scenerySoundId;
|
||||
Proto* proto;
|
||||
if (protoGetProto(object->pid, &proto) != -1) {
|
||||
|
|
|
@ -63,7 +63,7 @@ int _gsound_play_sfx_file_volume(const char* a1, int a2);
|
|||
Sound* soundEffectLoad(const char* name, Object* a2);
|
||||
Sound* soundEffectLoadWithVolume(const char* a1, Object* a2, int a3);
|
||||
void soundEffectDelete(Sound* a1);
|
||||
int _gsnd_anim_sound(Sound* a1);
|
||||
int _gsnd_anim_sound(Sound* sound, void* a2);
|
||||
int soundEffectPlay(Sound* a1);
|
||||
int _gsound_compute_relative_volume(Object* obj);
|
||||
char* sfxBuildCharName(Object* a1, int anim, int extra);
|
||||
|
|
106
src/interface.cc
106
src/interface.cc
|
@ -438,7 +438,7 @@ int interfaceInit()
|
|||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 16, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 16, 0, 0, 0);
|
||||
backgroundFrmData = artLockFrameData(fid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -447,13 +447,13 @@ int interfaceInit()
|
|||
blitBufferToBuffer(backgroundFrmData, INTERFACE_BAR_WIDTH, INTERFACE_BAR_HEIGHT - 1, INTERFACE_BAR_WIDTH, gInterfaceWindowBuffer, 640);
|
||||
artUnlock(backgroundFrmHandle);
|
||||
|
||||
fid = buildFid(6, 47, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 47, 0, 0, 0);
|
||||
gInventoryButtonUpFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonUpFrmHandle);
|
||||
if (gInventoryButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 46, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 46, 0, 0, 0);
|
||||
gInventoryButtonDownFrmData = artLockFrameData(fid, 0, 0, &gInventoryButtonDownFrmHandle);
|
||||
if (gInventoryButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -466,13 +466,13 @@ int interfaceInit()
|
|||
|
||||
buttonSetCallbacks(gInventoryButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 18, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 18, 0, 0, 0);
|
||||
gOptionsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonUpFrmHandle);
|
||||
if (gOptionsButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 17, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 17, 0, 0, 0);
|
||||
gOptionsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gOptionsButtonDownFrmHandle);
|
||||
if (gOptionsButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -485,19 +485,19 @@ int interfaceInit()
|
|||
|
||||
buttonSetCallbacks(gOptionsButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 6, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
|
||||
gSkilldexButtonUpFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonUpFrmHandle);
|
||||
if (gSkilldexButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 7, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0);
|
||||
gSkilldexButtonDownFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonDownFrmHandle);
|
||||
if (gSkilldexButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 6, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
|
||||
gSkilldexButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gSkilldexButtonMaskFrmHandle);
|
||||
if (gSkilldexButtonMaskFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -511,19 +511,19 @@ int interfaceInit()
|
|||
buttonSetMask(gSkilldexButton, gSkilldexButtonMaskFrmData);
|
||||
buttonSetCallbacks(gSkilldexButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 13, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0);
|
||||
gMapButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMapButtonUpFrmHandle);
|
||||
if (gMapButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 10, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 10, 0, 0, 0);
|
||||
gMapButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMapButtonDownFrmHandle);
|
||||
if (gMapButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 13, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 13, 0, 0, 0);
|
||||
gMapButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gMapButtonMaskFrmHandle);
|
||||
if (gMapButtonMaskFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -537,13 +537,13 @@ int interfaceInit()
|
|||
buttonSetMask(gMapButton, gMapButtonMaskFrmData);
|
||||
buttonSetCallbacks(gMapButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 59, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 59, 0, 0, 0);
|
||||
gPipboyButtonUpFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonUpFrmHandle);
|
||||
if (gPipboyButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 58, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 58, 0, 0, 0);
|
||||
gPipboyButtonDownFrmData = artLockFrameData(fid, 0, 0, &gPipboyButtonDownFrmHandle);
|
||||
if (gPipboyButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -557,13 +557,13 @@ int interfaceInit()
|
|||
buttonSetMask(gPipboyButton, gMapButtonMaskFrmData);
|
||||
buttonSetCallbacks(gPipboyButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 57, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 57, 0, 0, 0);
|
||||
gCharacterButtonUpFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonUpFrmHandle);
|
||||
if (gCharacterButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 56, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 56, 0, 0, 0);
|
||||
gCharacterButtonDownFrmData = artLockFrameData(fid, 0, 0, &gCharacterButtonDownFrmHandle);
|
||||
if (gCharacterButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -577,19 +577,19 @@ int interfaceInit()
|
|||
buttonSetMask(gCharacterButton, gMapButtonMaskFrmData);
|
||||
buttonSetCallbacks(gCharacterButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 32, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 32, 0, 0, 0);
|
||||
gSingleAttackButtonUpData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonUpHandle);
|
||||
if (gSingleAttackButtonUpData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 31, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 31, 0, 0, 0);
|
||||
gSingleAttackButtonDownData = artLockFrameData(fid, 0, 0, &gSingleAttackButtonDownHandle);
|
||||
if (gSingleAttackButtonDownData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 73, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 73, 0, 0, 0);
|
||||
_itemButtonDisabled = artLockFrameData(fid, 0, 0, &_itemButtonDisabledKey);
|
||||
if (_itemButtonDisabled == NULL) {
|
||||
goto err;
|
||||
|
@ -606,19 +606,19 @@ int interfaceInit()
|
|||
buttonSetRightMouseCallbacks(gSingleAttackButton, -1, KEY_LOWERCASE_N, NULL, NULL);
|
||||
buttonSetCallbacks(gSingleAttackButton, _gsound_lrg_butt_press, _gsound_lrg_butt_release);
|
||||
|
||||
fid = buildFid(6, 6, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
|
||||
gChangeHandsButtonUpFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonUpFrmHandle);
|
||||
if (gChangeHandsButtonUpFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 7, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 7, 0, 0, 0);
|
||||
gChangeHandsButtonDownFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonDownFrmHandle);
|
||||
if (gChangeHandsButtonDownFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 6, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 6, 0, 0, 0);
|
||||
gChangeHandsButtonMaskFrmData = artLockFrameData(fid, 0, 0, &gChangeHandsButtonMaskFrmHandle);
|
||||
if (gChangeHandsButtonMaskFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -633,25 +633,25 @@ int interfaceInit()
|
|||
buttonSetMask(gChangeHandsButton, gChangeHandsButtonMaskFrmData);
|
||||
buttonSetCallbacks(gChangeHandsButton, _gsound_med_butt_press, _gsound_med_butt_release);
|
||||
|
||||
fid = buildFid(6, 82, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0);
|
||||
gNumbersFrmData = artLockFrameData(fid, 0, 0, &gNumbersFrmHandle);
|
||||
if (gNumbersFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 83, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 83, 0, 0, 0);
|
||||
gGreenLightFrmData = artLockFrameData(fid, 0, 0, &gGreenLightFrmHandle);
|
||||
if (gGreenLightFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 84, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 84, 0, 0, 0);
|
||||
gYellowLightFrmData = artLockFrameData(fid, 0, 0, &gYellowLightFrmHandle);
|
||||
if (gYellowLightFrmData == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 85, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 85, 0, 0, 0);
|
||||
gRedLightFrmData = artLockFrameData(fid, 0, 0, &gRedLightFrmHandle);
|
||||
if (gRedLightFrmData == NULL) {
|
||||
goto err;
|
||||
|
@ -1592,7 +1592,7 @@ void interfaceBarEndButtonsShow(bool animated)
|
|||
return;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, 104, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 104, 0, 0, 0);
|
||||
CacheEntry* handle;
|
||||
Art* art = artLock(fid, &handle);
|
||||
if (art == NULL) {
|
||||
|
@ -1644,7 +1644,7 @@ void interfaceBarEndButtonsHide(bool animated)
|
|||
return;
|
||||
}
|
||||
|
||||
int fid = buildFid(6, 104, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 104, 0, 0, 0);
|
||||
CacheEntry* handle;
|
||||
Art* art = artLock(fid, &handle);
|
||||
if (art == NULL) {
|
||||
|
@ -1693,7 +1693,7 @@ void interfaceBarEndButtonsRenderGreenLights()
|
|||
buttonEnable(gEndCombatButton);
|
||||
|
||||
// endltgrn.frm - green lights around end turn/combat window
|
||||
int lightsFid = buildFid(6, 109, 0, 0, 0);
|
||||
int lightsFid = buildFid(OBJ_TYPE_INTERFACE, 109, 0, 0, 0);
|
||||
CacheEntry* lightsFrmHandle;
|
||||
unsigned char* lightsFrmData = artLockFrameData(lightsFid, 0, 0, &lightsFrmHandle);
|
||||
if (lightsFrmData == NULL) {
|
||||
|
@ -1717,7 +1717,7 @@ void interfaceBarEndButtonsRenderRedLights()
|
|||
|
||||
CacheEntry* lightsFrmHandle;
|
||||
// endltred.frm - red lights around end turn/combat window
|
||||
int lightsFid = buildFid(6, 110, 0, 0, 0);
|
||||
int lightsFid = buildFid(OBJ_TYPE_INTERFACE, 110, 0, 0, 0);
|
||||
unsigned char* lightsFrmData = artLockFrameData(lightsFid, 0, 0, &lightsFrmHandle);
|
||||
if (lightsFrmData == NULL) {
|
||||
return;
|
||||
|
@ -1751,10 +1751,10 @@ static int interfaceBarRefreshMainAction()
|
|||
int fid;
|
||||
if (_proto_action_can_use_on(itemState->item->pid)) {
|
||||
// USE ON
|
||||
fid = buildFid(6, 294, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 294, 0, 0, 0);
|
||||
} else if (_obj_action_can_use(itemState->item)) {
|
||||
// USE
|
||||
fid = buildFid(6, 292, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 292, 0, 0, 0);
|
||||
} else {
|
||||
fid = -1;
|
||||
}
|
||||
|
@ -1782,20 +1782,20 @@ static int interfaceBarRefreshMainAction()
|
|||
// jump table.
|
||||
switch (itemState->action) {
|
||||
case INTERFACE_ITEM_ACTION_PRIMARY_AIMING:
|
||||
bullseyeFid = buildFid(6, 288, 0, 0, 0);
|
||||
bullseyeFid = buildFid(OBJ_TYPE_INTERFACE, 288, 0, 0, 0);
|
||||
// FALLTHROUGH
|
||||
case INTERFACE_ITEM_ACTION_PRIMARY:
|
||||
hitMode = itemState->primaryHitMode;
|
||||
break;
|
||||
case INTERFACE_ITEM_ACTION_SECONDARY_AIMING:
|
||||
bullseyeFid = buildFid(6, 288, 0, 0, 0);
|
||||
bullseyeFid = buildFid(OBJ_TYPE_INTERFACE, 288, 0, 0, 0);
|
||||
// FALLTHROUGH
|
||||
case INTERFACE_ITEM_ACTION_SECONDARY:
|
||||
hitMode = itemState->secondaryHitMode;
|
||||
break;
|
||||
case INTERFACE_ITEM_ACTION_RELOAD:
|
||||
actionPoints = _item_mp_cost(gDude, gInterfaceCurrentHand == HAND_LEFT ? HIT_MODE_LEFT_WEAPON_RELOAD : HIT_MODE_RIGHT_WEAPON_RELOAD, false);
|
||||
primaryFid = buildFid(6, 291, 0, 0, 0);
|
||||
primaryFid = buildFid(OBJ_TYPE_INTERFACE, 291, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1893,7 +1893,7 @@ static int interfaceBarRefreshMainAction()
|
|||
break;
|
||||
}
|
||||
|
||||
primaryFid = buildFid(6, id, 0, 0, 0);
|
||||
primaryFid = buildFid(OBJ_TYPE_INTERFACE, id, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (primaryFid != -1) {
|
||||
|
@ -1913,7 +1913,7 @@ static int interfaceBarRefreshMainAction()
|
|||
|
||||
if (actionPoints >= 0 && actionPoints < 10) {
|
||||
// movement point text
|
||||
int fid = buildFid(6, 289, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 289, 0, 0, 0);
|
||||
|
||||
CacheEntry* handle;
|
||||
Art* art = artLock(fid, &handle);
|
||||
|
@ -1936,7 +1936,7 @@ static int interfaceBarRefreshMainAction()
|
|||
int offset = width + 7;
|
||||
|
||||
// movement point numbers - ten numbers 0 to 9, each 10 pixels wide.
|
||||
fid = buildFid(6, 290, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 290, 0, 0, 0);
|
||||
art = artLock(fid, &handle);
|
||||
if (art != NULL) {
|
||||
width = artGetWidth(art, 0, 0);
|
||||
|
@ -2018,30 +2018,32 @@ static void interfaceBarSwapHandsAnimatePutAwayTakeOutSequence(int previousWeapo
|
|||
gInterfaceBarSwapHandsInProgress = true;
|
||||
|
||||
reg_anim_clear(gDude);
|
||||
reg_anim_begin(2);
|
||||
reg_anim_update_light(gDude, 4, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
animationRegisterSetLightDistance(gDude, 4, 0);
|
||||
|
||||
if (previousWeaponAnimationCode != 0) {
|
||||
const char* sfx = sfxBuildCharName(gDude, ANIM_PUT_AWAY, CHARACTER_SOUND_EFFECT_UNUSED);
|
||||
reg_anim_play_sfx(gDude, sfx, 0);
|
||||
reg_anim_animate(gDude, ANIM_PUT_AWAY, 0);
|
||||
animationRegisterPlaySoundEffect(gDude, sfx, 0);
|
||||
animationRegisterAnimate(gDude, ANIM_PUT_AWAY, 0);
|
||||
}
|
||||
|
||||
reg_anim_11_1(NULL, NULL, _intface_redraw_items_callback, -1);
|
||||
// TODO: Get rid of cast.
|
||||
animationRegisterCallbackForced(NULL, NULL, (AnimationCallback*)_intface_redraw_items_callback, -1);
|
||||
|
||||
Object* item = gInterfaceItemStates[gInterfaceCurrentHand].item;
|
||||
if (item != NULL && item->lightDistance > 4) {
|
||||
reg_anim_update_light(gDude, item->lightDistance, 0);
|
||||
animationRegisterSetLightDistance(gDude, item->lightDistance, 0);
|
||||
}
|
||||
|
||||
if (weaponAnimationCode != 0) {
|
||||
reg_anim_18(gDude, weaponAnimationCode, -1);
|
||||
animationRegisterTakeOutWeapon(gDude, weaponAnimationCode, -1);
|
||||
} else {
|
||||
int fid = buildFid(1, gDude->fid & 0xFFF, ANIM_STAND, 0, gDude->rotation + 1);
|
||||
reg_anim_17(gDude, fid, -1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, gDude->fid & 0xFFF, ANIM_STAND, 0, gDude->rotation + 1);
|
||||
animationRegisterSetFid(gDude, fid, -1);
|
||||
}
|
||||
|
||||
reg_anim_11_1(NULL, NULL, _intface_change_fid_callback, -1);
|
||||
// TODO: Get rid of cast.
|
||||
animationRegisterCallbackForced(NULL, NULL, (AnimationCallback*)_intface_change_fid_callback, -1);
|
||||
|
||||
if (reg_anim_end() == -1) {
|
||||
return;
|
||||
|
@ -2084,13 +2086,13 @@ static int endTurnButtonInit()
|
|||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 105, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 105, 0, 0, 0);
|
||||
gEndTurnButtonUpFrmData = artLockFrameData(fid, 0, 0, &gEndTurnButtonUpFrmHandle);
|
||||
if (gEndTurnButtonUpFrmData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 106, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 106, 0, 0, 0);
|
||||
gEndTurnButtonDownFrmData = artLockFrameData(fid, 0, 0, &gEndTurnButtonDownFrmHandle);
|
||||
if (gEndTurnButtonDownFrmData == NULL) {
|
||||
return -1;
|
||||
|
@ -2147,13 +2149,13 @@ static int endCombatButtonInit()
|
|||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 107, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 107, 0, 0, 0);
|
||||
gEndCombatButtonUpFrmData = artLockFrameData(fid, 0, 0, &gEndCombatButtonUpFrmHandle);
|
||||
if (gEndCombatButtonUpFrmData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 108, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 108, 0, 0, 0);
|
||||
gEndCombatButtonDownFrmData = artLockFrameData(fid, 0, 0, &gEndCombatButtonDownFrmHandle);
|
||||
if (gEndCombatButtonDownFrmData == NULL) {
|
||||
return -1;
|
||||
|
@ -2412,7 +2414,7 @@ static int indicatorBarInit()
|
|||
CacheEntry* indicatorBoxFrmHandle;
|
||||
int width;
|
||||
int height;
|
||||
int indicatorBoxFid = buildFid(6, 126, 0, 0, 0);
|
||||
int indicatorBoxFid = buildFid(OBJ_TYPE_INTERFACE, 126, 0, 0, 0);
|
||||
unsigned char* indicatorBoxFrmData = artLockFrameDataReturningSize(indicatorBoxFid, &indicatorBoxFrmHandle, &width, &height);
|
||||
if (indicatorBoxFrmData == NULL) {
|
||||
debugPrint("\nINTRFACE: Error initializing indicator box graphics! **\n");
|
||||
|
|
|
@ -398,7 +398,7 @@ static void _detachProgram(Program* program)
|
|||
static void _purgeProgram(Program* program)
|
||||
{
|
||||
if (!program->exited) {
|
||||
_removeProgramReferences_(program);
|
||||
intLibRemoveProgramReferences(program);
|
||||
program->exited = true;
|
||||
}
|
||||
}
|
||||
|
@ -781,7 +781,7 @@ static void opCancelAll(Program* program)
|
|||
static void opIf(Program* program)
|
||||
{
|
||||
ProgramValue value = programStackPopValue(program);
|
||||
|
||||
|
||||
if (!value.isEmpty()) {
|
||||
programStackPopValue(program);
|
||||
} else {
|
||||
|
@ -1963,7 +1963,7 @@ static void opCall(Program* program)
|
|||
// 0x46B590
|
||||
static void op801F(Program* program)
|
||||
{
|
||||
program->field_84 = programStackPopInteger(program);
|
||||
program->windowId = programStackPopInteger(program);
|
||||
program->field_7C = (int (*)(Program*))programStackPopPointer(program);
|
||||
program->flags = programStackPopInteger(program) & 0xFFFF;
|
||||
}
|
||||
|
@ -2216,7 +2216,7 @@ static void opExportProcedure(Program* program)
|
|||
|
||||
unsigned char* proc_ptr = program->procedures + 4 + sizeof(Procedure) * procedureIndex;
|
||||
|
||||
char *procedureName = programGetIdentifier(program, stackReadInt32(proc_ptr, 0));
|
||||
char* procedureName = programGetIdentifier(program, stackReadInt32(proc_ptr, 0));
|
||||
int procedureAddress = stackReadInt32(proc_ptr, 16);
|
||||
|
||||
if (externalProcedureCreate(program, procedureName, procedureAddress, argumentCount) != 0) {
|
||||
|
@ -2253,7 +2253,7 @@ static void opExit(Program* program)
|
|||
}
|
||||
|
||||
if (!program->exited) {
|
||||
_removeProgramReferences_(program);
|
||||
intLibRemoveProgramReferences(program);
|
||||
program->exited = true;
|
||||
}
|
||||
}
|
||||
|
@ -2297,7 +2297,7 @@ static void opCallStart(Program* program)
|
|||
_interpret(program->child, 24);
|
||||
|
||||
program->child->parent = program;
|
||||
program->child->field_84 = program->field_84;
|
||||
program->child->windowId = program->windowId;
|
||||
}
|
||||
|
||||
// spawn
|
||||
|
@ -2323,7 +2323,7 @@ static void opSpawn(Program* program)
|
|||
_interpret(program->child, 24);
|
||||
|
||||
program->child->parent = program;
|
||||
program->child->field_84 = program->field_84;
|
||||
program->child->windowId = program->windowId;
|
||||
|
||||
if ((program->flags & PROGRAM_FLAG_CRITICAL_SECTION) != 0) {
|
||||
program->child->flags |= PROGRAM_FLAG_CRITICAL_SECTION;
|
||||
|
@ -2349,7 +2349,7 @@ static Program* forkProgram(Program* program)
|
|||
|
||||
_interpret(forked, 24);
|
||||
|
||||
forked->field_84 = program->field_84;
|
||||
forked->windowId = program->windowId;
|
||||
|
||||
return forked;
|
||||
}
|
||||
|
@ -2516,7 +2516,7 @@ void interpreterRegisterOpcodeHandlers()
|
|||
interpreterRegisterOpcode(OPCODE_START_CRITICAL, opEnterCriticalSection);
|
||||
interpreterRegisterOpcode(OPCODE_END_CRITICAL, opLeaveCriticalSection);
|
||||
|
||||
_initIntlib();
|
||||
intLibInit();
|
||||
_initExport();
|
||||
}
|
||||
|
||||
|
@ -2524,7 +2524,7 @@ void interpreterRegisterOpcodeHandlers()
|
|||
void _interpretClose()
|
||||
{
|
||||
externalVariablesClear();
|
||||
_intlibClose();
|
||||
intLibExit();
|
||||
}
|
||||
|
||||
// 0x46CCA4
|
||||
|
@ -2641,7 +2641,7 @@ static void _setupCallWithReturnVal(Program* program, int address, int returnAdd
|
|||
|
||||
programStackPushPointer(program, (void*)program->field_7C);
|
||||
|
||||
programStackPushInteger(program, program->field_84);
|
||||
programStackPushInteger(program, program->windowId);
|
||||
|
||||
program->flags &= ~0xFFFF;
|
||||
program->instructionPointer = address;
|
||||
|
@ -2664,11 +2664,11 @@ static void _setupExternalCallWithReturnVal(Program* program1, Program* program2
|
|||
|
||||
programStackPushPointer(program2, (void*)program2->field_7C);
|
||||
|
||||
programStackPushInteger(program2, program2->field_84);
|
||||
programStackPushInteger(program2, program2->windowId);
|
||||
|
||||
program2->flags &= ~0xFFFF;
|
||||
program2->instructionPointer = address;
|
||||
program2->field_84 = program1->field_84;
|
||||
program2->windowId = program1->windowId;
|
||||
|
||||
program1->flags |= PROGRAM_FLAG_0x20;
|
||||
}
|
||||
|
@ -2683,9 +2683,9 @@ void _executeProc(Program* program, int procedure_index)
|
|||
unsigned char* procedure_ptr;
|
||||
int flags;
|
||||
char err[256];
|
||||
Program* v12;
|
||||
Program* context;
|
||||
|
||||
procedure_ptr = program->procedures + 4 + 24 * procedure_index;
|
||||
procedure_ptr = program->procedures + 4 + sizeof(Procedure) * procedure_index;
|
||||
flags = stackReadInt32(procedure_ptr, 4);
|
||||
if (!(flags & PROCEDURE_FLAG_IMPORTED)) {
|
||||
address = stackReadInt32(procedure_ptr, 16);
|
||||
|
@ -2699,7 +2699,7 @@ void _executeProc(Program* program, int procedure_index)
|
|||
}
|
||||
|
||||
program->flags |= PROGRAM_FLAG_CRITICAL_SECTION;
|
||||
v12 = program;
|
||||
context = program;
|
||||
} else {
|
||||
identifier = programGetIdentifier(program, stackReadInt32(procedure_ptr, 0));
|
||||
external_program = externalProcedureGetProgram(identifier, &address, &arguments_count);
|
||||
|
@ -2721,7 +2721,7 @@ void _executeProc(Program* program, int procedure_index)
|
|||
|
||||
programStackPushInteger(external_program, 0);
|
||||
|
||||
procedure_ptr = external_program->procedures + 4 + 24 * procedure_index;
|
||||
procedure_ptr = external_program->procedures + 4 + sizeof(Procedure) * procedure_index;
|
||||
flags = stackReadInt32(procedure_ptr, 4);
|
||||
|
||||
if (!(flags & PROCEDURE_FLAG_CRITICAL)) {
|
||||
|
@ -2729,10 +2729,10 @@ void _executeProc(Program* program, int procedure_index)
|
|||
}
|
||||
|
||||
external_program->flags |= PROGRAM_FLAG_CRITICAL_SECTION;
|
||||
v12 = external_program;
|
||||
context = external_program;
|
||||
}
|
||||
|
||||
_interpret(v12, 0);
|
||||
_interpret(context, 0);
|
||||
}
|
||||
|
||||
// Returns index of the procedure with specified name or -1 if no such
|
||||
|
@ -2769,10 +2769,10 @@ void _executeProcedure(Program* program, int procedure_index)
|
|||
jmp_buf jmp_buf;
|
||||
Program* v13;
|
||||
|
||||
procedure_ptr = program->procedures + 4 + 24 * procedure_index;
|
||||
procedure_ptr = program->procedures + 4 + sizeof(Procedure) * procedure_index;
|
||||
flags = stackReadInt32(procedure_ptr, 4);
|
||||
|
||||
if (flags & 0x04) {
|
||||
if (flags & PROCEDURE_FLAG_IMPORTED) {
|
||||
identifier = programGetIdentifier(program, stackReadInt32(procedure_ptr, 0));
|
||||
external_program = externalProcedureGetProgram(identifier, &address, &arguments_count);
|
||||
if (external_program == NULL) {
|
||||
|
@ -2875,7 +2875,7 @@ void _updatePrograms()
|
|||
curr = next;
|
||||
}
|
||||
_doEvents();
|
||||
_updateIntLib();
|
||||
intLibUpdate();
|
||||
}
|
||||
|
||||
// 0x46E238
|
||||
|
|
|
@ -167,7 +167,7 @@ typedef struct Program {
|
|||
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
|
||||
int flags; // flags
|
||||
int field_84;
|
||||
int windowId;
|
||||
bool exited;
|
||||
ProgramStack* stackValues;
|
||||
ProgramStack* returnStackValues;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "game_sound.h"
|
||||
#include "geometry.h"
|
||||
#include "interface.h"
|
||||
#include "interpreter.h"
|
||||
#include "item.h"
|
||||
#include "light.h"
|
||||
#include "loadsave.h"
|
||||
|
@ -300,8 +299,8 @@ static void opObjectClose(Program* program);
|
|||
static void opGameUiDisable(Program* program);
|
||||
static void opGameUiEnable(Program* program);
|
||||
static void opGameUiIsDisabled(Program* program);
|
||||
static void opFadeOut(Program* program);
|
||||
static void opFadeIn(Program* program);
|
||||
static void opGameFadeOut(Program* program);
|
||||
static void opGameFadeIn(Program* program);
|
||||
static void opItemCapsTotal(Program* program);
|
||||
static void opItemCapsAdjust(Program* program);
|
||||
static void _op_anim_action_frame(Program* program);
|
||||
|
@ -496,11 +495,11 @@ static int _correctFidForRemovedItem(Object* a1, Object* a2, int flags)
|
|||
}
|
||||
|
||||
if (v8 == 0) {
|
||||
newFid = buildFid((fid & 0xF000000) >> 24, fid & 0xFFF, (fid & 0xFF0000) >> 16, 0, (fid & 0x70000000) >> 28);
|
||||
newFid = buildFid(FID_TYPE(fid), fid & 0xFFF, FID_ANIM_TYPE(fid), 0, (fid & 0x70000000) >> 28);
|
||||
}
|
||||
} else {
|
||||
if (a1 == gDude) {
|
||||
newFid = buildFid((fid & 0xF000000) >> 24, _art_vault_guy_num, (fid & 0xFF0000) >> 16, v8, (fid & 0x70000000) >> 28);
|
||||
newFid = buildFid(FID_TYPE(fid), _art_vault_guy_num, FID_ANIM_TYPE(fid), v8, (fid & 0x70000000) >> 28);
|
||||
}
|
||||
|
||||
_adjust_ac(a1, a2, NULL);
|
||||
|
@ -557,7 +556,7 @@ static void opSetMapStart(Program* program)
|
|||
int elevation = programStackPopInteger(program);
|
||||
int y = programStackPopInteger(program);
|
||||
int x = programStackPopInteger(program);
|
||||
|
||||
|
||||
if (mapSetElevation(elevation) != 0) {
|
||||
scriptError("\nScript Error: %s: op_set_map_start: map_set_elevation failed", program->name);
|
||||
return;
|
||||
|
@ -619,7 +618,7 @@ static void opHasSkill(Program* program)
|
|||
|
||||
int result = 0;
|
||||
if (object != NULL) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
result = skillGetValue(object, skill);
|
||||
}
|
||||
} else {
|
||||
|
@ -658,7 +657,7 @@ static void opRollVsSkill(Program* program)
|
|||
|
||||
int roll = ROLL_CRITICAL_FAILURE;
|
||||
if (object != NULL) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int sid = scriptGetSid(program);
|
||||
|
||||
Script* script;
|
||||
|
@ -835,7 +834,7 @@ static void opRandom(Program* program)
|
|||
}
|
||||
|
||||
int result;
|
||||
if (_vcr_status() == 2) {
|
||||
if (vcrGetState() == VCR_STATE_TURNED_OFF) {
|
||||
result = randomBetween(data[1], data[0]);
|
||||
} else {
|
||||
result = (data[0] - data[1]) / 2;
|
||||
|
@ -899,7 +898,7 @@ static void opMoveTo(Program* program)
|
|||
Rect before;
|
||||
objectGetRect(object, &before);
|
||||
|
||||
if (object->elevation != elevation && (object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (object->elevation != elevation && PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(object);
|
||||
}
|
||||
|
||||
|
@ -964,7 +963,7 @@ static void opCreateObject(Program* program)
|
|||
|
||||
if (sid != -1) {
|
||||
int scriptType = 0;
|
||||
switch (object->pid >> 24) {
|
||||
switch (PID_TYPE(object->pid)) {
|
||||
case OBJ_TYPE_CRITTER:
|
||||
scriptType = SCRIPT_TYPE_CRITTER;
|
||||
break;
|
||||
|
@ -991,7 +990,7 @@ static void opCreateObject(Program* program)
|
|||
script->field_14 = sid - 1;
|
||||
|
||||
if (scriptType == SCRIPT_TYPE_SPATIAL) {
|
||||
script->sp.built_tile = ((object->elevation << 29) & 0xE0000000) | object->tile;
|
||||
script->sp.built_tile = builtTileCreate(object->tile, object->elevation);
|
||||
script->sp.radius = 3;
|
||||
}
|
||||
|
||||
|
@ -1020,7 +1019,7 @@ static void opDestroyObject(Program* program)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (_isLoadingGame()) {
|
||||
debugPrint("\nError: attempt to destroy critter in load/save-game: %s!", program->name);
|
||||
program->flags &= ~PROGRAM_FLAG_0x20;
|
||||
|
@ -1030,7 +1029,7 @@ static void opDestroyObject(Program* program)
|
|||
|
||||
bool isSelf = object == scriptGetSelf(program);
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(object);
|
||||
}
|
||||
|
||||
|
@ -1311,7 +1310,7 @@ static void opGetObjectType(Program* program)
|
|||
|
||||
int objectType = -1;
|
||||
if (object != NULL) {
|
||||
objectType = (object->fid & 0xF000000) >> 24;
|
||||
objectType = FID_TYPE(object->fid);
|
||||
}
|
||||
|
||||
programStackPushInteger(program, objectType);
|
||||
|
@ -1325,7 +1324,7 @@ static void opGetItemType(Program* program)
|
|||
|
||||
int itemType = -1;
|
||||
if (obj != NULL) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_ITEM) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(obj->pid, &proto) != -1) {
|
||||
itemType = itemGetType(obj);
|
||||
|
@ -1400,8 +1399,8 @@ static void opAnimateStand(Program* program)
|
|||
}
|
||||
|
||||
if (!isInCombat()) {
|
||||
reg_anim_begin(1);
|
||||
reg_anim_animate(object, ANIM_STAND, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_UNRESERVED);
|
||||
animationRegisterAnimate(object, ANIM_STAND, 0);
|
||||
reg_anim_end();
|
||||
}
|
||||
}
|
||||
|
@ -1424,8 +1423,8 @@ static void opAnimateStandReverse(Program* program)
|
|||
}
|
||||
|
||||
if (!isInCombat()) {
|
||||
reg_anim_begin(0x01);
|
||||
reg_anim_animate_reverse(object, ANIM_STAND, 0);
|
||||
reg_anim_begin(ANIMATION_REQUEST_UNRESERVED);
|
||||
animationRegisterAnimateReversed(object, ANIM_STAND, 0);
|
||||
reg_anim_end();
|
||||
}
|
||||
}
|
||||
|
@ -1468,12 +1467,12 @@ static void opAnimateMoveObjectToTile(Program* program)
|
|||
flags &= ~0x10;
|
||||
}
|
||||
|
||||
reg_anim_begin(1);
|
||||
reg_anim_begin(ANIMATION_REQUEST_UNRESERVED);
|
||||
|
||||
if (flags == 0) {
|
||||
reg_anim_obj_move_to_tile(object, tile, object->elevation, -1, 0);
|
||||
animationRegisterMoveToTile(object, tile, object->elevation, -1, 0);
|
||||
} else {
|
||||
reg_anim_obj_run_to_tile(object, tile, object->elevation, -1, 0);
|
||||
animationRegisterRunToTile(object, tile, object->elevation, -1, 0);
|
||||
}
|
||||
|
||||
reg_anim_end();
|
||||
|
@ -1739,7 +1738,7 @@ static void opWieldItem(Program* program)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
scriptPredefinedError(program, "wield_obj_critter", SCRIPT_ERROR_FOLLOWS);
|
||||
debugPrint(" Only works for critters! ERROR ERROR ERROR!");
|
||||
return;
|
||||
|
@ -1805,7 +1804,7 @@ static void opUseObject(Program* program)
|
|||
}
|
||||
|
||||
Object* self = scriptGetSelf(program);
|
||||
if ((self->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
|
||||
_action_use_an_object(script->target, object);
|
||||
} else {
|
||||
_obj_use(self, object);
|
||||
|
@ -1946,7 +1945,7 @@ static void opStartGameDialog(Program* program)
|
|||
}
|
||||
|
||||
gGameDialogHeadFid = -1;
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(obj->pid, &proto) == -1) {
|
||||
return;
|
||||
|
@ -2009,7 +2008,7 @@ static void opMetarule3(Program* program)
|
|||
ProgramValue param2 = programStackPopValue(program);
|
||||
ProgramValue param1 = programStackPopValue(program);
|
||||
int rule = programStackPopInteger(program);
|
||||
|
||||
|
||||
ProgramValue result;
|
||||
result.opcode = VALUE_TYPE_INT;
|
||||
result.integerValue = 0;
|
||||
|
@ -2048,7 +2047,7 @@ static void opMetarule3(Program* program)
|
|||
|
||||
Object* object = objectFindFirstAtLocation(elevation, tile);
|
||||
while (object != NULL) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (critterFound) {
|
||||
result.opcode = VALUE_TYPE_PTR;
|
||||
result.pointerValue = object;
|
||||
|
@ -2069,9 +2068,9 @@ static void opMetarule3(Program* program)
|
|||
Object* obj = static_cast<Object*>(param1.pointerValue);
|
||||
int frmId = param2.integerValue;
|
||||
|
||||
int fid = buildFid((obj->fid & 0xF000000) >> 24,
|
||||
int fid = buildFid(FID_TYPE(obj->fid),
|
||||
frmId,
|
||||
(obj->fid & 0xFF0000) >> 16,
|
||||
FID_ANIM_TYPE(obj->fid),
|
||||
(obj->fid & 0xF000) >> 12,
|
||||
(obj->fid & 0x70000000) >> 28);
|
||||
|
||||
|
@ -2139,7 +2138,7 @@ static void opSetObjectVisibility(Program* program)
|
|||
|
||||
Rect rect;
|
||||
if (objectHide(obj, &rect) != -1) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
obj->flags |= OBJECT_NO_BLOCK;
|
||||
}
|
||||
|
||||
|
@ -2148,7 +2147,7 @@ static void opSetObjectVisibility(Program* program)
|
|||
}
|
||||
} else {
|
||||
if ((obj->flags & OBJECT_HIDDEN) != 0) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
obj->flags &= ~OBJECT_NO_BLOCK;
|
||||
}
|
||||
|
||||
|
@ -2364,7 +2363,7 @@ static int _correctDeath(Object* critter, int anim, bool forceBack)
|
|||
if (violenceLevel < VIOLENCE_LEVEL_MAXIMUM_BLOOD) {
|
||||
useStandardDeath = true;
|
||||
} else {
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, anim, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, anim, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
if (!artExists(fid)) {
|
||||
useStandardDeath = true;
|
||||
}
|
||||
|
@ -2374,7 +2373,7 @@ static int _correctDeath(Object* critter, int anim, bool forceBack)
|
|||
if (forceBack) {
|
||||
anim = ANIM_FALL_BACK;
|
||||
} else {
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, ANIM_FALL_FRONT, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, ANIM_FALL_FRONT, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
if (artExists(fid)) {
|
||||
anim = ANIM_FALL_FRONT;
|
||||
} else {
|
||||
|
@ -2407,7 +2406,7 @@ static void opKillCritterType(Program* program)
|
|||
|
||||
Object* obj = objectFindFirst();
|
||||
while (obj != NULL) {
|
||||
if (((obj->fid & 0xFF0000) >> 16) >= ANIM_FALL_BACK_SF) {
|
||||
if (FID_ANIM_TYPE(obj->fid) >= ANIM_FALL_BACK_SF) {
|
||||
obj = objectFindNext();
|
||||
continue;
|
||||
}
|
||||
|
@ -2447,7 +2446,7 @@ static void opKillCritterType(Program* program)
|
|||
|
||||
objectFindFirst();
|
||||
|
||||
gMapHeader.field_38 = gameTimeGetTime();
|
||||
gMapHeader.lastVisitTime = gameTimeGetTime();
|
||||
}
|
||||
|
||||
obj = objectFindNext();
|
||||
|
@ -2471,7 +2470,7 @@ static void opCritterDamage(Program* program)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
scriptPredefinedError(program, "critter_damage", SCRIPT_ERROR_FOLLOWS);
|
||||
debugPrint(" Can't call on non-critters!");
|
||||
return;
|
||||
|
@ -2485,7 +2484,7 @@ static void opCritterDamage(Program* program)
|
|||
bool animate = (damageTypeWithFlags & 0x200) == 0;
|
||||
bool bypassArmor = (damageTypeWithFlags & 0x100) != 0;
|
||||
int damageType = damageTypeWithFlags & ~(0x100 | 0x200);
|
||||
_action_dmg(object->tile, object->elevation, amount, amount, damageType, animate, bypassArmor);
|
||||
actionDamage(object->tile, object->elevation, amount, amount, damageType, animate, bypassArmor);
|
||||
|
||||
program->flags &= ~PROGRAM_FLAG_0x20;
|
||||
|
||||
|
@ -2567,12 +2566,12 @@ static void opHasTrait(Program* program)
|
|||
case CRITTER_TRAIT_OBJECT:
|
||||
switch (param) {
|
||||
case CRITTER_TRAIT_OBJECT_AI_PACKET:
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
result = object->data.critter.combat.aiPacket;
|
||||
}
|
||||
break;
|
||||
case CRITTER_TRAIT_OBJECT_TEAM:
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
result = object->data.critter.combat.team;
|
||||
}
|
||||
break;
|
||||
|
@ -2681,7 +2680,7 @@ static void opGameDialogSystemEnter(Program* program)
|
|||
}
|
||||
|
||||
Object* self = scriptGetSelf(program);
|
||||
if ((self->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (!critterIsActive(self)) {
|
||||
return;
|
||||
}
|
||||
|
@ -2723,11 +2722,11 @@ static void opGetCritterState(Program* program)
|
|||
Object* critter = static_cast<Object*>(programStackPopPointer(program));
|
||||
|
||||
int state = CRITTER_STATE_DEAD;
|
||||
if (critter != NULL && (critter->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (critter != NULL && PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (critterIsActive(critter)) {
|
||||
state = CRITTER_STATE_NORMAL;
|
||||
|
||||
int anim = (critter->fid & 0xFF0000) >> 16;
|
||||
int anim = FID_ANIM_TYPE(critter->fid);
|
||||
if (anim >= ANIM_FALL_BACK_SF && anim <= ANIM_FALL_FRONT_SF) {
|
||||
state = CRITTER_STATE_PRONE;
|
||||
}
|
||||
|
@ -2809,7 +2808,7 @@ static void opCritterAttemptPlacement(Program* program)
|
|||
return;
|
||||
}
|
||||
|
||||
if (elevation != critter->elevation && critter->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (elevation != critter->elevation && PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(critter);
|
||||
}
|
||||
|
||||
|
@ -2853,7 +2852,7 @@ static void opCritterAddTrait(Program* program)
|
|||
Object* object = static_cast<Object*>(programStackPopPointer(program));
|
||||
|
||||
if (object != NULL) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
switch (kind) {
|
||||
case CRITTER_TRAIT_PERK:
|
||||
if (1) {
|
||||
|
@ -2928,7 +2927,7 @@ static void opCritterRemoveTrait(Program* program)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
switch (kind) {
|
||||
case CRITTER_TRAIT_PERK:
|
||||
while (perkGetRank(object, param) > 0) {
|
||||
|
@ -2997,7 +2996,7 @@ static void opCritterGetInventoryObject(Program* program)
|
|||
int type = programStackPopInteger(program);
|
||||
Object* critter = static_cast<Object*>(programStackPopPointer(program));
|
||||
|
||||
if ((critter->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER) {
|
||||
switch (type) {
|
||||
case INVEN_TYPE_WORN:
|
||||
programStackPushPointer(program, critterGetArmor(critter));
|
||||
|
@ -3280,13 +3279,13 @@ static void opMetarule(Program* program)
|
|||
case METARULE_WEAPON_DAMAGE_TYPE:
|
||||
if (1) {
|
||||
Object* object = static_cast<Object*>(param.pointerValue);
|
||||
if ((object->pid >> 24) == OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_ITEM) {
|
||||
if (itemGetType(object) == ITEM_TYPE_WEAPON) {
|
||||
result = weaponGetDamageType(NULL, object);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (buildFid(5, 10, 0, 0, 0) == object->fid) {
|
||||
if (buildFid(OBJ_TYPE_MISC, 10, 0, 0, 0) == object->fid) {
|
||||
result = DAMAGE_TYPE_EXPLOSION;
|
||||
break;
|
||||
}
|
||||
|
@ -3299,10 +3298,10 @@ static void opMetarule(Program* program)
|
|||
case METARULE_CRITTER_BARTERS:
|
||||
if (1) {
|
||||
Object* object = static_cast<Object*>(param.pointerValue);
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
protoGetProto(object->pid, &proto);
|
||||
if ((proto->critter.data.flags & 0x02) != 0) {
|
||||
if ((proto->critter.data.flags & CRITTER_FLAG_0x2) != 0) {
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
@ -3348,40 +3347,40 @@ static void opAnim(Program* program)
|
|||
|
||||
if (anim < ANIM_COUNT) {
|
||||
CritterCombatData* combatData = NULL;
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData = &(obj->data.critter.combat);
|
||||
}
|
||||
|
||||
anim = _correctDeath(obj, anim, true);
|
||||
|
||||
reg_anim_begin(1);
|
||||
reg_anim_begin(ANIMATION_REQUEST_UNRESERVED);
|
||||
|
||||
// TODO: Not sure about the purpose, why it handles knock down flag?
|
||||
if (frame == 0) {
|
||||
reg_anim_animate(obj, anim, 0);
|
||||
animationRegisterAnimate(obj, anim, 0);
|
||||
if (anim >= ANIM_FALL_BACK && anim <= ANIM_FALL_FRONT_BLOOD) {
|
||||
int fid = buildFid(1, obj->fid & 0xFFF, anim + 28, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 28);
|
||||
reg_anim_17(obj, fid, -1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, obj->fid & 0xFFF, anim + 28, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 28);
|
||||
animationRegisterSetFid(obj, fid, -1);
|
||||
}
|
||||
|
||||
if (combatData != NULL) {
|
||||
combatData->results &= DAM_KNOCKED_DOWN;
|
||||
}
|
||||
} else {
|
||||
int fid = buildFid((obj->fid & 0xF000000) >> 24, obj->fid & 0xFFF, anim, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
reg_anim_animate_reverse(obj, anim, 0);
|
||||
int fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, anim, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
animationRegisterAnimateReversed(obj, anim, 0);
|
||||
|
||||
if (anim == ANIM_PRONE_TO_STANDING) {
|
||||
fid = buildFid((obj->fid & 0xF000000) >> 24, obj->fid & 0xFFF, ANIM_FALL_FRONT_SF, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_FALL_FRONT_SF, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
} else if (anim == ANIM_BACK_TO_STANDING) {
|
||||
fid = buildFid((obj->fid & 0xF000000) >> 24, obj->fid & 0xFFF, ANIM_FALL_BACK_SF, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
fid = buildFid(FID_TYPE(obj->fid), obj->fid & 0xFFF, ANIM_FALL_BACK_SF, (obj->fid & 0xF000) >> 12, (obj->fid & 0x70000000) >> 24);
|
||||
}
|
||||
|
||||
if (combatData != NULL) {
|
||||
combatData->results |= DAM_KNOCKED_DOWN;
|
||||
}
|
||||
|
||||
reg_anim_17(obj, fid, -1);
|
||||
animationRegisterSetFid(obj, fid, -1);
|
||||
}
|
||||
|
||||
reg_anim_end();
|
||||
|
@ -3451,7 +3450,7 @@ static void opRegAnimAnimate(Program* program)
|
|||
int violenceLevel = VIOLENCE_LEVEL_NONE;
|
||||
if (anim != 20 || object == NULL || object->pid != 0x100002F || (configGetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_VIOLENCE_LEVEL_KEY, &violenceLevel) && violenceLevel >= 2)) {
|
||||
if (object != NULL) {
|
||||
reg_anim_animate(object, anim, delay);
|
||||
animationRegisterAnimate(object, anim, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_animate", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
|
@ -3469,7 +3468,7 @@ static void opRegAnimAnimateReverse(Program* program)
|
|||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_animate_reverse(object, anim, delay);
|
||||
animationRegisterAnimateReversed(object, anim, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_animate_reverse", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
|
@ -3486,7 +3485,7 @@ static void opRegAnimObjectMoveToObject(Program* program)
|
|||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_obj_move_to_obj(object, dest, -1, delay);
|
||||
animationRegisterMoveToObject(object, dest, -1, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_obj_move_to_obj", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
|
@ -3503,7 +3502,7 @@ static void opRegAnimObjectRunToObject(Program* program)
|
|||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_obj_run_to_obj(object, dest, -1, delay);
|
||||
animationRegisterRunToObject(object, dest, -1, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_obj_run_to_obj", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
|
@ -3520,7 +3519,7 @@ static void opRegAnimObjectMoveToTile(Program* program)
|
|||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_obj_move_to_tile(object, tile, object->elevation, -1, delay);
|
||||
animationRegisterMoveToTile(object, tile, object->elevation, -1, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_obj_move_to_tile", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
|
@ -3537,7 +3536,7 @@ static void opRegAnimObjectRunToTile(Program* program)
|
|||
|
||||
if (!isInCombat()) {
|
||||
if (object != NULL) {
|
||||
reg_anim_obj_run_to_tile(object, tile, object->elevation, -1, delay);
|
||||
animationRegisterRunToTile(object, tile, object->elevation, -1, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_obj_run_to_tile", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
|
@ -3674,8 +3673,8 @@ static void opGetDaysSinceLastVisit(Program* program)
|
|||
{
|
||||
int days;
|
||||
|
||||
if (gMapHeader.field_38 != 0) {
|
||||
days = (gameTimeGetTime() - gMapHeader.field_38) / GAME_TIME_TICKS_PER_DAY;
|
||||
if (gMapHeader.lastVisitTime != 0) {
|
||||
days = (gameTimeGetTime() - gMapHeader.lastVisitTime) / GAME_TIME_TICKS_PER_DAY;
|
||||
} else {
|
||||
days = -1;
|
||||
}
|
||||
|
@ -3759,7 +3758,6 @@ static void _op_gsay_option(Program* program)
|
|||
}
|
||||
} else {
|
||||
programFatalError("Invalid arg 3 to sayOption");
|
||||
|
||||
}
|
||||
|
||||
program->flags &= ~PROGRAM_FLAG_0x20;
|
||||
|
@ -3868,7 +3866,7 @@ static void opGetPoison(Program* program)
|
|||
|
||||
int poison = 0;
|
||||
if (obj != NULL) {
|
||||
if (obj->pid >> 24 == 1) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
poison = critterGetPoison(obj);
|
||||
} else {
|
||||
debugPrint("\nScript Error: get_poison: who is not a critter!");
|
||||
|
@ -3915,7 +3913,7 @@ static void opRegAnimAnimateForever(Program* program)
|
|||
|
||||
if (!isInCombat()) {
|
||||
if (obj != NULL) {
|
||||
reg_anim_animate_forever(obj, anim, -1);
|
||||
animationRegisterAnimateForever(obj, anim, -1);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_animate_forever", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
|
@ -4119,7 +4117,7 @@ static void opGameUiIsDisabled(Program* program)
|
|||
|
||||
// gfade_out
|
||||
// 0x45B404
|
||||
static void opFadeOut(Program* program)
|
||||
static void opGameFadeOut(Program* program)
|
||||
{
|
||||
int data = programStackPopInteger(program);
|
||||
|
||||
|
@ -4132,7 +4130,7 @@ static void opFadeOut(Program* program)
|
|||
|
||||
// gfade_in
|
||||
// 0x45B47C
|
||||
static void opFadeIn(Program* program)
|
||||
static void opGameFadeIn(Program* program)
|
||||
{
|
||||
int data = programStackPopInteger(program);
|
||||
|
||||
|
@ -4186,7 +4184,7 @@ static void _op_anim_action_frame(Program* program)
|
|||
int actionFrame = 0;
|
||||
|
||||
if (object != NULL) {
|
||||
int fid = buildFid((object->fid & 0xF000000) >> 24, object->fid & 0xFFF, anim, 0, object->rotation);
|
||||
int fid = buildFid(FID_TYPE(object->fid), object->fid & 0xFFF, anim, 0, object->rotation);
|
||||
CacheEntry* frmHandle;
|
||||
Art* frm = artLock(fid, &frmHandle);
|
||||
if (frm != NULL) {
|
||||
|
@ -4214,7 +4212,7 @@ static void opRegAnimPlaySfx(Program* program)
|
|||
}
|
||||
|
||||
if (obj != NULL) {
|
||||
reg_anim_play_sfx(obj, soundEffectName, delay);
|
||||
animationRegisterPlaySoundEffect(obj, soundEffectName, delay);
|
||||
} else {
|
||||
scriptPredefinedError(program, "reg_anim_play_sfx", SCRIPT_ERROR_OBJECT_IS_NULL);
|
||||
}
|
||||
|
@ -4229,7 +4227,7 @@ static void opCritterModifySkill(Program* program)
|
|||
Object* critter = static_cast<Object*>(programStackPopPointer(program));
|
||||
|
||||
if (critter != NULL && points != 0) {
|
||||
if (critter->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (critter == gDude) {
|
||||
int normalizedPoints = abs(points);
|
||||
if (skillIsTagged(skill)) {
|
||||
|
@ -4430,7 +4428,7 @@ static void opDestroyMultipleObjects(Program* program)
|
|||
|
||||
int result = 0;
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(object);
|
||||
}
|
||||
|
||||
|
@ -4502,7 +4500,7 @@ static void opUseObjectOnObject(Program* program)
|
|||
}
|
||||
|
||||
Object* self = scriptGetSelf(program);
|
||||
if ((self->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
|
||||
_action_use_an_item_on_object(self, target, item);
|
||||
} else {
|
||||
_obj_use_item_on(self, target, item);
|
||||
|
@ -4723,7 +4721,7 @@ static void opTerminateCombat(Program* program)
|
|||
_game_user_wants_to_quit = 1;
|
||||
Object* self = scriptGetSelf(program);
|
||||
if (self != NULL) {
|
||||
if ((self->pid >> 24) == 1) {
|
||||
if (PID_TYPE(self->pid) == OBJ_TYPE_CRITTER) {
|
||||
self->data.critter.combat.maneuver |= CRITTER_MANEUVER_STOP_ATTACKING;
|
||||
self->data.critter.combat.whoHitMe = NULL;
|
||||
_combatAIInfoSetLastTarget(self, NULL);
|
||||
|
@ -4967,8 +4965,8 @@ void _initIntExtra()
|
|||
interpreterRegisterOpcode(0x8133, opGameUiDisable); // op_game_ui_disable
|
||||
interpreterRegisterOpcode(0x8134, opGameUiEnable); // op_game_ui_enable
|
||||
interpreterRegisterOpcode(0x8135, opGameUiIsDisabled); // op_game_ui_is_disabled
|
||||
interpreterRegisterOpcode(0x8136, opFadeOut); // op_gfade_out
|
||||
interpreterRegisterOpcode(0x8137, opFadeIn); // op_gfade_in
|
||||
interpreterRegisterOpcode(0x8136, opGameFadeOut); // op_gfade_out
|
||||
interpreterRegisterOpcode(0x8137, opGameFadeIn); // op_gfade_in
|
||||
interpreterRegisterOpcode(0x8138, opItemCapsTotal); // op_item_caps_total
|
||||
interpreterRegisterOpcode(0x8139, opItemCapsAdjust); // op_item_caps_adjust
|
||||
interpreterRegisterOpcode(0x813A, _op_anim_action_frame); // op_anim_action_frame
|
||||
|
@ -5001,7 +4999,16 @@ void _initIntExtra()
|
|||
interpreterRegisterOpcode(0x8155, opCritterStopAttacking); // op_critter_stop_attacking
|
||||
}
|
||||
|
||||
// NOTE: Uncollapsed 0x45D878.
|
||||
//
|
||||
// 0x45D878
|
||||
void _intExtraRemoveProgramReferences_()
|
||||
void intExtraUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
// NOTE: Uncollapsed 0x45D878.
|
||||
//
|
||||
// 0x45D878
|
||||
void intExtraRemoveProgramReferences(Program* program)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#ifndef INTERPRETER_EXTRA_H
|
||||
#define INTERPRETER_EXTRA_H
|
||||
|
||||
#include "interpreter.h"
|
||||
|
||||
void _intExtraClose_();
|
||||
void _initIntExtra();
|
||||
void _intExtraRemoveProgramReferences_();
|
||||
void intExtraUpdate();
|
||||
void intExtraRemoveProgramReferences(Program* program);
|
||||
|
||||
#endif /* INTERPRETER_EXTRA_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,12 +3,12 @@
|
|||
|
||||
#include "interpreter.h"
|
||||
|
||||
typedef void (*OFF_59E160)(Program*);
|
||||
typedef void(IntLibProgramDeleteCallback)(Program*);
|
||||
|
||||
void _updateIntLib();
|
||||
void _intlibClose();
|
||||
void _initIntlib();
|
||||
void _interpretRegisterProgramDeleteCallback(OFF_59E160 fn);
|
||||
void _removeProgramReferences_(Program* program);
|
||||
void intLibUpdate();
|
||||
void intLibExit();
|
||||
void intLibInit();
|
||||
void intLibRegisterProgramDeleteCallback(IntLibProgramDeleteCallback* callback);
|
||||
void intLibRemoveProgramReferences(Program* program);
|
||||
|
||||
#endif /* INTERPRETER_LIB_H */
|
||||
|
|
154
src/inventory.cc
154
src/inventory.cc
|
@ -675,7 +675,7 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
gInventoryWindowMaxY = windowDescription->height + inventoryWindowY;
|
||||
|
||||
unsigned char* dest = windowGetBuffer(gInventoryWindow);
|
||||
int backgroundFid = buildFid(6, windowDescription->field_0, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, windowDescription->field_0, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
|
@ -821,10 +821,10 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
unsigned char* buttonDownData;
|
||||
unsigned char* buttonDisabledData;
|
||||
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[0]));
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[1]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -853,13 +853,13 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
// TODO: Figure out why it building fid in chain.
|
||||
|
||||
// Large arrow up (normal).
|
||||
fid = buildFid(6, 100, 0, 0, 0);
|
||||
fid = buildFid(6, fid, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 100, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, fid, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[2]));
|
||||
|
||||
// Large arrow up (pressed).
|
||||
fid = buildFid(6, 101, 0, 0, 0);
|
||||
fid = buildFid(6, fid, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 101, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, fid, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[3]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -877,15 +877,15 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
}
|
||||
} else {
|
||||
// Large up arrow (normal).
|
||||
fid = buildFid(6, 49, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 49, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[2]));
|
||||
|
||||
// Large up arrow (pressed).
|
||||
fid = buildFid(6, 50, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 50, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[3]));
|
||||
|
||||
// Large up arrow (disabled).
|
||||
fid = buildFid(6, 53, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 53, 0, 0, 0);
|
||||
buttonDisabledData = artLockFrameData(fid, 0, 0, &(_ikey[4]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL && buttonDisabledData != NULL) {
|
||||
|
@ -913,13 +913,13 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_TRADE) {
|
||||
// Large dialog down button (normal)
|
||||
fid = buildFid(6, 93, 0, 0, 0);
|
||||
fid = buildFid(6, fid, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 93, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, fid, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[5]));
|
||||
|
||||
// Dialog down button (pressed)
|
||||
fid = buildFid(6, 94, 0, 0, 0);
|
||||
fid = buildFid(6, fid, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 94, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, fid, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[6]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -943,15 +943,15 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
}
|
||||
} else {
|
||||
// Large arrow down (normal).
|
||||
fid = buildFid(6, 51, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 51, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[5]));
|
||||
|
||||
// Large arrow down (pressed).
|
||||
fid = buildFid(6, 52, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 52, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[6]));
|
||||
|
||||
// Large arrow down (disabled).
|
||||
fid = buildFid(6, 54, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 54, 0, 0, 0);
|
||||
buttonDisabledData = artLockFrameData(fid, 0, 0, &(_ikey[7]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL && buttonDisabledData != NULL) {
|
||||
|
@ -986,11 +986,11 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT) {
|
||||
if (!_gIsSteal) {
|
||||
// Take all button (normal)
|
||||
fid = buildFid(6, 436, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 436, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[8]));
|
||||
|
||||
// Take all button (pressed)
|
||||
fid = buildFid(6, 437, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 437, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[9]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -1004,11 +1004,11 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
}
|
||||
} else {
|
||||
// Inventory button up (normal)
|
||||
fid = buildFid(6, 49, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 49, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[8]));
|
||||
|
||||
// Inventory button up (pressed)
|
||||
fid = buildFid(6, 50, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 50, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[9]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -1026,11 +1026,11 @@ static bool _setup_inventory(int inventoryWindowType)
|
|||
}
|
||||
|
||||
// Inventory button down (normal)
|
||||
fid = buildFid(6, 51, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 51, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_ikey[8]));
|
||||
|
||||
// Inventory button down (pressed).
|
||||
fid = buildFid(6, 52, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 52, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_ikey[9]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -1178,7 +1178,7 @@ static void _display_inventory(int a1, int a2, int inventoryWindowType)
|
|||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_NORMAL) {
|
||||
pitch = 499;
|
||||
|
||||
int backgroundFid = buildFid(6, 48, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
|
@ -1191,7 +1191,7 @@ static void _display_inventory(int a1, int a2, int inventoryWindowType)
|
|||
|
||||
if (gInventoryLeftHandItem != NULL && gInventoryLeftHandItem == gInventoryRightHandItem) {
|
||||
// Clear item1.
|
||||
int itemBackgroundFid = buildFid(6, 32, 0, 0, 0);
|
||||
int itemBackgroundFid = buildFid(OBJ_TYPE_INTERFACE, 32, 0, 0, 0);
|
||||
|
||||
CacheEntry* itemBackgroundFrmHandle;
|
||||
Art* itemBackgroundFrm = artLock(itemBackgroundFid, &itemBackgroundFrmHandle);
|
||||
|
@ -1212,7 +1212,7 @@ static void _display_inventory(int a1, int a2, int inventoryWindowType)
|
|||
} else if (inventoryWindowType == INVENTORY_WINDOW_TYPE_USE_ITEM_ON) {
|
||||
pitch = 292;
|
||||
|
||||
int backgroundFid = buildFid(6, 113, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 113, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
|
@ -1224,7 +1224,7 @@ static void _display_inventory(int a1, int a2, int inventoryWindowType)
|
|||
} else if (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT) {
|
||||
pitch = 537;
|
||||
|
||||
int backgroundFid = buildFid(6, 114, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
|
@ -1333,7 +1333,7 @@ static void _display_target_inventory(int a1, int a2, Inventory* inventory, int
|
|||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_LOOT) {
|
||||
pitch = 537;
|
||||
|
||||
int fid = buildFid(6, 114, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
|
||||
|
||||
CacheEntry* handle;
|
||||
unsigned char* data = artLockFrameData(fid, 0, 0, &handle);
|
||||
|
@ -1521,7 +1521,7 @@ static void _display_body(int fid, int inventoryWindowType)
|
|||
rect.bottom = rect.top + INVENTORY_BODY_VIEW_HEIGHT - 1;
|
||||
|
||||
int frmId = gGameDialogSpeakerIsPartyMember ? 420 : 111;
|
||||
int backgroundFid = buildFid(6, frmId, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, frmId, 0, 0, 0);
|
||||
|
||||
unsigned char* src = artLockFrameData(backgroundFid, 0, 0, &backrgroundFrmHandle);
|
||||
if (src != NULL) {
|
||||
|
@ -1563,7 +1563,7 @@ static void _display_body(int fid, int inventoryWindowType)
|
|||
rect.right = rect.left + INVENTORY_BODY_VIEW_WIDTH - 1;
|
||||
rect.bottom = rect.top + INVENTORY_BODY_VIEW_HEIGHT - 1;
|
||||
|
||||
int backgroundFid = buildFid(6, 114, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
|
||||
unsigned char* src = artLockFrameData(backgroundFid, 0, 0, &backrgroundFrmHandle);
|
||||
if (src != NULL) {
|
||||
blitBufferToBuffer(src + 537 * rect.top + rect.left,
|
||||
|
@ -1610,7 +1610,7 @@ static int inventoryCommonInit()
|
|||
for (index = 0; index < INVENTORY_WINDOW_CURSOR_COUNT; index++) {
|
||||
InventoryCursorData* cursorData = &(gInventoryCursorData[index]);
|
||||
|
||||
int fid = buildFid(6, gInventoryWindowCursorFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gInventoryWindowCursorFrmIds[index], 0, 0, 0);
|
||||
Art* frm = artLock(fid, &(cursorData->frmHandle));
|
||||
if (frm == NULL) {
|
||||
break;
|
||||
|
@ -1792,7 +1792,7 @@ static void _inven_pickup(int keyCode, int a2)
|
|||
}
|
||||
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 48, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
blitBufferToBuffer(backgroundFrmData + 499 * rect.top + rect.left, width, height, 499, windowBuffer + 499 * rect.top + rect.left, 499);
|
||||
|
@ -1803,7 +1803,7 @@ static void _inven_pickup(int keyCode, int a2)
|
|||
rect.bottom = rect.top + height - 1;
|
||||
} else {
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
int backgroundFid = buildFid(6, 48, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
if (backgroundFrmData != NULL) {
|
||||
blitBufferToBuffer(backgroundFrmData + 499 * 286 + 154, 180, 61, 499, windowBuffer + 499 * 286 + 154, 499);
|
||||
|
@ -2043,7 +2043,7 @@ void _adjust_ac(Object* critter, Object* oldArmor, Object* newArmor)
|
|||
static void _adjust_fid()
|
||||
{
|
||||
int fid;
|
||||
if ((_inven_dude->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(_inven_dude->fid) == OBJ_TYPE_CRITTER) {
|
||||
Proto* proto;
|
||||
|
||||
int v0 = _art_vault_guy_num;
|
||||
|
@ -2082,7 +2082,7 @@ static void _adjust_fid()
|
|||
}
|
||||
}
|
||||
|
||||
fid = buildFid(1, v0, 0, animationCode, 0);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, v0, 0, animationCode, 0);
|
||||
} else {
|
||||
fid = _inven_dude->fid;
|
||||
}
|
||||
|
@ -2325,7 +2325,7 @@ static void inventoryRenderSummary()
|
|||
|
||||
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
|
||||
|
||||
int fid = buildFid(6, 48, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
unsigned char* backgroundData = artLockFrameData(fid, 0, 0, &backgroundHandle);
|
||||
|
@ -2515,7 +2515,7 @@ static void inventoryRenderSummary()
|
|||
// Total wt:
|
||||
messageListItem.num = 20;
|
||||
if (messageListGetItem(&gInventoryMessageList, &messageListItem)) {
|
||||
if (_stack[0]->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(_stack[0]->pid) == OBJ_TYPE_CRITTER) {
|
||||
int carryWeight = critterGetStat(_stack[0], STAT_CARRY_WEIGHT);
|
||||
int inventoryWeight = objectGetInventoryWeight(_stack[0]);
|
||||
sprintf(formattedText, "%s %d/%d", messageListItem.text, inventoryWeight, carryWeight);
|
||||
|
@ -2623,7 +2623,7 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
|||
{
|
||||
if (a4) {
|
||||
if (!isoIsDisabled()) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2649,8 +2649,8 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
|||
|
||||
if (critter == gDude) {
|
||||
if (!isoIsDisabled()) {
|
||||
int fid = buildFid(1, baseFrmId, 0, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
reg_anim_17(critter, fid, 0);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, baseFrmId, 0, (critter->fid & 0xF000) >> 12, critter->rotation + 1);
|
||||
animationRegisterSetFid(critter, fid, 0);
|
||||
}
|
||||
} else {
|
||||
_adjust_ac(critter, armor, item);
|
||||
|
@ -2665,7 +2665,7 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
|||
|
||||
int weaponAnimationCode = weaponGetAnimationCode(item);
|
||||
int hitModeAnimationCode = weaponGetAnimationForHitMode(item, HIT_MODE_RIGHT_WEAPON_PRIMARY);
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, hitModeAnimationCode, weaponAnimationCode, critter->rotation + 1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, hitModeAnimationCode, weaponAnimationCode, critter->rotation + 1);
|
||||
if (!artExists(fid)) {
|
||||
debugPrint("\ninven_wield failed! ERROR ERROR ERROR!");
|
||||
return -1;
|
||||
|
@ -2730,21 +2730,21 @@ int _invenWieldFunc(Object* critter, Object* item, int a3, bool a4)
|
|||
if (a4) {
|
||||
if (!isoIsDisabled()) {
|
||||
const char* soundEffectName = sfxBuildCharName(critter, ANIM_PUT_AWAY, CHARACTER_SOUND_EFFECT_UNUSED);
|
||||
reg_anim_play_sfx(critter, soundEffectName, 0);
|
||||
reg_anim_animate(critter, ANIM_PUT_AWAY, 0);
|
||||
animationRegisterPlaySoundEffect(critter, soundEffectName, 0);
|
||||
animationRegisterAnimate(critter, ANIM_PUT_AWAY, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a4 && !isoIsDisabled()) {
|
||||
if (weaponAnimationCode != 0) {
|
||||
reg_anim_18(critter, weaponAnimationCode, -1);
|
||||
animationRegisterTakeOutWeapon(critter, weaponAnimationCode, -1);
|
||||
} else {
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, 0, 0, critter->rotation + 1);
|
||||
reg_anim_17(critter, fid, -1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, 0, 0, critter->rotation + 1);
|
||||
animationRegisterSetFid(critter, fid, -1);
|
||||
}
|
||||
} else {
|
||||
int fid = buildFid(1, critter->fid & 0xFFF, 0, weaponAnimationCode, critter->rotation + 1);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, 0, weaponAnimationCode, critter->rotation + 1);
|
||||
_dude_stand(critter, critter->rotation, fid);
|
||||
}
|
||||
}
|
||||
|
@ -2791,20 +2791,20 @@ int _invenUnwieldFunc(Object* obj, int a2, int a3)
|
|||
|
||||
if (v6 == a2 && ((obj->fid & 0xF000) >> 12) != 0) {
|
||||
if (a3 && !isoIsDisabled()) {
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
const char* sfx = sfxBuildCharName(obj, ANIM_PUT_AWAY, CHARACTER_SOUND_EFFECT_UNUSED);
|
||||
reg_anim_play_sfx(obj, sfx, 0);
|
||||
animationRegisterPlaySoundEffect(obj, sfx, 0);
|
||||
|
||||
reg_anim_animate(obj, 39, 0);
|
||||
animationRegisterAnimate(obj, ANIM_PUT_AWAY, 0);
|
||||
|
||||
fid = buildFid(1, obj->fid & 0xFFF, 0, 0, obj->rotation + 1);
|
||||
reg_anim_17(obj, fid, -1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, obj->fid & 0xFFF, 0, 0, obj->rotation + 1);
|
||||
animationRegisterSetFid(obj, fid, -1);
|
||||
|
||||
return reg_anim_end();
|
||||
}
|
||||
|
||||
fid = buildFid(1, obj->fid & 0xFFF, 0, 0, obj->rotation + 1);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, obj->fid & 0xFFF, 0, 0, obj->rotation + 1);
|
||||
_dude_stand(obj, obj->rotation, fid);
|
||||
}
|
||||
|
||||
|
@ -3003,7 +3003,7 @@ static void inventoryExamineItem(Object* critter, Object* item)
|
|||
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
|
||||
|
||||
// Clear item description area.
|
||||
int backgroundFid = buildFid(6, 48, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 48, 0, 0, 0);
|
||||
|
||||
CacheEntry* handle;
|
||||
unsigned char* backgroundData = artLockFrameData(backgroundFid, 0, 0, &handle);
|
||||
|
@ -3226,7 +3226,7 @@ static void inventoryWindowOpenContextMenu(int keyCode, int inventoryWindowType)
|
|||
windowBuffer + windowDescription->width * rect.top + rect.left,
|
||||
windowDescription->width);
|
||||
} else {
|
||||
int backgroundFid = buildFid(6, windowDescription->field_0, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, windowDescription->field_0, 0, 0, 0);
|
||||
CacheEntry* backgroundFrmHandle;
|
||||
unsigned char* backgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &backgroundFrmHandle);
|
||||
blitBufferToBuffer(backgroundFrmData + windowDescription->width * rect.top + rect.left,
|
||||
|
@ -3403,8 +3403,8 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (((a2->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (_critter_flag_check(a2->pid, 0x20)) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
|
||||
if (_critter_flag_check(a2->pid, CRITTER_FLAG_0x20)) {
|
||||
// You can't find anything to take from that.
|
||||
messageListItem.num = 50;
|
||||
if (messageListGetItem(&gInventoryMessageList, &messageListItem)) {
|
||||
|
@ -3414,7 +3414,7 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
|||
}
|
||||
}
|
||||
|
||||
if (((a2->fid & 0xF000000) >> 24) == OBJ_TYPE_ITEM) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_ITEM) {
|
||||
if (itemGetType(a2) == ITEM_TYPE_CONTAINER) {
|
||||
if (a2->frame == 0) {
|
||||
CacheEntry* handle;
|
||||
|
@ -3488,7 +3488,7 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
|||
int critterCount = 0;
|
||||
int critterIndex = 0;
|
||||
if (!_gIsSteal) {
|
||||
if ((a2->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
|
||||
critterCount = objectListCreate(a2->tile, a2->elevation, OBJ_TYPE_CRITTER, &critters);
|
||||
int endIndex = critterCount - 1;
|
||||
for (int index = 0; index < critterCount; index++) {
|
||||
|
@ -3520,10 +3520,10 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
|||
}
|
||||
|
||||
// Setup left arrow button.
|
||||
fid = buildFid(6, arrowFrmIds[INVENTORY_ARROW_FRM_LEFT_ARROW_UP], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, arrowFrmIds[INVENTORY_ARROW_FRM_LEFT_ARROW_UP], 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(arrowFrmHandles[INVENTORY_ARROW_FRM_LEFT_ARROW_UP]));
|
||||
|
||||
fid = buildFid(6, arrowFrmIds[INVENTORY_ARROW_FRM_LEFT_ARROW_DOWN], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, arrowFrmIds[INVENTORY_ARROW_FRM_LEFT_ARROW_DOWN], 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(arrowFrmHandles[INVENTORY_ARROW_FRM_LEFT_ARROW_DOWN]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -3534,10 +3534,10 @@ int inventoryOpenLooting(Object* a1, Object* a2)
|
|||
}
|
||||
|
||||
// Setup right arrow button.
|
||||
fid = buildFid(6, arrowFrmIds[INVENTORY_ARROW_FRM_RIGHT_ARROW_UP], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, arrowFrmIds[INVENTORY_ARROW_FRM_RIGHT_ARROW_UP], 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(arrowFrmHandles[INVENTORY_ARROW_FRM_RIGHT_ARROW_UP]));
|
||||
|
||||
fid = buildFid(6, arrowFrmIds[INVENTORY_ARROW_FRM_RIGHT_ARROW_DOWN], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, arrowFrmIds[INVENTORY_ARROW_FRM_RIGHT_ARROW_DOWN], 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(arrowFrmHandles[INVENTORY_ARROW_FRM_RIGHT_ARROW_DOWN]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -3800,7 +3800,7 @@ int inventoryOpenStealing(Object* a1, Object* a2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
_gIsSteal = (a1->pid >> 24) == OBJ_TYPE_CRITTER && critterIsActive(a2);
|
||||
_gIsSteal = PID_TYPE(a1->pid) == OBJ_TYPE_CRITTER && critterIsActive(a2);
|
||||
_gStealCount = 0;
|
||||
_gStealSize = 0;
|
||||
|
||||
|
@ -3848,7 +3848,7 @@ static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
|
|||
unsigned char* windowBuffer = windowGetBuffer(gInventoryWindow);
|
||||
|
||||
CacheEntry* handle;
|
||||
int fid = buildFid(6, 114, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 114, 0, 0, 0);
|
||||
unsigned char* data = artLockFrameData(fid, 0, 0, &handle);
|
||||
if (data != NULL) {
|
||||
blitBufferToBuffer(data + 537 * rect.top + rect.left, INVENTORY_SLOT_WIDTH, INVENTORY_SLOT_HEIGHT, 537, windowBuffer + 537 * rect.top + rect.left, 537);
|
||||
|
@ -3931,7 +3931,7 @@ static int _move_inventory(Object* a1, int a2, Object* a3, bool a4)
|
|||
if (rc != 1) {
|
||||
if (_item_move(a3, _inven_dude, a1, quantityToMove) == 0) {
|
||||
if ((a1->flags & OBJECT_IN_RIGHT_HAND) != 0) {
|
||||
a3->fid = buildFid((a3->fid & 0xF000000) >> 24, a3->fid & 0xFFF, (a3->fid & 0xFF0000) >> 16, 0, a3->rotation + 1);
|
||||
a3->fid = buildFid(FID_TYPE(a3->fid), a3->fid & 0xFFF, FID_ANIM_TYPE(a3->fid), 0, a3->rotation + 1);
|
||||
}
|
||||
|
||||
a3->flags &= ~OBJECT_EQUIPPED;
|
||||
|
@ -4735,7 +4735,7 @@ static void _draw_amount(int value, int inventoryWindowType)
|
|||
{
|
||||
// BIGNUM.frm
|
||||
CacheEntry* handle;
|
||||
int fid = buildFid(6, 170, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 170, 0, 0, 0);
|
||||
unsigned char* data = artLockFrameData(fid, 0, 0, &handle);
|
||||
if (data == NULL) {
|
||||
return;
|
||||
|
@ -4947,7 +4947,7 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
|||
unsigned char* windowBuffer = windowGetBuffer(_mt_wid);
|
||||
|
||||
CacheEntry* backgroundHandle;
|
||||
int backgroundFid = buildFid(6, windowDescription->field_0, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, windowDescription->field_0, 0, 0, 0);
|
||||
unsigned char* backgroundData = artLockFrameData(backgroundFid, 0, 0, &backgroundHandle);
|
||||
if (backgroundData != NULL) {
|
||||
blitBufferToBuffer(backgroundData, windowDescription->width, windowDescription->height, windowDescription->width, windowBuffer, windowDescription->width);
|
||||
|
@ -4972,7 +4972,7 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
|||
|
||||
// Timer overlay
|
||||
CacheEntry* overlayFrmHandle;
|
||||
int overlayFid = buildFid(6, 306, 0, 0, 0);
|
||||
int overlayFid = buildFid(OBJ_TYPE_INTERFACE, 306, 0, 0, 0);
|
||||
unsigned char* overlayFrmData = artLockFrameData(overlayFid, 0, 0, &overlayFrmHandle);
|
||||
if (overlayFrmData != NULL) {
|
||||
blitBufferToBuffer(overlayFrmData, 105, 81, 105, windowBuffer + 34 * windowDescription->width + 113, windowDescription->width);
|
||||
|
@ -4999,10 +4999,10 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
|||
int btn;
|
||||
|
||||
// Plus button
|
||||
fid = buildFid(6, 193, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 193, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_mt_key[0]));
|
||||
|
||||
fid = buildFid(6, 194, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 194, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_mt_key[1]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -5013,10 +5013,10 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
|||
}
|
||||
|
||||
// Minus button
|
||||
fid = buildFid(6, 191, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 191, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_mt_key[2]));
|
||||
|
||||
fid = buildFid(6, 192, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 192, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_mt_key[3]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -5026,10 +5026,10 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
|||
}
|
||||
}
|
||||
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_mt_key[4]));
|
||||
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_mt_key[5]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
@ -5047,10 +5047,10 @@ static int inventoryQuantityWindowInit(int inventoryWindowType, Object* item)
|
|||
}
|
||||
|
||||
if (inventoryWindowType == INVENTORY_WINDOW_TYPE_MOVE_ITEMS) {
|
||||
fid = buildFid(6, 307, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 307, 0, 0, 0);
|
||||
buttonUpData = artLockFrameData(fid, 0, 0, &(_mt_key[6]));
|
||||
|
||||
fid = buildFid(6, 308, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 308, 0, 0, 0);
|
||||
buttonDownData = artLockFrameData(fid, 0, 0, &(_mt_key[7]));
|
||||
|
||||
if (buttonUpData != NULL && buttonDownData != NULL) {
|
||||
|
|
36
src/item.cc
36
src/item.cc
|
@ -189,7 +189,7 @@ int itemAttemptAdd(Object* owner, Object* itemToAdd, int quantity)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int parentType = (owner->fid & 0xF000000) >> 24;
|
||||
int parentType = FID_TYPE(owner->fid);
|
||||
if (parentType == OBJ_TYPE_ITEM) {
|
||||
int itemType = itemGetType(owner);
|
||||
if (itemType == ITEM_TYPE_CONTAINER) {
|
||||
|
@ -205,7 +205,7 @@ int itemAttemptAdd(Object* owner, Object* itemToAdd, int quantity)
|
|||
|
||||
Object* containerOwner = objectGetOwner(owner);
|
||||
if (containerOwner != NULL) {
|
||||
if (((containerOwner->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(containerOwner->fid) == OBJ_TYPE_CRITTER) {
|
||||
int weightToAdd = itemGetWeight(itemToAdd);
|
||||
weightToAdd *= quantity;
|
||||
|
||||
|
@ -473,7 +473,7 @@ int _item_move_all_hidden(Object* a1, Object* a2)
|
|||
for (int j = i; j < inventory->length;) {
|
||||
bool v5;
|
||||
InventoryItem* inventoryItem = &(inventory->items[j]);
|
||||
if (inventoryItem->item->pid >> 24 == OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(inventoryItem->item->pid) == OBJ_TYPE_ITEM) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(inventoryItem->item->pid, &proto) != -1) {
|
||||
v5 = (proto->item.extendedFlags & ItemProtoExtendedFlags_NaturalWeapon) == 0;
|
||||
|
@ -505,7 +505,7 @@ int _item_destroy_all_hidden(Object* a1)
|
|||
for (int j = i; j < inventory->length;) {
|
||||
bool v5;
|
||||
InventoryItem* inventoryItem = &(inventory->items[j]);
|
||||
if (inventoryItem->item->pid >> 24 == OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(inventoryItem->item->pid) == OBJ_TYPE_ITEM) {
|
||||
Proto* proto;
|
||||
if (protoGetProto(inventoryItem->item->pid, &proto) != -1) {
|
||||
v5 = (proto->item.extendedFlags & ItemProtoExtendedFlags_NaturalWeapon) == 0;
|
||||
|
@ -584,9 +584,9 @@ int _item_drop_all(Object* critter, int tile)
|
|||
|
||||
if (hasEquippedItems) {
|
||||
Rect updatedRect;
|
||||
int fid = buildFid(1, frmId, (critter->fid & 0xFF0000) >> 16, 0, (critter->fid & 0x70000000) >> 28);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, frmId, FID_ANIM_TYPE(critter->fid), 0, (critter->fid & 0x70000000) >> 28);
|
||||
objectSetFid(critter, fid, &updatedRect);
|
||||
if (((critter->fid & 0xFF0000) >> 16) == 0) {
|
||||
if (FID_ANIM_TYPE(critter->fid) == ANIM_STAND) {
|
||||
tileWindowRefreshRect(&updatedRect, gElevation);
|
||||
}
|
||||
}
|
||||
|
@ -667,7 +667,7 @@ int itemGetType(Object* item)
|
|||
return ITEM_TYPE_MISC;
|
||||
}
|
||||
|
||||
if ((item->pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(item->pid) != OBJ_TYPE_ITEM) {
|
||||
return ITEM_TYPE_MISC;
|
||||
}
|
||||
|
||||
|
@ -845,7 +845,7 @@ int objectGetCost(Object* obj)
|
|||
}
|
||||
}
|
||||
|
||||
if ((obj->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_CRITTER) {
|
||||
Object* item2 = critterGetItem2(obj);
|
||||
if (item2 != NULL && (item2->flags & OBJECT_IN_RIGHT_HAND) == 0) {
|
||||
cost += itemGetCost(item2);
|
||||
|
@ -883,7 +883,7 @@ int objectGetInventoryWeight(Object* obj)
|
|||
weight += itemGetWeight(item) * inventoryItem->quantity;
|
||||
}
|
||||
|
||||
if (((obj->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_CRITTER) {
|
||||
Object* item2 = critterGetItem2(obj);
|
||||
if (item2 != NULL) {
|
||||
if ((item2->flags & OBJECT_IN_RIGHT_HAND) == 0) {
|
||||
|
@ -1088,7 +1088,7 @@ int weaponIsNatural(Object* obj)
|
|||
{
|
||||
Proto* proto;
|
||||
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_ITEM) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1590,7 +1590,7 @@ int _item_w_range(Object* critter, int hitMode)
|
|||
return range;
|
||||
}
|
||||
|
||||
if (_critter_flag_check(critter->pid, 0x2000)) {
|
||||
if (_critter_flag_check(critter->pid, CRITTER_FLAG_0x2000)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -1942,14 +1942,10 @@ int _item_w_compute_ammo_cost(Object* obj, int* inout_a2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Returns true if weapon's damage is explosion, plasma, or emp.
|
||||
// Probably checks if weapon is granade.
|
||||
//
|
||||
// 0x4790E8
|
||||
bool _item_w_is_grenade(Object* weapon)
|
||||
bool weaponIsGrenade(Object* weapon)
|
||||
{
|
||||
int damageType = weaponGetDamageType(NULL, weapon);
|
||||
|
||||
return damageType == DAMAGE_TYPE_EXPLOSION || damageType == DAMAGE_TYPE_PLASMA || damageType == DAMAGE_TYPE_EMP;
|
||||
}
|
||||
|
||||
|
@ -1968,7 +1964,7 @@ int _item_w_area_damage_radius(Object* weapon, int hitMode)
|
|||
}
|
||||
} else if (attackType == ATTACK_TYPE_THROW) {
|
||||
// NOTE: Uninline.
|
||||
if (_item_w_is_grenade(weapon)) {
|
||||
if (weaponIsGrenade(weapon)) {
|
||||
// NOTE: Uninline.
|
||||
v1 = _item_w_grenade_dmg_radius(weapon);
|
||||
}
|
||||
|
@ -2840,7 +2836,7 @@ int drugEffectEventProcess(Object* obj, void* data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3009,7 +3005,7 @@ int withdrawalEventWrite(File* stream, void* data)
|
|||
// 0x47A4C4
|
||||
static void performWithdrawalStart(Object* obj, int perk, int pid)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
debugPrint("\nERROR: perform_withdrawal_start: Was called on non-critter!");
|
||||
return;
|
||||
}
|
||||
|
@ -3039,7 +3035,7 @@ static void performWithdrawalStart(Object* obj, int perk, int pid)
|
|||
// 0x47A558
|
||||
static void performWithdrawalEnd(Object* obj, int perk)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
debugPrint("\nERROR: perform_withdrawal_end: Was called on non-critter!");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ Object* _item_w_unload(Object* weapon);
|
|||
int weaponGetActionPointCost1(Object* weapon);
|
||||
int weaponGetActionPointCost2(Object* weapon);
|
||||
int _item_w_compute_ammo_cost(Object* obj, int* inout_a2);
|
||||
bool _item_w_is_grenade(Object* weapon);
|
||||
bool weaponIsGrenade(Object* weapon);
|
||||
int _item_w_area_damage_radius(Object* weapon, int hitMode);
|
||||
int _item_w_grenade_dmg_radius(Object* weapon);
|
||||
int _item_w_rocket_dmg_radius(Object* weapon);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "light.h"
|
||||
|
||||
#include "map_defs.h"
|
||||
#include "object.h"
|
||||
#include "perk.h"
|
||||
#include "tile.h"
|
||||
#include "object.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -111,7 +111,7 @@ void lightIncreaseIntensity(int elevation, int tile, int lightIntensity)
|
|||
if (!hexGridTileIsValid(tile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gLightIntensity[elevation][tile] += lightIntensity;
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ void lightDecreaseIntensity(int elevation, int tile, int lightIntensity)
|
|||
if (!hexGridTileIsValid(tile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gLightIntensity[elevation][tile] -= lightIntensity;
|
||||
}
|
||||
|
||||
|
|
|
@ -1227,7 +1227,7 @@ static int lsgWindowInit(int windowType)
|
|||
}
|
||||
|
||||
for (int index = 0; index < LOAD_SAVE_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gLoadSaveFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gLoadSaveFrmIds[index], 0, 0, 0);
|
||||
gLoadSaveFrmData[index] = artLockFrameDataReturningSize(fid,
|
||||
&(gLoadSaveFrmHandles[index]),
|
||||
&(gLoadSaveFrmSizes[index].width),
|
||||
|
|
153
src/main.cc
153
src/main.cc
|
@ -23,13 +23,16 @@
|
|||
#include "options.h"
|
||||
#include "palette.h"
|
||||
#include "platform_compat.h"
|
||||
#include "proto.h"
|
||||
#include "random.h"
|
||||
#include "scripts.h"
|
||||
#include "sfall_config.h"
|
||||
#include "selfrun.h"
|
||||
#include "sfall_config.h"
|
||||
#include "text_font.h"
|
||||
#include "version.h"
|
||||
#include "window.h"
|
||||
#include "window_manager.h"
|
||||
#include "window_manager_private.h"
|
||||
#include "word_wrap.h"
|
||||
#include "world_map.h"
|
||||
|
||||
|
@ -57,7 +60,7 @@ typedef enum MainMenuOption {
|
|||
MAIN_MENU_INTRO,
|
||||
MAIN_MENU_NEW_GAME,
|
||||
MAIN_MENU_LOAD_GAME,
|
||||
MAIN_MENU_3,
|
||||
MAIN_MENU_SCREENSAVER,
|
||||
MAIN_MENU_TIMEOUT,
|
||||
MAIN_MENU_CREDITS,
|
||||
MAIN_MENU_QUOTES,
|
||||
|
@ -70,6 +73,8 @@ static bool falloutInit(int argc, char** argv);
|
|||
static int _main_load_new(char* fname);
|
||||
static void mainLoop(FpsLimiter& fpsLimiter);
|
||||
static void _main_selfrun_exit();
|
||||
static void _main_selfrun_record();
|
||||
static void _main_selfrun_play();
|
||||
static void showDeath();
|
||||
static void _main_death_voiceover_callback();
|
||||
static int _mainDeathGrabTextFile(const char* fileName, char* dest);
|
||||
|
@ -99,6 +104,16 @@ static int _main_selfrun_index = 0;
|
|||
// 0x5194E8
|
||||
static bool _main_show_death_scene = false;
|
||||
|
||||
// A switch to pick selfrun vs. intro video for screensaver:
|
||||
// - `false` - will play next selfrun recording
|
||||
// - `true` - will play intro video
|
||||
//
|
||||
// This value will alternate on every attempt, even if there are no selfrun
|
||||
// recordings.
|
||||
//
|
||||
// 0x5194EC
|
||||
static bool gMainMenuScreensaverCycle = false;
|
||||
|
||||
// 0x5194F0
|
||||
static int gMainMenuWindow = -1;
|
||||
|
||||
|
@ -175,7 +190,7 @@ int falloutMain(int argc, char** argv)
|
|||
// SFALL: Allow to skip intro movies
|
||||
int skipOpeningMovies;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_SKIP_OPENING_MOVIES_KEY, &skipOpeningMovies);
|
||||
if(skipOpeningMovies < 1) {
|
||||
if (skipOpeningMovies < 1) {
|
||||
gameMoviePlay(MOVIE_IPLOGO, GAME_MOVIE_FADE_IN);
|
||||
gameMoviePlay(MOVIE_INTRO, 0);
|
||||
gameMoviePlay(MOVIE_CREDITS, 0);
|
||||
|
@ -207,7 +222,7 @@ int falloutMain(int argc, char** argv)
|
|||
gameMoviePlay(MOVIE_ELDER, GAME_MOVIE_STOP_MUSIC);
|
||||
randomSeedPrerandom(-1);
|
||||
|
||||
// SFALL: Override starting map.
|
||||
// SFALL: Override starting map.
|
||||
char* mapName = NULL;
|
||||
if (configGetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_STARTING_MAP_KEY, &mapName)) {
|
||||
if (*mapName == '\0') {
|
||||
|
@ -273,8 +288,8 @@ int falloutMain(int argc, char** argv)
|
|||
case MAIN_MENU_TIMEOUT:
|
||||
debugPrint("Main menu timed-out\n");
|
||||
// FALLTHROUGH
|
||||
case MAIN_MENU_3:
|
||||
// _main_selfrun_play();
|
||||
case MAIN_MENU_SCREENSAVER:
|
||||
_main_selfrun_play();
|
||||
break;
|
||||
case MAIN_MENU_OPTIONS:
|
||||
mainMenuWindowHide(false);
|
||||
|
@ -303,7 +318,7 @@ int falloutMain(int argc, char** argv)
|
|||
backgroundSoundDelete();
|
||||
break;
|
||||
case MAIN_MENU_SELFRUN:
|
||||
// _main_selfrun_record();
|
||||
_main_selfrun_record();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -329,7 +344,7 @@ static bool falloutInit(int argc, char** argv)
|
|||
_main_selfrun_exit();
|
||||
}
|
||||
|
||||
if (_selfrun_get_list(&_main_selfrun_list, &_main_selfrun_count) == 0) {
|
||||
if (selfrunInitFileList(&_main_selfrun_list, &_main_selfrun_count) == 0) {
|
||||
_main_selfrun_index = 0;
|
||||
}
|
||||
|
||||
|
@ -408,7 +423,7 @@ static void mainLoop(FpsLimiter& fpsLimiter)
|
|||
static void _main_selfrun_exit()
|
||||
{
|
||||
if (_main_selfrun_list != NULL) {
|
||||
_selfrun_free_list(&_main_selfrun_list);
|
||||
selfrunFreeFileList(&_main_selfrun_list);
|
||||
}
|
||||
|
||||
_main_selfrun_count = 0;
|
||||
|
@ -416,6 +431,89 @@ static void _main_selfrun_exit()
|
|||
_main_selfrun_list = NULL;
|
||||
}
|
||||
|
||||
// 0x480F64
|
||||
static void _main_selfrun_record()
|
||||
{
|
||||
SelfrunData selfrunData;
|
||||
bool ready = false;
|
||||
|
||||
char** fileList;
|
||||
int fileListLength = fileNameListInit("maps\\*.map", &fileList, 0, 0);
|
||||
if (fileListLength != 0) {
|
||||
int selectedFileIndex = _win_list_select("Select Map", fileList, fileListLength, 0, 80, 80, 0x10000 | 0x100 | 4);
|
||||
if (selectedFileIndex != -1) {
|
||||
// NOTE: It's size is likely 13 chars (on par with SelfrunData
|
||||
// fields), but due to the padding it takes 16 chars on stack.
|
||||
char recordingName[SELFRUN_RECORDING_FILE_NAME_LENGTH];
|
||||
recordingName[0] = '\0';
|
||||
if (_win_get_str(recordingName, sizeof(recordingName) - 2, "Enter name for recording (8 characters max, no extension):", 100, 100) == 0) {
|
||||
memset(&selfrunData, 0, sizeof(selfrunData));
|
||||
if (selfrunPrepareRecording(recordingName, fileList[selectedFileIndex], &selfrunData) == 0) {
|
||||
ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
fileNameListFree(&fileList, 0);
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
mainMenuWindowHide(true);
|
||||
mainMenuWindowFree();
|
||||
backgroundSoundDelete();
|
||||
randomSeedPrerandom(0xBEEFFEED);
|
||||
gameReset();
|
||||
_proto_dude_init("premade\\combat.gcd");
|
||||
_main_load_new(selfrunData.mapFileName);
|
||||
selfrunRecordingLoop(&selfrunData);
|
||||
paletteFadeTo(gPaletteWhite);
|
||||
objectHide(gDude, NULL);
|
||||
_map_exit();
|
||||
gameReset();
|
||||
mainMenuWindowInit();
|
||||
|
||||
if (_main_selfrun_list != NULL) {
|
||||
_main_selfrun_exit();
|
||||
}
|
||||
|
||||
if (selfrunInitFileList(&_main_selfrun_list, &_main_selfrun_count) == 0) {
|
||||
_main_selfrun_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x48109C
|
||||
static void _main_selfrun_play()
|
||||
{
|
||||
if (!gMainMenuScreensaverCycle && _main_selfrun_count > 0) {
|
||||
SelfrunData selfrunData;
|
||||
if (selfrunPreparePlayback(_main_selfrun_list[_main_selfrun_index], &selfrunData) == 0) {
|
||||
mainMenuWindowHide(true);
|
||||
mainMenuWindowFree();
|
||||
backgroundSoundDelete();
|
||||
randomSeedPrerandom(0xBEEFFEED);
|
||||
gameReset();
|
||||
_proto_dude_init("premade\\combat.gcd");
|
||||
_main_load_new(selfrunData.mapFileName);
|
||||
selfrunPlaybackLoop(&selfrunData);
|
||||
paletteFadeTo(gPaletteWhite);
|
||||
objectHide(gDude, NULL);
|
||||
_map_exit();
|
||||
gameReset();
|
||||
mainMenuWindowInit();
|
||||
}
|
||||
|
||||
_main_selfrun_index++;
|
||||
if (_main_selfrun_index >= _main_selfrun_count) {
|
||||
_main_selfrun_index = 0;
|
||||
}
|
||||
} else {
|
||||
mainMenuWindowHide(true);
|
||||
gameMoviePlay(MOVIE_INTRO, GAME_MOVIE_PAUSE_MUSIC);
|
||||
}
|
||||
|
||||
gMainMenuScreensaverCycle = !gMainMenuScreensaverCycle;
|
||||
}
|
||||
|
||||
// 0x48118C
|
||||
static void showDeath()
|
||||
{
|
||||
|
@ -445,7 +543,7 @@ static void showDeath()
|
|||
|
||||
// DEATH.FRM
|
||||
CacheEntry* backgroundHandle;
|
||||
int fid = buildFid(6, 309, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 309, 0, 0, 0);
|
||||
unsigned char* background = artLockFrameData(fid, 0, 0, &backgroundHandle);
|
||||
if (background == NULL) {
|
||||
break;
|
||||
|
@ -591,32 +689,17 @@ static int _mainDeathGrabTextFile(const char* fileName, char* dest)
|
|||
// 0x481598
|
||||
static int _mainDeathWordWrap(char* text, int width, short* beginnings, short* count)
|
||||
{
|
||||
// TODO: Probably wrong.
|
||||
while (true) {
|
||||
char* p = text;
|
||||
while (*p != ':') {
|
||||
if (*p != '\0') {
|
||||
p++;
|
||||
if (*p == ':') {
|
||||
break;
|
||||
}
|
||||
if (*p != '\0') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
p = NULL;
|
||||
char* sep = strchr(text, ':');
|
||||
if (sep == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
if (sep - 1 < text) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p - 1 < text) {
|
||||
break;
|
||||
}
|
||||
p[0] = ' ';
|
||||
p[-1] = ' ';
|
||||
sep[0] = ' ';
|
||||
sep[-1] = ' ';
|
||||
}
|
||||
|
||||
if (wordWrap(text, width, beginnings, count) == -1) {
|
||||
|
@ -671,7 +754,7 @@ static int mainMenuWindowInit()
|
|||
gMainMenuWindowBuffer = windowGetBuffer(gMainMenuWindow);
|
||||
|
||||
// mainmenu.frm
|
||||
int backgroundFid = buildFid(6, 140, 0, 0, 0);
|
||||
int backgroundFid = buildFid(OBJ_TYPE_INTERFACE, 140, 0, 0, 0);
|
||||
gMainMenuBackgroundFrmData = artLockFrameData(backgroundFid, 0, 0, &gMainMenuBackgroundFrmHandle);
|
||||
if (gMainMenuBackgroundFrmData == NULL) {
|
||||
mainMenuWindowFree();
|
||||
|
@ -692,7 +775,7 @@ static int mainMenuWindowInit()
|
|||
int fontSettings = _colorTable[21091], fontSettingsSFall = 0;
|
||||
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_MAIN_MENU_FONT_COLOR_KEY, &fontSettingsSFall);
|
||||
if (fontSettingsSFall && !(fontSettingsSFall & 0x010000))
|
||||
fontSettings = fontSettingsSFall & 0xFF;
|
||||
fontSettings = fontSettingsSFall & 0xFF;
|
||||
|
||||
// SFALL: Allow to move copyright text
|
||||
int offsetX = 0, offsetY = 0;
|
||||
|
@ -717,7 +800,7 @@ static int mainMenuWindowInit()
|
|||
windowDrawText(gMainMenuWindow, version, 0, 615 - len, 460, fontSettings | 0x06000000);
|
||||
|
||||
// menuup.frm
|
||||
fid = buildFid(6, 299, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 299, 0, 0, 0);
|
||||
gMainMenuButtonUpFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonUpFrmHandle);
|
||||
if (gMainMenuButtonUpFrmData == NULL) {
|
||||
mainMenuWindowFree();
|
||||
|
@ -725,7 +808,7 @@ static int mainMenuWindowInit()
|
|||
}
|
||||
|
||||
// menudown.frm
|
||||
fid = buildFid(6, 300, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 300, 0, 0, 0);
|
||||
gMainMenuButtonDownFrmData = artLockFrameData(fid, 0, 0, &gMainMenuButtonDownFrmHandle);
|
||||
if (gMainMenuButtonDownFrmData == NULL) {
|
||||
mainMenuWindowFree();
|
||||
|
@ -900,7 +983,7 @@ static int mainMenuWindowHandleEvents(FpsLimiter& fpsLimiter)
|
|||
} else if (keyCode == KEY_MINUS || keyCode == KEY_UNDERSCORE) {
|
||||
brightnessDecrease();
|
||||
} else if (keyCode == KEY_UPPERCASE_D || keyCode == KEY_LOWERCASE_D) {
|
||||
rc = MAIN_MENU_3;
|
||||
rc = MAIN_MENU_SCREENSAVER;
|
||||
continue;
|
||||
} else if (keyCode == 1111) {
|
||||
if (!(mouseGetEvent() & MOUSE_EVENT_LEFT_BUTTON_REPEAT)) {
|
||||
|
|
83
src/map.cc
83
src/map.cc
|
@ -33,6 +33,7 @@
|
|||
#include "text_object.h"
|
||||
#include "tile.h"
|
||||
#include "window_manager.h"
|
||||
#include "window_manager_private.h"
|
||||
#include "world_map.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -922,7 +923,7 @@ static int mapLoad(File* stream)
|
|||
}
|
||||
|
||||
Object* object;
|
||||
int fid = buildFid(5, 12, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_MISC, 12, 0, 0, 0);
|
||||
objectCreateWithFidPid(&object, fid, -1);
|
||||
object->flags |= (OBJECT_LIGHT_THRU | OBJECT_TEMPORARY | OBJECT_HIDDEN);
|
||||
objectSetLocation(object, 1, 0, NULL);
|
||||
|
@ -1027,8 +1028,8 @@ int mapLoadSaved(char* fileName)
|
|||
|
||||
int rc = mapLoadByName(mapName);
|
||||
|
||||
if (gameTimeGetTime() >= gMapHeader.field_38) {
|
||||
if (((gameTimeGetTime() - gMapHeader.field_38) / 36000) >= 24) {
|
||||
if (gameTimeGetTime() >= gMapHeader.lastVisitTime) {
|
||||
if (((gameTimeGetTime() - gMapHeader.lastVisitTime) / GAME_TIME_TICKS_PER_HOUR) >= 24) {
|
||||
objectUnjamAll();
|
||||
}
|
||||
|
||||
|
@ -1061,37 +1062,31 @@ static int _map_age_dead_critters()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int v4 = (gameTimeGetTime() - gMapHeader.field_38) / 36000;
|
||||
if (v4 == 0) {
|
||||
int hoursSinceLastVisit = (gameTimeGetTime() - gMapHeader.lastVisitTime) / GAME_TIME_TICKS_PER_HOUR;
|
||||
if (hoursSinceLastVisit == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Object* obj = objectFindFirst();
|
||||
while (obj != NULL) {
|
||||
if (obj->pid >> 24 == OBJ_TYPE_CRITTER
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER
|
||||
&& obj != gDude
|
||||
&& !objectIsPartyMember(obj)
|
||||
&& !critterIsDead(obj)) {
|
||||
obj->data.critter.combat.maneuver &= 0x04;
|
||||
if (critterGetKillType(obj) != KILL_TYPE_ROBOT && _critter_flag_check(obj->pid, 512) == 0) {
|
||||
_critter_heal_hours(obj, v4);
|
||||
obj->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
|
||||
if (critterGetKillType(obj) != KILL_TYPE_ROBOT && _critter_flag_check(obj->pid, CRITTER_FLAG_0x200) == 0) {
|
||||
_critter_heal_hours(obj, hoursSinceLastVisit);
|
||||
}
|
||||
}
|
||||
obj = objectFindNext();
|
||||
}
|
||||
|
||||
int v20;
|
||||
if (v4 <= 336) {
|
||||
if (v4 > 144) {
|
||||
v20 = 1;
|
||||
} else {
|
||||
v20 = 0;
|
||||
}
|
||||
int agingType;
|
||||
if (hoursSinceLastVisit > 6 * 24) {
|
||||
agingType = 1;
|
||||
} else if (hoursSinceLastVisit > 14 * 24) {
|
||||
agingType = 2;
|
||||
} else {
|
||||
v20 = 2;
|
||||
}
|
||||
|
||||
if (v20 == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1101,10 +1096,10 @@ static int _map_age_dead_critters()
|
|||
|
||||
obj = objectFindFirst();
|
||||
while (obj != NULL) {
|
||||
int type = obj->pid >> 24;
|
||||
int type = PID_TYPE(obj->pid);
|
||||
if (type == OBJ_TYPE_CRITTER) {
|
||||
if (obj != gDude && critterIsDead(obj)) {
|
||||
if (critterGetKillType(obj) != KILL_TYPE_ROBOT && _critter_flag_check(obj->pid, 512) == 0) {
|
||||
if (critterGetKillType(obj) != KILL_TYPE_ROBOT && _critter_flag_check(obj->pid, CRITTER_FLAG_0x200) == 0) {
|
||||
objects[count++] = obj;
|
||||
|
||||
if (count >= capacity) {
|
||||
|
@ -1117,7 +1112,7 @@ static int _map_age_dead_critters()
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (v20 == 2 && type == OBJ_TYPE_MISC && obj->pid == 0x500000B) {
|
||||
} else if (agingType == 2 && type == OBJ_TYPE_MISC && obj->pid == 0x500000B) {
|
||||
objects[count++] = obj;
|
||||
if (count >= capacity) {
|
||||
capacity *= 2;
|
||||
|
@ -1134,18 +1129,18 @@ static int _map_age_dead_critters()
|
|||
int rc = 0;
|
||||
for (int index = 0; index < count; index++) {
|
||||
Object* obj = objects[index];
|
||||
if (obj->pid >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (_critter_flag_check(obj->pid, 64) == 0) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (_critter_flag_check(obj->pid, CRITTER_FLAG_0x40) == 0) {
|
||||
_item_drop_all(obj, obj->tile);
|
||||
}
|
||||
|
||||
Object* a1;
|
||||
if (objectCreateWithPid(&a1, 0x5000004) == -1) {
|
||||
Object* blood;
|
||||
if (objectCreateWithPid(&blood, 0x5000004) == -1) {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
objectSetLocation(a1, obj->tile, obj->elevation, NULL);
|
||||
objectSetLocation(blood, obj->tile, obj->elevation, NULL);
|
||||
|
||||
Proto* proto;
|
||||
protoGetProto(obj->pid, &proto);
|
||||
|
@ -1160,7 +1155,7 @@ static int _map_age_dead_critters()
|
|||
}
|
||||
}
|
||||
|
||||
objectSetFrame(a1, frame, NULL);
|
||||
objectSetFrame(blood, frame, NULL);
|
||||
}
|
||||
|
||||
reg_anim_clear(obj);
|
||||
|
@ -1264,7 +1259,7 @@ static void _map_fix_critter_combat_data()
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1327,13 +1322,13 @@ static int _map_save_file(File* stream)
|
|||
for (tile = 0; tile < SQUARE_GRID_SIZE; tile++) {
|
||||
int fid;
|
||||
|
||||
fid = buildFid(4, _square[elevation]->field_0[tile] & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(4, 1, 0, 0, 0)) {
|
||||
fid = buildFid(OBJ_TYPE_TILE, _square[elevation]->field_0[tile] & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
fid = buildFid(4, (_square[elevation]->field_0[tile] >> 16) & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(4, 1, 0, 0, 0)) {
|
||||
fid = buildFid(OBJ_TYPE_TILE, (_square[elevation]->field_0[tile] >> 16) & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1383,14 +1378,12 @@ static int _map_save_file(File* stream)
|
|||
|
||||
if (scriptSaveAll(stream) == -1) {
|
||||
sprintf(err, "Error saving scripts in %s", gMapHeader.name);
|
||||
// TODO: Incomplete.
|
||||
// _win_msg(err, 80, 80, _colorTable[31744]);
|
||||
_win_msg(err, 80, 80, _colorTable[31744]);
|
||||
}
|
||||
|
||||
if (objectSaveAll(stream) == -1) {
|
||||
sprintf(err, "Error saving objects in %s", gMapHeader.name);
|
||||
// TODO: Incomplete.
|
||||
// _win_msg(err, 80, 80, _colorTable[31744]);
|
||||
_win_msg(err, 80, 80, _colorTable[31744]);
|
||||
}
|
||||
|
||||
scriptsEnable();
|
||||
|
@ -1424,7 +1417,7 @@ int _map_save_in_game(bool a1)
|
|||
}
|
||||
|
||||
gMapHeader.flags |= 0x01;
|
||||
gMapHeader.field_38 = gameTimeGetTime();
|
||||
gMapHeader.lastVisitTime = gameTimeGetTime();
|
||||
|
||||
char name[16];
|
||||
|
||||
|
@ -1545,9 +1538,9 @@ static void _map_place_dude_and_mouse()
|
|||
_obj_clear_seen();
|
||||
|
||||
if (gDude != NULL) {
|
||||
if (((gDude->fid & 0xFF0000) >> 16) != 0) {
|
||||
if (FID_ANIM_TYPE(gDude->fid) != ANIM_STAND) {
|
||||
objectSetFrame(gDude, 0, 0);
|
||||
gDude->fid = buildFid(1, gDude->fid & 0xFFF, ANIM_STAND, (gDude->fid & 0xF000) >> 12, gDude->rotation + 1);
|
||||
gDude->fid = buildFid(OBJ_TYPE_CRITTER, gDude->fid & 0xFFF, ANIM_STAND, (gDude->fid & 0xF000) >> 12, gDude->rotation + 1);
|
||||
}
|
||||
|
||||
if (gDude->tile == -1) {
|
||||
|
@ -1577,11 +1570,11 @@ static void _square_reset()
|
|||
// check subsequent calls.
|
||||
int fid = *p;
|
||||
fid &= ~0xFFFF;
|
||||
*p = ((buildFid(4, 1, 0, 0, 0) & 0xFFF | (((fid >> 16) & 0xF000) >> 12)) << 16) | (fid & 0xFFFF);
|
||||
*p = ((buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0) & 0xFFF | (((fid >> 16) & 0xF000) >> 12)) << 16) | (fid & 0xFFFF);
|
||||
|
||||
fid = *p;
|
||||
int v3 = (fid & 0xF000) >> 12;
|
||||
int v4 = (buildFid(4, 1, 0, 0, 0) & 0xFFF) | v3;
|
||||
int v4 = (buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0) & 0xFFF) | v3;
|
||||
|
||||
fid &= ~0xFFFF;
|
||||
|
||||
|
@ -1642,7 +1635,7 @@ static int mapHeaderWrite(MapHeader* ptr, File* stream)
|
|||
if (fileWriteInt32(stream, ptr->darkness) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->globalVariablesCount) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_34) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->field_38) == -1) return -1;
|
||||
if (fileWriteInt32(stream, ptr->lastVisitTime) == -1) return -1;
|
||||
if (fileWriteInt32List(stream, ptr->field_3C, 44) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
|
@ -1662,7 +1655,7 @@ static int mapHeaderRead(MapHeader* ptr, File* stream)
|
|||
if (fileReadInt32(stream, &(ptr->darkness)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->globalVariablesCount)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->field_34)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->field_38)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(ptr->lastVisitTime)) == -1) return -1;
|
||||
if (fileReadInt32List(stream, ptr->field_3C, 44) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -49,7 +49,9 @@ typedef struct MapHeader {
|
|||
|
||||
// map_number
|
||||
int field_34;
|
||||
int field_38;
|
||||
|
||||
// Time in game ticks when PC last visited this map.
|
||||
int lastVisitTime;
|
||||
int field_3C[44];
|
||||
} MapHeader;
|
||||
|
||||
|
|
|
@ -1,57 +1,641 @@
|
|||
#include "mouse_manager.h"
|
||||
|
||||
#include "core.h"
|
||||
#include "datafile.h"
|
||||
#include "db.h"
|
||||
#include "debug.h"
|
||||
#include "memory_manager.h"
|
||||
#include "platform_compat.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// 0x5195A8
|
||||
char* (*_mouseNameMangler)(char*) = _defaultNameMangler;
|
||||
MouseManagerNameMangler* gMouseManagerNameMangler = mouseManagerNameManglerDefaultImpl;
|
||||
|
||||
// 0x5195AC
|
||||
int (*_rateCallback)() = _defaultRateCallback;
|
||||
MouseManagerRateProvider* gMouseManagerRateProvider = mouseManagerRateProviderDefaultImpl;
|
||||
|
||||
// 0x5195B0
|
||||
int (*_currentTimeCallback)() = _defaultTimeCallback;
|
||||
MouseManagerTimeProvider* gMouseManagerTimeProvider = mouseManagerTimeProviderDefaultImpl;
|
||||
|
||||
// 0x5195B4
|
||||
int _curref = 1;
|
||||
int gMouseManagerCurrentRef = 1;
|
||||
|
||||
// 0x63247C
|
||||
MouseManagerCacheEntry gMouseManagerCache[MOUSE_MGR_CACHE_CAPACITY];
|
||||
|
||||
// 0x638DFC
|
||||
bool gMouseManagerIsAnimating;
|
||||
|
||||
// 0x638E00
|
||||
unsigned char* gMouseManagerCurrentPalette;
|
||||
|
||||
// 0x638E04
|
||||
MouseManagerAnimatedData* gMouseManagerCurrentAnimatedData;
|
||||
|
||||
// 0x638E08
|
||||
unsigned char* gMouseManagerCurrentStaticData;
|
||||
|
||||
// 0x638E0C
|
||||
int gMouseManagerCurrentCacheEntryIndex;
|
||||
|
||||
// 0x485250
|
||||
char* _defaultNameMangler(char* a1)
|
||||
char* mouseManagerNameManglerDefaultImpl(char* a1)
|
||||
{
|
||||
return a1;
|
||||
}
|
||||
|
||||
// 0x485254
|
||||
int _defaultRateCallback()
|
||||
int mouseManagerRateProviderDefaultImpl()
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
// 0x48525C
|
||||
int _defaultTimeCallback()
|
||||
int mouseManagerTimeProviderDefaultImpl()
|
||||
{
|
||||
return _get_time();
|
||||
}
|
||||
|
||||
// 0x485288
|
||||
void _mousemgrSetNameMangler(char* (*func)(char*))
|
||||
void mouseManagerSetNameMangler(MouseManagerNameMangler* func)
|
||||
{
|
||||
_mouseNameMangler = func;
|
||||
gMouseManagerNameMangler = func;
|
||||
}
|
||||
|
||||
// 0x4852B8
|
||||
void mouseManagerFreeCacheEntry(MouseManagerCacheEntry* entry)
|
||||
{
|
||||
switch (entry->type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
if (entry->staticData != NULL) {
|
||||
if (entry->staticData->data != NULL) {
|
||||
internal_free_safe(entry->staticData->data, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 120
|
||||
entry->staticData->data = NULL;
|
||||
}
|
||||
internal_free_safe(entry->staticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 123
|
||||
entry->staticData = NULL;
|
||||
}
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
if (entry->animatedData != NULL) {
|
||||
if (entry->animatedData->field_0 != NULL) {
|
||||
for (int index = 0; index < entry->animatedData->frameCount; index++) {
|
||||
internal_free_safe(entry->animatedData->field_0[index], __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 134
|
||||
internal_free_safe(entry->animatedData->field_4[index], __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 135
|
||||
}
|
||||
internal_free_safe(entry->animatedData->field_0, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 137
|
||||
internal_free_safe(entry->animatedData->field_4, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 138
|
||||
internal_free_safe(entry->animatedData->field_8, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 139
|
||||
internal_free_safe(entry->animatedData->field_C, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 140
|
||||
}
|
||||
internal_free_safe(entry->animatedData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 143
|
||||
entry->animatedData = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
entry->type = 0;
|
||||
entry->fileName[0] = '\0';
|
||||
}
|
||||
|
||||
// 0x4853F8
|
||||
int mouseManagerInsertCacheEntry(void** data, int type, unsigned char* palette, const char* fileName)
|
||||
{
|
||||
int foundIndex = -1;
|
||||
int index;
|
||||
for (index = 0; index < MOUSE_MGR_CACHE_CAPACITY; index++) {
|
||||
MouseManagerCacheEntry* cacheEntry = &(gMouseManagerCache[index]);
|
||||
if (cacheEntry->type == MOUSE_MANAGER_MOUSE_TYPE_NONE && foundIndex == -1) {
|
||||
foundIndex = index;
|
||||
}
|
||||
|
||||
if (compat_stricmp(fileName, cacheEntry->fileName) == 0) {
|
||||
mouseManagerFreeCacheEntry(cacheEntry);
|
||||
foundIndex = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundIndex != -1) {
|
||||
index = foundIndex;
|
||||
}
|
||||
|
||||
if (index == MOUSE_MGR_CACHE_CAPACITY) {
|
||||
int v2 = -1;
|
||||
int v1 = gMouseManagerCurrentRef;
|
||||
for (int index = 0; index < MOUSE_MGR_CACHE_CAPACITY; index++) {
|
||||
MouseManagerCacheEntry* cacheEntry = &(gMouseManagerCache[index]);
|
||||
if (v1 > cacheEntry->ref) {
|
||||
v1 = cacheEntry->ref;
|
||||
v2 = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (v2 == -1) {
|
||||
debugPrint("Mouse cache overflow!!!!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
index = v2;
|
||||
mouseManagerFreeCacheEntry(&(gMouseManagerCache[index]));
|
||||
}
|
||||
|
||||
MouseManagerCacheEntry* cacheEntry = &(gMouseManagerCache[index]);
|
||||
cacheEntry->type = type;
|
||||
memcpy(cacheEntry->palette, palette, sizeof(cacheEntry->palette));
|
||||
cacheEntry->ref = gMouseManagerCurrentRef++;
|
||||
strncpy(cacheEntry->fileName, fileName, sizeof(cacheEntry->fileName) - 1);
|
||||
cacheEntry->field_32C[0] = '\0';
|
||||
cacheEntry->data = *data;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
// NOTE: Inlined.
|
||||
//
|
||||
// 0x4853D4
|
||||
void mouseManagerFlushCache()
|
||||
{
|
||||
for (int index = 0; index < MOUSE_MGR_CACHE_CAPACITY; index++) {
|
||||
mouseManagerFreeCacheEntry(&(gMouseManagerCache[index]));
|
||||
}
|
||||
}
|
||||
|
||||
// 0x48554C
|
||||
MouseManagerCacheEntry* mouseManagerFindCacheEntry(const char* fileName, unsigned char** palettePtr, int* a3, int* a4, int* widthPtr, int* heightPtr, int* typePtr)
|
||||
{
|
||||
for (int index = 0; index < MOUSE_MGR_CACHE_CAPACITY; index++) {
|
||||
MouseManagerCacheEntry* cacheEntry = &(gMouseManagerCache[index]);
|
||||
if (compat_strnicmp(cacheEntry->fileName, fileName, 31) == 0 || compat_strnicmp(cacheEntry->field_32C, fileName, 31) == 0) {
|
||||
*palettePtr = cacheEntry->palette;
|
||||
*typePtr = cacheEntry->type;
|
||||
|
||||
gMouseManagerCurrentCacheEntryIndex = index;
|
||||
|
||||
switch (cacheEntry->type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
*a3 = cacheEntry->staticData->field_4;
|
||||
*a4 = cacheEntry->staticData->field_8;
|
||||
*widthPtr = cacheEntry->staticData->width;
|
||||
*heightPtr = cacheEntry->staticData->height;
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
*widthPtr = cacheEntry->animatedData->width;
|
||||
*heightPtr = cacheEntry->animatedData->height;
|
||||
*a3 = cacheEntry->animatedData->field_8[cacheEntry->animatedData->field_26];
|
||||
*a4 = cacheEntry->animatedData->field_C[cacheEntry->animatedData->field_26];
|
||||
break;
|
||||
}
|
||||
|
||||
return cacheEntry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 0x48568C
|
||||
void _initMousemgr()
|
||||
void mouseManagerInit()
|
||||
{
|
||||
mouseSetSensitivity(1.0);
|
||||
}
|
||||
|
||||
// 0x48569C
|
||||
void mouseManagerExit()
|
||||
{
|
||||
mouseSetFrame(NULL, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 243
|
||||
gMouseManagerCurrentStaticData = NULL;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
mouseManagerFlushCache();
|
||||
|
||||
gMouseManagerCurrentPalette = NULL;
|
||||
gMouseManagerCurrentAnimatedData = 0;
|
||||
}
|
||||
|
||||
// 0x485704
|
||||
void mouseManagerUpdate()
|
||||
{
|
||||
if (!gMouseManagerIsAnimating) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gMouseManagerCurrentAnimatedData == NULL) {
|
||||
debugPrint("Animating == 1 but curAnim == 0\n");
|
||||
}
|
||||
|
||||
if (gMouseManagerTimeProvider() >= gMouseManagerCurrentAnimatedData->field_1C) {
|
||||
gMouseManagerCurrentAnimatedData->field_1C = (int)(gMouseManagerCurrentAnimatedData->field_18 / gMouseManagerCurrentAnimatedData->frameCount * gMouseManagerRateProvider() + gMouseManagerTimeProvider());
|
||||
if (gMouseManagerCurrentAnimatedData->field_24 != gMouseManagerCurrentAnimatedData->field_26) {
|
||||
int v1 = gMouseManagerCurrentAnimatedData->field_26 + gMouseManagerCurrentAnimatedData->field_20;
|
||||
if (v1 < 0) {
|
||||
v1 = gMouseManagerCurrentAnimatedData->frameCount - 1;
|
||||
} else if (v1 >= gMouseManagerCurrentAnimatedData->frameCount) {
|
||||
v1 = 0;
|
||||
}
|
||||
|
||||
gMouseManagerCurrentAnimatedData->field_26 = v1;
|
||||
memcpy(gMouseManagerCurrentAnimatedData->field_0[gMouseManagerCurrentAnimatedData->field_26],
|
||||
gMouseManagerCurrentAnimatedData->field_4[gMouseManagerCurrentAnimatedData->field_26],
|
||||
gMouseManagerCurrentAnimatedData->width * gMouseManagerCurrentAnimatedData->height);
|
||||
|
||||
sub_42EE84(gMouseManagerCurrentAnimatedData->field_0[gMouseManagerCurrentAnimatedData->field_26],
|
||||
gMouseManagerCurrentPalette,
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->height);
|
||||
|
||||
mouseSetFrame(gMouseManagerCurrentAnimatedData->field_0[v1],
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->height,
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->field_8[v1],
|
||||
gMouseManagerCurrentAnimatedData->field_C[v1],
|
||||
0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x485868
|
||||
int mouseManagerSetFrame(char* fileName, int a2)
|
||||
{
|
||||
char* mangledFileName = gMouseManagerNameMangler(fileName);
|
||||
|
||||
unsigned char* palette;
|
||||
int temp;
|
||||
int type;
|
||||
MouseManagerCacheEntry* cacheEntry = mouseManagerFindCacheEntry(fileName, &palette, &temp, &temp, &temp, &temp, &type);
|
||||
if (cacheEntry != NULL) {
|
||||
if (type == MOUSE_MANAGER_MOUSE_TYPE_ANIMATED) {
|
||||
cacheEntry->animatedData->field_24 = a2;
|
||||
if (cacheEntry->animatedData->field_24 >= cacheEntry->animatedData->field_26) {
|
||||
int v1 = cacheEntry->animatedData->field_24 - cacheEntry->animatedData->field_26;
|
||||
int v2 = cacheEntry->animatedData->frameCount + cacheEntry->animatedData->field_26 - cacheEntry->animatedData->field_24;
|
||||
if (v1 >= v2) {
|
||||
cacheEntry->animatedData->field_20 = -1;
|
||||
} else {
|
||||
cacheEntry->animatedData->field_20 = 1;
|
||||
}
|
||||
} else {
|
||||
int v1 = cacheEntry->animatedData->field_26 - cacheEntry->animatedData->field_24;
|
||||
int v2 = cacheEntry->animatedData->frameCount + cacheEntry->animatedData->field_24 - cacheEntry->animatedData->field_26;
|
||||
if (v1 < v2) {
|
||||
cacheEntry->animatedData->field_20 = -1;
|
||||
} else {
|
||||
cacheEntry->animatedData->field_20 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gMouseManagerIsAnimating || gMouseManagerCurrentAnimatedData != cacheEntry->animatedData) {
|
||||
memcpy(cacheEntry->animatedData->field_0[cacheEntry->animatedData->field_26],
|
||||
cacheEntry->animatedData->field_4[cacheEntry->animatedData->field_26],
|
||||
cacheEntry->animatedData->width * cacheEntry->animatedData->height);
|
||||
|
||||
mouseSetFrame(cacheEntry->animatedData->field_0[cacheEntry->animatedData->field_26],
|
||||
cacheEntry->animatedData->width,
|
||||
cacheEntry->animatedData->height,
|
||||
cacheEntry->animatedData->width,
|
||||
cacheEntry->animatedData->field_8[cacheEntry->animatedData->field_26],
|
||||
cacheEntry->animatedData->field_C[cacheEntry->animatedData->field_26],
|
||||
0);
|
||||
|
||||
gMouseManagerIsAnimating = true;
|
||||
}
|
||||
|
||||
gMouseManagerCurrentAnimatedData = cacheEntry->animatedData;
|
||||
gMouseManagerCurrentPalette = palette;
|
||||
gMouseManagerCurrentAnimatedData->field_1C = gMouseManagerTimeProvider();
|
||||
return true;
|
||||
}
|
||||
|
||||
mouseManagerSetMousePointer(fileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gMouseManagerIsAnimating) {
|
||||
gMouseManagerCurrentPalette = 0;
|
||||
gMouseManagerIsAnimating = 0;
|
||||
gMouseManagerCurrentAnimatedData = 0;
|
||||
} else {
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 337
|
||||
gMouseManagerCurrentStaticData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
File* stream = fileOpen(mangledFileName, "r");
|
||||
if (stream == NULL) {
|
||||
debugPrint("mouseSetFrame: couldn't find %s\n", mangledFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
char string[80];
|
||||
fileReadString(string, sizeof(string), stream);
|
||||
if (compat_strnicmp(string, "anim", 4) != 0) {
|
||||
fileClose(stream);
|
||||
mouseManagerSetMousePointer(fileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
char* sep = strchr(string, ' ');
|
||||
if (sep == NULL) {
|
||||
// FIXME: Leaks stream.
|
||||
return false;
|
||||
}
|
||||
|
||||
int v3;
|
||||
float v4;
|
||||
sscanf(sep + 1, "%d %f", &v3, &v4);
|
||||
|
||||
MouseManagerAnimatedData* animatedData = (MouseManagerAnimatedData*)internal_malloc_safe(sizeof(*animatedData), __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 359
|
||||
animatedData->field_0 = (unsigned char**)internal_malloc_safe(sizeof(*animatedData->field_0) * v3, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 360
|
||||
animatedData->field_4 = (unsigned char**)internal_malloc_safe(sizeof(*animatedData->field_4) * v3, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 361
|
||||
animatedData->field_8 = (int*)internal_malloc_safe(sizeof(*animatedData->field_8) * v3, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 362
|
||||
animatedData->field_C = (int*)internal_malloc_safe(sizeof(*animatedData->field_8) * v3, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 363
|
||||
animatedData->field_18 = v4;
|
||||
animatedData->field_1C = gMouseManagerTimeProvider();
|
||||
animatedData->field_26 = 0;
|
||||
animatedData->field_24 = a2;
|
||||
animatedData->frameCount = v3;
|
||||
if (animatedData->frameCount / 2 <= a2) {
|
||||
animatedData->field_20 = -1;
|
||||
} else {
|
||||
animatedData->field_20 = 1;
|
||||
}
|
||||
|
||||
int width;
|
||||
int height;
|
||||
for (int index = 0; index < v3; index++) {
|
||||
string[0] = '\0';
|
||||
fileReadString(string, sizeof(string), stream);
|
||||
if (string[0] == '\0') {
|
||||
debugPrint("Not enough frames in %s, got %d, needed %d", mangledFileName, index, v3);
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: Uninline.
|
||||
char* sep = strchr(string, ' ');
|
||||
if (sep == NULL) {
|
||||
debugPrint("Bad line %s in %s\n", string, fileName);
|
||||
// FIXME: Leaking stream.
|
||||
return false;
|
||||
}
|
||||
|
||||
*sep = '\0';
|
||||
|
||||
int v5;
|
||||
int v6;
|
||||
sscanf(sep + 1, "%d %d", &v5, &v6);
|
||||
|
||||
animatedData->field_4[index] = datafileReadRaw(gMouseManagerNameMangler(string), &width, &height);
|
||||
animatedData->field_0[index] = (unsigned char*)internal_malloc_safe(width * height, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 390
|
||||
memcpy(animatedData->field_0[index], animatedData->field_4[index], width * height);
|
||||
sub_42EE84(animatedData->field_0[index], datafileGetPalette(), width, height);
|
||||
animatedData->field_8[index] = v5;
|
||||
animatedData->field_C[index] = v6;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
animatedData->width = width;
|
||||
animatedData->height = height;
|
||||
|
||||
gMouseManagerCurrentCacheEntryIndex = mouseManagerInsertCacheEntry(reinterpret_cast<void**>(&animatedData), MOUSE_MANAGER_MOUSE_TYPE_ANIMATED, datafileGetPalette(), fileName);
|
||||
strncpy(gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex].field_32C, fileName, 31);
|
||||
|
||||
gMouseManagerCurrentAnimatedData = animatedData;
|
||||
gMouseManagerCurrentPalette = gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex].palette;
|
||||
gMouseManagerIsAnimating = true;
|
||||
|
||||
mouseSetFrame(animatedData->field_0[0],
|
||||
animatedData->width,
|
||||
animatedData->height,
|
||||
animatedData->width,
|
||||
animatedData->field_8[0],
|
||||
animatedData->field_C[0],
|
||||
0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x485E58
|
||||
bool mouseManagerSetMouseShape(char* fileName, int a2, int a3)
|
||||
{
|
||||
unsigned char* palette;
|
||||
int temp;
|
||||
int width;
|
||||
int height;
|
||||
int type;
|
||||
MouseManagerCacheEntry* cacheEntry = mouseManagerFindCacheEntry(fileName, &palette, &temp, &temp, &width, &height, &type);
|
||||
char* mangledFileName = gMouseManagerNameMangler(fileName);
|
||||
|
||||
if (cacheEntry == NULL) {
|
||||
MouseManagerStaticData* staticData;
|
||||
staticData = (MouseManagerStaticData*)internal_malloc_safe(sizeof(*staticData), __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 430
|
||||
staticData->data = datafileReadRaw(mangledFileName, &height, &width);
|
||||
staticData->field_4 = a2;
|
||||
staticData->field_8 = a3;
|
||||
staticData->width = width;
|
||||
staticData->height = height;
|
||||
gMouseManagerCurrentCacheEntryIndex = mouseManagerInsertCacheEntry(reinterpret_cast<void**>(&staticData), MOUSE_MANAGER_MOUSE_TYPE_STATIC, datafileGetPalette(), fileName);
|
||||
|
||||
// NOTE: Original code is slightly different. It obtains address of
|
||||
// `staticData` and sets it's it into `cacheEntry`, which is a bit
|
||||
// awkward. Maybe there is more level on indirection was used. Any way
|
||||
// in order to make code path below unaltered take entire cache entry.
|
||||
cacheEntry = &(gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex]);
|
||||
|
||||
type = MOUSE_MANAGER_MOUSE_TYPE_STATIC;
|
||||
palette = gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex].palette;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 446
|
||||
}
|
||||
|
||||
gMouseManagerCurrentStaticData = (unsigned char*)internal_malloc_safe(width * height, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 448
|
||||
memcpy(gMouseManagerCurrentStaticData, cacheEntry->staticData->data, width * height);
|
||||
sub_42EE84(gMouseManagerCurrentStaticData, palette, width, height);
|
||||
mouseSetFrame(gMouseManagerCurrentStaticData, width, height, width, a2, a3, 0);
|
||||
gMouseManagerIsAnimating = false;
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
gMouseManagerCurrentAnimatedData = cacheEntry->animatedData;
|
||||
gMouseManagerIsAnimating = true;
|
||||
gMouseManagerCurrentPalette = palette;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 0x486010
|
||||
bool mouseManagerSetMousePointer(char* fileName)
|
||||
{
|
||||
unsigned char* palette;
|
||||
int v1;
|
||||
int v2;
|
||||
int width;
|
||||
int height;
|
||||
int type;
|
||||
MouseManagerCacheEntry* cacheEntry = mouseManagerFindCacheEntry(fileName, &palette, &v1, &v2, &width, &height, &type);
|
||||
if (cacheEntry != NULL) {
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 482
|
||||
gMouseManagerCurrentStaticData = NULL;
|
||||
}
|
||||
|
||||
gMouseManagerCurrentPalette = NULL;
|
||||
gMouseManagerIsAnimating = false;
|
||||
gMouseManagerCurrentAnimatedData = 0;
|
||||
|
||||
switch (type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
gMouseManagerCurrentStaticData = (unsigned char*)internal_malloc_safe(width * height, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 492
|
||||
memcpy(gMouseManagerCurrentStaticData, cacheEntry->staticData->data, width * height);
|
||||
sub_42EE84(gMouseManagerCurrentStaticData, palette, width, height);
|
||||
mouseSetFrame(gMouseManagerCurrentStaticData, width, height, width, v1, v2, 0);
|
||||
gMouseManagerIsAnimating = false;
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
gMouseManagerCurrentAnimatedData = cacheEntry->animatedData;
|
||||
gMouseManagerCurrentPalette = palette;
|
||||
gMouseManagerCurrentAnimatedData->field_26 = 0;
|
||||
gMouseManagerCurrentAnimatedData->field_24 = 0;
|
||||
mouseSetFrame(gMouseManagerCurrentAnimatedData->field_0[0],
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->height,
|
||||
gMouseManagerCurrentAnimatedData->width,
|
||||
gMouseManagerCurrentAnimatedData->field_8[0],
|
||||
gMouseManagerCurrentAnimatedData->field_C[0],
|
||||
0);
|
||||
gMouseManagerIsAnimating = true;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char* dot = strrchr(fileName, '.');
|
||||
if (dot != NULL && compat_stricmp(dot + 1, "mou") == 0) {
|
||||
return mouseManagerSetMouseShape(fileName, 0, 0);
|
||||
}
|
||||
|
||||
char* mangledFileName = gMouseManagerNameMangler(fileName);
|
||||
File* stream = fileOpen(mangledFileName, "r");
|
||||
if (stream == NULL) {
|
||||
debugPrint("Can't find %s\n", mangledFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
char string[80];
|
||||
string[0] = '\0';
|
||||
fileReadString(string, sizeof(string) - 1, stream);
|
||||
if (string[0] == '\0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rc;
|
||||
if (compat_strnicmp(string, "anim", 4) == 0) {
|
||||
fileClose(stream);
|
||||
rc = mouseManagerSetFrame(fileName, 0);
|
||||
} else {
|
||||
// NOTE: Uninline.
|
||||
char* sep = strchr(string, ' ');
|
||||
if (sep != NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*sep = '\0';
|
||||
|
||||
int v3;
|
||||
int v4;
|
||||
sscanf(sep + 1, "%d %d", &v3, &v4);
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
rc = mouseManagerSetMouseShape(string, v3, v4);
|
||||
}
|
||||
|
||||
strncpy(gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex].field_32C, fileName, 31);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// 0x4862AC
|
||||
void mouseManagerResetMouse()
|
||||
{
|
||||
MouseManagerCacheEntry* entry = &(gMouseManagerCache[gMouseManagerCurrentCacheEntryIndex]);
|
||||
|
||||
int imageWidth;
|
||||
int imageHeight;
|
||||
switch (entry->type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
imageWidth = entry->staticData->width;
|
||||
imageHeight = entry->staticData->height;
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
imageWidth = entry->animatedData->width;
|
||||
imageHeight = entry->animatedData->height;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (entry->type) {
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_STATIC:
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
if (gMouseManagerCurrentStaticData != NULL) {
|
||||
internal_free_safe(gMouseManagerCurrentStaticData, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 572
|
||||
}
|
||||
|
||||
gMouseManagerCurrentStaticData = (unsigned char*)internal_malloc_safe(imageWidth * imageHeight, __FILE__, __LINE__); // "..\\int\\MOUSEMGR.C", 574
|
||||
memcpy(gMouseManagerCurrentStaticData, entry->staticData->data, imageWidth * imageHeight);
|
||||
sub_42EE84(gMouseManagerCurrentStaticData, entry->palette, imageWidth, imageHeight);
|
||||
|
||||
mouseSetFrame(gMouseManagerCurrentStaticData,
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
imageWidth,
|
||||
entry->staticData->field_4,
|
||||
entry->staticData->field_8,
|
||||
0);
|
||||
} else {
|
||||
debugPrint("Hm, current mouse type is M_STATIC, but no current mouse pointer\n");
|
||||
}
|
||||
break;
|
||||
case MOUSE_MANAGER_MOUSE_TYPE_ANIMATED:
|
||||
if (gMouseManagerCurrentAnimatedData != NULL) {
|
||||
for (int index = 0; index < gMouseManagerCurrentAnimatedData->frameCount; index++) {
|
||||
memcpy(gMouseManagerCurrentAnimatedData->field_0[index], gMouseManagerCurrentAnimatedData->field_4[index], imageWidth * imageHeight);
|
||||
sub_42EE84(gMouseManagerCurrentAnimatedData->field_0[index], entry->palette, imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
mouseSetFrame(gMouseManagerCurrentAnimatedData->field_0[gMouseManagerCurrentAnimatedData->field_26],
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
imageWidth,
|
||||
gMouseManagerCurrentAnimatedData->field_8[gMouseManagerCurrentAnimatedData->field_26],
|
||||
gMouseManagerCurrentAnimatedData->field_C[gMouseManagerCurrentAnimatedData->field_26],
|
||||
0);
|
||||
} else {
|
||||
debugPrint("Hm, current mouse type is M_ANIMATED, but no current mouse pointer\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4865C4
|
||||
void _mouseHide()
|
||||
void mouseManagerHideMouse()
|
||||
{
|
||||
mouseHideCursor();
|
||||
}
|
||||
|
||||
// 0x4865CC
|
||||
void _mouseShow()
|
||||
void mouseManagerShowMouse()
|
||||
{
|
||||
mouseShowCursor();
|
||||
}
|
||||
|
|
|
@ -1,16 +1,81 @@
|
|||
#ifndef MOUSE_MANAGER_H
|
||||
#define MOUSE_MANAGER_H
|
||||
|
||||
extern char* (*_mouseNameMangler)(char*);
|
||||
extern int (*_rateCallback)();
|
||||
extern int (*_currentTimeCallback)();
|
||||
#define MOUSE_MGR_CACHE_CAPACITY 32
|
||||
|
||||
char* _defaultNameMangler(char* a1);
|
||||
int _defaultRateCallback();
|
||||
int _defaultTimeCallback();
|
||||
void _mousemgrSetNameMangler(char* (*func)(char*));
|
||||
void _initMousemgr();
|
||||
void _mouseHide();
|
||||
void _mouseShow();
|
||||
typedef char*(MouseManagerNameMangler)(char* fileName);
|
||||
typedef int(MouseManagerRateProvider)();
|
||||
typedef int(MouseManagerTimeProvider)();
|
||||
|
||||
typedef enum MouseManagerMouseType {
|
||||
MOUSE_MANAGER_MOUSE_TYPE_NONE,
|
||||
MOUSE_MANAGER_MOUSE_TYPE_STATIC,
|
||||
MOUSE_MANAGER_MOUSE_TYPE_ANIMATED,
|
||||
} MouseManagerMouseType;
|
||||
|
||||
typedef struct MouseManagerStaticData {
|
||||
unsigned char* data;
|
||||
int field_4;
|
||||
int field_8;
|
||||
int width;
|
||||
int height;
|
||||
} MouseManagerStaticData;
|
||||
|
||||
typedef struct MouseManagerAnimatedData {
|
||||
unsigned char** field_0;
|
||||
unsigned char** field_4;
|
||||
int* field_8;
|
||||
int* field_C;
|
||||
int width;
|
||||
int height;
|
||||
float field_18;
|
||||
int field_1C;
|
||||
int field_20;
|
||||
signed char field_24;
|
||||
signed char frameCount;
|
||||
signed char field_26;
|
||||
} MouseManagerAnimatedData;
|
||||
|
||||
typedef struct MouseManagerCacheEntry {
|
||||
union {
|
||||
void* data;
|
||||
MouseManagerStaticData* staticData;
|
||||
MouseManagerAnimatedData* animatedData;
|
||||
};
|
||||
int type;
|
||||
unsigned char palette[256 * 3];
|
||||
int ref;
|
||||
char fileName[32];
|
||||
char field_32C[32];
|
||||
} MouseManagerCacheEntry;
|
||||
|
||||
extern MouseManagerNameMangler* gMouseManagerNameMangler;
|
||||
extern MouseManagerRateProvider* gMouseManagerRateProvider;
|
||||
extern MouseManagerTimeProvider* gMouseManagerTimeProvider;
|
||||
|
||||
extern MouseManagerCacheEntry gMouseManagerCache[MOUSE_MGR_CACHE_CAPACITY];
|
||||
extern bool gMouseManagerIsAnimating;
|
||||
extern unsigned char* gMouseManagerCurrentPalette;
|
||||
extern MouseManagerAnimatedData* gMouseManagerCurrentAnimatedData;
|
||||
extern unsigned char* gMouseManagerCurrentStaticData;
|
||||
extern int gMouseManagerCurrentCacheEntryIndex;
|
||||
|
||||
char* mouseManagerNameManglerDefaultImpl(char* a1);
|
||||
int mouseManagerRateProviderDefaultImpl();
|
||||
int mouseManagerTimeProviderDefaultImpl();
|
||||
void mouseManagerSetNameMangler(MouseManagerNameMangler* func);
|
||||
void mouseManagerFreeCacheEntry(MouseManagerCacheEntry* entry);
|
||||
int mouseManagerInsertCacheEntry(void** data, int type, unsigned char* palette, const char* fileName);
|
||||
void mouseManagerFlushCache();
|
||||
MouseManagerCacheEntry* mouseManagerFindCacheEntry(const char* fileName, unsigned char** palettePtr, int* a3, int* a4, int* widthPtr, int* heightPtr, int* typePtr);
|
||||
void mouseManagerInit();
|
||||
void mouseManagerExit();
|
||||
void mouseManagerUpdate();
|
||||
int mouseManagerSetFrame(char* fileName, int a2);
|
||||
bool mouseManagerSetMouseShape(char* fileName, int a2, int a3);
|
||||
bool mouseManagerSetMousePointer(char* fileName);
|
||||
void mouseManagerResetMouse();
|
||||
void mouseManagerHideMouse();
|
||||
void mouseManagerShowMouse();
|
||||
|
||||
#endif /* MOUSE_MANAGER_H */
|
||||
|
|
278
src/movie.cc
278
src/movie.cc
|
@ -14,6 +14,7 @@
|
|||
#include "pointer_registry.h"
|
||||
#include "sound.h"
|
||||
#include "text_font.h"
|
||||
#include "window.h"
|
||||
#include "window_manager.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -29,11 +30,14 @@ typedef struct MovieSubtitleListNode {
|
|||
static void* movieMallocImpl(size_t size);
|
||||
static void movieFreeImpl(void* ptr);
|
||||
static bool movieReadImpl(int fileHandle, void* buf, int count);
|
||||
static void movieDirectImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9);
|
||||
static void movieBufferedImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9);
|
||||
static int _movieScaleSubRectAlpha(int a1);
|
||||
static int _blitAlpha(int win, unsigned char* a2, int a3, int a4, int a5);
|
||||
static int _blitNormal(int win, int a2, int a3, int a4, int a5);
|
||||
static void movieDirectImpl(SDL_Surface* surface, int srcWidth, int srcHeight, int srcX, int srcY, int destWidth, int destHeight, int a8, int a9);
|
||||
static void movieBufferedImpl(SDL_Surface* surface, int srcWidth, int srcHeight, int srcX, int srcY, int destWidth, int destHeight, int a8, int a9);
|
||||
static int _movieScaleSubRect(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _movieScaleSubRectAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _movieScaleWindowAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _blitAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _movieScaleWindow(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static int _blitNormal(int win, unsigned char* data, int width, int height, int pitch);
|
||||
static void movieSetPaletteEntriesImpl(unsigned char* palette, int start, int end);
|
||||
static int _noop();
|
||||
static void _cleanupMovie(int a1);
|
||||
|
@ -51,6 +55,30 @@ static int gMovieWindow = -1;
|
|||
// 0x5195BC
|
||||
static int gMovieSubtitlesFont = -1;
|
||||
|
||||
// 0x5195C0
|
||||
static MovieBlitFunc* gMovieBlitFuncs[2][2][2] = {
|
||||
{
|
||||
{
|
||||
_blitNormal,
|
||||
_blitNormal,
|
||||
},
|
||||
{
|
||||
_movieScaleWindow,
|
||||
_movieScaleSubRect,
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
_blitAlpha,
|
||||
_blitAlpha,
|
||||
},
|
||||
{
|
||||
_movieScaleWindowAlpha,
|
||||
_movieScaleSubRectAlpha,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// 0x5195E0
|
||||
static MovieSetPaletteEntriesProc* gMovieSetPaletteEntriesProc = _setSystemPaletteEntries;
|
||||
|
||||
|
@ -72,19 +100,21 @@ static Rect _movieRect;
|
|||
// 0x638E30
|
||||
static void (*_movieCallback)();
|
||||
|
||||
// 0x638E34
|
||||
MovieEndFunc* _endMovieFunc;
|
||||
|
||||
// 0x638E38
|
||||
static MovieSetPaletteProc* gMoviePaletteProc;
|
||||
|
||||
// NOTE: Some kind of callback which was intended to change movie file path
|
||||
// in place during opening movie file to find subsitutions. This callback is
|
||||
// never set.
|
||||
//
|
||||
// 0x638E3C
|
||||
static int (*_failedOpenFunc)(char* filePath);
|
||||
static MovieFailedOpenFunc* _failedOpenFunc;
|
||||
|
||||
// 0x638E40
|
||||
static MovieBuildSubtitleFilePathProc* gMovieBuildSubtitleFilePathProc;
|
||||
|
||||
// 0x638E44
|
||||
static MovieStartFunc* _startMovieFunc;
|
||||
|
||||
// 0x638E48
|
||||
static int _subtitleW;
|
||||
|
||||
|
@ -103,6 +133,9 @@ static int _lastMovieSY;
|
|||
// 0x638E5C
|
||||
static int _movieScaleFlag;
|
||||
|
||||
// 0x638E60
|
||||
static MoviePreDrawFunc* _moviePreDrawFunc;
|
||||
|
||||
// 0x638E64
|
||||
static int _lastMovieH;
|
||||
|
||||
|
@ -134,7 +167,7 @@ static int _movieH;
|
|||
static int _movieOffset;
|
||||
|
||||
// 0x638E8C
|
||||
static void (*_movieCaptureFrameFunc)(void*, int, int, int, int, int);
|
||||
static MovieCaptureFrameProc* _movieCaptureFrameFunc;
|
||||
|
||||
// 0x638E90
|
||||
static unsigned char* _lastMovieBuffer;
|
||||
|
@ -143,7 +176,7 @@ static unsigned char* _lastMovieBuffer;
|
|||
static int _movieW;
|
||||
|
||||
// 0x638E98
|
||||
static void (*_movieFrameGrabFunc)();
|
||||
static MovieFrameGrabProc* _movieFrameGrabFunc;
|
||||
|
||||
// 0x638EA0
|
||||
static int _subtitleH;
|
||||
|
@ -172,6 +205,31 @@ static unsigned char* _alphaBuf;
|
|||
static SDL_Surface* gMovieSdlSurface = NULL;
|
||||
static int gMovieFileStreamPointerKey = 0;
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4865E0
|
||||
void _movieSetPreDrawFunc(MoviePreDrawFunc* preDrawFunc)
|
||||
{
|
||||
_moviePreDrawFunc = preDrawFunc;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4865E8
|
||||
void _movieSetFailedOpenFunc(MovieFailedOpenFunc* failedOpenFunc)
|
||||
{
|
||||
_failedOpenFunc = failedOpenFunc;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x4865F0
|
||||
void _movieSetFunc(MovieStartFunc* startFunc, MovieEndFunc* endFunc)
|
||||
{
|
||||
_startMovieFunc = startFunc;
|
||||
_endMovieFunc = endFunc;
|
||||
}
|
||||
|
||||
// 0x4865FC
|
||||
static void* movieMallocImpl(size_t size)
|
||||
{
|
||||
|
@ -249,7 +307,14 @@ static void movieDirectImpl(SDL_Surface* surface, int srcWidth, int srcHeight, i
|
|||
|
||||
if (_movieCaptureFrameFunc != NULL) {
|
||||
if (SDL_LockSurface(surface) == 0) {
|
||||
_movieCaptureFrameFunc(surface->pixels, srcWidth, destRect.x, destRect.y, destRect.w, destRect.h);
|
||||
_movieCaptureFrameFunc(static_cast<unsigned char*>(surface->pixels),
|
||||
srcWidth,
|
||||
srcHeight,
|
||||
surface->pitch,
|
||||
destRect.x,
|
||||
destRect.y,
|
||||
destRect.w,
|
||||
destRect.h);
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
}
|
||||
|
@ -269,8 +334,6 @@ static void movieDirectImpl(SDL_Surface* surface, int srcWidth, int srcHeight, i
|
|||
// 0x486900
|
||||
static void movieBufferedImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
|
||||
{
|
||||
int v13;
|
||||
|
||||
if (gMovieWindow == -1) {
|
||||
return;
|
||||
}
|
||||
|
@ -290,55 +353,135 @@ static void movieBufferedImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, i
|
|||
}
|
||||
|
||||
if (_movieCaptureFrameFunc != NULL) {
|
||||
// TODO: Ignore, _movieCaptureFrameFunc is never set.
|
||||
// _movieCaptureFrameFunc()
|
||||
_movieCaptureFrameFunc(static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch, _movieRect.left, _movieRect.top, a6, a7);
|
||||
}
|
||||
|
||||
if (_movieFrameGrabFunc != NULL) {
|
||||
// TODO: Ignore, _movieFrameGrabFunc is never set.
|
||||
// _movieFrameGrabFunc();
|
||||
_movieFrameGrabFunc(static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch);
|
||||
} else {
|
||||
v13 = 4 * _movieSubRectFlag + 8 * _movieScaleFlag + 16 * _movieAlphaFlag;
|
||||
// TODO: Incomplete.
|
||||
MovieBlitFunc* func = gMovieBlitFuncs[_movieAlphaFlag][_movieScaleFlag][_movieSubRectFlag];
|
||||
if (func(gMovieWindow, static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch) != 0) {
|
||||
if (_moviePreDrawFunc != NULL) {
|
||||
_moviePreDrawFunc(gMovieWindow, &_movieRect);
|
||||
}
|
||||
|
||||
windowRefreshRect(gMovieWindow, &_movieRect);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(a1);
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x486A98
|
||||
void _movieSetFrameGrabFunc(MovieFrameGrabProc* proc)
|
||||
{
|
||||
_movieFrameGrabFunc = proc;
|
||||
}
|
||||
|
||||
// NOTE: Unused.
|
||||
//
|
||||
// 0x486AA0
|
||||
void _movieSetCaptureFrameFunc(MovieCaptureFrameProc* func)
|
||||
{
|
||||
_movieCaptureFrameFunc = func;
|
||||
}
|
||||
|
||||
// 0x486B68
|
||||
int _movieScaleSubRect(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
int windowWidth = windowGetWidth(win);
|
||||
unsigned char* windowBuffer = windowGetBuffer(win) + windowWidth * _movieY + _movieX;
|
||||
if (width * 4 / 3 > _movieW) {
|
||||
gMovieFlags |= 0x01;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v1 = width / 3;
|
||||
for (int y = 0; y < height; y++) {
|
||||
int x;
|
||||
for (x = 0; x < v1; x++) {
|
||||
unsigned int value = data[0];
|
||||
value |= data[1] << 8;
|
||||
value |= data[2] << 16;
|
||||
value |= data[2] << 24;
|
||||
|
||||
*(unsigned int*)windowBuffer = value;
|
||||
|
||||
windowBuffer += 4;
|
||||
data += 3;
|
||||
}
|
||||
|
||||
for (x = x * 3; x < width; x++) {
|
||||
*windowBuffer++ = *data++;
|
||||
}
|
||||
|
||||
data += pitch - width;
|
||||
windowBuffer += windowWidth - _movieW;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 0x486C74
|
||||
static int _movieScaleSubRectAlpha(int a1)
|
||||
int _movieScaleSubRectAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
gMovieFlags |= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Uncollapsed 0x486C74.
|
||||
int _movieScaleWindowAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
gMovieFlags |= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x486C80
|
||||
static int _blitAlpha(int win, unsigned char* a2, int a3, int a4, int a5)
|
||||
int _blitAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
unsigned char* buf;
|
||||
int offset;
|
||||
int windowWidth = windowGetWidth(win);
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
_alphaBltBuf(data, width, height, pitch, _alphaWindowBuf, _alphaBuf, windowBuffer + windowWidth * _movieY + _movieX, windowWidth);
|
||||
return 1;
|
||||
}
|
||||
|
||||
offset = windowGetWidth(win) * _movieY + _movieX;
|
||||
buf = windowGetBuffer(win);
|
||||
// 0x486CD4
|
||||
int _movieScaleWindow(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
int windowWidth = windowGetWidth(win);
|
||||
if (width != 3 * windowWidth / 4) {
|
||||
gMovieFlags |= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: Incomplete.
|
||||
// _alphaBltBuf(a2, a3, a4, a5, _alphaWindowBuf, _alphaBuf, buf + offset, windowGetWidth(win));
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
for (int y = 0; y < height; y++) {
|
||||
int scaledWidth = width / 3;
|
||||
for (int x = 0; x < scaledWidth; x++) {
|
||||
unsigned int value = data[0];
|
||||
value |= data[1] << 8;
|
||||
value |= data[2] << 16;
|
||||
value |= data[3] << 24;
|
||||
|
||||
*(unsigned int*)windowBuffer = value;
|
||||
|
||||
windowBuffer += 4;
|
||||
data += 3;
|
||||
}
|
||||
data += pitch - width;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 0x486D84
|
||||
static int _blitNormal(int win, int a2, int a3, int a4, int a5)
|
||||
int _blitNormal(int win, unsigned char* data, int width, int height, int pitch)
|
||||
{
|
||||
unsigned char* buf;
|
||||
int offset;
|
||||
|
||||
offset = windowGetWidth(win) * _movieY + _movieX;
|
||||
buf = windowGetBuffer(win);
|
||||
|
||||
// TODO: Incomplete.
|
||||
// _drawScaled(buf + offset, _movieW, _movieH, windowGetWidth(win), a2, a3, a4, a5);
|
||||
|
||||
int windowWidth = windowGetWidth(win);
|
||||
unsigned char* windowBuffer = windowGetBuffer(win);
|
||||
_drawScaled(windowBuffer + windowWidth * _movieY + _movieX, _movieW, _movieH, windowWidth, data, width, height, pitch);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -373,10 +516,9 @@ static void _cleanupMovie(int a1)
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: Probably can be ignored.
|
||||
// if (_endMovieFunc) {
|
||||
// _endMovieFunc(_movieW, _movieX, _movieH);
|
||||
// }
|
||||
if (_endMovieFunc != NULL) {
|
||||
_endMovieFunc(gMovieWindow, _movieX, _movieY, _movieW, _movieH);
|
||||
}
|
||||
|
||||
int frame;
|
||||
int dropped;
|
||||
|
@ -579,30 +721,18 @@ static void movieLoadSubtitles(char* filePath)
|
|||
|
||||
char* pch;
|
||||
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != '\n') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, '\n');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != '\r') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, '\r');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
pch = string;
|
||||
while (*pch != '\0' && *pch != ':') {
|
||||
pch++;
|
||||
}
|
||||
|
||||
if (*pch != '\0') {
|
||||
pch = strchr(string, ':');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
subtitle->num = atoi(string);
|
||||
subtitle->text = strdup_safe(pch + 1, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1058
|
||||
|
@ -737,14 +867,28 @@ static int _movieStart(int win, char* filePath, int (*a3)())
|
|||
debugPrint("not scaled\n");
|
||||
}
|
||||
|
||||
// TODO: Probably can be ignored, never set.
|
||||
// if (_startMovieFunc) {
|
||||
// _startMovieFunc();
|
||||
// }
|
||||
if (_startMovieFunc != NULL) {
|
||||
_startMovieFunc(gMovieWindow);
|
||||
}
|
||||
|
||||
if (_alphaHandle != NULL) {
|
||||
// TODO: Probably can be ignored, never set.
|
||||
abort();
|
||||
int size;
|
||||
fileReadInt32(_alphaHandle, &size);
|
||||
|
||||
short tmp;
|
||||
fileReadInt16(_alphaHandle, &tmp);
|
||||
fileReadInt16(_alphaHandle, &tmp);
|
||||
|
||||
_alphaBuf = (unsigned char*)internal_malloc_safe(size, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1178
|
||||
_alphaWindowBuf = (unsigned char*)internal_malloc_safe(_movieH * _movieW, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1179
|
||||
|
||||
unsigned char* windowBuffer = windowGetBuffer(gMovieWindow);
|
||||
blitBufferToBuffer(windowBuffer + windowGetWidth(gMovieWindow) * _movieY + _movieX,
|
||||
_movieW,
|
||||
_movieH,
|
||||
windowGetWidth(gMovieWindow),
|
||||
_alphaWindowBuf,
|
||||
_movieW);
|
||||
}
|
||||
|
||||
_movieRect.left = _movieX;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef MOVIE_H
|
||||
#define MOVIE_H
|
||||
|
||||
#include "geometry.h"
|
||||
|
||||
typedef enum MovieFlags {
|
||||
MOVIE_FLAG_0x01 = 0x01,
|
||||
MOVIE_FLAG_0x02 = 0x02,
|
||||
|
@ -19,6 +21,13 @@ typedef enum MovieExtendedFlags {
|
|||
typedef char* MovieBuildSubtitleFilePathProc(char* movieFilePath);
|
||||
typedef void MovieSetPaletteEntriesProc(unsigned char* palette, int start, int end);
|
||||
typedef void MovieSetPaletteProc(int frame);
|
||||
typedef void(MovieFrameGrabProc)(unsigned char* data, int width, int height, int pitch);
|
||||
typedef void(MovieCaptureFrameProc)(unsigned char* data, int width, int height, int pitch, int movieX, int movieY, int movieWidth, int movieHeight);
|
||||
typedef int(MovieBlitFunc)(int win, unsigned char* data, int width, int height, int pitch);
|
||||
typedef void(MoviePreDrawFunc)(int win, Rect* rect);
|
||||
typedef void(MovieStartFunc)(int win);
|
||||
typedef void(MovieEndFunc)(int win, int x, int y, int width, int height);
|
||||
typedef int(MovieFailedOpenFunc)(char* path);
|
||||
|
||||
void movieInit();
|
||||
void movieExit();
|
||||
|
|
|
@ -715,11 +715,7 @@ static void* _ioRead(int size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!gMovieLibReadProc(_io_handle, buf, size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
return gMovieLibReadProc(_io_handle, buf, size) < 1 ? NULL : buf;
|
||||
}
|
||||
|
||||
// 0x4F4D40
|
||||
|
|
|
@ -89,7 +89,7 @@ static void _nevs_removeprogramreferences(Program* program)
|
|||
// 0x488418
|
||||
void _nevs_initonce()
|
||||
{
|
||||
_interpretRegisterProgramDeleteCallback(_nevs_removeprogramreferences);
|
||||
intLibRegisterProgramDeleteCallback(_nevs_removeprogramreferences);
|
||||
|
||||
if (gNevs == NULL) {
|
||||
gNevs = (Nevs*)internal_calloc_safe(sizeof(Nevs), NEVS_COUNT, __FILE__, __LINE__); // "..\\int\\NEVS.C", 131
|
||||
|
|
|
@ -27,6 +27,10 @@ enum {
|
|||
OBJ_TYPE_COUNT,
|
||||
};
|
||||
|
||||
#define FID_TYPE(value) ((value) & 0xF000000) >> 24
|
||||
#define PID_TYPE(value) (value) >> 24
|
||||
#define SID_TYPE(value) (value) >> 24
|
||||
|
||||
typedef enum OutlineType {
|
||||
OUTLINE_TYPE_HOSTILE = 1,
|
||||
OUTLINE_TYPE_2 = 2,
|
||||
|
@ -66,6 +70,20 @@ typedef enum ObjectFlags {
|
|||
OBJECT_OPEN_DOOR = OBJECT_SHOOT_THRU | OBJECT_LIGHT_THRU | OBJECT_NO_BLOCK,
|
||||
} ObjectFlags;
|
||||
|
||||
typedef enum CritterFlags {
|
||||
CRITTER_FLAG_0x2 = 0x2,
|
||||
CRITTER_FLAG_0x20 = 0x20,
|
||||
CRITTER_FLAG_0x40 = 0x40,
|
||||
CRITTER_FLAG_0x80 = 0x80,
|
||||
CRITTER_FLAG_0x100 = 0x100,
|
||||
CRITTER_FLAG_0x200 = 0x200,
|
||||
CRITTER_FLAG_0x400 = 0x400,
|
||||
CRITTER_FLAG_0x800 = 0x800,
|
||||
CRITTER_FLAG_0x1000 = 0x1000,
|
||||
CRITTER_FLAG_0x2000 = 0x2000,
|
||||
CRITTER_FLAG_0x4000 = 0x4000,
|
||||
} CritterFlags;
|
||||
|
||||
#define OUTLINE_TYPE_MASK 0xFFFFFF
|
||||
#define OUTLINE_PALETTED 0x40000000
|
||||
#define OUTLINE_DISABLED 0x80000000
|
||||
|
@ -77,9 +95,12 @@ typedef enum ObjectFlags {
|
|||
#define CONTAINER_FLAG_LOCKED 0x02000000
|
||||
#define DOOR_FLAG_LOCKED 0x02000000
|
||||
|
||||
#define CRITTER_MANEUVER_0x01 0x01
|
||||
#define CRITTER_MANEUVER_STOP_ATTACKING 0x02
|
||||
#define CRITTER_MANUEVER_FLEEING 0x04
|
||||
typedef enum CritterManeuver {
|
||||
CRITTER_MANEUVER_NONE = 0,
|
||||
CRITTER_MANEUVER_0x01 = 0x01,
|
||||
CRITTER_MANEUVER_STOP_ATTACKING = 0x02,
|
||||
CRITTER_MANUEVER_FLEEING = 0x04,
|
||||
} CritterManeuver;
|
||||
|
||||
typedef enum Dam {
|
||||
DAM_KNOCKED_OUT = 0x01,
|
||||
|
@ -178,18 +199,18 @@ typedef struct DoorSceneryData {
|
|||
} DoorSceneryData;
|
||||
|
||||
typedef struct StairsSceneryData {
|
||||
int field_0; // obj_pudg.pudstairs.destMap
|
||||
int field_4; // obj_pudg.pudstairs.destBuiltTile
|
||||
int destinationMap; // obj_pudg.pudstairs.destMap
|
||||
int destinationBuiltTile; // obj_pudg.pudstairs.destBuiltTile
|
||||
} StairsSceneryData;
|
||||
|
||||
typedef struct ElevatorSceneryData {
|
||||
int field_0; // obj_pudg.pudelevator.elevType
|
||||
int field_4; // obj_pudg.pudelevator.elevLevel
|
||||
int type;
|
||||
int level;
|
||||
} ElevatorSceneryData;
|
||||
|
||||
typedef struct LadderSceneryData {
|
||||
int field_0;
|
||||
int field_4;
|
||||
int destinationMap;
|
||||
int destinationBuiltTile;
|
||||
} LadderSceneryData;
|
||||
|
||||
typedef union SceneryObjectData {
|
||||
|
@ -252,4 +273,30 @@ typedef struct ObjectListNode {
|
|||
struct ObjectListNode* next;
|
||||
} ObjectListNode;
|
||||
|
||||
#define BUILT_TILE_TILE_MASK 0x3FFFFFF
|
||||
#define BUILT_TILE_ELEVATION_MASK 0xE0000000
|
||||
#define BUILT_TILE_ELEVATION_SHIFT 29
|
||||
#define BUILT_TILE_ROTATION_MASK 0x1C000000
|
||||
#define BUILT_TILE_ROTATION_SHIFT 26
|
||||
|
||||
static inline int builtTileGetTile(int builtTile)
|
||||
{
|
||||
return builtTile & BUILT_TILE_TILE_MASK;
|
||||
}
|
||||
|
||||
static inline int builtTileGetElevation(int builtTile)
|
||||
{
|
||||
return (builtTile & BUILT_TILE_ELEVATION_MASK) >> BUILT_TILE_ELEVATION_SHIFT;
|
||||
}
|
||||
|
||||
static inline int builtTileGetRotation(int builtTile)
|
||||
{
|
||||
return (builtTile & BUILT_TILE_ROTATION_MASK) >> BUILT_TILE_ROTATION_SHIFT;
|
||||
}
|
||||
|
||||
static inline int builtTileCreate(int tile, int elevation)
|
||||
{
|
||||
return tile | ((elevation << BUILT_TILE_ELEVATION_SHIFT) & BUILT_TILE_ELEVATION_MASK);
|
||||
}
|
||||
|
||||
#endif /* OBJ_TYPES_H */
|
||||
|
|
108
src/object.cc
108
src/object.cc
|
@ -332,7 +332,7 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch)
|
|||
gObjectsWindowBufferSize = height * width;
|
||||
gObjectsWindowPitch = pitch;
|
||||
|
||||
dudeFid = buildFid(1, _art_vault_guy_num, 0, 0, 0);
|
||||
dudeFid = buildFid(OBJ_TYPE_CRITTER, _art_vault_guy_num, 0, 0, 0);
|
||||
objectCreateWithFidPid(&gDude, dudeFid, 0x1000000);
|
||||
|
||||
gDude->flags |= OBJECT_FLAG_0x400;
|
||||
|
@ -346,7 +346,7 @@ int objectsInit(unsigned char* buf, int width, int height, int pitch)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
eggFid = buildFid(6, 2, 0, 0, 0);
|
||||
eggFid = buildFid(OBJ_TYPE_INTERFACE, 2, 0, 0, 0);
|
||||
objectCreateWithFidPid(&gEgg, eggFid, -1);
|
||||
gEgg->flags |= OBJECT_FLAG_0x400;
|
||||
gEgg->flags |= OBJECT_TEMPORARY;
|
||||
|
@ -437,13 +437,13 @@ int objectRead(Object* obj, File* stream)
|
|||
}
|
||||
|
||||
if (obj->pid < 0x5000010 || obj->pid > 0x5000017) {
|
||||
if ((obj->pid >> 24) == 0 && !(gMapHeader.flags & 0x01)) {
|
||||
if (PID_TYPE(obj->pid) == 0 && !(gMapHeader.flags & 0x01)) {
|
||||
_object_fix_weapon_ammo(obj);
|
||||
}
|
||||
} else {
|
||||
if (obj->data.misc.map <= 0) {
|
||||
if ((obj->fid & 0xFFF) < 33) {
|
||||
obj->fid = buildFid(5, (obj->fid & 0xFFF) + 16, (obj->fid & 0xFF0000) >> 16, 0, 0);
|
||||
obj->fid = buildFid(OBJ_TYPE_MISC, (obj->fid & 0xFFF) + 16, FID_ANIM_TYPE(obj->fid), 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ static int objectLoadAllInternal(File* stream)
|
|||
|
||||
_obj_insert(objectListNode);
|
||||
|
||||
if ((objectListNode->obj->flags & OBJECT_FLAG_0x400) && (objectListNode->obj->flags >> 24) == OBJ_TYPE_CRITTER && objectListNode->obj->pid != 18000) {
|
||||
if ((objectListNode->obj->flags & OBJECT_FLAG_0x400) && PID_TYPE(objectListNode->obj->pid) == OBJ_TYPE_CRITTER && objectListNode->obj->pid != 18000) {
|
||||
objectListNode->obj->flags &= ~OBJECT_FLAG_0x400;
|
||||
}
|
||||
|
||||
|
@ -619,7 +619,7 @@ static void _obj_fix_combat_cid_for_dude()
|
|||
// 0x48911C
|
||||
static void _object_fix_weapon_ammo(Object* obj)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_ITEM) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -641,7 +641,7 @@ static void _object_fix_weapon_ammo(Object* obj)
|
|||
obj->data.item.weapon.ammoQuantity = proto->item.data.weapon.ammoCapacity;
|
||||
}
|
||||
} else {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_MISC) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_MISC) {
|
||||
// FIXME: looks like this code in unreachable
|
||||
charges = obj->data.item.misc.charges;
|
||||
if (charges == 0xCCCCCCCC) {
|
||||
|
@ -723,7 +723,7 @@ int objectSaveAll(File* stream)
|
|||
|
||||
CritterCombatData* combatData = NULL;
|
||||
Object* whoHitMe = NULL;
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData = &(object->data.critter.combat);
|
||||
whoHitMe = combatData->whoHitMe;
|
||||
if (whoHitMe != 0) {
|
||||
|
@ -739,7 +739,7 @@ int objectSaveAll(File* stream)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData->whoHitMe = whoHitMe;
|
||||
}
|
||||
|
||||
|
@ -965,7 +965,7 @@ int objectCreateWithFidPid(Object** objectPtr, int fid, int pid)
|
|||
objectListNode->obj->pid = pid;
|
||||
objectListNode->obj->id = scriptsNewObjectId();
|
||||
|
||||
if (pid == -1 || (pid >> 24) == OBJ_TYPE_TILE) {
|
||||
if (pid == -1 || PID_TYPE(pid) == OBJ_TYPE_TILE) {
|
||||
Inventory* inventory = &(objectListNode->obj->data.inventory);
|
||||
inventory->length = 0;
|
||||
inventory->items = NULL;
|
||||
|
@ -1451,7 +1451,7 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
|||
}
|
||||
|
||||
if (isInCombat()) {
|
||||
if ((obj->fid & 0xF000000) >> 24 == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_CRITTER) {
|
||||
bool v8 = obj->outline != 0 && (obj->outline & OUTLINE_DISABLED) == 0;
|
||||
_combat_update_critter_outline_for_los(obj, v8);
|
||||
}
|
||||
|
@ -1471,7 +1471,7 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
|||
}
|
||||
|
||||
if (elevation == elev) {
|
||||
if ((obj->fid & 0xF000000) >> 24 == OBJ_TYPE_MISC) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_MISC) {
|
||||
if (obj->pid >= 0x5000010 && obj->pid <= 0x5000017) {
|
||||
ObjectData* data = &(obj->data);
|
||||
|
||||
|
@ -1498,9 +1498,9 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
|||
int v15 = tile / 200 / 2;
|
||||
if (v14 != _obj_last_roof_x || v15 != _obj_last_roof_y || elevation != _obj_last_elev) {
|
||||
int v16 = _square[elevation]->field_0[v14 + 100 * v15];
|
||||
int v31 = buildFid(4, (v16 >> 16) & 0xFFF, 0, 0, 0);
|
||||
int v31 = buildFid(OBJ_TYPE_TILE, (v16 >> 16) & 0xFFF, 0, 0, 0);
|
||||
int v32 = _square[elevation]->field_0[_obj_last_roof_x + 100 * _obj_last_roof_y];
|
||||
int v34 = buildFid(4, 1, 0, 0, 0) == v31;
|
||||
int v34 = buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0) == v31;
|
||||
|
||||
if (v34 != _obj_last_is_empty || (((v16 >> 16) & 0xF000) >> 12) != (((v32 >> 16) & 0xF000) >> 12)) {
|
||||
if (_obj_last_is_empty == 0) {
|
||||
|
@ -1538,7 +1538,7 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (elevation != _obj_last_elev && (obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (elevation != _obj_last_elev && PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
_combat_delete_critter(obj);
|
||||
}
|
||||
}
|
||||
|
@ -1549,8 +1549,8 @@ int objectSetLocation(Object* obj, int tile, int elevation, Rect* rect)
|
|||
// 0x48A9A0
|
||||
int _obj_reset_roof()
|
||||
{
|
||||
int fid = buildFid(4, (_square[gDude->elevation]->field_0[_obj_last_roof_x + 100 * _obj_last_roof_y] >> 16) & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(4, 1, 0, 0, 0)) {
|
||||
int fid = buildFid(OBJ_TYPE_TILE, (_square[gDude->elevation]->field_0[_obj_last_roof_x + 100 * _obj_last_roof_y] >> 16) & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
_tile_fill_roof(_obj_last_roof_x, _obj_last_roof_y, gDude->elevation, 1);
|
||||
}
|
||||
return 0;
|
||||
|
@ -2100,13 +2100,13 @@ bool _obj_action_can_use(Object* obj)
|
|||
// 0x48B278
|
||||
bool _obj_action_can_talk_to(Object* obj)
|
||||
{
|
||||
return _proto_action_can_talk_to(obj->pid) && ((obj->pid >> 24) == OBJ_TYPE_CRITTER) && critterIsActive(obj);
|
||||
return _proto_action_can_talk_to(obj->pid) && (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) && critterIsActive(obj);
|
||||
}
|
||||
|
||||
// 0x48B2A8
|
||||
bool _obj_portal_is_walk_thru(Object* obj)
|
||||
{
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_SCENERY) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_SCENERY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2207,7 +2207,7 @@ Object* objectFindFirst()
|
|||
}
|
||||
|
||||
while (objectListNode != NULL) {
|
||||
if (artIsObjectTypeHidden((objectListNode->obj->fid & 0xF000000) >> 24) == 0) {
|
||||
if (artIsObjectTypeHidden(FID_TYPE(objectListNode->obj->fid)) == 0) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return objectListNode->obj;
|
||||
}
|
||||
|
@ -2234,7 +2234,7 @@ Object* objectFindNext()
|
|||
|
||||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
|
@ -2257,7 +2257,7 @@ Object* objectFindFirstAtElevation(int elevation)
|
|||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (object->elevation == elevation) {
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
|
@ -2287,7 +2287,7 @@ Object* objectFindNextAtElevation()
|
|||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (object->elevation == gObjectFindElevation) {
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
|
@ -2310,7 +2310,7 @@ Object* objectFindFirstAtLocation(int elevation, int tile)
|
|||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (object->elevation == elevation) {
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
|
@ -2334,7 +2334,7 @@ Object* objectFindNextAtLocation()
|
|||
while (objectListNode != NULL) {
|
||||
Object* object = objectListNode->obj;
|
||||
if (object->elevation == gObjectFindElevation) {
|
||||
if (!artIsObjectTypeHidden((object->fid & 0xF000000) >> 24)) {
|
||||
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
|
||||
gObjectFindLastObjectListNode = objectListNode;
|
||||
return object;
|
||||
}
|
||||
|
@ -2449,7 +2449,7 @@ Object* _obj_blocking_at(Object* a1, int tile, int elev)
|
|||
v7 = objectListNode->obj;
|
||||
if (v7->elevation == elev) {
|
||||
if ((v7->flags & OBJECT_HIDDEN) == 0 && (v7->flags & OBJECT_NO_BLOCK) == 0 && v7 != a1) {
|
||||
type = (v7->fid & 0xF000000) >> 24;
|
||||
type = FID_TYPE(v7->fid);
|
||||
if (type == OBJ_TYPE_CRITTER
|
||||
|| type == OBJ_TYPE_SCENERY
|
||||
|| type == OBJ_TYPE_WALL) {
|
||||
|
@ -2469,7 +2469,7 @@ Object* _obj_blocking_at(Object* a1, int tile, int elev)
|
|||
if ((v7->flags & OBJECT_MULTIHEX) != 0) {
|
||||
if (v7->elevation == elev) {
|
||||
if ((v7->flags & OBJECT_HIDDEN) == 0 && (v7->flags & OBJECT_NO_BLOCK) == 0 && v7 != a1) {
|
||||
type = (v7->fid & 0xF000000) >> 24;
|
||||
type = FID_TYPE(v7->fid);
|
||||
if (type == OBJ_TYPE_CRITTER
|
||||
|| type == OBJ_TYPE_SCENERY
|
||||
|| type == OBJ_TYPE_WALL) {
|
||||
|
@ -2499,7 +2499,7 @@ Object* _obj_shoot_blocking_at(Object* obj, int tile, int elev)
|
|||
if (candidate->elevation == elev) {
|
||||
unsigned int flags = candidate->flags;
|
||||
if ((flags & OBJECT_HIDDEN) == 0 && ((flags & OBJECT_NO_BLOCK) == 0 || (flags & OBJECT_SHOOT_THRU) == 0) && candidate != obj) {
|
||||
int type = (candidate->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(candidate->fid);
|
||||
// SFALL: Fix to prevent corpses from blocking line of fire.
|
||||
if ((type == OBJ_TYPE_CRITTER && !critterIsDead(candidate))
|
||||
|| type == OBJ_TYPE_SCENERY
|
||||
|
@ -2524,7 +2524,7 @@ Object* _obj_shoot_blocking_at(Object* obj, int tile, int elev)
|
|||
if ((flags & OBJECT_MULTIHEX) != 0) {
|
||||
if (candidate->elevation == elev) {
|
||||
if ((flags & OBJECT_HIDDEN) == 0 && (flags & OBJECT_NO_BLOCK) == 0 && candidate != obj) {
|
||||
int type = (candidate->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(candidate->fid);
|
||||
// SFALL: Fix to prevent corpses from blocking line of
|
||||
// fire.
|
||||
if ((type == OBJ_TYPE_CRITTER && !critterIsDead(candidate))
|
||||
|
@ -2556,7 +2556,7 @@ Object* _obj_ai_blocking_at(Object* a1, int tile, int elevation)
|
|||
if ((object->flags & OBJECT_HIDDEN) == 0
|
||||
&& (object->flags & OBJECT_NO_BLOCK) == 0
|
||||
&& object != a1) {
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
if (objectType == OBJ_TYPE_CRITTER
|
||||
|| objectType == OBJ_TYPE_SCENERY
|
||||
|| objectType == OBJ_TYPE_WALL) {
|
||||
|
@ -2585,7 +2585,7 @@ Object* _obj_ai_blocking_at(Object* a1, int tile, int elevation)
|
|||
if ((object->flags & OBJECT_HIDDEN) == 0
|
||||
&& (object->flags & OBJECT_NO_BLOCK) == 0
|
||||
&& object != a1) {
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
if (objectType == OBJ_TYPE_CRITTER
|
||||
|| objectType == OBJ_TYPE_SCENERY
|
||||
|| objectType == OBJ_TYPE_WALL) {
|
||||
|
@ -2639,7 +2639,7 @@ Object* _obj_sight_blocking_at(Object* a1, int tile, int elevation)
|
|||
&& (object->flags & OBJECT_HIDDEN) == 0
|
||||
&& (object->flags & OBJECT_LIGHT_THRU) == 0
|
||||
&& object != a1) {
|
||||
int objectType = (object->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(object->fid);
|
||||
if (objectType == OBJ_TYPE_SCENERY || objectType == OBJ_TYPE_WALL) {
|
||||
return object;
|
||||
}
|
||||
|
@ -2713,7 +2713,7 @@ int objectListCreate(int tile, int elevation, int objectType, Object*** objectLi
|
|||
Object* obj = objectListNode->obj;
|
||||
if ((obj->flags & OBJECT_HIDDEN) == 0
|
||||
&& obj->elevation == elevation
|
||||
&& ((obj->fid & 0xF000000) >> 24) == objectType) {
|
||||
&& FID_TYPE(obj->fid) == objectType) {
|
||||
count++;
|
||||
}
|
||||
objectListNode = objectListNode->next;
|
||||
|
@ -2725,7 +2725,7 @@ int objectListCreate(int tile, int elevation, int objectType, Object*** objectLi
|
|||
Object* obj = objectListNode->obj;
|
||||
if ((obj->flags & OBJECT_HIDDEN) == 0
|
||||
&& obj->elevation == elevation
|
||||
&& ((objectListNode->obj->fid & 0xF000000) >> 24) == objectType) {
|
||||
&& FID_TYPE(objectListNode->obj->fid) == objectType) {
|
||||
count++;
|
||||
}
|
||||
objectListNode = objectListNode->next;
|
||||
|
@ -2748,7 +2748,7 @@ int objectListCreate(int tile, int elevation, int objectType, Object*** objectLi
|
|||
Object* obj = objectListNode->obj;
|
||||
if ((obj->flags & OBJECT_HIDDEN) == 0
|
||||
&& obj->elevation == elevation
|
||||
&& ((obj->fid & 0xF000000) >> 24) == objectType) {
|
||||
&& FID_TYPE(obj->fid) == objectType) {
|
||||
*objects++ = obj;
|
||||
}
|
||||
objectListNode = objectListNode->next;
|
||||
|
@ -2760,7 +2760,7 @@ int objectListCreate(int tile, int elevation, int objectType, Object*** objectLi
|
|||
Object* obj = objectListNode->obj;
|
||||
if ((obj->flags & OBJECT_HIDDEN) == 0
|
||||
&& obj->elevation == elevation
|
||||
&& ((obj->fid & 0xF000000) >> 24) == objectType) {
|
||||
&& FID_TYPE(obj->fid) == objectType) {
|
||||
*objects++ = obj;
|
||||
}
|
||||
objectListNode = objectListNode->next;
|
||||
|
@ -3003,7 +3003,7 @@ int _obj_intersects_with(Object* object, int x, int y)
|
|||
flags |= 0x02;
|
||||
}
|
||||
} else {
|
||||
int type = (object->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(object->fid);
|
||||
if (type == OBJ_TYPE_SCENERY || type == OBJ_TYPE_WALL) {
|
||||
Proto* proto;
|
||||
protoGetProto(object->pid, &proto);
|
||||
|
@ -3064,7 +3064,7 @@ int _obj_create_intersect_list(int x, int y, int elevation, int objectType, Obje
|
|||
}
|
||||
|
||||
if (object->elevation == elevation
|
||||
&& (objectType == -1 || (object->fid & 0xF000000) >> 24 == objectType)
|
||||
&& (objectType == -1 || FID_TYPE(object->fid) == objectType)
|
||||
&& object != gEgg) {
|
||||
int flags = _obj_intersects_with(object, x, y);
|
||||
if (flags != 0) {
|
||||
|
@ -3164,7 +3164,7 @@ void _obj_process_seen()
|
|||
// 0x48C8E4
|
||||
char* objectGetName(Object* obj)
|
||||
{
|
||||
int objectType = (obj->fid & 0xF000000) >> 24;
|
||||
int objectType = FID_TYPE(obj->fid);
|
||||
switch (objectType) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
return itemGetName(obj);
|
||||
|
@ -3178,7 +3178,7 @@ char* objectGetName(Object* obj)
|
|||
// 0x48C914
|
||||
char* objectGetDescription(Object* obj)
|
||||
{
|
||||
if (((obj->fid & 0xF000000) >> 24) == OBJ_TYPE_ITEM) {
|
||||
if (FID_TYPE(obj->fid) == OBJ_TYPE_ITEM) {
|
||||
return itemGetDescription(obj);
|
||||
}
|
||||
|
||||
|
@ -3226,13 +3226,13 @@ void _obj_preload_art_cache(int flags)
|
|||
int v11 = gObjectFidsLength;
|
||||
int v12 = gObjectFidsLength;
|
||||
|
||||
if ((gObjectFids[v12 - 1] & 0xF000000) >> 24 == 3) {
|
||||
int v13 = 0;
|
||||
if (FID_TYPE(gObjectFids[v12 - 1]) == OBJ_TYPE_WALL) {
|
||||
int objectType = OBJ_TYPE_ITEM;
|
||||
do {
|
||||
v11--;
|
||||
v13 = (gObjectFids[v12 - 1] & 0xF000000) >> 24;
|
||||
objectType = FID_TYPE(gObjectFids[v12 - 1]);
|
||||
v12--;
|
||||
} while (v13 == 3);
|
||||
} while (objectType == OBJ_TYPE_WALL);
|
||||
v11++;
|
||||
}
|
||||
|
||||
|
@ -3251,7 +3251,7 @@ void _obj_preload_art_cache(int flags)
|
|||
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (arr[i] != 0) {
|
||||
int fid = buildFid(4, i, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_TILE, i, 0, 0, 0);
|
||||
if (artLock(fid, &cache_handle) != NULL) {
|
||||
artUnlock(cache_handle);
|
||||
}
|
||||
|
@ -3543,7 +3543,7 @@ static int _obj_save_obj(File* stream, Object* object)
|
|||
|
||||
CritterCombatData* combatData = NULL;
|
||||
Object* whoHitMe = NULL;
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData = &(object->data.critter.combat);
|
||||
whoHitMe = combatData->whoHitMe;
|
||||
if (whoHitMe != 0) {
|
||||
|
@ -3559,7 +3559,7 @@ static int _obj_save_obj(File* stream, Object* object)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
combatData->whoHitMe = whoHitMe;
|
||||
}
|
||||
|
||||
|
@ -4602,7 +4602,7 @@ static int _obj_adjust_light(Object* obj, int a2, Rect* rect)
|
|||
|
||||
v14 = (objectListNode->obj->flags & OBJECT_LIGHT_THRU) == 0;
|
||||
|
||||
if ((objectListNode->obj->fid & 0xF000000) >> 24 == OBJ_TYPE_WALL) {
|
||||
if (FID_TYPE(objectListNode->obj->fid) == OBJ_TYPE_WALL) {
|
||||
if ((objectListNode->obj->flags & OBJECT_FLAT) == 0) {
|
||||
Proto* proto;
|
||||
protoGetProto(objectListNode->obj->pid, &proto);
|
||||
|
@ -4933,7 +4933,7 @@ static void objectDrawOutline(Object* object, Rect* rect)
|
|||
// 0x48F1B0
|
||||
static void _obj_render_object(Object* object, Rect* rect, int light)
|
||||
{
|
||||
int type = (object->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(object->fid);
|
||||
if (artIsObjectTypeHidden(type)) {
|
||||
return;
|
||||
}
|
||||
|
@ -5146,7 +5146,7 @@ static void _obj_render_object(Object* object, Rect* rect, int light)
|
|||
// 0x48FA14
|
||||
void _obj_fix_violence_settings(int* fid)
|
||||
{
|
||||
if ((*fid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(*fid) != OBJ_TYPE_CRITTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5181,12 +5181,12 @@ void _obj_fix_violence_settings(int* fid)
|
|||
break;
|
||||
}
|
||||
|
||||
int anim = (*fid & 0xFF0000) >> 16;
|
||||
int anim = FID_ANIM_TYPE(*fid);
|
||||
if (anim >= start && anim <= end) {
|
||||
anim = (anim == ANIM_FALL_BACK_BLOOD_SF)
|
||||
? ANIM_FALL_BACK_SF
|
||||
: ANIM_FALL_FRONT_SF;
|
||||
*fid = buildFid(1, *fid & 0xFFF, anim, (*fid & 0xF000) >> 12, (*fid & 0x70000000) >> 28);
|
||||
*fid = buildFid(OBJ_TYPE_CRITTER, *fid & 0xFFF, anim, (*fid & 0xF000) >> 12, (*fid & 0x70000000) >> 28);
|
||||
}
|
||||
|
||||
if (shouldResetViolenceLevel) {
|
||||
|
@ -5200,8 +5200,8 @@ static int _obj_preload_sort(const void* a1, const void* a2)
|
|||
int v1 = *(int*)a1;
|
||||
int v2 = *(int*)a2;
|
||||
|
||||
int v3 = _cd_order[(v1 & 0xF000000) >> 24];
|
||||
int v4 = _cd_order[(v2 & 0xF000000) >> 24];
|
||||
int v3 = _cd_order[FID_TYPE(v1)];
|
||||
int v4 = _cd_order[FID_TYPE(v2)];
|
||||
|
||||
int cmp = v3 - v4;
|
||||
if (cmp != 0) {
|
||||
|
|
|
@ -574,7 +574,7 @@ static int optionsWindowInit()
|
|||
}
|
||||
|
||||
for (int index = 0; index < OPTIONS_WINDOW_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gOptionsWindowFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gOptionsWindowFrmIds[index], 0, 0, 0);
|
||||
gOptionsWindowFrmData[index] = artLockFrameDataReturningSize(fid, &(gOptionsWindowFrmHandles[index]), &(gOptionsWindowFrmSizes[index].width), &(gOptionsWindowFrmSizes[index].height));
|
||||
|
||||
if (gOptionsWindowFrmData[index] == NULL) {
|
||||
|
@ -730,7 +730,7 @@ int showPause(bool a1)
|
|||
_ShadeScreen(a1);
|
||||
|
||||
for (int index = 0; index < PAUSE_WINDOW_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, graphicIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, graphicIds[index], 0, 0, 0);
|
||||
frmData[index] = artLockFrameDataReturningSize(fid, &(frmHandles[index]), &(frmSizes[index].width), &(frmSizes[index].height));
|
||||
if (frmData[index] == NULL) {
|
||||
while (--index >= 0) {
|
||||
|
@ -1498,7 +1498,7 @@ static int preferencesWindowInit()
|
|||
_SaveSettings();
|
||||
|
||||
for (i = 0; i < PREFERENCES_WINDOW_FRM_COUNT; i++) {
|
||||
fid = buildFid(6, gPreferencesWindowFrmIds[i], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gPreferencesWindowFrmIds[i], 0, 0, 0);
|
||||
gPreferencesWindowFrmData[i] = artLockFrameDataReturningSize(fid, &(gPreferencesWindowFrmHandles[i]), &(gPreferencesWindowFrmSizes[i].width), &(gPreferencesWindowFrmSizes[i].height));
|
||||
if (gPreferencesWindowFrmData[i] == NULL) {
|
||||
for (; i != 0; i--) {
|
||||
|
@ -2064,3 +2064,9 @@ static void _DoThing(int eventCode)
|
|||
|
||||
_changed = true;
|
||||
}
|
||||
|
||||
// 0x48FC48
|
||||
int _do_options()
|
||||
{
|
||||
return showOptionsWithInitialKeyCode(-1);
|
||||
}
|
||||
|
|
|
@ -29,5 +29,6 @@ int preferencesSave(File* stream);
|
|||
int preferencesLoad(File* stream);
|
||||
void brightnessIncrease();
|
||||
void brightnessDecrease();
|
||||
int _do_options();
|
||||
|
||||
#endif /* OPTIONS_H */
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "party_member.h"
|
||||
|
||||
#include "combat_ai.h"
|
||||
#include "combat_ai_defs.h"
|
||||
#include "animation.h"
|
||||
#include "color.h"
|
||||
#include "combat_ai.h"
|
||||
#include "combat_ai_defs.h"
|
||||
#include "config.h"
|
||||
#include "critter.h"
|
||||
#include "debug.h"
|
||||
|
@ -558,7 +558,7 @@ static int _partyMemberPrepLoadInstance(STRUCT_519DA8* a1)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
obj->data.critter.combat.whoHitMe = NULL;
|
||||
}
|
||||
|
||||
|
@ -605,7 +605,7 @@ static int _partyMemberPrepLoadInstance(STRUCT_519DA8* a1)
|
|||
|
||||
scriptRemove(script->sid);
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
_dude_stand(obj, obj->rotation, -1);
|
||||
}
|
||||
|
||||
|
@ -660,7 +660,7 @@ static int _partyMemberRecoverLoadInstance(STRUCT_519DA8* a1)
|
|||
}
|
||||
|
||||
int scriptType = SCRIPT_TYPE_CRITTER;
|
||||
if ((a1->object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a1->object->pid) != OBJ_TYPE_CRITTER) {
|
||||
scriptType = SCRIPT_TYPE_ITEM;
|
||||
}
|
||||
|
||||
|
@ -791,7 +791,7 @@ int _partyMemberSyncPosition()
|
|||
for (int index = 1; index < gPartyMembersLength; index++) {
|
||||
STRUCT_519DA8* partyMember = &(gPartyMembers[index]);
|
||||
Object* partyMemberObj = partyMember->object;
|
||||
if ((partyMemberObj->flags & OBJECT_HIDDEN) == 0 && (partyMemberObj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if ((partyMemberObj->flags & OBJECT_HIDDEN) == 0 && PID_TYPE(partyMemberObj->pid) == OBJ_TYPE_CRITTER) {
|
||||
int rotation;
|
||||
if ((n % 2) != 0) {
|
||||
rotation = clockwiseRotation;
|
||||
|
@ -822,7 +822,7 @@ int _partyMemberRestingHeal(int a1)
|
|||
|
||||
for (int index = 0; index < gPartyMembersLength; index++) {
|
||||
STRUCT_519DA8* partyMember = &(gPartyMembers[index]);
|
||||
if ((partyMember->object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(partyMember->object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int healingRate = critterGetStat(partyMember->object, STAT_HEALING_RATE);
|
||||
critterAdjustHitPoints(partyMember->object, v1 * healingRate);
|
||||
}
|
||||
|
@ -892,7 +892,7 @@ int _getPartyMemberCount()
|
|||
for (int index = 1; index < gPartyMembersLength; index++) {
|
||||
Object* object = gPartyMembers[index].object;
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER || critterIsDead(object) || (object->flags & OBJECT_HIDDEN) != 0) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER || critterIsDead(object) || (object->flags & OBJECT_HIDDEN) != 0) {
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
@ -1126,7 +1126,7 @@ int partyMemberGetBestSkill(Object* object)
|
|||
return bestSkill;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return bestSkill;
|
||||
}
|
||||
|
||||
|
@ -1152,7 +1152,7 @@ Object* partyMemberGetBestInSkill(int skill)
|
|||
|
||||
for (int index = 0; index < gPartyMembersLength; index++) {
|
||||
Object* object = gPartyMembers[index].object;
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0 && (object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0 && PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int value = skillGetValue(object, skill);
|
||||
if (value > bestValue) {
|
||||
bestValue = value;
|
||||
|
@ -1173,7 +1173,7 @@ int partyGetBestSkillValue(int skill)
|
|||
|
||||
for (int index = 0; index < gPartyMembersLength; index++) {
|
||||
Object* object = gPartyMembers[index].object;
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0 && (object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if ((object->flags & OBJECT_HIDDEN) == 0 && PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
int value = skillGetValue(object, skill);
|
||||
if (value > bestValue) {
|
||||
bestValue = value;
|
||||
|
@ -1191,7 +1191,7 @@ static int _partyFixMultipleMembers()
|
|||
|
||||
int critterCount = 0;
|
||||
for (Object* obj = objectFindFirst(); obj != NULL; obj = objectFindNext()) {
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
critterCount++;
|
||||
}
|
||||
|
||||
|
@ -1294,7 +1294,7 @@ bool partyMemberSupportsDisposition(Object* critter, int disposition)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1317,7 +1317,7 @@ bool partyMemberSupportsAreaAttackMode(Object* object, int areaAttackMode)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1340,7 +1340,7 @@ bool partyMemberSupportsRunAwayMode(Object* object, int runAwayMode)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1363,7 +1363,7 @@ bool partyMemberSupportsBestWeapon(Object* object, int bestWeapon)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1386,7 +1386,7 @@ bool partyMemberSupportsDistance(Object* object, int distanceMode)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1409,7 +1409,7 @@ bool partyMemberSupportsAttackWho(Object* object, int attackWho)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1432,7 +1432,7 @@ bool partyMemberSupportsChemUse(Object* object, int chemUse)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1475,7 +1475,7 @@ int _partyMemberIncLevels()
|
|||
break;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) != 1) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1623,7 +1623,7 @@ bool partyIsAnyoneCanBeHealedByRest()
|
|||
STRUCT_519DA8* ptr = &(gPartyMembers[index]);
|
||||
Object* object = ptr->object;
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) continue;
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) continue;
|
||||
if (critterIsDead(object)) continue;
|
||||
if ((object->flags & OBJECT_HIDDEN) != 0) continue;
|
||||
if (critterGetKillType(object) == KILL_TYPE_ROBOT) continue;
|
||||
|
@ -1650,7 +1650,7 @@ int partyGetMaxWoundToHealByRest()
|
|||
STRUCT_519DA8* ptr = &(gPartyMembers[index]);
|
||||
Object* object = ptr->object;
|
||||
|
||||
if ((object->pid >> 24) != OBJ_TYPE_CRITTER) continue;
|
||||
if (PID_TYPE(object->pid) != OBJ_TYPE_CRITTER) continue;
|
||||
if (critterIsDead(object)) continue;
|
||||
if ((object->flags & OBJECT_HIDDEN) != 0) continue;
|
||||
if (critterGetKillType(object) == KILL_TYPE_ROBOT) continue;
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
#include "pcx.h"
|
||||
|
||||
#include "memory_manager.h"
|
||||
|
||||
// 0x519DC8
|
||||
unsigned char gPcxLastRunLength = 0;
|
||||
|
||||
// 0x519DC9
|
||||
unsigned char gPcxLastValue = 0;
|
||||
|
||||
// NOTE: The reading method in this function is a little bit odd. It does not
|
||||
// use high level reading functions, which can read right into struct. Instead
|
||||
// they read everything into temporary variables. There are no error checks.
|
||||
//
|
||||
// 0x4961D4
|
||||
void pcxReadHeader(PcxHeader* pcxHeader, File* stream)
|
||||
{
|
||||
pcxHeader->identifier = fileReadChar(stream);
|
||||
pcxHeader->version = fileReadChar(stream);
|
||||
pcxHeader->encoding = fileReadChar(stream);
|
||||
pcxHeader->bitsPerPixel = fileReadChar(stream);
|
||||
|
||||
short minX;
|
||||
fileRead(&minX, 2, 1, stream);
|
||||
pcxHeader->minX = minX;
|
||||
|
||||
short minY;
|
||||
fileRead(&minY, 2, 1, stream);
|
||||
pcxHeader->minY = minY;
|
||||
|
||||
short maxX;
|
||||
fileRead(&maxX, 2, 1, stream);
|
||||
pcxHeader->maxX = maxX;
|
||||
|
||||
short maxY;
|
||||
fileRead(&maxY, 2, 1, stream);
|
||||
pcxHeader->maxY = maxY;
|
||||
|
||||
short horizontalResolution;
|
||||
fileRead(&horizontalResolution, 2, 1, stream);
|
||||
pcxHeader->horizontalResolution = horizontalResolution;
|
||||
|
||||
short verticalResolution;
|
||||
fileRead(&verticalResolution, 2, 1, stream);
|
||||
pcxHeader->verticalResolution = verticalResolution;
|
||||
|
||||
for (int index = 0; index < 48; index++) {
|
||||
pcxHeader->palette[index] = fileReadChar(stream);
|
||||
}
|
||||
|
||||
pcxHeader->reserved1 = fileReadChar(stream);
|
||||
pcxHeader->planeCount = fileReadChar(stream);
|
||||
|
||||
short bytesPerLine;
|
||||
fileRead(&bytesPerLine, 2, 1, stream);
|
||||
pcxHeader->bytesPerLine = bytesPerLine;
|
||||
|
||||
short paletteType;
|
||||
fileRead(&paletteType, 2, 1, stream);
|
||||
pcxHeader->paletteType = paletteType;
|
||||
|
||||
short horizontalScreenSize;
|
||||
fileRead(&horizontalScreenSize, 2, 1, stream);
|
||||
pcxHeader->horizontalScreenSize = horizontalScreenSize;
|
||||
|
||||
short verticalScreenSize;
|
||||
fileRead(&verticalScreenSize, 2, 1, stream);
|
||||
pcxHeader->verticalScreenSize = verticalScreenSize;
|
||||
|
||||
for (int index = 0; index < 54; index++) {
|
||||
pcxHeader->reserved2[index] = fileReadChar(stream);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x49636C
|
||||
int pcxReadLine(unsigned char* data, int size, File* stream)
|
||||
{
|
||||
unsigned char runLength = gPcxLastRunLength;
|
||||
unsigned char value = gPcxLastValue;
|
||||
|
||||
int uncompressedSize = 0;
|
||||
int index = 0;
|
||||
do {
|
||||
uncompressedSize += runLength;
|
||||
while (runLength > 0 && index < size) {
|
||||
data[index] = value;
|
||||
runLength--;
|
||||
index++;
|
||||
}
|
||||
|
||||
gPcxLastRunLength = runLength;
|
||||
gPcxLastValue = value;
|
||||
|
||||
if (runLength != 0) {
|
||||
uncompressedSize -= runLength;
|
||||
break;
|
||||
}
|
||||
|
||||
value = fileReadChar(stream);
|
||||
if ((value & 0xC0) == 0xC0) {
|
||||
gPcxLastRunLength = value & 0x3F;
|
||||
value = fileReadChar(stream);
|
||||
runLength = gPcxLastRunLength;
|
||||
} else {
|
||||
runLength = 1;
|
||||
}
|
||||
} while (index < size);
|
||||
|
||||
gPcxLastRunLength = runLength;
|
||||
gPcxLastValue = value;
|
||||
|
||||
return uncompressedSize;
|
||||
}
|
||||
|
||||
// 0x49641C
|
||||
int pcxReadPalette(PcxHeader* pcxHeader, unsigned char* palette, File* stream)
|
||||
{
|
||||
if (pcxHeader->version != 5) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long pos = fileTell(stream);
|
||||
long size = fileGetSize(stream);
|
||||
fileSeek(stream, size - 769, SEEK_SET);
|
||||
if (fileReadChar(stream) != 12) {
|
||||
fileSeek(stream, pos, SEEK_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int index = 0; index < 768; index++) {
|
||||
palette[index] = fileReadChar(stream);
|
||||
}
|
||||
|
||||
fileSeek(stream, pos, SEEK_SET);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 0x496494
|
||||
unsigned char* pcxRead(const char* path, int* widthPtr, int* heightPtr, unsigned char* palette)
|
||||
{
|
||||
File* stream = fileOpen(path, "rb");
|
||||
if (stream == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PcxHeader pcxHeader;
|
||||
pcxReadHeader(&pcxHeader, stream);
|
||||
|
||||
int width = pcxHeader.maxX - pcxHeader.minX + 1;
|
||||
int height = pcxHeader.maxY - pcxHeader.minY + 1;
|
||||
|
||||
*widthPtr = width;
|
||||
*heightPtr = height;
|
||||
|
||||
int bytesPerLine = pcxHeader.planeCount * pcxHeader.bytesPerLine;
|
||||
unsigned char* data = (unsigned char*)internal_malloc_safe(bytesPerLine * height, __FILE__, __LINE__); // "..\\int\\PCX.C", 195
|
||||
if (data == NULL) {
|
||||
// NOTE: This code is unreachable, internal_malloc_safe never fails.
|
||||
fileClose(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gPcxLastRunLength = 0;
|
||||
gPcxLastValue = 0;
|
||||
|
||||
unsigned char* ptr = data;
|
||||
for (int y = 0; y < height; y++) {
|
||||
pcxReadLine(ptr, bytesPerLine, stream);
|
||||
ptr += width;
|
||||
}
|
||||
|
||||
pcxReadPalette(&pcxHeader, palette, stream);
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
return data;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef PCX_H
|
||||
#define PCX_H
|
||||
|
||||
#include "db.h"
|
||||
|
||||
typedef struct PcxHeader {
|
||||
unsigned char identifier;
|
||||
unsigned char version;
|
||||
unsigned char encoding;
|
||||
unsigned char bitsPerPixel;
|
||||
short minX;
|
||||
short minY;
|
||||
short maxX;
|
||||
short maxY;
|
||||
short horizontalResolution;
|
||||
short verticalResolution;
|
||||
unsigned char palette[48];
|
||||
unsigned char reserved1;
|
||||
unsigned char planeCount;
|
||||
short bytesPerLine;
|
||||
short paletteType;
|
||||
short horizontalScreenSize;
|
||||
short verticalScreenSize;
|
||||
unsigned char reserved2[54];
|
||||
} PcxHeader;
|
||||
|
||||
extern unsigned char gPcxLastRunLength;
|
||||
extern unsigned char gPcxLastValue;
|
||||
|
||||
void pcxReadHeader(PcxHeader* pcxHeader, File* stream);
|
||||
int pcxReadLine(unsigned char* data, int size, File* stream);
|
||||
int pcxReadPalette(PcxHeader* pcxHeader, unsigned char* palette, File* stream);
|
||||
unsigned char* pcxRead(const char* path, int* widthPtr, int* heightPtr, unsigned char* palette);
|
||||
|
||||
#endif /* PCX_H */
|
|
@ -535,7 +535,7 @@ int perkGetFrmId(int perk)
|
|||
// 0x496BFC
|
||||
void perkAddEffect(Object* critter, int perk)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
debugPrint("\nERROR: perk_add_effect: Was called on non-critter!");
|
||||
return;
|
||||
}
|
||||
|
@ -575,7 +575,7 @@ void perkAddEffect(Object* critter, int perk)
|
|||
// 0x496CE0
|
||||
void perkRemoveEffect(Object* critter, int perk)
|
||||
{
|
||||
if ((critter->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(critter->pid) != OBJ_TYPE_CRITTER) {
|
||||
debugPrint("\nERROR: perk_remove_effect: Was called on non-critter!");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -512,7 +512,7 @@ static int pipboyWindowInit(bool forceRest)
|
|||
|
||||
int index;
|
||||
for (index = 0; index < PIPBOY_FRM_COUNT; index++) {
|
||||
int fid = buildFid(6, gPipboyFrmIds[index], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gPipboyFrmIds[index], 0, 0, 0);
|
||||
gPipboyFrmData[index] = artLockFrameDataReturningSize(fid, &(gPipboyFrmHandles[index]), &(gPipboyFrmSizes[index].width), &(gPipboyFrmSizes[index].height));
|
||||
if (gPipboyFrmData[index] == NULL) {
|
||||
break;
|
||||
|
@ -1087,7 +1087,7 @@ static void pipboyWindowHandleStatus(int a1)
|
|||
|
||||
// Skip quests in the same location.
|
||||
//
|
||||
// FIXME: This code should be identical to the one in the
|
||||
// FIXME: This code should be identical to the one in the
|
||||
// `pipboyWindowRenderQuestLocationList`. See buffer overread
|
||||
// bug involved.
|
||||
for (; index < gQuestsCount; index++) {
|
||||
|
@ -2013,7 +2013,7 @@ static bool pipboyRest(int hours, int minutes, int duration)
|
|||
rc = true;
|
||||
}
|
||||
|
||||
unsigned int v8 = (unsigned int)((double)hour / v7 * (hours * 36000.0) + gameTime);
|
||||
unsigned int v8 = (unsigned int)((double)hour / v7 * (hours * GAME_TIME_TICKS_PER_HOUR) + gameTime);
|
||||
unsigned int nextEventTime = queueGetNextEventTime();
|
||||
if (!rc && v8 >= nextEventTime) {
|
||||
gameTimeSetTime(nextEventTime + 1);
|
||||
|
@ -2050,7 +2050,7 @@ static bool pipboyRest(int hours, int minutes, int duration)
|
|||
}
|
||||
|
||||
if (!rc) {
|
||||
gameTimeSetTime(gameTime + 36000 * hours);
|
||||
gameTimeSetTime(gameTime + GAME_TIME_TICKS_PER_HOUR * hours);
|
||||
}
|
||||
|
||||
pipboyDrawNumber(gameTimeGetHour(), 4, PIPBOY_WINDOW_TIME_X, PIPBOY_WINDOW_TIME_Y);
|
||||
|
|
|
@ -55,7 +55,7 @@ void compat_splitpath(const char* path, char* drive, char* dir, char* fname, cha
|
|||
#ifdef _WIN32
|
||||
_splitpath(path, drive, dir, fname, ext);
|
||||
#else
|
||||
const char *driveStart = path;
|
||||
const char* driveStart = path;
|
||||
if (path[0] == '/' && path[1] == '/') {
|
||||
path += 2;
|
||||
while (*path != '\0' && *path != '/' && *path != '.') {
|
||||
|
@ -130,7 +130,7 @@ void compat_makepath(char* path, const char* drive, const char* dir, const char*
|
|||
if (*drive != '\0') {
|
||||
strcpy(path, drive);
|
||||
path = strchr(path, '\0');
|
||||
|
||||
|
||||
if (path[-1] == '/') {
|
||||
path--;
|
||||
} else {
|
||||
|
|
168
src/proto.cc
168
src/proto.cc
|
@ -185,17 +185,21 @@ static char** _perk_code_strs;
|
|||
// 0x6648BC
|
||||
static char** _critter_stats_list;
|
||||
|
||||
// NOTE: Inlined.
|
||||
void _proto_make_path(char* path, int pid)
|
||||
{
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, _proto_path_base);
|
||||
if (pid != -1) {
|
||||
strcat(path, artGetObjectTypeName(PID_TYPE(pid)));
|
||||
}
|
||||
}
|
||||
|
||||
// Append proto file name to proto_path from proto.lst.
|
||||
//
|
||||
// 0x49E758
|
||||
int _proto_list_str(int pid, char* proto_path)
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
char str[COMPAT_MAX_PATH];
|
||||
char* pch;
|
||||
File* stream;
|
||||
int i;
|
||||
|
||||
if (pid == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -204,17 +208,17 @@ int _proto_list_str(int pid, char* proto_path)
|
|||
return -1;
|
||||
}
|
||||
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, "proto\\");
|
||||
strcat(path, artGetObjectTypeName(pid >> 24));
|
||||
char path[COMPAT_MAX_PATH];
|
||||
_proto_make_path(path, pid);
|
||||
strcat(path, "\\");
|
||||
strcat(path, artGetObjectTypeName(pid >> 24));
|
||||
strcat(path, artGetObjectTypeName(PID_TYPE(pid)));
|
||||
strcat(path, ".lst");
|
||||
|
||||
stream = fileOpen(path, "rt");
|
||||
File* stream = fileOpen(path, "rt");
|
||||
|
||||
i = 1;
|
||||
while (fileReadString(str, sizeof(str), stream)) {
|
||||
int i = 1;
|
||||
char string[256];
|
||||
while (fileReadString(string, sizeof(string), stream)) {
|
||||
if (i == (pid & 0xFFFFFF)) {
|
||||
break;
|
||||
}
|
||||
|
@ -228,14 +232,17 @@ int _proto_list_str(int pid, char* proto_path)
|
|||
return -1;
|
||||
}
|
||||
|
||||
pch = str;
|
||||
while (*pch != '\0' && *pch != '\n') {
|
||||
*proto_path = *pch;
|
||||
proto_path++;
|
||||
pch++;
|
||||
char* pch = strchr(string, ' ');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
*proto_path = '\0';
|
||||
pch = strchr(string, '\n');
|
||||
if (pch != NULL) {
|
||||
*pch = '\0';
|
||||
}
|
||||
|
||||
strcpy(proto_path, string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -252,7 +259,7 @@ bool _proto_action_can_use(int pid)
|
|||
return true;
|
||||
}
|
||||
|
||||
if ((pid >> 24) == OBJ_TYPE_ITEM && proto->item.type == ITEM_TYPE_CONTAINER) {
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_ITEM && proto->item.type == ITEM_TYPE_CONTAINER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -271,7 +278,7 @@ bool _proto_action_can_use_on(int pid)
|
|||
return true;
|
||||
}
|
||||
|
||||
if ((pid >> 24) == OBJ_TYPE_ITEM && proto->item.type == ITEM_TYPE_DRUG) {
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_ITEM && proto->item.type == ITEM_TYPE_DRUG) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -286,7 +293,7 @@ bool _proto_action_can_talk_to(int pid)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_CRITTER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -302,7 +309,7 @@ bool _proto_action_can_talk_to(int pid)
|
|||
// 0x49EA5C
|
||||
int _proto_action_can_pickup(int pid)
|
||||
{
|
||||
if ((pid >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (PID_TYPE(pid) != OBJ_TYPE_ITEM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -326,7 +333,7 @@ char* protoGetMessage(int pid, int message)
|
|||
Proto* proto;
|
||||
if (protoGetProto(pid, &proto) != -1) {
|
||||
if (proto->messageId != -1) {
|
||||
MessageList* messageList = &(_proto_msg_files[pid >> 24]);
|
||||
MessageList* messageList = &(_proto_msg_files[PID_TYPE(pid)]);
|
||||
|
||||
MessageListItem messageListItem;
|
||||
messageListItem.num = proto->messageId + message;
|
||||
|
@ -366,7 +373,7 @@ static int _proto_critter_init(Proto* a1, int a2)
|
|||
|
||||
a1->pid = -1;
|
||||
a1->messageId = 100 * v1;
|
||||
a1->fid = buildFid(1, v1 - 1, 0, 0, 0);
|
||||
a1->fid = buildFid(OBJ_TYPE_CRITTER, v1 - 1, 0, 0, 0);
|
||||
a1->critter.lightDistance = 0;
|
||||
a1->critter.lightIntensity = 0;
|
||||
a1->critter.flags = 0x20000000;
|
||||
|
@ -377,7 +384,7 @@ static int _proto_critter_init(Proto* a1, int a2)
|
|||
a1->critter.headFid = -1;
|
||||
a1->critter.aiPacket = 1;
|
||||
if (!artExists(a1->fid)) {
|
||||
a1->fid = buildFid(1, 0, 0, 0, 0);
|
||||
a1->fid = buildFid(OBJ_TYPE_CRITTER, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
CritterProtoData* data = &(a1->critter.data);
|
||||
|
@ -437,7 +444,7 @@ int objectDataRead(Object* obj, File* stream)
|
|||
// TODO: See below.
|
||||
if (fileReadInt32(stream, (int*)&(inventory->items)) == -1) return -1;
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (fileReadInt32(stream, &(obj->data.critter.field_0)) == -1) return -1;
|
||||
if (objectCritterCombatDataRead(&(obj->data.critter.combat), stream) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.critter.hp)) == -1) return -1;
|
||||
|
@ -451,7 +458,7 @@ int objectDataRead(Object* obj, File* stream)
|
|||
obj->data.flags = 0;
|
||||
}
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (protoGetProto(obj->pid, &proto) == -1) return -1;
|
||||
|
||||
|
@ -482,27 +489,27 @@ int objectDataRead(Object* obj, File* stream)
|
|||
if (fileReadInt32(stream, &(obj->data.scenery.door.openFlags)) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_STAIRS:
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.stairs.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.stairs.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.stairs.destinationBuiltTile)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.stairs.destinationMap)) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.elevator.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.elevator.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.elevator.type)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.elevator.level)) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
if (gMapHeader.version == 19) {
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationBuiltTile)) == -1) return -1;
|
||||
} else {
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationMap)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationBuiltTile)) == -1) return -1;
|
||||
}
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_DOWN:
|
||||
if (gMapHeader.version == 19) {
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationBuiltTile)) == -1) return -1;
|
||||
} else {
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationMap)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(obj->data.scenery.ladder.destinationBuiltTile)) == -1) return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -534,7 +541,7 @@ int objectDataWrite(Object* obj, File* stream)
|
|||
// this field is shared with something else.
|
||||
if (fileWriteInt32(stream, (intptr_t)data->inventory.items) == -1) return -1;
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
if (fileWriteInt32(stream, data->flags) == -1) return -1;
|
||||
if (objectCritterCombatDataWrite(&(obj->data.critter.combat), stream) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->critter.hp) == -1) return -1;
|
||||
|
@ -543,7 +550,7 @@ int objectDataWrite(Object* obj, File* stream)
|
|||
} else {
|
||||
if (fileWriteInt32(stream, data->flags) == -1) return -1;
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (protoGetProto(obj->pid, &proto) == -1) return -1;
|
||||
|
||||
|
@ -571,20 +578,20 @@ int objectDataWrite(Object* obj, File* stream)
|
|||
if (fileWriteInt32(stream, data->scenery.door.openFlags) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_STAIRS:
|
||||
if (fileWriteInt32(stream, data->scenery.stairs.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.stairs.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.stairs.destinationBuiltTile) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.stairs.destinationMap) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.type) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.level) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.destinationMap) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.destinationBuiltTile) == -1) return -1;
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_DOWN:
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.elevator.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.destinationMap) == -1) return -1;
|
||||
if (fileWriteInt32(stream, data->scenery.ladder.destinationBuiltTile) == -1) return -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -624,7 +631,7 @@ static int _proto_update_gen(Object* obj)
|
|||
return -1;
|
||||
}
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
switch (proto->item.type) {
|
||||
case ITEM_TYPE_CONTAINER:
|
||||
|
@ -651,16 +658,16 @@ static int _proto_update_gen(Object* obj)
|
|||
data->scenery.door.openFlags = proto->scenery.data.door.openFlags;
|
||||
break;
|
||||
case SCENERY_TYPE_STAIRS:
|
||||
data->scenery.stairs.field_4 = proto->scenery.data.stairs.field_0;
|
||||
data->scenery.stairs.field_0 = proto->scenery.data.stairs.field_4;
|
||||
data->scenery.stairs.destinationBuiltTile = proto->scenery.data.stairs.field_0;
|
||||
data->scenery.stairs.destinationMap = proto->scenery.data.stairs.field_4;
|
||||
break;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
data->scenery.elevator.field_0 = proto->scenery.data.elevator.field_0;
|
||||
data->scenery.elevator.field_4 = proto->scenery.data.elevator.field_4;
|
||||
data->scenery.elevator.type = proto->scenery.data.elevator.type;
|
||||
data->scenery.elevator.level = proto->scenery.data.elevator.level;
|
||||
break;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
case SCENERY_TYPE_LADDER_DOWN:
|
||||
data->scenery.ladder.field_0 = proto->scenery.data.ladder.field_0;
|
||||
data->scenery.ladder.destinationMap = proto->scenery.data.ladder.field_0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -698,7 +705,7 @@ int _proto_update_init(Object* obj)
|
|||
obj->field_2C_array[i] = 0;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) != OBJ_TYPE_CRITTER) {
|
||||
return _proto_update_gen(obj);
|
||||
}
|
||||
|
||||
|
@ -749,11 +756,11 @@ int _proto_dude_update_gender()
|
|||
v1 = (gDude->fid & 0xF000) >> 12;
|
||||
}
|
||||
|
||||
int fid = buildFid(1, _art_vault_guy_num, 0, v1, 0);
|
||||
int fid = buildFid(OBJ_TYPE_CRITTER, _art_vault_guy_num, 0, v1, 0);
|
||||
objectSetFid(gDude, fid, NULL);
|
||||
}
|
||||
|
||||
proto->fid = buildFid(1, _art_vault_guy_num, 0, 0, 0);
|
||||
proto->fid = buildFid(OBJ_TYPE_CRITTER, _art_vault_guy_num, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -762,7 +769,7 @@ int _proto_dude_update_gender()
|
|||
// 0x49FA64
|
||||
int _proto_dude_init(const char* path)
|
||||
{
|
||||
gDudeProto.fid = buildFid(1, _art_vault_guy_num, 0, 0, 0);
|
||||
gDudeProto.fid = buildFid(OBJ_TYPE_CRITTER, _art_vault_guy_num, 0, 0, 0);
|
||||
|
||||
if (_init_true) {
|
||||
_obj_inven_free(&(gDude->data.inventory));
|
||||
|
@ -822,7 +829,7 @@ int protoGetDataMember(int pid, int member, ProtoDataMemberValue* value)
|
|||
return -1;
|
||||
}
|
||||
|
||||
switch (pid >> 24) {
|
||||
switch (PID_TYPE(pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
switch (member) {
|
||||
case ITEM_DATA_MEMBER_PID:
|
||||
|
@ -1076,7 +1083,7 @@ int protoInit()
|
|||
_proto_critter_init((Proto*)&gDudeProto, 0x1000000);
|
||||
|
||||
gDudeProto.pid = 0x1000000;
|
||||
gDudeProto.fid = buildFid(1, 1, 0, 0, 0);
|
||||
gDudeProto.fid = buildFid(OBJ_TYPE_CRITTER, 1, 0, 0, 0);
|
||||
|
||||
gDude->pid = 0x1000000;
|
||||
gDude->sid = 1;
|
||||
|
@ -1188,7 +1195,7 @@ void protoReset()
|
|||
// TODO: Get rid of cast.
|
||||
_proto_critter_init((Proto*)&gDudeProto, 0x1000000);
|
||||
gDudeProto.pid = 0x1000000;
|
||||
gDudeProto.fid = buildFid(1, 1, 0, 0, 0);
|
||||
gDudeProto.fid = buildFid(OBJ_TYPE_CRITTER, 1, 0, 0, 0);
|
||||
|
||||
gDude->pid = 0x1000000;
|
||||
gDude->sid = -1;
|
||||
|
@ -1233,9 +1240,7 @@ static int _proto_header_load()
|
|||
ptr->max_entries_num = 1;
|
||||
|
||||
char path[COMPAT_MAX_PATH];
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, _proto_path_base);
|
||||
strcat(path, artGetObjectTypeName(index));
|
||||
_proto_make_path(path, index << 24);
|
||||
strcat(path, "\\");
|
||||
strcat(path, artGetObjectTypeName(index));
|
||||
strcat(path, ".lst");
|
||||
|
@ -1358,8 +1363,8 @@ static int protoSceneryDataRead(SceneryProtoData* scenery_data, int type, File*
|
|||
|
||||
return 0;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
if (fileReadInt32(stream, &(scenery_data->elevator.field_0)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scenery_data->elevator.field_4)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scenery_data->elevator.type)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scenery_data->elevator.level)) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
|
@ -1384,7 +1389,7 @@ static int protoRead(Proto* proto, File* stream)
|
|||
if (fileReadInt32(stream, &(proto->messageId)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(proto->fid)) == -1) return -1;
|
||||
|
||||
switch (proto->pid >> 24) {
|
||||
switch (PID_TYPE(proto->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (fileReadInt32(stream, &(proto->item.lightDistance)) == -1) return -1;
|
||||
if (_db_freadInt(stream, &(proto->item.lightIntensity)) == -1) return -1;
|
||||
|
@ -1544,8 +1549,8 @@ static int protoSceneryDataWrite(SceneryProtoData* scenery_data, int type, File*
|
|||
|
||||
return 0;
|
||||
case SCENERY_TYPE_ELEVATOR:
|
||||
if (fileWriteInt32(stream, scenery_data->elevator.field_0) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scenery_data->elevator.field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scenery_data->elevator.type) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scenery_data->elevator.level) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
case SCENERY_TYPE_LADDER_UP:
|
||||
|
@ -1569,7 +1574,7 @@ static int protoWrite(Proto* proto, File* stream)
|
|||
if (fileWriteInt32(stream, proto->messageId) == -1) return -1;
|
||||
if (fileWriteInt32(stream, proto->fid) == -1) return -1;
|
||||
|
||||
switch (proto->pid >> 24) {
|
||||
switch (PID_TYPE(proto->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (fileWriteInt32(stream, proto->item.lightDistance) == -1) return -1;
|
||||
if (_db_fwriteLong(stream, proto->item.lightIntensity) == -1) return -1;
|
||||
|
@ -1645,13 +1650,7 @@ int _proto_save_pid(int pid)
|
|||
}
|
||||
|
||||
char path[260];
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, _proto_path_base);
|
||||
|
||||
if (pid != -1) {
|
||||
strcat(path, artGetObjectTypeName(pid >> 24));
|
||||
}
|
||||
|
||||
_proto_make_path(path, pid);
|
||||
strcat(path, "\\");
|
||||
|
||||
_proto_list_str(pid, path + strlen(path));
|
||||
|
@ -1672,14 +1671,7 @@ int _proto_save_pid(int pid)
|
|||
static int _proto_load_pid(int pid, Proto** protoPtr)
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
strcpy(path, _cd_path_base);
|
||||
|
||||
strcat(path, "proto\\");
|
||||
|
||||
if (pid != -1) {
|
||||
strcat(path, artGetObjectTypeName(pid >> 24));
|
||||
}
|
||||
|
||||
_proto_make_path(path, pid);
|
||||
strcat(path, "\\");
|
||||
|
||||
if (_proto_list_str(pid, path + strlen(path)) == -1) {
|
||||
|
@ -1693,7 +1685,7 @@ static int _proto_load_pid(int pid, Proto** protoPtr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (_proto_find_free_subnode(pid >> 24, protoPtr) == -1) {
|
||||
if (_proto_find_free_subnode(PID_TYPE(pid), protoPtr) == -1) {
|
||||
fileClose(stream);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1826,7 +1818,7 @@ int protoGetProto(int pid, Proto** protoPtr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ProtoList* protoList = &(_protoLists[pid >> 24]);
|
||||
ProtoList* protoList = &(_protoLists[PID_TYPE(pid)]);
|
||||
ProtoListExtent* protoListExtent = protoList->head;
|
||||
while (protoListExtent != NULL) {
|
||||
for (int index = 0; index < protoListExtent->length; index++) {
|
||||
|
@ -1841,7 +1833,7 @@ int protoGetProto(int pid, Proto** protoPtr)
|
|||
|
||||
if (protoList->head != NULL && protoList->tail != NULL) {
|
||||
if (PROTO_LIST_EXTENT_SIZE * protoList->length - (PROTO_LIST_EXTENT_SIZE - protoList->tail->length) > PROTO_LIST_MAX_ENTRIES) {
|
||||
_proto_remove_some_list(pid >> 24);
|
||||
_proto_remove_some_list(PID_TYPE(pid));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ extern char _cd_path_base[COMPAT_MAX_PATH];
|
|||
extern MessageList gProtoMessageList;
|
||||
extern char* _proto_none_str;
|
||||
|
||||
void _proto_make_path(char* path, int pid);
|
||||
int _proto_list_str(int pid, char* proto_path);
|
||||
bool _proto_action_can_use(int pid);
|
||||
bool _proto_action_can_use_on(int pid);
|
||||
|
|
|
@ -76,7 +76,7 @@ int _obj_new_sid(Object* object, int* sidPtr)
|
|||
}
|
||||
|
||||
int sid;
|
||||
int objectType = object->pid >> 24;
|
||||
int objectType = PID_TYPE(object->pid);
|
||||
if (objectType < OBJ_TYPE_TILE) {
|
||||
sid = proto->sid;
|
||||
} else if (objectType == OBJ_TYPE_TILE) {
|
||||
|
@ -91,7 +91,7 @@ int _obj_new_sid(Object* object, int* sidPtr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int scriptType = sid >> 24;
|
||||
int scriptType = SID_TYPE(sid);
|
||||
if (scriptAdd(sidPtr, scriptType) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ int _obj_new_sid(Object* object, int* sidPtr)
|
|||
}
|
||||
|
||||
if (scriptType == SCRIPT_TYPE_SPATIAL) {
|
||||
script->sp.built_tile = object->tile | ((object->elevation << 29) & 0xE0000000);
|
||||
script->sp.built_tile = builtTileCreate(object->tile, object->elevation);
|
||||
script->sp.radius = 3;
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ int _obj_new_sid_inst(Object* obj, int scriptType, int a3)
|
|||
|
||||
script->field_14 = a3;
|
||||
if (scriptType == SCRIPT_TYPE_SPATIAL) {
|
||||
script->sp.built_tile = ((obj->elevation << 29) & 0xE0000000) | obj->tile;
|
||||
script->sp.built_tile = builtTileCreate(obj->tile, obj->elevation);
|
||||
script->sp.radius = 3;
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ int _obj_new_sid_inst(Object* obj, int scriptType, int a3)
|
|||
|
||||
_scr_find_str_run_info(a3 & 0xFFFFFF, &(script->field_50), sid);
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
|
||||
obj->field_80 = script->field_14;
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ int _obj_look_at_func(Object* a1, Object* a2, void (*a3)(char* string))
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (((a2->fid & 0xF000000) >> 24) == OBJ_TYPE_TILE) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_TILE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ int _obj_look_at_func(Object* a1, Object* a2, void (*a3)(char* string))
|
|||
if (!scriptOverrides) {
|
||||
MessageListItem messageListItem;
|
||||
|
||||
if ((a2->pid >> 24) == OBJ_TYPE_CRITTER && critterIsDead(a2)) {
|
||||
if (PID_TYPE(a2->pid) == OBJ_TYPE_CRITTER && critterIsDead(a2)) {
|
||||
messageListItem.num = 491 + randomBetween(0, 1);
|
||||
} else {
|
||||
messageListItem.num = 490;
|
||||
|
@ -240,7 +240,7 @@ int _obj_examine_func(Object* critter, Object* target, void (*fn)(char* string))
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((target->fid & 0xF000000) >> 24 == OBJ_TYPE_TILE) {
|
||||
if (FID_TYPE(target->fid) == OBJ_TYPE_TILE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ int _obj_examine_func(Object* critter, Object* target, void (*fn)(char* string))
|
|||
}
|
||||
fn(messageListItem.text);
|
||||
} else {
|
||||
if ((target->pid >> 24) != OBJ_TYPE_CRITTER || !critterIsDead(target)) {
|
||||
if (PID_TYPE(target->pid) != OBJ_TYPE_CRITTER || !critterIsDead(target)) {
|
||||
fn(description);
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ int _obj_examine_func(Object* critter, Object* target, void (*fn)(char* string))
|
|||
|
||||
char formattedText[260];
|
||||
|
||||
int type = target->pid >> 24;
|
||||
int type = PID_TYPE(target->pid);
|
||||
if (type == OBJ_TYPE_CRITTER) {
|
||||
if (target != gDude && perkGetRank(gDude, PERK_AWARENESS) && !critterIsDead(target)) {
|
||||
MessageListItem hpMessageListItem;
|
||||
|
@ -597,7 +597,7 @@ static int _obj_remove_from_inven(Object* critter, Object* item)
|
|||
int v11 = 0;
|
||||
if (critterGetItem2(critter) == item) {
|
||||
if (critter != gDude || interfaceGetCurrentHand()) {
|
||||
fid = buildFid(1, critter->fid & 0xFFF, (critter->fid & 0xFF0000) >> 16, 0, critter->rotation);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, FID_ANIM_TYPE(critter->fid), 0, critter->rotation);
|
||||
objectSetFid(critter, fid, &updatedRect);
|
||||
v11 = 2;
|
||||
} else {
|
||||
|
@ -605,7 +605,7 @@ static int _obj_remove_from_inven(Object* critter, Object* item)
|
|||
}
|
||||
} else if (critterGetItem1(critter) == item) {
|
||||
if (critter == gDude && !interfaceGetCurrentHand()) {
|
||||
fid = buildFid(1, critter->fid & 0xFFF, (critter->fid & 0xFF0000) >> 16, 0, critter->rotation);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, critter->fid & 0xFFF, FID_ANIM_TYPE(critter->fid), 0, critter->rotation);
|
||||
objectSetFid(critter, fid, &updatedRect);
|
||||
v11 = 2;
|
||||
} else {
|
||||
|
@ -620,7 +620,7 @@ static int _obj_remove_from_inven(Object* critter, Object* item)
|
|||
v5 = proto->fid;
|
||||
}
|
||||
|
||||
fid = buildFid(1, v5, (critter->fid & 0xFF0000) >> 16, (critter->fid & 0xF000) >> 12, critter->rotation);
|
||||
fid = buildFid(OBJ_TYPE_CRITTER, v5, FID_ANIM_TYPE(critter->fid), (critter->fid & 0xF000) >> 12, critter->rotation);
|
||||
objectSetFid(critter, fid, &updatedRect);
|
||||
v11 = 3;
|
||||
}
|
||||
|
@ -1165,7 +1165,7 @@ static int _protinst_default_use_item(Object* a1, Object* a2, Object* item)
|
|||
int rc;
|
||||
switch (itemGetType(item)) {
|
||||
case ITEM_TYPE_DRUG:
|
||||
if ((a2->pid >> 24) != OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a2->pid) != OBJ_TYPE_CRITTER) {
|
||||
if (a1 == gDude) {
|
||||
// That does nothing
|
||||
messageListItem.num = 582;
|
||||
|
@ -1422,7 +1422,7 @@ int _check_scenery_ap_cost(Object* obj, Object* a2)
|
|||
// 0x49C740
|
||||
int _obj_use(Object* a1, Object* a2)
|
||||
{
|
||||
int type = (a2->fid & 0xF000000) >> 24;
|
||||
int type = FID_TYPE(a2->fid);
|
||||
if (a1 == gDude) {
|
||||
if (type != OBJ_TYPE_SCENERY) {
|
||||
return -1;
|
||||
|
@ -1438,7 +1438,7 @@ int _obj_use(Object* a1, Object* a2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((a2->pid >> 24) == OBJ_TYPE_SCENERY && sceneryProto->scenery.type == SCENERY_TYPE_DOOR) {
|
||||
if (PID_TYPE(a2->pid) == OBJ_TYPE_SCENERY && sceneryProto->scenery.type == SCENERY_TYPE_DOOR) {
|
||||
return _obj_use_door(a1, a2, 0);
|
||||
}
|
||||
|
||||
|
@ -1457,7 +1457,7 @@ int _obj_use(Object* a1, Object* a2)
|
|||
}
|
||||
|
||||
if (!scriptOverrides) {
|
||||
if ((a2->pid >> 24) == OBJ_TYPE_SCENERY) {
|
||||
if (PID_TYPE(a2->pid) == OBJ_TYPE_SCENERY) {
|
||||
if (sceneryProto->scenery.type == SCENERY_TYPE_LADDER_DOWN) {
|
||||
if (useLadderDown(a1, a2, 0) == 0) {
|
||||
scriptOverrides = true;
|
||||
|
@ -1498,21 +1498,21 @@ int _obj_use(Object* a1, Object* a2)
|
|||
// 0x49C900
|
||||
static int useLadderDown(Object* a1, Object* ladder, int a3)
|
||||
{
|
||||
int builtTile = ladder->data.scenery.ladder.field_4;
|
||||
int builtTile = ladder->data.scenery.ladder.destinationBuiltTile;
|
||||
if (builtTile == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tile = builtTile & 0x3FFFFFF;
|
||||
int elevation = (builtTile & 0xE0000000) >> 29;
|
||||
if (ladder->data.scenery.ladder.field_0 != 0) {
|
||||
int tile = builtTileGetTile(builtTile);
|
||||
int elevation = builtTileGetElevation(builtTile);
|
||||
if (ladder->data.scenery.ladder.destinationMap != 0) {
|
||||
MapTransition transition;
|
||||
memset(&transition, 0, sizeof(transition));
|
||||
|
||||
transition.map = ladder->data.scenery.ladder.field_0;
|
||||
transition.map = ladder->data.scenery.ladder.destinationMap;
|
||||
transition.elevation = elevation;
|
||||
transition.tile = tile;
|
||||
transition.rotation = (builtTile & 0x1C000000) >> 26;
|
||||
transition.rotation = builtTileGetRotation(builtTile);
|
||||
|
||||
mapSetTransition(&transition);
|
||||
|
||||
|
@ -1532,21 +1532,21 @@ static int useLadderDown(Object* a1, Object* ladder, int a3)
|
|||
// 0x49C9A4
|
||||
static int useLadderUp(Object* a1, Object* ladder, int a3)
|
||||
{
|
||||
int builtTile = ladder->data.scenery.ladder.field_4;
|
||||
int builtTile = ladder->data.scenery.ladder.destinationBuiltTile;
|
||||
if (builtTile == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tile = builtTile & 0x3FFFFFF;
|
||||
int elevation = (builtTile & 0xE0000000) >> 29;
|
||||
if (ladder->data.scenery.ladder.field_0 != 0) {
|
||||
int tile = builtTileGetTile(builtTile);
|
||||
int elevation = builtTileGetElevation(builtTile);
|
||||
if (ladder->data.scenery.ladder.destinationMap != 0) {
|
||||
MapTransition transition;
|
||||
memset(&transition, 0, sizeof(transition));
|
||||
|
||||
transition.map = ladder->data.scenery.ladder.field_0;
|
||||
transition.map = ladder->data.scenery.ladder.destinationMap;
|
||||
transition.elevation = elevation;
|
||||
transition.tile = tile;
|
||||
transition.rotation = (builtTile & 0x1C000000) >> 26;
|
||||
transition.rotation = builtTileGetRotation(builtTile);
|
||||
|
||||
mapSetTransition(&transition);
|
||||
|
||||
|
@ -1566,21 +1566,21 @@ static int useLadderUp(Object* a1, Object* ladder, int a3)
|
|||
// 0x49CA48
|
||||
static int useStairs(Object* a1, Object* stairs, int a3)
|
||||
{
|
||||
int builtTile = stairs->data.scenery.stairs.field_4;
|
||||
int builtTile = stairs->data.scenery.stairs.destinationBuiltTile;
|
||||
if (builtTile == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tile = builtTile & 0x3FFFFFF;
|
||||
int elevation = (builtTile & 0xE0000000) >> 29;
|
||||
if (stairs->data.scenery.stairs.field_0 > 0) {
|
||||
int tile = builtTileGetTile(builtTile);
|
||||
int elevation = builtTileGetElevation(builtTile);
|
||||
if (stairs->data.scenery.stairs.destinationMap > 0) {
|
||||
MapTransition transition;
|
||||
memset(&transition, 0, sizeof(transition));
|
||||
|
||||
transition.map = stairs->data.scenery.stairs.field_0;
|
||||
transition.map = stairs->data.scenery.stairs.destinationMap;
|
||||
transition.elevation = elevation;
|
||||
transition.tile = tile;
|
||||
transition.rotation = (builtTile & 0x1C000000) >> 26;
|
||||
transition.rotation = builtTileGetRotation(builtTile);
|
||||
|
||||
mapSetTransition(&transition);
|
||||
|
||||
|
@ -1734,31 +1734,31 @@ int _obj_use_door(Object* a1, Object* a2, int a3)
|
|||
step = 1;
|
||||
}
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
for (int i = start; i != end; i += step) {
|
||||
if (i != 0) {
|
||||
if (a3 == 0) {
|
||||
reg_anim_11_0(a2, a2, _set_door_state_closed, -1);
|
||||
animationRegisterCallback(a2, a2, (AnimationCallback*)_set_door_state_closed, -1);
|
||||
}
|
||||
|
||||
const char* sfx = sfxBuildOpenName(a2, SCENERY_SOUND_EFFECT_CLOSED);
|
||||
reg_anim_play_sfx(a2, sfx, -1);
|
||||
animationRegisterPlaySoundEffect(a2, sfx, -1);
|
||||
|
||||
reg_anim_animate_reverse(a2, 0, 0);
|
||||
animationRegisterAnimateReversed(a2, ANIM_STAND, 0);
|
||||
} else {
|
||||
if (a3 == 0) {
|
||||
reg_anim_11_0(a2, a2, _set_door_state_open, -1);
|
||||
animationRegisterCallback(a2, a2, (AnimationCallback*)_set_door_state_open, -1);
|
||||
}
|
||||
|
||||
const char* sfx = sfxBuildOpenName(a2, SCENERY_SOUND_EFFECT_CLOSED);
|
||||
reg_anim_play_sfx(a2, sfx, -1);
|
||||
animationRegisterPlaySoundEffect(a2, sfx, -1);
|
||||
|
||||
reg_anim_animate(a2, 0, 0);
|
||||
animationRegisterAnimate(a2, ANIM_STAND, 0);
|
||||
}
|
||||
}
|
||||
|
||||
reg_anim_11_1(a2, a2, _check_door_state, -1);
|
||||
animationRegisterCallbackForced(a2, a2, (AnimationCallback*)_check_door_state, -1);
|
||||
|
||||
reg_anim_end();
|
||||
}
|
||||
|
@ -1769,7 +1769,7 @@ int _obj_use_door(Object* a1, Object* a2, int a3)
|
|||
// 0x49CE7C
|
||||
int _obj_use_container(Object* critter, Object* item)
|
||||
{
|
||||
if (((item->fid & 0xF000000) >> 24) != OBJ_TYPE_ITEM) {
|
||||
if (FID_TYPE(item->fid) != OBJ_TYPE_ITEM) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1817,16 +1817,16 @@ int _obj_use_container(Object* critter, Object* item)
|
|||
return -1;
|
||||
}
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
if (item->frame == 0) {
|
||||
const char* sfx = sfxBuildOpenName(item, SCENERY_SOUND_EFFECT_OPEN);
|
||||
reg_anim_play_sfx(item, sfx, 0);
|
||||
reg_anim_animate(item, 0, 0);
|
||||
animationRegisterPlaySoundEffect(item, sfx, 0);
|
||||
animationRegisterAnimate(item, ANIM_STAND, 0);
|
||||
} else {
|
||||
const char* sfx = sfxBuildOpenName(item, SCENERY_SOUND_EFFECT_CLOSED);
|
||||
reg_anim_play_sfx(item, sfx, 0);
|
||||
reg_anim_animate_reverse(item, 0, 0);
|
||||
animationRegisterPlaySoundEffect(item, sfx, 0);
|
||||
animationRegisterAnimateReversed(item, ANIM_STAND, 0);
|
||||
}
|
||||
|
||||
reg_anim_end();
|
||||
|
@ -1902,7 +1902,7 @@ static bool _obj_is_lockable(Object* obj)
|
|||
return false;
|
||||
}
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (proto->item.type == ITEM_TYPE_CONTAINER) {
|
||||
return true;
|
||||
|
@ -1926,7 +1926,7 @@ bool objectIsLocked(Object* obj)
|
|||
}
|
||||
|
||||
ObjectData* data = &(obj->data);
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
return data->flags & CONTAINER_FLAG_LOCKED;
|
||||
case OBJ_TYPE_SCENERY:
|
||||
|
@ -1943,7 +1943,7 @@ int objectLock(Object* object)
|
|||
return -1;
|
||||
}
|
||||
|
||||
switch (object->pid >> 24) {
|
||||
switch (PID_TYPE(object->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
object->data.flags |= OBJ_LOCKED;
|
||||
break;
|
||||
|
@ -1964,7 +1964,7 @@ int objectUnlock(Object* object)
|
|||
return -1;
|
||||
}
|
||||
|
||||
switch (object->pid >> 24) {
|
||||
switch (PID_TYPE(object->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
object->data.flags &= ~OBJ_LOCKED;
|
||||
return 0;
|
||||
|
@ -1989,7 +1989,7 @@ static bool _obj_is_openable(Object* obj)
|
|||
return false;
|
||||
}
|
||||
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
if (proto->item.type == ITEM_TYPE_CONTAINER) {
|
||||
return true;
|
||||
|
@ -2028,24 +2028,24 @@ static int objectOpenClose(Object* obj)
|
|||
|
||||
objectUnjamLock(obj);
|
||||
|
||||
reg_anim_begin(2);
|
||||
reg_anim_begin(ANIMATION_REQUEST_RESERVED);
|
||||
|
||||
if (obj->frame != 0) {
|
||||
reg_anim_11_1(obj, obj, _set_door_state_closed, -1);
|
||||
animationRegisterCallbackForced(obj, obj, (AnimationCallback*)_set_door_state_closed, -1);
|
||||
|
||||
const char* sfx = sfxBuildOpenName(obj, SCENERY_SOUND_EFFECT_CLOSED);
|
||||
reg_anim_play_sfx(obj, sfx, -1);
|
||||
animationRegisterPlaySoundEffect(obj, sfx, -1);
|
||||
|
||||
reg_anim_animate_reverse(obj, 0, 0);
|
||||
animationRegisterAnimateReversed(obj, ANIM_STAND, 0);
|
||||
} else {
|
||||
reg_anim_11_1(obj, obj, _set_door_state_open, -1);
|
||||
animationRegisterCallbackForced(obj, obj, (AnimationCallback*)_set_door_state_open, -1);
|
||||
|
||||
const char* sfx = sfxBuildOpenName(obj, SCENERY_SOUND_EFFECT_OPEN);
|
||||
reg_anim_play_sfx(obj, sfx, -1);
|
||||
reg_anim_animate(obj, 0, 0);
|
||||
animationRegisterPlaySoundEffect(obj, sfx, -1);
|
||||
animationRegisterAnimate(obj, ANIM_STAND, 0);
|
||||
}
|
||||
|
||||
reg_anim_11_1(obj, obj, _check_door_state, -1);
|
||||
animationRegisterCallbackForced(obj, obj, (AnimationCallback*)_check_door_state, -1);
|
||||
|
||||
reg_anim_end();
|
||||
|
||||
|
@ -2079,7 +2079,7 @@ static bool objectIsJammed(Object* obj)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((obj->pid >> 24) == OBJ_TYPE_SCENERY) {
|
||||
if (PID_TYPE(obj->pid) == OBJ_TYPE_SCENERY) {
|
||||
if ((obj->data.scenery.door.openFlags & OBJ_JAMMED) != 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -2101,7 +2101,7 @@ int objectJamLock(Object* obj)
|
|||
}
|
||||
|
||||
ObjectData* data = &(obj->data);
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
data->flags |= CONTAINER_FLAG_JAMMED;
|
||||
break;
|
||||
|
@ -2121,7 +2121,7 @@ int objectUnjamLock(Object* obj)
|
|||
}
|
||||
|
||||
ObjectData* data = &(obj->data);
|
||||
switch (obj->pid >> 24) {
|
||||
switch (PID_TYPE(obj->pid)) {
|
||||
case OBJ_TYPE_ITEM:
|
||||
data->flags &= ~CONTAINER_FLAG_JAMMED;
|
||||
break;
|
||||
|
|
|
@ -362,8 +362,8 @@ typedef struct {
|
|||
} SceneryProtoStairsData;
|
||||
|
||||
typedef struct {
|
||||
int field_0; // d.lower_tile
|
||||
int field_4; // d.upper_tile
|
||||
int type;
|
||||
int level;
|
||||
} SceneryProtoElevatorData;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct WithdrawalEvent {
|
|||
|
||||
typedef struct ScriptEvent {
|
||||
int sid;
|
||||
int field_4;
|
||||
int fixedParam;
|
||||
} ScriptEvent;
|
||||
|
||||
typedef struct RadiationEvent {
|
||||
|
|
106
src/region.cc
106
src/region.cc
|
@ -44,6 +44,82 @@ void _regionSetBound(Region* region)
|
|||
}
|
||||
}
|
||||
|
||||
// 0x4A2C14
|
||||
bool regionContainsPoint(Region* region, int x, int y)
|
||||
{
|
||||
if (region == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x < region->field_24 || x > region->field_2C || y < region->field_28 || y > region->field_30) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int v1;
|
||||
|
||||
Point* prev = &(region->points[0]);
|
||||
if (x >= prev->x) {
|
||||
if (y >= prev->y) {
|
||||
v1 = 2;
|
||||
} else {
|
||||
v1 = 1;
|
||||
}
|
||||
} else {
|
||||
if (y >= prev->y) {
|
||||
v1 = 3;
|
||||
} else {
|
||||
v1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int v4 = 0;
|
||||
for (int index = 0; index < region->pointsLength; index++) {
|
||||
int v2;
|
||||
|
||||
Point* point = &(region->points[index + 1]);
|
||||
if (x >= point->x) {
|
||||
if (y >= point->y) {
|
||||
v2 = 2;
|
||||
} else {
|
||||
v2 = 1;
|
||||
}
|
||||
} else {
|
||||
if (y >= point->y) {
|
||||
v2 = 3;
|
||||
} else {
|
||||
v2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int v3 = v2 - v1;
|
||||
switch (v3) {
|
||||
case -3:
|
||||
v3 = 1;
|
||||
break;
|
||||
case -2:
|
||||
case 2:
|
||||
if ((double)x < ((double)point->x - (double)(prev->x - point->x) / (double)(prev->y - point->y) * (double)(point->y - y))) {
|
||||
v3 = -v3;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
v3 = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
prev = point;
|
||||
v1 = v2;
|
||||
|
||||
v4 += v3;
|
||||
}
|
||||
|
||||
if (v4 == 4 || v4 == -4) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0x4A2D78
|
||||
Region* regionCreate(int initialCapacity)
|
||||
{
|
||||
|
@ -62,24 +138,24 @@ Region* regionCreate(int initialCapacity)
|
|||
region->field_74 = 0;
|
||||
region->field_28 = INT_MIN;
|
||||
region->field_30 = INT_MAX;
|
||||
region->field_54 = 0;
|
||||
region->field_5C = 0;
|
||||
region->field_64 = 0;
|
||||
region->procs[3] = 0;
|
||||
region->rightProcs[1] = 0;
|
||||
region->rightProcs[3] = 0;
|
||||
region->field_68 = 0;
|
||||
region->field_6C = 0;
|
||||
region->rightProcs[0] = 0;
|
||||
region->field_70 = 0;
|
||||
region->field_60 = 0;
|
||||
region->field_78 = 0;
|
||||
region->field_7C = 0;
|
||||
region->field_80 = 0;
|
||||
region->field_84 = 0;
|
||||
region->rightProcs[2] = 0;
|
||||
region->mouseEventCallback = NULL;
|
||||
region->rightMouseEventCallback = NULL;
|
||||
region->mouseEventCallbackUserData = 0;
|
||||
region->rightMouseEventCallbackUserData = 0;
|
||||
region->pointsLength = 0;
|
||||
region->field_24 = 0;
|
||||
region->field_2C = 0;
|
||||
region->field_50 = 0;
|
||||
region->field_4C = 0;
|
||||
region->field_48 = 0;
|
||||
region->field_58 = 0;
|
||||
region->field_24 = region->field_28;
|
||||
region->field_2C = region->field_30;
|
||||
region->procs[2] = 0;
|
||||
region->procs[1] = 0;
|
||||
region->procs[0] = 0;
|
||||
region->rightProcs[0] = 0;
|
||||
|
||||
return region;
|
||||
}
|
||||
|
|
22
src/region.h
22
src/region.h
|
@ -6,6 +6,10 @@
|
|||
|
||||
#define REGION_NAME_LENGTH (32)
|
||||
|
||||
typedef struct Region Region;
|
||||
|
||||
typedef void RegionMouseEventCallback(Region* region, void* userData, int event);
|
||||
|
||||
typedef struct Region {
|
||||
char name[REGION_NAME_LENGTH];
|
||||
Point* points;
|
||||
|
@ -18,22 +22,16 @@ typedef struct Region {
|
|||
int pointsLength;
|
||||
int pointsCapacity;
|
||||
Program* program;
|
||||
int field_48;
|
||||
int field_4C;
|
||||
int field_50;
|
||||
int field_54;
|
||||
int field_58;
|
||||
int field_5C;
|
||||
int field_60;
|
||||
int field_64;
|
||||
int procs[4];
|
||||
int rightProcs[4];
|
||||
int field_68;
|
||||
int field_6C;
|
||||
int field_70;
|
||||
int field_74;
|
||||
int field_78;
|
||||
int field_7C;
|
||||
int field_80;
|
||||
int field_84;
|
||||
RegionMouseEventCallback* mouseEventCallback;
|
||||
RegionMouseEventCallback* rightMouseEventCallback;
|
||||
void* mouseEventCallbackUserData;
|
||||
void* rightMouseEventCallbackUserData;
|
||||
void* userData;
|
||||
} Region;
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
#include "window_manager_private.h"
|
||||
#include "world_map.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
@ -567,12 +567,12 @@ Object* scriptGetSelf(Program* program)
|
|||
return script->owner;
|
||||
}
|
||||
|
||||
if ((sid >> 24) != SCRIPT_TYPE_SPATIAL) {
|
||||
if (SID_TYPE(sid) != SCRIPT_TYPE_SPATIAL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Object* object;
|
||||
int fid = buildFid(6, 3, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, 3, 0, 0, 0);
|
||||
objectCreateWithFidPid(&object, fid, -1);
|
||||
objectHide(object, NULL);
|
||||
_obj_toggle_flat(object, NULL);
|
||||
|
@ -595,7 +595,7 @@ Object* scriptGetSelf(Program* program)
|
|||
Script* spatialScript = scriptGetFirstSpatialScript(elevation);
|
||||
while (spatialScript != NULL) {
|
||||
if (spatialScript == script) {
|
||||
objectSetLocation(object, script->sp.built_tile & 0x3FFFFFF, elevation, NULL);
|
||||
objectSetLocation(object, builtTileGetTile(script->sp.built_tile), elevation, NULL);
|
||||
return object;
|
||||
}
|
||||
spatialScript = scriptGetNextSpatialScript();
|
||||
|
@ -780,7 +780,7 @@ void _scrSetQueueTestVals(Object* a1, int a2)
|
|||
int _scrQueueRemoveFixed(Object* obj, void* data)
|
||||
{
|
||||
ScriptEvent* scriptEvent = (ScriptEvent*)data;
|
||||
return obj == _scrQueueTestObj && scriptEvent->field_4 == _scrQueueTestValue;
|
||||
return obj == _scrQueueTestObj && scriptEvent->fixedParam == _scrQueueTestValue;
|
||||
}
|
||||
|
||||
// 0x4A3E60
|
||||
|
@ -792,7 +792,7 @@ int scriptAddTimerEvent(int sid, int delay, int param)
|
|||
}
|
||||
|
||||
scriptEvent->sid = sid;
|
||||
scriptEvent->field_4 = param;
|
||||
scriptEvent->fixedParam = param;
|
||||
|
||||
Script* script;
|
||||
if (scriptGetScript(sid, &script) == -1) {
|
||||
|
@ -814,7 +814,7 @@ int scriptEventWrite(File* stream, void* data)
|
|||
ScriptEvent* scriptEvent = (ScriptEvent*)data;
|
||||
|
||||
if (fileWriteInt32(stream, scriptEvent->sid) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scriptEvent->field_4) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scriptEvent->fixedParam) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -828,7 +828,7 @@ int scriptEventRead(File* stream, void** dataPtr)
|
|||
}
|
||||
|
||||
if (fileReadInt32(stream, &(scriptEvent->sid)) == -1) goto err;
|
||||
if (fileReadInt32(stream, &(scriptEvent->field_4)) == -1) goto err;
|
||||
if (fileReadInt32(stream, &(scriptEvent->fixedParam)) == -1) goto err;
|
||||
|
||||
*dataPtr = scriptEvent;
|
||||
|
||||
|
@ -852,7 +852,7 @@ int scriptEventProcess(Object* obj, void* data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
script->fixedParam = scriptEvent->field_4;
|
||||
script->fixedParam = scriptEvent->fixedParam;
|
||||
|
||||
scriptExecProc(scriptEvent->sid, SCRIPT_PROC_TIMED);
|
||||
|
||||
|
@ -929,7 +929,7 @@ int scriptsHandleRequests()
|
|||
Object* elevatorDoors = objectFindFirstAtElevation(gDude->elevation);
|
||||
while (elevatorDoors != NULL) {
|
||||
int pid = elevatorDoors->pid;
|
||||
if ((pid >> 24) == OBJ_TYPE_SCENERY
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_SCENERY
|
||||
&& (pid == PROTO_ID_0x2000099 || pid == PROTO_ID_0x20001A5 || pid == PROTO_ID_0x20001D6)
|
||||
&& tileDistanceBetween(elevatorDoors->tile, gDude->tile) <= 4) {
|
||||
break;
|
||||
|
@ -955,7 +955,7 @@ int scriptsHandleRequests()
|
|||
Object* elevatorDoors = objectFindFirstAtElevation(gDude->elevation);
|
||||
while (elevatorDoors != NULL) {
|
||||
int pid = elevatorDoors->pid;
|
||||
if ((pid >> 24) == OBJ_TYPE_SCENERY
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_SCENERY
|
||||
&& (pid == PROTO_ID_0x2000099 || pid == PROTO_ID_0x20001A5 || pid == PROTO_ID_0x20001D6)
|
||||
&& tileDistanceBetween(elevatorDoors->tile, gDude->tile) <= 4) {
|
||||
break;
|
||||
|
@ -1035,7 +1035,7 @@ int _scripts_check_state_in_combat()
|
|||
Object* elevatorDoors = objectFindFirstAtElevation(gDude->elevation);
|
||||
while (elevatorDoors != NULL) {
|
||||
int pid = elevatorDoors->pid;
|
||||
if ((pid >> 24) == OBJ_TYPE_SCENERY
|
||||
if (PID_TYPE(pid) == OBJ_TYPE_SCENERY
|
||||
&& (pid == PROTO_ID_0x2000099 || pid == PROTO_ID_0x20001A5 || pid == PROTO_ID_0x20001D6)
|
||||
&& tileDistanceBetween(elevatorDoors->tile, gDude->tile) <= 4) {
|
||||
break;
|
||||
|
@ -1137,8 +1137,8 @@ int scriptsRequestElevator(Object* a1, int a2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// TODO: What the hell is this?
|
||||
tile -= 1005;
|
||||
// In the following code we are looking for an elevator. 5 tiles in each direction
|
||||
tile = tile - (HEX_GRID_WIDTH * 5) - 5; // left upper corner
|
||||
|
||||
Object* obj;
|
||||
for (int y = -5; y < 5; y++) {
|
||||
|
@ -1163,12 +1163,12 @@ int scriptsRequestElevator(Object* a1, int a2)
|
|||
break;
|
||||
}
|
||||
|
||||
tile += 190;
|
||||
tile += HEX_GRID_WIDTH - 10;
|
||||
}
|
||||
|
||||
if (obj != NULL) {
|
||||
elevatorType = obj->data.scenery.elevator.field_0;
|
||||
elevatorLevel = obj->data.scenery.elevator.field_4;
|
||||
elevatorType = obj->data.scenery.elevator.type;
|
||||
elevatorLevel = obj->data.scenery.elevator.level;
|
||||
}
|
||||
|
||||
if (elevatorType == -1) {
|
||||
|
@ -1224,6 +1224,13 @@ int scriptsRequestStealing(Object* a1, Object* a2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Inlined.
|
||||
void _script_make_path(char* path)
|
||||
{
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, gScriptsBasePath);
|
||||
}
|
||||
|
||||
// exec_script_proc
|
||||
// 0x4A4810
|
||||
int scriptExecProc(int sid, int proc)
|
||||
|
@ -1341,7 +1348,8 @@ bool scriptHasProc(int sid, int proc)
|
|||
static int scriptsLoadScriptsList()
|
||||
{
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s", "scripts\\", "scripts.lst");
|
||||
_script_make_path(path);
|
||||
strcat(path, "scripts.lst");
|
||||
|
||||
File* stream = fileOpen(path, "rt");
|
||||
if (stream == NULL) {
|
||||
|
@ -1716,8 +1724,7 @@ static int _scr_header_load()
|
|||
_num_script_indexes = 0;
|
||||
|
||||
char path[COMPAT_MAX_PATH];
|
||||
strcpy(path, _cd_path_base);
|
||||
strcat(path, gScriptsBasePath);
|
||||
_script_make_path(path);
|
||||
strcat(path, "scripts.lst");
|
||||
|
||||
File* stream = fileOpen(path, "rt");
|
||||
|
@ -1757,7 +1764,7 @@ static int scriptWrite(Script* scr, File* stream)
|
|||
if (fileWriteInt32(stream, scr->sid) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scr->field_4) == -1) return -1;
|
||||
|
||||
switch (scr->sid >> 24) {
|
||||
switch (SID_TYPE(scr->sid)) {
|
||||
case SCRIPT_TYPE_SPATIAL:
|
||||
if (fileWriteInt32(stream, scr->sp.built_tile) == -1) return -1;
|
||||
if (fileWriteInt32(stream, scr->sp.radius) == -1) return -1;
|
||||
|
@ -1911,7 +1918,7 @@ static int scriptRead(Script* scr, File* stream)
|
|||
if (fileReadInt32(stream, &(scr->sid)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scr->field_4)) == -1) return -1;
|
||||
|
||||
switch (scr->sid >> 24) {
|
||||
switch (SID_TYPE(scr->sid)) {
|
||||
case SCRIPT_TYPE_SPATIAL:
|
||||
if (fileReadInt32(stream, &(scr->sp.built_tile)) == -1) return -1;
|
||||
if (fileReadInt32(stream, &(scr->sp.radius)) == -1) return -1;
|
||||
|
@ -2066,7 +2073,7 @@ int scriptGetScript(int sid, Script** scriptPtr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
ScriptList* scriptList = &(gScriptLists[sid >> 24]);
|
||||
ScriptList* scriptList = &(gScriptLists[SID_TYPE(sid)]);
|
||||
ScriptListExtent* scriptListExtent = scriptList->head;
|
||||
|
||||
while (scriptListExtent != NULL) {
|
||||
|
@ -2221,7 +2228,7 @@ int scriptRemove(int sid)
|
|||
return -1;
|
||||
}
|
||||
|
||||
ScriptList* scriptList = &(gScriptLists[sid >> 24]);
|
||||
ScriptList* scriptList = &(gScriptLists[SID_TYPE(sid)]);
|
||||
|
||||
ScriptListExtent* scriptListExtent = scriptList->head;
|
||||
int index;
|
||||
|
@ -2399,7 +2406,7 @@ static Script* scriptGetFirstSpatialScript(int elevation)
|
|||
}
|
||||
|
||||
Script* script = &(gScriptsEnumerationScriptListExtent->scripts[0]);
|
||||
if ((script->flags & SCRIPT_FLAG_0x02) != 0 || ((script->sp.built_tile & 0xE0000000) >> 29) != elevation) {
|
||||
if ((script->flags & SCRIPT_FLAG_0x02) != 0 || builtTileGetElevation(script->sp.built_tile) != elevation) {
|
||||
script = scriptGetNextSpatialScript();
|
||||
}
|
||||
|
||||
|
@ -2431,7 +2438,7 @@ static Script* scriptGetNextSpatialScript()
|
|||
}
|
||||
|
||||
Script* script = &(scriptListExtent->scripts[scriptIndex]);
|
||||
if ((script->flags & SCRIPT_FLAG_0x02) == 0 && ((script->sp.built_tile & 0xE0000000) >> 29) == gScriptsEnumerationElevation) {
|
||||
if ((script->flags & SCRIPT_FLAG_0x02) == 0 && builtTileGetElevation(script->sp.built_tile) == gScriptsEnumerationElevation) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2486,7 +2493,7 @@ bool scriptsExecSpatialProc(Object* object, int tile, int elevation)
|
|||
|
||||
_scr_SpatialsEnabled = false;
|
||||
|
||||
int builtTile = ((elevation << 29) & 0xE0000000) | tile;
|
||||
int builtTile = builtTileCreate(tile, elevation);
|
||||
|
||||
for (Script* script = scriptGetFirstSpatialScript(elevation); script != NULL; script = scriptGetNextSpatialScript()) {
|
||||
if (builtTile == script->sp.built_tile) {
|
||||
|
@ -2497,7 +2504,7 @@ bool scriptsExecSpatialProc(Object* object, int tile, int elevation)
|
|||
continue;
|
||||
}
|
||||
|
||||
int distance = tileDistanceBetween(script->sp.built_tile & 0x3FFFFFF, tile);
|
||||
int distance = tileDistanceBetween(builtTileGetTile(script->sp.built_tile), tile);
|
||||
if (distance > script->sp.radius) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2686,7 +2693,7 @@ char* _scr_get_msg_str_speech(int messageListId, int messageId, int a3)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (((gGameDialogHeadFid & 0xF000000) >> 24) != 8) {
|
||||
if (FID_TYPE(gGameDialogHeadFid) != OBJ_TYPE_HEAD) {
|
||||
a3 = 0;
|
||||
}
|
||||
|
||||
|
@ -2717,7 +2724,7 @@ char* _scr_get_msg_str_speech(int messageListId, int messageId, int a3)
|
|||
// 0x4A6D64
|
||||
int scriptGetLocalVar(int sid, int variable, int* value)
|
||||
{
|
||||
if (sid >> 24 == SCRIPT_TYPE_SYSTEM) {
|
||||
if (SID_TYPE(sid) == SCRIPT_TYPE_SYSTEM) {
|
||||
debugPrint("\nError! System scripts/Map scripts not allowed local_vars! ");
|
||||
|
||||
_tempStr1[0] = '\0';
|
||||
|
@ -2859,8 +2866,8 @@ int _scr_explode_scenery(Object* a1, int tile, int radius, int elevation)
|
|||
}
|
||||
|
||||
if (script->procs[SCRIPT_PROC_DAMAGE] > 0
|
||||
&& (script->sp.built_tile & 0xE0000000) >> 29 == elevation
|
||||
&& tileDistanceBetween(script->sp.built_tile & 0x3FFFFFF, tile) <= radius) {
|
||||
&& builtTileGetElevation(script->sp.built_tile) == elevation
|
||||
&& tileDistanceBetween(builtTileGetTile(script->sp.built_tile), tile) <= radius) {
|
||||
scriptIds[scriptsCount] = script->sid;
|
||||
scriptsCount += 1;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#define SCRIPT_FLAG_0x08 (0x08)
|
||||
#define SCRIPT_FLAG_0x10 (0x10)
|
||||
|
||||
// 60 * 60 * 10
|
||||
#define GAME_TIME_TICKS_PER_HOUR 36000
|
||||
|
||||
// 24 * 60 * 60 * 10
|
||||
#define GAME_TIME_TICKS_PER_DAY (864000)
|
||||
|
||||
|
@ -175,6 +178,7 @@ void scriptsRequestDialog(Object* a1);
|
|||
void scriptsRequestEndgame();
|
||||
int scriptsRequestLooting(Object* a1, Object* a2);
|
||||
int scriptsRequestStealing(Object* a1, Object* a2);
|
||||
void _script_make_path(char* path);
|
||||
int scriptExecProc(int sid, int proc);
|
||||
bool scriptHasProc(int sid, int proc);
|
||||
int _scr_find_str_run_info(int a1, int* a2, int sid);
|
||||
|
|
202
src/selfrun.cc
202
src/selfrun.cc
|
@ -1,15 +1,18 @@
|
|||
#include "selfrun.h"
|
||||
|
||||
#include "core.h"
|
||||
#include "db.h"
|
||||
#include "game.h"
|
||||
#include "game_config.h"
|
||||
#include "platform_compat.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// 0x51C8D8
|
||||
int _selfrun_state = 0;
|
||||
int gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
||||
|
||||
// 0x4A8BE0
|
||||
int _selfrun_get_list(char*** fileListPtr, int* fileListLengthPtr)
|
||||
int selfrunInitFileList(char*** fileListPtr, int* fileListLengthPtr)
|
||||
{
|
||||
if (fileListPtr == NULL) {
|
||||
return -1;
|
||||
|
@ -25,7 +28,7 @@ int _selfrun_get_list(char*** fileListPtr, int* fileListLengthPtr)
|
|||
}
|
||||
|
||||
// 0x4A8C10
|
||||
int _selfrun_free_list(char*** fileListPtr)
|
||||
int selfrunFreeFileList(char*** fileListPtr)
|
||||
{
|
||||
if (fileListPtr == NULL) {
|
||||
return -1;
|
||||
|
@ -36,9 +39,198 @@ int _selfrun_free_list(char*** fileListPtr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// 0x4A8C28
|
||||
int selfrunPreparePlayback(const char* fileName, SelfrunData* selfrunData)
|
||||
{
|
||||
if (fileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selfrunData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vcrGetState() != VCR_STATE_TURNED_OFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gSelfrunState != SELFRUN_STATE_TURNED_OFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s", "selfrun\\", fileName);
|
||||
|
||||
if (selfrunReadData(path, selfrunData) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gSelfrunState = SELFRUN_STATE_PLAYING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4A8C88
|
||||
void selfrunPlaybackLoop(SelfrunData* selfrunData)
|
||||
{
|
||||
if (gSelfrunState == SELFRUN_STATE_PLAYING) {
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s", "selfrun\\", selfrunData->recordingFileName);
|
||||
|
||||
if (vcrPlay(path, VCR_TERMINATE_ON_KEY_PRESS | VCR_TERMINATE_ON_MOUSE_PRESS, selfrunPlaybackCompleted)) {
|
||||
bool cursorWasHidden = cursorIsHidden();
|
||||
if (cursorWasHidden) {
|
||||
mouseShowCursor();
|
||||
}
|
||||
|
||||
while (gSelfrunState == SELFRUN_STATE_PLAYING) {
|
||||
int keyCode = _get_input();
|
||||
if (keyCode != selfrunData->stopKeyCode) {
|
||||
gameHandleKey(keyCode, false);
|
||||
}
|
||||
}
|
||||
|
||||
while (mouseGetEvent() != 0) {
|
||||
_get_input();
|
||||
}
|
||||
|
||||
if (cursorWasHidden) {
|
||||
mouseHideCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4A8D28
|
||||
int selfrunPrepareRecording(const char* recordingName, const char* mapFileName, SelfrunData* selfrunData)
|
||||
{
|
||||
if (recordingName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mapFileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vcrGetState() != VCR_STATE_TURNED_OFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gSelfrunState != SELFRUN_STATE_TURNED_OFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(selfrunData->recordingFileName, "%s%s", recordingName, ".vcr");
|
||||
strcpy(selfrunData->mapFileName, mapFileName);
|
||||
|
||||
selfrunData->stopKeyCode = KEY_CTRL_R;
|
||||
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s%s", "selfrun\\", recordingName, ".sdf");
|
||||
|
||||
if (selfrunWriteData(path, selfrunData) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gSelfrunState = SELFRUN_STATE_RECORDING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x4A8DDC
|
||||
void selfrunRecordingLoop(SelfrunData* selfrunData)
|
||||
{
|
||||
if (gSelfrunState == SELFRUN_STATE_RECORDING) {
|
||||
char path[COMPAT_MAX_PATH];
|
||||
sprintf(path, "%s%s", "selfrun\\", selfrunData->recordingFileName);
|
||||
if (vcrRecord(path)) {
|
||||
if (!cursorIsHidden()) {
|
||||
mouseShowCursor();
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
int keyCode = _get_input();
|
||||
if (keyCode == selfrunData->stopKeyCode) {
|
||||
vcrStop();
|
||||
_game_user_wants_to_quit = 2;
|
||||
done = true;
|
||||
} else {
|
||||
gameHandleKey(keyCode, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4A8E74
|
||||
void _selfrun_playback_callback()
|
||||
void selfrunPlaybackCompleted(int reason)
|
||||
{
|
||||
_game_user_wants_to_quit = 2;
|
||||
_selfrun_state = 0;
|
||||
gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
||||
}
|
||||
|
||||
// 0x4A8E8C
|
||||
int selfrunReadData(const char* path, SelfrunData* selfrunData)
|
||||
{
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selfrunData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
File* stream = fileOpen(path, "rb");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc = -1;
|
||||
if (fileReadFixedLengthString(stream, selfrunData->recordingFileName, SELFRUN_RECORDING_FILE_NAME_LENGTH) == 0
|
||||
&& fileReadFixedLengthString(stream, selfrunData->mapFileName, SELFRUN_MAP_FILE_NAME_LENGTH) == 0
|
||||
&& fileReadInt32(stream, &(selfrunData->stopKeyCode)) == 0) {
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// 0x4A8EF4
|
||||
int selfrunWriteData(const char* path, SelfrunData* selfrunData)
|
||||
{
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selfrunData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* masterPatches;
|
||||
configGetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_MASTER_PATCHES_KEY, &masterPatches);
|
||||
|
||||
char selfrunDirectoryPath[COMPAT_MAX_PATH];
|
||||
sprintf(selfrunDirectoryPath, "%s\\%s", masterPatches, "selfrun\\");
|
||||
|
||||
compat_mkdir(selfrunDirectoryPath);
|
||||
|
||||
File* stream = fileOpen(path, "wb");
|
||||
if (stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc = -1;
|
||||
if (fileWriteFixedLengthString(stream, selfrunData->recordingFileName, SELFRUN_RECORDING_FILE_NAME_LENGTH) == 0
|
||||
&& fileWriteFixedLengthString(stream, selfrunData->mapFileName, SELFRUN_MAP_FILE_NAME_LENGTH) == 0
|
||||
&& fileWriteInt32(stream, selfrunData->stopKeyCode) == 0) {
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
fileClose(stream);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,33 @@
|
|||
#ifndef SELFRUN_H
|
||||
#define SELFRUN_H
|
||||
|
||||
extern int _selfrun_state;
|
||||
#define SELFRUN_RECORDING_FILE_NAME_LENGTH 13
|
||||
#define SELFRUN_MAP_FILE_NAME_LENGTH 13
|
||||
|
||||
int _selfrun_get_list(char*** fileListPtr, int* fileListLengthPtr);
|
||||
int _selfrun_free_list(char*** fileListPtr);
|
||||
void _selfrun_playback_callback();
|
||||
typedef enum SelfrunState {
|
||||
SELFRUN_STATE_TURNED_OFF,
|
||||
SELFRUN_STATE_PLAYING,
|
||||
SELFRUN_STATE_RECORDING,
|
||||
} SelfrunState;
|
||||
|
||||
typedef struct SelfrunData {
|
||||
char recordingFileName[SELFRUN_RECORDING_FILE_NAME_LENGTH];
|
||||
char mapFileName[SELFRUN_MAP_FILE_NAME_LENGTH];
|
||||
int stopKeyCode;
|
||||
} SelfrunData;
|
||||
|
||||
static_assert(sizeof(SelfrunData) == 32, "wrong size");
|
||||
|
||||
extern int gSelfrunState;
|
||||
|
||||
int selfrunInitFileList(char*** fileListPtr, int* fileListLengthPtr);
|
||||
int selfrunFreeFileList(char*** fileListPtr);
|
||||
int selfrunPreparePlayback(const char* fileName, SelfrunData* selfrunData);
|
||||
void selfrunPlaybackLoop(SelfrunData* selfrunData);
|
||||
int selfrunPrepareRecording(const char* recordingName, const char* mapFileName, SelfrunData* selfrunData);
|
||||
void selfrunRecordingLoop(SelfrunData* selfrunData);
|
||||
void selfrunPlaybackCompleted(int reason);
|
||||
int selfrunReadData(const char* path, SelfrunData* selfrunData);
|
||||
int selfrunWriteData(const char* path, SelfrunData* selfrunData);
|
||||
|
||||
#endif /* SELFRUN_H */
|
||||
|
|
|
@ -1032,7 +1032,7 @@ int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting)
|
|||
// -4% per item size
|
||||
stealModifier -= 4 * itemGetSize(item);
|
||||
|
||||
if (((a2->fid & 0xF000000) >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (FID_TYPE(a2->fid) == OBJ_TYPE_CRITTER) {
|
||||
// check facing: -25% if face to face
|
||||
if (_is_hit_from_front(a1, a2)) {
|
||||
stealModifier -= 25;
|
||||
|
@ -1064,7 +1064,7 @@ int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting)
|
|||
catchRoll = ROLL_SUCCESS;
|
||||
} else {
|
||||
int catchChance;
|
||||
if ((a2->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(a2->pid) == OBJ_TYPE_CRITTER) {
|
||||
catchChance = skillGetValue(a2, SKILL_STEAL) - stealModifier;
|
||||
} else {
|
||||
catchChance = 30 - stealModifier;
|
||||
|
|
|
@ -162,7 +162,7 @@ static int skilldexWindowInit()
|
|||
|
||||
int frmIndex;
|
||||
for (frmIndex = 0; frmIndex < SKILLDEX_FRM_COUNT; frmIndex++) {
|
||||
int fid = buildFid(6, gSkilldexFrmIds[frmIndex], 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_INTERFACE, gSkilldexFrmIds[frmIndex], 0, 0, 0);
|
||||
gSkilldexFrmData[frmIndex] = artLockFrameDataReturningSize(fid, &(gSkilldexFrmHandles[frmIndex]), &(gSkilldexFrmSizes[frmIndex].width), &(gSkilldexFrmSizes[frmIndex].height));
|
||||
if (gSkilldexFrmData[frmIndex] == NULL) {
|
||||
break;
|
||||
|
|
|
@ -446,7 +446,6 @@ Sound* soundAllocate(int a1, int a2)
|
|||
sound->field_78 = _numBuffers;
|
||||
sound->readLimit = sound->field_7C * _numBuffers;
|
||||
|
||||
|
||||
if (a1 & 0x10) {
|
||||
sound->field_50 = -1;
|
||||
sound->field_3C |= 0x20;
|
||||
|
|
|
@ -57,13 +57,13 @@ typedef enum Stat {
|
|||
STAT_CURRENT_POISON_LEVEL,
|
||||
STAT_CURRENT_RADIATION_LEVEL,
|
||||
STAT_COUNT,
|
||||
|
||||
|
||||
// Number of primary stats.
|
||||
PRIMARY_STAT_COUNT = 7,
|
||||
|
||||
// Number of SPECIAL stats (primary + secondary).
|
||||
SPECIAL_STAT_COUNT = 33,
|
||||
|
||||
|
||||
// Number of saveable stats (i.e. excluding CURRENT pseudostats).
|
||||
SAVEABLE_STAT_COUNT = 35,
|
||||
} Stat;
|
||||
|
@ -81,4 +81,3 @@ typedef enum PcStat {
|
|||
} PcStat;
|
||||
|
||||
#endif /* STAT_DEFS */
|
||||
|
||||
|
|
19
src/tile.cc
19
src/tile.cc
|
@ -14,6 +14,7 @@
|
|||
#include "platform_compat.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct STRUCT_51D99C {
|
||||
|
@ -1228,8 +1229,8 @@ void tileRenderRoofsInRect(Rect* rect, int elevation)
|
|||
int frmId = gTileSquares[elevation]->field_0[squareTile];
|
||||
frmId >>= 16;
|
||||
if ((((frmId & 0xF000) >> 12) & 0x01) == 0) {
|
||||
int fid = buildFid(4, frmId & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(4, 1, 0, 0, 0)) {
|
||||
int fid = buildFid(OBJ_TYPE_TILE, frmId & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
int screenX;
|
||||
int screenY;
|
||||
squareTileToRoofScreenXY(squareTile, &screenX, &screenY, elevation);
|
||||
|
@ -1250,7 +1251,7 @@ static void _roof_fill_on(int a1, int a2, int elevation)
|
|||
int upper = (value >> 16) & 0xFFFF;
|
||||
|
||||
int id = upper & 0xFFF;
|
||||
if (buildFid(4, id, 0, 0, 0) == buildFid(4, 1, 0, 0, 0)) {
|
||||
if (buildFid(OBJ_TYPE_TILE, id, 0, 0, 0) == buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1290,7 +1291,7 @@ static void sub_4B23DC(int a1, int a2, int elevation)
|
|||
int upper = (value >> 16) & 0xFFFF;
|
||||
|
||||
int id = upper & 0xFFF;
|
||||
if (buildFid(4, id, 0, 0, 0) == buildFid(4, 1, 0, 0, 0)) {
|
||||
if (buildFid(OBJ_TYPE_TILE, id, 0, 0, 0) == buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1462,7 +1463,7 @@ void tileRenderFloorsInRect(Rect* rect, int elevation)
|
|||
int v12;
|
||||
int v13;
|
||||
squareTileToScreenXY(v3, &v12, &v13, elevation);
|
||||
int fid = buildFid(4, frmId & 0xFFF, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_TILE, frmId & 0xFFF, 0, 0, 0);
|
||||
tileRenderFloor(fid, v12, v13, rect);
|
||||
}
|
||||
}
|
||||
|
@ -1486,10 +1487,10 @@ bool _square_roof_intersect(int x, int y, int elevation)
|
|||
TileData* ptr = gTileSquares[elevation];
|
||||
int idx = gSquareGridWidth * tileY + tileX;
|
||||
int upper = ptr->field_0[gSquareGridWidth * tileY + tileX] >> 16;
|
||||
int fid = buildFid(4, upper & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(4, 1, 0, 0, 0)) {
|
||||
int fid = buildFid(OBJ_TYPE_TILE, upper & 0xFFF, 0, 0, 0);
|
||||
if (fid != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||
if ((((upper & 0xF000) >> 12) & 1) == 0) {
|
||||
int fid = buildFid(4, upper & 0xFFF, 0, 0, 0);
|
||||
int fid = buildFid(OBJ_TYPE_TILE, upper & 0xFFF, 0, 0, 0);
|
||||
CacheEntry* handle;
|
||||
Art* art = artLock(fid, &handle);
|
||||
if (art != NULL) {
|
||||
|
@ -1583,7 +1584,7 @@ static void _draw_grid(int tile, int elevation, Rect* rect)
|
|||
// 0x4B30C4
|
||||
static void tileRenderFloor(int fid, int x, int y, Rect* rect)
|
||||
{
|
||||
if (artIsObjectTypeHidden((fid & 0xF000000) >> 24) != 0) {
|
||||
if (artIsObjectTypeHidden(FID_TYPE(fid)) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "window.h"
|
||||
|
||||
static void _showRegion(int a1);
|
||||
static int widgetGetTextFlags();
|
||||
static unsigned char widgetGetHighlightColor();
|
||||
|
||||
// 0x50EB1C
|
||||
|
@ -93,3 +92,9 @@ int widgetSetHighlightColor(float a1, float a2, float a3)
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 0x4B5998
|
||||
void sub_4B5998(int win)
|
||||
{
|
||||
// TODO: Incomplete.
|
||||
}
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
int _update_widgets();
|
||||
int widgetGetFont();
|
||||
int widgetSetFont(int a1);
|
||||
int widgetGetTextFlags();
|
||||
int widgetSetTextFlags(int a1);
|
||||
unsigned char widgetGetTextColor();
|
||||
int widgetSetTextColor(float a1, float a2, float a3);
|
||||
int widgetSetHighlightColor(float a1, float a2, float a3);
|
||||
void sub_4B5998(int win);
|
||||
|
||||
#endif /* WIDGET_H */
|
||||
|
|
1590
src/window.cc
1590
src/window.cc
File diff suppressed because it is too large
Load Diff
83
src/window.h
83
src/window.h
|
@ -1,10 +1,18 @@
|
|||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include "geometry.h"
|
||||
#include "interpreter.h"
|
||||
#include "region.h"
|
||||
#include "window_manager.h"
|
||||
|
||||
typedef void (*WINDOWDRAWINGPROC)(unsigned char* src, int src_pitch, int a3, int src_x, int src_y, int src_width, int src_height, int dest_x, int dest_y);
|
||||
typedef void WindowDrawingProc2(unsigned char* buf, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, unsigned char a10);
|
||||
typedef bool(WindowInputHandler)(int key);
|
||||
typedef void(WindowDeleteCallback)(int windowIndex, const char* windowName);
|
||||
typedef void(DisplayInWindowCallback)(int windowIndex, const char* windowName, unsigned char* data, int width, int height);
|
||||
typedef void(ManagedButtonMouseEventCallback)(void* userData, int eventType);
|
||||
typedef void(ManagedWindowCreateCallback)(int windowIndex, const char* windowName, int* flagsPtr);
|
||||
|
||||
typedef enum TextAlignment {
|
||||
TEXT_ALIGNMENT_LEFT,
|
||||
|
@ -12,6 +20,20 @@ typedef enum TextAlignment {
|
|||
TEXT_ALIGNMENT_CENTER,
|
||||
} TextAlignment;
|
||||
|
||||
typedef enum ManagedButtonMouseEvent {
|
||||
MANAGED_BUTTON_MOUSE_EVENT_BUTTON_DOWN,
|
||||
MANAGED_BUTTON_MOUSE_EVENT_BUTTON_UP,
|
||||
MANAGED_BUTTON_MOUSE_EVENT_ENTER,
|
||||
MANAGED_BUTTON_MOUSE_EVENT_EXIT,
|
||||
MANAGED_BUTTON_MOUSE_EVENT_COUNT,
|
||||
} ManagedButtonMouseEvent;
|
||||
|
||||
typedef enum ManagedButtonRightMouseEvent {
|
||||
MANAGED_BUTTON_RIGHT_MOUSE_EVENT_BUTTON_DOWN,
|
||||
MANAGED_BUTTON_RIGHT_MOUSE_EVENT_BUTTON_UP,
|
||||
MANAGED_BUTTON_RIGHT_MOUSE_EVENT_COUNT,
|
||||
} ManagedButtonRightMouseEvent;
|
||||
|
||||
extern int _currentHighlightColorR;
|
||||
extern int gWidgetFont;
|
||||
extern int _currentTextColorG;
|
||||
|
@ -21,27 +43,86 @@ extern int _currentTextColorR;
|
|||
extern int _currentHighlightColorG;
|
||||
extern int _currentHighlightColorB;
|
||||
|
||||
bool _checkRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent);
|
||||
bool _windowCheckRegion(int windowIndex, int mouseX, int mouseY, int mouseEvent);
|
||||
bool _windowRefreshRegions();
|
||||
bool _checkAllRegions();
|
||||
void _windowAddInputFunc(WindowInputHandler* handler);
|
||||
void _doRegionRightFunc(Region* region, int a2);
|
||||
void _doRegionFunc(Region* region, int a2);
|
||||
bool _windowActivateRegion(const char* regionName, int a2);
|
||||
int _getInput();
|
||||
void _doButtonOn(int btn, int keyCode);
|
||||
void sub_4B6F68(int btn, int mouseEvent);
|
||||
void _doButtonOff(int btn, int keyCode);
|
||||
void _doButtonPress(int btn, int keyCode);
|
||||
void _doButtonRelease(int btn, int keyCode);
|
||||
void _doRightButtonPress(int btn, int keyCode);
|
||||
void sub_4B704C(int btn, int mouseEvent);
|
||||
void _doRightButtonRelease(int btn, int keyCode);
|
||||
void _setButtonGFX(int width, int height, unsigned char* normal, unsigned char* pressed, unsigned char* a5);
|
||||
int _windowWidth();
|
||||
int _windowHeight();
|
||||
bool _windowDraw();
|
||||
bool _deleteWindow(const char* windowName);
|
||||
int sub_4B7AC4(const char* windowName, int x, int y, int width, int height);
|
||||
int sub_4B7E7C(const char* windowName, int x, int y, int width, int height);
|
||||
int _createWindow(const char* windowName, int x, int y, int width, int height, int a6, int flags);
|
||||
int _windowOutput(char* string);
|
||||
bool _windowGotoXY(int x, int y);
|
||||
bool _selectWindowID(int index);
|
||||
int _selectWindow(const char* windowName);
|
||||
unsigned char* _windowGetBuffer();
|
||||
int _pushWindow(const char* windowName);
|
||||
int _popWindow();
|
||||
void _windowPrintBuf(int win, char* string, int stringLength, int width, int maxY, int x, int y, int flags, int textAlignment);
|
||||
char** _windowWordWrap(char* string, int maxLength, int a3, int* substringListLengthPtr);
|
||||
void _windowFreeWordList(char** substringList, int substringListLength);
|
||||
void _windowWrapLineWithSpacing(int win, char* string, int width, int height, int x, int y, int flags, int textAlignment, int a9);
|
||||
void _windowWrapLine(int win, char* string, int width, int height, int x, int y, int flags, int textAlignment);
|
||||
bool _windowPrintRect(char* string, int a2, int textAlignment);
|
||||
bool _windowFormatMessage(char* string, int x, int y, int width, int height, int textAlignment);
|
||||
bool _windowPrint(char* string, int a2, int x, int y, int a5);
|
||||
void _displayInWindow(unsigned char* data, int width, int height, int pitch);
|
||||
void _displayFile(char* fileName);
|
||||
void _displayFileRaw(char* fileName);
|
||||
bool _windowDisplay(char* fileName, int x, int y, int width, int height);
|
||||
bool _windowDisplayBuf(unsigned char* src, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight);
|
||||
int _windowGetXres();
|
||||
int _windowGetYres();
|
||||
void _removeProgramReferences_3(Program* program);
|
||||
void _initWindow(int resolution, int a2);
|
||||
void _windowClose();
|
||||
bool _windowDeleteButton(const char* buttonName);
|
||||
bool _windowSetButtonFlag(const char* buttonName, int value);
|
||||
bool _windowAddButtonProc(const char* buttonName, Program* program, int a3, int a4, int a5, int a6);
|
||||
bool _windowAddButton(const char* buttonName, int x, int y, int width, int height, int flags);
|
||||
bool _windowAddButtonGfx(const char* buttonName, char* pressedFileName, char* normalFileName, char* hoverFileName);
|
||||
bool _windowAddButtonProc(const char* buttonName, Program* program, int mouseEnterProc, int mouseExitProc, int mouseDownProc, int mouseUpProc);
|
||||
bool _windowAddButtonRightProc(const char* buttonName, Program* program, int rightMouseDownProc, int rightMouseUpProc);
|
||||
bool _windowAddButtonCfunc(const char* buttonName, ManagedButtonMouseEventCallback* callback, void* userData);
|
||||
bool _windowAddButtonRightCfunc(const char* buttonName, ManagedButtonMouseEventCallback* callback, void* userData);
|
||||
bool _windowAddButtonText(const char* buttonName, const char* text);
|
||||
bool _windowAddButtonTextWithOffsets(const char* buttonName, const char* text, int pressedImageOffsetX, int pressedImageOffsetY, int normalImageOffsetX, int normalImageOffsetY);
|
||||
bool _windowFill(float r, float g, float b);
|
||||
bool _windowFillRect(int x, int y, int width, int height, float r, float g, float b);
|
||||
void _windowEndRegion();
|
||||
bool _windowCheckRegionExists(const char* regionName);
|
||||
bool _windowStartRegion(int initialCapacity);
|
||||
bool _windowAddRegionPoint(int x, int y, bool a3);
|
||||
bool _windowAddRegionProc(const char* regionName, Program* program, int a3, int a4, int a5, int a6);
|
||||
bool _windowAddRegionRightProc(const char* regionName, Program* program, int a3, int a4);
|
||||
bool _windowSetRegionFlag(const char* regionName, int value);
|
||||
bool _windowAddRegionName(const char* regionName);
|
||||
bool _windowDeleteRegion(const char* regionName);
|
||||
void _updateWindows();
|
||||
int _windowMoviePlaying();
|
||||
bool _windowSetMovieFlags(int flags);
|
||||
bool _windowPlayMovie(char* filePath);
|
||||
bool _windowPlayMovieRect(char* filePath, int a2, int a3, int a4, int a5);
|
||||
void _windowStopMovie();
|
||||
void _drawScaled(unsigned char* dest, int destWidth, int destHeight, int destPitch, unsigned char* src, int srcWidth, int srcHeight, int srcPitch);
|
||||
void _drawScaledBuf(unsigned char* dest, int destWidth, int destHeight, unsigned char* src, int srcWidth, int srcHeight);
|
||||
void _alphaBltBuf(unsigned char* src, int srcWidth, int srcHeight, int srcPitch, unsigned char* alphaWindowBuffer, unsigned char* alphaBuffer, unsigned char* dest, int destPitch);
|
||||
void _fillBuf3x3(unsigned char* src, int srcWidth, int srcHeight, unsigned char* dest, int destWidth, int destHeight);
|
||||
|
||||
#endif /* WINDOW_H */
|
||||
|
|
|
@ -24,20 +24,16 @@
|
|||
static void windowFree(int win);
|
||||
static void _win_buffering(bool a1);
|
||||
static void _win_move(int win_index, int x, int y);
|
||||
static void _GNW_win_refresh(Window* window, Rect* rect, unsigned char* a3);
|
||||
static void _win_clip(Window* window, RectListNode** rect, unsigned char* a3);
|
||||
static void _win_drag(int win);
|
||||
static void _refresh_all(Rect* rect, unsigned char* a2);
|
||||
static Button* buttonGetButton(int btn, Window** out_win);
|
||||
static void _win_text(int win, char** fileNameList, int fileNameListLength, int maxWidth, int x, int y, int flags);
|
||||
static int paletteOpenFileImpl(const char* path, int flags);
|
||||
static int paletteReadFileImpl(int fd, void* buf, size_t count);
|
||||
static int paletteCloseFileImpl(int fd);
|
||||
static int _win_register_button_image(int btn, unsigned char* up, unsigned char* down, unsigned char* hover, int a5);
|
||||
static Button* buttonCreateInternal(int win, int x, int y, int width, int height, int mouseEnterEventCode, int mouseExitEventCode, int mouseDownEventCode, int mouseUpEventCode, int flags, unsigned char* up, unsigned char* dn, unsigned char* hover);
|
||||
static int _GNW_check_buttons(Window* window, int* out_a2);
|
||||
static bool _button_under_mouse(Button* button, Rect* rect);
|
||||
static int _win_last_button_winID();
|
||||
static void buttonFree(Button* ptr);
|
||||
static int _win_group_check_buttons(int a1, int* a2, int a3, void (*a4)(int));
|
||||
static int _button_check_group(Button* button);
|
||||
|
@ -59,7 +55,7 @@ static HANDLE _GNW95_title_mutex = INVALID_HANDLE_VALUE;
|
|||
bool gWindowSystemInitialized = false;
|
||||
|
||||
// 0x51E3E4
|
||||
static int _GNW_wcolor[6] = {
|
||||
int _GNW_wcolor[6] = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
@ -244,7 +240,7 @@ int windowManagerInit(VideoSystemInitProc* videoSystemInitProc, VideoSystemExitP
|
|||
window->buttonListHead = NULL;
|
||||
window->field_34 = NULL;
|
||||
window->field_38 = 0;
|
||||
window->field_3C = 0;
|
||||
window->menuBar = NULL;
|
||||
|
||||
gWindowsLength = 1;
|
||||
gWindowSystemInitialized = 1;
|
||||
|
@ -363,14 +359,14 @@ int windowCreate(int x, int y, int width, int height, int a4, int flags)
|
|||
a4 = _colorTable[_GNW_wcolor[0]];
|
||||
}
|
||||
} else if ((a4 & 0xFF00) != 0) {
|
||||
int v1 = (a4 & 0xFF00) >> 8;
|
||||
a4 = (a4 & ~0xFFFF) | _colorTable[_GNW_wcolor[v1]];
|
||||
int colorIndex = (a4 & 0xFF) - 1;
|
||||
a4 = (a4 & ~0xFFFF) | _colorTable[_GNW_wcolor[colorIndex]];
|
||||
}
|
||||
|
||||
window->buttonListHead = 0;
|
||||
window->field_34 = 0;
|
||||
window->field_38 = 0;
|
||||
window->field_3C = 0;
|
||||
window->menuBar = NULL;
|
||||
window->blitProc = blitBufferToBufferTrans;
|
||||
window->field_20 = a4;
|
||||
gOrderedWindowIds[index] = gWindowsLength;
|
||||
|
@ -454,8 +450,8 @@ void windowFree(int win)
|
|||
internal_free(window->buffer);
|
||||
}
|
||||
|
||||
if (window->field_3C != NULL) {
|
||||
internal_free(window->field_3C);
|
||||
if (window->menuBar != NULL) {
|
||||
internal_free(window->menuBar);
|
||||
}
|
||||
|
||||
Button* curr = window->buttonListHead;
|
||||
|
@ -500,7 +496,7 @@ void windowDrawBorder(int win)
|
|||
}
|
||||
|
||||
// 0x4D684C
|
||||
void windowDrawText(int win, char* str, int a3, int x, int y, int a6)
|
||||
void windowDrawText(int win, const char* str, int a3, int x, int y, int a6)
|
||||
{
|
||||
int v7;
|
||||
int v14;
|
||||
|
@ -1021,7 +1017,7 @@ void _win_drag(int win)
|
|||
|
||||
tickersExecute();
|
||||
|
||||
if (_vcr_update() != 3) {
|
||||
if (vcrUpdate() != 3) {
|
||||
_mouse_info();
|
||||
}
|
||||
|
||||
|
@ -1209,10 +1205,10 @@ int _GNW_check_menu_bars(int a1)
|
|||
int v1 = a1;
|
||||
for (int index = gWindowsLength - 1; index >= 1; index--) {
|
||||
Window* window = gWindows[index];
|
||||
if (window->field_3C != NULL) {
|
||||
for (int v2 = 0; v2 < window->field_3C->entriesCount; v2++) {
|
||||
if (v1 == window->field_3C->entries[v2].field_10) {
|
||||
v1 = _GNW_process_menu(window->field_3C, v2);
|
||||
if (window->menuBar != NULL) {
|
||||
for (int pulldownIndex = 0; pulldownIndex < window->menuBar->pulldownsLength; pulldownIndex++) {
|
||||
if (v1 == window->menuBar->pulldowns[pulldownIndex].keyCode) {
|
||||
v1 = _GNW_process_menu(window->menuBar, pulldownIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1242,7 +1238,7 @@ void _win_text(int win, char** fileNameList, int fileNameListLength, int maxWidt
|
|||
int width = window->width;
|
||||
unsigned char* ptr = window->buffer + y * width + x;
|
||||
int lineHeight = fontGetLineHeight();
|
||||
|
||||
|
||||
int step = width * lineHeight;
|
||||
int v1 = lineHeight / 2;
|
||||
int v2 = v1 + 1;
|
||||
|
@ -1376,6 +1372,103 @@ int buttonCreate(int win, int x, int y, int width, int height, int mouseEnterEve
|
|||
return button->id;
|
||||
}
|
||||
|
||||
// 0x4D8308
|
||||
int _win_register_text_button(int win, int x, int y, int mouseEnterEventCode, int mouseExitEventCode, int mouseDownEventCode, int mouseUpEventCode, const char* title, int flags)
|
||||
{
|
||||
Window* window = windowGetWindow(win);
|
||||
|
||||
if (!gWindowSystemInitialized) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (window == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int buttonWidth = fontGetStringWidth(title) + 16;
|
||||
int buttonHeight = fontGetLineHeight() + 7;
|
||||
unsigned char* normal = (unsigned char*)internal_malloc(buttonWidth * buttonHeight);
|
||||
if (normal == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char* pressed = (unsigned char*)internal_malloc(buttonWidth * buttonHeight);
|
||||
if (pressed == NULL) {
|
||||
internal_free(normal);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (window->field_20 == 256 && _GNW_texture != NULL) {
|
||||
// TODO: Incomplete.
|
||||
} else {
|
||||
bufferFill(normal, buttonWidth, buttonHeight, buttonWidth, window->field_20);
|
||||
bufferFill(pressed, buttonWidth, buttonHeight, buttonWidth, window->field_20);
|
||||
}
|
||||
|
||||
_lighten_buf(normal, buttonWidth, buttonHeight, buttonWidth);
|
||||
|
||||
fontDrawText(normal + buttonWidth * 3 + 8, title, buttonWidth, buttonWidth, _colorTable[_GNW_wcolor[3]]);
|
||||
bufferDrawRectShadowed(normal,
|
||||
buttonWidth,
|
||||
2,
|
||||
2,
|
||||
buttonWidth - 3,
|
||||
buttonHeight - 3,
|
||||
_colorTable[_GNW_wcolor[1]],
|
||||
_colorTable[_GNW_wcolor[2]]);
|
||||
bufferDrawRectShadowed(normal,
|
||||
buttonWidth,
|
||||
1,
|
||||
1,
|
||||
buttonWidth - 2,
|
||||
buttonHeight - 2,
|
||||
_colorTable[_GNW_wcolor[1]],
|
||||
_colorTable[_GNW_wcolor[2]]);
|
||||
bufferDrawRect(normal, buttonWidth, 0, 0, buttonWidth - 1, buttonHeight - 1, _colorTable[0]);
|
||||
|
||||
fontDrawText(pressed + buttonWidth * 4 + 9, title, buttonWidth, buttonWidth, _colorTable[_GNW_wcolor[3]]);
|
||||
bufferDrawRectShadowed(pressed,
|
||||
buttonWidth,
|
||||
2,
|
||||
2,
|
||||
buttonWidth - 3,
|
||||
buttonHeight - 3,
|
||||
_colorTable[_GNW_wcolor[2]],
|
||||
_colorTable[_GNW_wcolor[1]]);
|
||||
bufferDrawRectShadowed(pressed,
|
||||
buttonWidth,
|
||||
1,
|
||||
1,
|
||||
buttonWidth - 2,
|
||||
buttonHeight - 2,
|
||||
_colorTable[_GNW_wcolor[2]],
|
||||
_colorTable[_GNW_wcolor[1]]);
|
||||
bufferDrawRect(pressed, buttonWidth, 0, 0, buttonWidth - 1, buttonHeight - 1, _colorTable[0]);
|
||||
|
||||
Button* button = buttonCreateInternal(win,
|
||||
x,
|
||||
y,
|
||||
buttonWidth,
|
||||
buttonHeight,
|
||||
mouseEnterEventCode,
|
||||
mouseExitEventCode,
|
||||
mouseDownEventCode,
|
||||
mouseUpEventCode,
|
||||
flags,
|
||||
normal,
|
||||
pressed,
|
||||
NULL);
|
||||
if (button == NULL) {
|
||||
internal_free(normal);
|
||||
internal_free(pressed);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_button_draw(button, window, button->mouseUpImage, 0, NULL, 0);
|
||||
|
||||
return button->id;
|
||||
}
|
||||
|
||||
// 0x4D8674
|
||||
int _win_register_button_disable(int btn, unsigned char* up, unsigned char* down, unsigned char* hover)
|
||||
{
|
||||
|
|
|
@ -61,26 +61,23 @@ typedef enum ButtonFlags {
|
|||
BUTTON_FLAG_RIGHT_MOUSE_BUTTON_CONFIGURED = 0x080000,
|
||||
} ButtonFlags;
|
||||
|
||||
typedef struct struc_176 {
|
||||
int field_0;
|
||||
int field_4;
|
||||
int field_8;
|
||||
int field_C;
|
||||
int field_10;
|
||||
int field_14;
|
||||
int field_18;
|
||||
typedef struct MenuPulldown {
|
||||
Rect rect;
|
||||
int keyCode;
|
||||
int itemsLength;
|
||||
char** items;
|
||||
int field_1C;
|
||||
int field_20;
|
||||
} struc_176;
|
||||
} MenuPulldown;
|
||||
|
||||
typedef struct struc_177 {
|
||||
typedef struct MenuBar {
|
||||
int win;
|
||||
Rect rect;
|
||||
int entriesCount;
|
||||
struc_176 entries[15];
|
||||
int field_234;
|
||||
int field_238;
|
||||
} struc_177;
|
||||
int pulldownsLength;
|
||||
MenuPulldown pulldowns[15];
|
||||
int borderColor;
|
||||
int backgroundColor;
|
||||
} MenuBar;
|
||||
|
||||
typedef void WindowBlitProc(unsigned char* src, int width, int height, int srcPitch, unsigned char* dest, int destPitch);
|
||||
|
||||
|
@ -102,7 +99,7 @@ typedef struct Window {
|
|||
Button* buttonListHead;
|
||||
Button* field_34;
|
||||
Button* field_38;
|
||||
struc_177* field_3C;
|
||||
MenuBar* menuBar;
|
||||
WindowBlitProc* blitProc;
|
||||
} Window;
|
||||
|
||||
|
@ -151,13 +148,15 @@ typedef int(VideoSystemInitProc)();
|
|||
typedef void(VideoSystemExitProc)();
|
||||
|
||||
extern bool gWindowSystemInitialized;
|
||||
extern int _GNW_wcolor[6];
|
||||
|
||||
int windowManagerInit(VideoSystemInitProc* videoSystemInitProc, VideoSystemExitProc* videoSystemExitProc, int a3);
|
||||
void windowManagerExit(void);
|
||||
int windowCreate(int x, int y, int width, int height, int a4, int flags);
|
||||
void windowDestroy(int win);
|
||||
void windowDrawBorder(int win);
|
||||
void windowDrawText(int win, char* str, int a3, int x, int y, int a6);
|
||||
void windowDrawText(int win, const char* str, int a3, int x, int y, int a6);
|
||||
void _win_text(int win, char** fileNameList, int fileNameListLength, int maxWidth, int x, int y, int flags);
|
||||
void windowDrawLine(int win, int left, int top, int right, int bottom, int color);
|
||||
void windowDrawRect(int win, int left, int top, int right, int bottom, int color);
|
||||
void windowFill(int win, int x, int y, int width, int height, int a6);
|
||||
|
@ -165,6 +164,7 @@ void windowUnhide(int win);
|
|||
void windowHide(int win);
|
||||
void windowRefresh(int win);
|
||||
void windowRefreshRect(int win, const Rect* rect);
|
||||
void _GNW_win_refresh(Window* window, Rect* rect, unsigned char* a3);
|
||||
void windowRefreshAll(Rect* rect);
|
||||
void _win_get_mouse_buf(unsigned char* a1);
|
||||
Window* windowGetWindow(int win);
|
||||
|
@ -178,13 +178,16 @@ int _GNW_check_menu_bars(int a1);
|
|||
void programWindowSetTitle(const char* title);
|
||||
bool showMesageBox(const char* str);
|
||||
int buttonCreate(int win, int x, int y, int width, int height, int mouseEnterEventCode, int mouseExitEventCode, int mouseDownEventCode, int mouseUpEventCode, unsigned char* up, unsigned char* dn, unsigned char* hover, int flags);
|
||||
int _win_register_text_button(int win, int x, int y, int mouseEnterEventCode, int mouseExitEventCode, int mouseDownEventCode, int mouseUpEventCode, const char* title, int flags);
|
||||
int _win_register_button_disable(int btn, unsigned char* up, unsigned char* down, unsigned char* hover);
|
||||
int _win_register_button_image(int btn, unsigned char* up, unsigned char* down, unsigned char* hover, int a5);
|
||||
int buttonSetMouseCallbacks(int btn, ButtonCallback* mouseEnterProc, ButtonCallback* mouseExitProc, ButtonCallback* mouseDownProc, ButtonCallback* mouseUpProc);
|
||||
int buttonSetRightMouseCallbacks(int btn, int rightMouseDownEventCode, int rightMouseUpEventCode, ButtonCallback* rightMouseDownProc, ButtonCallback* rightMouseUpProc);
|
||||
int buttonSetCallbacks(int btn, ButtonCallback* onPressed, ButtonCallback* onUnpressed);
|
||||
int buttonSetMask(int btn, unsigned char* mask);
|
||||
bool _win_button_down(int btn);
|
||||
int buttonGetWindowId(int btn);
|
||||
int _win_last_button_winID();
|
||||
int buttonDestroy(int btn);
|
||||
int buttonEnable(int btn);
|
||||
int buttonDisable(int btn);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,37 @@
|
|||
#ifndef WINDOW_MANAGER_PRIVATE_H
|
||||
#define WINDOW_MANAGER_PRIVATE_H
|
||||
|
||||
typedef struct struc_177 struc_177;
|
||||
#include "geometry.h"
|
||||
|
||||
typedef struct MenuBar MenuBar;
|
||||
|
||||
typedef void(ListSelectionHandler)(char** items, int index);
|
||||
|
||||
extern char gProgramWindowTitle[256];
|
||||
|
||||
int _win_debug(char* a1);
|
||||
int _GNW_process_menu(struc_177* ptr, int i);
|
||||
int _win_list_select(const char* title, char** fileList, int fileListLength, ListSelectionHandler* callback, int x, int y, int a7);
|
||||
int _win_list_select_at(const char* title, char** items, int itemsLength, ListSelectionHandler* callback, int x, int y, int a7, int a8);
|
||||
int _win_get_str(char* dest, int length, const char* title, int x, int y);
|
||||
int _win_msg(const char* string, int x, int y, int flags);
|
||||
int _win_pull_down(char** items, int itemsLength, int x, int y, int a5);
|
||||
int _create_pull_down(char** stringList, int stringListLength, int x, int y, int a5, int a6, Rect* rect);
|
||||
int _win_debug(char* string);
|
||||
void _win_debug_delete(int btn, int keyCode);
|
||||
int _win_register_menu_bar(int win, int x, int y, int width, int height, int borderColor, int backgroundColor);
|
||||
int _win_register_menu_pulldown(int win, int x, char* title, int keyCode, int itemsLength, char** items, int a7, int a8);
|
||||
void _win_delete_menu_bar(int win);
|
||||
int _find_first_letter(int ch, char** stringList, int stringListLength);
|
||||
int _win_width_needed(char** fileNameList, int fileNameListLength);
|
||||
int _win_input_str(int win, char* dest, int maxLength, int x, int y, int textColor, int backgroundColor);
|
||||
int sub_4DBD04(int win, Rect* rect, char** items, int itemsLength, int a5, int a6, MenuBar* menuBar, int pulldownIndex);
|
||||
int _GNW_process_menu(MenuBar* menuBar, int pulldownIndex);
|
||||
int _calc_max_field_chars_wcursor(int a1, int a2);
|
||||
void _GNW_intr_init();
|
||||
void _GNW_intr_exit();
|
||||
void _tm_watch_msgs();
|
||||
void _tm_kill_msg();
|
||||
void _tm_kill_out_of_order(int a1);
|
||||
void _tm_click_response(int btn);
|
||||
int _tm_index_active(int a1);
|
||||
|
||||
#endif /* WINDOW_MANAGER_PRIVATE_H */
|
||||
|
|
113
src/world_map.cc
113
src/world_map.cc
|
@ -102,7 +102,6 @@ typedef enum EncounterFormationType {
|
|||
ENCOUNTER_FORMATION_TYPE_COUNT,
|
||||
} EncounterFormationType;
|
||||
|
||||
|
||||
typedef enum EncounterFrequencyType {
|
||||
ENCOUNTER_FREQUENCY_TYPE_NONE,
|
||||
ENCOUNTER_FREQUENCY_TYPE_RARE,
|
||||
|
@ -1549,7 +1548,7 @@ int worldmapConfigInit()
|
|||
// NOTE: Uninline.
|
||||
worldmapTileInfoInit(tile);
|
||||
|
||||
tile->fid = buildFid(6, artIndex, 0, 0, 0);
|
||||
tile->fid = buildFid(OBJ_TYPE_INTERFACE, artIndex, 0, 0, 0);
|
||||
|
||||
int encounterDifficulty;
|
||||
if (configGetInt(&config, section, "encounter_difficulty", &encounterDifficulty)) {
|
||||
|
@ -1876,7 +1875,7 @@ int _wmReadEncBaseType(char* name, int* valuePtr)
|
|||
|
||||
for (int index = 0; index < entry->field_34; index++) {
|
||||
ENC_BASE_TYPE_38* ptr = &(entry->field_38[index]);
|
||||
if ((ptr->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(ptr->pid) == OBJ_TYPE_CRITTER) {
|
||||
ptr->team = team;
|
||||
}
|
||||
}
|
||||
|
@ -2653,14 +2652,14 @@ int cityInit()
|
|||
city->field_28 = area_idx;
|
||||
|
||||
if (num != -1) {
|
||||
num = buildFid(6, num, 0, 0, 0);
|
||||
num = buildFid(OBJ_TYPE_INTERFACE, num, 0, 0, 0);
|
||||
}
|
||||
|
||||
city->mapFid = num;
|
||||
|
||||
if (configGetInt(&cfg, section, "townmap_label_art_idx", &num)) {
|
||||
if (num != -1) {
|
||||
num = buildFid(6, num, 0, 0, 0);
|
||||
num = buildFid(OBJ_TYPE_INTERFACE, num, 0, 0, 0);
|
||||
}
|
||||
|
||||
city->labelFid = num;
|
||||
|
@ -4021,13 +4020,13 @@ int worldmapSetupCritters(int type_idx, Object** critterPtr, int critterCount)
|
|||
}
|
||||
|
||||
if (*critterPtr == NULL) {
|
||||
if ((v5->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(v5->pid) == OBJ_TYPE_CRITTER) {
|
||||
*critterPtr = object;
|
||||
}
|
||||
}
|
||||
|
||||
if (v5->team != -1) {
|
||||
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
|
||||
if (PID_TYPE(object->pid) == OBJ_TYPE_CRITTER) {
|
||||
object->data.critter.combat.team = v5->team;
|
||||
}
|
||||
}
|
||||
|
@ -4644,7 +4643,7 @@ int worldmapWindowInit()
|
|||
int fid;
|
||||
Art* frm;
|
||||
CacheEntry* frmHandle;
|
||||
|
||||
|
||||
_wmLastRndTime = _get_time();
|
||||
_fontnum = fontGetCurrent();
|
||||
fontSetCurrent(0);
|
||||
|
@ -4666,7 +4665,7 @@ int worldmapWindowInit()
|
|||
return -1;
|
||||
}
|
||||
|
||||
fid = buildFid(6, 136, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 136, 0, 0, 0);
|
||||
frm = artLock(fid, &gWorldmapBoxFrmHandle);
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4678,7 +4677,7 @@ int worldmapWindowInit()
|
|||
artUnlock(gWorldmapBoxFrmHandle);
|
||||
gWorldmapBoxFrmHandle = INVALID_CACHE_ENTRY;
|
||||
|
||||
fid = buildFid(6, 136, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 136, 0, 0, 0);
|
||||
gWorldmapBoxFrmData = artLockFrameData(fid, 0, 0, &gWorldmapBoxFrmHandle);
|
||||
if (gWorldmapBoxFrmData == NULL) {
|
||||
return -1;
|
||||
|
@ -4694,7 +4693,7 @@ int worldmapWindowInit()
|
|||
for (int citySize = 0; citySize < CITY_SIZE_COUNT; citySize++) {
|
||||
CitySizeDescription* citySizeDescription = &(gCitySizeDescriptions[citySize]);
|
||||
|
||||
fid = buildFid(6, 336 + citySize, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 336 + citySize, 0, 0, 0);
|
||||
citySizeDescription->fid = fid;
|
||||
|
||||
frm = artLock(fid, &(citySizeDescription->handle));
|
||||
|
@ -4715,7 +4714,7 @@ int worldmapWindowInit()
|
|||
}
|
||||
}
|
||||
|
||||
fid = buildFid(6, 168, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 168, 0, 0, 0);
|
||||
frm = artLock(fid, &gWorldmapHotspotUpFrmHandle);
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4728,18 +4727,18 @@ int worldmapWindowInit()
|
|||
gWorldmapHotspotUpFrmHandle = INVALID_CACHE_ENTRY;
|
||||
|
||||
// hotspot1.frm - town map selector shape #1
|
||||
fid = buildFid(6, 168, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 168, 0, 0, 0);
|
||||
gWorldmapHotspotUpFrmData = artLockFrameData(fid, 0, 0, &gWorldmapHotspotUpFrmHandle);
|
||||
|
||||
// hotspot2.frm - town map selector shape #2
|
||||
fid = buildFid(6, 223, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 223, 0, 0, 0);
|
||||
gWorldmapHotspotDownFrmData = artLockFrameData(fid, 0, 0, &gWorldmapHotspotDownFrmHandle);
|
||||
if (gWorldmapHotspotDownFrmData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// wmaptarg.frm - world map move target maker #1
|
||||
fid = buildFid(6, 139, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 139, 0, 0, 0);
|
||||
frm = artLock(fid, &gWorldmapDestinationMarkerFrmHandle);
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4752,7 +4751,7 @@ int worldmapWindowInit()
|
|||
gWorldmapDestinationMarkerFrmHandle = INVALID_CACHE_ENTRY;
|
||||
|
||||
// wmaploc.frm - world map location marker
|
||||
fid = buildFid(6, 138, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 138, 0, 0, 0);
|
||||
frm = artLock(fid, &gWorldmapLocationMarkerFrmHandle);
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4765,21 +4764,21 @@ int worldmapWindowInit()
|
|||
gWorldmapLocationMarkerFrmHandle = INVALID_CACHE_ENTRY;
|
||||
|
||||
// wmaptarg.frm - world map move target maker #1
|
||||
fid = buildFid(6, 139, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 139, 0, 0, 0);
|
||||
gWorldmapDestinationMarkerFrmData = artLockFrameData(fid, 0, 0, &gWorldmapDestinationMarkerFrmHandle);
|
||||
if (gWorldmapDestinationMarkerFrmData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// wmaploc.frm - world map location marker
|
||||
fid = buildFid(6, 138, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 138, 0, 0, 0);
|
||||
gWorldmapLocationMarkerFrmData = artLockFrameData(fid, 0, 0, &gWorldmapLocationMarkerFrmHandle);
|
||||
if (gWorldmapLocationMarkerFrmData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int index = 0; index < WORLD_MAP_ENCOUNTER_FRM_COUNT; index++) {
|
||||
fid = buildFid(6, gWorldmapEncounterFrmIds[index], 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, gWorldmapEncounterFrmIds[index], 0, 0, 0);
|
||||
frm = artLock(fid, &(gWorldmapEncounterFrmHandles[index]));
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4799,7 +4798,7 @@ int worldmapWindowInit()
|
|||
}
|
||||
|
||||
// wmtabs.frm - worldmap town tabs underlay
|
||||
fid = buildFid(6, 364, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 364, 0, 0, 0);
|
||||
frm = artLock(fid, &frmHandle);
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4816,14 +4815,14 @@ int worldmapWindowInit()
|
|||
}
|
||||
|
||||
// wmtbedge.frm - worldmap town tabs edging overlay
|
||||
fid = buildFid(6, 367, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 367, 0, 0, 0);
|
||||
gWorldmapTownTabsEdgeFrmData = artLockFrameData(fid, 0, 0, &gWorldmapTownTabsEdgeFrmHandle);
|
||||
if (gWorldmapTownTabsEdgeFrmData == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// wmdial.frm - worldmap night/day dial
|
||||
fid = buildFid(6, 365, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 365, 0, 0, 0);
|
||||
gWorldmapDialFrm = artLock(fid, &gWorldmapDialFrmHandle);
|
||||
if (gWorldmapDialFrm == NULL) {
|
||||
return -1;
|
||||
|
@ -4833,7 +4832,7 @@ int worldmapWindowInit()
|
|||
gWorldmapDialFrmHeight = artGetHeight(gWorldmapDialFrm, 0, 0);
|
||||
|
||||
// wmscreen - worldmap overlay screen
|
||||
fid = buildFid(6, 363, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 363, 0, 0, 0);
|
||||
frm = artLock(fid, &frmHandle);
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4850,7 +4849,7 @@ int worldmapWindowInit()
|
|||
}
|
||||
|
||||
// wmglobe.frm - worldmap globe stamp overlay
|
||||
fid = buildFid(6, 366, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 366, 0, 0, 0);
|
||||
frm = artLock(fid, &frmHandle);
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4867,7 +4866,7 @@ int worldmapWindowInit()
|
|||
}
|
||||
|
||||
// lilredup.frm - little red button up
|
||||
fid = buildFid(6, 8, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 8, 0, 0, 0);
|
||||
frm = artLock(fid, &frmHandle);
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4881,18 +4880,18 @@ int worldmapWindowInit()
|
|||
gWorldmapLittleRedButtonUpFrmData = artLockFrameData(fid, 0, 0, &gWorldmapLittleRedButtonUpFrmHandle);
|
||||
|
||||
// lilreddn.frm - little red button down
|
||||
fid = buildFid(6, 9, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 9, 0, 0, 0);
|
||||
gWorldmapLittleRedButtonDownFrmData = artLockFrameData(fid, 0, 0, &gWorldmapLittleRedButtonDownFrmHandle);
|
||||
|
||||
// months.frm - month strings for pip boy
|
||||
fid = buildFid(6, 129, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 129, 0, 0, 0);
|
||||
gWorldmapMonthsFrm = artLock(fid, &gWorldmapMonthsFrmHandle);
|
||||
if (gWorldmapMonthsFrm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// numbers.frm - numbers for the hit points and fatigue counters
|
||||
fid = buildFid(6, 82, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 82, 0, 0, 0);
|
||||
gWorldmapNumbersFrm = artLock(fid, &gWorldmapNumbersFrmHandle);
|
||||
if (gWorldmapNumbersFrm == NULL) {
|
||||
return -1;
|
||||
|
@ -4902,37 +4901,37 @@ int worldmapWindowInit()
|
|||
buttonCreate(gWorldmapWindow,
|
||||
WM_TOWN_WORLD_SWITCH_X,
|
||||
WM_TOWN_WORLD_SWITCH_Y,
|
||||
littleRedButtonUpWidth,
|
||||
littleRedButtonUpHeight,
|
||||
-1,
|
||||
-1,
|
||||
littleRedButtonUpWidth,
|
||||
littleRedButtonUpHeight,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_UPPERCASE_T,
|
||||
gWorldmapLittleRedButtonUpFrmData,
|
||||
gWorldmapLittleRedButtonDownFrmData,
|
||||
NULL,
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
|
||||
for (int index = 0; index < 7; index++) {
|
||||
_wmTownMapSubButtonIds[index] = buttonCreate(gWorldmapWindow,
|
||||
508,
|
||||
508,
|
||||
138 + 27 * index,
|
||||
littleRedButtonUpWidth,
|
||||
littleRedButtonUpHeight,
|
||||
-1,
|
||||
littleRedButtonUpWidth,
|
||||
littleRedButtonUpHeight,
|
||||
-1,
|
||||
-1,
|
||||
KEY_CTRL_F1 + index,
|
||||
gWorldmapLittleRedButtonUpFrmData,
|
||||
gWorldmapLittleRedButtonDownFrmData,
|
||||
NULL,
|
||||
-1,
|
||||
-1,
|
||||
KEY_CTRL_F1 + index,
|
||||
gWorldmapLittleRedButtonUpFrmData,
|
||||
gWorldmapLittleRedButtonDownFrmData,
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
}
|
||||
|
||||
for (int index = 0; index < WORLDMAP_ARROW_FRM_COUNT; index++) {
|
||||
// 200 - uparwon.frm - character editor
|
||||
// 199 - uparwoff.frm - character editor
|
||||
fid = buildFid(6, 200 - index, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 200 - index, 0, 0, 0);
|
||||
frm = artLock(fid, &(gWorldmapTownListScrollUpFrmHandle[index]));
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4946,7 +4945,7 @@ int worldmapWindowInit()
|
|||
for (int index = 0; index < WORLDMAP_ARROW_FRM_COUNT; index++) {
|
||||
// 182 - dnarwon.frm - character editor
|
||||
// 181 - dnarwoff.frm - character editor
|
||||
fid = buildFid(6, 182 - index, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 182 - index, 0, 0, 0);
|
||||
frm = artLock(fid, &(gWorldmapTownListScrollDownFrmHandle[index]));
|
||||
if (frm == NULL) {
|
||||
return -1;
|
||||
|
@ -4961,35 +4960,35 @@ int worldmapWindowInit()
|
|||
buttonCreate(gWorldmapWindow,
|
||||
WM_TOWN_LIST_SCROLL_UP_X,
|
||||
WM_TOWN_LIST_SCROLL_UP_Y,
|
||||
gWorldmapTownListScrollUpFrmWidth,
|
||||
gWorldmapTownListScrollUpFrmHeight,
|
||||
-1,
|
||||
-1,
|
||||
gWorldmapTownListScrollUpFrmWidth,
|
||||
gWorldmapTownListScrollUpFrmHeight,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_CTRL_ARROW_UP,
|
||||
gWorldmapTownListScrollUpFrmData[WORLDMAP_ARROW_FRM_NORMAL],
|
||||
gWorldmapTownListScrollUpFrmData[WORLDMAP_ARROW_FRM_NORMAL],
|
||||
gWorldmapTownListScrollUpFrmData[WORLDMAP_ARROW_FRM_PRESSED],
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
|
||||
// Scroll down button.
|
||||
buttonCreate(gWorldmapWindow,
|
||||
WM_TOWN_LIST_SCROLL_DOWN_X,
|
||||
WM_TOWN_LIST_SCROLL_DOWN_Y,
|
||||
gWorldmapTownListScrollDownFrmWidth,
|
||||
buttonCreate(gWorldmapWindow,
|
||||
WM_TOWN_LIST_SCROLL_DOWN_X,
|
||||
WM_TOWN_LIST_SCROLL_DOWN_Y,
|
||||
gWorldmapTownListScrollDownFrmWidth,
|
||||
gWorldmapTownListScrollDownFrmHeight,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
KEY_CTRL_ARROW_DOWN,
|
||||
gWorldmapTownListScrollDownFrmData[WORLDMAP_ARROW_FRM_NORMAL],
|
||||
gWorldmapTownListScrollDownFrmData[WORLDMAP_ARROW_FRM_NORMAL],
|
||||
gWorldmapTownListScrollDownFrmData[WORLDMAP_ARROW_FRM_PRESSED],
|
||||
NULL,
|
||||
NULL,
|
||||
BUTTON_FLAG_TRANSPARENT);
|
||||
|
||||
if (gWorldmapIsInCar) {
|
||||
// wmcarmve.frm - worldmap car movie
|
||||
fid = buildFid(6, 433, 0, 0, 0);
|
||||
fid = buildFid(OBJ_TYPE_INTERFACE, 433, 0, 0, 0);
|
||||
gWorldmapCarFrm = artLock(fid, &gWorldmapCarFrmHandle);
|
||||
if (gWorldmapCarFrm == NULL) {
|
||||
return -1;
|
||||
|
|
Loading…
Reference in New Issue