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
This commit is contained in:
codemaster 2014-12-30 23:59:59 +00:00
parent 87bffa6c6d
commit 13694b9ade
68 changed files with 7713 additions and 0 deletions

View File

@ -0,0 +1,39 @@
3 GAMES FOR KOLIBRI (AND WINDOWS)
Binary Master: Fun game for programmers.
Practice binary arithmetic.
Hang Programmer: Teaches English words/phrases
related to programming
Puzzle Challenge: Custom game for Kolibri.
Tests your visual attention to fine details.
If you solve the puzzle, lines will disappear
and there will be a message. Look close into
the clouds and direction of lights.
Written in FASM(1) macros, Abakis advanced language
+ library, 7,000+ lines, custom graphics and fonts.
Spent the most time on this library.
* Created by codemaster (codemazt3r@gmail.com)
* Educational games made specifically for programmers.
* Very clear professional style, good examples
for the community.
* First portable games written in FASM. Assembles
on/for both Kolibri and Windows with the same
source just by changing the first 1-2 lines
in A.INC. Allows programmers to create games
_for_Kolibri_ on Windows
* 24-27 years of programming experience,
recreationally in my freetime. Made 1,000s of
programs, given 100s of examples away for free
while poor. Never been paid.
Thanks. Happy new years!
===========================================================
(1) FASM is the abbreviation for Flat ASseMbler, open-source
assembly language being developed by Tomasz Grysztar.
FASM is available for Windows, DOS, Linux and KolibriOS.
You can download FASM from: http://www.flatassembler.net/

View File

@ -0,0 +1,47 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; ************** STAR^2 SOFTWARE *****************
; ????????????????????????????????????????????????
; true portability: windows + kolibri
; define cpu intel windows
define cpu intel kolibri
; define cpu arm mobile
; current directory. optional '/usbhd0/1'
; prefix to assemble+run from SD in kolibri
CD fix ''
; CD fix '/usbhd0/1'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MAIN.ICON fix ''
SCREEN.W = WINDOW.W ; 1024
SCREEN.H = WINDOW.H ; 768-32
SCREEN.BPP = 32
SCREEN.PI = SCREEN.W*(SCREEN.BPP/8)
match x =windows, cpu {
format PE GUI 4.0
entry !main
stack 8*KB
heap 16*KB
include CD#'/include/a.inc'
WINDOW.X=0
WINDOW.Y=0
}
match x =kolibri, cpu {
format binary as ""
use32
org 0
db 'MENUET01'
dd 1, !main, end.code,\
4*MB, 32*KB, 0, 0
postpone \{ end.code: \}
include CD#'/include/a.inc'
WINDOW.X=(1024/2)-(WINDOW.W/2)
WINDOW.Y=(768/2)-(WINDOW.H/2)
}

View File

@ -0,0 +1,299 @@
; BINARY MASTER
WINDOW.W=360
WINDOW.H=492
include 'a.inc'
text t(256), title.t='Binary Master: %hh'
text help.t=+\
'Fun Game for Programmers.' RET\
'Click BITs. Count in binary.' RET\
'Match the decimal number' RET\
'in the red box to make rows' RET\
'disappear. Press any key.' RET\
'r=Reset. p=Pause. Esc=exit'
text pause.t=+\
'Paused. Press p to continue' RET\
'or r=Reset. Esc=exit'
text game.over.t=+\
'Game over. Score: %hh.' RET\
'Press any key'
align
integer scene, score
numeric SCENE.*, TITLE, PLAY,\
PAUSE, GAME.OVER
numeric EASY=5000, NORMAL=4000, HARD=2000
BOX board, my.box
integer my.n, red.n, magic.n=10101101b
integer cbit.x, cbit.y, bits.h
numeric BIT.*, W=32, H=48
text my.numbers(8+4), red.numbers(8+4)
FONT main.font='font'
IMAGE bits.i='bits', bit1.i='1',\
bit0.i='0', close.i='x'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function random.byte
locals n
.r:
random 3
if r0<2
random 16
else.if r0=2
random 128
else.if r0=3
random 255
end
. n=r0
text.find red.numbers, n
if true, go .r, end
. r0=n
if false, r0++, end
endf
function reset.game
locals n, p
. score=0, bits.h=1
memory.zero my.numbers, 12
memory.zero red.numbers, 12
. n=8, p=red.numbers
loop n
random.byte
. r1=p, *r1++=r0, p=r1
endl
set.box board, 4, 70, BIT.W*8, BIT.H*8
. scene=SCENE.TITLE
endf
function on.create
set.font main.font
set.timer NORMAL
reset.game
endf
function remove.byte, t, i
locals n
alias p=r0, q=r1, x=r2
if i=7, go .new, end
. p=t, p+i, q=p, q++, x=7, x-i, n=x
loop n, *p++=*q++, endl
.new:
. p=my.numbers, *(p+7)=0
random.byte
. q=red.numbers, *(q+7)=r0
endf
function remove.row, i
remove.byte my.numbers, i
remove.byte red.numbers, i
. bits.h--
if bits.h<1, bits.h=1, end
endf
function check.numbers
locals i
. i=0
while i<8, r0=my.numbers, r0+i
. r1=*r0, r0=red.numbers
. r0+i, r2=*r0
if r1=r2, score+r1
remove.row i
return 1
end
. i++
endw
endf 0
function draw.board
locals i, n, x, y, w, h
draw.image bits.i, 4, 35
draw.image bits.i, 4, 457
. x=0, y=0, w=32, h=48
while y<8, x=0
while x<8
. r0=x, r0*w, r0+board.x
. r1=y, r1*h, r1+board.y
set.box my.box, r0, r1, w, h
draw.box my.box, BLACK, GRAY
. x++
endw
. r0=x, r0*w, r0+board.x
. r1=y, r1*h, r1+board.y
set.box my.box, r0, r1, 48, h
draw.box.o my.box, WHITE
. my.box.x+48
draw.box.o my.box, RED
. r0=y, r1=8, r1-bits.h
if r0>=r1
. r0=my.numbers, r1=y, r2=8
. r2-bits.h, r1-r2, r0+r1
. r1=*r0, my.n=r1
. r0=red.numbers, r1=y, r2=8
. r2-bits.h, r1-r2, r0+r1
. r1=*r0, red.n=r1
u2t my.n, t
. my.box.x-40, my.box.y+11
draw.text t, my.box.x, my.box.y
. my.box.x+44
u2t red.n, t
draw.text t, my.box.x, my.box.y
end
. y++
endw
endf
function draw.bit, n, x, y
if n
draw.image bit1.i, x, y
else
draw.image bit0.i, x, y
end
endf
function draw.byte, n, x, y
locals i
. i=8
loop i, r0=n, r1=i, r1--, r0>>cl, r0&1
draw.bit r0, x, y
. x+BIT.W
endl
endf
function draw.my.numbers
locals i, n, y
. i=bits.h, y=404
loop i, r0=my.numbers, r0+i, r0--
. r0=*r0, n=r0
draw.byte n, 4, y
. y-BIT.H
endl
endf
function draw.title.scene
draw.text help.t, 16, 130
draw.byte magic.n, 50, 300
endf
function draw.play.scene
draw.board
draw.my.numbers
endf
function draw.pause.scene
draw.text pause.t, 16, 130
draw.byte magic.n, 50, 300
endf
function draw.game.over
print t, game.over.t, score
draw.text t, 44, 170
draw.byte magic.n, 50, 300
endf
function on.draw
locals x, y, w, h
clear.screen BLACK
print t, title.t, score
draw.text t, 4, 4
draw.image close.i, 324, 4
. r0=screen.w, r0--
. r1=screen.h, r1--
draw.outline 0, 0, r0, r1, GRAY
if scene=SCENE.TITLE
draw.title.scene
else.if scene=SCENE.PLAY
draw.play.scene
else.if scene=SCENE.PAUSE
draw.pause.scene
else.if scene=SCENE.GAME.OVER
draw.game.over
end
endf
function on.key
if key.event='c'
if scene=SCENE.TITLE
. scene=SCENE.PLAY
go .draw
end
if scene=SCENE.GAME.OVER
go .reset
end
if key='r'
.reset:
reset.game
go .draw
end
if key='p'
.pause:
if scene=SCENE.PLAY
. scene=SCENE.PAUSE
else.if scene=SCENE.PAUSE
. scene=SCENE.PLAY
end
go .draw
end
.draw:
render
end
endf
function on.mouse
if.select board
. r0=mouse.x, r0-WINDOW.X, r0-board.x
. r1=BIT.W, r0/r1, cbit.x=r0
. r0=mouse.y, r0-WINDOW.Y, r0-board.y
. r1=BIT.H, r0/r1, cbit.y=r0
if mouse.event='c'
. r0=cbit.y, r1=8, r1-bits.h
if r0>=r1, r0=my.numbers, r1=cbit.y
. r2=8, r2-bits.h, r1-r2, r0+r1
. r3=*r0, r2=1, r1=7, r1-cbit.x
. r2<<cl, r3><r2, *r0=r3
end
end
end
if mouse.event='r'
check.numbers
go .draw
end
if mouse.event='c'
. r0=&close.i.x
if.select r0
exit
end
if scene<>SCENE.PLAY
reset.game
. scene=SCENE.PLAY
end
.draw:
render
end
endf
function on.timer
if scene<>SCENE.PLAY
return
end
if mouse.1, return, end
if bits.h<8, bits.h++
else
. scene=SCENE.GAME.OVER
end
render
endf
function on.exit
; ...
endf

View File

