; WINMO-skeleton by TomCat&Legacy 1998
; -------------------------------------------------------------------- Constans
%DEFINE WIDTH   160
%DEFINE HEIGHT  100
; ------------------------------------------------------------ Import Functions
EXTERN GetSystemMetrics
IMPORT GetSystemMetrics user32.dll
EXTERN SystemParametersInfoA
IMPORT SystemParametersInfoA user32.dll

EXTERN GetCurrentProcess
IMPORT GetCurrentProcess kernel32.dll
EXTERN GetCurrentThread
IMPORT GetCurrentThread kernel32.dll
EXTERN SetPriorityClass
IMPORT SetPriorityClass kernel32.dll
EXTERN SetThreadPriority
IMPORT SetThreadPriority kernel32.dll

EXTERN GetModuleHandleA
IMPORT GetModuleHandleA kernel32.dll
EXTERN RegisterClassA
IMPORT RegisterClassA user32.dll
EXTERN CreateWindowExA
IMPORT CreateWindowExA user32.dll

EXTERN ShowWindow
IMPORT ShowWindow user32.dll
EXTERN ShowCursor
IMPORT ShowCursor user32.dll
EXTERN MoveWindow
IMPORT MoveWindow user32.dll

EXTERN PeekMessageA
IMPORT PeekMessageA user32.dll
EXTERN DispatchMessageA
IMPORT DispatchMessageA user32.dll
EXTERN DefWindowProcA
IMPORT DefWindowProcA user32.dll

EXTERN GlobalAlloc
IMPORT GlobalAlloc kernel32.dll
EXTERN GlobalFree
IMPORT GlobalFree kernel32.dll
EXTERN ExitProcess
IMPORT ExitProcess kernel32.dll

EXTERN GetWindowRect
IMPORT GetWindowRect user32.dll
EXTERN GetClientRect
IMPORT GetClientRect user32.dll
EXTERN GetDC
IMPORT GetDC user32.dll
EXTERN ReleaseDC
IMPORT ReleaseDC user32.dll

EXTERN StretchDIBits
IMPORT StretchDIBits gdi32.dll
; ================================================================ Code Section
SECTION CODE USE32 CLASS=CODE
..start:
; ------------------------------------------------------------- Get System Info
PUSH INTEGER SM_CXSCREEN
CALL [GetSystemMetrics]
MOV [xScreen],EAX

PUSH INTEGER SM_CYSCREEN
CALL [GetSystemMetrics]
MOV [yScreen],EAX

PUSH UINT 0
PUSH PVOID border
PUSH UINT 0
PUSH UINT SPI_GETBORDER
CALL [SystemParametersInfoA]
ADD DWORD [border],3

PUSH INTEGER SM_CYCAPTION
CALL [GetSystemMetrics]
MOV [caption],EAX
; ------------------------------------------------------- Register Window Class
PUSH LPCTSTR NULL
CALL [GetModuleHandleA]
MOV [WindowClassStruc+WNDCLASS.hInstance],EAX

PUSH DWORD WindowClassStruc
CALL [RegisterClassA]
; ---------------------------------------------------------------- Make Windows
PUSH LPVOID NULL
PUSH HINSTANCE [WindowClassStruc+WNDCLASS.hInstance]
PUSH HMENU NULL
PUSH HWND NULL
MOV EAX,[border]
ADD EAX,EAX
MOV EDX,EAX
ADD EAX,[caption]
ADD EAX,[height]
PUSH INTEGER EAX
ADD EDX,[width]
PUSH INTEGER EDX
SUB EAX,[yScreen]
NEG EAX
SHR EAX,1
PUSH INTEGER EAX
SUB EDX,[xScreen]
NEG EDX
SHR EDX,1
PUSH INTEGER EDX
PUSH DWORD WS_SIZEBOX|WS_VISIBLE
PUSH LPCTSTR szAppName
PUSH LPCTSTR szAppName
PUSH DWORD 0
CALL [CreateWindowExA]
MOV [hwnd1],EAX
MOV [hwnd0],EAX

