From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/Wasabi/api/script/script.cpp | 269 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 Src/Wasabi/api/script/script.cpp (limited to 'Src/Wasabi/api/script/script.cpp') diff --git a/Src/Wasabi/api/script/script.cpp b/Src/Wasabi/api/script/script.cpp new file mode 100644 index 00000000..4d0df190 --- /dev/null +++ b/Src/Wasabi/api/script/script.cpp @@ -0,0 +1,269 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WASABI_COMPILE_SKIN +#include +#endif +#include +#ifdef WASABI_COMPILE_COMPONENTS +#include //CUT!! +#endif +#include +#include +#include + +extern StringW g_resourcepath; + +// insert the given script in the virtual machine +int Script::addScript(const wchar_t *path, const wchar_t *filename, const wchar_t *id) +{ + static int reentering = 0; + static int redisplay = 0; + + StringPathCombine fpn(path, filename); + + wchar_t olddir[WA_MAX_PATH] = {0}; + Wasabi::Std::getCurDir(olddir, WA_MAX_PATH); + Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath()); + OSFILETYPE fp = WFOPEN(fpn, WF_READONLY_BINARY, NO_FILEREADERS); + Wasabi::Std::setCurDir(olddir); +#ifdef WASABI_COMPILE_SKIN + if (fp == OPEN_FAILED) + { + fpn = StringPathCombine(Skin::getDefaultSkinPath(), filename); + Wasabi::Std::getCurDir(olddir, WA_MAX_PATH); + Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath()); + fp = WFOPEN(fpn, WF_READONLY_BINARY, NO_FILEREADERS); + Wasabi::Std::setCurDir(olddir); +#endif + if (fp == OPEN_FAILED) + { + if (reentering == 1) + { + redisplay = 1; + return -1; + } + reentering = 1; +#ifdef WANT_WASABI_API_WNDMGR + WASABI_API_SKIN->messageBox(StringPrintf("Could not load script \'%s%s\'\r\n\r\nPress \'OK\' to continue.", path, filename), "Skin Warning", MSGBOX_OK, NULL, NULL); +#else + Wasabi::Std::messageBox(StringPrintfW(L"Could not load script \'%s%s\'\r\n\r\nPress \'OK\' to continue.", path, filename), L"Skin Warning", 0); +#endif + if (redisplay) + { +#ifdef WANT_WASABI_API_WNDMGR + WASABI_API_WND->appdeactivation_setbypass(1); +#endif + Wasabi::Std::messageBox(StringPrintfW(L"Could not load script \'%s%s\'\r\n\r\nPress \'OK\' to continue.", path, filename), L"Skin Warning", 0); +#ifdef WANT_WASABI_API_WNDMGR + WASABI_API_WND->appdeactivation_setbypass(0); +#endif + redisplay = 0; + } + reentering = 0; + return -1; + } +#ifdef WASABI_COMPILE_SKIN + } +#endif + + int size = (int)FGETSIZE(fp); + + void *scriptBlock = MALLOC(size); + FREAD(scriptBlock, size, 1, fp); + FCLOSE(fp); + +#ifdef WASABI_COMPILE_COMPONENTS + WasabiKernelController *wkc = Main::getKernelController(); + if (wkc && !wkc->testScript(fpn, scriptBlock, size)) return -1; +#endif + + int vcpuid = VCPU::assignNewScriptId(); + + SystemObject *system = new SystemObject(); + system->setScriptId(vcpuid); + system->setFilename(filename); + + int r = VCPU::addScript(scriptBlock, size, vcpuid); + + if (r != vcpuid) + { + FREE(scriptBlock); + delete system; + return -1; + } + + scriptEntry *e = new scriptEntry; + e->scriptBlock = scriptBlock; + e->vcpuId = vcpuid; + + scriptslist.addItem(e); + + if (!ObjectTable::checkScript(system)) + { + unloadScript(vcpuid); + return -1; + } + + return vcpuid; +} + +// unload the given script +void Script::unloadScript(int id) +{ + for (int i=0;ivcpuId == id) { + VCPU::removeScript(id); + FREE(scriptslist.enumItem(i)->scriptBlock); + delete scriptslist.enumItem(i); + scriptslist.removeByPos(i); + } + } + if (scriptslist.getNumItems() == 0) scriptslist.removeAll(); // disable fortify warning +} + +// unload ALL scripts +void Script::unloadAllScripts() +{ + while (scriptslist.getNumItems()>0) + { + int n = scriptslist.getNumItems()-1; + VCPU::removeScript(scriptslist.enumItem(n)->vcpuId); + FREE(scriptslist.enumItem(n)->scriptBlock); + delete scriptslist.enumItem(n); + scriptslist.removeByPos(n); + } + scriptslist.removeAll(); // disable fortify warning +} + +PtrList Script::scriptslist; + +int Script::codeToSeverity(int code, wchar_t *t, int len) +{ + switch (code) + { + case GURU_INVALIDHEADER: + case GURU_OLDFORMAT: + wcsncpy(t, L"Ignoring script", len); + return 5; + case GURU_DIVBYZERO: + wcsncpy(t, L"Returning 0", len); + return 4; + case GURU_NEWFAILED: + wcsncpy(t, L"Returning NULL", len); + return 4; + case GURU_NULLCALLED: + wcsncpy(t, L"Ignoring call", len); + return 4; + case GURU_INCOMPATIBLEOBJECT: + wcsncpy(t, L"Assigning NULL", len); + return 4; + default: + wcsncpy(t, L"Internal error", len); + return 9; + } +} + +void Script::guruMeditation(SystemObject *script, int code, const wchar_t *pub, int intinfo) { + + wchar_t t[256] = {0}, u[256] = {0}; + codeToSeverity(code, u, 256); + if (pub) + WCSNPRINTF(t, 256, L"guru: %s - #%04X.%04X%04X", pub, code, (intinfo & 0xFFFF), VCPU::VIP & 0xFFFF); + else + WCSNPRINTF(t, 256, L"guru: #%04X.%04X%04X", pub, code, (intinfo & 0xFFFF), VCPU::VIP & 0xFFFF); + if (*u) { + wcscat(t, L" - "); + wcscat(t, u); + } + DebugStringW(L"%s\n", t); + + time_t now; + time(&now); + struct tm *lt = localtime(&now); +#ifdef _WIN32 + wchar_t *p = _wasctime(lt); +#else +#warning port me + wchar_t *p = L"port me"; +#endif + if (p && *p) p[wcslen(p)-1]=0; + + FILE *fout = _wfopen(StringPathCombine(WASABI_API_APP->path_getUserSettingsPath(), L"guru.log"), WF_APPEND_RW); + if (fout) + { + StringPrintfW z(L"%s (%s/%s) - ", p, WASABI_API_SKIN->getSkinName(),script->getFilename()); + if (*u) + { + z.cat(u); + z.cat(L" - "); + } + StringPrintfW log(L"%s#%04X.%04X%04X.%d%s%s\n", z.getValue(), code, (intinfo & 0xFFFF), VCPU::VIP & 0xFFFF, VCPU::VSD, pub?L" ":L"", pub?pub:L""); + fputws(log.getValue(), fout); + fclose(fout); + } + + Guru::spawn(script, code, pub, intinfo); + +#ifdef WASABI_COMPILE_MAKIDEBUG +// WASABI_API_MAKIDEBUG->debugger_createJITD(script->getScriptId(), 1); +// debugApi->debugger_trace(); +#endif +} + +void Script::setScriptParam(int id, const wchar_t *p) +{ + SystemObject *s = SOM::getSystemObjectByScriptId(id); + if (s) s->setParam(p); +} + +void Script::setParentGroup(int id, Group *g) +{ + SystemObject *s = SOM::getSystemObjectByScriptId(id); + if (s) s->setParentGroup(g); +} + +void Script::setSkinPartId(int id, int skinpartid) +{ + SystemObject *s = SOM::getSystemObjectByScriptId(id); + if (s) s->setSkinPartId(skinpartid); +} + +int Script::varIdToGlobal(int id, int script) +{ + return id + VCPU::varBase(script); +} + +int Script::getNumEventsLinked() +{ + return VCPU::eventsTable.getNumItems(); +} + +int Script::getLinkedEventParams(int num, int *dlfid, int *scriptid, int *varid) +{ + VCPUeventEntry *e = VCPU::eventsTable.enumItem(num); + if (dlfid) *dlfid = e->DLFid; + if (scriptid) *scriptid = e->scriptId; + if (varid) *varid = e->varId; + return num; +} + +int Script::getCacheCount() +{ + return VCPU::getCacheCount(); +} + +int Script::getUserAncestor(int varid, int scriptid) +{ + return VCPU::getUserAncestor(varid, scriptid); +} + +int Script::isValidScriptId(int id) +{ + return VCPU::isValidScriptId(id); +} \ No newline at end of file -- cgit