diff --git a/EEex-v2.6.6.0/EEex-v2.6.6.0.vcxproj b/EEex-v2.6.6.0/EEex-v2.6.6.0.vcxproj
index f354478..206c946 100644
--- a/EEex-v2.6.6.0/EEex-v2.6.6.0.vcxproj
+++ b/EEex-v2.6.6.0/EEex-v2.6.6.0.vcxproj
@@ -15,6 +15,7 @@
+
@@ -23,6 +24,7 @@
+
@@ -33,9 +35,11 @@
+
+
@@ -46,6 +50,9 @@
+
+
+
16.0
Win32Proj
@@ -69,6 +76,7 @@
+
@@ -146,5 +154,6 @@
+
\ No newline at end of file
diff --git a/EEex-v2.6.6.0/EEex-v2.6.6.0.vcxproj.filters b/EEex-v2.6.6.0/EEex-v2.6.6.0.vcxproj.filters
index 8cfa8c8..d5c3005 100644
--- a/EEex-v2.6.6.0/EEex-v2.6.6.0.vcxproj.filters
+++ b/EEex-v2.6.6.0/EEex-v2.6.6.0.vcxproj.filters
@@ -84,6 +84,12 @@
Source Files\EEex-v2.6.6.0
+
+ Source Files\EEex-v2.6.6.0
+
+
+ Source Files\EEex-v2.6.6.0
+
@@ -122,6 +128,12 @@
Header Files\EEex-v2.6.6.0
+
+ Header Files\EEex-v2.6.6.0
+
+
+ Header Files\EEex-v2.6.6.0
+
@@ -131,4 +143,9 @@
Build Tasks
+
+
+ Source Files\EEex-v2.6.6.0
+
+
\ No newline at end of file
diff --git a/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/EEex.h b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/EEex.h
index 3cbc1ed..edc3203 100644
--- a/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/EEex.h
+++ b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/EEex.h
@@ -55,6 +55,7 @@ namespace EEex {
int __cdecl Override_Infinity_TransitionMenu(lua_State* L);
int __cdecl Override_Infinity_WriteINILine(lua_State* L);
void __cdecl Override_uiDoFile(char* fileName);
+ void __cdecl Override_uiDrawMenuStack();
bool __cdecl Override_uiEventMenuStack(SDL_Event* pEvent, SDL_Rect* pWindow);
//-------------------------//
@@ -95,6 +96,8 @@ namespace EEex {
bool Opcode_Hook_Op280_ShouldSuppressWildSurgeVisuals(CGameSprite* pSprite);
// op319
bool Opcode_Hook_Op319_IsInverted(CGameEffect* pEffect);
+ // op342
+ void Opcode_Hook_Op342_OnUnhandledParam2(CGameEffect* pEffect, CGameSprite* pSprite);
// New op400
int Opcode_Hook_SetTemporaryAIScript_ApplyEffect(CGameEffect* pEffect, CGameSprite* pSprite);
void Opcode_Hook_SetTemporaryAIScript_OnRemove(CGameEffect* pEffect, CGameSprite* pSprite);
@@ -124,6 +127,7 @@ namespace EEex {
void Sprite_Hook_OnDestruct(CGameSprite* pSprite);
void Sprite_Hook_OnAfterEffectListUnmarshalled(CGameSprite* pSprite);
void Sprite_Hook_OnBeforeEffectListMarshalled(CGameSprite* pSprite);
+ byte Sprite_Hook_OnGetAttackFrameType(CGameSprite* pSprite, byte numAttacks);
////////////
// Action //
@@ -160,6 +164,7 @@ namespace EEex {
/////////
void Fix_Hook_HandleMiddleMouseDrag(SDL_Event* pEvent);
+ void Fix_Hook_ImplementWSPECIALSpeedColumn(CGameSprite* pSprite, int nProficiencyLevel, bool bOffHand);
void Fix_Hook_OnBeforeUIKillCapture();
bool Fix_Hook_OnUIItemCheckRenderScrollbar(uiItem* pItem, bool bVisible);
bool Fix_Hook_ShouldProcessEffectListSkipRolls();
diff --git a/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/engine_function_names.hpp b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/engine_function_names.hpp
new file mode 100644
index 0000000..7cd1fe3
--- /dev/null
+++ b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/engine_function_names.hpp
@@ -0,0 +1,8 @@
+
+#pragma once
+
+#include
+
+const std::string& GetContainingFunctionName(uintptr_t address);
+const std::string& GetFunctionName(uintptr_t address);
+void LoadFunctionNames();
diff --git a/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/profiler.hpp b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/profiler.hpp
new file mode 100644
index 0000000..6829043
--- /dev/null
+++ b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/profiler.hpp
@@ -0,0 +1,30 @@
+
+#pragma once
+
+#include "time_util.hpp"
+
+enum class TraceType
+{
+ NONE,
+ NORMAL,
+ SPAM
+};
+
+#pragma pack(push, 1)
+struct SavedRegisters
+{
+ byte xmm1[16];
+ byte xmm0[16];
+ uintptr_t r11;
+ uintptr_t r10;
+ uintptr_t r9;
+ uintptr_t r8;
+ uintptr_t rdx;
+ uintptr_t rcx;
+ uintptr_t rax;
+};
+#pragma pack(pop)
+
+void Profiler_StartTrace(TimeType startTime, TraceType toStartType);
+void __stdcall Profiler_Trace(uintptr_t funcAddress, const SavedRegisters* savedRegisters, void* stackPtr);
+void Profiler_RegisterTrace(const char* traceName, uintptr_t address, TimeType logTimeThreshold);
diff --git a/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/time_util.hpp b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/time_util.hpp
index 545e4d3..d8d2257 100644
--- a/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/time_util.hpp
+++ b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0/time_util.hpp
@@ -1,11 +1,17 @@
#pragma once
+//-----------------------------//
+// Type Defs //
+//-----------------------------//
+
+typedef long long TimeType;
+
//-----------------------------//
// Functions //
//-----------------------------//
DWORD getHighestRefreshRate();
-long long getInitTime();
-long long getTime();
+TimeType getInitTime();
+TimeType getTime();
void initTimeUtil();
diff --git a/EEex-v2.6.6.0/headers/EEex-v2.6.6.0_generated/Baldur-v2.6.6.0_generated.h b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0_generated/Baldur-v2.6.6.0_generated.h
index 011ad69..0b0048d 100644
--- a/EEex-v2.6.6.0/headers/EEex-v2.6.6.0_generated/Baldur-v2.6.6.0_generated.h
+++ b/EEex-v2.6.6.0/headers/EEex-v2.6.6.0_generated/Baldur-v2.6.6.0_generated.h
@@ -195,10 +195,14 @@ struct Item_Header_st;
struct Item_ability_st;
struct Item_effect_st;
union SDL_Event;
+struct SDL_MessageBoxButtonData;
+struct SDL_MessageBoxColorScheme;
struct SDL_PixelFormat;
struct SDL_Point;
+struct SDL_PrivateGLESData;
struct SDL_Rect;
struct SDL_Surface;
+struct SDL_VideoDevice;
struct SDL_Window;
struct STR_RES;
struct Spell_Header_st;
@@ -258,6 +262,11 @@ struct SDL_Cursor
SDL_Cursor() = delete;
};
+struct SDL_PrivateGLESData
+{
+ SDL_PrivateGLESData() = delete;
+};
+
struct SDL_WindowUserData
{
char* name;
@@ -1559,6 +1568,15 @@ struct SDL_version
SDL_version() = delete;
};
+struct SDL_MessageBoxColor
+{
+ unsigned __int8 r;
+ unsigned __int8 g;
+ unsigned __int8 b;
+
+ SDL_MessageBoxColor() = delete;
+};
+
struct SDL_Color
{
unsigned __int8 r;
@@ -2013,6 +2031,31 @@ struct SDL_SysWMmsg
SDL_SysWMmsg() = delete;
};
+struct SDL_SysWMinfo
+{
+ union info_t
+ {
+ struct win_t
+ {
+ HWND__* window;
+ HDC__* hdc;
+
+ win_t() = delete;
+ };
+
+ SDL_SysWMinfo::info_t::win_t win;
+ int dummy;
+
+ info_t() = delete;
+ };
+
+ SDL_version version;
+ SDL_SYSWM_TYPE subsystem;
+ SDL_SysWMinfo::info_t info;
+
+ SDL_SysWMinfo() = delete;
+};
+
struct SDL_SysWMEvent
{
unsigned int type;
@@ -2022,6 +2065,15 @@ struct SDL_SysWMEvent
SDL_SysWMEvent() = delete;
};
+struct SDL_ShapeDriver
+{
+ SDL_WindowShaper* (__fastcall *CreateShaper)(SDL_Window*);
+ int (__fastcall *SetWindowShape)(SDL_WindowShaper*, SDL_Surface*, SDL_WindowShapeMode*);
+ int (__fastcall *ResizeWindowShape)(SDL_Window*);
+
+ SDL_ShapeDriver() = delete;
+};
+
struct SDL_QuitEvent
{
unsigned int type;
@@ -2099,6 +2151,28 @@ struct SDL_MouseButtonEvent
SDL_MouseButtonEvent() = delete;
};
+struct SDL_MessageBoxData
+{
+ unsigned int flags;
+ SDL_Window* window;
+ const char* title;
+ const char* message;
+ int numbuttons;
+ const SDL_MessageBoxButtonData* buttons;
+ const SDL_MessageBoxColorScheme* colorScheme;
+
+ SDL_MessageBoxData() = delete;
+};
+
+struct SDL_MessageBoxButtonData
+{
+ unsigned int flags;
+ int buttonid;
+ const char* text;
+
+ SDL_MessageBoxButtonData() = delete;
+};
+
struct SDL_Keysym
{
SDL_Scancode scancode;
@@ -2188,6 +2262,53 @@ struct SDL_JoyAxisEvent
SDL_JoyAxisEvent() = delete;
};
+struct SDL_GLDriverData
+{
+ SDL_bool HAS_WGL_ARB_pixel_format;
+ SDL_bool HAS_WGL_EXT_swap_control_tear;
+ SDL_bool HAS_WGL_EXT_create_context_es2_profile;
+ SDL_bool HAS_WGL_ARB_context_flush_control;
+ void* (__fastcall *wglGetProcAddress)(const char*);
+ HGLRC__* (__fastcall *wglCreateContext)(HDC__*);
+ int (__fastcall *wglDeleteContext)(HGLRC__*);
+ int (__fastcall *wglMakeCurrent)(HDC__*, HGLRC__*);
+ int (__fastcall *wglShareLists)(HGLRC__*, HGLRC__*);
+ int (__fastcall *wglChoosePixelFormatARB)(HDC__*, const int*, const float*, unsigned int, int*, unsigned int*);
+ int (__fastcall *wglGetPixelFormatAttribivARB)(HDC__*, int, int, unsigned int, const int*, int*);
+ int (__fastcall *wglSwapIntervalEXT)(int);
+ int (__fastcall *wglGetSwapIntervalEXT)();
+
+ SDL_GLDriverData() = delete;
+};
+
+struct SDL_EGL_VideoData
+{
+ void* egl_dll_handle;
+ void* dll_handle;
+ void* egl_display;
+ void* egl_config;
+ int egl_swapinterval;
+ void* (__fastcall *eglGetDisplay)(HDC__*);
+ unsigned int (__fastcall *eglInitialize)(void*, int*, int*);
+ unsigned int (__fastcall *eglTerminate)(void*);
+ void* (__fastcall *eglGetProcAddress)(const char*);
+ unsigned int (__fastcall *eglChooseConfig)(void*, const int*, void**, int, int*);
+ void* (__fastcall *eglCreateContext)(void*, void*, void*, const int*);
+ unsigned int (__fastcall *eglDestroyContext)(void*, void*);
+ void* (__fastcall *eglCreateWindowSurface)(void*, void*, HWND__*, const int*);
+ unsigned int (__fastcall *eglDestroySurface)(void*, void*);
+ unsigned int (__fastcall *eglMakeCurrent)(void*, void*, void*, void*);
+ unsigned int (__fastcall *eglSwapBuffers)(void*, void*);
+ unsigned int (__fastcall *eglSwapInterval)(void*, int);
+ const char* (__fastcall *eglQueryString)(void*, int);
+ unsigned int (__fastcall *eglGetConfigAttrib)(void*, void*, int, int*);
+ unsigned int (__fastcall *eglWaitNative)(int);
+ unsigned int (__fastcall *eglWaitGL)();
+ unsigned int (__fastcall *eglBindAPI)(unsigned int);
+
+ SDL_EGL_VideoData() = delete;
+};
+
struct SDL_DropEvent
{
unsigned int type;
@@ -2222,6 +2343,21 @@ struct SDL_DisplayMode
SDL_DisplayMode() = delete;
};
+struct SDL_VideoDisplay
+{
+ char* name;
+ int max_display_modes;
+ int num_display_modes;
+ SDL_DisplayMode* display_modes;
+ SDL_DisplayMode desktop_mode;
+ SDL_DisplayMode current_mode;
+ SDL_Window* fullscreen_window;
+ SDL_VideoDevice* device;
+ void* driverdata;
+
+ SDL_VideoDisplay() = delete;
+};
+
struct SDL_ControllerDeviceEvent
{
unsigned int type;
@@ -3741,6 +3877,19 @@ struct slicedRect
}
};
+struct _820A8B7015E7E0FD9144A7C186FBF075
+{
+ SDL_Point pt;
+ bool on;
+ const char* text;
+ SDL_Rect r;
+ int count;
+ const char* lastText;
+ bool playedSound;
+
+ _820A8B7015E7E0FD9144A7C186FBF075() = delete;
+};
+
struct _9B9540D9920A90D57A3D80DDD1A70514
{
bool (__fastcall *f)(uiMenu*, const SDL_Rect*, SDL_Event*);
@@ -4741,6 +4890,8 @@ namespace EEex
extern int UncapFPS_BusyWaitThreshold;
extern bool UncapFPS_Enabled;
extern int UncapFPS_FPSLimit;
+ extern bool UncapFPS_FPSLimitEnabled;
+ extern int UncapFPS_LuaGCSteps;
extern bool UncapFPS_RemoveMiddleMouseScrollMultiplier;
uiItem* CreateTemplateFromCopy(lua_State* L, const char* menuName, const char* templateName, uiItem* pItem);
@@ -9165,6 +9316,120 @@ struct font_t
font_t() = delete;
};
+struct SDL_VideoDevice
+{
+ struct gl_config_t
+ {
+ int red_size;
+ int green_size;
+ int blue_size;
+ int alpha_size;
+ int depth_size;
+ int buffer_size;
+ int stencil_size;
+ int double_buffer;
+ int accum_red_size;
+ int accum_green_size;
+ int accum_blue_size;
+ int accum_alpha_size;
+ int stereo;
+ int multisamplebuffers;
+ int multisamplesamples;
+ int accelerated;
+ int major_version;
+ int minor_version;
+ int flags;
+ int profile_mask;
+ int share_with_current_context;
+ int release_behavior;
+ int framebuffer_srgb_capable;
+ int retained_backing;
+ int driver_loaded;
+ Array driver_path;
+ void* dll_handle;
+
+ gl_config_t() = delete;
+ };
+
+ const char* name;
+ int (__fastcall *VideoInit)(SDL_VideoDevice*);
+ void (__fastcall *VideoQuit)(SDL_VideoDevice*);
+ int (__fastcall *GetDisplayBounds)(SDL_VideoDevice*, SDL_VideoDisplay*, SDL_Rect*);
+ int (__fastcall *GetDisplayDPI)(SDL_VideoDevice*, SDL_VideoDisplay*, float*, float*, float*);
+ void (__fastcall *GetDisplayModes)(SDL_VideoDevice*, SDL_VideoDisplay*);
+ int (__fastcall *SetDisplayMode)(SDL_VideoDevice*, SDL_VideoDisplay*, SDL_DisplayMode*);
+ int (__fastcall *CreateWindowA)(SDL_VideoDevice*, SDL_Window*);
+ int (__fastcall *CreateWindowFrom)(SDL_VideoDevice*, SDL_Window*, const void*);
+ void (__fastcall *SetWindowTitle)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowIcon)(SDL_VideoDevice*, SDL_Window*, SDL_Surface*);
+ void (__fastcall *SetWindowPosition)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowSize)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowMinimumSize)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowMaximumSize)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *ShowWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *HideWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *RaiseWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *MaximizeWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *MinimizeWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *RestoreWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowBordered)(SDL_VideoDevice*, SDL_Window*, SDL_bool);
+ void (__fastcall *SetWindowFullscreen)(SDL_VideoDevice*, SDL_Window*, SDL_VideoDisplay*, SDL_bool);
+ int (__fastcall *SetWindowGammaRamp)(SDL_VideoDevice*, SDL_Window*, const unsigned __int16*);
+ int (__fastcall *GetWindowGammaRamp)(SDL_VideoDevice*, SDL_Window*, wchar_t*);
+ void (__fastcall *SetWindowGrab)(SDL_VideoDevice*, SDL_Window*, SDL_bool);
+ void (__fastcall *DestroyWindow)(SDL_VideoDevice*, SDL_Window*);
+ int (__fastcall *CreateWindowFramebuffer)(SDL_VideoDevice*, SDL_Window*, unsigned int*, void**, int*);
+ int (__fastcall *UpdateWindowFramebuffer)(SDL_VideoDevice*, SDL_Window*, const SDL_Rect*, int);
+ void (__fastcall *DestroyWindowFramebuffer)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *OnWindowEnter)(SDL_VideoDevice*, SDL_Window*);
+ SDL_ShapeDriver shape_driver;
+ SDL_bool (__fastcall *GetWindowWMInfo)(SDL_VideoDevice*, SDL_Window*, SDL_SysWMinfo*);
+ int (__fastcall *GL_LoadLibrary)(SDL_VideoDevice*, const char*);
+ void* (__fastcall *GL_GetProcAddress)(SDL_VideoDevice*, const char*);
+ void (__fastcall *GL_UnloadLibrary)(SDL_VideoDevice*);
+ void* (__fastcall *GL_CreateContext)(SDL_VideoDevice*, SDL_Window*);
+ int (__fastcall *GL_MakeCurrent)(SDL_VideoDevice*, SDL_Window*, void*);
+ void (__fastcall *GL_GetDrawableSize)(SDL_VideoDevice*, SDL_Window*, int*, int*);
+ int (__fastcall *GL_SetSwapInterval)(SDL_VideoDevice*, int);
+ int (__fastcall *GL_GetSwapInterval)(SDL_VideoDevice*);
+ void (__fastcall *GL_SwapWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *GL_DeleteContext)(SDL_VideoDevice*, void*);
+ void (__fastcall *PumpEvents)(SDL_VideoDevice*);
+ void (__fastcall *SuspendScreenSaver)(SDL_VideoDevice*);
+ void (__fastcall *StartTextInput)(SDL_VideoDevice*);
+ void (__fastcall *StopTextInput)(SDL_VideoDevice*);
+ void (__fastcall *SetTextInputRect)(SDL_VideoDevice*, SDL_Rect*);
+ SDL_bool (__fastcall *HasScreenKeyboardSupport)(SDL_VideoDevice*);
+ void (__fastcall *ShowScreenKeyboard)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *HideScreenKeyboard)(SDL_VideoDevice*, SDL_Window*);
+ SDL_bool (__fastcall *IsScreenKeyboardShown)(SDL_VideoDevice*, SDL_Window*);
+ int (__fastcall *SetClipboardText)(SDL_VideoDevice*, const char*);
+ char* (__fastcall *GetClipboardText)(SDL_VideoDevice*);
+ SDL_bool (__fastcall *HasClipboardText)(SDL_VideoDevice*);
+ int (__fastcall *ShowMessageBox)(SDL_VideoDevice*, const SDL_MessageBoxData*, int*);
+ int (__fastcall *SetWindowHitTest)(SDL_Window*, SDL_bool);
+ SDL_bool suspend_screensaver;
+ int num_displays;
+ SDL_VideoDisplay* displays;
+ SDL_Window* windows;
+ SDL_Window* grabbed_window;
+ unsigned __int8 window_magic;
+ unsigned int next_object_id;
+ char* clipboard_text;
+ SDL_VideoDevice::gl_config_t gl_config;
+ SDL_Window* current_glwin;
+ void* current_glctx;
+ unsigned int current_glwin_tls;
+ unsigned int current_glctx_tls;
+ void* driverdata;
+ SDL_GLDriverData* gl_data;
+ SDL_EGL_VideoData* egl_data;
+ SDL_PrivateGLESData* gles_data;
+ void (__fastcall *free)(SDL_VideoDevice*);
+
+ SDL_VideoDevice() = delete;
+};
+
struct SDL_PixelFormat
{
unsigned int format;
@@ -9190,6 +9455,13 @@ struct SDL_PixelFormat
SDL_PixelFormat() = delete;
};
+struct SDL_MessageBoxColorScheme
+{
+ Array colors;
+
+ SDL_MessageBoxColorScheme() = delete;
+};
+
template
struct LCharString
{
@@ -9446,6 +9718,9 @@ extern type_restoreMenuStack p_restoreMenuStack;
typedef void (*type_saveMenuStack)();
extern type_saveMenuStack p_saveMenuStack;
+typedef SDL_VideoDisplay* (*type_SDL_GetDisplayForWindow)(SDL_Window* window);
+extern type_SDL_GetDisplayForWindow p_SDL_GetDisplayForWindow;
+
typedef int (*type_SDL_GetKeyFromName)(const char* name);
extern type_SDL_GetKeyFromName p_SDL_GetKeyFromName;
@@ -9524,6 +9799,9 @@ extern type_DrawEndScaled p_DrawEndScaled;
typedef void (*type_drawLetters)(int X, int Y, int W, const SDL_Rect* rClip, const letter_t* letters, int nletters, int horizontalAlignment, font_t* font, int pointSize, int cursorPosition, int cursor, int selectionStart, int selectionEnd, int nLines, bool inlineColor, int indent, float fOffsetX, float fOffsetY);
extern type_drawLetters p_drawLetters;
+typedef bool (__cdecl *type_drawMenu)(uiMenu* m, const SDL_Rect* window);
+extern type_drawMenu p_drawMenu;
+
typedef void (*type_DrawOrtho11Begin)();
extern type_DrawOrtho11Begin p_DrawOrtho11Begin;
@@ -9548,6 +9826,9 @@ extern type_drawSliceSide p_drawSliceSide;
typedef void (*type_DrawTexCoord)(int s, int t);
extern type_DrawTexCoord p_DrawTexCoord;
+typedef bool (__cdecl *type_drawTop)(const SDL_Rect* window);
+extern type_drawTop p_drawTop;
+
typedef void (__cdecl *type_DrawTransformToScreen)(SDL_Rect* w, SDL_Rect* s);
extern type_DrawTransformToScreen p_DrawTransformToScreen;
@@ -9599,6 +9880,9 @@ extern type_uiDrawSlicedRect p_uiDrawSlicedRect;
typedef int (*type_uiExecLuaInt)(int id);
extern type_uiExecLuaInt p_uiExecLuaInt;
+typedef void (__cdecl *type_uiHandleTooltip)();
+extern type_uiHandleTooltip p_uiHandleTooltip;
+
typedef bool (*type_uiPop)(const char* name);
extern type_uiPop p_uiPop;
@@ -9625,6 +9909,8 @@ extern type_YScreenToZoomed p_YScreenToZoomed;
extern char** p_afxPchNil;
extern _9B9540D9920A90D57A3D80DDD1A70514* p_capture;
+extern bool* p_fingerDown;
+extern uiMenu** p_g_backgroundMenu;
extern RendererType* p_g_drawBackend;
extern Array* p_g_keywords;
extern lua_State** p_g_lua;
@@ -9637,6 +9923,7 @@ extern Array* p_menuStack;
extern int* p_nextStackMenuIdx;
extern int* p_numMenus;
extern CTypedPtrArray* p_resources;
+extern _820A8B7015E7E0FD9144A7C186FBF075* p_tooltip;
extern _A92C2F5FC159A4FE55DD6CCAABD58E72* p_transition;
extern ConstArray* p_yy_action;
extern ConstArray* p_yy_default;
@@ -10557,7 +10844,7 @@ struct C2DArray : CResHelper
typedef void (__thiscall *type_Destruct)(C2DArray* pThis);
static type_Destruct p_Destruct;
- typedef const CString* (__thiscall *type_GetAtCStringLabels)(C2DArray* pThis, const CString* nX, const CString* nY);
+ typedef const CString* (__thiscall *type_GetAtCStringLabels)(const C2DArray* pThis, const CString* nX, const CString* nY);
static type_GetAtCStringLabels p_GetAtCStringLabels;
typedef void (__thiscall *type_Load)(C2DArray* pThis, const CResRef* res);
@@ -10573,7 +10860,7 @@ struct C2DArray : CResHelper
p_Destruct(this);
}
- int FindColumnLabel(const char* sLabel)
+ int FindColumnLabel(const char* sLabel) const
{
EngineVal sLabelUppercase { sLabel };
sLabelUppercase->MakeUpper();
@@ -10593,7 +10880,7 @@ struct C2DArray : CResHelper
return -1;
}
- int FindRowLabel(const char* sLabel)
+ int FindRowLabel(const char* sLabel) const
{
EngineVal sLabelUppercase { sLabel };
sLabelUppercase->MakeUpper();
@@ -10613,7 +10900,7 @@ struct C2DArray : CResHelper
return -1;
}
- const CString* GetAt(int x, int y)
+ const CString* GetAt(int x, int y) const
{
if (x >= 0 && x < this->m_nSizeX && y >= 0 && y < this->m_nSizeY)
{
@@ -10622,7 +10909,7 @@ struct C2DArray : CResHelper
return &this->m_default;
}
- const CString* GetAt(const char* nX, const char* nY)
+ const CString* GetAt(const char* nX, const char* nY) const
{
const int nColumnIndex = this->FindColumnLabel(nX);
if (nColumnIndex == -1) return &this->m_default;
@@ -10633,7 +10920,7 @@ struct C2DArray : CResHelper
return this->GetAt(nColumnIndex, nRowIndex);
}
- const CString* GetAt(const CString* nX, const CString* nY)
+ const CString* GetAt(const CString* nX, const CString* nY) const
{
return p_GetAtCStringLabels(this, nX, nY);
}
@@ -10876,13 +11163,45 @@ struct CVidBitmap : CVidImage, CResHelper
CVidBitmap() = delete;
+ typedef void (__thiscall *type_Construct)(CVidBitmap* pThis);
+ static type_Construct p_Construct;
+
+ typedef void (__thiscall *type_Destruct)(CVidBitmap* pThis);
+ static type_Destruct p_Destruct;
+
typedef int (__thiscall *type_GetPixelColor)(CVidBitmap* pThis, tagRGBQUAD* color, int x, int y);
static type_GetPixelColor p_GetPixelColor;
+ typedef byte (__thiscall *type_GetPixelValueOrZero)(CVidBitmap* pThis, int x, int y);
+ static type_GetPixelValueOrZero p_GetPixelValueOrZero;
+
+ typedef void (__thiscall *type_SetResRef)(CVidBitmap* pThis, const CResRef* cNewResRef, int bSetAutoRequest, int bWarningIfMissing);
+ static type_SetResRef p_SetResRef;
+
+ void Construct()
+ {
+ p_Construct(this);
+ }
+
+ void Destruct()
+ {
+ p_Destruct(this);
+ }
+
int GetPixelColor(tagRGBQUAD* color, int x, int y)
{
return p_GetPixelColor(this, color, x, y);
}
+
+ byte GetPixelValue(int x, int y)
+ {
+ return p_GetPixelValueOrZero(this, x, y);
+ }
+
+ void SetResRef(const CResRef* cNewResRef, int bSetAutoRequest, int bWarningIfMissing)
+ {
+ p_SetResRef(this, cNewResRef, bSetAutoRequest, bWarningIfMissing);
+ }
};
struct CScreenAI : CBaldurEngine
diff --git a/EEex-v2.6.6.0/scripts/generate_bindings/in/bindings.txt b/EEex-v2.6.6.0/scripts/generate_bindings/in/bindings.txt
index 0f49e82..f4bc78e 100644
--- a/EEex-v2.6.6.0/scripts/generate_bindings/in/bindings.txt
+++ b/EEex-v2.6.6.0/scripts/generate_bindings/in/bindings.txt
@@ -121,6 +121,8 @@ namespace EEex
int UncapFPS_BusyWaitThreshold;
bool UncapFPS_Enabled;
int UncapFPS_FPSLimit;
+ bool UncapFPS_FPSLimitEnabled;
+ int UncapFPS_LuaGCSteps;
bool UncapFPS_RemoveMiddleMouseScrollMultiplier;
// Functions
diff --git a/EEex-v2.6.6.0/scripts/generate_bindings/in/ignore_header_types.txt b/EEex-v2.6.6.0/scripts/generate_bindings/in/ignore_header_types.txt
index a64bd70..363dfce 100644
--- a/EEex-v2.6.6.0/scripts/generate_bindings/in/ignore_header_types.txt
+++ b/EEex-v2.6.6.0/scripts/generate_bindings/in/ignore_header_types.txt
@@ -68,6 +68,7 @@ GCheader
GCObject
global_State
HDC__
+HGLRC__
HMONITOR__
HWND__
ID3DXBaseEffect
diff --git a/EEex-v2.6.6.0/scripts/generate_bindings/in/manual_types.txt b/EEex-v2.6.6.0/scripts/generate_bindings/in/manual_types.txt
index d153cdf..097bdf7 100644
--- a/EEex-v2.6.6.0/scripts/generate_bindings/in/manual_types.txt
+++ b/EEex-v2.6.6.0/scripts/generate_bindings/in/manual_types.txt
@@ -841,7 +841,7 @@ struct C2DArray : CResHelper
$constructor_fake Construct();
void Destruct();
- int FindColumnLabel(primitive const char* sLabel)
+ int FindColumnLabel(primitive const char* sLabel) const
{
EngineVal sLabelUppercase { sLabel };
sLabelUppercase->MakeUpper();
@@ -861,7 +861,7 @@ struct C2DArray : CResHelper
return -1;
}
- int FindRowLabel(primitive const char* sLabel)
+ int FindRowLabel(primitive const char* sLabel) const
{
EngineVal sLabelUppercase { sLabel };
sLabelUppercase->MakeUpper();
@@ -881,7 +881,7 @@ struct C2DArray : CResHelper
return -1;
}
- $binding_name(GetAtPoint) const CString* GetAt(int x, int y)
+ $binding_name(GetAtPoint) const CString* GetAt(int x, int y) const
{
if (x >= 0 && x < this->m_nSizeX && y >= 0 && y < this->m_nSizeY)
{
@@ -890,7 +890,7 @@ struct C2DArray : CResHelper
return &this->m_default;
}
- $binding_name(GetAtLabels) const CString* GetAt(primitive const char* nX, primitive const char* nY)
+ $binding_name(GetAtLabels) const CString* GetAt(primitive const char* nX, primitive const char* nY) const
{
const int nColumnIndex = this->FindColumnLabel(nX);
if (nColumnIndex == -1) return &this->m_default;
@@ -901,7 +901,7 @@ struct C2DArray : CResHelper
return this->GetAt(nColumnIndex, nRowIndex);
}
- $binding_name(GetAtCStringLabels) $pattern_name(GetAt(const CString*,const CString*)) const CString* GetAt(const CString* nX, const CString* nY);
+ $binding_name(GetAtCStringLabels) $pattern_name(GetAt(const CString*,const CString*)) const CString* GetAt(const CString* nX, const CString* nY) const;
void Load(const CResRef* res);
};
@@ -1620,7 +1620,11 @@ struct CBaldurEngine : CWarp
struct CVidBitmap : CVidImage, CResHelper
{
+ $constructor_fake Construct();
+ void Destruct();
int GetPixelColor(tagRGBQUAD* color, int x, int y);
+ $binding_name(GetPixelValueOrZero) $pattern_name(GetPixelValue(int,int)) byte GetPixelValue(int x, int y);
+ void SetResRef(const CResRef* cNewResRef, int bSetAutoRequest, int bWarningIfMissing);
};
struct CVidFont : CResHelper
@@ -1647,6 +1651,7 @@ uiMenu* findMenu(primitive const char* name, int panel, int state);
int rand();
void restoreMenuStack();
void saveMenuStack();
+SDL_VideoDisplay* SDL_GetDisplayForWindow(SDL_Window* window);
int SDL_GetKeyFromName(primitive const char* name);
primitive char* __cdecl SDL_GetKeyName(int key);
uint SDL_GetWindowFlags(SDL_Window* window);
@@ -1674,6 +1679,7 @@ $nobinding void DrawEnable(DrawFeature f);
$nobinding void DrawEnd();
$nobinding void DrawEndScaled();
$nobinding void drawLetters(int X, int Y, int W, const SDL_Rect* rClip, const letter_t* letters, int nletters, int horizontalAlignment, font_t* font, int pointSize, int cursorPosition, int cursor, int selectionStart, int selectionEnd, int nLines, bool inlineColor, int indent, float fOffsetX, float fOffsetY);
+$nobinding bool __cdecl drawMenu(uiMenu* m, const SDL_Rect* window);
$nobinding void DrawOrtho11Begin();
$nobinding void DrawOrtho11End();
$nobinding void DrawPopState();
@@ -1682,6 +1688,7 @@ $pattern_name(DrawQuad(CRect*,CRect*)) void DrawQuad(const CRect* rDest, const C
$nobinding void drawSlice(const SDL_Rect* dr, const SDL_Rect* r, const SDL_Rect* rClip, float scaleX, float scaleY, bool unused);
$nobinding void drawSliceSide(const SDL_Rect* dr, const SDL_Rect* r, const SDL_Rect* rClip, float scaleX, float scaleY, bool wide);
$nobinding void DrawTexCoord(int s, int t);
+$nobinding bool __cdecl drawTop(const SDL_Rect* window);
$nobinding void __cdecl DrawTransformToScreen(SDL_Rect* w, SDL_Rect* s);
$nobinding float __cdecl DrawTransformToScreenH(float h);
$nobinding void DrawVertex(int x, int y);
@@ -1699,6 +1706,7 @@ $nobinding int __cdecl SDL_ShowSimpleMessageBox(uint flags, const char* title, c
$nobinding void SearchThreadMain();
$nobinding void uiDrawSlicedRect(int rectNum, const SDL_Rect* bounds, int alpha, const SDL_Rect* rClip);
$nobinding int uiExecLuaInt(int id);
+$nobinding void __cdecl uiHandleTooltip();
$nobinding bool uiPop(const char* name);
$nobinding bool uiPush(const char* name);
$nobinding void uiSetHidden(bool bHidden);
@@ -1714,6 +1722,8 @@ $nobinding float YScreenToZoomed(float y);
char* afxPchNil;
$9B9540D9920A90D57A3D80DDD1A70514 capture;
+bool fingerDown;
+uiMenu* g_backgroundMenu;
RendererType g_drawBackend;
keyword g_keywords[124];
lua_State* g_lua;
@@ -1726,6 +1736,7 @@ uiMenu* menuStack[256];
int nextStackMenuIdx;
int numMenus;
CTypedPtrArray resources;
+$820A8B7015E7E0FD9144A7C186FBF075 tooltip;
$A92C2F5FC159A4FE55DD6CCAABD58E72 transition;
const ushort yy_action[1765];
const ushort yy_default[329];
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/EEex.cpp b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/EEex.cpp
index 80ea91b..9a80717 100644
--- a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/EEex.cpp
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/EEex.cpp
@@ -8,9 +8,11 @@
#include "Baldur-v2.6.6.0_generated.h"
#include "EEex.h"
+#include "engine_function_names.hpp"
#include "infinity_loader_util_api.h"
#include "lua_util.hpp"
#include "menu_util.hpp"
+#include "profiler.hpp"
#include "time_util.hpp"
#include "uncap_fps.hpp"
#include "util.hpp"
@@ -141,6 +143,7 @@ std::unordered_map> proj
struct ExSpriteData {
+ EngineVal combatRoundsOverride[5]{};
Array oldDisabledSpellTypes;
int oldDisableSpells = 0;
uint64_t uuid = 0;
@@ -384,11 +387,7 @@ bool EEex::IsMarshallingCopy() {
// Stutter Util //
//--------------------------------//
-long long currentMicroseconds() {
- return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count();
-}
-
-void exitStutterLog(const char *const name, long long timeTaken) {
+void exitStutterLog(const char *const name, TimeType timeTaken) {
lua_State *const L = *p_g_lua;
lua_getglobal(L, "EEex_StutterDetector_Private_Times"); // 1 [ ..., EEex_StutterDetector_Private_Times ]
@@ -448,9 +447,9 @@ RetType logStutter(const char* name, std::function func) {
bool oldTopLevel = topLevel;
topLevel = false;
- long long startTime = currentMicroseconds();
+ TimeType startTime = getTime();
RetType ret = func();
- long long timeTaken = currentMicroseconds() - startTime;
+ TimeType timeTaken = getTime() - startTime;
topLevel = oldTopLevel;
exitStutterLog(name, timeTaken);
return ret;
@@ -466,9 +465,9 @@ void logStutter(const char* name, std::function func) {
bool oldTopLevel = topLevel;
topLevel = false;
- long long startTime = currentMicroseconds();
+ TimeType startTime = getTime();
func();
- long long timeTaken = currentMicroseconds() - startTime;
+ TimeType timeTaken = getTime() - startTime;
topLevel = oldTopLevel;
exitStutterLog(name, timeTaken);
}
@@ -1955,6 +1954,150 @@ void EEex::SetUIItemExtraScrollbarPad(uiItem* pItem, int nExtraPad) {
// Overrides //
/////////////////////////////////
+int CAICondition::Override_Hold(CTypedPtrList* pTriggerList, CGameAIBase* pCaller)
+{
+ auto pNode = this->m_triggerList.m_pNodeHead;
+ if (pNode == nullptr) {
+ return 1;
+ }
+
+ bool bRet = false;
+ int nORCounter = 0;
+
+ bool bNextTriggerObject = false;
+ CGameAIBase* pNextTriggerObject = nullptr;
+
+ // EEex
+ int nTrigger = 0;
+
+ do
+ {
+ if (nORCounter <= 0) {
+ bRet = false;
+ }
+
+ CAITrigger *const pTrigger = pNode->data;
+ const short nTriggerID = pTrigger->m_triggerID;
+
+ if (nTriggerID == 0x4089) // OR
+ {
+ nORCounter = pTrigger->m_specificID;
+ }
+ else if (nTriggerID == 0x40E0) // NextTriggerObject
+ {
+ EngineVal nextTriggerObjectType{ &pTrigger->m_triggerCause };
+ nextTriggerObjectType->Decode(pCaller);
+
+ bNextTriggerObject = true;
+ pNextTriggerObject = reinterpret_cast(nextTriggerObjectType->GetShareType(pCaller, CGameObjectType::AIBASE, 0));
+
+ if (pNextTriggerObject != nullptr && nORCounter < 1) {
+ bRet = true;
+ }
+ }
+ else {
+ --nORCounter;
+ }
+
+ if (nTriggerID != 0x40E0) // NOT NextTriggerObject
+ {
+ if (bNextTriggerObject)
+ {
+ if (pNextTriggerObject != nullptr)
+ {
+ // EEex
+ if (EEex::bInTrackedResponse)
+ {
+ for (auto callback : triggerHitCallbacks) {
+ callback(nTrigger);
+ }
+ }
+
+ bNextTriggerObject = false;
+ const bool bTriggerHolds = this->TriggerHolds(pTrigger, pTriggerList, pNextTriggerObject);
+ bRet |= bTriggerHolds;
+
+ // EEex
+ if (EEex::bInTrackedResponse)
+ {
+ for (auto callback : triggerEvaluatedCallbacks) {
+ callback(bTriggerHolds);
+ }
+ }
+ }
+ }
+ else
+ {
+ // EEex
+ if (EEex::bInTrackedResponse)
+ {
+ for (auto callback : triggerHitCallbacks) {
+ callback(nTrigger);
+ }
+ }
+
+ const bool bTriggerHolds = this->TriggerHolds(pTrigger, pTriggerList, pCaller);
+ bRet |= bTriggerHolds;
+
+ // EEex
+ if (EEex::bInTrackedResponse)
+ {
+ for (auto callback : triggerEvaluatedCallbacks) {
+ callback(bTriggerHolds);
+ }
+ }
+ }
+ }
+
+ if (!bRet && nORCounter < 1) // Fail
+ {
+ break;
+ }
+
+ pNode = pNode->pNext;
+
+ // EEex
+ ++nTrigger;
+ }
+ while (pNode != nullptr);
+
+ return bRet;
+}
+
+int CAICondition::Override_TriggerHolds(CAITrigger* pTrigger, CTypedPtrList* pTriggerList, CGameAIBase* pCaller)
+{
+ bool nRet = false;
+
+ if ((pTrigger->m_triggerID & 0x4000) == 0) // Event-driven trigger
+ {
+ for (auto pNode = pTriggerList->m_pNodeHead; pNode != nullptr; pNode = pNode->pNext)
+ {
+ pTrigger->m_triggerCause.Decode(pCaller);
+ nRet = pNode->data->OfType(pTrigger);
+
+ if ((pTrigger->m_flags & 1) != 0) // Inverted
+ {
+ nRet = !nRet;
+ }
+
+ if (nRet) {
+ break;
+ }
+ }
+ }
+ else // Status trigger
+ {
+ nRet = pCaller->virtual_EvaluateStatusTrigger(pTrigger);
+
+ if ((pTrigger->m_flags & 1) != 0) // Inverted
+ {
+ nRet = !nRet;
+ }
+ }
+
+ return nRet;
+}
+
void CChitin::Override_SynchronousUpdate() {
CWarp *const pActiveEngine = this->pActiveEngine;
@@ -2015,52 +2158,316 @@ void CChitin::Override_SynchronousUpdate() {
}
}
-void __cdecl EEex::Override_uiDoFile(char* fileName) {
+void updateScriptingObject(CGameAIBase* pAIBase, EEex_ScriptingObject scriptingObject, CAIObjectType* pToSet, CAIObjectType* pToSetWith) {
- lua_State* const L = *p_g_lua;
+ if (*pToSet != pToSetWith) {
- EngineVal fullFileName{};
- fullFileName->Format("%s.lua", fileName);
+ pToSet->Set(pToSetWith);
- const CResRef resref { fileName };
- CRes *const pRes = p_dimmGetResObject(&resref, 0x409, false);
+ lua_State *const L = *p_g_lua;
+ luaCallProtected(L, 2, 0, [&](int _) {
+ lua_getglobal(L, "EEex_AIBase_LuaHook_OnScriptingObjectUpdated"); // 1 [ ..., EEex_AIBase_LuaHook_OnScriptingObjectUpdated ]
+ tolua_pushusertype(L, pAIBase, "CGameAIBase"); // 2 [ ..., EEex_AIBase_LuaHook_OnScriptingObjectUpdated, pAIBaseUD ]
+ lua_pushinteger(L, static_cast<__int32>(scriptingObject)); // 3 [ ..., EEex_AIBase_LuaHook_OnScriptingObjectUpdated, pAIBaseUD, scriptingObject ]
+ });
+ }
+}
- if (pRes != nullptr) {
+void CGameAIBase::Override_ApplyTriggers() {
- const char *const pResBuffer = reinterpret_cast(pRes->Demand());
+ CBaldurChitin *const pBaldurChitin = *p_g_pBaldurChitin;
+ CInfGame *const pGame = pBaldurChitin->m_pObjectGame;
- if (luaL_loadbufferx(L, pResBuffer, pRes->nSize, fullFileName->m_pchData, nullptr) == LUA_OK) {
+ if (pGame->m_worldTime.m_gameTime % 3600 == 0) {
+ CMessageUpdateReaction *const pMessage = newEngineObj(11, this->m_id, this->m_id);
+ pBaldurChitin->m_cMessageHandler.AddMessage(pMessage, 0);
+ }
- if (lua_pcallk(L, 0, -1, 0, 0, nullptr) != LUA_OK) {
+ if (this->virtual_GetObjectType() == CGameObjectType::SPRITE) {
+ CGameSprite *const pSprite = reinterpret_cast(this);
+ pSprite->GetActiveStats()->m_cContingencyList.Process(pSprite);
+ }
- const char *const pErrorMessage = lua_tolstring(L, -1, nullptr);
+ for (auto pNode = this->m_pendingTriggers.m_pNodeHead; pNode != nullptr; pNode = pNode->pNext) {
- if (pErrorMessage != nullptr) {
- p_SDL_ShowSimpleMessageBox(0x10, CChitin::p_m_sGameName->m_pchData, pErrorMessage, (*p_g_pBaldurChitin)->cVideo.pCurrentMode->m_pWindow);
- p_SDL_Log("Error [%s] in %s", pErrorMessage, fullFileName->m_pchData);
+ CAITrigger *const pTrigger = pNode->data;
+ if ((pTrigger->m_flags & 4) != 0) {
+ continue;
+ }
+ pTrigger->m_flags |= 4;
+
+ switch (pTrigger->m_triggerID) {
+
+ case 0x0002: { // AttackedBy
+
+ this->virtual_AutoPause(2);
+ this->m_lAttackStyle = pTrigger->m_specificID;
+
+ if
+ (
+ pGame->GetCharacterPortraitNum(this->m_id) == -1
+ ||
+ pGame->GetCharacterPortraitNum(pTrigger->m_triggerCause.m_Instance) == -1
+ )
+ {
+ updateScriptingObject(this, EEex_ScriptingObject::ATTACKER, &this->m_lAttacker, &pTrigger->m_triggerCause);
}
+ break;
+ }
+ case 0x0003: { // Help
+ updateScriptingObject(this, EEex_ScriptingObject::HELP, &this->m_lHelp, &pTrigger->m_triggerCause);
+ break;
+ }
+ case 0x0006: { // ReceivedOrder
+ updateScriptingObject(this, EEex_ScriptingObject::ORDERED_BY, &this->m_lOrderedBy, &pTrigger->m_triggerCause);
+ break;
+ }
+ case 0x0007: { // Said
+ updateScriptingObject(this, EEex_ScriptingObject::TALKED_TO, &this->m_lTalkedTo, &pTrigger->m_triggerCause);
+ break;
+ }
+ case 0x0020: { // HitBy
+
+ this->virtual_AutoPause(4);
+ this->m_lAttackStyle = pTrigger->m_specificID;
+
+ updateScriptingObject(this, EEex_ScriptingObject::HITTER, &this->m_lHitter, &pTrigger->m_triggerCause);
+ break;
+ }
+ case 0x002F: { // Heard
+ updateScriptingObject(this, EEex_ScriptingObject::HEARD, &this->m_lHeard, &pTrigger->m_triggerCause);
+ break;
+ }
+ case 0x0097: { // Summoned
+ updateScriptingObject(this, EEex_ScriptingObject::SUMMONED_BY, &this->m_lSummonedBy, &pTrigger->m_triggerCause);
+ break;
}
}
- else {
- const char *const pErrorMessage = lua_tolstring(L, -1, nullptr);
- p_SDL_ShowSimpleMessageBox(0x10, CChitin::p_m_sGameName->m_pchData, pErrorMessage, (*p_g_pBaldurChitin)->cVideo.pCurrentMode->m_pWindow);
- p_SDL_Log("Err: %s", pErrorMessage);
+
+ if (pGame->SAVE_OBJECT_LIST.Find(pTrigger->m_triggerID) != nullptr) {
+ updateScriptingObject(this, EEex_ScriptingObject::TRIGGER, &this->m_lTrigger, &pTrigger->m_triggerCause);
}
- pRes->virtual_Dump();
+ if (this->virtual_GetObjectType() == CGameObjectType::SPRITE) {
+ CGameSprite *const pSprite = reinterpret_cast(this);
+ pSprite->GetActiveStats()->m_cContingencyList.ProcessTrigger(pSprite, pTrigger);
+ }
}
+}
- EngineVal langFile{};
- langFile->Format("L_%s", static_cast(*p_lang));
+static void onEventTriggerSet(CGameAIBase *const pAIBase, CAITrigger *const pTrigger) {
- if (_stricmp(fileName, langFile->m_pchData) == 0) {
- luaCallProtected(L, 0, 0, [&](int _) {
- lua_getglobal(L, "EEex_Menu_LuaHook_AfterTranslationLoaded"); // 1 [ ..., EEex_Menu_LuaHook_AfterTranslationLoaded ]
- });
+ if (!EEex::AIBase_LuaHook_OnEventTriggerSet_Enabled) {
+ return;
}
-}
-void EEex::Override_bootstrapLua() {
+ lua_State *const L = *p_g_lua;
+ luaCallProtected(L, 2, 0, [&](int) {
+ lua_getglobal(L, "EEex_AIBase_LuaHook_OnEventTriggerSet"); // 1 [ ..., EEex_AIBase_LuaHook_OnEventTriggerSet ]
+ pushGameObjectUD(L, pAIBase); // 2 [ ..., EEex_AIBase_LuaHook_OnEventTriggerSet, pAIBaseUD ]
+ tolua_pushusertype(L, pTrigger, "CAITrigger"); // 3 [ ..., EEex_AIBase_LuaHook_OnEventTriggerSet, pAIBaseUD, pTriggerUD ]
+ });
+}
+
+void CGameAIBase::Override_SetTrigger(const CAITrigger* pTrigger) {
+
+ CAITrigger *const pTriggerCopy = newEngineObj(pTrigger);
+
+ onEventTriggerSet(this, pTriggerCopy);
+ this->m_pendingTriggers.AddTail(pTriggerCopy);
+ this->m_bNewTrigger = 1;
+
+ if ((pTriggerCopy->m_flags & 4) != 0) {
+ return;
+ }
+ pTriggerCopy->m_flags |= 4;
+
+ CInfGame *const pGame = (*p_g_pBaldurChitin)->m_pObjectGame;
+
+ switch (pTriggerCopy->m_triggerID) {
+
+ case 0x0002: { // AttackedBy
+
+ this->virtual_AutoPause(2);
+
+ CGameSprite* pSprite = reinterpret_cast(pTriggerCopy->m_triggerCause.GetShareType(this, CGameObjectType::SPRITE, 0));
+ if (pSprite != nullptr) {
+ // I don't know why the engine repeats this
+ pSprite = reinterpret_cast(pTriggerCopy->m_triggerCause.GetShareType(this, CGameObjectType::SPRITE, 0));
+ if ((pSprite->GetActiveStats()->m_generalState & 0x800) != 0) {
+ break;
+ }
+ }
+
+ this->m_lAttackStyle = pTriggerCopy->m_specificID;
+ if
+ (
+ pGame->GetCharacterPortraitNum(this->m_id) == -1
+ ||
+ pGame->GetCharacterPortraitNum(pTriggerCopy->m_triggerCause.m_Instance) == -1
+ )
+ {
+ updateScriptingObject(this, EEex_ScriptingObject::ATTACKER, &this->m_lAttacker, &pTriggerCopy->m_triggerCause);
+ }
+ break;
+ }
+ case 0x0003: { // Help
+ updateScriptingObject(this, EEex_ScriptingObject::HELP, &this->m_lHelp, &pTriggerCopy->m_triggerCause);
+ break;
+ }
+ case 0x0006: { // ReceivedOrder
+ updateScriptingObject(this, EEex_ScriptingObject::ORDERED_BY, &this->m_lOrderedBy, &pTriggerCopy->m_triggerCause);
+ break;
+ }
+ case 0x0007: { // Said
+ updateScriptingObject(this, EEex_ScriptingObject::TALKED_TO, &this->m_lTalkedTo, &pTriggerCopy->m_triggerCause);
+ break;
+ }
+ case 0x0020: { // HitBy
+
+ this->virtual_AutoPause(4);
+ this->m_lAttackStyle = pTriggerCopy->m_specificID;
+
+ updateScriptingObject(this, EEex_ScriptingObject::HITTER, &this->m_lHitter, &pTriggerCopy->m_triggerCause);
+ break;
+ }
+ case 0x002F: { // Heard
+ updateScriptingObject(this, EEex_ScriptingObject::HEARD, &this->m_lHeard, &pTriggerCopy->m_triggerCause);
+ break;
+ }
+ case 0x004C: { // Entered
+ if (this->virtual_GetObjectType() == CGameObjectType::TRIGGER) {
+ CGameTrigger *const pTrigger = reinterpret_cast(this);
+ if ((pTrigger->m_dwFlags & 2) == 0) {
+ pTrigger->SetDrawPoly(0);
+ }
+ }
+ break;
+ }
+ case 0x0052: { // Opened
+ if (this->virtual_GetObjectType() == CGameObjectType::DOOR) {
+ CGameDoor *const pDoor = reinterpret_cast(this);
+ if ((pDoor->m_dwFlags & 4) == 0) {
+ pDoor->SetDrawPoly(0);
+ }
+ }
+ else {
+ if (this->virtual_GetObjectType() == CGameObjectType::CONTAINER) {
+ CGameContainer *const pContainer = reinterpret_cast(this);
+ if ((pContainer->m_dwFlags & 8) == 0) {
+ pContainer->SetDrawPoly(0);
+ }
+ }
+ }
+ break;
+ }
+ case 0x0097: { // Summoned
+ updateScriptingObject(this, EEex_ScriptingObject::SUMMONED_BY, &this->m_lSummonedBy, &pTriggerCopy->m_triggerCause);
+ break;
+ }
+ }
+
+ if (pGame->SAVE_OBJECT_LIST.Find(pTriggerCopy->m_triggerID) != nullptr) {
+ updateScriptingObject(this, EEex_ScriptingObject::TRIGGER, &this->m_lTrigger, &pTriggerCopy->m_triggerCause);
+ }
+
+ if (this->virtual_GetObjectType() == CGameObjectType::SPRITE) {
+ CGameSprite *const pSprite = reinterpret_cast(this);
+ pSprite->GetActiveStats()->m_cContingencyList.ProcessTrigger(pSprite, pTriggerCopy);
+ }
+}
+
+void CMessageSetLastObject::Override_Run() {
+
+ CGameObject* pObject;
+ if
+ (
+ CGameObjectArray::GetShare(this->m_targetId, &pObject) != 0
+ ||
+ (pObject->virtual_GetObjectType() & CGameObjectType::AIBASE) == 0
+ )
+ {
+ return;
+ }
+
+ if (pObject->virtual_GetObjectType() == CGameObjectType::SPRITE) {
+ CGameSprite *const pSprite = reinterpret_cast(pObject);
+ if ((pSprite->m_derivedStats.m_generalState & 0x80) != 0 || (pSprite->m_baseStats.m_generalState & 0x80) != 0) {
+ // STONE_DEATH
+ return;
+ }
+ }
+
+ CGameAIBase *const pAIBase = reinterpret_cast(pObject);
+
+ switch (this->m_type) {
+ case 0x0002: { // AttackedBy
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::ATTACKER, &pAIBase->m_lAttacker, &this->m_lAttacker);
+ pAIBase->m_lAttackerSent.Set(&this->m_lAttacker);
+ break;
+ }
+ case 0x0003: { // Help
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::HELP, &pAIBase->m_lHelp, &this->m_lAttacker);
+ pAIBase->m_lHelpSent.Set(&this->m_lAttacker);
+ break;
+ }
+ case 0x0006: { // ReceivedOrder
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::ORDERED_BY, &pAIBase->m_lOrderedBy, &this->m_lAttacker);
+ pAIBase->m_lOrderedBySent.Set(&this->m_lAttacker);
+ break;
+ }
+ case 0x0007: { // Said
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::TALKED_TO, &pAIBase->m_lTalkedTo, &this->m_lAttacker);
+ pAIBase->m_lTalkedToSent.Set(&this->m_lAttacker);
+ break;
+ }
+ case 0x0020: { // HitBy
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::HITTER, &pAIBase->m_lHitter, &this->m_lAttacker);
+ pAIBase->m_lHitterSent.Set(&this->m_lAttacker);
+ break;
+ }
+ case 0x002F: { // Heard
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::HEARD, &pAIBase->m_lHeard, &this->m_lAttacker);
+ pAIBase->m_lHeardSent.Set(&this->m_lAttacker);
+ break;
+ }
+ case 0x004B: { // Killed
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::KILLED, &pAIBase->m_lKilled, &this->m_lAttacker);
+ pAIBase->m_lKilledSent.Set(&this->m_lAttacker);
+ break;
+ }
+ case 0x0097: { // Summoned
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::SUMMONED_BY, &pAIBase->m_lSummonedBy, &this->m_lAttacker);
+ pAIBase->m_lSummonedBySent.Set(&this->m_lAttacker);
+ break;
+ }
+ case 0x401C: { // See
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::SEEN, &pAIBase->m_lSeen, &this->m_lAttacker);
+ pAIBase->m_lSeenSent.Set(&this->m_lAttacker);
+ break;
+ }
+ default: {
+ updateScriptingObject(pAIBase, EEex_ScriptingObject::TRIGGER, &pAIBase->m_lTrigger, &this->m_lAttacker);
+ pAIBase->m_lTriggerSent.Set(&this->m_lAttacker);
+ break;
+ }
+ }
+}
+
+void CScreenMap::Override_OnLButtonDblClk(CPoint cPoint) {
+
+ CBaldurEngine *const pActiveEngine = reinterpret_cast((*p_g_pBaldurChitin)->pActiveEngine);
+ pActiveEngine->OnLeftPanelButtonClick(0);
+
+ // Vanilla Bugfix: Fix closing the local area map with a double click resulting in the world screen responding to the button up event
+ // |
+ lua_State *const L = luaState();
+ luaCallProtected(L, 0, 0, [&](int _) {
+ lua_getglobal(L, "EEex_Fix_LuaHook_OnLocalMapDoubleClick");
+ });
+}
+
+void EEex::Override_bootstrapLua() {
//*p_g_lua = luaL_newstate();
lua_State *const L = luaState();
@@ -2138,114 +2545,6 @@ end
}
}
-//int __cdecl EEex::Override_fontWrap(
-// char* text,
-// SDL_Rect* r,
-// SDL_Rect* rClip,
-// int* horizontalAlignment,
-// int* verticalAlignment,
-// font_t* font,
-// int* pointSize,
-// letter_t* letters,
-// int* nlines,
-// int* nletters,
-// int* pointIndex,
-// bool* scale,
-// adjustmentData_t* adjustData,
-// int indent,
-// bool bUseFontSizeFloor)
-//{
-// const int maxLines = (*verticalAlignment >> 16) & 0xFFF;
-// *verticalAlignment &= 0xFFFF;
-//
-// if (r->h == 0xFFFFFF)
-// {
-// *verticalAlignment = 0;
-// }
-//
-// SDL_Rect rTransformed;
-// SDL_Rect rClipTransformed;
-//
-// p_DrawTransformToScreen(r, &rTransformed);
-// p_DrawTransformToScreen(rClip, &rClipTransformed);
-//
-// int nAlignAdjX = 0;
-//
-// if ((*horizontalAlignment & 4) != 0) {
-// nAlignAdjX = rClipTransformed.w - rClipTransformed.x;
-// }
-//
-// if ((*horizontalAlignment & 8) != 0) {
-// nAlignAdjX = rTransformed.w;
-// }
-//
-// int nAlignAdjY = 0;
-//
-// if ((*verticalAlignment & 4) != 0) {
-// nAlignAdjY = rClipTransformed.h - rClipTransformed.y;
-// }
-//
-// if ((*verticalAlignment & 8) != 0) {
-// nAlignAdjY = rTransformed.h;
-// }
-//
-// *horizontalAlignment = *horizontalAlignment & 0xFFFFFFF3; // Unset 0x4 | 0x8
-// *verticalAlignment = *verticalAlignment & 0xFFFFFFF3; // Unset 0x4 | 0x8
-//
-// int nFinalPoint = static_cast(p_DrawTransformToScreenH(static_cast(*pointSize)));
-//
-// if (bUseFontSizeFloor)
-// {
-// nFinalPoint = (std::max)(10, nFinalPoint);
-// }
-//
-// nFinalPoint = (std::min)(nFinalPoint, 79);
-// nFinalPoint = static_cast(floor(nFinalPoint));
-//
-// line_metric *const pNewLineMetrics = font->newLineMetrics;
-// int lastLineHeight;
-//
-// for (; nFinalPoint > 1 && (nAlignAdjX != 0 || nAlignAdjY != 0); --nFinalPoint)
-// {
-// line_metric *const pNewLineMetric = &pNewLineMetrics[nFinalPoint];
-// const float fLineHeight = pNewLineMetric->ascent - pNewLineMetric->descent + pNewLineMetric->line_spacing - 0.001f;
-//
-// if (nAlignAdjY < 1 || fLineHeight <= nAlignAdjY)
-// {
-// *nlines = p_wordwrap(letters, 0x40000, nletters, text, rTransformed.w, font, nFinalPoint, *pointIndex, maxLines, &lastLineHeight, adjustData, indent);
-//
-// if
-// (
-// (nAlignAdjY < 1 || *nlines * fLineHeight <= nAlignAdjY)
-// &&
-// (nAlignAdjX < 1 || letters->w <= nAlignAdjX)
-// )
-// {
-// break;
-// }
-// }
-// }
-//
-// if (*nletters == 0)
-// {
-// *nlines = p_wordwrap(letters, 0x40000, nletters, text, rTransformed.w, font, nFinalPoint, *pointIndex, maxLines, &lastLineHeight, adjustData, indent);
-// }
-//
-// r->x = rTransformed.x;
-// r->y = rTransformed.y;
-// r->w = rTransformed.w;
-// r->h = rTransformed.h;
-// rClip->x = rClipTransformed.x;
-// rClip->y = rClipTransformed.y;
-// rClip->w = rClipTransformed.w;
-// rClip->h = rClipTransformed.h;
-// *pointSize = nFinalPoint;
-//
-// line_metric *const pNewLineMetric = &pNewLineMetrics[nFinalPoint];
-// const int nLineHeight = static_cast(ceil(pNewLineMetric->ascent - pNewLineMetric->descent + pNewLineMetric->line_spacing));
-// return nLineHeight * *nlines;
-//}
-
int checkNoSavingThrowsAndEvasion(CGameEffect *const pEffect, CGameSprite *const pTarget) {
if ((pEffect->m_savingThrow & 0x1F) == 0) {
@@ -2684,468 +2983,168 @@ void __cdecl EEex::Override_crashHandler(EXCEPTION_POINTERS* pExceptionPointers)
DumpCrashInfo(pExceptionPointers);
}
-#undef fprintf
-
-int __cdecl EEex::Override_Infinity_WriteINILine(lua_State* L) {
- _iobuf *const buf = reinterpret_cast<_iobuf*>(lua_touserdata(L, 1));
- const char *const line = lua_tolstring(L, 2, nullptr);
- fprintf(buf, "%s", line);
- return 0;
-}
-
-#define fprintf error
-
-int CAICondition::Override_Hold(CTypedPtrList* pTriggerList, CGameAIBase* pCaller)
-{
- auto pNode = this->m_triggerList.m_pNodeHead;
- if (pNode == nullptr) {
- return 1;
- }
-
- bool bRet = false;
- int nORCounter = 0;
-
- bool bNextTriggerObject = false;
- CGameAIBase* pNextTriggerObject = nullptr;
-
- // EEex
- int nTrigger = 0;
-
- do
- {
- if (nORCounter <= 0) {
- bRet = false;
- }
-
- CAITrigger *const pTrigger = pNode->data;
- const short nTriggerID = pTrigger->m_triggerID;
-
- if (nTriggerID == 0x4089) // OR
- {
- nORCounter = pTrigger->m_specificID;
- }
- else if (nTriggerID == 0x40E0) // NextTriggerObject
- {
- EngineVal nextTriggerObjectType{ &pTrigger->m_triggerCause };
- nextTriggerObjectType->Decode(pCaller);
-
- bNextTriggerObject = true;
- pNextTriggerObject = reinterpret_cast(nextTriggerObjectType->GetShareType(pCaller, CGameObjectType::AIBASE, 0));
-
- if (pNextTriggerObject != nullptr && nORCounter < 1) {
- bRet = true;
- }
- }
- else {
- --nORCounter;
- }
-
- if (nTriggerID != 0x40E0) // NOT NextTriggerObject
- {
- if (bNextTriggerObject)
- {
- if (pNextTriggerObject != nullptr)
- {
- // EEex
- if (EEex::bInTrackedResponse)
- {
- for (auto callback : triggerHitCallbacks) {
- callback(nTrigger);
- }
- }
-
- bNextTriggerObject = false;
- const bool bTriggerHolds = this->TriggerHolds(pTrigger, pTriggerList, pNextTriggerObject);
- bRet |= bTriggerHolds;
-
- // EEex
- if (EEex::bInTrackedResponse)
- {
- for (auto callback : triggerEvaluatedCallbacks) {
- callback(bTriggerHolds);
- }
- }
- }
- }
- else
- {
- // EEex
- if (EEex::bInTrackedResponse)
- {
- for (auto callback : triggerHitCallbacks) {
- callback(nTrigger);
- }
- }
-
- const bool bTriggerHolds = this->TriggerHolds(pTrigger, pTriggerList, pCaller);
- bRet |= bTriggerHolds;
-
- // EEex
- if (EEex::bInTrackedResponse)
- {
- for (auto callback : triggerEvaluatedCallbacks) {
- callback(bTriggerHolds);
- }
- }
- }
- }
-
- if (!bRet && nORCounter < 1) // Fail
- {
- break;
- }
-
- pNode = pNode->pNext;
-
- // EEex
- ++nTrigger;
- }
- while (pNode != nullptr);
-
- return bRet;
-}
-
-int CAICondition::Override_TriggerHolds(CAITrigger* pTrigger, CTypedPtrList* pTriggerList, CGameAIBase* pCaller)
-{
- bool nRet = false;
-
- if ((pTrigger->m_triggerID & 0x4000) == 0) // Event-driven trigger
- {
- for (auto pNode = pTriggerList->m_pNodeHead; pNode != nullptr; pNode = pNode->pNext)
- {
- pTrigger->m_triggerCause.Decode(pCaller);
- nRet = pNode->data->OfType(pTrigger);
-
- if ((pTrigger->m_flags & 1) != 0) // Inverted
- {
- nRet = !nRet;
- }
-
- if (nRet) {
- break;
- }
- }
- }
- else // Status trigger
- {
- nRet = pCaller->virtual_EvaluateStatusTrigger(pTrigger);
-
- if ((pTrigger->m_flags & 1) != 0) // Inverted
- {
- nRet = !nRet;
- }
- }
-
- return nRet;
-}
-
-void updateScriptingObject(CGameAIBase* pAIBase, EEex_ScriptingObject scriptingObject, CAIObjectType* pToSet, CAIObjectType* pToSetWith) {
-
- if (*pToSet != pToSetWith) {
-
- pToSet->Set(pToSetWith);
-
- lua_State *const L = *p_g_lua;
- luaCallProtected(L, 2, 0, [&](int _) {
- lua_getglobal(L, "EEex_AIBase_LuaHook_OnScriptingObjectUpdated"); // 1 [ ..., EEex_AIBase_LuaHook_OnScriptingObjectUpdated ]
- tolua_pushusertype(L, pAIBase, "CGameAIBase"); // 2 [ ..., EEex_AIBase_LuaHook_OnScriptingObjectUpdated, pAIBaseUD ]
- lua_pushinteger(L, static_cast<__int32>(scriptingObject)); // 3 [ ..., EEex_AIBase_LuaHook_OnScriptingObjectUpdated, pAIBaseUD, scriptingObject ]
- });
- }
-}
-
-void CMessageSetLastObject::Override_Run() {
-
- CGameObject* pObject;
- if
- (
- CGameObjectArray::GetShare(this->m_targetId, &pObject) != 0
- ||
- (pObject->virtual_GetObjectType() & CGameObjectType::AIBASE) == 0
- )
- {
- return;
- }
-
- if (pObject->virtual_GetObjectType() == CGameObjectType::SPRITE) {
- CGameSprite *const pSprite = reinterpret_cast(pObject);
- if ((pSprite->m_derivedStats.m_generalState & 0x80) != 0 || (pSprite->m_baseStats.m_generalState & 0x80) != 0) {
- // STONE_DEATH
- return;
- }
- }
-
- CGameAIBase *const pAIBase = reinterpret_cast(pObject);
-
- switch (this->m_type) {
- case 0x0002: { // AttackedBy
- updateScriptingObject(pAIBase, EEex_ScriptingObject::ATTACKER, &pAIBase->m_lAttacker, &this->m_lAttacker);
- pAIBase->m_lAttackerSent.Set(&this->m_lAttacker);
- break;
- }
- case 0x0003: { // Help
- updateScriptingObject(pAIBase, EEex_ScriptingObject::HELP, &pAIBase->m_lHelp, &this->m_lAttacker);
- pAIBase->m_lHelpSent.Set(&this->m_lAttacker);
- break;
- }
- case 0x0006: { // ReceivedOrder
- updateScriptingObject(pAIBase, EEex_ScriptingObject::ORDERED_BY, &pAIBase->m_lOrderedBy, &this->m_lAttacker);
- pAIBase->m_lOrderedBySent.Set(&this->m_lAttacker);
- break;
- }
- case 0x0007: { // Said
- updateScriptingObject(pAIBase, EEex_ScriptingObject::TALKED_TO, &pAIBase->m_lTalkedTo, &this->m_lAttacker);
- pAIBase->m_lTalkedToSent.Set(&this->m_lAttacker);
- break;
- }
- case 0x0020: { // HitBy
- updateScriptingObject(pAIBase, EEex_ScriptingObject::HITTER, &pAIBase->m_lHitter, &this->m_lAttacker);
- pAIBase->m_lHitterSent.Set(&this->m_lAttacker);
- break;
- }
- case 0x002F: { // Heard
- updateScriptingObject(pAIBase, EEex_ScriptingObject::HEARD, &pAIBase->m_lHeard, &this->m_lAttacker);
- pAIBase->m_lHeardSent.Set(&this->m_lAttacker);
- break;
- }
- case 0x004B: { // Killed
- updateScriptingObject(pAIBase, EEex_ScriptingObject::KILLED, &pAIBase->m_lKilled, &this->m_lAttacker);
- pAIBase->m_lKilledSent.Set(&this->m_lAttacker);
- break;
- }
- case 0x0097: { // Summoned
- updateScriptingObject(pAIBase, EEex_ScriptingObject::SUMMONED_BY, &pAIBase->m_lSummonedBy, &this->m_lAttacker);
- pAIBase->m_lSummonedBySent.Set(&this->m_lAttacker);
- break;
- }
- case 0x401C: { // See
- updateScriptingObject(pAIBase, EEex_ScriptingObject::SEEN, &pAIBase->m_lSeen, &this->m_lAttacker);
- pAIBase->m_lSeenSent.Set(&this->m_lAttacker);
- break;
- }
- default: {
- updateScriptingObject(pAIBase, EEex_ScriptingObject::TRIGGER, &pAIBase->m_lTrigger, &this->m_lAttacker);
- pAIBase->m_lTriggerSent.Set(&this->m_lAttacker);
- break;
- }
- }
-}
-
-static void onEventTriggerSet(CGameAIBase *const pAIBase, CAITrigger *const pTrigger) {
-
- if (!EEex::AIBase_LuaHook_OnEventTriggerSet_Enabled) {
- return;
- }
-
- lua_State *const L = *p_g_lua;
- luaCallProtected(L, 2, 0, [&](int) {
- lua_getglobal(L, "EEex_AIBase_LuaHook_OnEventTriggerSet"); // 1 [ ..., EEex_AIBase_LuaHook_OnEventTriggerSet ]
- pushGameObjectUD(L, pAIBase); // 2 [ ..., EEex_AIBase_LuaHook_OnEventTriggerSet, pAIBaseUD ]
- tolua_pushusertype(L, pTrigger, "CAITrigger"); // 3 [ ..., EEex_AIBase_LuaHook_OnEventTriggerSet, pAIBaseUD, pTriggerUD ]
- });
-}
-
-void CGameAIBase::Override_SetTrigger(const CAITrigger* pTrigger) {
-
- CAITrigger *const pTriggerCopy = newEngineObj(pTrigger);
-
- onEventTriggerSet(this, pTriggerCopy);
- this->m_pendingTriggers.AddTail(pTriggerCopy);
- this->m_bNewTrigger = 1;
-
- if ((pTriggerCopy->m_flags & 4) != 0) {
- return;
- }
- pTriggerCopy->m_flags |= 4;
-
- CInfGame *const pGame = (*p_g_pBaldurChitin)->m_pObjectGame;
-
- switch (pTriggerCopy->m_triggerID) {
-
- case 0x0002: { // AttackedBy
-
- this->virtual_AutoPause(2);
-
- CGameSprite* pSprite = reinterpret_cast(pTriggerCopy->m_triggerCause.GetShareType(this, CGameObjectType::SPRITE, 0));
- if (pSprite != nullptr) {
- // I don't know why the engine repeats this
- pSprite = reinterpret_cast(pTriggerCopy->m_triggerCause.GetShareType(this, CGameObjectType::SPRITE, 0));
- if ((pSprite->GetActiveStats()->m_generalState & 0x800) != 0) {
- break;
- }
- }
-
- this->m_lAttackStyle = pTriggerCopy->m_specificID;
- if
- (
- pGame->GetCharacterPortraitNum(this->m_id) == -1
- ||
- pGame->GetCharacterPortraitNum(pTriggerCopy->m_triggerCause.m_Instance) == -1
- )
- {
- updateScriptingObject(this, EEex_ScriptingObject::ATTACKER, &this->m_lAttacker, &pTriggerCopy->m_triggerCause);
- }
- break;
- }
- case 0x0003: { // Help
- updateScriptingObject(this, EEex_ScriptingObject::HELP, &this->m_lHelp, &pTriggerCopy->m_triggerCause);
- break;
- }
- case 0x0006: { // ReceivedOrder
- updateScriptingObject(this, EEex_ScriptingObject::ORDERED_BY, &this->m_lOrderedBy, &pTriggerCopy->m_triggerCause);
- break;
- }
- case 0x0007: { // Said
- updateScriptingObject(this, EEex_ScriptingObject::TALKED_TO, &this->m_lTalkedTo, &pTriggerCopy->m_triggerCause);
- break;
- }
- case 0x0020: { // HitBy
-
- this->virtual_AutoPause(4);
- this->m_lAttackStyle = pTriggerCopy->m_specificID;
-
- updateScriptingObject(this, EEex_ScriptingObject::HITTER, &this->m_lHitter, &pTriggerCopy->m_triggerCause);
- break;
- }
- case 0x002F: { // Heard
- updateScriptingObject(this, EEex_ScriptingObject::HEARD, &this->m_lHeard, &pTriggerCopy->m_triggerCause);
- break;
- }
- case 0x004C: { // Entered
- if (this->virtual_GetObjectType() == CGameObjectType::TRIGGER) {
- CGameTrigger *const pTrigger = reinterpret_cast(this);
- if ((pTrigger->m_dwFlags & 2) == 0) {
- pTrigger->SetDrawPoly(0);
- }
- }
- break;
- }
- case 0x0052: { // Opened
- if (this->virtual_GetObjectType() == CGameObjectType::DOOR) {
- CGameDoor *const pDoor = reinterpret_cast(this);
- if ((pDoor->m_dwFlags & 4) == 0) {
- pDoor->SetDrawPoly(0);
- }
- }
- else {
- if (this->virtual_GetObjectType() == CGameObjectType::CONTAINER) {
- CGameContainer *const pContainer = reinterpret_cast(this);
- if ((pContainer->m_dwFlags & 8) == 0) {
- pContainer->SetDrawPoly(0);
- }
- }
- }
- break;
- }
- case 0x0097: { // Summoned
- updateScriptingObject(this, EEex_ScriptingObject::SUMMONED_BY, &this->m_lSummonedBy, &pTriggerCopy->m_triggerCause);
- break;
- }
- }
+//int __cdecl EEex::Override_fontWrap(
+// char* text,
+// SDL_Rect* r,
+// SDL_Rect* rClip,
+// int* horizontalAlignment,
+// int* verticalAlignment,
+// font_t* font,
+// int* pointSize,
+// letter_t* letters,
+// int* nlines,
+// int* nletters,
+// int* pointIndex,
+// bool* scale,
+// adjustmentData_t* adjustData,
+// int indent,
+// bool bUseFontSizeFloor)
+//{
+// const int maxLines = (*verticalAlignment >> 16) & 0xFFF;
+// *verticalAlignment &= 0xFFFF;
+//
+// if (r->h == 0xFFFFFF)
+// {
+// *verticalAlignment = 0;
+// }
+//
+// SDL_Rect rTransformed;
+// SDL_Rect rClipTransformed;
+//
+// p_DrawTransformToScreen(r, &rTransformed);
+// p_DrawTransformToScreen(rClip, &rClipTransformed);
+//
+// int nAlignAdjX = 0;
+//
+// if ((*horizontalAlignment & 4) != 0) {
+// nAlignAdjX = rClipTransformed.w - rClipTransformed.x;
+// }
+//
+// if ((*horizontalAlignment & 8) != 0) {
+// nAlignAdjX = rTransformed.w;
+// }
+//
+// int nAlignAdjY = 0;
+//
+// if ((*verticalAlignment & 4) != 0) {
+// nAlignAdjY = rClipTransformed.h - rClipTransformed.y;
+// }
+//
+// if ((*verticalAlignment & 8) != 0) {
+// nAlignAdjY = rTransformed.h;
+// }
+//
+// *horizontalAlignment = *horizontalAlignment & 0xFFFFFFF3; // Unset 0x4 | 0x8
+// *verticalAlignment = *verticalAlignment & 0xFFFFFFF3; // Unset 0x4 | 0x8
+//
+// int nFinalPoint = static_cast(p_DrawTransformToScreenH(static_cast(*pointSize)));
+//
+// if (bUseFontSizeFloor)
+// {
+// nFinalPoint = (std::max)(10, nFinalPoint);
+// }
+//
+// nFinalPoint = (std::min)(nFinalPoint, 79);
+// nFinalPoint = static_cast(floor(nFinalPoint));
+//
+// line_metric *const pNewLineMetrics = font->newLineMetrics;
+// int lastLineHeight;
+//
+// for (; nFinalPoint > 1 && (nAlignAdjX != 0 || nAlignAdjY != 0); --nFinalPoint)
+// {
+// line_metric *const pNewLineMetric = &pNewLineMetrics[nFinalPoint];
+// const float fLineHeight = pNewLineMetric->ascent - pNewLineMetric->descent + pNewLineMetric->line_spacing - 0.001f;
+//
+// if (nAlignAdjY < 1 || fLineHeight <= nAlignAdjY)
+// {
+// *nlines = p_wordwrap(letters, 0x40000, nletters, text, rTransformed.w, font, nFinalPoint, *pointIndex, maxLines, &lastLineHeight, adjustData, indent);
+//
+// if
+// (
+// (nAlignAdjY < 1 || *nlines * fLineHeight <= nAlignAdjY)
+// &&
+// (nAlignAdjX < 1 || letters->w <= nAlignAdjX)
+// )
+// {
+// break;
+// }
+// }
+// }
+//
+// if (*nletters == 0)
+// {
+// *nlines = p_wordwrap(letters, 0x40000, nletters, text, rTransformed.w, font, nFinalPoint, *pointIndex, maxLines, &lastLineHeight, adjustData, indent);
+// }
+//
+// r->x = rTransformed.x;
+// r->y = rTransformed.y;
+// r->w = rTransformed.w;
+// r->h = rTransformed.h;
+// rClip->x = rClipTransformed.x;
+// rClip->y = rClipTransformed.y;
+// rClip->w = rClipTransformed.w;
+// rClip->h = rClipTransformed.h;
+// *pointSize = nFinalPoint;
+//
+// line_metric *const pNewLineMetric = &pNewLineMetrics[nFinalPoint];
+// const int nLineHeight = static_cast(ceil(pNewLineMetric->ascent - pNewLineMetric->descent + pNewLineMetric->line_spacing));
+// return nLineHeight * *nlines;
+//}
- if (pGame->SAVE_OBJECT_LIST.Find(pTriggerCopy->m_triggerID) != nullptr) {
- updateScriptingObject(this, EEex_ScriptingObject::TRIGGER, &this->m_lTrigger, &pTriggerCopy->m_triggerCause);
- }
+#undef fprintf
- if (this->virtual_GetObjectType() == CGameObjectType::SPRITE) {
- CGameSprite *const pSprite = reinterpret_cast(this);
- pSprite->GetActiveStats()->m_cContingencyList.ProcessTrigger(pSprite, pTriggerCopy);
- }
+int __cdecl EEex::Override_Infinity_WriteINILine(lua_State* L) {
+ _iobuf *const buf = reinterpret_cast<_iobuf*>(lua_touserdata(L, 1));
+ const char *const line = lua_tolstring(L, 2, nullptr);
+ fprintf(buf, "%s", line);
+ return 0;
}
-void CGameAIBase::Override_ApplyTriggers() {
-
- CBaldurChitin *const pBaldurChitin = *p_g_pBaldurChitin;
- CInfGame *const pGame = pBaldurChitin->m_pObjectGame;
+#define fprintf error
- if (pGame->m_worldTime.m_gameTime % 3600 == 0) {
- CMessageUpdateReaction *const pMessage = newEngineObj(11, this->m_id, this->m_id);
- pBaldurChitin->m_cMessageHandler.AddMessage(pMessage, 0);
- }
+void __cdecl EEex::Override_uiDoFile(char* fileName) {
- if (this->virtual_GetObjectType() == CGameObjectType::SPRITE) {
- CGameSprite *const pSprite = reinterpret_cast(this);
- pSprite->GetActiveStats()->m_cContingencyList.Process(pSprite);
- }
+ lua_State *const L = *p_g_lua;
- for (auto pNode = this->m_pendingTriggers.m_pNodeHead; pNode != nullptr; pNode = pNode->pNext) {
+ EngineVal fullFileName{};
+ fullFileName->Format("%s.lua", fileName);
- CAITrigger *const pTrigger = pNode->data;
- if ((pTrigger->m_flags & 4) != 0) {
- continue;
- }
- pTrigger->m_flags |= 4;
+ const CResRef resref { fileName };
+ CRes *const pRes = p_dimmGetResObject(&resref, 0x409, false);
- switch (pTrigger->m_triggerID) {
+ if (pRes != nullptr) {
- case 0x0002: { // AttackedBy
+ const char *const pResBuffer = reinterpret_cast(pRes->Demand());
- this->virtual_AutoPause(2);
- this->m_lAttackStyle = pTrigger->m_specificID;
+ if (luaL_loadbufferx(L, pResBuffer, pRes->nSize, fullFileName->m_pchData, nullptr) == LUA_OK) {
- if
- (
- pGame->GetCharacterPortraitNum(this->m_id) == -1
- ||
- pGame->GetCharacterPortraitNum(pTrigger->m_triggerCause.m_Instance) == -1
- )
- {
- updateScriptingObject(this, EEex_ScriptingObject::ATTACKER, &this->m_lAttacker, &pTrigger->m_triggerCause);
- }
- break;
- }
- case 0x0003: { // Help
- updateScriptingObject(this, EEex_ScriptingObject::HELP, &this->m_lHelp, &pTrigger->m_triggerCause);
- break;
- }
- case 0x0006: { // ReceivedOrder
- updateScriptingObject(this, EEex_ScriptingObject::ORDERED_BY, &this->m_lOrderedBy, &pTrigger->m_triggerCause);
- break;
- }
- case 0x0007: { // Said
- updateScriptingObject(this, EEex_ScriptingObject::TALKED_TO, &this->m_lTalkedTo, &pTrigger->m_triggerCause);
- break;
- }
- case 0x0020: { // HitBy
+ if (lua_pcallk(L, 0, -1, 0, 0, nullptr) != LUA_OK) {
- this->virtual_AutoPause(4);
- this->m_lAttackStyle = pTrigger->m_specificID;
+ const char *const pErrorMessage = lua_tolstring(L, -1, nullptr);
- updateScriptingObject(this, EEex_ScriptingObject::HITTER, &this->m_lHitter, &pTrigger->m_triggerCause);
- break;
- }
- case 0x002F: { // Heard
- updateScriptingObject(this, EEex_ScriptingObject::HEARD, &this->m_lHeard, &pTrigger->m_triggerCause);
- break;
- }
- case 0x0097: { // Summoned
- updateScriptingObject(this, EEex_ScriptingObject::SUMMONED_BY, &this->m_lSummonedBy, &pTrigger->m_triggerCause);
- break;
+ if (pErrorMessage != nullptr) {
+ p_SDL_ShowSimpleMessageBox(0x10, CChitin::p_m_sGameName->m_pchData, pErrorMessage, (*p_g_pBaldurChitin)->cVideo.pCurrentMode->m_pWindow);
+ p_SDL_Log("Error [%s] in %s", pErrorMessage, fullFileName->m_pchData);
+ }
}
}
-
- if (pGame->SAVE_OBJECT_LIST.Find(pTrigger->m_triggerID) != nullptr) {
- updateScriptingObject(this, EEex_ScriptingObject::TRIGGER, &this->m_lTrigger, &pTrigger->m_triggerCause);
+ else {
+ const char *const pErrorMessage = lua_tolstring(L, -1, nullptr);
+ p_SDL_ShowSimpleMessageBox(0x10, CChitin::p_m_sGameName->m_pchData, pErrorMessage, (*p_g_pBaldurChitin)->cVideo.pCurrentMode->m_pWindow);
+ p_SDL_Log("Err: %s", pErrorMessage);
}
- if (this->virtual_GetObjectType() == CGameObjectType::SPRITE) {
- CGameSprite *const pSprite = reinterpret_cast(this);
- pSprite->GetActiveStats()->m_cContingencyList.ProcessTrigger(pSprite, pTrigger);
- }
+ pRes->virtual_Dump();
}
-}
-
-void CScreenMap::Override_OnLButtonDblClk(CPoint cPoint) {
- CBaldurEngine *const pActiveEngine = reinterpret_cast((*p_g_pBaldurChitin)->pActiveEngine);
- pActiveEngine->OnLeftPanelButtonClick(0);
+ EngineVal langFile{};
+ langFile->Format("L_%s", static_cast(*p_lang));
- // Vanilla Bugfix: Fix closing the local area map with a double click resulting in the world screen responding to the button up event
- // |
- lua_State *const L = luaState();
- luaCallProtected(L, 0, 0, [&](int _) {
- lua_getglobal(L, "EEex_Fix_LuaHook_OnLocalMapDoubleClick");
- });
+ if (_stricmp(fileName, langFile->m_pchData) == 0) {
+ luaCallProtected(L, 0, 0, [&](int _) {
+ lua_getglobal(L, "EEex_Menu_LuaHook_AfterTranslationLoaded"); // 1 [ ..., EEex_Menu_LuaHook_AfterTranslationLoaded ]
+ });
+ }
}
/////////////////////////////
@@ -3531,6 +3530,28 @@ int CGameEffectUsability::Override_CheckUsability(CGameSprite* pSprite) {
return match ^ EEex::Opcode_Hook_Op319_IsInverted(this);
}
+//-------//
+// op342 //
+//-------//
+
+void EEex::Opcode_Hook_Op342_OnUnhandledParam2(CGameEffect* pEffect, CGameSprite* pSprite) {
+
+ if (pEffect->m_dWFlags == 5) { // Override combat_round_* in animation INI
+
+ const int nCombatRoundSlot = pEffect->m_effectAmount;
+
+ if (nCombatRoundSlot < 0 || nCombatRoundSlot > 4) {
+ // Invalid combat round slot
+ pEffect->m_done = true;
+ return;
+ }
+
+ ExSpriteData& exData = exSpriteDataMap[pSprite];
+ exData.combatRoundsOverride[nCombatRoundSlot]->SetResRef(&pEffect->m_res, true, true);
+ pSprite->m_animation.m_overrides |= (0x4 << (nCombatRoundSlot + 1));
+ }
+}
+
//-----------//
// New op400 //
//-----------//
@@ -3955,6 +3976,38 @@ void EEex::Sprite_Hook_OnBeforeEffectListMarshalled(CGameSprite* pSprite) {
STUTTER_LOG_END
}
+static byte getAttackFrameTypeReimplementation(CVidBitmap* aBitmaps, byte numAttacks, byte speedFactor, byte combatFrame) {
+
+ if (numAttacks <= 5 && speedFactor <= 10) {
+
+ if (combatFrame > 100) {
+ return 15;
+ }
+
+ return aBitmaps[numAttacks - 1].GetPixelValue(combatFrame, speedFactor);
+ }
+
+ return 0;
+}
+
+byte EEex::Sprite_Hook_OnGetAttackFrameType(CGameSprite* pSprite, byte numAttacks) {
+
+ const CGameAnimation *const pAnimation = &pSprite->m_animation;
+ const byte nSpeedFactor = static_cast(pSprite->m_speedFactor);
+ const byte nAttackFrame = static_cast(pSprite->m_attackFrame);
+
+ if ((pAnimation->m_overrides & (0x4 << numAttacks)) != 0) { // Override combat_round_* in animation INI
+
+ // Passing `combatRoundsOverride` as a raw `CVidBitmap` array requires that the `EngineVal` wrapper isn't adding any fields
+ static_assert(sizeof(EngineVal) == sizeof(CVidBitmap));
+
+ ExSpriteData& exData = exSpriteDataMap[pSprite];
+ return getAttackFrameTypeReimplementation(&**exData.combatRoundsOverride, numAttacks, nSpeedFactor, nAttackFrame);
+ }
+
+ return pAnimation->m_animation->virtual_GetAttackFrameType(numAttacks, nSpeedFactor, nAttackFrame);
+}
+
CGameEffectDamage* CGameSprite::Override_Damage(
CItem* curWeaponIn, CItem* pLauncher, int curAttackNum, int criticalDamage,
CAIObjectType* type, short facing, short myFacing, CGameSprite* target, int lastSwing)
@@ -5082,6 +5135,26 @@ void CGameText::Override_Render(CGameArea* pArea, CVidMode* pVidMode)
}
}
+void EEex::Fix_Hook_ImplementWSPECIALSpeedColumn(CGameSprite* pSprite, int nProficiencyLevel, bool bOffHand) {
+
+ if (bOffHand) {
+ return;
+ }
+
+ const C2DArray& WSPECIAL = (*p_g_pBaldurChitin)->m_pObjectGame->m_ruleTables.m_tWeaponSpecialization;
+ const CString *const sCell = WSPECIAL.GetAt(2, nProficiencyLevel);
+
+ int nBonus = 0;
+
+ if (sscanf(sCell->m_pchData, "%d", &nBonus) != 1) {
+ #pragma warning(disable:6031)
+ sscanf(WSPECIAL.m_default.m_pchData, "%d", &nBonus);
+ #pragma warning(default:6031)
+ }
+
+ pSprite->m_derivedStats.m_nPhysicalSpeed -= nBonus;
+}
+
void EEex::Fix_Hook_OnBeforeUIKillCapture() {
if (p_capture->item == nullptr || p_capture->item->type != uiItemType::ITEM_EDIT) {
@@ -5291,4 +5364,8 @@ void EEex::InitEEex() {
EEex::Projectile_LuaHook_GlobalMutators_Enabled = false;
initProjectileMutator();
EEex::StutterDetector_Enabled = false;
+
+ //LoadFunctionNames();
+ //Profiler_RegisterTrace("Render", 0x140136300, 15);
+ //Profiler_RegisterTrace("AI", 0x140131BF0, 5);
}
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/Generated/Baldur-v2.6.6.0_generated_internal_pointers.cpp b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/Generated/Baldur-v2.6.6.0_generated_internal_pointers.cpp
index d21ae1d..4e470c8 100644
--- a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/Generated/Baldur-v2.6.6.0_generated_internal_pointers.cpp
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/Generated/Baldur-v2.6.6.0_generated_internal_pointers.cpp
@@ -15,6 +15,8 @@ bool EEex::StutterDetector_Enabled;
int EEex::UncapFPS_BusyWaitThreshold;
bool EEex::UncapFPS_Enabled;
int EEex::UncapFPS_FPSLimit;
+bool EEex::UncapFPS_FPSLimitEnabled;
+int EEex::UncapFPS_LuaGCSteps;
bool EEex::UncapFPS_RemoveMiddleMouseScrollMultiplier;
CTimerWorld::type_StartTime CTimerWorld::p_StartTime;
CString::type_Construct_Overload_String CString::p_Construct_Overload_String;
@@ -67,6 +69,7 @@ type_findMenu p_findMenu;
type_rand p_rand;
type_restoreMenuStack p_restoreMenuStack;
type_saveMenuStack p_saveMenuStack;
+type_SDL_GetDisplayForWindow p_SDL_GetDisplayForWindow;
type_SDL_GetKeyFromName p_SDL_GetKeyFromName;
type_SDL_GetKeyName p_SDL_GetKeyName;
type_SDL_GetWindowFlags p_SDL_GetWindowFlags;
@@ -93,6 +96,7 @@ type_DrawEnable p_DrawEnable;
type_DrawEnd p_DrawEnd;
type_DrawEndScaled p_DrawEndScaled;
type_drawLetters p_drawLetters;
+type_drawMenu p_drawMenu;
type_DrawOrtho11Begin p_DrawOrtho11Begin;
type_DrawOrtho11End p_DrawOrtho11End;
type_DrawPopState p_DrawPopState;
@@ -101,6 +105,7 @@ type_DrawQuad p_DrawQuad;
type_drawSlice p_drawSlice;
type_drawSliceSide p_drawSliceSide;
type_DrawTexCoord p_DrawTexCoord;
+type_drawTop p_drawTop;
type_DrawTransformToScreen p_DrawTransformToScreen;
type_DrawTransformToScreenH p_DrawTransformToScreenH;
type_DrawVertex p_DrawVertex;
@@ -118,6 +123,7 @@ type_SDL_ShowSimpleMessageBox p_SDL_ShowSimpleMessageBox;
type_SearchThreadMain p_SearchThreadMain;
type_uiDrawSlicedRect p_uiDrawSlicedRect;
type_uiExecLuaInt p_uiExecLuaInt;
+type_uiHandleTooltip p_uiHandleTooltip;
type_uiPop p_uiPop;
type_uiPush p_uiPush;
type_uiSetHidden p_uiSetHidden;
@@ -128,6 +134,8 @@ type_XScreenToZoomed p_XScreenToZoomed;
type_YScreenToZoomed p_YScreenToZoomed;
char** p_afxPchNil;
_9B9540D9920A90D57A3D80DDD1A70514* p_capture;
+bool* p_fingerDown;
+uiMenu** p_g_backgroundMenu;
RendererType* p_g_drawBackend;
Array* p_g_keywords;
lua_State** p_g_lua;
@@ -140,6 +148,7 @@ Array* p_menuStack;
int* p_nextStackMenuIdx;
int* p_numMenus;
CTypedPtrArray* p_resources;
+_820A8B7015E7E0FD9144A7C186FBF075* p_tooltip;
_A92C2F5FC159A4FE55DD6CCAABD58E72* p_transition;
ConstArray* p_yy_action;
ConstArray* p_yy_default;
@@ -188,7 +197,11 @@ CAIScriptFile::type_ParseObjectType CAIScriptFile::p_ParseObjectType;
CAIScriptFile::type_ParseResponseString CAIScriptFile::p_ParseResponseString;
CSound::type_Construct CSound::p_Construct;
CSound::type_Destruct CSound::p_Destruct;
+CVidBitmap::type_Construct CVidBitmap::p_Construct;
+CVidBitmap::type_Destruct CVidBitmap::p_Destruct;
CVidBitmap::type_GetPixelColor CVidBitmap::p_GetPixelColor;
+CVidBitmap::type_GetPixelValueOrZero CVidBitmap::p_GetPixelValueOrZero;
+CVidBitmap::type_SetResRef CVidBitmap::p_SetResRef;
CSearchBitmap::type_GetCost CSearchBitmap::p_GetCost;
CSearchBitmap::type_GetLOSCost CSearchBitmap::p_GetLOSCost;
CSearchBitmap::type_GetNearestOpenSquare CSearchBitmap::p_GetNearestOpenSquare;
@@ -394,6 +407,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("rand"), p_rand);
attemptFillPointer(TEXT("restoreMenuStack"), p_restoreMenuStack);
attemptFillPointer(TEXT("saveMenuStack"), p_saveMenuStack);
+ attemptFillPointer(TEXT("SDL_GetDisplayForWindow"), p_SDL_GetDisplayForWindow);
attemptFillPointer(TEXT("SDL_GetKeyFromName"), p_SDL_GetKeyFromName);
attemptFillPointer(TEXT("SDL_GetKeyName"), p_SDL_GetKeyName);
attemptFillPointer(TEXT("SDL_GetWindowFlags"), p_SDL_GetWindowFlags);
@@ -420,6 +434,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("DrawEnd"), p_DrawEnd);
attemptFillPointer(TEXT("DrawEndScaled"), p_DrawEndScaled);
attemptFillPointer(TEXT("drawLetters"), p_drawLetters);
+ attemptFillPointer(TEXT("drawMenu"), p_drawMenu);
attemptFillPointer(TEXT("DrawOrtho11Begin"), p_DrawOrtho11Begin);
attemptFillPointer(TEXT("DrawOrtho11End"), p_DrawOrtho11End);
attemptFillPointer(TEXT("DrawPopState"), p_DrawPopState);
@@ -428,6 +443,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("drawSlice"), p_drawSlice);
attemptFillPointer(TEXT("drawSliceSide"), p_drawSliceSide);
attemptFillPointer(TEXT("DrawTexCoord"), p_DrawTexCoord);
+ attemptFillPointer(TEXT("drawTop"), p_drawTop);
attemptFillPointer(TEXT("DrawTransformToScreen"), p_DrawTransformToScreen);
attemptFillPointer(TEXT("DrawTransformToScreenH"), p_DrawTransformToScreenH);
attemptFillPointer(TEXT("DrawVertex"), p_DrawVertex);
@@ -445,6 +461,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("SearchThreadMain"), p_SearchThreadMain);
attemptFillPointer(TEXT("uiDrawSlicedRect"), p_uiDrawSlicedRect);
attemptFillPointer(TEXT("uiExecLuaInt"), p_uiExecLuaInt);
+ attemptFillPointer(TEXT("uiHandleTooltip"), p_uiHandleTooltip);
attemptFillPointer(TEXT("uiPop"), p_uiPop);
attemptFillPointer(TEXT("uiPush"), p_uiPush);
attemptFillPointer(TEXT("uiSetHidden"), p_uiSetHidden);
@@ -455,6 +472,8 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("YScreenToZoomed"), p_YScreenToZoomed);
attemptFillPointer(TEXT("afxPchNil"), p_afxPchNil);
attemptFillPointer(TEXT("capture"), p_capture);
+ attemptFillPointer(TEXT("fingerDown"), p_fingerDown);
+ attemptFillPointer(TEXT("g_backgroundMenu"), p_g_backgroundMenu);
attemptFillPointer(TEXT("g_drawBackend"), p_g_drawBackend);
attemptFillPointer(TEXT("g_keywords"), p_g_keywords);
attemptFillPointer(TEXT("g_lua"), p_g_lua);
@@ -467,6 +486,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("nextStackMenuIdx"), p_nextStackMenuIdx);
attemptFillPointer(TEXT("numMenus"), p_numMenus);
attemptFillPointer(TEXT("resources"), p_resources);
+ attemptFillPointer(TEXT("tooltip"), p_tooltip);
attemptFillPointer(TEXT("transition"), p_transition);
attemptFillPointer(TEXT("yy_action"), p_yy_action);
attemptFillPointer(TEXT("yy_default"), p_yy_default);
@@ -515,7 +535,11 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("CAIScriptFile::ParseResponseString"), CAIScriptFile::p_ParseResponseString);
attemptFillPointer(TEXT("CSound::Construct"), CSound::p_Construct);
attemptFillPointer(TEXT("CSound::Destruct"), CSound::p_Destruct);
+ attemptFillPointer(TEXT("CVidBitmap::Construct"), CVidBitmap::p_Construct);
+ attemptFillPointer(TEXT("CVidBitmap::Destruct"), CVidBitmap::p_Destruct);
attemptFillPointer(TEXT("CVidBitmap::GetPixelColor"), CVidBitmap::p_GetPixelColor);
+ attemptFillPointer(TEXT("CVidBitmap::GetPixelValue(int,int)"), CVidBitmap::p_GetPixelValueOrZero);
+ attemptFillPointer(TEXT("CVidBitmap::SetResRef"), CVidBitmap::p_SetResRef);
attemptFillPointer(TEXT("CSearchBitmap::GetCost"), CSearchBitmap::p_GetCost);
attemptFillPointer(TEXT("CSearchBitmap::GetLOSCost"), CSearchBitmap::p_GetLOSCost);
attemptFillPointer(TEXT("CSearchBitmap::GetNearestOpenSquare"), CSearchBitmap::p_GetNearestOpenSquare);
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/Generated/EEexLua_generated.cpp b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/Generated/EEexLua_generated.cpp
index 432028a..686f498 100644
--- a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/Generated/EEexLua_generated.cpp
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/Generated/EEexLua_generated.cpp
@@ -129,6 +129,42 @@ static int tolua_get_EEex_reference_UncapFPS_FPSLimit(lua_State* L)
return 1;
}
+static int tolua_get_EEex_UncapFPS_FPSLimitEnabled(lua_State* L)
+{
+ tolua_pushboolean(L, (bool)EEex::UncapFPS_FPSLimitEnabled);
+ return 1;
+}
+
+static int tolua_set_EEex_UncapFPS_FPSLimitEnabled(lua_State* L)
+{
+ EEex::UncapFPS_FPSLimitEnabled = tolua_setter_toboolean(L, "UncapFPS_FPSLimitEnabled");
+ return 0;
+}
+
+static int tolua_get_EEex_reference_UncapFPS_FPSLimitEnabled(lua_State* L)
+{
+ tolua_pushusertype(L, (void*)&EEex::UncapFPS_FPSLimitEnabled, "Primitive");
+ return 1;
+}
+
+static int tolua_get_EEex_UncapFPS_LuaGCSteps(lua_State* L)
+{
+ lua_pushinteger(L, (lua_Integer)EEex::UncapFPS_LuaGCSteps);
+ return 1;
+}
+
+static int tolua_set_EEex_UncapFPS_LuaGCSteps(lua_State* L)
+{
+ EEex::UncapFPS_LuaGCSteps = tolua_setter_tointeger(L, "UncapFPS_LuaGCSteps");
+ return 0;
+}
+
+static int tolua_get_EEex_reference_UncapFPS_LuaGCSteps(lua_State* L)
+{
+ tolua_pushusertype(L, (void*)&EEex::UncapFPS_LuaGCSteps, "Primitive");
+ return 1;
+}
+
static int tolua_get_EEex_UncapFPS_RemoveMiddleMouseScrollMultiplier(lua_State* L)
{
tolua_pushboolean(L, (bool)EEex::UncapFPS_RemoveMiddleMouseScrollMultiplier);
@@ -319,7 +355,7 @@ static int tolua_function_CGameSprite_getUUID(lua_State* L)
{
CGameSprite* self = (CGameSprite*)tolua_tousertype_dynamic(L, 1, 0, "CGameSprite");
if (!self) tolua_error(L, "invalid 'self' in calling function 'getUUID'", NULL);
- uint64_t returnVal = self->GetUUID();
+ uint64_t returnVal = (self->GetUUID)();
lua_pushinteger(L, (lua_Integer)returnVal);
return 1;
}
@@ -335,6 +371,8 @@ static void tolua_reg_types(lua_State* L)
tolua_usertype(L, "frameTableEntry_st::_anonymous_tag_");
tolua_usertype(L, "SDL_SysWMmsg");
tolua_usertype(L, "SDL_SysWMmsg::msg_t");
+ tolua_usertype(L, "SDL_SysWMinfo");
+ tolua_usertype(L, "SDL_SysWMinfo::info_t");
tolua_usertype(L, "Udata");
tolua_usertype(L, "TString");
tolua_usertype(L, "ISteamUserStats");
@@ -620,6 +658,7 @@ static void tolua_reg_types(lua_State* L)
tolua_usertype(L, "EEex_CBaldurEngine");
tolua_usertype(L, "CDungeonMaster");
tolua_usertype(L, "uiItem");
+ tolua_usertype(L, "SDL_VideoDevice");
tolua_usertype(L, "CResBinary");
tolua_usertype(L, "CMessageSetVariableAll");
tolua_usertype(L, "EngineGlobals");
@@ -824,6 +863,12 @@ int OpenBindingsInternal(lua_State* L)
tolua_cclass(L, "SDL_SysWMmsg::msg_t", "SDL_SysWMmsg::msg_t", {}, NULL);
tolua_beginmodule(L, "SDL_SysWMmsg::msg_t");
tolua_endmodule(L);
+ tolua_cclass(L, "SDL_SysWMinfo", "SDL_SysWMinfo", {}, NULL);
+ tolua_beginmodule(L, "SDL_SysWMinfo");
+ tolua_endmodule(L);
+ tolua_cclass(L, "SDL_SysWMinfo::info_t", "SDL_SysWMinfo::info_t", {}, NULL);
+ tolua_beginmodule(L, "SDL_SysWMinfo::info_t");
+ tolua_endmodule(L);
tolua_cclass(L, "Udata", "Udata", {}, NULL);
tolua_beginmodule(L, "Udata");
tolua_endmodule(L);
@@ -882,6 +927,10 @@ int OpenBindingsInternal(lua_State* L)
tolua_variable(L, "reference_UncapFPS_Enabled", tolua_get_EEex_reference_UncapFPS_Enabled, NULL);
tolua_variable(L, "UncapFPS_FPSLimit", tolua_get_EEex_UncapFPS_FPSLimit, tolua_set_EEex_UncapFPS_FPSLimit);
tolua_variable(L, "reference_UncapFPS_FPSLimit", tolua_get_EEex_reference_UncapFPS_FPSLimit, NULL);
+ tolua_variable(L, "UncapFPS_FPSLimitEnabled", tolua_get_EEex_UncapFPS_FPSLimitEnabled, tolua_set_EEex_UncapFPS_FPSLimitEnabled);
+ tolua_variable(L, "reference_UncapFPS_FPSLimitEnabled", tolua_get_EEex_reference_UncapFPS_FPSLimitEnabled, NULL);
+ tolua_variable(L, "UncapFPS_LuaGCSteps", tolua_get_EEex_UncapFPS_LuaGCSteps, tolua_set_EEex_UncapFPS_LuaGCSteps);
+ tolua_variable(L, "reference_UncapFPS_LuaGCSteps", tolua_get_EEex_reference_UncapFPS_LuaGCSteps, NULL);
tolua_variable(L, "UncapFPS_RemoveMiddleMouseScrollMultiplier", tolua_get_EEex_UncapFPS_RemoveMiddleMouseScrollMultiplier, tolua_set_EEex_UncapFPS_RemoveMiddleMouseScrollMultiplier);
tolua_variable(L, "reference_UncapFPS_RemoveMiddleMouseScrollMultiplier", tolua_get_EEex_reference_UncapFPS_RemoveMiddleMouseScrollMultiplier, NULL);
tolua_function(L, "CreateTemplateFromCopy", &tolua_function_EEex_CreateTemplateFromCopy);
@@ -917,6 +966,8 @@ int OpenBindingsInternal(lua_State* L)
tolua_constantstring(L, "usertype_UncapFPS_BusyWaitThreshold", "Primitive");
tolua_constantstring(L, "usertype_UncapFPS_Enabled", "Primitive");
tolua_constantstring(L, "usertype_UncapFPS_FPSLimit", "Primitive");
+ tolua_constantstring(L, "usertype_UncapFPS_FPSLimitEnabled", "Primitive");
+ tolua_constantstring(L, "usertype_UncapFPS_LuaGCSteps", "Primitive");
tolua_constantstring(L, "usertype_UncapFPS_RemoveMiddleMouseScrollMultiplier", "Primitive");
tolua_endmodule(L);
tolua_cclass(L, "EEex::ProjectileType", "EEex::ProjectileType", {"__int32"}, NULL);
@@ -1749,6 +1800,9 @@ int OpenBindingsInternal(lua_State* L)
tolua_cclass(L, "uiItem", "uiItem", {}, NULL);
tolua_beginmodule(L, "uiItem");
tolua_endmodule(L);
+ tolua_cclass(L, "SDL_VideoDevice", "SDL_VideoDevice", {}, NULL);
+ tolua_beginmodule(L, "SDL_VideoDevice");
+ tolua_endmodule(L);
tolua_cclass(L, "CResBinary", "CResBinary", {"CRes"}, NULL);
tolua_beginmodule(L, "CResBinary");
tolua_endmodule(L);
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/engine_function_names.cpp b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/engine_function_names.cpp
new file mode 100644
index 0000000..dc0ff7b
--- /dev/null
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/engine_function_names.cpp
@@ -0,0 +1,101 @@
+
+#include
+#include
+
+#include "engine_function_names.hpp"
+#include "infinity_loader_common_api.h"
+
+///////////////
+// Constants //
+///////////////
+
+std::string EMPTY_STRING { "" };
+
+/////////////
+// Globals //
+/////////////
+
+std::vector> addressToName{};
+
+///////////////
+// Functions //
+///////////////
+
+const std::string& GetContainingFunctionName(uintptr_t address)
+{
+ const size_t size = addressToName.size();
+ const size_t lastValidIndex = size - 1;
+
+ size_t l = 0;
+ size_t r = size;
+
+ while (l < r)
+ {
+ const size_t mid = (l + r) / 2;
+ const std::pair& pair = addressToName.at(mid);
+
+ if (address >= pair.first)
+ {
+ if (pair.first == address || mid == lastValidIndex || address < addressToName.at(mid + 1).first)
+ {
+ return pair.second;
+ }
+
+ l = mid + 1;
+ }
+ else
+ {
+ r = mid;
+ }
+ }
+
+ return EMPTY_STRING;
+}
+
+const std::string& GetFunctionName(uintptr_t address)
+{
+ size_t l = 0;
+ size_t r = addressToName.size();
+
+ while (l < r)
+ {
+ const size_t mid = (l + r) / 2;
+ const std::pair& pair = addressToName.at(mid);
+
+ if (address < pair.first)
+ {
+ r = mid;
+ }
+ else if (pair.first == address)
+ {
+ return pair.second;
+ }
+ else
+ {
+ l = mid + 1;
+ }
+ }
+
+ return EMPTY_STRING;
+}
+
+void LoadFunctionNames()
+{
+ std::ifstream inputFile { "function_names.db" };
+
+ if (!inputFile)
+ {
+ FPrint("[!][EEex.dll] LoadFunctionNames() - Error opening function_names.db\n");
+ return;
+ }
+
+ for (std::string line; std::getline(inputFile, line); )
+ {
+ const size_t spaceI = line.find('\t');
+ const uintptr_t address = std::stoull(line.substr(0, spaceI), nullptr, 16);
+ addressToName.emplace_back(address, line.substr(spaceI + 1));
+ }
+
+ inputFile.close();
+ return;
+}
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/main.cpp b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/main.cpp
index 527751d..a0cb76e 100644
--- a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/main.cpp
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/main.cpp
@@ -2,6 +2,7 @@
#include "Baldur-v2.6.6.0_generated.h"
#include "EEex.h"
#include "EEexLua_generated.h"
+#include "profiler.hpp"
static void exportPattern(const String& name, void* value) {
@@ -49,8 +50,8 @@ static void exportPatterns() {
exportPattern(TEXT("CGameText::Override_Render"), getMemberPtr(&CGameText::Override_Render));
exportPattern(TEXT("CInfinity::Override_AdjustViewPosition"), getMemberPtr(&CInfinity::Override_AdjustViewPosition));
exportPattern(TEXT("CInfinity::Override_FitViewPosition"), getMemberPtr(&CInfinity::Override_FitViewPosition));
- exportPattern(TEXT("CInfinity::Override_SetScrollDest"), getMemberPtr(&CInfinity::Override_SetScrollDest));
exportPattern(TEXT("CInfinity::Override_Scroll"), getMemberPtr(&CInfinity::Override_Scroll));
+ exportPattern(TEXT("CInfinity::Override_SetScrollDest"), getMemberPtr(&CInfinity::Override_SetScrollDest));
exportPattern(TEXT("CMessageSetLastObject::Override_Run"), getMemberPtr(&CMessageSetLastObject::Override_Run));
exportPattern(TEXT("CScreenMap::Override_CenterViewPort"), getMemberPtr(&CScreenMap::Override_CenterViewPort));
exportPattern(TEXT("CScreenMap::Override_OnLButtonDblClk"), getMemberPtr(&CScreenMap::Override_OnLButtonDblClk));
@@ -73,6 +74,7 @@ static void exportPatterns() {
exportPattern(TEXT("EEex::Override_Infinity_TransitionMenu"), EEex::Override_Infinity_TransitionMenu);
exportPattern(TEXT("EEex::Override_Infinity_WriteINILine"), EEex::Override_Infinity_WriteINILine);
exportPattern(TEXT("EEex::Override_uiDoFile"), EEex::Override_uiDoFile);
+ exportPattern(TEXT("EEex::Override_uiDrawMenuStack"), EEex::Override_uiDrawMenuStack);
exportPattern(TEXT("EEex::Override_uiEventMenuStack"), EEex::Override_uiEventMenuStack);
/////////////////////////////
@@ -113,6 +115,8 @@ static void exportPatterns() {
exportPattern(TEXT("EEex::Opcode_Hook_Op280_ShouldSuppressWildSurgeVisuals"), EEex::Opcode_Hook_Op280_ShouldSuppressWildSurgeVisuals);
// op319
exportPattern(TEXT("EEex::Opcode_Hook_Op319_IsInverted"), EEex::Opcode_Hook_Op319_IsInverted);
+ // op342
+ exportPattern(TEXT("EEex::Opcode_Hook_Op342_OnUnhandledParam2"), EEex::Opcode_Hook_Op342_OnUnhandledParam2);
// New op400
exportPattern(TEXT("EEex::Opcode_Hook_SetTemporaryAIScript_ApplyEffect"), EEex::Opcode_Hook_SetTemporaryAIScript_ApplyEffect);
exportPattern(TEXT("EEex::Opcode_Hook_SetTemporaryAIScript_OnRemove"), EEex::Opcode_Hook_SetTemporaryAIScript_OnRemove);
@@ -142,6 +146,7 @@ static void exportPatterns() {
exportPattern(TEXT("EEex::Sprite_Hook_OnDestruct"), EEex::Sprite_Hook_OnDestruct);
exportPattern(TEXT("EEex::Sprite_Hook_OnAfterEffectListUnmarshalled"), EEex::Sprite_Hook_OnAfterEffectListUnmarshalled);
exportPattern(TEXT("EEex::Sprite_Hook_OnBeforeEffectListMarshalled"), EEex::Sprite_Hook_OnBeforeEffectListMarshalled);
+ exportPattern(TEXT("EEex::Sprite_Hook_OnGetAttackFrameType"), EEex::Sprite_Hook_OnGetAttackFrameType);
////////////
// Action //
@@ -178,6 +183,7 @@ static void exportPatterns() {
/////////
exportPattern(TEXT("EEex::Fix_Hook_HandleMiddleMouseDrag"), EEex::Fix_Hook_HandleMiddleMouseDrag);
+ exportPattern(TEXT("EEex::Fix_Hook_ImplementWSPECIALSpeedColumn"), EEex::Fix_Hook_ImplementWSPECIALSpeedColumn);
exportPattern(TEXT("EEex::Fix_Hook_OnBeforeUIKillCapture"), EEex::Fix_Hook_OnBeforeUIKillCapture);
exportPattern(TEXT("EEex::Fix_Hook_OnUIItemCheckRenderScrollbar"), EEex::Fix_Hook_OnUIItemCheckRenderScrollbar);
exportPattern(TEXT("EEex::Fix_Hook_ShouldProcessEffectListSkipRolls"), EEex::Fix_Hook_ShouldProcessEffectListSkipRolls);
@@ -221,6 +227,12 @@ static void exportPatterns() {
exportPattern(TEXT("EEex::bNoUUID"), &EEex::bNoUUID);
exportPattern(TEXT("EEex::bStripUUID"), &EEex::bStripUUID);
exportPattern(TEXT("EEex::CGameSprite_Hit_Roll"), &EEex::CGameSprite_Hit_Roll);
+
+ ////////////////////////////////
+ // Profiler //
+ ////////////////////////////////
+
+ //exportPattern(TEXT("Profiler_Trace"), Profiler_Trace);
}
void __stdcall InitBindings(SharedState argSharedState) {
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/profiler.cpp b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/profiler.cpp
new file mode 100644
index 0000000..3b90e97
--- /dev/null
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/profiler.cpp
@@ -0,0 +1,445 @@
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "Baldur-v2.6.6.0_generated.h"
+#include "engine_function_names.hpp"
+#include "infinity_loader_common_api.h"
+#include "profiler.hpp"
+#include "time_util.hpp"
+
+//---------------------------//
+// Structs //
+//---------------------------//
+
+struct ReturnPtr
+{
+ void* sourceStackPtr;
+ uintptr_t function;
+ SavedRegisters savedRegisters;
+ void* returnPtr;
+ bool alsoPopPrevious;
+ TimeType startTime;
+};
+
+template
+struct ThreadLocalContainer
+{
+ T value{};
+ DWORD threadID = GetCurrentThreadId();
+ std::vector*>* storageVector;
+ size_t position = static_cast(-1);
+ bool deadAllocatedCopy = false;
+ std::shared_mutex* storageLock;
+
+ ThreadLocalContainer(std::vector*>* storageVector, std::shared_mutex* storageLock, bool add = true);
+ ~ThreadLocalContainer();
+};
+
+template
+ThreadLocalContainer::ThreadLocalContainer(std::vector*> *const theStorageVector, std::shared_mutex *const theStorageLock, const bool add)
+{
+ storageVector = theStorageVector;
+ storageLock = theStorageLock;
+
+ if (add)
+ {
+ const std::unique_lock lk1 { *storageLock };
+ position = storageVector->size();
+ storageVector->push_back(this);
+ }
+}
+
+template
+ThreadLocalContainer::~ThreadLocalContainer()
+{
+ if (!deadAllocatedCopy)
+ {
+ const std::unique_lock lk1 { *storageLock };
+ ThreadLocalContainer *const copy = new ThreadLocalContainer { storageVector, storageLock, false };
+ copy->deadAllocatedCopy = true;
+ copy->value = std::move(value);
+ storageVector->at(position) = copy;
+ }
+}
+
+struct TimerEntry
+{
+ TimeType milliseconds;
+ std::string column1;
+ std::string column2;
+ std::string column3;
+ std::string column4;
+ std::string column5;
+ std::string column6;
+};
+
+struct TimerTime
+{
+ TimeType microseconds = 0;
+ size_t callCount = 0;
+ std::vector debugLines{};
+};
+
+struct TraceEntry
+{
+ TraceType traceType;
+ std::string traceName;
+ uintptr_t endFunction;
+ TimeType logTimeThreshold;
+};
+
+//---------------------------//
+// Globals //
+//---------------------------//
+
+thread_local std::vector threadSavedReturnPtrs;
+
+std::vector>*> funcTimesRefs;
+std::shared_mutex funcTimesRefsLock;
+thread_local ThreadLocalContainer> threadFuncTimes { &funcTimesRefs, &funcTimesRefsLock };
+
+std::atomic traceType;
+std::atomic pendingSpamTrace;
+TimeType startTraceTime;
+
+DWORD traceStartThreadID;
+
+std::unordered_map traceEntries;
+std::shared_mutex traceEntriesLock;
+TraceEntry currentTraceEntry;
+std::mutex startTracingLock;
+
+//-----------------------------//
+// Functions //
+//-----------------------------//
+
+void Profiler_StartTrace(const TimeType startTime, const TraceType toStartType)
+{
+ if (toStartType == TraceType::NORMAL)
+ {
+ traceStartThreadID = GetCurrentThreadId();
+ startTraceTime = startTime;
+
+ const std::unique_lock lk1 { funcTimesRefsLock };
+
+ size_t curI = 0;
+ for (auto itr = funcTimesRefs.begin(); itr != funcTimesRefs.end(); )
+ {
+ auto& threadLocalContainer = *itr;
+ if (threadLocalContainer->deadAllocatedCopy)
+ {
+ delete threadLocalContainer;
+ itr = funcTimesRefs.erase(itr);
+ }
+ else
+ {
+ threadLocalContainer->value.clear();
+ threadLocalContainer->position = curI++;
+ ++itr;
+ }
+ }
+ }
+
+ traceType = toStartType;
+}
+
+void Profiler_RegisterTrace(const char *const traceName, const uintptr_t address, const TimeType logTimeThreshold)
+{
+ std::unique_lock lk1 { traceEntriesLock };
+ traceEntries.try_emplace(address, TraceType::NORMAL, traceName, address, logTimeThreshold);
+}
+
+static bool sortTimerEntryByTime(const TimerEntry& a, const TimerEntry& b)
+{
+ return a.milliseconds > b.milliseconds;
+}
+
+static std::string formatString(const char *const format, ...)
+{
+ constexpr int initialBufferSize = 256;
+
+ va_list args;
+ va_start(args, format);
+
+ int bufferSize = initialBufferSize;
+ std::string result;
+
+ while (true)
+ {
+ char *const buffer = new char[bufferSize];
+ const int ret = vsnprintf(buffer, bufferSize, format, args);
+
+ if (ret <= -1)
+ {
+ // Encoding error
+ delete[] buffer;
+ result = "";
+ break;
+ }
+
+ if (ret < bufferSize)
+ {
+ // Formatting succeeded
+ result = buffer;
+ delete[] buffer;
+ break;
+ }
+
+ // Increase buffer size and try again
+ delete[] buffer;
+ bufferSize = ret + 1;
+ }
+
+ va_end(args);
+ return result;
+}
+
+static void endTracingNormal(const TimeType endTime)
+{
+ const TimeType totalMicroseconds = endTime - startTraceTime;
+
+ if (totalMicroseconds / 1000 <= currentTraceEntry.logTimeThreshold)
+ {
+ return;
+ }
+
+ FPrint("[%s] - Total Time: %.02f ms\n", currentTraceEntry.traceName.c_str(), static_cast(totalMicroseconds) / 1000);
+
+ {
+ const std::unique_lock lk1 { funcTimesRefsLock };
+
+ for (const ThreadLocalContainer> *const threadFuncTimesRef : funcTimesRefs)
+ {
+ if (threadFuncTimesRef->value.empty())
+ {
+ continue;
+ }
+
+ std::vector toSort{};
+ size_t longestColumn1 = 0;
+ size_t longestColumn2 = 0;
+ size_t longestColumn3 = 0;
+ size_t longestColumn4 = 0;
+ size_t longestColumn5 = 0;
+
+ for (const auto& x : threadFuncTimesRef->value)
+ {
+ const TimeType microseconds = x.second.microseconds;
+ const double percent = totalMicroseconds != 0 ? (static_cast(microseconds) * 100 / totalMicroseconds) : 0;
+
+ if (percent >= 1)
+ {
+ TimerEntry& placed = toSort.emplace_back();
+ placed.milliseconds = microseconds;
+ placed.column1 = formatString("%lux", x.second.callCount);
+ placed.column2 = formatString("%.02f%%", percent);
+ placed.column3 = formatString("%.02f ms", static_cast(microseconds) / 1000);
+ placed.column4 = formatString("%.02f ms", static_cast(microseconds) / 1000 / x.second.callCount);
+ placed.column5 = formatString("0x%" PRIXPTR, x.first);
+ placed.column6 = formatString("%s", GetFunctionName(x.first).c_str());
+
+ if (const size_t len = placed.column1.length(); len > longestColumn1)
+ {
+ longestColumn1 = len;
+ }
+
+ if (const size_t len = placed.column2.length(); len > longestColumn2)
+ {
+ longestColumn2 = len;
+ }
+
+ if (const size_t len = placed.column3.length(); len > longestColumn3)
+ {
+ longestColumn3 = len;
+ }
+
+ if (const size_t len = placed.column4.length(); len > longestColumn4)
+ {
+ longestColumn4 = len;
+ }
+
+ if (const size_t len = placed.column5.length(); len > longestColumn5)
+ {
+ longestColumn5 = len;
+ }
+ }
+ }
+
+ std::sort(toSort.begin(), toSort.end(), sortTimerEntryByTime);
+
+ if (!toSort.empty())
+ {
+ if (threadFuncTimesRef->threadID == traceStartThreadID)
+ {
+ FPrint(" [Thread 0x%X] - Primary\n", threadFuncTimesRef->threadID);
+ }
+ else
+ {
+ FPrint(" [Thread 0x%X]\n", threadFuncTimesRef->threadID);
+ }
+
+ for (const auto& x : toSort)
+ {
+ FPrint(" | %s | total %s | %s | %s avg | %s | %s\n",
+ formatString("%*s", longestColumn1, x.column1.c_str()).c_str(),
+ formatString("%*s", longestColumn2, x.column2.c_str()).c_str(),
+ formatString("%*s", longestColumn3, x.column3.c_str()).c_str(),
+ formatString("%*s", longestColumn4, x.column4.c_str()).c_str(),
+ formatString("%*s", longestColumn5, x.column5.c_str()).c_str(),
+ formatString("%s", x.column6.c_str()).c_str()
+ );
+ }
+ }
+
+ for (const auto& x : threadFuncTimesRef->value)
+ {
+ const TimerTime& timerTime = x.second;
+
+ for (const std::string& debugLine : timerTime.debugLines)
+ {
+ FPrint(" %s", debugLine.c_str());
+ }
+ }
+ }
+ }
+}
+
+static void endTracing(const TimeType endTime)
+{
+ const std::unique_lock lk1 { startTracingLock };
+
+ if (traceType == TraceType::NORMAL)
+ {
+ endTracingNormal(endTime);
+ }
+
+ traceType = TraceType::NONE;
+}
+
+static void endFunctionTrace(const TimeType endTime, const ReturnPtr& realReturnPtr)
+{
+ switch (traceType)
+ {
+ case TraceType::NORMAL:
+ {
+ {
+ // To prevent endTracing() from locking threadFuncTimes is ONLY modified by the current thread
+ const std::shared_lock lk1 { funcTimesRefsLock };
+ TimerTime& timerTime = threadFuncTimes.value[realReturnPtr.function];
+ // std::max() so long running functions (those in another thread that started before the trace) don't appear over 100%
+
+ const TimeType timeTaken = endTime - (std::max)(startTraceTime, realReturnPtr.startTime);
+ timerTime.microseconds += timeTaken;
+ ++timerTime.callCount;
+
+ // TODO HACK
+ if (realReturnPtr.function == 0x1403D0A50)
+ {
+ const uiItem *const item = reinterpret_cast(realReturnPtr.savedRegisters.rcx);
+ const char *const menuName = item->menu != nullptr ? item->menu->name : "(null)";
+ timerTime.debugLines.emplace_back(formatString("Took %.02f ms to draw item %s with type %d in menu %s\n", static_cast(timeTaken) / 1000, item->name, item->type, menuName));
+ }
+ }
+
+ if (traceStartThreadID == GetCurrentThreadId() && realReturnPtr.function == currentTraceEntry.endFunction)
+ {
+ endTracing(endTime);
+ }
+
+ break;
+ }
+ case TraceType::SPAM:
+ {
+ const std::string funcName = GetFunctionName(realReturnPtr.function);
+ FPrint("[%p] END %s\n", GetCurrentThreadId(), funcName.c_str());
+ break;
+ }
+ }
+}
+
+extern "C" void* Profiler_GetCurReturn() // Called by Profiler_Return() in profiler_assembly.asm
+{
+ const TimeType endTime = getTime();
+
+ if (threadSavedReturnPtrs.empty())
+ {
+ MessageBoxA(NULL, "[EEex] Assert failed", "EEex", MB_ICONERROR);
+ }
+
+ ReturnPtr realReturnPtr;
+ do
+ {
+ realReturnPtr = threadSavedReturnPtrs.back();
+ threadSavedReturnPtrs.pop_back();
+
+ if (traceType != TraceType::NONE)
+ {
+ endFunctionTrace(endTime, realReturnPtr);
+ }
+ }
+ while (realReturnPtr.alsoPopPrevious);
+
+ return realReturnPtr.returnPtr;
+}
+
+extern "C" void Profiler_Return(); // In profiler_assembly.asm
+
+void __stdcall Profiler_Trace(const uintptr_t funcAddress, const SavedRegisters *const savedRegisters, void *const stackPtr)
+{
+ const TimeType startTime = getTime();
+ const bool alsoPopPrevious = !threadSavedReturnPtrs.empty() && threadSavedReturnPtrs.back().sourceStackPtr == stackPtr;
+
+ ReturnPtr& placed = threadSavedReturnPtrs.emplace_back();
+ placed.sourceStackPtr = stackPtr;
+ placed.function = funcAddress;
+ placed.returnPtr = (void*)*(uintptr_t*)stackPtr;
+ placed.alsoPopPrevious = alsoPopPrevious;
+ placed.startTime = startTime;
+ placed.savedRegisters = *savedRegisters;
+
+ *reinterpret_cast(stackPtr) = reinterpret_cast(Profiler_Return);
+
+ switch (traceType)
+ {
+ case TraceType::NONE:
+ {
+ {
+ const std::shared_lock lk1 { traceEntriesLock };
+
+ if (const auto itr = traceEntries.find(funcAddress); itr != traceEntries.end())
+ {
+ const std::unique_lock lk1 { startTracingLock };
+
+ if (traceType == TraceType::NONE)
+ {
+ currentTraceEntry = itr->second;
+ Profiler_StartTrace(startTime, currentTraceEntry.traceType);
+ }
+ }
+ }
+
+ const std::unique_lock lk1 { startTracingLock };
+
+ if (traceType == TraceType::NONE && pendingSpamTrace)
+ {
+ pendingSpamTrace = false;
+ Profiler_StartTrace(startTime, TraceType::SPAM);
+ }
+
+ break;
+ }
+ case TraceType::SPAM:
+ {
+ const std::string funcName = GetFunctionName(funcAddress);
+ FPrint("[%p] START %s\n", GetCurrentThreadId(), funcName.c_str());
+ break;
+ }
+ }
+}
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/profiler_assembly.asm b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/profiler_assembly.asm
new file mode 100644
index 0000000..c401f5d
--- /dev/null
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/profiler_assembly.asm
@@ -0,0 +1,39 @@
+
+OPTION CASEMAP:NONE
+
+EXTERN Profiler_GetCurReturn:PROC
+
+.code
+
+Profiler_Return PROC
+
+ lea rsp, qword ptr [rsp-128]
+ movdqu [rsp+104], xmm0
+ movdqu [rsp+88], xmm1
+ mov qword ptr [rsp+80], rax
+ mov qword ptr [rsp+72], rcx
+ mov qword ptr [rsp+64], rdx
+ mov qword ptr [rsp+56], r8
+ mov qword ptr [rsp+48], r9
+ mov qword ptr [rsp+40], r10
+ mov qword ptr [rsp+32], r11
+
+ call Profiler_GetCurReturn
+ mov qword ptr [rsp+120], rax
+
+ movdqu xmm0, [rsp+104]
+ movdqu xmm1, [rsp+88]
+ mov rax, qword ptr [rsp+80]
+ mov rcx, qword ptr [rsp+72]
+ mov rdx, qword ptr [rsp+64]
+ mov r8, qword ptr [rsp+56]
+ mov r9, qword ptr [rsp+48]
+ mov r10, qword ptr [rsp+40]
+ mov r11, qword ptr [rsp+32]
+
+ lea rsp, qword ptr [rsp+128]
+ jmp qword ptr [rsp-8]
+
+Profiler_Return ENDP
+
+END
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/time_util.cpp b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/time_util.cpp
index c93496b..58f7aa1 100644
--- a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/time_util.cpp
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/time_util.cpp
@@ -1,12 +1,14 @@
-#include "Windows.h"
+#include
+
+#include "time_util.hpp"
//---------------------------//
// Globals //
//---------------------------//
-long long numTicksInMicrosecond;
-long long initTime;
+TimeType numTicksInMicrosecond;
+TimeType initTime;
//-----------------------------//
// Functions //
@@ -14,42 +16,42 @@ long long initTime;
DWORD getHighestRefreshRate()
{
- DWORD highestRefreshRate = 0;
+ DWORD highestRefreshRate = 0;
- DISPLAY_DEVICE displayDevice;
- displayDevice.cb = sizeof(DISPLAY_DEVICE);
+ DISPLAY_DEVICE displayDevice;
+ displayDevice.cb = sizeof(DISPLAY_DEVICE);
- DEVMODE devMode;
- devMode.dmSize = sizeof(DEVMODE);
- devMode.dmDriverExtra = 0;
+ DEVMODE devMode;
+ devMode.dmSize = sizeof(DEVMODE);
+ devMode.dmDriverExtra = 0;
- for (DWORD deviceIndex = 0; EnumDisplayDevices(NULL, deviceIndex, &displayDevice, 0); ++deviceIndex)
- {
- if ((displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE) == 0)
- {
- continue;
- }
+ for (DWORD deviceIndex = 0; EnumDisplayDevices(NULL, deviceIndex, &displayDevice, 0); ++deviceIndex)
+ {
+ if ((displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE) == 0)
+ {
+ continue;
+ }
- if (!EnumDisplaySettings(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode))
- {
- continue;
- }
+ if (!EnumDisplaySettings(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode))
+ {
+ continue;
+ }
- if (devMode.dmDisplayFrequency > highestRefreshRate)
- {
- highestRefreshRate = devMode.dmDisplayFrequency;
- }
- }
+ if (devMode.dmDisplayFrequency > highestRefreshRate)
+ {
+ highestRefreshRate = devMode.dmDisplayFrequency;
+ }
+ }
- return highestRefreshRate;
+ return highestRefreshRate;
}
-long long getInitTime()
+TimeType getInitTime()
{
return initTime;
}
-long long getTime()
+TimeType getTime()
{
LARGE_INTEGER result;
QueryPerformanceCounter(&result);
diff --git a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/uncap_fps.cpp b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/uncap_fps.cpp
index 9f52e65..78a4a8e 100644
--- a/EEex-v2.6.6.0/source/EEex-v2.6.6.0/uncap_fps.cpp
+++ b/EEex-v2.6.6.0/source/EEex-v2.6.6.0/uncap_fps.cpp
@@ -1,8 +1,8 @@
#include
-#include "EEex.h"
#include "coordinate_util.hpp"
+#include "EEex.h"
#include "lua_util.hpp"
#include "menu_util.hpp"
#include "time_util.hpp"
@@ -11,7 +11,7 @@
// Constants //
//-----------------------------//
-constexpr long long AUTO_ZOOM_TARGET_TIME = 10 * 1000000LL / 30;
+constexpr TimeType AUTO_ZOOM_TARGET_TIME = 10 * 1000000LL / 30;
// Empirically derived; lower values increase the smoothness of the "snap" at the
// end of an exponential autoscroll at the cost of drawing out the autoscroll.
@@ -62,27 +62,27 @@ class RollingAverage
{
struct Entry
{
- const long long timestamp;
+ const TimeType timestamp;
const T value;
- Entry(long long timestamp, T value) : timestamp(timestamp), value(value) {}
+ Entry(TimeType timestamp, T value) : timestamp(timestamp), value(value) {}
};
- const long long timeWindow;
+ const TimeType timeWindow;
T currentAverage = 0;
std::deque queue{};
public:
- RollingAverage(long long timeWindow);
+ RollingAverage(TimeType timeWindow);
T get();
T getLast();
- void push(long long currentTime, T value);
- void recalculate(long long currentTime);
+ void push(TimeType currentTime, T value);
+ void recalculate(TimeType currentTime);
};
template
-RollingAverage::RollingAverage(long long timeWindow) : timeWindow(timeWindow) {}
+RollingAverage::RollingAverage(TimeType timeWindow) : timeWindow(timeWindow) {}
template
T RollingAverage::get()
@@ -97,15 +97,15 @@ T RollingAverage::getLast()
}
template
-void RollingAverage::push(long long currentTime, T value)
+void RollingAverage::push(TimeType currentTime, T value)
{
queue.emplace_back(currentTime, value);
}
template
-void RollingAverage::recalculate(long long currentTime)
+void RollingAverage::recalculate(TimeType currentTime)
{
- const long long dropTime = currentTime - this->timeWindow;
+ const TimeType dropTime = currentTime - this->timeWindow;
while (!queue.empty() && queue.front().timestamp < dropTime)
{
@@ -130,18 +130,20 @@ RollingAverage averageSyncUpdateDelta { 1000000 };
ExMenuStateOverrides beforeWorldScreenDeactivatedMenuStates{};
bool bAutoScrollFirstTick = false;
bool bFullTick = false;
-long long nLastAutoZoomTime = 0;
-long long nLastScrollTime = 0;
-long long nLastSyncUpdateTime = 0;
-long long nLastTPSPrintTime = 0;
-long long nNextFullSyncUpdateTick = 0;
-long long nNextLightSyncUpdateTick = -1;
-long long nRemainingAutoZoomTime = 0;
-long long nRemainingScrollTime = 0;
+bool bVSyncEnabled = true;
+TimeType nLastAutoZoomTime = 0;
+TimeType nLastScrollTime = 0;
+TimeType nLastSyncUpdateTime = 0;
+TimeType nLastTPSPrintTime = 0;
+TimeType nNextFullSyncUpdateTick = 0;
+TimeType nNextLightSyncUpdateTick = -1;
+TimeType nRemainingAutoZoomTime = 0;
+TimeType nRemainingScrollTime = 0;
int nScreenShakeSavedX = 0;
int nScreenShakeSavedY = 0;
-long long nTransitionStartTime = 0;
-long long nTransitionEndTime = 0;
+TimeType nTooltipEnableTime = 0;
+TimeType nTransitionStartTime = 0;
+TimeType nTransitionEndTime = 0;
CPoint ptMapPosExact;
//-----------------------------//
@@ -465,7 +467,7 @@ static void adjustViewPosition(CInfinity* pInfinity, byte nScrollState, ExAdjust
// |
pInfinity->m_nLastTickCount = nCurrentTick;
// |
- const long long nCurrentTime = getTime();
+ const TimeType nCurrentTime = getTime();
const int nScrollUpdateDelta = static_cast(nCurrentTime - nLastScrollTime);
const int nDeltaT = (std::max)(1, (std::min)(nScrollUpdateDelta, 500000));
nLastScrollTime = nCurrentTime;
@@ -734,7 +736,7 @@ static ExpScrollResult expScrollNumSteps(int src, int dst, int minStep, int thre
}
}
-static int expScrollScaleSpeedToTime(int src, int dst, int minStep, int threshold, int microsecondDelta, long long targetMicroseconds)
+static int expScrollScaleSpeedToTime(int src, int dst, int minStep, int threshold, int microsecondDelta, TimeType targetMicroseconds)
{
if (std::abs(src - dst) <= threshold)
{
@@ -758,7 +760,7 @@ static int expScrollScaleSpeedToTime(int src, int dst, int minStep, int threshol
// Lua Functions //
///////////////////
-long long EEex::GetMicroseconds()
+TimeType EEex::GetMicroseconds()
{
return getTime() - getInitTime();
}
@@ -781,6 +783,8 @@ void EEex::SetVSyncEnabled(bool bEnable, bool bResetDevice)
{
p_SDL_GL_SetSwapInterval(bEnable);
}
+
+ bVSyncEnabled = bEnable;
}
void EEex::UpdateLastScrollTime()
@@ -1012,7 +1016,7 @@ void EEex::UncapFPS_Hook_HandleTransitionMenuFade()
// | p_uiPush(p_transition->newMenu->name);
// | }
// |
- const long long nCurrentTime = getTime();
+ const TimeType nCurrentTime = getTime();
// |
if (nCurrentTime >= nTransitionEndTime)
{
@@ -1037,8 +1041,8 @@ void EEex::UncapFPS_Hook_HandleTransitionMenuFade()
}
else
{
- const long long nCurrentProgress = nCurrentTime - nTransitionStartTime;
- const long long nTotalDistance = nTransitionEndTime - nTransitionStartTime;
+ const TimeType nCurrentProgress = nCurrentTime - nTransitionStartTime;
+ const TimeType nTotalDistance = nTransitionEndTime - nTransitionStartTime;
const float fPercent = static_cast(nCurrentProgress) / nTotalDistance;
if (p_transition->state == 1)
@@ -1056,7 +1060,7 @@ void EEex::UncapFPS_Hook_HandleTransitionMenuFade()
// Overrides //
///////////////
-static void trackSyncUpdateDelta(long long nStartTime)
+static void trackSyncUpdateDelta(TimeType nStartTime)
{
const int nSyncUpdateDelta = static_cast(nStartTime - nLastSyncUpdateTime);
nLastSyncUpdateTime = nStartTime;
@@ -1070,9 +1074,17 @@ static void trackSyncUpdateDelta(long long nStartTime)
//}
}
+static int getWindowRefreshRate()
+{
+ CBaldurChitin *const pChitin = *p_g_pBaldurChitin;
+ SDL_Window *const pWindow = pChitin->cVideo.pCurrentMode->m_pWindow;
+ SDL_VideoDisplay *const pVideoDisplay = p_SDL_GetDisplayForWindow(pWindow);
+ return pVideoDisplay->current_mode.refresh_rate;
+}
+
void CChitin::Override_Update()
{
- const long long nStartTime = getTime();
+ const TimeType nStartTime = getTime();
//////////////////////////////////////////////////////////////////////
// Dump Lua values that were not properly cleaned up from the stack //
@@ -1111,6 +1123,8 @@ void CChitin::Override_Update()
}
}
+ const bool bUsingFPSLimit = EEex::UncapFPS_FPSLimitEnabled && (!bVSyncEnabled || EEex::UncapFPS_FPSLimit < getWindowRefreshRate());
+
// Patch: Run "full ticks" at 30tps like normal, and (if uncapped) run in-between "light" ticks that only render the game
// |
if (!EEex::UncapFPS_Enabled || nStartTime >= nNextFullSyncUpdateTick)
@@ -1157,6 +1171,7 @@ void CChitin::Override_Update()
this->m_displayStale = 0;
this->m_bInSyncUpdate = 1;
this->virtual_SynchronousUpdate();
+ lua_gc(L, LUA_GCSTEP, EEex::UncapFPS_LuaGCSteps);
this->m_bInSyncUpdate = 0;
this->m_AIStale = 1;
}
@@ -1207,23 +1222,30 @@ void CChitin::Override_Update()
}
else
{
- const long long nEndTime = getTime();
- const long long nTimeTaken = nEndTime - nStartTime;
+ const TimeType nEndTime = getTime();
+ const TimeType nTimeTaken = nEndTime - nStartTime;
- const long long nTarget = 1000000 / EEex::UncapFPS_FPSLimit;
+ const TimeType nTarget = 1000000 / EEex::UncapFPS_FPSLimit;
if (nTimeTaken > nTarget)
{
//FPrint("Light frame took too long: %lld > %lld\n", nTimeTaken, nTarget);
}
- const long long nTargetFullMicroseconds = 1000000 / *CChitin::p_TIMER_UPDATES_PER_SECOND - nTimeTaken;
+ const TimeType nTargetFullMicroseconds = (1000000 / *CChitin::p_TIMER_UPDATES_PER_SECOND) - nTimeTaken;
nNextFullSyncUpdateTick = nEndTime + nTargetFullMicroseconds;
// Check reschedule light ticks if they are disabled
if (nNextLightSyncUpdateTick == -1)
{
- const int nEffectiveCap = EEex::UncapFPS_FPSLimit - *CChitin::p_TIMER_UPDATES_PER_SECOND;
- nNextLightSyncUpdateTick = nEffectiveCap > 0 ? nEndTime + 1000000 / nEffectiveCap - nTimeTaken : -1;
+ if (!bUsingFPSLimit)
+ {
+ nNextLightSyncUpdateTick = 0;
+ }
+ else
+ {
+ const int nEffectiveCap = EEex::UncapFPS_FPSLimit - *CChitin::p_TIMER_UPDATES_PER_SECOND;
+ nNextLightSyncUpdateTick = nEffectiveCap > 0 ? nEndTime + (1000000 / nEffectiveCap) - nTimeTaken : -1;
+ }
}
}
@@ -1263,32 +1285,40 @@ void CChitin::Override_Update()
this->m_displayStale = 0;
this->m_bInSyncUpdate = 1;
this->virtual_SynchronousUpdate();
+ lua_gc(L, LUA_GCSTEP, EEex::UncapFPS_LuaGCSteps);
this->m_bInSyncUpdate = 0;
this->m_AIStale = 1;
}
- const long long nEndTime = getTime();
- const long long nTimeTaken = nEndTime - nStartTime;
+ const TimeType nEndTime = getTime();
+ const TimeType nTimeTaken = nEndTime - nStartTime;
- const long long nTarget = 1000000 / EEex::UncapFPS_FPSLimit;
+ const TimeType nTarget = 1000000 / EEex::UncapFPS_FPSLimit;
if (nTimeTaken > nTarget)
{
//FPrint("Light frame took too long: %lld > %lld\n", nTimeTaken, nTarget);
}
- const int nEffectiveCap = EEex::UncapFPS_FPSLimit - *CChitin::p_TIMER_UPDATES_PER_SECOND;
- nNextLightSyncUpdateTick = nEffectiveCap > 0 ? nEndTime + 1000000 / nEffectiveCap - nTimeTaken : -1;
+ if (!bUsingFPSLimit)
+ {
+ nNextLightSyncUpdateTick = 0;
+ }
+ else
+ {
+ const int nEffectiveCap = EEex::UncapFPS_FPSLimit - *CChitin::p_TIMER_UPDATES_PER_SECOND;
+ nNextLightSyncUpdateTick = nEffectiveCap > 0 ? nEndTime + (1000000 / nEffectiveCap) - nTimeTaken : -1;
+ }
}
// Patch: If uncapped, sleep for a small amount so the main update loop doesn't hog the CPU
// |
- if (EEex::UncapFPS_Enabled && EEex::UncapFPS_BusyWaitThreshold != 0)
+ if (EEex::UncapFPS_Enabled && EEex::UncapFPS_BusyWaitThreshold != 0 && bUsingFPSLimit)
{
- const long long nNextTick = nNextLightSyncUpdateTick != -1 && nNextLightSyncUpdateTick < nNextFullSyncUpdateTick
+ const TimeType nNextTick = nNextLightSyncUpdateTick != -1 && nNextLightSyncUpdateTick < nNextFullSyncUpdateTick
? nNextLightSyncUpdateTick
: nNextFullSyncUpdateTick;
- const long long nDelayMilliseconds = (nNextTick - getTime()) / 1000;
+ const TimeType nDelayMilliseconds = (nNextTick - getTime()) / 1000;
if (nDelayMilliseconds >= EEex::UncapFPS_BusyWaitThreshold)
{
@@ -1649,7 +1679,7 @@ void CInfinity::Override_Scroll(CPoint ptDest, short speed)
// |
this->m_nLastTickCount = nCurrentTick;
// |
- const long long nCurrentTime = getTime();
+ const TimeType nCurrentTime = getTime();
const int nScrollUpdateDelta = bAutoScrollFirstTick ? averageSyncUpdateDelta.getLast() : static_cast(nCurrentTime - nLastScrollTime);
const int nDeltaT = (std::max)(1, (std::min)(nScrollUpdateDelta, 500000));
bAutoScrollFirstTick = false;
@@ -2320,6 +2350,91 @@ int __cdecl EEex::Override_Infinity_TransitionMenu(lua_State* L)
return 0;
}
+void __cdecl EEex::Override_uiDrawMenuStack()
+{
+ CBaldurChitin *const pChitin = *p_g_pBaldurChitin;
+ CScreenWorld *const pWorld = pChitin->m_pEngineWorld;
+
+ if
+ (
+ (pChitin->pActiveEngine == pWorld && p_uiIsHidden())
+ ||
+ pWorld->m_bWaitToRender
+ )
+ {
+ return;
+ }
+
+ const uint nTooltipDelay = pChitin->m_pObjectGame->m_options.m_toolTips;
+
+ // |
+ // Patch: Enable UI tooltips based on microsecond measurements (versus the tick-based vanilla implementation)
+ // |
+ // | if
+ // | (
+ // | (!pChitin->m_bIsTouchUI || *p_fingerDown)
+ // | &&
+ // | nTooltipDelay != 99 && static_cast(p_tooltip->count) > nTooltipDelay
+ // | )
+ // | {
+ // | p_tooltip->on = true;
+ // | }
+ // |
+ // | ++p_tooltip->count;
+ // |
+ const TimeType nCurTime = getTime();
+ // |
+ if (p_tooltip->count == nTooltipDelay || (GetAsyncKeyState(VK_TAB) & 0x8000) != 0)
+ {
+ // Pressing tab (to force the tooltip) sets `p_tooltip->count = nTooltipDelay`, which has been detected.
+ // This patch also directly checks the TAB key state, which is a bit hacky, but the vanilla implementation
+ // has an annoying flicker to the tooltip if the tab key is held down while the mouse is moved. The engine
+ // usually waits a tick to display the tooltip, but this patch immediately enables the tooltip to prevent
+ // flicker.
+ p_tooltip->count = -1;
+ nTooltipEnableTime = nCurTime;
+ }
+ else if (p_tooltip->count == 0)
+ {
+ // Engine has started the tooltip timer. The default implementation never immediately enables the tooltip,
+ // but this patch can do so for `nTooltipDelay == 0` to prevent flicker when the mouse is moved.
+ p_tooltip->count = -1;
+ nTooltipEnableTime = nCurTime + nTooltipDelay * 33333LL;
+ }
+ // |
+ if
+ (
+ (!pChitin->m_bIsTouchUI || *p_fingerDown)
+ &&
+ nTooltipDelay != 99 && nCurTime >= nTooltipEnableTime
+ )
+ {
+ p_tooltip->on = true;
+ }
+
+ const SDL_Rect rWindow { 0, 0, *CVidMode::p_SCREENWIDTH, *CVidMode::p_SCREENHEIGHT };
+
+ if (uiMenu *const g_backgroundMenu = *p_g_backgroundMenu; g_backgroundMenu != nullptr)
+ {
+ p_drawMenu(g_backgroundMenu, &rWindow);
+ }
+
+ for (int nMenuIndex = 0; ; ++nMenuIndex)
+ {
+ uiMenu *const pMenu = getStackMenu(nMenuIndex);
+ if (pMenu == nullptr) break;
+ p_drawMenu(pMenu, &rWindow);
+ }
+
+ if (uiMenu *const g_overlayMenu = *p_g_overlayMenu; g_overlayMenu != nullptr)
+ {
+ p_drawMenu(g_overlayMenu, &rWindow);
+ }
+
+ p_drawTop(&rWindow);
+ p_uiHandleTooltip();
+}
+
//-----------------------------------//
// Local Map Fixes //
//-----------------------------------//
@@ -2350,8 +2465,8 @@ void static handleAreaAutoZoom()
// Patch: Keep track of auto zoom time delta
// |
- const long long nCurrentTime = getTime();
- const long long nDeltaT = nCurrentTime - nLastAutoZoomTime;
+ const TimeType nCurrentTime = getTime();
+ const TimeType nDeltaT = nCurrentTime - nLastAutoZoomTime;
nLastAutoZoomTime = nCurrentTime;
// Patch: Calculate zoom percentage using time (instead of a static number of ticks)
@@ -2420,7 +2535,7 @@ void static handleAreaAutoZoom()
pArea->m_cGameAreaNotes.UpdateButtonPositions();
}
-static void zoomOutToLocalMap(long long nCurrentTime, bool bOverwriteOriginal, bool bForceInstant)
+static void zoomOutToLocalMap(TimeType nCurrentTime, bool bOverwriteOriginal, bool bForceInstant)
{
CBaldurChitin *const pChitin = *p_g_pBaldurChitin;
CScreenWorld *const pScreenWorld = pChitin->m_pEngineWorld;
@@ -2618,7 +2733,7 @@ void CScreenWorld::Override_ResetZoom()
CInfGame *const pGame = pChitin->m_pObjectGame;
CInfinity *const pInfinity = &pGame->m_gameAreas[pGame->m_visibleArea]->m_cInfinity;
- const long long nCurrentTime = getTime();
+ const TimeType nCurrentTime = getTime();
if (!this->m_bAutoZooming)
{
@@ -2657,7 +2772,7 @@ void CScreenWorld::Override_ZoomToMap(bool bOverwriteOriginal)
CInfGame *const pGame = pChitin->m_pObjectGame;
CInfinity *const pInfinity = &pGame->m_gameAreas[pGame->m_visibleArea]->m_cInfinity;
- const long long nCurrentTime = getTime();
+ const TimeType nCurrentTime = getTime();
if (!this->m_bAutoZooming)
{
@@ -2702,7 +2817,10 @@ void CScreenWorld::Override_ZoomToMap(bool bOverwriteOriginal)
void initUncapFPS()
{
- const long long initTime = getInitTime();
+ const TimeType initTime = getInitTime();
nLastSyncUpdateTime = initTime;
nLastScrollTime = initTime;
+
+ lua_gc(sharedState().LuaState(), LUA_GCSTOP, 0);
+ EEex::UncapFPS_LuaGCSteps = 50;
}
diff --git a/InfinityLoaderCommon/headers/common/lua_provider_api_core.h b/InfinityLoaderCommon/headers/common/lua_provider_api_core.h
index 06df766..9f18be1 100644
--- a/InfinityLoaderCommon/headers/common/lua_provider_api_core.h
+++ b/InfinityLoaderCommon/headers/common/lua_provider_api_core.h
@@ -44,6 +44,7 @@ LUA_PROVIDER_API lua_CFunction lua_atpanic(lua_State* L, lua_CFunction panicf);
LUA_PROVIDER_API void lua_callk(lua_State* L, int nargs, int nresults, int ctx, lua_CFunction k);
LUA_PROVIDER_API void lua_concat(lua_State* L, int n);
LUA_PROVIDER_API void lua_createtable(lua_State* L, int narr, int nrec);
+LUA_PROVIDER_API int lua_gc(lua_State* L, int what, int data);
LUA_PROVIDER_API void lua_getfield(lua_State* L, int idx, const char* k);
LUA_PROVIDER_API void lua_getglobal(lua_State* L, const char* name);
LUA_PROVIDER_API int lua_getmetatable(lua_State* L, int objindex);
@@ -141,6 +142,16 @@ LUA_PROVIDER_API bool CheckLuaArgBoundsUIntPtr(lua_State* L, const int argI, siz
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
+#define LUA_GCSTOP 0
+#define LUA_GCRESTART 1
+#define LUA_GCCOLLECT 2
+#define LUA_GCCOUNT 3
+#define LUA_GCCOUNTB 4
+#define LUA_GCSTEP 5
+#define LUA_GCSETPAUSE 6
+#define LUA_GCSETSTEPMUL 7
+#define LUA_GCISRUNNING 9
+
#define lua_call(L, n, r) lua_callk(L, (n), (r), 0, NULL)
#define lua_isboolean(L, n) (lua_type(L, (n)) == LUA_TBOOLEAN)
#define lua_isfunction(L, n) (lua_type(L, (n)) == LUA_TFUNCTION)
diff --git a/LuaBindings-v2.6.6.0/headers/LuaBindings-v2.6.6.0_generated/Baldur-v2.6.6.0_generated.h b/LuaBindings-v2.6.6.0/headers/LuaBindings-v2.6.6.0_generated/Baldur-v2.6.6.0_generated.h
index 4042b3a..36c60ac 100644
--- a/LuaBindings-v2.6.6.0/headers/LuaBindings-v2.6.6.0_generated/Baldur-v2.6.6.0_generated.h
+++ b/LuaBindings-v2.6.6.0/headers/LuaBindings-v2.6.6.0_generated/Baldur-v2.6.6.0_generated.h
@@ -188,10 +188,14 @@ struct Item_Header_st;
struct Item_ability_st;
struct Item_effect_st;
union SDL_Event;
+struct SDL_MessageBoxButtonData;
+struct SDL_MessageBoxColorScheme;
struct SDL_PixelFormat;
struct SDL_Point;
+struct SDL_PrivateGLESData;
struct SDL_Rect;
struct SDL_Surface;
+struct SDL_VideoDevice;
struct SDL_Window;
struct STR_RES;
struct Spell_Header_st;
@@ -251,6 +255,11 @@ struct SDL_Cursor
SDL_Cursor() = delete;
};
+struct SDL_PrivateGLESData
+{
+ SDL_PrivateGLESData() = delete;
+};
+
struct SDL_WindowUserData
{
char* name;
@@ -1504,6 +1513,15 @@ struct SDL_version
SDL_version() = delete;
};
+struct SDL_MessageBoxColor
+{
+ unsigned __int8 r;
+ unsigned __int8 g;
+ unsigned __int8 b;
+
+ SDL_MessageBoxColor() = delete;
+};
+
struct SDL_Color
{
unsigned __int8 r;
@@ -1958,6 +1976,31 @@ struct SDL_SysWMmsg
SDL_SysWMmsg() = delete;
};
+struct SDL_SysWMinfo
+{
+ union info_t
+ {
+ struct win_t
+ {
+ HWND__* window;
+ HDC__* hdc;
+
+ win_t() = delete;
+ };
+
+ SDL_SysWMinfo::info_t::win_t win;
+ int dummy;
+
+ info_t() = delete;
+ };
+
+ SDL_version version;
+ SDL_SYSWM_TYPE subsystem;
+ SDL_SysWMinfo::info_t info;
+
+ SDL_SysWMinfo() = delete;
+};
+
struct SDL_SysWMEvent
{
unsigned int type;
@@ -1967,6 +2010,15 @@ struct SDL_SysWMEvent
SDL_SysWMEvent() = delete;
};
+struct SDL_ShapeDriver
+{
+ SDL_WindowShaper* (__fastcall *CreateShaper)(SDL_Window*);
+ int (__fastcall *SetWindowShape)(SDL_WindowShaper*, SDL_Surface*, SDL_WindowShapeMode*);
+ int (__fastcall *ResizeWindowShape)(SDL_Window*);
+
+ SDL_ShapeDriver() = delete;
+};
+
struct SDL_QuitEvent
{
unsigned int type;
@@ -2044,6 +2096,28 @@ struct SDL_MouseButtonEvent
SDL_MouseButtonEvent() = delete;
};
+struct SDL_MessageBoxData
+{
+ unsigned int flags;
+ SDL_Window* window;
+ const char* title;
+ const char* message;
+ int numbuttons;
+ const SDL_MessageBoxButtonData* buttons;
+ const SDL_MessageBoxColorScheme* colorScheme;
+
+ SDL_MessageBoxData() = delete;
+};
+
+struct SDL_MessageBoxButtonData
+{
+ unsigned int flags;
+ int buttonid;
+ const char* text;
+
+ SDL_MessageBoxButtonData() = delete;
+};
+
struct SDL_Keysym
{
SDL_Scancode scancode;
@@ -2133,6 +2207,53 @@ struct SDL_JoyAxisEvent
SDL_JoyAxisEvent() = delete;
};
+struct SDL_GLDriverData
+{
+ SDL_bool HAS_WGL_ARB_pixel_format;
+ SDL_bool HAS_WGL_EXT_swap_control_tear;
+ SDL_bool HAS_WGL_EXT_create_context_es2_profile;
+ SDL_bool HAS_WGL_ARB_context_flush_control;
+ void* (__fastcall *wglGetProcAddress)(const char*);
+ HGLRC__* (__fastcall *wglCreateContext)(HDC__*);
+ int (__fastcall *wglDeleteContext)(HGLRC__*);
+ int (__fastcall *wglMakeCurrent)(HDC__*, HGLRC__*);
+ int (__fastcall *wglShareLists)(HGLRC__*, HGLRC__*);
+ int (__fastcall *wglChoosePixelFormatARB)(HDC__*, const int*, const float*, unsigned int, int*, unsigned int*);
+ int (__fastcall *wglGetPixelFormatAttribivARB)(HDC__*, int, int, unsigned int, const int*, int*);
+ int (__fastcall *wglSwapIntervalEXT)(int);
+ int (__fastcall *wglGetSwapIntervalEXT)();
+
+ SDL_GLDriverData() = delete;
+};
+
+struct SDL_EGL_VideoData
+{
+ void* egl_dll_handle;
+ void* dll_handle;
+ void* egl_display;
+ void* egl_config;
+ int egl_swapinterval;
+ void* (__fastcall *eglGetDisplay)(HDC__*);
+ unsigned int (__fastcall *eglInitialize)(void*, int*, int*);
+ unsigned int (__fastcall *eglTerminate)(void*);
+ void* (__fastcall *eglGetProcAddress)(const char*);
+ unsigned int (__fastcall *eglChooseConfig)(void*, const int*, void**, int, int*);
+ void* (__fastcall *eglCreateContext)(void*, void*, void*, const int*);
+ unsigned int (__fastcall *eglDestroyContext)(void*, void*);
+ void* (__fastcall *eglCreateWindowSurface)(void*, void*, HWND__*, const int*);
+ unsigned int (__fastcall *eglDestroySurface)(void*, void*);
+ unsigned int (__fastcall *eglMakeCurrent)(void*, void*, void*, void*);
+ unsigned int (__fastcall *eglSwapBuffers)(void*, void*);
+ unsigned int (__fastcall *eglSwapInterval)(void*, int);
+ const char* (__fastcall *eglQueryString)(void*, int);
+ unsigned int (__fastcall *eglGetConfigAttrib)(void*, void*, int, int*);
+ unsigned int (__fastcall *eglWaitNative)(int);
+ unsigned int (__fastcall *eglWaitGL)();
+ unsigned int (__fastcall *eglBindAPI)(unsigned int);
+
+ SDL_EGL_VideoData() = delete;
+};
+
struct SDL_DropEvent
{
unsigned int type;
@@ -2167,6 +2288,21 @@ struct SDL_DisplayMode
SDL_DisplayMode() = delete;
};
+struct SDL_VideoDisplay
+{
+ char* name;
+ int max_display_modes;
+ int num_display_modes;
+ SDL_DisplayMode* display_modes;
+ SDL_DisplayMode desktop_mode;
+ SDL_DisplayMode current_mode;
+ SDL_Window* fullscreen_window;
+ SDL_VideoDevice* device;
+ void* driverdata;
+
+ SDL_VideoDisplay() = delete;
+};
+
struct SDL_ControllerDeviceEvent
{
unsigned int type;
@@ -3686,6 +3822,19 @@ struct slicedRect
}
};
+struct _820A8B7015E7E0FD9144A7C186FBF075
+{
+ SDL_Point pt;
+ bool on;
+ const char* text;
+ SDL_Rect r;
+ int count;
+ const char* lastText;
+ bool playedSound;
+
+ _820A8B7015E7E0FD9144A7C186FBF075() = delete;
+};
+
struct _9B9540D9920A90D57A3D80DDD1A70514
{
bool (__fastcall *f)(uiMenu*, const SDL_Rect*, SDL_Event*);
@@ -9038,6 +9187,120 @@ struct font_t
font_t() = delete;
};
+struct SDL_VideoDevice
+{
+ struct gl_config_t
+ {
+ int red_size;
+ int green_size;
+ int blue_size;
+ int alpha_size;
+ int depth_size;
+ int buffer_size;
+ int stencil_size;
+ int double_buffer;
+ int accum_red_size;
+ int accum_green_size;
+ int accum_blue_size;
+ int accum_alpha_size;
+ int stereo;
+ int multisamplebuffers;
+ int multisamplesamples;
+ int accelerated;
+ int major_version;
+ int minor_version;
+ int flags;
+ int profile_mask;
+ int share_with_current_context;
+ int release_behavior;
+ int framebuffer_srgb_capable;
+ int retained_backing;
+ int driver_loaded;
+ Array driver_path;
+ void* dll_handle;
+
+ gl_config_t() = delete;
+ };
+
+ const char* name;
+ int (__fastcall *VideoInit)(SDL_VideoDevice*);
+ void (__fastcall *VideoQuit)(SDL_VideoDevice*);
+ int (__fastcall *GetDisplayBounds)(SDL_VideoDevice*, SDL_VideoDisplay*, SDL_Rect*);
+ int (__fastcall *GetDisplayDPI)(SDL_VideoDevice*, SDL_VideoDisplay*, float*, float*, float*);
+ void (__fastcall *GetDisplayModes)(SDL_VideoDevice*, SDL_VideoDisplay*);
+ int (__fastcall *SetDisplayMode)(SDL_VideoDevice*, SDL_VideoDisplay*, SDL_DisplayMode*);
+ int (__fastcall *CreateWindowA)(SDL_VideoDevice*, SDL_Window*);
+ int (__fastcall *CreateWindowFrom)(SDL_VideoDevice*, SDL_Window*, const void*);
+ void (__fastcall *SetWindowTitle)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowIcon)(SDL_VideoDevice*, SDL_Window*, SDL_Surface*);
+ void (__fastcall *SetWindowPosition)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowSize)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowMinimumSize)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowMaximumSize)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *ShowWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *HideWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *RaiseWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *MaximizeWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *MinimizeWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *RestoreWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *SetWindowBordered)(SDL_VideoDevice*, SDL_Window*, SDL_bool);
+ void (__fastcall *SetWindowFullscreen)(SDL_VideoDevice*, SDL_Window*, SDL_VideoDisplay*, SDL_bool);
+ int (__fastcall *SetWindowGammaRamp)(SDL_VideoDevice*, SDL_Window*, const unsigned __int16*);
+ int (__fastcall *GetWindowGammaRamp)(SDL_VideoDevice*, SDL_Window*, wchar_t*);
+ void (__fastcall *SetWindowGrab)(SDL_VideoDevice*, SDL_Window*, SDL_bool);
+ void (__fastcall *DestroyWindow)(SDL_VideoDevice*, SDL_Window*);
+ int (__fastcall *CreateWindowFramebuffer)(SDL_VideoDevice*, SDL_Window*, unsigned int*, void**, int*);
+ int (__fastcall *UpdateWindowFramebuffer)(SDL_VideoDevice*, SDL_Window*, const SDL_Rect*, int);
+ void (__fastcall *DestroyWindowFramebuffer)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *OnWindowEnter)(SDL_VideoDevice*, SDL_Window*);
+ SDL_ShapeDriver shape_driver;
+ SDL_bool (__fastcall *GetWindowWMInfo)(SDL_VideoDevice*, SDL_Window*, SDL_SysWMinfo*);
+ int (__fastcall *GL_LoadLibrary)(SDL_VideoDevice*, const char*);
+ void* (__fastcall *GL_GetProcAddress)(SDL_VideoDevice*, const char*);
+ void (__fastcall *GL_UnloadLibrary)(SDL_VideoDevice*);
+ void* (__fastcall *GL_CreateContext)(SDL_VideoDevice*, SDL_Window*);
+ int (__fastcall *GL_MakeCurrent)(SDL_VideoDevice*, SDL_Window*, void*);
+ void (__fastcall *GL_GetDrawableSize)(SDL_VideoDevice*, SDL_Window*, int*, int*);
+ int (__fastcall *GL_SetSwapInterval)(SDL_VideoDevice*, int);
+ int (__fastcall *GL_GetSwapInterval)(SDL_VideoDevice*);
+ void (__fastcall *GL_SwapWindow)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *GL_DeleteContext)(SDL_VideoDevice*, void*);
+ void (__fastcall *PumpEvents)(SDL_VideoDevice*);
+ void (__fastcall *SuspendScreenSaver)(SDL_VideoDevice*);
+ void (__fastcall *StartTextInput)(SDL_VideoDevice*);
+ void (__fastcall *StopTextInput)(SDL_VideoDevice*);
+ void (__fastcall *SetTextInputRect)(SDL_VideoDevice*, SDL_Rect*);
+ SDL_bool (__fastcall *HasScreenKeyboardSupport)(SDL_VideoDevice*);
+ void (__fastcall *ShowScreenKeyboard)(SDL_VideoDevice*, SDL_Window*);
+ void (__fastcall *HideScreenKeyboard)(SDL_VideoDevice*, SDL_Window*);
+ SDL_bool (__fastcall *IsScreenKeyboardShown)(SDL_VideoDevice*, SDL_Window*);
+ int (__fastcall *SetClipboardText)(SDL_VideoDevice*, const char*);
+ char* (__fastcall *GetClipboardText)(SDL_VideoDevice*);
+ SDL_bool (__fastcall *HasClipboardText)(SDL_VideoDevice*);
+ int (__fastcall *ShowMessageBox)(SDL_VideoDevice*, const SDL_MessageBoxData*, int*);
+ int (__fastcall *SetWindowHitTest)(SDL_Window*, SDL_bool);
+ SDL_bool suspend_screensaver;
+ int num_displays;
+ SDL_VideoDisplay* displays;
+ SDL_Window* windows;
+ SDL_Window* grabbed_window;
+ unsigned __int8 window_magic;
+ unsigned int next_object_id;
+ char* clipboard_text;
+ SDL_VideoDevice::gl_config_t gl_config;
+ SDL_Window* current_glwin;
+ void* current_glctx;
+ unsigned int current_glwin_tls;
+ unsigned int current_glctx_tls;
+ void* driverdata;
+ SDL_GLDriverData* gl_data;
+ SDL_EGL_VideoData* egl_data;
+ SDL_PrivateGLESData* gles_data;
+ void (__fastcall *free)(SDL_VideoDevice*);
+
+ SDL_VideoDevice() = delete;
+};
+
struct SDL_PixelFormat
{
unsigned int format;
@@ -9063,6 +9326,13 @@ struct SDL_PixelFormat
SDL_PixelFormat() = delete;
};
+struct SDL_MessageBoxColorScheme
+{
+ Array colors;
+
+ SDL_MessageBoxColorScheme() = delete;
+};
+
template
struct LCharString
{
@@ -9319,6 +9589,9 @@ extern type_restoreMenuStack p_restoreMenuStack;
typedef void (*type_saveMenuStack)();
extern type_saveMenuStack p_saveMenuStack;
+typedef SDL_VideoDisplay* (*type_SDL_GetDisplayForWindow)(SDL_Window* window);
+extern type_SDL_GetDisplayForWindow p_SDL_GetDisplayForWindow;
+
typedef int (*type_SDL_GetKeyFromName)(const char* name);
extern type_SDL_GetKeyFromName p_SDL_GetKeyFromName;
@@ -9397,6 +9670,9 @@ extern type_DrawEndScaled p_DrawEndScaled;
typedef void (*type_drawLetters)(int X, int Y, int W, const SDL_Rect* rClip, const letter_t* letters, int nletters, int horizontalAlignment, font_t* font, int pointSize, int cursorPosition, int cursor, int selectionStart, int selectionEnd, int nLines, bool inlineColor, int indent, float fOffsetX, float fOffsetY);
extern type_drawLetters p_drawLetters;
+typedef bool (__cdecl *type_drawMenu)(uiMenu* m, const SDL_Rect* window);
+extern type_drawMenu p_drawMenu;
+
typedef void (*type_DrawOrtho11Begin)();
extern type_DrawOrtho11Begin p_DrawOrtho11Begin;
@@ -9421,6 +9697,9 @@ extern type_drawSliceSide p_drawSliceSide;
typedef void (*type_DrawTexCoord)(int s, int t);
extern type_DrawTexCoord p_DrawTexCoord;
+typedef bool (__cdecl *type_drawTop)(const SDL_Rect* window);
+extern type_drawTop p_drawTop;
+
typedef void (__cdecl *type_DrawTransformToScreen)(SDL_Rect* w, SDL_Rect* s);
extern type_DrawTransformToScreen p_DrawTransformToScreen;
@@ -9472,6 +9751,9 @@ extern type_uiDrawSlicedRect p_uiDrawSlicedRect;
typedef int (*type_uiExecLuaInt)(int id);
extern type_uiExecLuaInt p_uiExecLuaInt;
+typedef void (__cdecl *type_uiHandleTooltip)();
+extern type_uiHandleTooltip p_uiHandleTooltip;
+
typedef bool (*type_uiPop)(const char* name);
extern type_uiPop p_uiPop;
@@ -9498,6 +9780,8 @@ extern type_YScreenToZoomed p_YScreenToZoomed;
extern char** p_afxPchNil;
extern _9B9540D9920A90D57A3D80DDD1A70514* p_capture;
+extern bool* p_fingerDown;
+extern uiMenu** p_g_backgroundMenu;
extern RendererType* p_g_drawBackend;
extern Array* p_g_keywords;
extern lua_State** p_g_lua;
@@ -9510,6 +9794,7 @@ extern Array* p_menuStack;
extern int* p_nextStackMenuIdx;
extern int* p_numMenus;
extern CTypedPtrArray* p_resources;
+extern _820A8B7015E7E0FD9144A7C186FBF075* p_tooltip;
extern _A92C2F5FC159A4FE55DD6CCAABD58E72* p_transition;
extern ConstArray* p_yy_action;
extern ConstArray* p_yy_default;
@@ -10421,7 +10706,7 @@ struct C2DArray : CResHelper
typedef void (__thiscall *type_Destruct)(C2DArray* pThis);
static type_Destruct p_Destruct;
- typedef const CString* (__thiscall *type_GetAtCStringLabels)(C2DArray* pThis, const CString* nX, const CString* nY);
+ typedef const CString* (__thiscall *type_GetAtCStringLabels)(const C2DArray* pThis, const CString* nX, const CString* nY);
static type_GetAtCStringLabels p_GetAtCStringLabels;
typedef void (__thiscall *type_Load)(C2DArray* pThis, const CResRef* res);
@@ -10437,7 +10722,7 @@ struct C2DArray : CResHelper
p_Destruct(this);
}
- int FindColumnLabel(const char* sLabel)
+ int FindColumnLabel(const char* sLabel) const
{
EngineVal sLabelUppercase { sLabel };
sLabelUppercase->MakeUpper();
@@ -10457,7 +10742,7 @@ struct C2DArray : CResHelper
return -1;
}
- int FindRowLabel(const char* sLabel)
+ int FindRowLabel(const char* sLabel) const
{
EngineVal sLabelUppercase { sLabel };
sLabelUppercase->MakeUpper();
@@ -10477,7 +10762,7 @@ struct C2DArray : CResHelper
return -1;
}
- const CString* GetAt(int x, int y)
+ const CString* GetAt(int x, int y) const
{
if (x >= 0 && x < this->m_nSizeX && y >= 0 && y < this->m_nSizeY)
{
@@ -10486,7 +10771,7 @@ struct C2DArray : CResHelper
return &this->m_default;
}
- const CString* GetAt(const char* nX, const char* nY)
+ const CString* GetAt(const char* nX, const char* nY) const
{
const int nColumnIndex = this->FindColumnLabel(nX);
if (nColumnIndex == -1) return &this->m_default;
@@ -10497,7 +10782,7 @@ struct C2DArray : CResHelper
return this->GetAt(nColumnIndex, nRowIndex);
}
- const CString* GetAt(const CString* nX, const CString* nY)
+ const CString* GetAt(const CString* nX, const CString* nY) const
{
return p_GetAtCStringLabels(this, nX, nY);
}
@@ -10740,13 +11025,45 @@ struct CVidBitmap : CVidImage, CResHelper
CVidBitmap() = delete;
+ typedef void (__thiscall *type_Construct)(CVidBitmap* pThis);
+ static type_Construct p_Construct;
+
+ typedef void (__thiscall *type_Destruct)(CVidBitmap* pThis);
+ static type_Destruct p_Destruct;
+
typedef int (__thiscall *type_GetPixelColor)(CVidBitmap* pThis, tagRGBQUAD* color, int x, int y);
static type_GetPixelColor p_GetPixelColor;
+ typedef byte (__thiscall *type_GetPixelValueOrZero)(CVidBitmap* pThis, int x, int y);
+ static type_GetPixelValueOrZero p_GetPixelValueOrZero;
+
+ typedef void (__thiscall *type_SetResRef)(CVidBitmap* pThis, const CResRef* cNewResRef, int bSetAutoRequest, int bWarningIfMissing);
+ static type_SetResRef p_SetResRef;
+
+ void Construct()
+ {
+ p_Construct(this);
+ }
+
+ void Destruct()
+ {
+ p_Destruct(this);
+ }
+
int GetPixelColor(tagRGBQUAD* color, int x, int y)
{
return p_GetPixelColor(this, color, x, y);
}
+
+ byte GetPixelValue(int x, int y)
+ {
+ return p_GetPixelValueOrZero(this, x, y);
+ }
+
+ void SetResRef(const CResRef* cNewResRef, int bSetAutoRequest, int bWarningIfMissing)
+ {
+ p_SetResRef(this, cNewResRef, bSetAutoRequest, bWarningIfMissing);
+ }
};
struct CScreenAI : CBaldurEngine
diff --git a/LuaBindings-v2.6.6.0/scripts/generate_bindings/in/ignore_header_types.txt b/LuaBindings-v2.6.6.0/scripts/generate_bindings/in/ignore_header_types.txt
index a64bd70..363dfce 100644
--- a/LuaBindings-v2.6.6.0/scripts/generate_bindings/in/ignore_header_types.txt
+++ b/LuaBindings-v2.6.6.0/scripts/generate_bindings/in/ignore_header_types.txt
@@ -68,6 +68,7 @@ GCheader
GCObject
global_State
HDC__
+HGLRC__
HMONITOR__
HWND__
ID3DXBaseEffect
diff --git a/LuaBindings-v2.6.6.0/scripts/generate_bindings/in/manual_types.txt b/LuaBindings-v2.6.6.0/scripts/generate_bindings/in/manual_types.txt
index e299a72..4c8d69c 100644
--- a/LuaBindings-v2.6.6.0/scripts/generate_bindings/in/manual_types.txt
+++ b/LuaBindings-v2.6.6.0/scripts/generate_bindings/in/manual_types.txt
@@ -841,7 +841,7 @@ struct C2DArray : CResHelper
$constructor_fake Construct();
void Destruct();
- int FindColumnLabel(primitive const char* sLabel)
+ int FindColumnLabel(primitive const char* sLabel) const
{
EngineVal sLabelUppercase { sLabel };
sLabelUppercase->MakeUpper();
@@ -861,7 +861,7 @@ struct C2DArray : CResHelper
return -1;
}
- int FindRowLabel(primitive const char* sLabel)
+ int FindRowLabel(primitive const char* sLabel) const
{
EngineVal sLabelUppercase { sLabel };
sLabelUppercase->MakeUpper();
@@ -881,7 +881,7 @@ struct C2DArray : CResHelper
return -1;
}
- $binding_name(GetAtPoint) const CString* GetAt(int x, int y)
+ $binding_name(GetAtPoint) const CString* GetAt(int x, int y) const
{
if (x >= 0 && x < this->m_nSizeX && y >= 0 && y < this->m_nSizeY)
{
@@ -890,7 +890,7 @@ struct C2DArray : CResHelper
return &this->m_default;
}
- $binding_name(GetAtLabels) const CString* GetAt(primitive const char* nX, primitive const char* nY)
+ $binding_name(GetAtLabels) const CString* GetAt(primitive const char* nX, primitive const char* nY) const
{
const int nColumnIndex = this->FindColumnLabel(nX);
if (nColumnIndex == -1) return &this->m_default;
@@ -901,7 +901,7 @@ struct C2DArray : CResHelper
return this->GetAt(nColumnIndex, nRowIndex);
}
- $binding_name(GetAtCStringLabels) $pattern_name(GetAt(const CString*,const CString*)) const CString* GetAt(const CString* nX, const CString* nY);
+ $binding_name(GetAtCStringLabels) $pattern_name(GetAt(const CString*,const CString*)) const CString* GetAt(const CString* nX, const CString* nY) const;
void Load(const CResRef* res);
};
@@ -1620,7 +1620,11 @@ struct CBaldurEngine : CWarp
struct CVidBitmap : CVidImage, CResHelper
{
+ $constructor_fake Construct();
+ void Destruct();
int GetPixelColor(tagRGBQUAD* color, int x, int y);
+ $binding_name(GetPixelValueOrZero) $pattern_name(GetPixelValue(int,int)) byte GetPixelValue(int x, int y);
+ void SetResRef(const CResRef* cNewResRef, int bSetAutoRequest, int bWarningIfMissing);
};
struct CVidFont : CResHelper
@@ -1647,6 +1651,7 @@ uiMenu* findMenu(primitive const char* name, int panel, int state);
int rand();
void restoreMenuStack();
void saveMenuStack();
+SDL_VideoDisplay* SDL_GetDisplayForWindow(SDL_Window* window);
int SDL_GetKeyFromName(primitive const char* name);
primitive char* __cdecl SDL_GetKeyName(int key);
uint SDL_GetWindowFlags(SDL_Window* window);
@@ -1674,6 +1679,7 @@ $nobinding void DrawEnable(DrawFeature f);
$nobinding void DrawEnd();
$nobinding void DrawEndScaled();
$nobinding void drawLetters(int X, int Y, int W, const SDL_Rect* rClip, const letter_t* letters, int nletters, int horizontalAlignment, font_t* font, int pointSize, int cursorPosition, int cursor, int selectionStart, int selectionEnd, int nLines, bool inlineColor, int indent, float fOffsetX, float fOffsetY);
+$nobinding bool __cdecl drawMenu(uiMenu* m, const SDL_Rect* window);
$nobinding void DrawOrtho11Begin();
$nobinding void DrawOrtho11End();
$nobinding void DrawPopState();
@@ -1682,6 +1688,7 @@ $pattern_name(DrawQuad(CRect*,CRect*)) void DrawQuad(const CRect* rDest, const C
$nobinding void drawSlice(const SDL_Rect* dr, const SDL_Rect* r, const SDL_Rect* rClip, float scaleX, float scaleY, bool unused);
$nobinding void drawSliceSide(const SDL_Rect* dr, const SDL_Rect* r, const SDL_Rect* rClip, float scaleX, float scaleY, bool wide);
$nobinding void DrawTexCoord(int s, int t);
+$nobinding bool __cdecl drawTop(const SDL_Rect* window);
$nobinding void __cdecl DrawTransformToScreen(SDL_Rect* w, SDL_Rect* s);
$nobinding float __cdecl DrawTransformToScreenH(float h);
$nobinding void DrawVertex(int x, int y);
@@ -1699,6 +1706,7 @@ $nobinding int __cdecl SDL_ShowSimpleMessageBox(uint flags, const char* title, c
$nobinding void SearchThreadMain();
$nobinding void uiDrawSlicedRect(int rectNum, const SDL_Rect* bounds, int alpha, const SDL_Rect* rClip);
$nobinding int uiExecLuaInt(int id);
+$nobinding void __cdecl uiHandleTooltip();
$nobinding bool uiPop(const char* name);
$nobinding bool uiPush(const char* name);
$nobinding void uiSetHidden(bool bHidden);
@@ -1714,6 +1722,8 @@ $nobinding float YScreenToZoomed(float y);
char* afxPchNil;
$9B9540D9920A90D57A3D80DDD1A70514 capture;
+bool fingerDown;
+uiMenu* g_backgroundMenu;
RendererType g_drawBackend;
keyword g_keywords[124];
lua_State* g_lua;
@@ -1726,6 +1736,7 @@ uiMenu* menuStack[256];
int nextStackMenuIdx;
int numMenus;
CTypedPtrArray resources;
+$820A8B7015E7E0FD9144A7C186FBF075 tooltip;
$A92C2F5FC159A4FE55DD6CCAABD58E72 transition;
const ushort yy_action[1765];
const ushort yy_default[329];
diff --git a/LuaBindings-v2.6.6.0/source/LuaBindings-v2.6.6.0/Generated/Baldur-v2.6.6.0_generated_internal_pointers.cpp b/LuaBindings-v2.6.6.0/source/LuaBindings-v2.6.6.0/Generated/Baldur-v2.6.6.0_generated_internal_pointers.cpp
index 13e1822..64567d5 100644
--- a/LuaBindings-v2.6.6.0/source/LuaBindings-v2.6.6.0/Generated/Baldur-v2.6.6.0_generated_internal_pointers.cpp
+++ b/LuaBindings-v2.6.6.0/source/LuaBindings-v2.6.6.0/Generated/Baldur-v2.6.6.0_generated_internal_pointers.cpp
@@ -55,6 +55,7 @@ type_findMenu p_findMenu;
type_rand p_rand;
type_restoreMenuStack p_restoreMenuStack;
type_saveMenuStack p_saveMenuStack;
+type_SDL_GetDisplayForWindow p_SDL_GetDisplayForWindow;
type_SDL_GetKeyFromName p_SDL_GetKeyFromName;
type_SDL_GetKeyName p_SDL_GetKeyName;
type_SDL_GetWindowFlags p_SDL_GetWindowFlags;
@@ -81,6 +82,7 @@ type_DrawEnable p_DrawEnable;
type_DrawEnd p_DrawEnd;
type_DrawEndScaled p_DrawEndScaled;
type_drawLetters p_drawLetters;
+type_drawMenu p_drawMenu;
type_DrawOrtho11Begin p_DrawOrtho11Begin;
type_DrawOrtho11End p_DrawOrtho11End;
type_DrawPopState p_DrawPopState;
@@ -89,6 +91,7 @@ type_DrawQuad p_DrawQuad;
type_drawSlice p_drawSlice;
type_drawSliceSide p_drawSliceSide;
type_DrawTexCoord p_DrawTexCoord;
+type_drawTop p_drawTop;
type_DrawTransformToScreen p_DrawTransformToScreen;
type_DrawTransformToScreenH p_DrawTransformToScreenH;
type_DrawVertex p_DrawVertex;
@@ -106,6 +109,7 @@ type_SDL_ShowSimpleMessageBox p_SDL_ShowSimpleMessageBox;
type_SearchThreadMain p_SearchThreadMain;
type_uiDrawSlicedRect p_uiDrawSlicedRect;
type_uiExecLuaInt p_uiExecLuaInt;
+type_uiHandleTooltip p_uiHandleTooltip;
type_uiPop p_uiPop;
type_uiPush p_uiPush;
type_uiSetHidden p_uiSetHidden;
@@ -116,6 +120,8 @@ type_XScreenToZoomed p_XScreenToZoomed;
type_YScreenToZoomed p_YScreenToZoomed;
char** p_afxPchNil;
_9B9540D9920A90D57A3D80DDD1A70514* p_capture;
+bool* p_fingerDown;
+uiMenu** p_g_backgroundMenu;
RendererType* p_g_drawBackend;
Array* p_g_keywords;
lua_State** p_g_lua;
@@ -128,6 +134,7 @@ Array* p_menuStack;
int* p_nextStackMenuIdx;
int* p_numMenus;
CTypedPtrArray* p_resources;
+_820A8B7015E7E0FD9144A7C186FBF075* p_tooltip;
_A92C2F5FC159A4FE55DD6CCAABD58E72* p_transition;
ConstArray* p_yy_action;
ConstArray* p_yy_default;
@@ -176,7 +183,11 @@ CAIScriptFile::type_ParseObjectType CAIScriptFile::p_ParseObjectType;
CAIScriptFile::type_ParseResponseString CAIScriptFile::p_ParseResponseString;
CSound::type_Construct CSound::p_Construct;
CSound::type_Destruct CSound::p_Destruct;
+CVidBitmap::type_Construct CVidBitmap::p_Construct;
+CVidBitmap::type_Destruct CVidBitmap::p_Destruct;
CVidBitmap::type_GetPixelColor CVidBitmap::p_GetPixelColor;
+CVidBitmap::type_GetPixelValueOrZero CVidBitmap::p_GetPixelValueOrZero;
+CVidBitmap::type_SetResRef CVidBitmap::p_SetResRef;
CSearchBitmap::type_GetCost CSearchBitmap::p_GetCost;
CSearchBitmap::type_GetLOSCost CSearchBitmap::p_GetLOSCost;
CSearchBitmap::type_GetNearestOpenSquare CSearchBitmap::p_GetNearestOpenSquare;
@@ -381,6 +392,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("rand"), p_rand);
attemptFillPointer(TEXT("restoreMenuStack"), p_restoreMenuStack);
attemptFillPointer(TEXT("saveMenuStack"), p_saveMenuStack);
+ attemptFillPointer(TEXT("SDL_GetDisplayForWindow"), p_SDL_GetDisplayForWindow);
attemptFillPointer(TEXT("SDL_GetKeyFromName"), p_SDL_GetKeyFromName);
attemptFillPointer(TEXT("SDL_GetKeyName"), p_SDL_GetKeyName);
attemptFillPointer(TEXT("SDL_GetWindowFlags"), p_SDL_GetWindowFlags);
@@ -407,6 +419,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("DrawEnd"), p_DrawEnd);
attemptFillPointer(TEXT("DrawEndScaled"), p_DrawEndScaled);
attemptFillPointer(TEXT("drawLetters"), p_drawLetters);
+ attemptFillPointer(TEXT("drawMenu"), p_drawMenu);
attemptFillPointer(TEXT("DrawOrtho11Begin"), p_DrawOrtho11Begin);
attemptFillPointer(TEXT("DrawOrtho11End"), p_DrawOrtho11End);
attemptFillPointer(TEXT("DrawPopState"), p_DrawPopState);
@@ -415,6 +428,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("drawSlice"), p_drawSlice);
attemptFillPointer(TEXT("drawSliceSide"), p_drawSliceSide);
attemptFillPointer(TEXT("DrawTexCoord"), p_DrawTexCoord);
+ attemptFillPointer(TEXT("drawTop"), p_drawTop);
attemptFillPointer(TEXT("DrawTransformToScreen"), p_DrawTransformToScreen);
attemptFillPointer(TEXT("DrawTransformToScreenH"), p_DrawTransformToScreenH);
attemptFillPointer(TEXT("DrawVertex"), p_DrawVertex);
@@ -432,6 +446,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("SearchThreadMain"), p_SearchThreadMain);
attemptFillPointer(TEXT("uiDrawSlicedRect"), p_uiDrawSlicedRect);
attemptFillPointer(TEXT("uiExecLuaInt"), p_uiExecLuaInt);
+ attemptFillPointer(TEXT("uiHandleTooltip"), p_uiHandleTooltip);
attemptFillPointer(TEXT("uiPop"), p_uiPop);
attemptFillPointer(TEXT("uiPush"), p_uiPush);
attemptFillPointer(TEXT("uiSetHidden"), p_uiSetHidden);
@@ -442,6 +457,8 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("YScreenToZoomed"), p_YScreenToZoomed);
attemptFillPointer(TEXT("afxPchNil"), p_afxPchNil);
attemptFillPointer(TEXT("capture"), p_capture);
+ attemptFillPointer(TEXT("fingerDown"), p_fingerDown);
+ attemptFillPointer(TEXT("g_backgroundMenu"), p_g_backgroundMenu);
attemptFillPointer(TEXT("g_drawBackend"), p_g_drawBackend);
attemptFillPointer(TEXT("g_keywords"), p_g_keywords);
attemptFillPointer(TEXT("g_lua"), p_g_lua);
@@ -454,6 +471,7 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("nextStackMenuIdx"), p_nextStackMenuIdx);
attemptFillPointer(TEXT("numMenus"), p_numMenus);
attemptFillPointer(TEXT("resources"), p_resources);
+ attemptFillPointer(TEXT("tooltip"), p_tooltip);
attemptFillPointer(TEXT("transition"), p_transition);
attemptFillPointer(TEXT("yy_action"), p_yy_action);
attemptFillPointer(TEXT("yy_default"), p_yy_default);
@@ -502,7 +520,11 @@ void InitBindingsInternal() {
attemptFillPointer(TEXT("CAIScriptFile::ParseResponseString"), CAIScriptFile::p_ParseResponseString);
attemptFillPointer(TEXT("CSound::Construct"), CSound::p_Construct);
attemptFillPointer(TEXT("CSound::Destruct"), CSound::p_Destruct);
+ attemptFillPointer(TEXT("CVidBitmap::Construct"), CVidBitmap::p_Construct);
+ attemptFillPointer(TEXT("CVidBitmap::Destruct"), CVidBitmap::p_Destruct);
attemptFillPointer(TEXT("CVidBitmap::GetPixelColor"), CVidBitmap::p_GetPixelColor);
+ attemptFillPointer(TEXT("CVidBitmap::GetPixelValue(int,int)"), CVidBitmap::p_GetPixelValueOrZero);
+ attemptFillPointer(TEXT("CVidBitmap::SetResRef"), CVidBitmap::p_SetResRef);
attemptFillPointer(TEXT("CSearchBitmap::GetCost"), CSearchBitmap::p_GetCost);
attemptFillPointer(TEXT("CSearchBitmap::GetLOSCost"), CSearchBitmap::p_GetLOSCost);
attemptFillPointer(TEXT("CSearchBitmap::GetNearestOpenSquare"), CSearchBitmap::p_GetNearestOpenSquare);
diff --git a/LuaBindings-v2.6.6.0/source/LuaBindings-v2.6.6.0/Generated/EEexLua_generated.cpp b/LuaBindings-v2.6.6.0/source/LuaBindings-v2.6.6.0/Generated/EEexLua_generated.cpp
index 5bed072..efedb5a 100644
--- a/LuaBindings-v2.6.6.0/source/LuaBindings-v2.6.6.0/Generated/EEexLua_generated.cpp
+++ b/LuaBindings-v2.6.6.0/source/LuaBindings-v2.6.6.0/Generated/EEexLua_generated.cpp
@@ -51,171 +51,171 @@ static int tolua_get_Primitive_CGameObjectType__reference_value(lua_State* L)
return 1;
}
-static int tolua_get_Primitive_CButtonType__value(lua_State* L)
+static int tolua_get_Primitive_WindowShapeMode__value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
lua_pushinteger(L, (lua_Integer)self->value);
return 1;
}
-static int tolua_set_Primitive_CButtonType__value(lua_State* L)
+static int tolua_set_Primitive_WindowShapeMode__value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
- self->value = (CButtonType)tolua_setter_tointeger<__int32>(L, "value");
+ self->value = (WindowShapeMode)tolua_setter_tointeger<__int32>(L, "value");
return 0;
}
-static int tolua_get_Primitive_CButtonType__reference_value(lua_State* L)
+static int tolua_get_Primitive_WindowShapeMode__reference_value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
- tolua_pushusertype(L, (void*)&self->value, "Primitive");
+ tolua_pushusertype(L, (void*)&self->value, "Primitive");
return 1;
}
-static int tolua_get_Primitive_CGameJournalEntryFlag__value(lua_State* L)
+static int tolua_get_Primitive_SDL_bool__value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
lua_pushinteger(L, (lua_Integer)self->value);
return 1;
}
-static int tolua_set_Primitive_CGameJournalEntryFlag__value(lua_State* L)
+static int tolua_set_Primitive_SDL_bool__value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
- self->value = (CGameJournalEntryFlag)tolua_setter_tointeger<__int32>(L, "value");
+ self->value = (SDL_bool)tolua_setter_tointeger<__int32>(L, "value");
return 0;
}
-static int tolua_get_Primitive_CGameJournalEntryFlag__reference_value(lua_State* L)
+static int tolua_get_Primitive_SDL_bool__reference_value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
- tolua_pushusertype(L, (void*)&self->value, "Primitive");
+ tolua_pushusertype(L, (void*)&self->value, "Primitive");
return 1;
}
-static int tolua_get_Primitive_CSpawn__ePMode__value(lua_State* L)
+static int tolua_get_Primitive_SDL_HitTestResult__value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
lua_pushinteger(L, (lua_Integer)self->value);
return 1;
}
-static int tolua_set_Primitive_CSpawn__ePMode__value(lua_State* L)
+static int tolua_set_Primitive_SDL_HitTestResult__value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
- self->value = (CSpawn::ePMode)tolua_setter_tointeger<__int32>(L, "value");
+ self->value = (SDL_HitTestResult)tolua_setter_tointeger<__int32>(L, "value");
return 0;
}
-static int tolua_get_Primitive_CSpawn__ePMode__reference_value(lua_State* L)
+static int tolua_get_Primitive_SDL_HitTestResult__reference_value(lua_State* L)
{
- Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
+ Primitive* self = (Primitive*)tolua_tousertype_dynamic(L, 1, 0, "Primitive");
if (!self) tolua_error(L, "invalid 'self' in accessing variable 'value'", NULL);
- tolua_pushusertype(L, (void*)&self->value, "Primitive