349 lines
11 KiB
C
349 lines
11 KiB
C
#include "osg.h"
|
|
|
|
#include <memory.h>
|
|
#include <stdlib.h>
|
|
|
|
mxdraw *mxdrawZero(mxdraw *this, OSU *osu) {
|
|
this->hasState = 0;
|
|
this->s1 = NULL;
|
|
this->s2 = NULL;
|
|
this->hInstance = NULL;
|
|
this->nCmdShow = 0;
|
|
this->hWnd = NULL;
|
|
this->hBitmap = NULL;
|
|
this->hDc = NULL;
|
|
this->dispWidth = 0;
|
|
this->dispHeight = 0;
|
|
this->font1 = NULL;
|
|
this->font2 = NULL;
|
|
this->font3 = NULL;
|
|
ShowCursor(0);
|
|
if (osu != NULL) {
|
|
this->hInstance = osu->hInstance;
|
|
this->nCmdShow = osu->nShowCmd;
|
|
this->s1 = osu->s1;
|
|
this->s2 = osu->s2;
|
|
this->hasState = 1;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
void mxdrawCleanup(mxdraw *this) {
|
|
ShowCursor(1);
|
|
DeleteObject(this->font1);
|
|
DeleteObject(this->font2);
|
|
DeleteObject(this->font3);
|
|
DeleteObject(this->hBitmap);
|
|
ReleaseDC(this->hWnd, this->hDc);
|
|
}
|
|
|
|
void peekDispatchLoop(void) {
|
|
MSG msg;
|
|
PeekMessageA(&msg, NULL, 0, 0, 0);
|
|
while (msg.message != WM_QUIT) {
|
|
if (PeekMessageA(&msg, NULL, 0, 0, 1)) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessageA(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
COLORREF GetColour(colour col) {
|
|
switch (col) {
|
|
case Black:
|
|
return 0x000000;
|
|
case Red:
|
|
return 0x0000ff;
|
|
case Blue:
|
|
return 0xc80000;
|
|
case Green:
|
|
return 0xb4ffb4;
|
|
case Grey:
|
|
return 0x646464;
|
|
default:
|
|
return 0xffffff;
|
|
}
|
|
}
|
|
|
|
void mxdrawR1(mxdraw *this) {
|
|
RECT rect;
|
|
rect.bottom = this->dispHeight;
|
|
rect.left = 0;
|
|
rect.top = 0;
|
|
rect.right = this->dispWidth;
|
|
|
|
EnterCriticalSection(&this->s1->criticalSection);
|
|
HBRUSH hbr = CreateSolidBrush(GetColour(this->s2->backgroundColour));
|
|
LeaveCriticalSection(&this->s1->criticalSection);
|
|
|
|
FillRect(this->hDc, &rect, hbr);
|
|
DeleteObject(hbr);
|
|
}
|
|
void mxdrawR2(mxdraw *this) {
|
|
if (!this->s1->show_top) return;
|
|
|
|
switch (this->s1->top_text_font) {
|
|
case 1:
|
|
SelectObject(this->hDc, this->font3);
|
|
break;
|
|
case 2:
|
|
SelectObject(this->hDc, this->font1);
|
|
break;
|
|
default:
|
|
SelectObject(this->hDc, this->font2);
|
|
break;
|
|
}
|
|
|
|
SetTextAlign(this->hDc, TA_CENTER + TA_BASELINE);
|
|
SetTextColor(this->hDc, GetColour(this->s1->top_text_colour));
|
|
SetBkMode(this->hDc, TRANSPARENT);
|
|
|
|
EnterCriticalSection(&this->s1->criticalSection);
|
|
if (this->s1->str1)
|
|
TextOutA(this->hDc, this->dispWidth / 2, this->dispHeight / 6, this->s1->str1,
|
|
strlen(this->s1->str1));
|
|
LeaveCriticalSection(&this->s1->criticalSection);
|
|
}
|
|
void mxdrawR3(mxdraw *this) {
|
|
if (!this->s1->show_top) return;
|
|
|
|
switch (this->s1->top_text_font) {
|
|
case 1:
|
|
SelectObject(this->hDc, this->font3);
|
|
break;
|
|
case 2:
|
|
SelectObject(this->hDc, this->font1);
|
|
break;
|
|
default:
|
|
SelectObject(this->hDc, this->font2);
|
|
break;
|
|
}
|
|
|
|
SetTextAlign(this->hDc, TA_CENTER + TA_BASELINE);
|
|
SetTextColor(this->hDc, GetColour(this->s1->top_text_colour));
|
|
SetBkMode(this->hDc, TRANSPARENT);
|
|
|
|
EnterCriticalSection(&this->s1->criticalSection);
|
|
if (this->s1->str2)
|
|
TextOutA(this->hDc, this->dispWidth / 2, this->dispHeight / 3, this->s1->str2,
|
|
strlen(this->s1->str2));
|
|
LeaveCriticalSection(&this->s1->criticalSection);
|
|
}
|
|
void mxdrawR4(mxdraw *this) {
|
|
static int _counter = 0;
|
|
|
|
SetTextAlign(this->hDc, TA_CENTER + TA_BASELINE);
|
|
switch (this->s2->status_font) {
|
|
case 1:
|
|
SelectObject(this->hDc, this->font3);
|
|
break;
|
|
case 2:
|
|
SelectObject(this->hDc, this->font1);
|
|
break;
|
|
default:
|
|
SelectObject(this->hDc, this->font2);
|
|
break;
|
|
}
|
|
|
|
SetTextColor(this->hDc, GetColour(this->s2->status_colour));
|
|
SetBkMode(this->hDc, TRANSPARENT);
|
|
EnterCriticalSection(&this->s1->criticalSection);
|
|
if (this->s2->status_use_counter == 0 || _counter > 1) {
|
|
if (this->s2->status_str)
|
|
TextOutA(this->hDc, this->dispWidth / 2, this->dispHeight / 2, this->s2->status_str,
|
|
strlen(this->s2->status_str));
|
|
}
|
|
LeaveCriticalSection(&this->s1->criticalSection);
|
|
_counter = (_counter + 1) % 7;
|
|
}
|
|
void mxdrawR5(mxdraw *this) {
|
|
static int _counter = 0;
|
|
|
|
SetTextAlign(this->hDc, TA_CENTER + TA_TOP);
|
|
switch (this->s2->power_font) {
|
|
case 1:
|
|
SelectObject(this->hDc, this->font3);
|
|
break;
|
|
case 2:
|
|
SelectObject(this->hDc, this->font1);
|
|
break;
|
|
default:
|
|
SelectObject(this->hDc, this->font2);
|
|
break;
|
|
}
|
|
|
|
SetTextColor(this->hDc, GetColour(this->s2->power_colour));
|
|
|
|
EnterCriticalSection(&this->s1->criticalSection);
|
|
if (this->s2->hide_power != 1 || _counter > 1) {
|
|
if (this->s2->str2)
|
|
TextOutA(this->hDc, (int)this->dispWidth / 2, (this->dispHeight * 4) / 6,
|
|
this->s2->str2, strlen(this->s2->str2));
|
|
}
|
|
LeaveCriticalSection(&this->s1->criticalSection);
|
|
_counter = (_counter + 1) % 7;
|
|
}
|
|
void mxdrawR6(mxdraw *this) {
|
|
if (!this->s1->debugEnable) return;
|
|
|
|
SetTextAlign(this->hDc, TA_LEFT + TA_BASELINE);
|
|
SelectObject(this->hDc, this->font3);
|
|
SetTextColor(this->hDc, GetColour(this->s2->debug_colour));
|
|
|
|
EnterCriticalSection(&this->s1->criticalSection);
|
|
if (this->s2->debug_text)
|
|
TextOutA(this->hDc, this->dispWidth / 10, (this->dispHeight * 10) / 11,
|
|
this->s2->debug_text, strlen(this->s2->debug_text));
|
|
LeaveCriticalSection(&this->s1->criticalSection);
|
|
}
|
|
|
|
void mxdrawR7(mxdraw *this) {
|
|
SetTextAlign(this->hDc, TA_LEFT + TA_BASELINE);
|
|
SelectObject(this->hDc, this->font3);
|
|
SetTextColor(this->hDc, GetColour(this->s2->line5_colour));
|
|
|
|
EnterCriticalSection(&this->s1->criticalSection);
|
|
if (this->s2->line5)
|
|
TextOutA(this->hDc, 0, this->dispHeight, this->s2->line5, strlen(this->s2->line5));
|
|
LeaveCriticalSection(&this->s1->criticalSection);
|
|
}
|
|
|
|
void mxdrawRender(mxdraw *this) {
|
|
this->dispWidth = GetSystemMetrics(0);
|
|
this->dispHeight = GetSystemMetrics(1);
|
|
if (this->dispWidth != 640 || this->dispHeight != 480) {
|
|
// iVar1 = amSysDataGetDotClockTiming(640, 480, local_38);
|
|
// if (iVar1 == 0) {
|
|
// amPlatformSetDisplayResolution(local_38, extraout_EDX, (ushort *)local_38);
|
|
// }
|
|
}
|
|
|
|
mxdrawR1(this); // Clear background
|
|
mxdrawR2(this); // s1, str1
|
|
mxdrawR3(this); // s1, str2
|
|
mxdrawR4(this); // s2, status_str
|
|
mxdrawR5(this); // s2, str2
|
|
mxdrawR6(this); // s2, debug_text
|
|
mxdrawR7(this); // s2, line5
|
|
|
|
HDC hdc = GetDC(this->hWnd);
|
|
BitBlt(hdc, 0, 0, this->dispWidth, this->dispHeight, this->hDc, 0, 0, SRCCOPY);
|
|
ReleaseDC(this->hWnd, hdc);
|
|
SetWindowPos(this->hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
}
|
|
|
|
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
|
if (uMsg == WM_CREATE) {
|
|
SetTimer(hWnd, 15000, 0x80, NULL);
|
|
} else if (uMsg == WM_DESTROY) {
|
|
RemovePropA(hWnd, "prp");
|
|
PostQuitMessage(0);
|
|
} else if (uMsg == WM_TIMER) {
|
|
mxdraw *this = (mxdraw *)GetPropA(hWnd, "prp");
|
|
mxdrawRender(this);
|
|
if (this->s2->only_sends_if == 1) {
|
|
SendMessageA(hWnd, WM_DESTROY, 0, 0);
|
|
}
|
|
}
|
|
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
int mxdrawSetup(mxdraw *this) {
|
|
if (this->hasState == 0) return 1;
|
|
|
|
WNDCLASSEXA class;
|
|
class.hInstance = this->hInstance;
|
|
class.cbSize = 0x30;
|
|
class.style = 3;
|
|
class.lpfnWndProc = WndProc;
|
|
class.cbClsExtra = 0;
|
|
class.cbWndExtra = 0;
|
|
class.hIcon = LoadIconA(NULL, IDI_APPLICATION);
|
|
class.hCursor = LoadCursorA(NULL, IDC_ARROW);
|
|
class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
|
class.lpszMenuName = NULL;
|
|
class.lpszClassName = "MxDraw";
|
|
class.hIconSm = LoadIconA(NULL, IDI_APPLICATION);
|
|
if (!RegisterClassExA(&class)) {
|
|
if (GetLastError() != ERROR_CLASS_ALREADY_EXISTS) return 2;
|
|
}
|
|
|
|
this->dispWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
this->dispHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
if (this->dispWidth != 640 || this->dispHeight != 480) {
|
|
// TODO: This
|
|
// setres_640_480();
|
|
this->dispWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
this->dispHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
|
|
this->hWnd =
|
|
CreateWindowExA(0, "MxDraw", "MxDraw", WS_DISABLED | WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
this->dispWidth, this->dispHeight, NULL, NULL, this->hInstance, NULL);
|
|
SetPropA(this->hWnd, "prp", this);
|
|
|
|
this->font1 = CreateFontA((int)(this->dispHeight * 0.125f), 0, 0, 0, 700, FALSE, FALSE, FALSE,
|
|
0, 7, 0, 0, 1, "Tahoma bold");
|
|
this->font2 = CreateFontA((int)(this->dispHeight * 0.09f), 0, 0, 0, 700, FALSE, FALSE, FALSE, 0,
|
|
7, 0, 0, 1, "Tahoma bold");
|
|
this->font3 = CreateFontA((int)(this->dispHeight * 0.03125f), 0, 0, 0, 700, FALSE, FALSE, FALSE,
|
|
0, 7, 0, 0, 1, "Tahoma bold");
|
|
|
|
ShowWindow(this->hWnd, this->nCmdShow);
|
|
UpdateWindow(this->hWnd);
|
|
HDC hdc = GetDC(this->hWnd);
|
|
this->hBitmap = CreateCompatibleBitmap(hdc, this->dispWidth, this->dispHeight);
|
|
this->hDc = CreateCompatibleDC(hdc);
|
|
ReleaseDC(this->hWnd, hdc);
|
|
SelectObject(this->hDc, this->hBitmap);
|
|
return 0;
|
|
}
|
|
|
|
DWORD mxdrawThread(OSU *osu) {
|
|
mxdraw *this = (mxdraw *)malloc(sizeof *this);
|
|
if (this != NULL) mxdrawZero(this, osu);
|
|
mxdrawSetup(this);
|
|
peekDispatchLoop();
|
|
if (this != NULL) {
|
|
mxdrawCleanup(this);
|
|
free(this);
|
|
}
|
|
ExitThread(1);
|
|
}
|
|
|
|
BOOL osgInitDraw(OSU *lpOsu) {
|
|
OSU *lpParameter;
|
|
HANDLE pvVar1;
|
|
|
|
lpParameter = lpOsu;
|
|
if (lpOsu == NULL) return FALSE;
|
|
|
|
InitializeCriticalSection(&lpOsu->s1->criticalSection);
|
|
EnterCriticalSection(&lpParameter->s1->criticalSection);
|
|
lpParameter->s2->only_sends_if = 0;
|
|
LeaveCriticalSection(&lpParameter->s1->criticalSection);
|
|
pvVar1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)mxdrawThread, lpParameter, 0,
|
|
(LPDWORD)&lpOsu);
|
|
lpParameter->handle = pvVar1;
|
|
if (pvVar1 == NULL) {
|
|
lpParameter->field3_0xc = 0;
|
|
return FALSE;
|
|
}
|
|
lpParameter->field3_0xc = 1;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL osgExit(OSU *this) {
|
|
if (this->field3_0xc != 1) return FALSE;
|
|
|
|
EnterCriticalSection(&this->s1->criticalSection);
|
|
this->s2->only_sends_if = 1;
|
|
LeaveCriticalSection(&this->s1->criticalSection);
|
|
WaitForSingleObject(this->handle, INFINITE);
|
|
CloseHandle(this->handle);
|
|
DeleteCriticalSection(&this->s1->criticalSection);
|
|
this->field3_0xc = 0;
|
|
|
|
return TRUE;
|
|
}
|