diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cf9e53..e7a50bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) set(EXECUTABLE_NAME fallout2-ce) -if (APPLE) +if(APPLE) if(IOS) set(CMAKE_OSX_DEPLOYMENT_TARGET "11" CACHE STRING "") set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "") @@ -20,7 +20,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_EXTENSIONS NO) -if (ANDROID) +if(ANDROID) add_library(${EXECUTABLE_NAME} SHARED) else() add_executable(${EXECUTABLE_NAME} WIN32 MACOSX_BUNDLE) @@ -271,6 +271,10 @@ target_sources(${EXECUTABLE_NAME} PUBLIC "src/sfall_lists.h" "src/sfall_opcodes.cc" "src/sfall_opcodes.h" + "src/sfall_script_value.cc" + "src/sfall_script_value.h" + "src/sfall_arrays.cc" + "src/sfall_arrays.h" ) if(IOS) @@ -295,7 +299,7 @@ if(WIN32) ) endif() -if (WIN32) +if(WIN32) target_sources(${EXECUTABLE_NAME} PUBLIC "os/windows/fallout2-ce.ico" "os/windows/fallout2-ce.rc" @@ -356,7 +360,7 @@ if(APPLE) " COMPONENT Runtime) - if (CPACK_BUNDLE_APPLE_CERT_APP) + if(CPACK_BUNDLE_APPLE_CERT_APP) install(CODE " execute_process(COMMAND codesign --deep --force --options runtime --sign \"${CPACK_BUNDLE_APPLE_CERT_APP}\" ${CMAKE_BINARY_DIR}/${MACOSX_BUNDLE_BUNDLE_NAME}.app) " diff --git a/src/sfall_arrays.cc b/src/sfall_arrays.cc index cee6b52..32899ee 100644 --- a/src/sfall_arrays.cc +++ b/src/sfall_arrays.cc @@ -1,4 +1,7 @@ +#include "sfall_arrays.h" #include "interpreter.h" +#include "sfall_script_value.h" + #include #include #include @@ -7,67 +10,9 @@ namespace fallout { -using ArrayId = unsigned int; - static ArrayId nextArrayID = 1; static ArrayId stackArrayId = 1; -class SFallScriptValue : public ProgramValue { -public: - SFallScriptValue() - { - opcode = VALUE_TYPE_INT; - integerValue = 0; - } - SFallScriptValue(int value) - { - opcode = VALUE_TYPE_INT; - integerValue = value; - } - SFallScriptValue(Object* value) - { - opcode = VALUE_TYPE_PTR; - pointerValue = value; - } - SFallScriptValue(ProgramValue& value) - { - // Assuming that pointer is the biggest in size - static_assert(sizeof(decltype(value.floatValue)) <= sizeof(decltype(value.pointerValue))); - static_assert(sizeof(decltype(value.integerValue)) <= sizeof(decltype(value.pointerValue))); - opcode = value.opcode; - pointerValue = value.pointerValue; - } - - bool isInt() const - { - return opcode == VALUE_TYPE_INT; - } - bool isFloat() const - { - return opcode == VALUE_TYPE_FLOAT; - } - bool isPointer() const - { - return opcode == VALUE_TYPE_PTR; - } - - int asInt() const - { - switch (opcode) { - case VALUE_TYPE_INT: - return integerValue; - case VALUE_TYPE_FLOAT: - return static_cast(floatValue); - default: - return 0; - } - } -}; - -#define ARRAYFLAG_ASSOC (1) // is map -#define ARRAYFLAG_CONSTVAL (2) // don't update value of key if the key exists in map -#define ARRAYFLAG_RESERVED (4) - #define ARRAY_MAX_STRING (255) // maximum length of string to be stored as array key or value #define ARRAY_MAX_SIZE (100000) // maximum number of array elements, @@ -100,7 +45,7 @@ ArrayId CreateArray(int len, uint32_t flags) flags = (flags & ~1); // reset 1 bit if (len < 0) { - flags |= ARRAYFLAG_ASSOC; + flags |= SFALL_ARRAYFLAG_ASSOC; throw(std::invalid_argument("Not implemented yet")); }; @@ -171,4 +116,20 @@ ProgramValue GetArray(ArrayId array_id, ProgramValue key) }; return arr->data[element_index]; } + +void SetArray(ArrayId array_id, const SFallScriptValue& key, const SFallScriptValue& val, bool allowUnset) +{ + auto arr = get_array_by_id(array_id); + if (arr == nullptr) { + return; + }; + + if (key.isInt()) { + auto index = key.asInt(); + if (index >= 0 && index < arr->size()) { + arr->data[index] = key; + } + } +} + } \ No newline at end of file diff --git a/src/sfall_arrays.h b/src/sfall_arrays.h index e69de29..f3a1d7b 100644 --- a/src/sfall_arrays.h +++ b/src/sfall_arrays.h @@ -0,0 +1,25 @@ +#ifndef SFALL_ARRAYS +#define SFALL_ARRAYS + +#include "interpreter.h" +#include "object.h" +#include "sfall_script_value.h" +#include + +namespace fallout { + +#define SFALL_ARRAYFLAG_ASSOC (1) // is map +#define SFALL_ARRAYFLAG_CONSTVAL (2) // don't update value of key if the key exists in map +#define SFALL_ARRAYFLAG_RESERVED (4) + +using ArrayId = unsigned int; + +ArrayId CreateArray(int len, uint32_t flags); +ArrayId CreateTempArray(int len, uint32_t flags); +ProgramValue GetArrayKey(ArrayId array_id, int index); +int LenArray(ArrayId array_id); +ProgramValue GetArray(ArrayId array_id, ProgramValue key); +void SetArray(ArrayId array_id, const SFallScriptValue& key, const SFallScriptValue& val, bool allowUnset); + +} +#endif /* SFALL_ARRAYS */ \ No newline at end of file diff --git a/src/sfall_opcodes.cc b/src/sfall_opcodes.cc index 0bccd5f..2c2f026 100644 --- a/src/sfall_opcodes.cc +++ b/src/sfall_opcodes.cc @@ -11,9 +11,10 @@ #include "mouse.h" #include "object.h" #include "party_member.h" -#include "sfall_arrays.cc" +#include "sfall_arrays.h" #include "sfall_global_vars.h" #include "sfall_lists.h" +#include "sfall_script_value.h" #include "stat.h" #include "svga.h" #include @@ -341,10 +342,9 @@ static void opPartyMemberList(Program* program) { auto includeHidden = programStackPopInteger(program); auto objects = get_all_party_members_objects(includeHidden); - auto array_id = CreateTempArray(objects.size(), ARRAYFLAG_RESERVED); - auto arr = get_array_by_id(array_id); - for (int i = 0; i < arr->size(); i++) { - arr->data[i] = SFallScriptValue { objects[i] }; + auto array_id = CreateTempArray(objects.size(), SFALL_ARRAYFLAG_RESERVED); + for (int i = 0; i < LenArray(array_id); i++) { + SetArray(array_id, SFallScriptValue { i }, SFallScriptValue { objects[i] }, false); } programStackPushInteger(program, 100); } diff --git a/src/sfall_script_value.cc b/src/sfall_script_value.cc new file mode 100644 index 0000000..f3e8348 --- /dev/null +++ b/src/sfall_script_value.cc @@ -0,0 +1,55 @@ + +#include "sfall_script_value.h" + +namespace fallout { +SFallScriptValue::SFallScriptValue() +{ + opcode = VALUE_TYPE_INT; + integerValue = 0; +} +SFallScriptValue::SFallScriptValue(int value) +{ + opcode = VALUE_TYPE_INT; + integerValue = value; +}; +SFallScriptValue::SFallScriptValue(Object* value) +{ + opcode = VALUE_TYPE_PTR; + pointerValue = value; +}; +SFallScriptValue::SFallScriptValue(ProgramValue& value) +{ + // Assuming that pointer is the biggest in size + static_assert(sizeof(decltype(value.floatValue)) <= sizeof(decltype(value.pointerValue))); + static_assert(sizeof(decltype(value.integerValue)) <= sizeof(decltype(value.pointerValue))); + opcode = value.opcode; + pointerValue = value.pointerValue; + // TODO: If type is string then copy string +} + +bool SFallScriptValue::isInt() const +{ + return opcode == VALUE_TYPE_INT; +} +bool SFallScriptValue::isFloat() const +{ + return opcode == VALUE_TYPE_FLOAT; +} +bool SFallScriptValue::isPointer() const +{ + return opcode == VALUE_TYPE_PTR; +} + +int SFallScriptValue::asInt() const +{ + switch (opcode) { + case VALUE_TYPE_INT: + return integerValue; + case VALUE_TYPE_FLOAT: + return static_cast(floatValue); + default: + return 0; + } +} + +} \ No newline at end of file diff --git a/src/sfall_script_value.h b/src/sfall_script_value.h new file mode 100644 index 0000000..47e2a60 --- /dev/null +++ b/src/sfall_script_value.h @@ -0,0 +1,23 @@ +#ifndef SFALL_SCRIPT_VALUE +#define SFALL_SCRIPT_VALUE + +#include "interpreter.h" +#include "object.h" + +namespace fallout { + +class SFallScriptValue : public ProgramValue { +public: + SFallScriptValue(); + SFallScriptValue(int value); + SFallScriptValue(Object* value); + SFallScriptValue(ProgramValue& value); + bool isInt() const; + bool isFloat() const; + bool isPointer() const; + int asInt() const; +}; + +} + +#endif /* SFALL_SCRIPT_VALUE */ \ No newline at end of file