diff --git a/src/micetools/dll/devices/ser_maitouch.c b/src/micetools/dll/devices/ser_maitouch.c index df3cdad..9dfe340 100644 --- a/src/micetools/dll/devices/ser_maitouch.c +++ b/src/micetools/dll/devices/ser_maitouch.c @@ -108,9 +108,13 @@ static void populateActiveResponse() { } } - for (DWORD i = 0; i < nActiveTouches; i++) { - handleOneButton(w, h, activeTouches[i].m_X, activeTouches[i].m_Y); - } + MICE_DA_ITER(g_activeTouches, ACTIVE_TOUCH, i) { + handleOneButton(w, h, i->m_X, i->m_Y); + } MICE_DA_ITER_END + + // for (DWORD i = 0; i < nActiveTouches; i++) { + // handleOneButton(w, h, activeTouches[i].m_X, activeTouches[i].m_Y); + // } } BOOL touch_is_enabled = TRUE; // Default on is important! diff --git a/src/micetools/dll/hooks/gui.c b/src/micetools/dll/hooks/gui.c index d33c1f3..2016c52 100644 --- a/src/micetools/dll/hooks/gui.c +++ b/src/micetools/dll/hooks/gui.c @@ -247,49 +247,25 @@ void register_gui_hook(FnEndScene* end_scene) { *head = hook; } -DWORD nActiveTouches = 0; -ACTIVE_TOUCH* activeTouches = NULL; -extern DWORD nActiveTouchesMax = 0; +MICE_DA_NEW(g_activeTouches, ACTIVE_TOUCH) void SetTouch(UINT id, INT x, INT y, BOOL state) { if (state) { - // If we can just update in place, do - for (DWORD i = 0; i < nActiveTouches; i++) { - if (activeTouches[i].m_Id == id) { - activeTouches[i].m_X = x; - activeTouches[i].m_Y = y; + MICE_DA_ITER(g_activeTouches, ACTIVE_TOUCH, i) { + if (i->m_Id == id) { + i->m_X = x; + i->m_Y = y; return; } } - - // Dynamic array re-allocation - if (nActiveTouches == nActiveTouchesMax) { - DWORD newSize = nActiveTouchesMax * 2 + 1; - ACTIVE_TOUCH* newMemory = realloc(activeTouches, sizeof *activeTouches * newSize); - if (newMemory != activeTouches) { - memcpy(newMemory, activeTouches, sizeof *activeTouches * nActiveTouchesMax); - } - activeTouches = newMemory; - nActiveTouchesMax = newSize; - } - - // Store into end of DA - activeTouches[nActiveTouches].m_Id = id; - activeTouches[nActiveTouches].m_X = x; - activeTouches[nActiveTouches].m_Y = y; - nActiveTouches++; + MICE_DA_ITER_END + ACTIVE_TOUCH touch = { .m_Id = id, .m_X = x, .m_Y = y }; + MiceDAPush(g_activeTouches, &touch); } else { - for (DWORD i = 0; i < nActiveTouches; i++) { - if (activeTouches[i].m_Id == id) { - // Copy backwards - for (DWORD j = i + 1; j < nActiveTouches; j++) { - activeTouches[j - 1].m_Id = activeTouches[j].m_Id; - activeTouches[j - 1].m_X = activeTouches[j].m_X; - activeTouches[j - 1].m_Y = activeTouches[j].m_Y; - } - nActiveTouches--; - } + MICE_DA_ITER(g_activeTouches, ACTIVE_TOUCH, i) { + if (i->m_Id == id) MICE_DA_REMOVE_CURRENT(g_activeTouches); } + MICE_DA_ITER_END } } @@ -413,7 +389,8 @@ void SetupWindowPosition(LPRECT lpRect, DWORD dwStyle) { // RECT adjustedRect; // memcpy(&adjustedRect, lpRect, sizeof *lpRect); // UnadjustWindowRect(&adjustedRect, dwStyle, FALSE); - // // We're going to only adjust y, on the assumption x is unchanged, and even if it is + // // We're going to only adjust y, on the assumption x is unchanged, and even if it + // is // // it'll be symmetic. y has the titlebar to worry about. // int outerH = adjustedRect.bottom - adjustedRect.top; diff --git a/src/micetools/dll/hooks/gui.h b/src/micetools/dll/hooks/gui.h index b3fce91..7d0fda6 100644 --- a/src/micetools/dll/hooks/gui.h +++ b/src/micetools/dll/hooks/gui.h @@ -48,8 +48,10 @@ typedef struct { INT m_X; INT m_Y; } ACTIVE_TOUCH; -extern DWORD nActiveTouches; -extern ACTIVE_TOUCH* activeTouches; +// extern DWORD nActiveTouches; +// extern ACTIVE_TOUCH* activeTouches; + +extern PMICE_DA g_activeTouches; BOOL UnadjustWindowRect(LPRECT prc, DWORD dwStyle, BOOL fMenu); extern HWND mainWindow; diff --git a/src/micetools/dll/util/misc.c b/src/micetools/dll/util/misc.c index fd1137c..c94c6c0 100644 --- a/src/micetools/dll/util/misc.c +++ b/src/micetools/dll/util/misc.c @@ -42,74 +42,58 @@ BOOL FileExistsA(const char* szPath) { return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); } -typedef struct _handle_list { +typedef struct HANDLE_DATA { HANDLE m_Handle; PVOID m_pData; DWORD m_Type; BOOL m_IsOnHeap; - struct _handle_list* m_Next; -} handle_list_t; -handle_list_t handle_list_root = { - .m_Handle = INVALID_HANDLE_VALUE, - .m_pData = NULL, - .m_Type = 0xffffffff, - .m_IsOnHeap = FALSE, - .m_Next = NULL, -}; +} HANDLE_DATA; +MICE_DA_NEW(g_handleData, HANDLE_DATA) PVOID GetDataForHandle(HANDLE hObject, DWORD type) { if (hObject == INVALID_HANDLE_VALUE) return NULL; - handle_list_t* head = &handle_list_root; - while (head) { - if (head->m_Handle == hObject && (type == HDATA_ANY || head->m_Type == type)) - return head->m_pData; - head = head->m_Next; + MICE_DA_ITER(g_handleData, HANDLE_DATA, i) { + if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) { + return i->m_pData; + } } + MICE_DA_ITER_END return NULL; } void SetDataForHandle(HANDLE hObject, DWORD type, PVOID pData, BOOL isHeap) { if (hObject == INVALID_HANDLE_VALUE) return; - handle_list_t* head = &handle_list_root; - while (1) { - if (head->m_Handle == hObject && (type == HDATA_ANY || head->m_Type == type)) { - if (head->m_IsOnHeap) free(head->m_pData); - head->m_pData = pData; - head->m_IsOnHeap = isHeap; + MICE_DA_ITER(g_handleData, HANDLE_DATA, i) { + if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) { + if (i->m_IsOnHeap) free(i->m_pData); + i->m_pData = pData; + i->m_IsOnHeap = isHeap; return; } - if (head->m_Next == NULL) break; - head = head->m_Next; } - head->m_Next = malloc(sizeof *head); - head->m_Next->m_Handle = hObject; - head->m_Next->m_pData = pData; - head->m_Next->m_Next = NULL; - head->m_Next->m_IsOnHeap = isHeap; - head->m_Next->m_Type = type; + MICE_DA_ITER_END + + HANDLE_DATA newHandleData = { + .m_Handle = hObject, + .m_pData = pData, + .m_IsOnHeap = isHeap, + .m_Type = type, + }; + MiceDAPush(g_handleData, &newHandleData); } BOOL RemoveDataForHandle(HANDLE hObject, DWORD type) { if (hObject == INVALID_HANDLE_VALUE) return FALSE; - handle_list_t* head = &handle_list_root; - handle_list_t* previous = &handle_list_root; - BOOL ret = FALSE; - while (head) { - if (head->m_Handle == hObject && (type == HDATA_ANY || head->m_Type == type)) { - previous->m_Next = head->m_Next; - if (head->m_IsOnHeap) free(head->m_pData); - handle_list_t* next = head->m_Next; - free(head); - head = next; - if (type != HDATA_ANY) return TRUE; - ret = TRUE; - } else { - previous = head; - head = head->m_Next; + MICE_DA_ITER(g_handleData, HANDLE_DATA, i) { + if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) { + if (i->m_IsOnHeap) free(i->m_pData); + MICE_DA_REMOVE_CURRENT(g_handleData); + return TRUE; } } - return ret; + MICE_DA_ITER_END + return FALSE; } HANDLE GetDummyHandle() { diff --git a/src/micetools/lib/mice/da.c b/src/micetools/lib/mice/da.c new file mode 100644 index 0000000..6c19b87 --- /dev/null +++ b/src/micetools/lib/mice/da.c @@ -0,0 +1,87 @@ +#include "da.h" + +#include +#include + +static inline void _MiceDAGrow(PMICE_DA lpDa) { + DWORD_PTR newSize = lpDa->m_Capacity * 2 + 1; + if (lpDa->m_Array) { + LPVOID newArray = realloc(lpDa->m_Array, lpDa->m_Size * newSize); + if (newArray != lpDa->m_Array) { + memcpy(newArray, lpDa->m_Array, lpDa->m_Size * lpDa->m_Capacity); + } + lpDa->m_Array = newArray; + } else { + lpDa->m_Array = malloc(lpDa->m_Size * newSize); + } + lpDa->m_Capacity = newSize; +} + +BOOL MiceDAPush(PMICE_DA lpDa, LPVOID lpSrc) { + if (!lpDa || !lpSrc) return FALSE; + if (lpDa->m_Capacity == lpDa->m_Length) _MiceDAGrow(lpDa); + + _MICE_DA_COPY_INTO_DA(lpDa, lpDa->m_Length, lpSrc); + lpDa->m_Length++; + return TRUE; +} +BOOL MiceDAPop(PMICE_DA lpDa, LPVOID lpDst) { + if (!lpDa) return FALSE; + if (lpDa->m_Length == 0) return FALSE; + lpDa->m_Length--; + if (lpDst) _MICE_DA_COPY_OUTOF_DA(lpDa, lpDa->m_Length, lpDst); + return TRUE; +} + +BOOL MiceDAShift(PMICE_DA lpDa, LPVOID lpSrc) { + if (!lpDa || !lpSrc) return FALSE; + if (lpDa->m_Capacity == lpDa->m_Length) _MiceDAGrow(lpDa); + + // Copy every value one index forwards + for (DWORD_PTR i = lpDa->m_Length; i; i--) { + memcpy(_MICE_DA_INDEX_P(lpDa, i), _MICE_DA_INDEX_P(lpDa, i + 1), lpDa->m_Size); + } + _MICE_DA_COPY_INTO_DA(lpDa, 0, lpSrc); + lpDa->m_Length++; + return TRUE; +} +BOOL MiceDAUnshift(PMICE_DA lpDa, LPVOID lpDst) { + if (!lpDa) return FALSE; + if (lpDst) _MICE_DA_COPY_OUTOF_DA(lpDa, 0, lpDst); + lpDa->m_Length--; + // Copy every value one index back + for (DWORD_PTR i = 0; i < lpDa->m_Length; i++) { + memcpy(_MICE_DA_INDEX_P(lpDa, i), _MICE_DA_INDEX_P(lpDa, i + 1), lpDa->m_Size); + } + return TRUE; +} +BOOL MiceDASet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue) { + if (!lpDa || !lpValue) return FALSE; + if (dwIndex >= lpDa->m_Length) return FALSE; + _MICE_DA_COPY_INTO_DA(lpDa, dwIndex, lpValue); + return TRUE; +} +LPVOID MiceDAGet(PMICE_DA lpDa, DWORD_PTR dwIndex) { + if (!lpDa) NULL; + if (dwIndex >= lpDa->m_Length) return NULL; + return _MICE_DA_INDEX_P(lpDa, dwIndex); +} + +BOOL MiceDARemove(PMICE_DA lpDa, DWORD_PTR dwIndex) { + if (!lpDa) return FALSE; + if (dwIndex > lpDa->m_Length) return FALSE; + if (dwIndex == lpDa->m_Length) { + lpDa->m_Length--; + return TRUE; + } + lpDa->m_Length--; + for (DWORD_PTR i = dwIndex; i < lpDa->m_Length; i++) { + memcpy(_MICE_DA_INDEX_P(lpDa, i), _MICE_DA_INDEX_P(lpDa, i + 1), lpDa->m_Size); + } + return TRUE; +} + +DWORD_PTR MiceDALength(PMICE_DA lpDa) { + if (!lpDa) _invalid_parameter_noinfo_noreturn(); + return lpDa->m_Length; +} diff --git a/src/micetools/lib/mice/da.h b/src/micetools/lib/mice/da.h new file mode 100644 index 0000000..e1bb09e --- /dev/null +++ b/src/micetools/lib/mice/da.h @@ -0,0 +1,35 @@ +#include + +typedef struct MICE_DA { + DWORD_PTR m_Capacity; + DWORD_PTR m_Length; + DWORD_PTR m_Size; + LPVOID m_Array; +} MICE_DA, *PMICE_DA; +#define MICE_DA_NEW(name, type) \ + MICE_DA __mda##name = { \ + .m_Capacity = 0, .m_Length = 0, .m_Size = sizeof(type), .m_Array = NULL \ + }; \ + PMICE_DA name = &__mda##name; + +#define _MICE_DA_INDEX_P(lpDa, index) \ + (LPVOID)((DWORD_PTR)((lpDa)->m_Array) + (index) * (lpDa)->m_Size) +#define _MICE_DA_COPY_INTO_DA(lpDa, index, value) \ + memcpy(_MICE_DA_INDEX_P((lpDa), (index)), (value), (lpDa)->m_Size) +#define _MICE_DA_COPY_OUTOF_DA(lpDa, index, value) \ + memcpy((value), _MICE_DA_INDEX_P((lpDa), (index)), (lpDa)->m_Size) + +#define MICE_DA_ITER(lpDa, type, name) \ + for (DWORD_PTR __mdaI##lpDa = 0; __mdaI##lpDa < (lpDa)->m_Length; __mdaI##lpDa++) { \ + type* name = (type*)_MICE_DA_INDEX_P((lpDa), __mdaI##lpDa); +#define MICE_DA_ITER_END } +#define MICE_DA_REMOVE_CURRENT(lpDa) MiceDARemove((lpDa), __mdaI##lpDa) + +BOOL MiceDAPush(PMICE_DA lpDa, LPVOID lpSrc); +BOOL MiceDAPop(PMICE_DA lpDa, LPVOID lpDst); +BOOL MiceDAShift(PMICE_DA lpDa, LPVOID lpSrc); +BOOL MiceDAUnshift(PMICE_DA lpDa, LPVOID lpDst); +BOOL MiceDASet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue); +LPVOID MiceDAGet(PMICE_DA lpDa, DWORD_PTR dwIndex); +BOOL MiceDARemove(PMICE_DA lpDa, DWORD_PTR dwIndex); +DWORD_PTR MiceDALength(PMICE_DA lpDa); diff --git a/src/micetools/lib/mice/meson.build b/src/micetools/lib/mice/meson.build index ead8596..71ae8bb 100644 --- a/src/micetools/lib/mice/meson.build +++ b/src/micetools/lib/mice/meson.build @@ -14,6 +14,7 @@ mice_lib = static_library( 'dmi.c', 'ipc.c', 'serial.c', + 'da.c', ], link_with: [ inih.get_variable('lib_inih'), diff --git a/src/micetools/lib/mice/mice.h b/src/micetools/lib/mice/mice.h index 839a1b7..bb10938 100644 --- a/src/micetools/lib/mice/mice.h +++ b/src/micetools/lib/mice/mice.h @@ -13,6 +13,7 @@ #include "log.h" #include "patch.h" #include "ringbuf.h" +#include "da.h" #define SRAM_PATH MiceIpcRelativePath("sram.bin") diff --git a/src/micetools/util/meson.build b/src/micetools/util/meson.build index 9170011..a3a06d6 100644 --- a/src/micetools/util/meson.build +++ b/src/micetools/util/meson.build @@ -91,3 +91,13 @@ executable( amSram, ], ) +executable( + 'mice_test', + win_subsystem: subsystem, + sources: [ + 'test.c', + ], + link_with: [ + mice_lib + ], +) diff --git a/src/micetools/util/test.c b/src/micetools/util/test.c new file mode 100644 index 0000000..e798311 --- /dev/null +++ b/src/micetools/util/test.c @@ -0,0 +1,36 @@ +#include + +#include "../lib/mice/mice.h" + +MICE_DA_NEW(testDa, int) + +int main(int argc, char** argv) { + printf("length = %d\n", MiceDALength(testDa)); + for (int i = 0; i < 10; i++) MiceDAPush(testDa, &i); + printf("length = %d\n", MiceDALength(testDa)); + for (int i = 0; i < 10; i++) printf("[%d]: %d\n", i, *(int*)MiceDAGet(testDa, i)); + + MICE_DA_ITER(testDa, int, test) { + printf("iter: %d\n", *test); + } MICE_DA_ITER_END + + puts("Pop"); + MiceDAPop(testDa, NULL); + MICE_DA_ITER(testDa, int, test) { + printf("iter: %d\n", *test); + } MICE_DA_ITER_END + + puts("Unshift"); + MiceDAUnshift(testDa, NULL); + MICE_DA_ITER(testDa, int, test) { + printf("iter: %d\n", *test); + } MICE_DA_ITER_END + + puts("Remove 1"); + MiceDARemove(testDa, 1); + MICE_DA_ITER(testDa, int, test) { + printf("iter: %d\n", *test); + } MICE_DA_ITER_END + + return 0; +} \ No newline at end of file