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
39
programs/games/codemaster/ReadMe.txt
Normal 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/
|
47
programs/games/codemaster/a.inc
Normal 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)
|
||||
}
|
299
programs/games/codemaster/binary_master.asm
Normal 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
|
392
programs/games/codemaster/hang_programmer.asm
Normal 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
|
26
programs/games/codemaster/include/a.inc
Normal 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' }
|
218
programs/games/codemaster/include/box.inc
Normal 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
|
227
programs/games/codemaster/include/color.inc
Normal 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
|
385
programs/games/codemaster/include/draw.inc
Normal 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
|
344
programs/games/codemaster/include/drawk.inc
Normal 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
|
104
programs/games/codemaster/include/font.inc
Normal 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
|
397
programs/games/codemaster/include/image.inc
Normal 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
|
348
programs/games/codemaster/include/imagek.inc
Normal 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
|
2110
programs/games/codemaster/include/language.inc
Normal file
274
programs/games/codemaster/include/memory.inc
Normal 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
|
956
programs/games/codemaster/include/system.inc
Normal 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
|
231
programs/games/codemaster/include/systemk.inc
Normal 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
|
1006
programs/games/codemaster/include/text.inc
Normal file
79
programs/games/codemaster/include/words.txt
Normal 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)
|
231
programs/games/codemaster/kolibri_puzzle.asm
Normal 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
|
BIN
programs/games/codemaster/media/0.bmp
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
programs/games/codemaster/media/1.bmp
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
programs/games/codemaster/media/1000.bmp
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
programs/games/codemaster/media/a/a.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/b.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/c.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/d.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/e.bmp
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
programs/games/codemaster/media/a/f.bmp
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
programs/games/codemaster/media/a/g.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/h.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/i.bmp
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
programs/games/codemaster/media/a/j.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
programs/games/codemaster/media/a/k.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/l.bmp
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
programs/games/codemaster/media/a/m.bmp
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
programs/games/codemaster/media/a/n.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/o.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/p.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/q.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/r.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/s.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/t.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/u.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/v.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/w.bmp
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
programs/games/codemaster/media/a/x.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/y.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/a/z.bmp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
programs/games/codemaster/media/arm1.bmp
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
programs/games/codemaster/media/arm2.bmp
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
programs/games/codemaster/media/bits.bmp
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
programs/games/codemaster/media/board.bmp
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
programs/games/codemaster/media/body.bmp
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
programs/games/codemaster/media/font.bmp
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
programs/games/codemaster/media/head.bmp
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
programs/games/codemaster/media/kolibri.bmp
Normal file
After Width: | Height: | Size: 768 KiB |
BIN
programs/games/codemaster/media/leg1.bmp
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
programs/games/codemaster/media/leg2.bmp
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
programs/games/codemaster/media/logo.bmp
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
programs/games/codemaster/media/logo2.bmp
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
programs/games/codemaster/media/money.bmp
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
programs/games/codemaster/media/smile.bmp
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
programs/games/codemaster/media/solved.bmp
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
programs/games/codemaster/media/stand1.bmp
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
programs/games/codemaster/media/stand2.bmp
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
programs/games/codemaster/media/wood1.bmp
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
programs/games/codemaster/media/wood2.bmp
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
programs/games/codemaster/media/x.bmp
Normal file
After Width: | Height: | Size: 3.1 KiB |