kolibrios-fun/programs/games/codemaster/include/system.inc
codemaster 13694b9ade Added 3 games for the New Year competition: Binary Master, Hang Programmer, Kolibri Puzzle
(Author: codemaster; initially sources are uploaded to SVN "as is" without modification)
### Redo r.5303 with correct letter case for auto-build machine ###

git-svn-id: svn://kolibrios.org@5305 a494cfbc-eb01-0410-851d-a64ba20cac60
2014-12-30 23:59:59 +00:00

956 lines
19 KiB
PHP

; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ????????????????? SYSTEM.INC ???????????????????
;;;;;;;;;;;;;;;;;;;;; IMPORT ;;;;;;;;;;;;;;;;;;;;;
; RVAs of dll names and tables, ending with 20
; zero bytes
macro library [names] {
forward dd 0,0,0,\
RVA names#_name, RVA names#_table
common dd 0,0,0,0,0
}
; DLL name + import RVA table. each table ends with 0.
; finally, import names. dw 0 is "ordinal" (N/A)
macro import name, [names] {
common
name#_name \ ; text DLL_name='DLL.DLL'
db `name#'.DLL', 0
name#_table: ; DLL_table:
forward
IF used !#names
!#names dd RVA _#names ; import name RVAs
macro names [p] \{ ; call with no
\common ; invoke prefix
pushr p
call [!#names]
\}
END IF
common dd 0 ; end
forward
IF used !#names
_#names dw 0 ; import names
db `names, 0 ; 'import'
END IF
}
;;;;;;;;;;;;;;;;;;;; IMPORTS ;;;;;;;;;;;;;;;;;;;;;
data import
library MSVCRT, KERNEL32, USER32, SHELL32,\
GDI32, COMDLG32
import MSVCRT, sprintf
import KERNEL32,\
ExitProcess, GetCommandLineA,\
HeapCreate, HeapAlloc, HeapReAlloc, HeapSize,\
HeapFree, HeapDestroy, VirtualAlloc, VirtualFree,\
GetModuleHandleA, GetModuleFileNameA,\
CreateFileA, GetFileSize, ReadFile, WriteFile,\
SetFilePointer, CloseHandle, CopyFileA,\
MoveFileA, DeleteFileA, GetTickCount,\
GetSystemTime, GetLocalTime, GetFileTime,\
FileTimeToSystemTime, SystemTimeToFileTime,\
FileTimeToLocalFileTime,\
SystemTimeToTzSpecificLocalTime,\
GetFileAttributesExA, CompareFileTimeA,\
GetCurrentDirectoryA, SetCurrentDirectoryA,\
CreateDirectoryA, LoadLibraryA, FreeLibrary,\
GetProcAddress, FindFirstFileA, FindNextFileA,\
FindClose, WaitForSingleObject, Sleep
import USER32,\
GetDC, ReleaseDC,\
MessageBoxA, RegisterClassExA, CreateWindowExA,\
DestroyWindow, ShowWindow, MoveWindow,\
UpdateWindow, GetMessageA, PeekMessageA,\
TranslateMessage, DispatchMessageA,\
SendMessageA, DefWindowProcA, PostQuitMessage,\
WaitMessage, GetAsyncKeyState, LoadImageA,\
LoadIconA, LoadCursorA, SetCursor, ShowCursor,\
SetCursorPos, OpenClipboard, SetClipboardData,\
IsClipboardFormatAvailable, GetClipboardData,\
CloseClipboard, EmptyClipboard,\
GetSystemMetrics, BeginPaint, EndPaint,\
FillRect, InvalidateRect, SetTimer
import SHELL32, ShellExecuteA, ShellExecuteExA
import GDI32, SelectObject, DeleteObject,\
GetObjectA, DeleteDC, TextOutA, CreateFontA,\
CreateFontIndirectA, SetDIBits, BitBlt, StretchBlt,\
CreateBitmap, CreateCompatibleDC
import COMDLG32, GetOpenFileNameA,\
GetSaveFileNameA, ChooseColorA, ChooseFontA
END data
;;;;;;;;;;;;;;;;;;;;; SYSTEM ;;;;;;;;;;;;;;;;;;;;;
align
void @module, @heap
void directory, file.name, command.line
?t equ directory
;;;;;;;;;;;;;;;;;;;; MINIMAL ;;;;;;;;;;;;;;;;;;;;;
; say t - display message
; say t, m - title and message
; say.n n - number
; examples:
; say 'Hi'
; say name
; say.n 123
macro os.say t, m { MessageBoxA 0, m, t, 0 }
macro os.ask q, t { MessageBoxA, 0, q, t, 3 }
function _say, t, m
os.say t, m
endf
macro say a, b {
pusha
IF a eqtype ''
make.txt r0, a
ELSE
. r0=a
END IF
IF b eq
_say r0, r0
ELSE
IF b eqtype ''
make.txt r2, b
ELSE
. r2=b
END IF
_say r2, r0
END IF
popa
}
function say.n, n
locale t(32)
pusha
. r1=&t
u2t n, r1
. r1=&t
_say r1, r1
popa
endf
function say.h, n
locale t(32)
pusha
. r1=&t
h2t n, r1
. r1=&t
_say r1, r1
popa
endf
function say.b, n
locale t(32)
pusha
. r1=&t
b2t n, r1
. r1=&t
_say r1, r1
popa
endf
macro sayz t {
say ?LITERALS+?literals.i
?literal t
}
macro ask q, t { os.ask q, t }
macro cinvoke proc,[arg]
{ common
size@ccall = 0
IF ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
END IF
call [proc]
IF size@ccall
add esp,size@ccall
END IF }
macro sprintf t, f, [p] {
common
cinvoke !sprintf, t, f, p
}
;;;;;;;;;;;;;;;;;;;;; DEBUG ;;;;;;;;;;;;;;;;;;;;;;
bug.t db 'BUG', 0
macro bug { say bug.t }
macro bug.x t {
log t
execute log.file
exit
}
macro BUG { db 0CCh } ; int3 breakpoint
;;;;;;;;;;;;;;;;;;;; MEMORY ;;;;;;;;;;;;;;;;;;;;;;
macro os.memory
{ get @heap=HeapCreate 0, 0, 0 }
macro os.allocate n { HeapAlloc @heap, 0, n }
macro os.reallocate p, n
{ HeapReAlloc @heap, 0, p, n }
macro os.destroy p { HeapFree @heap, 0, p }
;;;;;;;;;;;;;;; ALLOCATE, DESTROY ;;;;;;;;;;;;;;;;
; allocate n
; allocate.p &p, n
; destroy &p
; example: try p=allocate 4*KB
function allocate, n
os.allocate n
endf
function allocate.p, p, n
if p=0
allocate n
return
end
os.reallocate p, n
endf
function destroy, p
if p
os.destroy p
end
endf
macro destroy [p] { forward destroy p }
;;;;;;;;;;;;;;;;;;;;; TIME ;;;;;;;;;;;;;;;;;;;;;;;
FILE.TIME fix u64
macro os.get.time {
GetLocalTime local.time
update.time local.time
}
function os.delay, ms
locals start
get start=GetTickCount
@@:
GetTickCount
. r1=start, r1+ms
cmp r0, r1
jb @b
endf
get.clock fix GetTickCount
;;;;;;;;;;;;;;;;;;;;; RANDOM ;;;;;;;;;;;;;;;;;;;;;
align integer @seed
; generate unique random number: 0-n
; seed=(seed*343FDh)+269EC3h
; seed=((seed>>16)&7FFFh)/(n+1)
function random, n
. r0=@seed
if false ; initialize seed
rdtsc ; read date/time stamp counter
. @seed=r0
end
. r0*343FDh, r0+269EC3h,\
@seed=r0, r0>>16, r0&7FFFh,\
r1=n, r1+1, r0/r1, r0=r2
endf
; random(from-to-2)+from
function random.x, from, to
. r0=from, r0-to, r0-2
random r0
. r0+from
endf
;;;;;;;;;;;;;;;;;;; FILE I/O ;;;;;;;;;;;;;;;;;;;;;
numeric EOF=-1,\
CREATE_NEW=1, CREATE_ALWAYS, OPEN_EXISTING,\
OPEN_ALWAYS, TRUNCATE_EXISTING,\
GENERIC_READ=80000000h, GENERIC_WRITE=40000000h,\
FILE_SHARE_READ=1, FILE_SHARE_WRITE,\
FILE_ATTRIBUTE_NORMAL=80h,\
SEEK.BEGIN=0, SEEK.SET, SEEK.END
;;;;;;;;;;;;;;;;; CURRENT FILE ;;;;;;;;;;;;;;;;;;;
align
void file.p ; pointer for load/save
integer file.h,\ ; handle
file.n64, file.n ; size 64:32
integer tmp.rw
macro flush { destroy file.p }
; return handle or -1 if error
function os.create.file, file, access, share,\
security, action, attributes, template
call !text.copy, file.name, file
CreateFileA file.name, access, share,\
security, action, attributes, template
. file.h=r0
endf
macro os.open file {
os.create.file file, GENERIC_READ \
or GENERIC_WRITE, FILE_SHARE_READ,\
0, OPEN_EXISTING, 0, 0
}
macro os.create file {
os.create.file file, GENERIC_WRITE,\
0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
}
macro os.seek n, r
{ SetFilePointer file.h, n, 0, r }
macro os.read p, n {
. r0=&tmp.rw
ReadFile file.h, p, n, r0, 0
}
macro os.write p, n {
. r0=&tmp.rw
WriteFile file.h, p, n, r0, 0
}
macro os.get.file.size { GetFileSize file.h, 0 }
macro os.close { CloseHandle file.h }
;;;;;;;;;;;;;;; COPY, MOVE, DELETE ;;;;;;;;;;;;;;;
macro copy.file a, b, r { CopyFileA a, b, r }
macro move.file a, b { MoveFileA a, b }
macro delete.file f { DeleteFileA f }
macro rename.file a, b { os.move.file a, b }
;;;;;;;;;;;;;;;;;; DIRECTORIES ;;;;;;;;;;;;;;;;;;;
macro os.get.directory
{ GetCurrentDirectoryA 256, directory }
macro os.set.directory f
{ SetCurrentDirectoryA f }
macro os.create.directory f
{ CreateDirectoryA f, 0 }
macro os.get.file.name
{ GetModuleFileNameA 0, directory, 1*KB }
macro os.get.command.line { GetCommandLineA }
;;;;;;;;;;;;;;;;;;;; EXECUTE ;;;;;;;;;;;;;;;;;;;;;
macro execute file
{ ShellExecuteA 0, 0, file, 0, 0, 3 }
;;;;;;;;;;;;;;;;;; FIND FILES ;;;;;;;;;;;;;;;;;;;;
macro os.find.data {
BLOCK find.data(338) ; WIN32_FIND_DATA
os.found.file equ find.data+44
}
macro os.find.first file
{ FindFirstFileA file, find.data }
macro os.find.next
{ FindNextFileA find.data.h, find.data }
macro os.find.end { FindClose find.data.h }
;;;;;;;;;;;;;;;;;;;;; REDRAW ;;;;;;;;;;;;;;;;;;;;;
macro create.blank.screen w, h {
create.vga os.w, os.h, WHITE ; 0
create.blank.window w, h
}
macro redraw {
calle draw
}
macro render b {
; call !clear.screen
IF b eq
redraw
END IF
IF used cursor
call !draw.cursor, cursor
END IF
IF b eq
call !show.vga
ELSE
copy.box box, b
call !show.vga.box
END IF
}
;;;;;;;;;;;;;;;;;;;; WINDOZE ;;;;;;;;;;;;;;;;;;;;;
macro POINT [a] { a: integer a#.x, a#.y }
macro RECT [a] { a: integer a#.left,\
a#.top, a#.right, a#.bottom }
macro MSG [a] {
a: integer a#.hwnd, a#.message,\
a#.wParam, a#.lParam, a#.time
POINT a#.pt
}
macro WNDCLASSEX [a] {
a: integer a#.cbSize=48,\
a#.style, a#.lpfnWndProc, a#.cbClsExtra,\
a#.cbWndExtra, a#.hInstance, a#.hIcon,\
a#.hCursor, a#.hbrBackground,\
a#.lpszMenuName, a#.lpszClassName, a#.hIconSm
WNDCLASSEX.$=$-a
}
macro PAINTSTRUCT [a] {
a: integer a#.hdc, a#.fErase
RECT a#.rcPaint
integer a#.fRestore, a#.fIncUpdate
text a#.rgbReserved(32)
}
macro BITMAP [a] {
a: integer a#.bmType,\
a#.bmWidth, a#.bmHeight, a#.bmWidthBytes
short a#.bmPlanes, a#.bmBitsPixel
void a#.bmBits
BITMAP.$=$-a
}
macro BITMAPINFOHEADER [a] {
a: integer a#.biSize, a#.biWidth, a#.biHeight
short a#.biPlanes, a#.biBitCount
integer a#.biCompression, a#.biSizeImage,\
a#.biXPelsPerMeter, a#.biYPelsPerMeter,\
a#.biClrUsed, a#.biClrImportant
BITMAPINFOHEADER.$=$-a
}
macro BITMAPINFO [a] {
BITMAPINFOHEADER a
integer bmiColors
BITMAPINFO.$=BITMAPINFOHEADER.$+4
}
; window messages
numeric WM_*, \
CREATE=1, DESTROY=2, MOVE=3, SIZE=5,\
SETFOCUS=7, KILLFOCUS=8, GETTEXT=0Dh,\
SETTEXT=0Ch, GETTEXTLENGTH=0Eh,\
PAINT=0Fh, CLOSE=10h, QUIT=12h, CUT=300h,\
COPY=301h, PASTE=302h, CLEAR=303h,\
SETFONT=30h, COMMAND=111h, TIMER=0113h
; window styles
numeric WS_*, \
POPUP=80000000h, MINIMIZE=20000000h,\
VISIBLE=10000000h, MAXIMIZE=1000000h,\
CAPTION=0C00000h, BORDER=800000h,\
DLGFRAME=400000h, VSCROLL=200000h,\
HSCROLL=100000h, SYSMENU=80000h,\
THICKFRAME=40000h, MINIMIZEBOX=20000h,\
MAXIMIZEBOX=10000h
WS_BLANK = WS_VISIBLE+WS_POPUP
WS_DEFAULT = WS_VISIBLE+WS_CAPTION+\
WS_MINIMIZEBOX+WS_SYSMENU
CS_DBLCLKS=8
; keyboard+mouse messages
numeric WM_*,\
KEYDOWN=100h, KEYUP, CHAR, DEADCHAR,\
SYSKEYDOWN, SYSKEYUP, SYSCHAR
numeric WM_*,\
MOUSEMOVE=200h, LBUTTONDOWN, LBUTTONUP,\
LBUTTONDBLCLK, RBUTTONDOWN, RBUTTONUP,\
RBUTTONDBLCLK, MBUTTONDOWN, MBUTTONUP,\
MBUTTONDBLCLK, MOUSEWHEEL
; virtual key codes. function keys=(6Fh+N).
; example: F1=70h (6Fh+1)
numeric K.*,\
FUNCTION=6Fh, LEFT=25h, UP=26h, RIGHT=27h,\
DOWN=28h, ESCAPE=1Bh, SPACE=20h, DELETE=2Eh,\
CONTROL=11h, LCONTROL=0A2h, RCONTROL=0A3h,\
LALT=0A4h, RALT=0A5h, BACK=8, TAB=9,\
RETURN=0Dh, END=23h, HOME=24h,\
A='A', S='S', D='D', W='W'
SRCCOPY=00CC0020h
macro os.show.cursor { ShowCursor 1 }
;;;;;;;;;;;;;;;;;;;;; SYSTEM ;;;;;;;;;;;;;;;;;;;;;
align
integer os.w, os.h, os.bpp
void _hwnd ; handle
void _dc ; device context
void _mdc ; memory dc
WNDCLASSEX _wc ; window
MSG _wm ; message
PAINTSTRUCT _ps ; for PAINT
BITMAP _bm ; for draw.bitmap.w
void vga.hbm
BITMAPINFO vga.bmi
RECT vga.rect
text _cn='WC', _wt='' ; classname, title
;;;;;;;;;;;;;;;;; CREATE WINDOW ;;;;;;;;;;;;;;;;;;
function create.window.x, style, procedure,\
w, h, title, class.name
locals x, y
. _wc.cbSize=WNDCLASSEX.$
. _wc.hInstance=@module
. _wc.lpfnWndProc=procedure
. _wc.lpszClassName=class.name
. _wc.style=CS_DBLCLKS, _wc.hbrBackground=8
get _wc.hIcon=LoadIconA 0, 7F00h
get _wc.hCursor=LoadCursorA 0, 7F00h
try RegisterClassExA _wc
. r0=os.w, r0>>1, r2=w, r2>>1, r0-r2, x=r0
. r0=os.h, r0>>1, r2=h, r2>>1, r0-r2, y=r0
try _hwnd=CreateWindowExA 0, class.name,\
title, style, x, y, w, h, 0, 0, @module, 0
endf 1
macro create.blank.window w, h {
create.window.x WS_BLANK, !_window.procedure,\
w, h, _wt, _wc
}
macro create.default.window title {
create.window.x WS_DEFAULT, !_window.procedure,\
os.w, os.h, title, _wc
}
;;;;;;;;;;;;;;;;;; MESSAGE LOOP ;;;;;;;;;;;;;;;;;;
macro begin.message.loop {
.begin.ml:
GetMessageA _wm, 0, 0, 0
fail .end.ml
TranslateMessage _wm
DispatchMessageA _wm
}
macro end.message.loop {
go .begin.ml
.end.ml:
. r0=_wm.wParam
}
macro message.loop {
begin.message.loop
end.message.loop
}
macro process.messages {
.begin.ml:
PeekMessageA _wm, 0, 0, 0, 0
fail .no.message
GetMessageA _wm, 0, 0, 0
fail .end.ml
TranslateMessage _wm
DispatchMessageA _wm
go .begin.ml
.no.message:
}
macro end.messages {
go .begin.ml
.end.ml:
ExitProcess _wm.wParam
}
macro minimize.window { ShowWindow _hwnd, 6 }
;;;;;;;;;;;;;;;;;;;;;; INPUT ;;;;;;;;;;;;;;;;;;;;;
align 4
integer event.id, key.event, mouse.event,\
key, any.key, key.c, exit.if.esc=YES,\
mouse.1, mouse.2, mouse.x, mouse.y,\
mouse.px, mouse.py, mouse.double, mouse.wheel,\
mouse.drag, mouse.drag.x, mouse.drag.y,\
mouse.drop, mouse.drop.x, mouse.drop.y
macro os.key.state k { GetAsyncKeyState k }
macro os.set.cursor.xy x, y
{ SetCursorPos x, y }
function key.state, k
os.key.state k
endf
; if key state
macro if.key k { !if key.state K.#k }
macro if.not.keys k { !if.n key.state K.#k }
function select.box, box
. r0=mouse.x, r1=mouse.y
IF defined cursor
. r0+cursor.spot.x, r1+cursor.spot.y
END IF
call !point.inside, box, r0, r1
endf
macro if.select box { !if select.box, box }
macro else.if.select box
{ !else.if select.box, box }
macro if.not.select box
{ !if.n select.box, box }
macro if.click box {
select.box box
and r0, mouse.1
if true
}
;;;;;;;;;;;;;;;;;;;;; EVENTS ;;;;;;;;;;;;;;;;;;;;;
align
void !_on.event, !on.main,\
!_on.create, !_on.destroy, !_on.close,\
!_on.draw, !_on.game, !_on.command,\
!_on.key, !_on.mouse, !_on.timer, !_on.exit
macro define.events [e]
{ mov [!!_on.#e], !on.#e }
macro calle e {
if dword [!!_on.#e]
call dword [!!_on.#e]
end
}
!call fix calle
macro !on name { function on.#name }
macro !end { endf 1 }
;;;;;;;;;;;;;;;;;;;;; TIMER ;;;;;;;;;;;;;;;;;;;;;;
macro os.set.timer f, ms
{ SetTimer _hwnd, 1, ms, f }
macro set.timer a, b {
IF b eq
os.set.timer !on.timer, a
ELSE
os.set.timer a, b
END IF
}
;;;;;;;;;;;;;;;; WINDOW PROCEDURE ;;;;;;;;;;;;;;;;
function _window.procedure, window, message, wp, lp
alias m=r0
. m=message, event.id=0, mouse.double=0
if m=WM_PAINT
get _dc=BeginPaint _hwnd, _ps
render
EndPaint _hwnd, _ps
go .default
else.if m=WM_COMMAND
calle command
else.if m=WM_KEYDOWN
. key=wp, event.id='k', key.event='k'
if exit.if.esc
if wp=K.ESCAPE
SendMessageA window, WM_DESTROY, 0, 0
end
end
.key:
calle key
return 0
else.if m=WM_KEYUP
. key=NO, event.id='k', key.event='r'
go .key
else.if m=WM_CHAR
. key=wp, event.id='k', key.event='c'
go .key
else.if m=WM_MOUSEMOVE
. mouse.event='m'
if mouse.1
if not mouse.drag
. mouse.drag=YES,\
mouse.drag.x=mouse.x,\
mouse.drag.y=mouse.y
end
end
.mouse:
. event.id='m', r0=lp, r1=r0,\
r0&0FFFFh, mouse.x=r0,\
r1>>16, r1&0FFFFh, mouse.y=r1
calle mouse
if mouse.event='m'
. mouse.px=mouse.x,\
mouse.py=mouse.y
end
return 0
else.if m=WM_LBUTTONDOWN
. mouse.event='c', mouse.1=YES,\
mouse.drop=NO
go .mouse
else.if m=WM_LBUTTONUP
. mouse.event='r', mouse.1=NO
if mouse.drag
. mouse.drop=YES,\
mouse.drop.x=mouse.x,\
mouse.drop.y=mouse.y,\
mouse.drag=NO
end
go .mouse
else.if m=WM_LBUTTONDBLCLK
. mouse.double=YES
go .mouse
else.if m=WM_RBUTTONDOWN
. mouse.event='rc', mouse.2=YES
go .mouse
else.if m=WM_RBUTTONUP
. mouse.event='rr', mouse.2=NO
go .mouse
else.if m=WM_MOUSEWHEEL
. mouse.event='w', r1=wp,\
r1>>16, mouse.wheel=r1
go .mouse
else.if m=WM_CREATE
calle create
go .default
else.if m=WM_DESTROY
.destroy:
calle destroy
PostQuitMessage 0
end
.default: DefWindowProcA \
window, message, wp, lp
endf
;;;;;;;;;;;;;;; LOAD/DRAW H/BITMAP ;;;;;;;;;;;;;;;
function load.bitmap.w, file
locals p
try p=LoadImageA @module, file, 0, 0, 0, 10h
GetObjectA p, BITMAP.$, _bm
endf p
function draw.bitmap.w, hbmp, x, y, w, h
locals bmw, bmh
GetObjectA hbmp, BITMAP.$, _bm
. bmw=_bm.bmWidth, bmh=_bm.bmHeight
get _mdc=CreateCompatibleDC _dc
SelectObject _mdc, hbmp
StretchBlt _dc, x, y, w, h,\
_mdc, 0, 0, bmw, bmh, SRCCOPY
DeleteDC _mdc
endf
;;;;;;;;;;;;;;;;;;;;;; VGA ;;;;;;;;;;;;;;;;;;;;;;;
macro os.get.screen.w
{ get os.w=GetSystemMetrics 0 }
macro os.get.screen.h
{ get os.h=GetSystemMetrics 1 }
function os.create.vga, w, h
alias p=r0, x=r1
; set.screen screen.w, screen.h, screen.bpp
try vga.hbm=CreateBitmap \
screen.w, screen.h, 32, 1, vga.p
memory.zero vga.bmi, BITMAPINFOHEADER.$
. vga.bmi.biSize=BITMAPINFOHEADER.$
. vga.bmi.biWidth=screen.w
. x=screen.h, neg x, vga.bmi.biHeight=x
. vga.bmi.biPlanes=1, vga.bmi.biBitCount=32
endf
function os.show.vga
SetDIBits _dc, vga.hbm, 0, screen.h,\
vga.p, vga.bmi, 0
draw.bitmap.w vga.hbm, 0, 0, screen.w, screen.h
. vga.rect.left=0, vga.rect.top=0,\
vga.rect.right=screen.w,\
vga.rect.bottom=screen.h
InvalidateRect _hwnd, vga.rect, 0
endf
function show.vga.box
SetDIBits _dc, vga.hbm, 0, screen.h,\
vga.p, vga.bmi, 0
draw.bitmap.w vga.hbm,\
box.x, box.y, box.w, box.y
. r0=box.x, r1=box.y,\
vga.rect.left=r0, vga.rect.top=r1,\
r0+box.w, vga.rect.right=r0,\
r1+box.h, vga.rect.bottom=r1
InvalidateRect _hwnd, vga.rect, 0
endf
macro show.vga.box b {
IF ~b eq
copy.box box, b
END IF
show.vga.box
}
macro define.vga { os.define.vga }
; create vga/buffer for drawing
function create.vga, w, h, c
if vga.p=0, r0=w, r0*h, r0<<2
try vga.p=allocate r0
end
call !clear.screen, c
os.create.vga w, h
endf 1
function show.vga
os.show.vga
endf
function set.vga, w, h
os.set.vga
endf
function end.vga
destroy vga
os.end.vga
endf
;;;;;;;;;;;;;;;;;; ENTER+EXIT ;;;;;;;;;;;;;;;;;;;;
; user-defined enter/exit routines will be called
; if defined/nonzero
function os.enter
try @module=GetModuleHandleA 0
try @heap=HeapCreate 0, 0, 0
try directory=allocate 1*KB
. r0=directory, *r0=0
try file.name=allocate 1*KB
. r0=file.name, *r0=0
os.get.directory
os.get.command.line
. command.line=r0
endf 1
function exit
ExitProcess 0
endf
;;;;;;;;;;;;; EXECUTABLE STRUCTURE ;;;;;;;;;;;;;;;
align
section '.one' \
code readable writable executable
!main:
os.enter
if false
say 'System error'
exit
end
call !main!
exit
ret
function main!
os.get.screen.w
os.get.screen.h
set.screen WINDOW.W, WINDOW.H, 32
try create.vga screen.w, screen.h, BLACK
define.events create, draw, key, mouse
create.blank.window screen.w, screen.h
os.show.cursor
message.loop
endf
align