#include <stdint.h>

#include "coduo_engine_structs.h"
#include "script_runtime_private.h"

void Scr_Shutdown(void);
void Scr_Abort(void);
extern qboolean Scr_GetBool(uint32_t index);
extern int32_t Scr_GetInt(uint32_t index);
extern scr_anim_t Scr_GetAnim(uint32_t index, XAnimTree *runtimeTree);
extern coduo_script_anim_tree_ref_t Scr_GetAnimTree(uint32_t index);
extern float Scr_GetFloat(uint32_t index);
extern const char *Scr_GetString(uint32_t index);
extern uint16_t Scr_GetConstString(uint32_t index);
extern const char *Scr_GetDebugString(uint32_t index);
extern const char *Scr_GetIString(uint32_t index);
extern uint16_t Scr_GetConstIString(uint32_t index);
extern void Scr_GetVector(uint32_t index, float *value);
extern uint32_t Scr_GetFunc(uint32_t index);
extern uint32_t Scr_GetEntityNum(uint32_t index, int32_t *classnum);
extern coduo_script_variable_type_t Scr_GetType(uint32_t index);
extern coduo_script_variable_type_t Scr_GetPointerType(uint32_t index);
extern uint32_t Scr_GetNumParam(void);
extern void Scr_AddBool(qboolean value);
extern void Scr_AddInt(int32_t value);
extern void Scr_AddFloat(float value);
extern void Scr_AddAnim(uint32_t value);
extern void Scr_AddUndefined(void);
extern void Scr_AddEntityNum(int32_t entityNum, int32_t classnum);
extern void Scr_AddStruct(void);
extern void Scr_AddString(const char *value);
extern void Scr_AddIString(const char *value);
extern void Scr_AddVector(const float *value);
extern void Scr_AddObject(uint16_t value);
extern void Scr_MakeArray(void);
extern void Scr_AddArray(void);
extern void Scr_AddArrayStringIndexed(uint16_t stringValue);
extern void Scr_ErrorWithDialogMessage(const char *message,
                                       const char *dialogMessage);
extern void Scr_ParamError(int32_t index, const char *message);
extern void Scr_ObjectError(const char *message);
extern void Scr_SetDynamicEntityField(int32_t entityNum, int32_t classNum,
                                      uint16_t fieldName);
extern void Scr_FreeEntityNum(int32_t entnum, int32_t classnum);
extern uint16_t Scr_GetEntityId(int32_t entnum, int32_t classnum);
extern void Scr_SetClassMap(coduo_script_entity_type_usage_t *classMap,
                            uint32_t classCount);
extern void Scr_RemoveClassMap(void);
extern void Scr_AddClassField(uint16_t classnum, const char *name,
                              uint16_t offset);
extern void Scr_AddFields(const char *path, const char *extension);
extern uint16_t Scr_FindField(const char *name, int32_t *type);
extern uint32_t Scr_GetOffset(uint16_t classnum, const char *name);
extern void Scr_CopyEntityNum(int32_t fromEntnum, int32_t toEntnum,
                              int32_t classnum);
extern void Scr_InitSystem(uint32_t sys, uint32_t time);
extern qboolean Scr_HasSourceFiles(void);
extern void Scr_SaveSource(coduo_script_source_io_fn writeCallback);
extern void Scr_LoadSource(coduo_script_source_io_fn readCallback);
extern void Scr_SkipSource(coduo_script_source_io_fn readCallback);
extern void Scr_SavePre(void);
extern void Scr_SavePost(void);
extern void Scr_SaveShutdown(void);
extern void Scr_LoadPre(void);
extern void Scr_LoadShutdown(void);
extern qboolean Scr_LoadScript(const char *filename);
extern coduo_script_anim_tree_ref_t Scr_FindAnimTree(const char *filename);
extern void Scr_FindAnim(const char *treeName, const char *animName,
                         scr_anim_t *anim);
extern uint32_t Scr_GetFunctionHandle(const char *scriptName,
                                      const char *functionName);
extern uint16_t Scr_ExecThread(uint32_t handle, uint32_t paramCount);
extern uint16_t Scr_ExecEntThreadNum(int32_t entnum, int32_t classnum,
                                     uint32_t handle, uint32_t paramCount);