@ -0,0 +1,392 @@
; HANG PROGRAMMER
WINDOW.W=720
WINDOW.H=512
include 'a.inc'
include 'include/words.txt'
text title.t(32)='Hang Programmer'
text t(256), t2(256)
integer scene
numeric SCENE.*, TITLE, PLAY, GAME.OVER
integer guesses, word.index
BOX my.box
text word.t(64), used.letters(16)
align
IMAGE8 \
board.i='board', logo.i='logo',\
stand1.i='stand1', stand2.i='stand2',\
head.i='head', body.i='body',\
arm1.i='arm1', arm2.i='arm2',\
leg1.i='leg1', leg2.i='leg2',\
smile.i='smile', money.i='money',\
prize.i='1000'
IMAGE close.i='x'
text abc='ABCDEFGHIJKLM', xyz='NOPQRSTUVWXYZ'
text help.t='CLICK TO START',\
winner.t='WINNER', looser.t='LOOSER'
text example.t='DYNAMIC BINARY TRANSLATION'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function reset.game
. guesses=0
text.zero used.letters
text.zero word.t
. r0=word.index, r0*4, r0+words.pa
. (u32) r0=*r0
text.copy word.t, r0
. word.index++
if word.index>=(N.WORDS-1)
. word.index=0
end
endf
; exchange pointer array elements.
; words.pa[a] and [b]
function exchange.words, a, b
alias pa=r0, i=r0, p=r1, q=r2, x=r3
. pa=words.pa
. p=a, p*4, p+pa, q=b, q*4, q+pa
. (u32) i=*p, (u32) x=*q
. (u32) *p=x, (u32) *q=i
endf
; do this once when game begins.
; initialize pointer array to words[0-n]
; then randomize indices
function initialize
locals i, n, j
alias p=r0, x=r1
. p=words.pa, i=0, n=N.WORDS
loop n, x=i, (u32) x=*(words.ta+r1*4)
. (u32) *p++=x, i++
endl
. i=N.WORDS
loop i
get j=random (N.WORDS-1)
exchange.words i, j
endl
. word.index=0 ; random (N.WORDS-1)
endf
; is winner? if all characters in
; word.t have been used. return
; winner.t/looser.t
function is.winner
locals i, q, n, win
alias p=r0, c=r1
. q=word.t
get n=text.n q
. win=1
loop n, p=q, c=*p++
if c<>' '
text.find used.letters, c
if false
. win=0, break
end
end
. q++
endl
if win, r0=winner.t
else, r0=looser.t, end
endf
function on.create
initialize
reset.game
endf
function insert.c, c
if c>='a', c-32, end
if c<'A', return, end
if c>'Z', return, end
text.find used.letters, c
if true, return, end
text.attach.c used.letters, c
is.winner
if r0=winner.t
go .reset
end
text.find word.t, c
if true, return, end
. guesses++
if guesses=6
.reset: . scene=SCENE.GAME.OVER
end
endf
; special "my" font
align
alphabet.p: dd \
a.i, b.i, c.i, d.i, e.i, f.i, g.i, h.i, i.i,\
j.i, k.i, l.i, m.i, n.i, o.i, p.i, q.i, r.i,\
s.i, t.i, u.i, v.i, w.i, x.i, y.i, z.i
irps _,\
a b c d e f g h i j k l m \
n o p q r s t u v w x y z {
IMAGE8 _#.i='a/'#`_
}
function index.my.c, c
. r0=c, r0-'A', r0*4, r0+alphabet.p
. (u32) r0=*r0
endf
function get.my.cw, c
if c=' ', return 0, end
index.my.c c
. (u32) r0=*(r0+?image.w)
endf
function get.my.tw, t
locals n, w
alias p=r0, c=r1
get n=text.n t
. w=0
loop n, p=t, c=*p
get.my.cw c
. w+r0, t++
endl
endf w
function draw.my.c, c, x, y, co
locals im, w
if c=' ', return, end
get im=index.my.c c
. (u32) r1=*(r0+?image.w), w=r1
draw.image.v8 im, x, y, co
endf w
function draw.my.text, t, x, y
locals p, n
get n=text.n t
. p=t
loop n, r0=p, r0=*r0
draw.my.c r0, x, y, WHITE
. x+r0, x+4, p++
endl
endf
function draw.my.word, t, x, y
locals p, n, w, c, co
get n=text.n t
. p=t
loop n, r0=p, r0=*r0, c=r0
get w=get.my.cw c
text.find used.letters, c
if true
. r0=x, r0+18, r1=w, r1/2, r0-r1
draw.my.c c, r0, y, WHITE
end
. r0=x, r0+2, r1=y, r1+48
draw.box r0, r1, 32, 3, WHITE
. r0=36, x+r0, p++
endl
endf
function draw.message
locals n, x, y, w
get n=text.count.w word.t
if n=0, n=1, end
set.source word.t
set.token t
. x=250, y=80
loop n
skip.space
copy.until C.SPACE
set.box my.box, 250, 65, 390, 220
text.n t
. r0*36, w=r0, r0=my.box.x, r0+195
. r1=w, r1/2, r0-r1
draw.my.word t, r0, y
. y+70
endl
endf
function draw.letters, t, x, y
locals n, p, c, co
get n=text.n t
. p=t
loop n, r0=p, r0=*r0, c=r0
index.my.c c
. r0+?image.box
memory.copy my.box, r0, 16
. my.box.x=x, my.box.y=y
if.select my.box
if mouse.1
insert.c c
end
end
. co=WHITE
text.find used.letters, c
if true, co=409040h, end
draw.my.c c, x, y, co
. r0+4, x+r0, p++
endl
endf
function draw.alphabet
draw.letters abc, 255, 308
draw.letters xyz, 248, 370
endf
function draw.man
locals x, y
. x=40, y=62
. alpha.bias=A.DARK
draw.image.v.8 stand1.i, x, y, WHITE
. r0=x, r0+27
draw.image.v.8 stand2.i, r0, y, WHITE
. alpha.bias=A.DARKER
if guesses>0
. r0=x, r0+80, r1=y, r1+40
draw.image.v.8 head.i, r0, r1, WHITE
end
if guesses>1
. r0=x, r0+95, r1=y, r1+150
draw.image.v.8 body.i, r0, r1, WHITE
end
if guesses>2
. r0=x, r0+70, r1=y, r1+150
draw.image.v.8 arm1.i, r0, r1, WHITE
end
if guesses>3
. r0=x, r0+143, r1=y, r1+150
draw.image.v.8 arm2.i, r0, r1, WHITE
end
if guesses>4
. r0=x, r0+87, r1=y, r1+228
draw.image.v.8 leg1.i, r0, r1, WHITE
end
if guesses>5
. r0=x, r0+118, r1=y, r1+228
draw.image.v.8 leg2.i, r0, r1, WHITE
end
. alpha.bias=0
endf
function draw.hang.man
. guesses=6
draw.man
. guesses=0
endf
function draw.winner
locals x, y
. alpha.bias=A.DARKER
. x=40, y=62
. r0=x, r0+80, r1=y, r1+40
draw.image.v.8 head.i, r0, r1, WHITE
. r0=x, r0+95, r1=y, r1+150
draw.image.v.8 body.i, r0, r1, WHITE
. r0=x, r0+67, r1=y, r1+87
draw.image.viy.8 arm1.i, r0, r1, WHITE
. r0=x, r0+147, r1=y, r1+87
draw.image.viy.8 arm2.i, r0, r1, WHITE
. r0=x, r0+87, r1=y, r1+228
draw.image.v.8 leg1.i, r0, r1, WHITE
. r0=x, r0+118, r1=y, r1+228
draw.image.v.8 leg2.i, r0, r1, WHITE
. alpha.bias=A.LIGHT
draw.image.v.8 smile.i, 547, 307, WHITE
draw.image.v.8 smile.i, 310, 307, WHITE
. alpha.bias=A.DARK
draw.image.v.8 money.i, 547, 342, 0DDFFDDh
draw.image.v.8 prize.i, 367, 377, WHITE
. alpha.bias=0
endf
function draw.title.scene
draw.my.text help.t, 237, 100
draw.hang.man
endf
function draw.play.scene
draw.message
draw.alphabet
draw.man
endf
function draw.game.over
locals p
get p=is.winner
draw.my.text p, 362, 308
draw.message
if p=winner.t
draw.winner
else
draw.hang.man
end
endf
function on.draw
clear.screen 283D25h
draw.image.8 board.i, 0, 0
. alpha.bias=A.DARKER
draw.image.v.8 logo.i, 240, 32, WHITE
. alpha.bias=0
if scene=SCENE.TITLE
draw.title.scene
else.if scene=SCENE.PLAY
draw.play.scene
else.if scene=SCENE.GAME.OVER
draw.game.over
end
draw.image close.i, 663, 28
endf
function on.key
if key.event='k'
if scene=SCENE.PLAY
insert.c key
else.if scene=SCENE.TITLE
reset.game
. scene=SCENE.PLAY
else.if scene=SCENE.GAME.OVER
reset.game
. scene=SCENE.TITLE
end
render
end
endf
function on.mouse
if mouse.event='c'
. r0=&close.i.x
if.select r0
exit
end
if scene=SCENE.TITLE
reset.game
. scene=SCENE.PLAY
else.if scene=SCENE.GAME.OVER
reset.game
. scene=SCENE.TITLE
end
render
end
endf
function on.timer
; ...
endf
function on.exit
; ...
endf

View File

@ -0,0 +1,26 @@
match =intel x, cpu {
include 'language.inc'
}
include 'memory.inc'
include 'text.inc'
match x =windows, cpu
{ include 'draw.inc' }
match x =kolibri, cpu
{ include 'drawk.inc' }
match x =windows, cpu
{ include 'image.inc' }
match x =kolibri, cpu
{ include 'imagek.inc' }
include 'font.inc'
match x =windows, cpu
{ include 'system.inc' }
match x =kolibri, cpu
{ include 'systemk.inc' }

View File

@ -0,0 +1,218 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ??????????????????? BOX.INC ????????????????????
screen.w equ [!screen.w] ; forward reference
screen.h equ [!screen.h] ; restore at end
macro BOX [p] {
forward p: integer p#.x, p#.y, p#.w, p#.h
}
;;;;;;;;;;;;;;;;;; VISIBILITY ;;;;;;;;;;;;;;;;;;;;
; is visible or partially? return 0 if
; completely invisible
function visible, x, y, w, h
if w<=0, go .0, end
if h<=0, go .0, end
. r0=x, r1=y
if r0>=screen.w, go .0, end
if r1>=screen.h, go .0, end
. r0+w, r1+h
if r0<0, go .0, end
if r1<0, go .0, end
return 1
.0:
endf 0
;;;;;;;;;;;;;;; POINT INSIDE BOX? ;;;;;;;;;;;;;;;;
; x>=bx and x<bx+bw and y>=by and y<by+bh
function point.inside, b, x, y
locals b.x, b.y, b.w, b.h
. r0=b,\
b.x=[?box.x+r0], b.y=[?box.y+r0],\
b.w=[?box.w+r0], b.h=[?box.h+r0],\
r1=x, r2=b.x
cmp r1, r2
jl .r0
add r2, b.w
cmp r1, r2
jge .r0
. r1=y, r2=b.y
cmp r1, r2
jl .r0
add r2, b.h
cmp r1, r2
jge .r0
return 1
.r0: . r0=0
endf
;;;;;;;;;;;;;;;;;;;;;; CLIP ;;;;;;;;;;;;;;;;;;;;;;
; "clipping"; to exclude invisible sections of
; imagery before drawing
; clip.pixel x, y. if invisible, return 0
function clip.pixel, x, y
. r0=x, r1=y
if r0<0, go .0, end
if r0>=screen.w, go .0, end
if r1<0, go .0, end
if r1>=screen.h, go .0, end
return 1
.0:
endf 0
; 2-DO: convert to ABAKIS...
; clip.line o, &x, &y, &n. return 0 if
; completely invisible or adjust x/y/n
; if partially in/visible. o/rientation=
; 'h'/'v'. n=w/h. parameters sent by
; reference
function clip.line, o, x, y, n
push r6 r7 r3
. r6=x, r7=y, r3=n,\
r0=[r6], r2=[r7], r1=[r3]
; if invisible, return 0
cmp r0, screen.w ; x>=screen.w?
jge .0
cmp r2, screen.h ; y>=screen.h?
jge .0
cmp r1, 0 ; w/h<=0?
jle .0
cmp o, 0 ; orientation?
jne .vertical
.horizontal:
cmp r2, 0 ; y<0?
jl .0
cmp r2, screen.h ; y>=screen.h?
jge .0
. r2=r0, r2+r1 ; x+w<0?
cmp r2, 0
jl .0
if r0<0 ; if x<0
. r0+r1,\ ; { w=x+w, x=0 }
[r3]=r0,\
dword [r6]=0
end
cmp r2, screen.w ; if x+w>=screen.w
jl @f ; { w=screen.w-x }
. r0=screen.w,\
r0-[r6], [r3]=r0
@@:
jmp .yes
.vertical:
cmp r0, 0 ; x<0?
jl .0
cmp r0, screen.w ; x>=screen.w?
jge .0
. r1=r2,\
r1+[r3] ; y+h<0?
cmp r1, 0
jl .0
if r2<0 ; if y<0
. [r3]=r1,\ ; { h=y+h, y=0 }
dword [r7]=0
end
cmp r1, screen.h ; if y+h>=screen.h
jl .yes ; { h=screen.h-y }
. r0=screen.h,\
r0-[r7], [r3]=r0
.yes: . r0=YES
jmp .e
.0: . r0=NO
.e:
pop r3 r7 r6
endf
; clip.scanline &s, &x, &y, &w does the same
; as clip.line but sets the s/tart offset of
; pixels and adjusts w correctly. this only
; applies to scanlines, not one-color lines
function clip.scanline, s, x, y, w
push r3
. r3=s,\
dword [r3]=0,\ ; offset=0 initially
r0=x, r0=[r0]
cmp r0, screen.w ; x>=screen.w?
jge .0
. r2=y, r2=[r2]
cmp r2, screen.h ; y>=screen.h?
jge .0
cmp r2, 0 ; y<0?
jl .0
cmp r2, screen.h ; y>=screen.h?
jge .0
. r1=w, r1=[r1],\
r3=r0, r3+r1 ; x+w<0?
cmp r3, 0
jl .0
cmp r3, screen.w ; if x+w>=screen.w
jl @f ; w=screen.w-x
. r1=screen.w,\
r1-r0, r3=w,\
[r3]=r1
@@:
cmp r0, 0 ; if x<0, clip
jg .e
. r2=r0, -r2, r2*4 ; index=-x * scale
. r3=s, [r3]=r2,\
r1=w, [r1]+r0,\ ; w+=x
r3=x, dword [r3]=0 ; x=0
. r0=YES
jmp .e
.0: . r0=NO
.e:
pop r3
endf
;;;;;;;;;;;;;;;;;;;;;;; BOX ;;;;;;;;;;;;;;;;;;;;;;
; BOX structure...
virtual at 0
?box:
.x dd 0
.y dd 0
.w dd 0
.h dd 0
END virtual
align
box:
integer .x, .y, .w, .h
macro set.box box, x, y, w, h {
. box#.x=x, box#.y=y,\
box#.w=w, box#.h=h
}
function move.box.right, b, n
. r0=b, r1=n, r0+?box.x, [r0]+r1
endf
function move.box.down, b, n
. r0=b, r1=n, r0+?box.y, [r0]+r1
endf
function move.box.r, b
. r0=b, r1=[?box.w+r0], r0+?box.x, [r0]+r1
endf
function move.box.d, b
. r0=b, r1=[?box.h+r0], r0+?box.y, [r0]+r1
endf
restore screen.w, screen.h