PUSH LPVOID NULL
PUSH HINSTANCE [WindowClassStruc+WNDCLASS.hInstance]
PUSH HMENU NULL
PUSH HWND NULL
PUSH INTEGER [yScreen]
PUSH INTEGER [xScreen]
PUSH INTEGER 0
PUSH INTEGER 0
PUSH DWORD WS_POPUP
PUSH LPCTSTR szAppName
PUSH LPCTSTR szAppName
PUSH DWORD WS_EX_TOPMOST
CALL [CreateWindowExA]
MOV [hwnd2],EAX
; --------------------------------------------------------------------- Speedup
CALL PriorityGUI
; ------------------------------------------------------------------ Winmo init
CALL CreateBuffer
CALL Valami
MOV EDI,[vscreen]
ADD EDI,WIDTH*3*25
MOV ECX,WIDTH*3*50/4
SUB EAX,EAX
REP STOSD
; ------------------------------------------------------------------- Main Loop
mainloop:

MOV EDI,[vscreen]
MOV EAX,25
MUL DWORD [bytesperline]
ADD EDI,EAX
MOV ECX,50
.1:
MOV EBX,[bytesperline]
.2:
MOV EAX,[EDI]
ADD EAX,01010101H
STOSD
SUB EBX,4
JNZ .2
LOOP .1
CALL videoput
JMP mainloop
; ------------------------------------------------------------------------ Quit
quit:
CALL DeleteBuffer
PUSH INTEGER 0
CALL [ExitProcess]
; ----------------------------------------------------------------------- Paint
videoput:
CALL PriorityRT

PUSH DWORD client
PUSH HWND [hwnd0]
CALL [GetClientRect]

PUSH HWND [hwnd0]
CALL [GetDC]
MOV [hdc],EAX

PUSH DWORD SRCCOPY
PUSH UINT DIB_RGB_COLORS
PUSH DWORD [lpbi]
PUSH DWORD [vscreen]
PUSH INTEGER [height]
PUSH INTEGER [width]
PUSH INTEGER 0
PUSH INTEGER 0
PUSH INTEGER [client+RECT.bottom]
PUSH INTEGER [client+RECT.right]
PUSH INTEGER 0
PUSH INTEGER 0
PUSH HDC EAX
CALL [StretchDIBits]

PUSH HDC [hdc]
PUSH HWND [hwnd0]
CALL [ReleaseDC]

MOV EAX,[hwnd0]
CMP EAX,[hwnd1]
JNE .1
CALL PriorityGUI
.1:
; ---------------------------------------------------------------- Message Loop
messages:
PUSH UINT PM_REMOVE
PUSH UINT NULL
PUSH UINT NULL
PUSH HWND NULL
PUSH DWORD msg
CALL [PeekMessageA]
CMP EAX,FALSE
JE .return

CMP UINT [msg+MSG.message],WM_KEYDOWN
JE NEAR keydown
CMP UINT [msg+MSG.message],WM_SYSKEYDOWN
JE NEAR syskeydown

PUSH DWORD msg
CALL [DispatchMessageA]
JMP messages

.return:
RETN
; ------------------------------------------------------------------ WM_KEYDOWN
keydown:
CMP WPARAM [msg+MSG.wParam],VK_ESCAPE
JE NEAR quit
CMP WPARAM [msg+MSG.wParam],VK_ADD
JE NEAR double
CMP WPARAM [msg+MSG.wParam],VK_SUBTRACT
JNE NEAR messages

PUSH BOOL TRUE
MOV EAX,[border]
ADD EAX,EAX
MOV EDX,EAX
ADD EAX,[caption]
ADD EAX,[height]
PUSH INTEGER EAX
ADD EDX,[width]
PUSH INTEGER EDX
SUB EAX,[yScreen]
NEG EAX
SHR EAX,1
PUSH INTEGER EAX
SUB EDX,[xScreen]
NEG EDX
SHR EDX,1
PUSH INTEGER EDX
PUSH HWND [hwnd1]
CALL [MoveWindow]
JMP messages