extern qboolean Scr_IsThreadAlive(uint16_t threadId);
extern void Scr_BeginLoadScripts(void);
extern void Scr_BeginLoadAnimTrees(void);
extern void Scr_EndLoadScripts(void);
extern void Scr_EndLoadAnimTrees(void);
extern void Scr_PrecacheAnimTrees(coduo_script_anim_tree_alloc_fn alloc);
extern void Scr_FreeScripts(uint8_t unused);
extern void Scr_ShutdownSystem(uint8_t sys);
extern qboolean Scr_IsSystemActive(uint8_t sys);
extern void Scr_AddExecThread(uint32_t handle, uint32_t paramCount);
extern void Scr_AddExecEntThreadNum(int32_t entnum, int32_t classnum,
                                    uint32_t handle, uint32_t paramCount);
extern void Scr_FreeThread(uint16_t threadId);
extern uint16_t Scr_ConvertThreadToSave(uint16_t threadId);
extern uint16_t Scr_ConvertThreadFromLoad(uint16_t threadId);
extern void Scr_SetString(uint16_t *handle, uint16_t value);
extern uint16_t Scr_AllocString(const char *text);
extern void Scr_NotifyNum(int32_t entnum, int32_t classnum,
                          uint16_t notifyName, uint32_t paramCount);
extern const char *SL_ConvertToString(uint16_t handle);
extern uint16_t SL_GetString(const char *text, uint8_t user);
extern uint16_t SL_GetLowercaseString(const char *text, uint8_t user);
extern uint16_t SL_FindLowercaseString(const char *text);
extern uint16_t Scr_CreateCanonicalFilename(const char *filename);
extern void Scr_SetTime(uint32_t time);
extern void Scr_RunCurrentThreads(void);
extern void Scr_ResetTimeout(void);
extern uint32_t Scr_GetAnimsIndex(XAnim *anims);
extern XAnim *Scr_GetAnims(uint32_t index);
extern void *MT_Alloc(size_t size, int32_t type);
extern void MT_Free(void *memory, size_t size);

/*
 * The original i386 table stores these four core function addresses directly.
 * The game-side wrappers nevertheless forward legacy arguments which the
 * engine implementations do not consume; caller-cleaned i386 cdecl tolerates
 * that machine-code contract. Calling through those incompatible C function
 * types is not valid portable C, and native 64-bit ABIs are not required to
 * preserve it. Use adapters only on wider hosts, while the i386 build keeps
 * the original direct table entries. Scr_AllocString deliberately retains the
 * engine's stock hard-coded string user (1), ignoring the redundant game arg.
 */
#if UINTPTR_MAX > UINT32_MAX
/* NOT_FROM_ORIGINAL_SOURCE: native callback-signature adapter. */
static void coduo_script_callback_save_pre(void *unusedFile)
{
    (void)unusedFile;
    Scr_SavePre();
}

/* NOT_FROM_ORIGINAL_SOURCE: native callback-signature adapter. */
static void coduo_script_callback_save_post(void *unusedFile)
{
    (void)unusedFile;
    Scr_SavePost();
}

/* NOT_FROM_ORIGINAL_SOURCE: native callback-signature adapter. */
static void coduo_script_callback_load_pre(void *unusedFile,
                                           int32_t unusedScriptRunning)
{
    (void)unusedFile;
    (void)unusedScriptRunning;
    Scr_LoadPre();
}

/* NOT_FROM_ORIGINAL_SOURCE: native callback-signature adapter. */
static uint16_t coduo_script_callback_alloc_string(const char *text,
                                                   int32_t unusedUser)
{
    (void)unusedUser;
    return Scr_AllocString(text);
}

#define CODUO_SCRIPT_CALLBACK_SAVE_PRE coduo_script_callback_save_pre
#define CODUO_SCRIPT_CALLBACK_SAVE_POST coduo_script_callback_save_post
#define CODUO_SCRIPT_CALLBACK_LOAD_PRE coduo_script_callback_load_pre
#define CODUO_SCRIPT_CALLBACK_ALLOC_STRING coduo_script_callback_alloc_string
#else
/* The four casts below are the original i386 cdecl contract described above:
 * the game pushes legacy arguments, the engine ignores them, and the caller
 * removes the stack arguments. Keep this incompatibility isolated here. The
 * warning suppression covers only this proved stock-i386 boundary; replacing
 * the functions with adapters here would change its original machine shape. */
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
#define CODUO_SCRIPT_CALLBACK_SAVE_PRE ((void (*)(void *))Scr_SavePre)
#define CODUO_SCRIPT_CALLBACK_SAVE_POST ((void (*)(void *))Scr_SavePost)
#define CODUO_SCRIPT_CALLBACK_LOAD_PRE \
    ((void (*)(void *, int32_t))Scr_LoadPre)