View File

@ -0,0 +1,227 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ?????????????????? COLOR.INC ???????????????????
COLOR fix integer
PIXEL fix integer
; rgb r, g, b
; get.rgb c, &r, &g, &b
; set.rgb &c, r, g, b
; mix a, b, n ; alpha combination
; lightness c, n ; adjust light/darkness. n=+/-
; colorize a, b, n ; in/decrease r/g/b
; grayscale c ; convert to grayscale
; inversion c ; invert
; channelize a, b ; split r/g/b channel
; PAL1 = I (2)
; PAL2 = II (4)
; PAL4 = IIII (16)
; PAL8 = IIIIIIII (256)
; PAL10 = IIIIIIIIII (1K, 1024)
; PAL12 = IIIIIIIIIIII (4K, 4096)
; RGB15 = X.RRRRR.GGGGG.BBBBB (32768, 32K)
; RGB16 = RRRRR.GGGGGG.BBBBB (65535, 64K)
; RGB24 = R8.G8.B8 (16777216, 16M)
; RGB32 = A8.R8.G8.B8 (same with alpha)
; "standard" colors
numeric BLACK=0, WHITE=0FFFFFFh,\
RED=0FF0000h, GREEN=0FF00h, BLUE=0FFh,\
CYAN=BLUE+GREEN, MAGENTA=RED+BLUE,\
YELLOW=RED+GREEN, GRAY32=202020h,\
GRAY64=404040h, GRAY128=808080h,\
GRAY192=0C0C0C0h, GRAY224=0E0E0E0h,\
GRAY=808080h, GRAY25=404040h,\
GRAY50=GRAY, GRAY75=0C0C0C0h
; personally selected "cool colors". includes
; nature colors for custom brushes/textures -
; grass, dirt, etc
numeric \
RED.CHERRY=720E21h, FIRE.RED=821100h,\
RED.ROSE=7B0024h, DARK.RED=470707h,\
POWER.BLUE=0B008Ah, ROYAL.BLUE=140357h,\
BEACH.BLUE=0362C1h, DARK.BLUE=070720h,\
ICE.BLUE=8ACAE2h, SKY.BLUE=0A3A3F9h,\
CLOUD.BLUE=11A3F5h, BABY.BLUE=4F77FFh,\
LILAC=0DA4FE7h, PURPLE=700E7Fh,\
VIOLET=08C047Ah, DARK.VIOLET=2D0327h,\
LIME.GREEN=8CE007h, SEA.GREEN=72CC90h,\
LEAF.GREEN=7EBB1Dh, GRASS.GREEN=507B11h,\
DARK.GREEN=0B1F0Fh, EMERALD.GREEN=1C3E14h,\
PINK=0FF67A0h, PASTEL.PINK=0F7A7CFh,\
ROSE.PINK=0FB57A0h, PINK.FLESH=0FBD7BDh,\
FLESH=0FCEEDEh, MEDIUM.FLESH=0EF9F5Dh,\
DARK.FLESH=0E87D2Eh, LIGHT.BROWN=0C77237h,\
DARK.BROWN=4D2207h, ORANGE.BROWN=0B04700h,\
RED.BROWN=782712h, SAND=0D1A877h,\
COOL.GRAY=837B9Bh, LILAC.GRAY=0E1ABFFh,\
METAL.GRAY=0AEBEBEh, LIGHT.GRAY=0E7E7E7h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; construct RGB 24/32BPP. assumes 0-255
function rgb, r, g, b
. r0=r, r0<<16, r1=g, r1<<8,\
r0|r1, r2=b, r0|r2
endf
macro rgbm r, g, b {
. r0=r, r0<<16, r1=g, r1<<8,\
r0|r1, r0|b
}
; with truncation. ensure 0-255
function rgbc, r, g, b
. r0=r, r0&0FFh, r0<<16,\
r1=g, r1&0FFh, r1<<8, r0|r1,\
r2=b, r2&0FFh, r0|r2
endf
; extract rgb components from color
; parameters: c, &r, &g, &b. addresses
function get.rgb, c, r, g, b
. r0=c,\
r1=r0, r1>>16, r1&0FFh, r2=r, [r2]=r1,\
r1=r0, r1>>8, r1&0FFh, r2=g, [r2]=r1,\
r1=r0, r1&0FFh, r2=b, [r2]=r1
endf
; set rgb of color. parameters: &c, r, g, b.
; c is address
function set.rgb, c, r, g, b
rgbm r, g, b
. r1=c, [r1]=r0
endf
;;;;;;;;;;;;;;;;;;; CLIP RGB ;;;;;;;;;;;;;;;;;;;;;
; clip RGB components, 0-255. if c<min, c=min.
; if c>max, c=max. all parameters are address
function clip.c, c
. r0=c, r0=[r0]
if r0<0, r0=0
else.if r0>255
r0=255
end
. r2=c, [r2]=r0
endf
function clip.rgb, r, g, b
clip.c r
clip.c g
clip.c b
endf
;;;;;;;;;;;;;;;;;;;;; ALPHA ;;;;;;;;;;;;;;;;;;;;;;
; mix a, b, n - alpha blend/combination.
; n=0-255. (((s-d)*n)/256)+d
function mix, a, b, n
locals sr, sg, sb, dr, dg, db
. r0=a, r2=b,\
r1=r0, r1>>16, r1&0FFh, sr=r1,\
r1=r0, r1>>8, r1&0FFh, sg=r1,\
r1=r0, r1&0FFh, sb=r1,\
r1=r2, r1>>16, r1&0FFh, dr=r1,\
r1=r2, r1>>8, r1&0FFh, dg=r1,\
r1=r2, r1&0FFh, db=r1,\
r0=sr, r0-dr, r0*n, r0>>8, r0+dr,\
r1=sg, r1-dg, r1*n, r1>>8, r1+dg,\
r2=sb, r2-db, r2*n, r2>>8, r2+db,\
r0<<16, r1<<8, r0|r1, r0|r2
endf
; mix25/50/75 a, b, n - much faster
; if alpha is constant 25%/50%/75%
; ((a&0FEFEFEh)>>1)|((b&0FEFEFEh)>>1)
macro mix50 a, b {
. r0=a, r2=b, r1=0FEFEFEh,\
r0&r1, r0>>1, r2&r1, r2>>1, r0|r2
}
function mix25, a, b
mix50 a, b
mix50 r0, b
endf
function mix75, a, b
mix50 a, b
mix50 a, r0
endf
;;;;;;;;;;;;;;;; COLOR OPERATIONS ;;;;;;;;;;;;;;;;
macro operation name, [ps] {
common
function name, ps
locals r, g, b
. r0=&r, r1=&g, r2=&b
get.rgb c, r0, r1, r2
; ...
}
macro endo {
; ...
. r0=&r, r1=&g, r2=&b
clip.rgb r0, r1, r2
rgb r, g, b
endf
}
; adjust light/darkness. n=+/-
operation lightness, c, n
. r1=n, r+r1, g+r1, b+r1
endo
; in/decrease r/g/b
operation colorize, c, x, n
. r1=n
if x=RED, r+r1, g-r1, b-r1
else.if x=GREEN, r-r1, g+r1, b-r1
else.if x=BLUE, r-r1, g-r1, b+r1
end
endo
; convert to grayscale. algorithm:
; g=(r+g+b)/3, rgb(g,g,g). no "endo"
; after. r0=return. note: n/3 =
; (n*155h)>>10
operation grayscale, c
. r0=r, r0+g, r0+b, r0*155h,\
r0>>>10, r1=r0, r1<<8, r0|r1,\
r1<<8, r0|r1
endf
; invert color: c=255-c
operation inversion, c
. \
r1=255, r1-r, r0=&r, [r0]=r1,\
r1=255, r1-g, r0=&g, [r0]=r1,\
r1=255, r1-b, r0=&b, [r0]=r1
endo
; split rgb channel: a=&~b. for 3D
; anaglyph images with R/B glasses
function channelize, a, b
. r0=a, r1=b, not r1, r0&r1
endf
purge operation, endo

View File

