Merge remote-tracking branch 'alex/main' into add_party_member_list

This commit is contained in:
Vasilii Rogin 2023-05-25 18:05:05 +03:00
commit ecef5910ea
9 changed files with 132 additions and 129 deletions

View File

@ -41,7 +41,7 @@ jobs:
uses: actions/checkout@v3
- name: clang-format
run: find src -type f -exec clang-format --dry-run --Werror {} \;
run: find src -type f -name \*.cc -o -name \*.h | xargs clang-format --dry-run --Werror
android:
name: Android

View File

@ -50,6 +50,14 @@ bool mouseDeviceUnacquire()
// 0x4E053C
bool mouseDeviceGetData(MouseData* mouseState)
{
// CE: This function is sometimes called outside loops calling `get_input`
// and subsequently `GNW95_process_message`, so mouse events might not be
// handled by SDL yet.
//
// TODO: Move mouse events processing into `GNW95_process_message` and
// update mouse position manually.
SDL_PumpEvents();
Uint32 buttons = SDL_GetRelativeMouseState(&(mouseState->x), &(mouseState->y));
mouseState->buttons[0] = (buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
mouseState->buttons[1] = (buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;

View File

@ -87,17 +87,17 @@ static void opLeaveCriticalSection(Program* program);
static void opEnterCriticalSection(Program* program);
static void opJump(Program* program);
static void opCall(Program* program);
static void op801F(Program* program);
static void op801C(Program* program);
static void op801D(Program* program);
static void op8020(Program* program);
static void op8021(Program* program);
static void op8025(Program* program);
static void op8026(Program* program);
static void op8022(Program* program);
static void op8023(Program* program);
static void op8024(Program* program);
static void op801E(Program* program);
static void opPopFlags(Program* program);
static void opPopReturn(Program* program);
static void opPopExit(Program* program);
static void opPopFlagsReturn(Program* program);
static void opPopFlagsExit(Program* program);
static void opPopFlagsReturnValExit(Program* program);
static void opPopFlagsReturnValExitExtern(Program* program);
static void opPopFlagsReturnExtern(Program* program);
static void opPopFlagsExitExtern(Program* program);
static void opPopFlagsReturnValExtern(Program* program);
static void opPopAddress(Program* program);
static void opAtoD(Program* program);
static void opDtoA(Program* program);
static void opExitProgram(Program* program);
@ -932,7 +932,7 @@ static void opConditionalOperatorNotEqual(Program* program)
result = value[1].integerValue != value[0].integerValue;
break;
case VALUE_TYPE_PTR:
result = (intptr_t)(value[1].integerValue) != (intptr_t)(value[0].pointerValue);
result = (uintptr_t)(value[1].integerValue) != (uintptr_t)(value[0].pointerValue);
break;
default:
assert(false && "Should be unreachable");
@ -941,7 +941,7 @@ static void opConditionalOperatorNotEqual(Program* program)
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_INT:
result = (intptr_t)(value[1].pointerValue) != (intptr_t)(value[0].integerValue);
result = (uintptr_t)(value[1].pointerValue) != (uintptr_t)(value[0].integerValue);
break;
case VALUE_TYPE_PTR:
result = value[1].pointerValue != value[0].pointerValue;
@ -1028,7 +1028,7 @@ static void opConditionalOperatorEqual(Program* program)
result = value[1].integerValue == value[0].integerValue;
break;
case VALUE_TYPE_PTR:
result = (intptr_t)(value[1].integerValue) == (intptr_t)(value[0].pointerValue);
result = (uintptr_t)(value[1].integerValue) == (uintptr_t)(value[0].pointerValue);
break;
default:
assert(false && "Should be unreachable");
@ -1037,7 +1037,7 @@ static void opConditionalOperatorEqual(Program* program)
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_INT:
result = (intptr_t)(value[1].pointerValue) == (intptr_t)(value[0].integerValue);
result = (uintptr_t)(value[1].pointerValue) == (uintptr_t)(value[0].integerValue);
break;
case VALUE_TYPE_PTR:
result = value[1].pointerValue == value[0].pointerValue;
@ -1131,7 +1131,7 @@ static void opConditionalOperatorLessThanEquals(Program* program)
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_INT:
result = (intptr_t)value[1].pointerValue <= (intptr_t)value[0].integerValue;
result = (uintptr_t)value[1].pointerValue <= (uintptr_t)value[0].integerValue;
break;
default:
assert(false && "Should be unreachable");
@ -1385,7 +1385,7 @@ static void opConditionalOperatorGreaterThan(Program* program)
case VALUE_TYPE_PTR:
switch (value[0].opcode) {
case VALUE_TYPE_INT:
result = (intptr_t)value[1].pointerValue > (intptr_t)value[0].integerValue;
result = (uintptr_t)value[1].pointerValue > (uintptr_t)value[0].integerValue;
break;
default:
assert(false && "Should be unreachable");
@ -2042,7 +2042,7 @@ static void opCall(Program* program)
}
// 0x46B590
static void op801F(Program* program)
static void opPopFlags(Program* program)
{
program->windowId = programStackPopInteger(program);
program->checkWaitFunc = (InterpretCheckWaitFunc*)programStackPopPointer(program);
@ -2051,13 +2051,13 @@ static void op801F(Program* program)
// pop stack 2 -> set program address
// 0x46B63C
static void op801C(Program* program)
static void opPopReturn(Program* program)
{
program->instructionPointer = programReturnStackPopInteger(program);
}
// 0x46B658
static void op801D(Program* program)
static void opPopExit(Program* program)
{
program->instructionPointer = programReturnStackPopInteger(program);
@ -2065,37 +2065,37 @@ static void op801D(Program* program)
}
// 0x46B67C
static void op8020(Program* program)
static void opPopFlagsReturn(Program* program)
{
op801F(program);
opPopFlags(program);
program->instructionPointer = programReturnStackPopInteger(program);
}
// 0x46B698
static void op8021(Program* program)
static void opPopFlagsExit(Program* program)
{
op801F(program);
opPopFlags(program);
program->instructionPointer = programReturnStackPopInteger(program);
program->flags |= PROGRAM_FLAG_0x40;
}
// 0x46B6BC
static void op8025(Program* program)
static void opPopFlagsReturnValExit(Program* program)
{
ProgramValue value = programStackPopValue(program);
op801F(program);
opPopFlags(program);
program->instructionPointer = programReturnStackPopInteger(program);
program->flags |= PROGRAM_FLAG_0x40;
programStackPushValue(program, value);
}
// 0x46B73C
static void op8026(Program* program)
static void opPopFlagsReturnValExitExtern(Program* program)
{
ProgramValue value = programStackPopValue(program);
op801F(program);
opPopFlags(program);
Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
@ -2109,9 +2109,9 @@ static void op8026(Program* program)
}
// 0x46B808
static void op8022(Program* program)
static void opPopFlagsReturnExtern(Program* program)
{
op801F(program);
opPopFlags(program);
Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
@ -2121,9 +2121,9 @@ static void op8022(Program* program)
}
// 0x46B86C
static void op8023(Program* program)
static void opPopFlagsExitExtern(Program* program)
{
op801F(program);
opPopFlags(program);
Program* v1 = (Program*)programReturnStackPopPointer(program);
v1->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
@ -2136,11 +2136,11 @@ static void op8023(Program* program)
// pop value from stack 1 and push it to script popped from stack 2
// 0x46B8D8
static void op8024(Program* program)
static void opPopFlagsReturnValExtern(Program* program)
{
ProgramValue value = programStackPopValue(program);
op801F(program);
opPopFlags(program);
Program* v10 = (Program*)programReturnStackPopPointer(program);
v10->checkWaitFunc = (InterpretCheckWaitFunc*)programReturnStackPopPointer(program);
@ -2164,7 +2164,7 @@ static void op8024(Program* program)
}
// 0x46BA10
static void op801E(Program* program)
static void opPopAddress(Program* program)
{
programReturnStackPopValue(program);
}
@ -2540,17 +2540,17 @@ void interpreterRegisterOpcodeHandlers()
interpreterRegisterOpcode(OPCODE_SWAPA, opSwapReturnStack);
interpreterRegisterOpcode(OPCODE_POP, opPop);
interpreterRegisterOpcode(OPCODE_DUP, opDuplicate);
interpreterRegisterOpcode(OPCODE_POP_RETURN, op801C);
interpreterRegisterOpcode(OPCODE_POP_EXIT, op801D);
interpreterRegisterOpcode(OPCODE_POP_ADDRESS, op801E);
interpreterRegisterOpcode(OPCODE_POP_FLAGS, op801F);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN, op8020);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_EXIT, op8021);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_EXTERN, op8022);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_EXIT_EXTERN, op8023);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXTERN, op8024);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXIT, op8025);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXIT_EXTERN, op8026);
interpreterRegisterOpcode(OPCODE_POP_RETURN, opPopReturn);
interpreterRegisterOpcode(OPCODE_POP_EXIT, opPopExit);
interpreterRegisterOpcode(OPCODE_POP_ADDRESS, opPopAddress);
interpreterRegisterOpcode(OPCODE_POP_FLAGS, opPopFlags);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN, opPopFlagsReturn);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_EXIT, opPopFlagsExit);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_EXTERN, opPopFlagsReturnExtern);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_EXIT_EXTERN, opPopFlagsExitExtern);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXTERN, opPopFlagsReturnValExtern);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXIT, opPopFlagsReturnValExit);
interpreterRegisterOpcode(OPCODE_POP_FLAGS_RETURN_VAL_EXIT_EXTERN, opPopFlagsReturnValExitExtern);
interpreterRegisterOpcode(OPCODE_CHECK_PROCEDURE_ARGUMENT_COUNT, opCheckProcedureArgumentCount);
interpreterRegisterOpcode(OPCODE_LOOKUP_PROCEDURE_BY_NAME, opLookupStringProc);
interpreterRegisterOpcode(OPCODE_POP_BASE, opPopBase);