#define CODUO_SCRIPT_CALLBACK_ALLOC_STRING \
    ((uint16_t (*)(const char *, int32_t))Scr_AllocString)
#endif

#define SCRIPT_IMPORT_ASSIGN(importId, member, callback) \
    script_importCallbacks[(importId)].member = (callback)

coduo_script_function_callback_fn
Scr_GetFunction(const char **name, int *developerOnly)
{
    return script_exportCallbacks[CODUO_SCRIPT_EXPORT_GET_FUNCTION]
        .get_function(name, developerOnly);
}

coduo_script_method_callback_fn Scr_GetMethod(const char **name,
                                              int *developerOnly)
{
    return script_exportCallbacks[CODUO_SCRIPT_EXPORT_GET_METHOD]
        .get_method(name, developerOnly);
}

void Scr_SetObjectField(int classnum, int objectNum, int fieldIndex)
{
    script_exportCallbacks[CODUO_SCRIPT_EXPORT_SET_OBJECT_FIELD]
        .object_field(classnum, objectNum, fieldIndex);
}

void Scr_GetObjectField(int classnum, int objectNum, int fieldIndex)
{
    script_exportCallbacks[CODUO_SCRIPT_EXPORT_GET_OBJECT_FIELD]
        .object_field(classnum, objectNum, fieldIndex);
}

void *Scr_LoadRead(uint32_t size)
{
    return script_exportCallbacks[CODUO_SCRIPT_EXPORT_LOAD_READ].load_read(size);
}