@ -0,0 +1,385 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ?????????????????? DRAW.INC ????????????????????
; fast portable graphics
include 'color.inc'
include 'box.inc'
;;;;;;;;;;;;;;;;;;;;; SCREEN ;;;;;;;;;;;;;;;;;;;;;
align
void vga.p
integer screen.x, screen.y,\
screen.w, screen.h, screen.n,\
screen.bpp, screen.size,\
screen.pw, screen.pitch
void palette.p
BOX g.box
function set.screen, w, h, bpp
alias n=r0, pw=r1
. screen.w=w, screen.h=h ; size
. n=w, n*h, screen.n=n ; # pixels
. pw=bpp, pw/8 ; pixel width
. screen.pw=pw, n*pw ; screen size
. screen.size=n ; in bytes
. n=w, n*pw ; screen pitch
. screen.pitch=n ; w in bytes
. screen.bpp=bpp ; bits per pixel
endf
;;;;;;;;;;;;;;;;;;;; DRAWING ;;;;;;;;;;;;;;;;;;;;;
; erase screen with color
function clear.screen, c
alias p=r0, n=r1, z=r2
. p=vga.p, n=screen.n, z=c
loop n, (u32) *p++=z, endl
endf
; calculate x/y offset: (y*screen.w+x)*4
macro get.xy x, y
{ . r0=y, r0*screen.w, r0+x, r0*4 }
; address &vga[(y*screen.w+x)*4]
function vga.xy, x, y
get.xy x, y
. r0+vga.p
endf
; draw pixel
function draw.pixel, x, y, c
alias p=r0, z=r1
try clip.pixel x, y
vga.xy x, y
. z=c, (u32) *p=z
endf 1
; draw horizontal line
function draw.line.h, x, y, n, c
alias p=r0, z=r1, w=r2
. p=&x, z=&y, w=&n
try clip.line 0, p, z, w
vga.xy x, y
. z=c
loop n, (u32) *p++=z, endl
endf 1
; draw vertical line
function draw.line.v, x, y, n, c
locals swb
alias p=r0, z=r1, h=r2
. p=&x, z=&y, h=&n
try clip.line 1, p, z, h
vga.xy x, y
. z=c, swb=screen.pitch
loop n, (u32) *p=z, p+swb, endl
endf 1
; draw solid rectangle
function draw.box, x, y, w, h, c
locals i
try visible x, y, w, h
. i=y, i--
loop h, i++
draw.line.h x, i, w, c
endl
endf 1
; draw rectangle outline
function draw.outline, x, y, w, h, c
try visible x, y, w, h
draw.line.h x, y, w, c ; top
. r0=y, r0+h, r0-- ; bottom
draw.line.h x, r0, w, c
. r0=y, r0++, r1=h, r1-2 ; left
draw.line.v x, r0, r1, c
. r0=x, r0+w, r0--
. r2=y, r2++, r1=h, r1-2 ; right
draw.line.v r0, r2, r1, c
endf 1
macro draw.box.s b, c
{ draw.box b#.x, b#.y, b#.w, b#.h, c }
macro draw.box.o b, c
{ draw.outline b#.x, b#.y, b#.w, b#.h, c }
macro draw.box a, b, c, d, e {
IF ~e eq
draw.box a, b, c, d, e
ELSE IF ~d eq
'Unsupported'
ELSE IF ~c eq
draw.box.s a, b
draw.box.o a, c
ELSE IF ~b eq
draw.box.s a, b
END IF
}
; draw scanline
function draw.scanline, pixels, x, y, w
locals i
alias p=r0, s=r1
. r0=&i, r1=&x, r2=&y, r3=&w
try clip.scanline r0, r1, r2, r3
vga.xy x, y
. s=pixels, s+i
loop w, (u32) *p++=*s++, endl
endf 1
; draw scanline with transparent key
function draw.scanline.t, pixels, x, y, w, key
locals i
alias p=r0, s=r1, c=r2
. r0=&i, r1=&x, r2=&y, r3=&w
try clip.scanline r0, r1, r2, r3
vga.xy x, y
. s=pixels, s+i
loop w, (u32) c=*s++
if c<>key, (u32) *p=c, end, p+4
endl
endf 1
; draw scanline with inverted x
function draw.scanline.ix, pixels, x, y, w
locals i
alias p=r0, s=r1
. r0=x, r0+w
vga.xy r0, y
. p-4, s=pixels
loop w, (u32) *p--=*s++, endl
endf 1
; draw variant scanline. pixels are
; grayscale, alpha intensity of co=color.
; for brushes and special effects
function draw.scanline.v, pixels, x, y, w, co
locals a, i
alias p=r0, s=r1, c=r2, c2=r3
. r0=&i, r1=&x, r2=&y, r3=&w
try clip.scanline r0, r1, r2, r3
vga.xy x, y
. s=pixels, s+i
loop w, (u32) c=*s++
. a=c, a&0FFh
if a=0, go .next, end
if a=0FFh, c=co, go .draw, end
. (u32) c2=*p
push p s
get c=mix co, c2, a
pop s p
.draw: . (u32) *p=c
.next: . p+4
endl
endf 1
; draw bitmap
function draw.bitmap, pixels, x, y, w, h
locals i, p
try visible x, y, w, h
. i=y, p=pixels
loop h
draw.scanline p, x, i, w
. r0=w, r0*4, p+r0, i++
endl
endf 1
; draw bitmap with transparency by
; upper left pixel color (X=0, Y=0)
function draw.bitmap.t, pixels, x, y, w, h
locals i, p, key
try visible x, y, w, h
. i=y, r0=pixels, p=r0
. (u32) r0=*r0, key=r0
loop h
draw.scanline.t p, x, i, w, key
. r0=w, r0*4, p+r0, i++
endl
endf 1
; draw bitmap with inverted x
function draw.bitmap.ix, pixels, x, y, w, h
locals i, p
try visible x, y, w, h
. p=pixels
loop h
draw.scanline.ix p, x, y, w
. r0=w, r0*4, p+r0, y++
endl
endf 1
; draw bitmap with inverted y
function draw.bitmap.iy, pixels, x, y, w, h
locals i, p
try visible x, y, w, h
. r0=h, r0--, y+r0, p=pixels
loop h
draw.scanline p, x, y, w
. r0=w, r0*4, p+r0, y--
endl
endf 1
; draw bitmap with both inverted
function draw.bitmap.ixy, pixels, x, y, w, h
locals i, p, n
try visible x, y, w, h
. p=pixels
loop h
draw.scanline.ix p, x, y, w
. r0=w, r0*4, p+r0, y--
endl
endf 1
; draw variant bitmap
function draw.bitmap.v, pixels, x, y, w, h, c
locals i, p
try visible x, y, w, h
. i=y, r0=pixels, p=r0
loop h
draw.scanline.v p, x, i, w, c
. r0=w, r0*4, p+r0, i++
endl
endf 1
; draw gradual vertical fade from
; color a to b. o/rient:
; 'h'=horizontal, 'v'=vertical
function draw.fade, bo, c1, c2
locals x, y, w, h, i, n, c,\
r, g, b, red, green, blue,\
nr, ng, nb, first, last
. r0=bo,\
x=[?box.x+r0], y=[?box.y+r0],\
w=[?box.w+r0], h=[?box.h+r0]
. r0=y, first=r0, r1=h
. n=r1, r0+r1, last=r0
. r0=&r, r1=&g, r2=&b
get.rgb c1, r0, r1, r2
. r0=&red, r1=&green, r2=&blue
get.rgb c2, r0, r1, r2
. r<<8, g<<8, b<<8, r1=n
if r1=0, r1++, end
. r0=red, r0<<8, r0-r, r0/r1, nr=r0
. r0=green, r0<<8, r0-g, r0/r1, ng=r0
. r0=blue, r0<<8, r0-b, r0/r1, nb=r0
. i=first
forever
. r0=r, r0>>8, r1=g, r1>>8, r2=b, r2>>8
get c=rgb r0, r1, r2
draw.line.h x, i, w, c
. r0=nr, r+r0, r1=ng, g+r1, r2=nb, b+r2
. i++, r0=last
if i>r0, go .out, end
endfv
.out:
endf
; draw with vertical center fade:
; a to b then b to a
function draw.shade, bo, a, b
memory.copy g.box, bo, 16
. g.box.h>>>1
draw.fade g.box, a, b
. r0=g.box.h, g.box.y+r0
draw.fade g.box, b, a
endf
;;;;;;;;;;;;;;;;; PALETTE PIXELS ;;;;;;;;;;;;;;;;;
; 8BPP versions with pa/lette. no clipping
function draw.scanline.8, pixels, x, y, w
alias p=r0, s=r1, c=r2, q=r3
vga.xy x, y
. s=pixels
loop w, q=*s++, q*4, q+palette.p
. (u32) c=*q, (u32) *p++=c
endl
endf 1
function draw.bitmap.8, pixels, x, y, w, h
locals i, p
try visible x, y, w, h
. i=y, i--, p=pixels
loop h, i++
draw.scanline.8 p, x, i, w
. r0=w, p+r0
endl
endf 1
;;;;;;;;;;;;;;;;;;;;; SPECIAL ;;;;;;;;;;;;;;;;;;;;
; special variant 8BPP with alpha bias for
; fonts and sketching effects (example:
; chalkboard)
A.LIGHTEST=128
A.LIGHTER=96
A.LIGHT=64
A.DARK=-32
A.DARKER=-64
A.DARKEST=-96
align
integer alpha.bias=0 ; A.DARKEST
function draw.scanline.v.8, pixels, x, y, w, co
locals a, i
alias p=r0, s=r1, c=r2, c2=r3, q=r3
vga.xy x, y
. s=pixels
loop w, q=*s++, q*4, q+palette.p
. (u32) c=*q, a=c, a&0FFh
if a=0, go .next, end
. (u32) c2=*p
push p s
. r0=a
if alpha.bias, r0+alpha.bias
if r0<0, r0=0
else.if r0>255, r0=255, end
end
get c=mix co, c2, r0
pop s p
.draw: . (u32) *p=c
.next: . p+4
endl
endf 1
function draw.bitmap.v.8, pixels, x, y, w, h, c
locals i, p
try visible x, y, w, h
. i=y, i--, p=pixels
loop h, i++
draw.scanline.v.8 p, x, i, w, c
. r0=w, p+r0
endl
endf 1

View File

@ -0,0 +1,344 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ?????????????????? DRAW.INC ????????????????????
; fast portable graphics
include 'color.inc'
include 'box.inc'
;;;;;;;;;;;;;;;;;;;;; SCREEN ;;;;;;;;;;;;;;;;;;;;;
align
vga equ (gs:r0)
; void vga.p
integer \
screen.w, screen.h, screen.n,\
screen.size, screen.pitch,\
screen.bpp, screen.pw
void palette.p
function set.screen, w, h, bpp
alias n=r0, pw=r1
. screen.w=w, screen.h=h ; size
. n=w, n*h, screen.n=n ; # pixels
. n=bpp, n>>>3, pw=n ; pixel width
. screen.pw=pw, n*pw ; size
. screen.size=n ; in bytes
. n=w, n*4 ; width
. screen.pitch=n ; in bytes
. screen.bpp=bpp ; bits per pixel
endf
; calculate x/y offset: (y*screen.w+x)*4
macro xy x, y {
. r0=y, r0*1024, r0+x, r0*4
. r1=WINDOW.Y, r1*4096, r0+r1
. r1=WINDOW.X, r1*4, r0+r1
}
; erase screen with color
function clear.screen, c
callf draw.box, 0, 0, WINDOW.W-1, WINDOW.H-1, c
endf
; draw straight line: loop n, *p++=c
function draw.line.h, x, y, w, c
xy x, y
. r1=c
loop w, (u32) *vga=r1, r0+4, endl
endf
; draw vertical line
function draw.line.v, x, y, n, c
locals swb
alias p=r0, z=r1, h=r2
xy x, y
. z=c, swb=4096
loop n, (u32) *vga=z, p+swb, endl
endf 1
; draw solid rectangle
function draw.box, x, y, w, h, c
try visible x, y, w, h
loop h
draw.line.h x, y, w, c
. y++
endl
endf
; draw rectangle outline
function draw.outline, x, y, w, h, c
try visible x, y, w, h
draw.line.h x, y, w, c
. r0=y, r0+h, r0--
draw.line.h x, r0, w, c
. r0=y, r0++, r1=h, r1-2
draw.line.v x, r0, r1, c
. r0=x, r0+w, r0--
. r1=y, r1++, r2=h, r2-2
draw.line.v r0, r1, r2, c
endf
macro draw.box.s b, c
{ draw.box b#.x, b#.y, b#.w, b#.h, c }
macro draw.box.o b, c
{ draw.outline b#.x, b#.y, b#.w, b#.h, c }
macro draw.box a, b, c, d, e {
IF ~e eq
draw.box a, b, c, d, e
ELSE IF ~d eq
'Unsupported'
ELSE IF ~c eq
draw.box.s a, b
draw.box.o a, c
ELSE IF ~b eq
draw.box.s a, b
END IF
}
; draw scanline: multi-color line,
; array of pixels:
; loop w, *p++=*s++, endl
function draw.scanline, s, x, y, w
alias p=r0, q=r1, c=r2
xy x, y
. q=s
loop w, (u32) c=*q, (u32) *vga=c
. p+4, q+4
endl
endf
; draw transparent scanline with color
; "key" to exclude
function draw.scanline.t, s, x, y, w, k
alias p=r0, q=r1, c=r2
xy x, y
. q=s
loop w, (u32) c=*q
if c<>k, (u32) *vga=c, end
. p+4, q+4
endl
endf
; draw scanline with inverted x
function draw.scanline.ix, pixels, x, y, w
alias p=r0, s=r1, c=r2
. r0=x, r0+w
xy r0, y
. p-4, s=pixels
loop w, (u32) c=*s++, (u32) *vga=c, p-4, endl
endf 1
; draw variant scanline. pixels are
; grayscale, alpha intensity of co=color.
; for brushes and special effects
function draw.scanline.v, pixels, x, y, w, co
locals a
alias p=r0, s=r1, c=r2, c2=r3
xy x, y
. s=pixels
loop w, (u32) c=*s++
. a=c, a&0FFh
if a=0, go .next, end
if a=0FFh, c=co, go .draw, end
. (u32) c2=*p
push p s
get c=mix co, c2, a
pop s p
.draw: . (u32) *vga=c
.next: . p+4
endl
endf 1
; draw transparent scanline with key and
; alpha (0-255) applied to entire line
function draw.scanline.a, s, x, y, w, k, a
alias p=r0, q=r1, c=r2, c2=r3
xy x, y
. q=s
loop w, (u32) c=*q
if c<>k, (u32) c2=*vga
push p q
get c=mix c, c2, a
pop q p
end, (u32) *vga=c
.next:
. p+4, q+4
endl
endf
; draw bitmap; 2D array of pixels
function draw.bitmap, p, x, y, w, h
locals i
try visible x, y, w, h
. i=y
loop h, i++
draw.scanline p, x, i, w
. r0=w, r0*4, p+r0
endl
endf
; draw transparent bitmap with color
; "key" by upper left pixel (X0,Y0)
function draw.bitmap.t, p, x, y, w, h
locals i, k
try visible x, y, w, h
. r0=p, (u32) r0=*r0, k=r0
. i=y
loop h, i++
draw.scanline.t p, x, i, w, k
. r0=w, r0*4, p+r0
endl
endf
; draw transparent bitmap with key and
; alpha (0-255) applied to entire image
function draw.bitmap.a, p, x, y, w, h, a
locals i, k
try visible x, y, w, h
. i=y, r0=p, (u32) r0=*r0, k=r0
loop h, i++
draw.scanline.a p, x, i, w, k, a
. r0=w, r0*4, p+r0
endl
endf
; draw bitmap with inverted x
function draw.bitmap.ix, pixels, x, y, w, h
locals p
try visible x, y, w, h
. p=pixels
loop h
draw.scanline.ix p, x, y, w
. r0=w, r0*4, p+r0, y++
endl
endf 1
; draw bitmap with inverted y
function draw.bitmap.iy, pixels, x, y, w, h
locals p
try visible x, y, w, h
. r0=h, r0--, y+r0, p=pixels
loop h
draw.scanline p, x, y, w
. r0=w, r0*4, p+r0, y--
endl
endf 1
; draw bitmap with both inverted
function draw.bitmap.ixy, pixels, x, y, w, h
locals p, n
try visible x, y, w, h
. p=pixels
loop h
draw.scanline.ix p, x, y, w
. r0=w, r0*4, p+r0, y--
endl
endf 1
; draw variant bitmap
function draw.bitmap.v, pixels, x, y, w, h, c
locals i, p
try visible x, y, w, h
. i=y, r0=pixels, p=r0
loop h
draw.scanline.v p, x, i, w, c
. r0=w, r0*4, p+r0, i++
endl
endf 1
;;;;;;;;;;;;;;;;; PALETTE PIXELS ;;;;;;;;;;;;;;;;;
; 8BPP versions with pa/lette. no clipping
function draw.scanline.8, pixels, x, y, w
alias p=r0, s=r1, c=r2, q=r3
xy x, y
. s=pixels
loop w, q=*s++, q*4, q+palette.p
. (u32) c=*q, (u32) *vga=c, r0+4
endl
endf 1
function draw.bitmap.8, pixels, x, y, w, h
locals i, p
try visible x, y, w, h
. i=y, p=pixels
loop h
draw.scanline.8 p, x, i, w
. i++, r0=w, p+r0
endl
endf 1
;;;;;;;;;;;;;;;;;;;;; SPECIAL ;;;;;;;;;;;;;;;;;;;;
; special variant 8BPP with alpha bias for
; fonts and sketching effects (example:
; chalkboard)
A.LIGHTEST=128
A.LIGHTER=96
A.LIGHT=64
A.DARK=-32
A.DARKER=-64
A.DARKEST=-96
align
integer alpha.bias=0 ; A.DARKEST
function draw.scanline.v.8, pixels, x, y, w, co
locals a
alias p=r0, s=r1, c=r2, c2=r3, q=r3
xy x, y
. s=pixels
loop w, q=*s++, q*4, q+palette.p
. (u32) c=*q, a=c, a&0FFh
if a=0, go .next, end
. (u32) c2=*vga
push p s
. r0=a
if alpha.bias, r0+alpha.bias
if r0<0, r0=0
else.if r0>255, r0=255, end
end
get c=mix co, c2, r0
pop s p
.draw: . (u32) *vga=c
.next: . p+4
endl
endf 1
function draw.bitmap.v.8, pixels, x, y, w, h, c
locals i, p
try visible x, y, w, h
. i=y, p=pixels
loop h
draw.scanline.v.8 p, x, i, w, c
. i++, r0=w, p+r0
endl
endf 1

View File

@ -0,0 +1,104 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ?????????????????? FONT.INC ????????????????????
; 100% portable font
;;;;;;;;;;;;;;;;;;;; SYMBOLS ;;;;;;;;;;;;;;;;;;;;;
; my default character arrangement: 95 symbols.
; includes all standard visible characters
; 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I
; J K L M N O P Q R S T U V W X Y Z a b
; c d e f g h i j k l m n o p q r s t u
; v w x y z _ . ? ; : ' " , ~ ! @ # $
; % ^ & * ( ) [ ] { } = + - < > / \ | `
; symbol lookup table to convert 7BIT ASCII
; character to index. 63=ignore (spaces, etc)
align 4
FONT.SYMBOLS: db \
63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,\
63,63,63,63,63,63,63,63, 63,63,63,63,63,63,63,63,\
63,72,69,74,75,76,78,68, 80,81,79,87,70,88,64,91,\
00,01,02,03,04,05,06,07, 08,09,67,66,89,86,90,65,\
73,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,\
25,26,27,28,29,30,31,32, 33,34,35,82,92,83,77,62,\
94,36,37,38,39,40,41,42, 43,44,45,46,47,48,49,50,\
51,52,53,54,55,56,57,58, 59,60,61,84,93,85,71,63
NO.C=63
macro FONT [p] { common IMAGE p }
align
void font.image.p
integer font.image.w, font.w, font.h
integer font.color=WHITE
macro set.font i {
. font.image.p=i#.p, r0=i#.w
. font.image.w=r0, r1=95, r0/r1
. font.w=r0, font.h=i#.h
}
;;;;;;;;;;;;;;;;; DRAW CHARACTER ;;;;;;;;;;;;;;;;;
function draw.c, c, x, y
locals i, p, iw
try visible x, y, font.w, font.h
. r0=FONT.SYMBOLS, r0+c, r0=*r0
if r0=NO.C, return, end
. r0*font.w, r0*4, r0+font.image.p
. p=r0, iw=font.image.w, iw*4, i=font.h
loop i, r0=i
if r0>=font.h, break, end
draw.scanline p, x, y, font.w
. r1=iw, p+r1, y++
endl
endf
;;;;;;;;;;;;;;;;;;; DRAW TEXT ;;;;;;;;;;;;;;;;;;;;
align
integer clip.tx=-1, clip.ty=-1
function draw.text, t, x, y
locals i, n, p
. r0=t, p=r0, i=0
while true ; draw all characters
. r1=i, r1*font.w ; x=i*font.w+x
. r1+x, r0=p, r0=*r0 ; get c
if r0=0Dh ; return?
. i=0, r1=font.h ; reset x
. y+r1, p++ ; y+font.h
go .next
end
. r2=y, r2-font.h ; clipping
if r2>screen.h
return
end
. r2=clip.tx
if r2<>-1, r2-font.w
if r1>=r2, return, end
end
. r2=clip.ty
if r2<>-1, r2-font.h
if r1>=r2, return, end
end
draw.c r0, r1, y ; draw
. i++
.next:
. p++, r0=p, r0=*r0
endw
endf
; get width of text=a1 with insets
function get.text.w, t
text.n t
. r1=r0, r1+2, r0=font.w, r0*r1
endf

View File

@ -0,0 +1,397 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ;;;;;;;;;;;;;;;;;;; IMAGE ;;;;;;;;;;;;;;;;;;;;;;
; image class/object/structure
macro IMAGE a {
a:
void a#.p
integer a#.x, a#.y, a#.w, a#.h
integer a#.bpp=32, a#.key, a#.alpha
}
virtual at 0
?image.p dd 0
?image.x dd 0
?image.y dd 0
?image.w dd 0
?image.h dd 0
?image.bpp dd 32
?image.key dd 0
?image.alpha dd 0
END virtual
?image.box fix ?image.x
; create image file/s with header:
; 8 bytes:
; byte s='I' ; signature
; byte v=0 ; version: AABBCC.VV
; int16 w, h ; size: w:h
; byte bpp ; bpp: 32/24/16/15/8
; byte n ; # colors or 0=256+
; byte pixels[w*h*(bpp/8)] ; or *2 if 15
macro IMAGE [p] {
forward
local w, h
w=0
h=0
define ?s 0
match a==b, p \{
\local ..q
..q: inject.image b, 32
load w word from ..q+2
load h word from ..q+4
a:
void a\#.p=..q+8
integer a\#.x, a\#.y, a\#.w=w, a\#.h=h
integer a\#.bpp, a\#.key, a\#.alpha
define ?s 1
\}
IF ?s eq 0
IMAGE p
END IF
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; load 24PP .BMP, store as .IMAGE 15/16/24/32.
; for OSs, ROMs. warning: causes slow compile
; with 1+ MB worth of images. to compile fast
; without images, comment "; IMAGE name='abc'"
macro inject.image name, bpp {
local i, p, a, r, g, b,\
x, y, w, h, wb
virtual at 0
p:: file CD#'/media/'#name#'.BMP'
END virtual
IF ~bpp in <15,16,24,32>
'Invalid BPP' name
END IF
load a word from p:0
IF a<>'BM'
'Invalid signature' name
END IF
load a byte from p:1Ch
IF a<>24
'Must be 24BPP' name
END IF
load w dword from p:12h
load h dword from p:16h
db 'I', 0
dw w, h
db bpp, 0
a=((3-((w*3)+3)) and 3)
wb=(w*3)+a
y=h
WHILE y>0
o=36h+((y-1)*wb)
x=0
WHILE x<w
i=o+(x*3)
load b byte from p:i
load g byte from p:i+1
load r byte from p:i+2
IF bpp=32
dd (r shl 16) or (g shl 8) or b
ELSE IF bpp=24
db r, g, b ; or b, g, r
ELSE IF bpp=16
r=((r and 11111b)/8) shl 11
g=((g and 111111b)/4) shl 5
b=((b and 11111b)/8)
dw r or g or b
ELSE IF bpp=15
r=((r and 11111b)/8) shl 10
g=((g and 11111b)/8) shl 5
b=((b and 11111b)/8)
dw r or g or b
END IF
x=x+1
END WHILE
y=y-1
END WHILE
}
; insert 8BPP .BMP as .IMAGE with palette.
; note: must use special .8 drawing
macro inject.image.8 name {
local i, p, a, c,\
x, y, w, h, wb
virtual at 0
p:: file CD#'/media/'#name#'.BMP'
END virtual
load a word from p:0
IF a<>'BM'
'Invalid signature' name
END IF
load a byte from p:1Ch
IF a<>8
'Must be 8BPP' name
END IF
load w dword from p:12h
load h dword from p:16h
db 'I', 0
dw w, h
db 8, 0
i=0
WHILE i<256
o=36h+(i*4)
load b byte from p:o
load g byte from p:o+1
load r byte from p:o+2
db b, g, r, 0
i=i+1
END WHILE
a=((3-(w+3)) and 3)
wb=w+a
y=h
WHILE y>0
o=436h+((y-1)*wb)
x=0
WHILE x<w
load c byte from p:o+x
db c
x=x+1
END WHILE
y=y-1
END WHILE
}
macro IMAGE8 [p] {
forward
local w, h
w=0
h=0
define ?s 0
match a==b, p \{
\local ..q
..q: inject.image.8 b
load w word from ..q+2
load h word from ..q+4
a:
void a\#.p=..q+408h
integer a\#.x, a\#.y, a\#.w=w, a\#.h=h
integer a\#.bpp, a\#.key, a\#.alpha
; ...
void a\#.palette=..q+8
define ?s 1
\}
IF ?s eq 0
'Error: 8BPP must specify file'
END IF
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; unfinished, unorganized...
; 2-DO: convert to functions. create one
; good draw.scanline.x with bpp and type
; BIT flags:
; draw.scanline.x p, x, y, w, 32,\
; G.KEY or G.ALPHA or G.GRAY or G.INVERT.X
macro move.image i, x, y { . i#.x=x, i#.y=y }
macro draw.image i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.t i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.t i#.p, i#.x, i#.y, i#.w, i#.h
}
; draw with inverted x/y
macro draw.image.ix i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.ix i#.p,\
i#.x, i#.y, i#.w, i#.h
}
macro draw.image.iy i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.iy i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.ixy i, x, y, ix, iy {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.ixy i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.v i, x, y, c {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.v i#.p, i#.x, i#.y, i#.w, i#.h, c
}
; draw rotated. warning: no clipping
function draw.scanline.rl, pixels, x, y, w
alias p=r0, s=r1, n=r2
vga.xy x, y
. s=w, s--, s*4, s+pixels, n=screen.pitch
loop w, (u32) *p=*s--, p+n, endl
endf 1
function draw.scanline.rr, pixels, x, y, w
alias p=r0, s=r1, n=r2
vga.xy x, y
. s=pixels, n=screen.pitch
loop w, (u32) *p=*s++, p+n, endl
endf 1
function draw.bitmap.rl, pixels, x, y, w, h
locals i, p
try visible x, y, w, h
. p=pixels
loop h
draw.scanline.rl p, x, y, w
. r0=w, r0*4, p+r0, x++
endl
endf 1
function draw.bitmap.rr, pixels, x, y, w, h
locals i, p
try visible x, y, w, h
. r0=w, r0--, x+r0, p=pixels
loop h
draw.scanline.rr p, x, y, w
. r0=w, r0*4, p+r0, x--
endl
endf 1
macro draw.image.rl i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.rl i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.rr i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.rr i#.p, i#.x, i#.y, i#.w, i#.h
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 8BPP with palette...
macro draw.image.8 i, x, y {
IF ~x eq
move.image i, x, y
END IF
. palette.p=i#.palette
draw.bitmap.8 i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.v.8 i, x, y, c {
IF ~x eq
move.image i, x, y
END IF
. palette.p=i#.palette
draw.bitmap.v.8 i#.p, i#.x, i#.y, i#.w, i#.h, c
}
function draw.image.v8, im, x, y, co
locals p, w, h
. r0=im
. (u32) r1=*(r0+?image.p), p=r1
. (u32) r1=*(r0+?image.w), w=r1
. (u32) r1=*(r0+?image.h), h=r1
draw.bitmap.v.8 p, x, y, w, h, co
endf
function draw.bitmap.viy.8, pixels,\
x, y, w, h, c
locals i, p
try visible x, y, w, h
. r0=h, y+r0, p=pixels
loop h
draw.scanline.v.8 p, x, y, w, c
. r0=w, p+r0, y--
endl
endf 1
function draw.image.viy.8, im, x, y, co
locals p, w, h
. r0=im
. (u32) r1=*(r0+?image.p), p=r1
. (u32) r1=*(r0+?image.w), w=r1
. (u32) r1=*(r0+?image.h), h=r1
draw.bitmap.viy.8 p, x, y, w, h, co
endf
;;;;;;;;;;;;;;;;;;; LOAD .BMP ;;;;;;;;;;;;;;;;;;;;
; load 8BPP .BMP as 32BIT pixel array.
; if success, return allocated pixels address
; in r0 and w/h in r1/r2. return 0 if error
function load.bmp, file
locals image, palette,\
p, s, x, y, w, h, a
catch .error
; load file, get size then allocate
; 32BPP image...
try file=load.file file
. r1=[r0+18], r2=[r0+22]
. w=r1, h=r2, r1*r2, r1*4
try image=allocate r1
; create and load palette...
try palette=allocate 1024
. r0=file, r0+54
memory.copy palette, r0, 1024
align.n w, 4 ; get alignment value
. a=r1 ; 0-3 bytes
; advance to p/ixels data, point
; s/ource at first pixel in last
; line then read image upside down
. p=image, r0=file, r0+54, r0+1024
. r1=w, r1+a, r2=h, r2--, r1*r2
. r0+r1, s=r0, y=h
loop y, x=w
loop x, r2=s, r1=*r2, r1*4
. r1+palette, r0=p, (u32) *r0=*r1
. p+4, s++
endl
. r0=w, r0*2, r0+a, s-r0
endl
destroy file, palette
. r0=image, r1=w, r2=h
return
.error:
destroy image, file, palette
endf 0

View File

@ -0,0 +1,348 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ;;;;;;;;;;;;;;;;;;; IMAGE ;;;;;;;;;;;;;;;;;;;;;;
; image class/object/structure
macro IMAGE a {
a:
void a#.p
integer a#.x, a#.y, a#.w, a#.h
integer a#.bpp=32, a#.key, a#.alpha
}
virtual at 0
?image.p dd 0
?image.x dd 0
?image.y dd 0
?image.w dd 0
?image.h dd 0
?image.bpp dd 32
?image.key dd 0
?image.alpha dd 0
END virtual
?image.box fix ?image.x
; create image file/s with header:
; 8 bytes:
; byte s='I' ; signature
; byte v=0 ; version: AABBCC.VV
; int16 w, h ; size: w:h
; byte bpp ; bpp: 32/24/16/15/8
; byte n ; # colors or 0=256+
; byte pixels[w*h*(bpp/8)] ; or *2 if 15
macro IMAGE [p] {
forward
local w, h
w=0
h=0
define ?s 0
match a==b, p \{
\local ..q
..q: inject.image b, 32
load w word from ..q+2
load h word from ..q+4
a:
void a\#.p=..q+8
integer a\#.x, a\#.y, a\#.w=w, a\#.h=h
integer a\#.bpp, a\#.key, a\#.alpha
define ?s 1
\}
IF ?s eq 0
IMAGE p
END IF
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; load 24PP .BMP, store as .IMAGE 15/16/24/32.
; for OSs, ROMs. warning: causes slow compile
; with 1+ MB worth of images. to compile fast
; without images, comment "; IMAGE name='abc'"
macro inject.image name, bpp {
local i, p, a, r, g, b,\
x, y, w, h, wb
virtual at 0
p:: file CD#'/media/'#name#'.BMP'
END virtual
IF ~bpp in <15,16,24,32>
'Invalid BPP' name
END IF
load a word from p:0
IF a<>'BM'
'Invalid signature' name
END IF
load a byte from p:1Ch
IF a<>24
'Must be 24BPP' name
END IF
load w dword from p:12h
load h dword from p:16h
db 'I', 0
dw w, h
db bpp, 0
a=((3-((w*3)+3)) and 3)
wb=(w*3)+a
y=h
WHILE y>0
o=36h+((y-1)*wb)
x=0
WHILE x<w
i=o+(x*3)
load b byte from p:i
load g byte from p:i+1
load r byte from p:i+2
IF bpp=32
dd (r shl 16) or (g shl 8) or b
ELSE IF bpp=24
db r, g, b ; or b, g, r
ELSE IF bpp=16
r=((r and 11111b)/8) shl 11
g=((g and 111111b)/4) shl 5
b=((b and 11111b)/8)
dw r or g or b
ELSE IF bpp=15
r=((r and 11111b)/8) shl 10
g=((g and 11111b)/8) shl 5
b=((b and 11111b)/8)
dw r or g or b
END IF
x=x+1
END WHILE
y=y-1
END WHILE
}
; insert 8BPP .BMP as .IMAGE with palette.
; note: must use special .8 drawing
macro inject.image.8 name {
local i, p, a, c,\
x, y, w, h, wb
virtual at 0
p:: file CD#'/media/'#name#'.BMP'
END virtual
load a word from p:0
IF a<>'BM'
'Invalid signature' name
END IF
load a byte from p:1Ch
IF a<>8
'Must be 8BPP' name
END IF
load w dword from p:12h
load h dword from p:16h
db 'I', 0
dw w, h
db 8, 0
i=0
WHILE i<256
o=36h+(i*4)
load b byte from p:o
load g byte from p:o+1
load r byte from p:o+2
db b, g, r, 0
i=i+1
END WHILE
a=((3-(w+3)) and 3)
wb=w+a
y=h
WHILE y>0
o=436h+((y-1)*wb)
x=0
WHILE x<w
load c byte from p:o+x
db c
x=x+1
END WHILE
y=y-1
END WHILE
}
macro IMAGE8 [p] {
forward
local w, h
w=0
h=0
define ?s 0
match a==b, p \{
\local ..q
..q: inject.image.8 b
load w word from ..q+2
load h word from ..q+4
a:
void a\#.p=..q+408h
integer a\#.x, a\#.y, a\#.w=w, a\#.h=h
integer a\#.bpp, a\#.key, a\#.alpha
; ...
void a\#.palette=..q+8
define ?s 1
\}
IF ?s eq 0
'Error: 8BPP must specify file'
END IF
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; unfinished, unorganized...
; 2-DO: convert to functions. create one
; good draw.scanline.x with bpp and type
; BIT flags:
; draw.scanline.x p, x, y, w, 32,\
; G.KEY or G.ALPHA or G.GRAY or G.INVERT.X
macro move.image i, x, y {
IF ~x eq
. i#.x=x, i#.y=y
END IF
}
macro draw.image i, x, y {
move.image i, x, y
draw.bitmap i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.t i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.t i#.p, i#.x, i#.y, i#.w, i#.h
}
; draw with inverted x/y
macro draw.image.ix i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.ix i#.p,\
i#.x, i#.y, i#.w, i#.h
}
macro draw.image.iy i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.iy i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.ixy i, x, y, ix, iy {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.ixy i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.v i, x, y, c {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.v i#.p, i#.x, i#.y, i#.w, i#.h, c
}
; draw rotated. warning: no clipping
function draw.scanline.rl, pixels, x, y, w
alias p=r0, s=r1, n=r2, c=r3
xy x, y
. s=w, s--, s*4, s+pixels, n=4096 ; screen.pitch
loop w, (u32) c=*s--, (u32) *vga=c, p+n, endl
endf 1
function draw.scanline.rr, pixels, x, y, w
alias p=r0, s=r1, n=r2, c=r3
xy x, y
. s=pixels, n=4096 ; screen.pitch
loop w, (u32) c=*s++, (u32) *vga=c, p+n, endl
endf 1
function draw.bitmap.rl, pixels, x, y, w, h
locals p
try visible x, y, w, h
. p=pixels
loop h
draw.scanline.rl p, x, y, w
. r0=w, r0*4, p+r0, x++
endl
endf 1
function draw.bitmap.rr, pixels, x, y, w, h
locals p
try visible x, y, w, h
. r0=w, r0--, x+r0, p=pixels
loop h
draw.scanline.rr p, x, y, w
. r0=w, r0*4, p+r0, x--
endl
endf 1
macro draw.image.rl i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.rl i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.rr i, x, y {
IF ~x eq
move.image i, x, y
END IF
draw.bitmap.rr i#.p, i#.x, i#.y, i#.w, i#.h
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 8BPP with palette...
macro draw.image.8 i, x, y {
IF ~x eq
move.image i, x, y
END IF
. palette.p=i#.palette
draw.bitmap.8 i#.p, i#.x, i#.y, i#.w, i#.h
}
macro draw.image.v.8 i, x, y, c {
IF ~x eq
move.image i, x, y
END IF
. palette.p=i#.palette
draw.bitmap.v.8 i#.p, i#.x, i#.y, i#.w, i#.h, c
}
function draw.image.v8, im, x, y, co
locals p, w, h
. r0=im
. (u32) r1=*(r0+?image.p), p=r1
. (u32) r1=*(r0+?image.w), w=r1
. (u32) r1=*(r0+?image.h), h=r1
draw.bitmap.v.8 p, x, y, w, h, co
endf
function draw.bitmap.viy.8, pixels,\
x, y, w, h, c
locals i, p
try visible x, y, w, h
. r0=h, y+r0, p=pixels
loop h
draw.scanline.v.8 p, x, y, w, c
. r0=w, p+r0, y--
endl
endf 1
function draw.image.viy.8, im, x, y, co
locals p, w, h
. r0=im
. (u32) r1=*(r0+?image.p), p=r1
. (u32) r1=*(r0+?image.w), w=r1
. (u32) r1=*(r0+?image.h), h=r1
draw.bitmap.viy.8 p, x, y, w, h, co
endf

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,274 @@
; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ????????????????? MEMORY.INC ???????????????????
; allocate n ; see SYSTEM.INC
; allocate.p p, n
; destroy p
; memory.set p, v, n ; 32BIT set/copy/zero
; memory.copy a, b, n
; memory.zero p, n
; get.bit v, n ; get/set/zero bit
; set.bit v, n
; zero.bit v, n
; enable.f v, n ; enable/disable flag
; disable.f v, n
; power.2 n ; is power of 2? which one?
; align.n n, p ; versatile align n to p
;;;;;;;;;;;;; MEMORY COPY, SET, ZERO ;;;;;;;;;;;;;
; portable. 32BIT
function memory.copy, a, b, n
alias p=r0, q=r1
. p=a, q=b, n>>>2
loop n, (u32) *p++=*q++, endl
endf
function memory.set, a, b, n
alias p=r0, v=r1, x=r2
. p=a, v=b, n>>>2
loop n, (u32) *p++=v, endl
endf
macro memory.zero p, n { memory.set p, 0, n }
; x86 specific. aligned
function memory.copy.x, a, b, n
push r6 r7
. r7=a,\
r6=b, r1=n
test r7, r6 ; address=0?
jz .e
cmp r1, 4 ; if n<4
jb @f
push r1
shr r1, 2 ; n/4
rep movsd ; copy dwords
pop r1
and r1, 3 ; modulo 4
jz .e ; remainder?
@@:
rep movsb ; copy bytes
.e:
pop r7 r6
endf
function memory.set.x, p, v, n
push r7
. r7=p, r0=v,\
r0*01010101h,\
r1=n
test r7, r7 ; address=0?
jz .e
cmp r1, 4 ; n<4?
jb @f
push r1
shr r1, 2
rep stosd ; copy dwords
pop r1
and r1, 3 ; modulo 4
jz .e ; remainder?
@@:
rep stosb ; copy bytes
.e:
pop r7
endf
;;;;;;;;;;;;;;;; GET/SET/ZERO BIT ;;;;;;;;;;;;;;;;
; 76543210. warning: r0/r1/r2 cannot be used
; as parameters. 'v' should be m, 'i' can be m/i
macro get.bit v, i { ; (v>>i)&1
. r0=v, r1=i, r0>>cl, r0&1
}
macro set.bit v, i { ; v|=(1<<i)
. r0=1, r1=i, r0<<cl, v|r0
}
macro zero.bit v, i { ; v&=~(1<<i)
. r0=1, r1=i, r0<<cl, not r0, v&r0
}
; 1111.0000
macro get.nibble v, i { ; (v>>(i*4))&1111b
. r0=v, r1=i, r1<<2, r0>>cl, r0&1111b
}
macro set.nibble v, i, n { ; v|=(n<<(i*4))
. r0=v, r1=i, r2=n, r1<<2, r2<<cl,\
r0|r2, v=r0
}
; 33.22.11.00
macro get.couple v, i { ; (v>>(i*2))&11b
. r0=v, r1=i, r1<<1, r0>>cl, r0&11b
}
macro set.couple v, i, n { ; v|=(n<<(i*2))
. r0=v, r1=i, r2=n, r1<<1, r2<<cl,\
r0|r2, v=r0
}
; enable/disable flag
macro enable.f v, n { . r0=n, v|r0 }
macro disable.f v, n
{ . r0=n, not r0, v&r0 }
macro toggle n { xor n, 1 } ; invert 1/0
; create AA.BBB.CCCb/AA.BB.CC.DDb BIT structures
function triplet, a, b, c
. r0=a, r0<<6, r1=b, r1<<3, r0|r1, r0|c
endf
function quadruplet, a, b, c, d
. r0=a, r0<<6, r1=b, r1<<4
. r2=c, r2<<2, r0|r1, r0|r2, r0|d
endf
; reverse byte order
macro reverse.32 n
{ . r0=n, bswap r0 }
macro reverse.24 n
{ . r0=n, bswap r0, r0>>>8 }
macro reverse.16 n
{ . r0=n, cl=al, al=ah, ah=cl }
;;;;;;;;;;;;;;;;;; POWERS OF 2 ;;;;;;;;;;;;;;;;;;;
; an unsigned number is a power of 2 if only
; 1 BIT is set: if !(n&n-1). subtracting 1
; inverts all BITs. if n=10000000b (80h/128),
; n&01111111b=0
; to find out which power of 2, search n
; for 1st 0 BIT from right to left
; is n power of 2? example: power.2 128
; returns 7
function power.2, n
locals i
. r0=n
if r0<2, go .r0, end
. r1=r0, r1-1, r0&r1
test r0, r0
jnz .r0
. n--, i=1
@@:
. r0=1, r1=i, r0<<cl, i++
test n, r0
jnz @b
. r0=i, r0--
jmp @f
.r0: . r0=0
@@:
endf
;;;;;;;;;;;;;;;;;;;;; ALIGN ;;;;;;;;;;;;;;;;;;;;;;
; versatile align n/umber by power of 2
; return n aligned to p in r0. in r1,
; return the quantity to add to make n
; divisible by p. algorithm:
; n+(((p-1)-(n+p-1))&(p-1))
function align.n, n, p
. r1=p, r1-1, r2=n, r2+r1, r0=r1
. r0-r2, r0&r1, r1=r0, r2=n, r0+r2
endf
;;;;;;;;;;;;;;;; SOURCE, DESTINY ;;;;;;;;;;;;;;;;;
align
void source, destiny
integer origin, omega
function create.source, size
destroy source
try source=allocate size
memory.zero source, size
. origin=0, omega=0
endf 1
function create.destiny, size
destroy destiny
try destiny=allocate size
memory.zero destiny, size
. origin=0, omega=0
endf 1
;;;;;;;;;;;;;;;;;;; TESTING... ;;;;;;;;;;;;;;;;;;;
; optimized 128-BIT copy/set. ".fast"=CPU
; specific, but they do not replace the
; portable algorithms
; address p must be aligned by 16 (movaps) and
; size n must be divisible by 16. v/alue must
; be 32BIT or use 1/2 macros to expand
function memory.set.fast, p, v, n
. r0=p, r2=v, r1=n,\ ; start at end
r0+r1, neg r1 ; negate index
movd xmm0, r2
pshufd xmm0, xmm0, 0 ; duplicate dwords
@@:
movaps [r0+r1], xmm0
add r1, 16
jnz @b
endf
macro memory.set.2.fast p, v, n {
. r0=v, r0*00010001h
memory.set.fast p, r0, n
}
macro memory.set.1.fast p, v, n {
. r0=v, r0*01010101h
memory.set.fast p, r0, n
}
; destiny a/ddress must be aligned by 16 and
; size n must be divisible by 16
function memory.copy.fast.a, a, b, n
. r0=a, r2=b, r1=n,\
r0+r1, r2+r1, neg r1
@@:
movaps xmm0, [r2+r1]
movaps [r0+r1], xmm0
add r1, 16
jnz @b
endf
; unaligned...
function memory.copy.fast, a, b, n
. r0=a, r2=b, r1=n,\
r0+r1, r2+r1, neg r1
@@:
movups xmm0, [r2+r1]
movups [r0+r1], xmm0
add r1, 16
jnz @b
endf

View File

@ -0,0 +1,956 @@
; $$$$$$$$$$$$$$$$$$$ 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

View File

@ -0,0 +1,231 @@
;;;;;;;;;;;;;;;;;;;;; SYSTEM ;;;;;;;;;;;;;;;;;;;;;
; menuet interrupt: eax, ebx, ecx, edx
macro mint a, b, c, d {
IF ~a eq
. r0=a
END IF
IF ~b eq
. r3=b
END IF
IF ~c eq
. r1=c
END IF
IF ~d eq
. r2=d
END IF
db 0CDh, 40h
}
; events
EVENT.REDRAW=1
EVENT.KEY=2
EVENT.BUTTON=3
align
integer timer.speed=-1,\
timer.counter, event.delay=1
macro set.timer n {
. r0=n, r1=10, r0/r1
. timer.speed=r0, timer.counter=r0
}
macro get.timer { mint 26, 9 }
macro delay x {
. r0=x, r0/100, r3=r0
mint 5
}
macro wait.event { mint 23, event.delay }
;;;;;;;;;;;;;;;;;;;;; WINDOW ;;;;;;;;;;;;;;;;;;;;;
function draw.window
. r2=0, r6=0, r7=0FFFFFFh
. r3=WINDOW.X, r3<<16, r3|screen.w
. r1=WINDOW.Y, r1<<16, r1|screen.h
mint 0
endf
macro draw.begin { mint 12, 1 }
macro draw.end { mint 12, 2 }
macro render { call !on.draw } ; mint 15, 3
macro retrace { mint 18, 14 }
;;;;;;;;;;;;;;;;;;;;; INPUT ;;;;;;;;;;;;;;;;;;;;;;
align 4
align
integer event.type
integer key, old.key, key.event
text keys.t(128)
numeric KEY.ESCAPE=27, KEY.SPACE=' ',\
KEY.UP=0B2h, KEY.RIGHT=0B3h, KEY.DOWN=0B1h,\
KEY.LEFT=0B0h, KEY.A='a', KEY.S='s',\
KEY.D='d', KEY.W='w'
macro get.key.buffer { mint 26, 2, 1, keys.t }
integer mouse.event,\
mouse.1, mouse.2, mouse.x, mouse.y,\
mouse.drag, mouse.drag.x, mouse.drag.y,\
mouse.drop, mouse.drop.x, mouse.drop.y,\
old.mouse.1, old.mouse.2,\
old.mouse.x, old.mouse.y
macro get.mouse.xy { mint 37, 0 }
macro get.mouse.buttons { mint 37, 2 }
macro get.mouse.wheel { mint 37, 3 }
function update.mouse
. mouse.event=0
. old.mouse.1=mouse.1, old.mouse.2=mouse.2
. old.mouse.x=mouse.x, old.mouse.y=mouse.y
get.mouse.xy
. r1=r0, r1&0FFFFh, r0>>>16, r0&0FFFFh
. mouse.x=r0, mouse.y=r1
get.mouse.buttons
. r1=r0, r1&1, mouse.1=r1
. r1=r0, r1&2, mouse.2=r1
if mouse.1
if not old.mouse.1, mouse.event='c'
. mouse.drop=NO
callf on.mouse
return 1
end
else.if old.mouse.1, mouse.event='r'
callf on.mouse
if mouse.drag
. mouse.drop=YES,\
mouse.drop.x=mouse.x,\
mouse.drop.y=mouse.y,\
mouse.drag=NO
. mouse.event='d'
callf on.mouse
end
return 1
end
. r0=mouse.x, r1=old.mouse.x
if r0<>r1
.mouse.move:
. mouse.event='m'
callf on.mouse
if mouse.1
if not mouse.drag
. mouse.drag=YES,\
mouse.drag.x=mouse.x,\
mouse.drag.y=mouse.y
end
else
. mouse.drop=NO
end
return 1
else
. r0=mouse.y, r1=old.mouse.y
if r0<>r1
go .mouse.move
end
end
endf 0
function select.box, box
. r0=mouse.x, r1=mouse.y
. r0-WINDOW.X, r1-WINDOW.Y
callf point.inside, box, r0, r1
endf
macro if.select box { !if select.box, box }
macro else.if.select box
{ !else.if select.box, box }
;;;;;;;;;;;;;;;;;;;;; RANDOM ;;;;;;;;;;;;;;;;;;;;;
align integer @seed
; generate unique random number: 0-n
function random, n
. r0=@seed
if false
rdtsc
. @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
;;;;;;;;;;;;;;;;;;;;;; MAIN ;;;;;;;;;;;;;;;;;;;;;;
; main entry. detect current input states,
; translate and redirect to on.event handlers.
; drawing has slight flicker. no double
; buffer yet. kolibri only supports misaligned
; 24BPP images :( images should be stored in
; memory as 1-8BPP or 16/32BPP for fast access
!main:
callf set.screen,\
SCREEN.W, SCREEN.H, SCREEN.BPP
callf on.create
get.event:
wait.event
. event.type=r0
update.mouse
if timer.speed<>-1
. timer.counter--
if timer.counter<=0
. timer.counter=timer.speed
callf on.timer
end
end
if event.type=EVENT.REDRAW
; draw.begin
callf draw.window
callf on.draw
; draw.end
; retrace ; ?
else.if event.type=EVENT.KEY
mint 2
if r0<>1, r0>>8, r0&0FFh, key=r0
. key.event='k'
callf on.key
. key.event='c'
callf on.key
if key=KEY.ESCAPE
callf exit
end
end
else.if event.type=EVENT.BUTTON
callf exit
end
go get.event
function exit
callf on.exit
mint -1
endf

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
; 100+ words/phrases. maximum 3 words,
; 1-12 letters each. example:
; 'PREPROCESSOR' = 12
text words.ta[]=\
'ABSTRACT SYNTAX TREE',\
'ACCUMULATOR',\
'ADDRESS SIZE OVERRIDE',\
'ADDRESSING MODE',\
'ARRAY BOUNDS EXCEPTION',\
'ARITHMETIC LOGICAL UNIT',\
'ARTIFICIAL INTELLIGENCE', 'ASSEMBLER',\
'BARREL SHIFTER', 'BINARY TREE',\
'BINARY ARITHMETIC', 'BITS AND BYTES',\
'BITWISE OPERATION', 'BREAKPOINT',\
'CALLING CONVENTION',\
'CENTRAL PROCESSING UNIT', 'CPU CLOCK CYCLE',\
'COMPRESSION SCHEME', 'COMPUTER',\
'CONDITIONAL ASSEMBLY',\
'COSINE OF ANGLE', 'DATA ALIGNMENT',\
'DIRECT MEMORY ACCESS', 'DISASSEMBLER',\
'DIVIDE BY ZERO', 'DRAW TRANSPARENT BITMAP',\
'DYNAMIC ARRAY', 'DYNAMIC BINARY TRANSLATION',\
'EFFECIENT ALGORITHM', 'ENCRYPTION',\
'EXPRESSION PARSER', 'FILE INPUT OUTPUT',\
'FIXED POINT DIVISION',\
'FLAT ASSEMBLER', 'FLOATING POINT UNIT',\
'FLOPPY DISK', 'FOUR BIT MULTIPLIER',\
'FUNCTION PROTOTYPE',\
'FUNCTION EPILOGUE SEQUENCE',\
'GIGABYTE', 'GLOBAL VARIABLE',\
'EXTERNAL HARD DRIVE', 'HARDWARE INTERRUPT',\
'HELLO WORLD', 'HEXADECIMAL EDITOR',\
'HIGH LEVEL ASSEMBLER', 'HYPOTENUSE',\
'IF EXPRESSION', 'INFINITE LOOP',\
'INSTRUCTION POINTER',\
'INTEGRATED CIRCUIT',\
'KEYBOARD AND MOUSE', 'KOLIBRI OS',\
'LINKED LIST', 'LOCAL VARIABLES',\
'LOCAL DESCRIPTOR TABLE', 'LOGARITHM',\
'LOGIC GATE', 'LOOKUP TABLE',\
'MACHINE LANGUAGE', 'MACRO INSTRUCTION',\
'MEMORY COPY', 'MOTHERBOARD', 'MENUET OS',\
'MULTIPLE INHERITANCE',\
'NATURAL LOGARITHM', 'NO OPERATION',\
'NULL POINTER', 'NUMERIC CONSTANT',\
'OBJECT ORIENTED PROGRAMMING',\
'OPCODE', 'OPERATING SYSTEM',\
'OPTIMIZATION', 'STACK OVERFLOW',\
'PARAMETERS AND LOCALS', 'PIPELINE',\
'POINTER OPERATION', 'PORTABLE EXECUTABLE',\
'POSITION INDEPENDANT CODE',\
'POWERS OF TWO', 'PRECEDENCE',\
'PREPROCESSOR DIRECTIVE',\
'PRINT FORMATTED TEXT', 'PROCEDURE',\
'PROTECTED MODE', 'RANDOM ACCESS MEMORY',\
'READ ONLY MEMORY', 'RECURSIVE FUNCTION',\
'REGISTER', 'RELATIONAL OPERATOR',\
'RELATIVE OFFSET', 'RETURN VALUE',\
'REVERSE ENGINEERING',\
'REVERSE POLISH NOTATION',\
'SCALED INDEX BYTE', 'SEGMENT PREFIX',\
'SIGNED INTEGER OVERFLOW', 'SILICON CHIP',\
'SOFTWARE INTERRUPT', 'SOURCE AND DESTINY',\
'SPRITE ANIMATION', 'STRING LENGTH',\
'STRUCTURE', 'SYMBOLIC CONSTANT',\
'TOMASZ GRYSZTAR',\ ; :)
'TRANSISTOR', 'TRUTH TABLE', 'TWO BIT ADDER',\
'UNSIGNED INTEGER', 'VARIABLE DECLARATION',\
'VIDEO CARD', 'VIDEO GRAPHICS ARRAY',\
'VIRTUAL MACHINE', 'VIRTUAL MEMORY'
N.WORDS=words.ta.$-1
; pointer array
align
words.pa dd N.WORDS dup(0)

View File

@ -0,0 +1,231 @@
; KOLIBRI PUZZLE CHALLENGE
TILE.W=64
TILE.H=64
MAP.X=TILE.W
MAP.Y=TILE.H
MAP.W=8
MAP.H=8
PUZZLE.W=MAP.W*TILE.W
PUZZLE.H=MAP.H*TILE.H
WINDOW.W=PUZZLE.W+(TILE.W*2)
WINDOW.H=PUZZLE.H+(TILE.H*2)
include 'a.inc'
text title(64)='Kolibri Puzzle Challenge'
align
integer scene
numeric SCENE.*, TITLE, PLAY, SOLVED
integer solved, select.x, select.y
puzzle: db (MAP.W*MAP.H*4) dup(0)
numeric NORMAL, ROTATE.R, INVERT.XY, ROTATE.L
IMAGE piece.i
piece.pixels: db (TILE.W*TILE.H*4) dup(0)
BOX my.box, puzzle.box
integer grid.color=WHITE
IMAGE kolibri.i='kolibri', logo.i='logo2',\
wood1.i='wood1', wood2.i='wood2',\
close.i='x', solved.i='solved'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get.random equ random.x ROTATE.R, ROTATE.L
function erase.puzzle
memory.zero piece.pixels, (TILE.W*TILE.H*4)
endf
function randomize.puzzle
locals q, n
alias p=r0, x=r1
. q=puzzle, n=(MAP.W*MAP.H)
loop n
. x=ROTATE.L, p=q, (u32) *p=x, q+4
endl
endf
function reset.game
randomize.puzzle
endf
function on.create
erase.puzzle
. scene=SCENE.TITLE
set.box puzzle.box,\
MAP.X, MAP.Y, PUZZLE.W, PUZZLE.H
endf
function is.solved
locals n
alias p=r0, x=r1
. p=puzzle, n=(MAP.W*MAP.H)
loop n, (u32) x=*p++
if x<>NORMAL, return 0, end
endl
endf 1
function get.piece, x, y
. r0=y, r0*MAP.W, r0+x, r0*4, r0+puzzle
endf
function get.piece.rotate, x, y
get.piece x, y
. (u32) r0=*r0
endf
function set.piece.rotate, x, y, r
if r>ROTATE.L, r=0, end
get.piece x, y
. r1=r, (u32) *r0=r1
is.solved
if true
. scene=SCENE.SOLVED
end
endf
function copy.piece, x, y
locals w, h, pw
alias p=r0, s=r1, n=r2
. p=piece.pixels, piece.i.p=p
. piece.i.w=TILE.W, piece.i.h=TILE.H
. n=PUZZLE.W, n*4, pw=n
. n=y, n*pw, n*TILE.W
. s=x, s*TILE.W, s*4, n+s
. s=kolibri.i.p, s+n
. h=TILE.H
loop h, w=TILE.W
loop w, (u32) *p++=*s++
endl
. n=TILE.W, n*4, s-n, s+pw
endl
endf
function draw.piece, px, py, x, y
locals z
get z=get.piece.rotate px, py
copy.piece px, py
if z=NORMAL
draw.image piece.i, x, y
else.if z=ROTATE.R
draw.image.rr piece.i, x, y
else.if z=INVERT.XY
. r0=y, r0+TILE.H
draw.image.ixy piece.i, x, r0
else.if z=ROTATE.L
draw.image.rl piece.i, x, y
end
endf
function draw.puzzle
locals x, y
. y=0
while y<8, x=0
while x<8
. r0=x, r0*TILE.W, r0+MAP.X
. r1=y, r1*TILE.H, r1+MAP.Y
draw.piece x, y, r0, r1
. x++
endw
. y++
endw
endf
function draw.grid
locals x, y
. y=0
while y<8, x=0
while x<8
. r0=x, r0*TILE.W, r0+MAP.X
. r1=y, r1*TILE.H, r1+MAP.Y
draw.outline r0, r1,\
TILE.W, TILE.H, grid.color
. x++
endw
. y++
endw
endf
function draw.wood.frame
draw.image wood1.i, 0, 0
draw.image wood1.i, 0, WINDOW.H-TILE.H
draw.image wood2.i, 0, TILE.H
draw.image wood2.i, WINDOW.W-TILE.W, TILE.H
draw.image close.i, WINDOW.W-40, 8
endf
function on.draw
draw.wood.frame
draw.puzzle
if scene=SCENE.TITLE
draw.box.o puzzle.box, grid.color
end
if scene=SCENE.PLAY
draw.grid
end
if scene=SCENE.SOLVED
draw.image.v solved.i, 132, 13, WHITE
else
draw.image.v logo.i, 180, 13, WHITE
end
endf
function on.key
; ...
endf
function get.select.xy
. r0=mouse.x, r0-MAP.X, r0-WINDOW.X
. r1=TILE.W, r0/r1, select.x=r0
. r0=mouse.y, r0-MAP.Y, r0-WINDOW.Y
. r1=TILE.H, r0/r1, select.y=r0
endf
function on.mouse
locals r
if mouse.event='c'
. r0=&close.i.x
if.select r0
exit
end
if scene=SCENE.TITLE
reset.game
. scene=SCENE.PLAY
go .draw
end
if scene=SCENE.PLAY
if.select puzzle.box
get.select.xy
get r=get.piece.rotate \
select.x, select.y
. r++
set.piece.rotate \
select.x, select.y, r
go .draw
end
end
if scene=SCENE.SOLVED
reset.game
. scene=SCENE.TITLE
go .draw
end
.draw:
render
end
endf
function on.timer
; ...
endf
function on.exit
; ...
endf

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB