diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 1115d0a7..cdeb0439 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -394,6 +394,11 @@ Some utility/math functions are available: - take control of a given critter - passing 0 will reset control back to "real" dude +> array sfall_func1("get_ini_sections", string fileName) +- returns an array of names of all sections in a given INI file + +> array sfall_func2("get_ini_section", string fileName, string section) +- returns an associative array of keys and values for a given INI file and section ------------------------ ------ MORE INFO ------- diff --git a/sfall/Modules/Scripting/Handlers/Metarule.cpp b/sfall/Modules/Scripting/Handlers/Metarule.cpp index f3587b62..94dfed3c 100644 --- a/sfall/Modules/Scripting/Handlers/Metarule.cpp +++ b/sfall/Modules/Scripting/Handlers/Metarule.cpp @@ -125,6 +125,8 @@ static const SfallMetarule metaruleArray[] = { {"intface_is_hidden", sf_intface_is_hidden, 0, 0}, {"item_weight", sf_item_weight, 1, 1, {ARG_OBJECT}}, {"exec_map_update_scripts", sf_exec_map_update_scripts, 0, 0}, + {"get_ini_sections", sf_get_ini_sections, 1, 1, {ARG_STRING}}, + {"get_ini_section", sf_get_ini_section, 2, 2, {ARG_STRING, ARG_STRING}}, {"set_outline", sf_set_outline, 2, 2, {ARG_OBJECT, ARG_INT}}, {"get_outline", sf_get_outline, 1, 1, {ARG_OBJECT}}, {"set_flags", sf_set_flags, 2, 2, {ARG_OBJECT, ARG_INT}}, diff --git a/sfall/Modules/Scripting/Handlers/Misc.cpp b/sfall/Modules/Scripting/Handlers/Misc.cpp index 6a765da6..66b185ff 100644 --- a/sfall/Modules/Scripting/Handlers/Misc.cpp +++ b/sfall/Modules/Scripting/Handlers/Misc.cpp @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +#include + #include "..\..\..\FalloutEngine\Fallout2.h" #include "..\..\AI.h" #include "..\..\Criticals.h" @@ -28,6 +30,7 @@ #include "..\..\PlayerModel.h" #include "..\..\ScriptExtender.h" #include "..\..\Stats.h" +#include "..\Arrays.h" #include "..\OpcodeContext.h" #include "Misc.h" @@ -47,6 +50,10 @@ static void _stdcall strcpy_p(char* to, const char* from) { strcpy_s(to, 64, from); } +/************************************************************************/ +/* TODO: Rewrite these raw handlers using OpcodeContext */ +/************************************************************************/ + void __declspec(naked) op_set_dm_model() { __asm { push ebx; @@ -1714,5 +1721,47 @@ void sf_exec_map_update_scripts(OpcodeContext& ctx) { __asm call fo::funcoffs::scr_exec_map_update_scripts_ } +char getIniSectionBuf[512]; +void sf_get_ini_sections(OpcodeContext& ctx) { + auto fileName = std::string(".\\") + ctx.arg(0).asString(); + GetPrivateProfileSectionNamesA(getIniSectionBuf, 512, fileName.data()); + std::vector sections; + char* section = getIniSectionBuf; + while (*section != 0) { + sections.push_back(section); + section += std::strlen(section) + 1; + } + int arrayId = TempArray(sections.size(), 0); + auto& arr = arrays[arrayId]; + + for (size_t i = 0; i < sections.size(); ++i) { + arr.val[i].set(sections[i]); + } + ctx.setReturn(arrayId); +} + +void sf_get_ini_section(OpcodeContext& ctx) { + auto fileName = std::string(".\\") + ctx.arg(0).asString(); + auto section = ctx.arg(1).asString(); + GetPrivateProfileSectionA(section, getIniSectionBuf, 512, fileName.data()); + int arrayId = TempArray(-1, 0); // associative + auto& arr = arrays[arrayId]; + char *key = getIniSectionBuf, *val = nullptr; + while (*key != 0) { + char* val = std::strpbrk(key, "="); + if (val != nullptr) { + *val = '\0'; + val += 1; + + SetArray(arrayId, ScriptValue(key), ScriptValue(val), false); + + key = val + std::strlen(val) + 1; + } else { + key += std::strlen(key) + 1; + } + } + ctx.setReturn(arrayId); +} + } } diff --git a/sfall/Modules/Scripting/Handlers/Misc.h b/sfall/Modules/Scripting/Handlers/Misc.h index 378b4711..5319b9dd 100644 --- a/sfall/Modules/Scripting/Handlers/Misc.h +++ b/sfall/Modules/Scripting/Handlers/Misc.h @@ -157,5 +157,9 @@ void sf_tile_light(OpcodeContext& ctx); void sf_exec_map_update_scripts(OpcodeContext&); +void sf_get_ini_sections(OpcodeContext&); + +void sf_get_ini_section(OpcodeContext&); + } }