View File

@ -3098,8 +3098,7 @@ static void _op_inven_cmds(Program* program)
break;
}
} else {
// FIXME: Should be inven_cmds.
scriptPredefinedError(program, "anim", SCRIPT_ERROR_OBJECT_IS_NULL);
scriptPredefinedError(program, "inven_cmds", SCRIPT_ERROR_OBJECT_IS_NULL);
}
programStackPushPointer(program, item);
@ -3657,7 +3656,8 @@ static void opRemoveMultipleObjectsFromInventory(Program* program)
Object* owner = static_cast<Object*>(programStackPopPointer(program));
if (owner == NULL || item == NULL) {
// FIXME: Ruined stack.
scriptPredefinedError(program, "rm_mult_objs_from_inven", SCRIPT_ERROR_OBJECT_IS_NULL);
programStackPushInteger(program, 0);
return;
}

View File

@ -2133,27 +2133,18 @@ Object* objectFindFirst()
{
gObjectFindElevation = 0;
ObjectListNode* objectListNode;
for (gObjectFindTile = 0; gObjectFindTile < HEX_GRID_SIZE; gObjectFindTile++) {
objectListNode = gObjectListHeadByTile[gObjectFindTile];
if (objectListNode) {
break;
ObjectListNode* objectListNode = gObjectListHeadByTile[gObjectFindTile];
while (objectListNode != NULL) {
Object* object = objectListNode->obj;
if (!artIsObjectTypeHidden(FID_TYPE(object->fid))) {
gObjectFindLastObjectListNode = objectListNode;
return object;
}
objectListNode = objectListNode->next;
}
}
if (gObjectFindTile == HEX_GRID_SIZE) {
gObjectFindLastObjectListNode = NULL;
return NULL;
}
while (objectListNode != NULL) {
if (artIsObjectTypeHidden(FID_TYPE(objectListNode->obj->fid)) == 0) {
gObjectFindLastObjectListNode = objectListNode;
return objectListNode->obj;
}
objectListNode = objectListNode->next;
}
gObjectFindLastObjectListNode = NULL;
return NULL;
}
@ -2167,9 +2158,14 @@ Object* objectFindNext()
ObjectListNode* objectListNode = gObjectFindLastObjectListNode->next;
while (gObjectFindTile < HEX_GRID_SIZE) {
while (true) {
if (objectListNode == NULL) {
objectListNode = gObjectListHeadByTile[gObjectFindTile++];
gObjectFindTile++;
if (gObjectFindTile >= HEX_GRID_SIZE) {
break;
}
objectListNode = gObjectListHeadByTile[gObjectFindTile];
}
while (objectListNode != NULL) {
@ -2219,9 +2215,14 @@ Object* objectFindNextAtElevation()
ObjectListNode* objectListNode = gObjectFindLastObjectListNode->next;
while (gObjectFindTile < HEX_GRID_SIZE) {
while (true) {
if (objectListNode == NULL) {
objectListNode = gObjectListHeadByTile[gObjectFindTile++];
gObjectFindTile++;
if (gObjectFindTile >= HEX_GRID_SIZE) {
break;
}
objectListNode = gObjectListHeadByTile[gObjectFindTile];
}
while (objectListNode != NULL) {

View File

@ -6,6 +6,7 @@
#include "animation.h"
#include "color.h"
#include "combat.h"
#include "combat_ai.h"
#include "combat_ai_defs.h"
#include "config.h"
@ -80,7 +81,7 @@ static int _partyMemberPrepItemSave(Object* object);
static int _partyMemberItemSave(Object* object);
static int _partyMemberItemRecover(PartyMemberListItem* a1);
static int _partyMemberClearItemList();
static int _partyFixMultipleMembers();
static int partyFixMultipleMembers();
static int _partyMemberCopyLevelInfo(Object* object, int a2);
// 0x519D9C
@ -655,7 +656,7 @@ int _partyMemberRecoverLoad()
_partyStatePrepped = 0;
if (!_isLoadingGame()) {
_partyFixMultipleMembers();
partyFixMultipleMembers();
}
return 0;
@ -759,7 +760,7 @@ int partyMembersLoad(File* stream)
}
}
_partyFixMultipleMembers();
partyFixMultipleMembers();
for (int index = 1; index < gPartyMemberDescriptionsLength; index++) {
STRU_519DBC* ptr_519DBC = &(_partyMemberLevelUpInfoList[index]);
@ -1209,16 +1210,14 @@ int partyGetBestSkillValue(int skill)
}
// 0x495620
static int _partyFixMultipleMembers()
static int partyFixMultipleMembers()
{
debugPrint("\n\n\n[Party Members]:");
// NOTE: Original code is slightly different (uses two nested loops).
int critterCount = 0;
for (Object* obj = objectFindFirst(); obj != NULL; obj = objectFindNext()) {
if (PID_TYPE(obj->pid) == OBJ_TYPE_CRITTER) {
critterCount++;
}
Object* obj = objectFindFirst();
while (obj != NULL) {
bool isPartyMember = false;
for (int index = 1; index < gPartyMemberDescriptionsLength; index++) {
if (obj->pid == gPartyMemberPids[index]) {
@ -1227,61 +1226,52 @@ static int _partyFixMultipleMembers()
}
}
if (!isPartyMember) {
continue;
}
if (isPartyMember) {
debugPrint("\n PM: %s", critterGetName(obj));
debugPrint("\n PM: %s", critterGetName(obj));
bool v19 = false;
if (obj->sid == -1) {
v19 = true;
} else {
Object* v7 = NULL;
for (int i = 0; i < gPartyMembersLength; i++) {
if (obj->pid == gPartyMembers[i].object->pid) {
v7 = gPartyMembers[i].object;
break;
bool remove = false;
if (obj->sid == -1) {
remove = true;
} else {
// NOTE: Uninline.
Object* partyMember = partyMemberFindByPid(obj->pid);
if (partyMember != NULL && partyMember != obj) {
if (partyMember->sid == obj->sid) {
obj->sid = -1;
}
remove = true;
}
}
if (v7 != NULL && obj != v7) {
if (v7->sid == obj->sid) {
obj->sid = -1;
if (remove) {
// NOTE: Uninline.
if (obj != partyMemberFindByPid(obj->pid)) {
debugPrint("\nDestroying evil critter doppleganger!");
if (obj->sid != -1) {
scriptRemove(obj->sid);
obj->sid = -1;
} else {
if (queueRemoveEventsByType(obj, EVENT_TYPE_SCRIPT) == -1) {
debugPrint("\nERROR Removing Timed Events on FIX remove!!\n");
}
}
_combat_delete_critter(obj);
objectDestroy(obj, NULL);
// Start over.
critterCount = 0;
obj = objectFindFirst();
continue;
} else {
debugPrint("\nError: Attempting to destroy evil critter doppleganger FAILED!");
}
v19 = true;
}
}
if (!v19) {
continue;
}
Object* v10 = NULL;
for (int i = 0; i < gPartyMembersLength; i++) {
if (obj->pid == gPartyMembers[i].object->pid) {
v10 = gPartyMembers[i].object;
}
}
// TODO: Probably wrong.
if (obj == v10) {
debugPrint("\nError: Attempting to destroy evil critter doppleganger FAILED!");
continue;
}
debugPrint("\nDestroying evil critter doppleganger!");
if (obj->sid != -1) {
scriptRemove(obj->sid);
obj->sid = -1;
} else {
if (queueRemoveEventsByType(obj, EVENT_TYPE_SCRIPT) == -1) {
debugPrint("\nERROR Removing Timed Events on FIX remove!!\n");
}
}
objectDestroy(obj, NULL);
obj = objectFindNext();
}
for (int index = 0; index < gPartyMembersLength; index++) {

View File

@ -315,7 +315,7 @@ void compat_resolve_path(char* path)
#ifndef _WIN32
char* pch = path;
DIR *dir;
DIR* dir;
if (pch[0] == '/') {
dir = opendir("/");
pch++;

View File

@ -1766,7 +1766,7 @@ int _obj_use_door(Object* a1, Object* a2, int a3)
animationRegisterCallback(a2, a2, (AnimationCallback*)_set_door_state_open, -1);
}
const char* sfx = sfxBuildOpenName(a2, SCENERY_SOUND_EFFECT_CLOSED);
const char* sfx = sfxBuildOpenName(a2, SCENERY_SOUND_EFFECT_OPEN);
animationRegisterPlaySoundEffect(a2, sfx, -1);
animationRegisterAnimate(a2, ANIM_STAND, 0);

View File

@ -208,6 +208,10 @@ int strParseIntWithKey(char** stringPtr, const char* key, int* valuePtr, const c
*(str + v4) = tmp2;
*(str + v2) = tmp1;
if (**stringPtr == ',') {
*stringPtr = *stringPtr + 1;
}
return result;
}