coduo_script_import_callback_t *
Scr_NearHook(
    const coduo_script_export_callback_t *gameCallbacks)
{
    if (gameCallbacks != NULL) {
        for (coduo_script_export_t exportId = CODUO_SCRIPT_EXPORT_GET_FUNCTION;
             exportId <= CODUO_SCRIPT_EXPORT_LOAD_READ; ++exportId) {
            script_exportCallbacks[exportId] = gameCallbacks[exportId];
        }
    }

    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_BOOL,
                         bool_from_u32,
                         Scr_GetBool);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_INT,
                         int_from_u32,
                         Scr_GetInt);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_ANIM,
                         anim_ref_from_u32_xanimtree,
                         Scr_GetAnim);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_ANIM_TREE,
                         anim_tree_ref_from_u32,
                         Scr_GetAnimTree);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_FLOAT,
                         float_from_u32,
                         Scr_GetFloat);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_STRING,
                         cstring_from_u32,
                         Scr_GetString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_CONST_STRING,
                         u16_from_u32,
                         Scr_GetConstString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_DEBUG_STRING,
                         cstring_from_u32,
                         Scr_GetDebugString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_ISTRING,
                         cstring_from_u32,
                         Scr_GetIString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_CONST_ISTRING,
                         u16_from_u32,
                         Scr_GetConstIString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_VECTOR,
                         void_from_u32_floatp,
                         Scr_GetVector);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_FUNC,
                         u32_from_u32,
                         Scr_GetFunc);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_ENTITY_NUM,
                         u32_from_u32_intp,
                         Scr_GetEntityNum);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_TYPE,
                         variable_type_from_u32,
                         Scr_GetType);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_POINTER_TYPE,
                         variable_type_from_u32,
                         Scr_GetPointerType);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_NUM_PARAM,
                         u32_from_void,
                         Scr_GetNumParam);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_BOOL,
                         void_from_bool,
                         Scr_AddBool);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_INT,
                         void_from_int,
                         Scr_AddInt);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_FLOAT,
                         void_from_float,
                         Scr_AddFloat);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_ANIM,
                         void_from_u32,
                         Scr_AddAnim);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_UNDEFINED,
                         void_from_void,
                         Scr_AddUndefined);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_ENTITY_NUM,
                         void_from_int_int,
                         Scr_AddEntityNum);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_STRUCT,
                         void_from_void,
                         Scr_AddStruct);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_STRING,
                         void_from_cstring,
                         Scr_AddString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_ISTRING,
                         void_from_cstring,
                         Scr_AddIString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_CONST_STRING,
                         void_from_u16,
                         Scr_AddConstString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_VECTOR,
                         void_from_const_floatp,
                         Scr_AddVector);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_OBJECT,
                         void_from_u16,
                         Scr_AddObject);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_MAKE_ARRAY,
                         void_from_void,
                         Scr_MakeArray);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_ARRAY,
                         void_from_void,
                         Scr_AddArray);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_ARRAY_STRING_INDEXED,
                         void_from_u16,
                         Scr_AddArrayStringIndexed);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ERROR,
                         void_from_cstring,
                         Scr_Error);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ERROR_WITH_DIALOG_MESSAGE,
                         void_from_cstring_cstring,
                         Scr_ErrorWithDialogMessage);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_PARAM_ERROR,
                         void_from_int_cstring,
                         Scr_ParamError);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_OBJECT_ERROR,
                         void_from_cstring,
                         Scr_ObjectError);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SET_DYNAMIC_ENTITY_FIELD,
                         void_from_int_int_u16,
                         Scr_SetDynamicEntityField);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_FREE_ENTITY_NUM,
                         void_from_int_int,
                         Scr_FreeEntityNum);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_ENTITY_ID,
                         u16_from_int_int,
                         Scr_GetEntityId);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SET_CLASS_MAP,
                         void_from_classmap_u32,
                         Scr_SetClassMap);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_REMOVE_CLASS_MAP,
                         void_from_void,
                         Scr_RemoveClassMap);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_CLASS_FIELD,
                         void_from_u16_cstring_u16,
                         Scr_AddClassField);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_FIELDS,
                         void_from_cstring_cstring,
                         Scr_AddFields);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_FIND_FIELD,
                         u16_from_cstring_intp,
                         Scr_FindField);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_OFFSET,
                         u32_from_u16_cstring,
                         Scr_GetOffset);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_COPY_ENTITY_NUM,
                         void_from_int_int_int,
                         Scr_CopyEntityNum);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_INIT,
                         void_from_int_int_int,
                         Scr_Init);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SHUTDOWN,
                         void_from_void,
                         Scr_Shutdown);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ABORT,
                         void_from_void,
                         Scr_Abort);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SET_LOADING,
                         void_from_int,
                         Scr_SetLoading);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_INIT_SYSTEM,
                         void_from_u32_u32,
                         Scr_InitSystem);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ALLOC_GAME_VARIABLE,
                         void_from_void,
                         Scr_AllocGameVariable);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_CHECKSUM,
                         void_from_u32p,
                         Scr_GetChecksum);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_HAS_SOURCE_FILES,
                         bool_from_void,
                         Scr_HasSourceFiles);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SAVE_SOURCE,
                         void_from_source_io,
                         Scr_SaveSource);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_LOAD_SOURCE,
                         void_from_source_io,
                         Scr_LoadSource);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SKIP_SOURCE,
                         void_from_source_io,
                         Scr_SkipSource);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SAVE_PRE,
                         void_from_voidp,
                         CODUO_SCRIPT_CALLBACK_SAVE_PRE);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SAVE_POST,
                         void_from_voidp,
                         CODUO_SCRIPT_CALLBACK_SAVE_POST);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SAVE_SHUTDOWN,
                         void_from_void,
                         Scr_SaveShutdown);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_LOAD_PRE,
                         void_from_voidp_int,
                         CODUO_SCRIPT_CALLBACK_LOAD_PRE);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_LOAD_SHUTDOWN,
                         void_from_void,
                         Scr_LoadShutdown);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_LOAD_SCRIPT,
                         bool_from_cstring,
                         Scr_LoadScript);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_FIND_ANIM_TREE,
                         anim_tree_ref_from_cstring,
                         Scr_FindAnimTree);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_FIND_ANIM,
                         void_from_cstring_cstring_animref,
                         Scr_FindAnim);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_FUNCTION_HANDLE,
                         u32_from_cstring_cstring,
                         Scr_GetFunctionHandle);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_EXEC_THREAD,
                         u16_from_u32_u32,
                         Scr_ExecThread);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_EXEC_ENT_THREAD_NUM,
                         u16_from_int_int_u32_u32,
                         Scr_ExecEntThreadNum);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_IS_THREAD_ALIVE,
                         bool_from_u16,
                         Scr_IsThreadAlive);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_BEGIN_LOAD_SCRIPTS,
                         void_from_void,
                         Scr_BeginLoadScripts);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_BEGIN_LOAD_ANIM_TREES,
                         void_from_void,
                         Scr_BeginLoadAnimTrees);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_END_LOAD_SCRIPTS,
                         void_from_void,
                         Scr_EndLoadScripts);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_END_LOAD_ANIM_TREES,
                         void_from_void,
                         Scr_EndLoadAnimTrees);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_PRECACHE_ANIM_TREES,
                         void_from_anim_tree_alloc,
                         Scr_PrecacheAnimTrees);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_FREE_SCRIPTS,
                         void_from_u8,
                         Scr_FreeScripts);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_FREE_GAME_VARIABLE,
                         void_from_bool,
                         Scr_FreeGameVariable);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SHUTDOWN_SYSTEM,
                         void_from_u8,
                         Scr_ShutdownSystem);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_IS_SYSTEM_ACTIVE,
                         bool_from_u8,
                         Scr_IsSystemActive);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_EXEC_THREAD,
                         void_from_u32_u32,
                         Scr_AddExecThread);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ADD_EXEC_ENT_THREAD_NUM,
                         void_from_int_int_u32_u32,
                         Scr_AddExecEntThreadNum);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_FREE_THREAD,
                         void_from_u16,
                         Scr_FreeThread);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_CONVERT_THREAD_TO_SAVE,
                         u16_from_u16,
                         Scr_ConvertThreadToSave);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_CONVERT_THREAD_FROM_LOAD,
                         u16_from_u16,
                         Scr_ConvertThreadFromLoad);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SET_STRING,
                         void_from_voidp_u16,
                         Scr_SetString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_ALLOC_STRING,
                         u16_from_cstring_int,
                         CODUO_SCRIPT_CALLBACK_ALLOC_STRING);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_NOTIFY_NUM,
                         void_from_int_int_u16_u32,
                         Scr_NotifyNum);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_NOTIFY_ID,
                         void_from_u16_u16_u32,
                         Scr_NotifyId);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SL_CONVERT_TO_STRING,
                         cstring_from_u16,
                         SL_ConvertToString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SL_GET_STRING,
                         u16_from_cstring_u8,
                         SL_GetString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SL_GET_LOWERCASE_STRING,
                         u16_from_cstring_u8,
                         SL_GetLowercaseString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SL_FIND_LOWERCASE_STRING,
                         u16_from_cstring,
                         SL_FindLowercaseString);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_CREATE_CANONICAL_FILENAME,
                         u16_from_cstring,
                         Scr_CreateCanonicalFilename);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_SET_TIME,
                         void_from_u32,
                         Scr_SetTime);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_RUN_CURRENT_THREADS,
                         void_from_void,
                         Scr_RunCurrentThreads);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_RESET_TIMEOUT,
                         void_from_void,
                         Scr_ResetTimeout);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_ANIMS_INDEX,
                         u32_from_xanim,
                         Scr_GetAnimsIndex);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_GET_ANIMS,
                         xanim_from_u32,
                         Scr_GetAnims);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_MT_ALLOC,
                         voidp_from_size_int,
                         MT_Alloc);
    SCRIPT_IMPORT_ASSIGN(CODUO_SCRIPT_IMPORT_MT_FREE,
                         void_from_voidp_size,
                         MT_Free);

    return script_importCallbacks;
}

#if UINTPTR_MAX == UINT32_MAX
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif

void Scr_Shutdown(void)
{
    if (script_runtimeActive != qfalse) {
        script_runtimeActive = qfalse;
    }
}

void Scr_Abort(void)
{
    script_timeArrayHandle = 0;
    script_runtimeActive = qfalse;
}

void Scr_SetLoading(
    int32_t enabled)
{
    script_loopWatchdogWarningFlag = enabled;
}

#undef SCRIPT_IMPORT_ASSIGN
#undef CODUO_SCRIPT_CALLBACK_SAVE_PRE
#undef CODUO_SCRIPT_CALLBACK_SAVE_POST
#undef CODUO_SCRIPT_CALLBACK_LOAD_PRE
#undef CODUO_SCRIPT_CALLBACK_ALLOC_STRING