double:
PUSH BOOL TRUE
MOV EAX,[border]
ADD EAX,[height]
ADD EAX,EAX
ADD EAX,[caption]
PUSH INTEGER EAX
MOV EDX,[border]
ADD EDX,[width]
ADD EDX,EDX
PUSH INTEGER EDX
SUB EAX,[yScreen]
NEG EAX
SHR EAX,1
PUSH INTEGER EAX
SUB EDX,[xScreen]
NEG EDX
SHR EDX,1
PUSH INTEGER EDX
PUSH HWND [hwnd1]
CALL [MoveWindow]
JMP messages
; --------------------------------------------------------------- WM_SYSKEYDOWN
syskeydown:
CMP WPARAM [msg+MSG.wParam],VK_RETURN
JNE NEAR messages

MOV EAX,[hwnd1]
CMP HWND [msg+MSG.hwnd],EAX
JE gui

CALL PriorityGUI

PUSH INTEGER SW_HIDE
PUSH HWND [hwnd2]
CALL [ShowWindow]
PUSH INTEGER SW_SHOWNORMAL
PUSH HWND [hwnd1]
CALL [ShowWindow]
PUSH BOOL TRUE
CALL [ShowCursor]

MOV EAX,[hwnd1]
MOV [hwnd0],EAX
JMP messages

gui:
PUSH BOOL FALSE
CALL [ShowCursor]
PUSH INTEGER SW_SHOWNORMAL
PUSH HWND [hwnd2]
CALL [ShowWindow]
PUSH INTEGER SW_HIDE
PUSH HWND [hwnd1]
CALL [ShowWindow]

MOV EAX,[hwnd2]
MOV [hwnd0],EAX

CALL PriorityRT
JMP messages
; ------------------------------------------------------------ Main Window Proc
MainWndProc:
PUSH EBP
MOV EBP,ESP
%DEFINE hwnd EBP+8
%DEFINE message EBP+12
%DEFINE wParam EBP+16
%DEFINE lParam EBP+20
; -------------------------------------------------------------- Switch Message
CMP UINT [message],WM_SYSCOMMAND
JE NEAR syscommand
CMP UINT [message],WM_NCHITTEST
JE NEAR hittest
; --------------------------------------------------------------------- Default
default:
PUSH LPARAM [lParam]
PUSH WPARAM [wParam]
PUSH UINT [message]
PUSH HWND [hwnd]
CALL [DefWindowProcA]
JMP return
; --------------------------------------------------------------- WM_SYSCOMMAND
syscommand:
MOV EAX,[wParam]
AND EAX,0xFFF0
CMP EAX,SC_CLOSE
JNE NEAR default
JMP break
; ---------------------------------------------------------------- WM_NCHITTEST
hittest:
MOV EAX,[hwnd1]
CMP HWND [hwnd],EAX
JNE NEAR default

PUSH DWORD client
PUSH HWND [hwnd]
CALL [GetWindowRect]

MOV EAX,[border]
ADD [client+RECT.left],EAX
ADD [client+RECT.top],EAX
SUB [client+RECT.right],EAX
SUB [client+RECT.bottom],EAX

MOVSX EAX,WORD [lParam]
CMP EAX,[client+RECT.left]
JL NEAR default
CMP EAX,[client+RECT.right]
JNL NEAR default
MOV EAX,[lParam]
SAR EAX,16
CMP EAX,[client+RECT.top]
JL NEAR default
CMP EAX,[client+RECT.bottom]
JNL NEAR default

MOV EAX,HTCAPTION
JMP return
; ----------------------------------------------------------------------- Break
break:
MOV EAX,FALSE
; ---------------------------------------------------------------------- Return
return:
POP EBP
RETN 16
; ------------------------------------------------------------------- Subrutins
PriorityGUI:
CALL [GetCurrentProcess]
PUSH DWORD HIGH_PRIORITY_CLASS
PUSH HANDLE EAX
CALL [SetPriorityClass]

CALL [GetCurrentThread]
PUSH INTEGER THREAD_PRIORITY_ABOVE_NORMAL
PUSH HANDLE EAX
CALL [SetThreadPriority]
RETN

PriorityRT:
CALL [GetCurrentProcess]
PUSH DWORD REALTIME_PRIORITY_CLASS
PUSH HANDLE EAX
CALL [SetPriorityClass]

CALL [GetCurrentThread]
PUSH INTEGER THREAD_PRIORITY_TIME_CRITICAL
PUSH HANDLE EAX
CALL [SetThreadPriority]
RETN

CreateBuffer:
MOV EAX,[width]
MOV [bmih+BITMAPINFOHEADER.biWidth],EAX
MOV EDX,[height]
NEG EDX
MOV [bmih+BITMAPINFOHEADER.biHeight],EDX
NEG EDX
MUL EDX
LEA EAX,[EAX*2+EAX]
MOV [bmih+BITMAPINFOHEADER.biSizeImage],EAX

ADD EAX,BITMAPINFOHEADER_size

PUSH DWORD EAX
PUSH UINT GMEM_FIXED
CALL [GlobalAlloc]
TEST EAX,EAX
JZ .return
MOV [lpbi],EAX

MOV ESI,bmih
MOV EDI,EAX
MOV ECX,BITMAPINFOHEADER_size / 4
REP MOVSD
MOV [vscreen],EDI

.return:
RETN

DeleteBuffer:
PUSH HGLOBAL [lpbi]
CALL [GlobalFree]
RETN

Valami:
MOV EDI,[vscreen]
MOV EAX,HEIGHT
.1:
OR AL,128
MOV ECX,WIDTH/2
.1a:
STOSB
STOSB
STOSB
NEG EAX
STOSB
STOSB
STOSB
NEG EAX
LOOP .1a
AND AL,127
DEC EAX
MOV ECX,WIDTH/2
.1b:
STOSB
STOSB
STOSB
NEG EAX
STOSB
STOSB
STOSB
NEG EAX
LOOP .1b
DEC EAX
JNZ .1
MOV EAX,0FF00H
MOV EDI,[vscreen]
MOV ECX,[width]
.2:
MOV [EDI],EAX
MOV [EDI+(HEIGHT-1)*WIDTH*3],EAX
ADD EDI,3
LOOP .2
MOV EDI,[vscreen]
MOV ECX,HEIGHT
.3:
MOV [EDI],EAX
MOV [EDI+(WIDTH-1)*3],EAX
ADD EDI,WIDTH*3
LOOP .3
RETN
; ==================================================== Initialised Data Section
ALIGN 4

width DD WIDTH
height DD HEIGHT

bytesperline DD WIDTH*3

WindowClassStruc:
ISTRUC WNDCLASS
AT WNDCLASS.style,         DD CS_VREDRAW|CS_HREDRAW
AT WNDCLASS.lpfnWndProc,   DD MainWndProc
AT WNDCLASS.cbClsExtra,    DD 0
AT WNDCLASS.cbWndExtra,    DD 0
AT WNDCLASS.hInstance,     DD 0
AT WNDCLASS.hIcon,         DD NULL
AT WNDCLASS.hCursor,       DD NULL
AT WNDCLASS.hbrBackground, DD NULL
AT WNDCLASS.lpszMenuName,  DD NULL
AT WNDCLASS.lpszClassName, DD szAppName
IEND

bmih:
ISTRUC BITMAPINFOHEADER
AT BITMAPINFOHEADER.biSize,          DD BITMAPINFOHEADER_size
AT BITMAPINFOHEADER.biWidth,         DD 0
AT BITMAPINFOHEADER.biHeight,        DD 0
AT BITMAPINFOHEADER.biPlanes,        DW 1
AT BITMAPINFOHEADER.biBitCount,      DW 24
AT BITMAPINFOHEADER.biCompression,   DD BI_RGB
AT BITMAPINFOHEADER.biSizeImage,     DD 0
AT BITMAPINFOHEADER.biXPelsPerMeter, DD 0
AT BITMAPINFOHEADER.biYPelsPerMeter, DD 0
AT BITMAPINFOHEADER.biClrUsed,       DD 0
AT BITMAPINFOHEADER.biClrImportant,  DD 0
IEND

szAppName DB "WINMO5",0

; ================================================== Uninitialised Data Section
ALIGNB 4

hwnd0 RESD 1
hdc RESD 1
hwnd1 RESD 1
hwnd2 RESD 1
xScreen RESD 1
yScreen RESD 1
border RESD 1
caption RESD 1
lpbi RESD 1
vscreen RESD 1
msg RESB MSG_size
client RESB RECT_size
