a wild codebox approaches:
Code:
.nolist
#include "ti83plus.inc"
#include "ti83plusasm.inc" ;yea, im including both....
#define ProgStart $9D95 -2
.list
itemdata .equ appbackupscreen
balldata2 .equ itemdata+140 ;never used atm...
.org ProgStart
.db t2ByteTok, tAsmCmp
XOR A
JR NC,start
.db "arkanoid by darkstone",$00
drawmap:
LD HL,map
LD DE,0
yloop:
xloop:
LD A,(HL)
INC HL
ADD A,A ;2
LD B,A ;2
add a,a ;4
add a,B ;6
LD B,0
LD C,A
LD IX,tiles
ADD IX,BC
push HL
push DE ;de bevat de bestemming.. D=X E=Y
LD B,6 ;hoogte
;IX beval al de spritedata
CALL putspritexor
POP DE
POP HL
;coordinated updaten... we moeten 8 optellen bij D
LD A,8 ;\
ADD A,D ; >onhandig... maargoed
LD D,A ;/
CP 12*8 ;als hij bij de laatste kolom is
JR NZ,xloop
LD D,0
LD A,6
ADD A,E
LD E,A
CP 5*6
JR NZ,yloop
RET
start:
LD DE,plotsscreen+1\ LD HL,plotsscreen
LD (HL),0\ LD BC,(12*64-1)\ LDIR
LD (ssp),sp
CALL drawmap
CALL draw_all ;draw
mainloop:
CALL draw_all ;erase buffer
CALL getkey ;update everyting
CALL psysics
CALL delete_items
CALL draw_all ;draw shit
CALL fastcopy
JR mainloop
; #################################
; # DRAWING ROUTINES #
; #################################
draw_all
CALL drawball
CALL drawpad
CALL drawitems
RET
drawpad:
LD A,(xpad)
LD D,A
LD E,61 ;y
LD B,3 ;height
LD IX,pad
CALL putspritexor
LD A,(xpad)
ADD A,8
LD D,A
LD E,61 ;y
LD B,3 ;height
LD IX,pad2
CALL putspritexor
RET
drawball:
LD A,(balls)
or A
RET Z
LD HL,balldata
push HL
drawballoop
POP HL
LD DE,yball
LDI\ LDI\ LDI\ LDI
LDI\ LDI\ LDI\ LDI
push HL
;laad goede data
push AF
LD DE,(xball)
LD A,(yball+1)
LD E,A
LD B,4 ;height
LD IX,ball
CALL putspritexor
POP AF
DEC A
JR NZ,drawballoop
POP HL
RET
drawitems:
; dx
; X
; Y LSB,Y MSB
; type # (sprite, #powerup)
; sprite location
LD A,(itemamount)
OR A
RET Z
LD B,A
LD IX,itemdata
itemdrawloop:
push BC
LD D,(IX+1)
LD E,(IX+3)
LD H,(IX+6)
LD L,(IX+5)
push IX
push HL\ POP IX
LD B,4
CALL putspritexor
POP IX
LD BC,7
ADD IX,BC
POP BC
DJNZ itemdrawloop
RET
; #########################
; # PSYSICS #
; #########################
psysics: ;eerst hit- detect, dan coordinaten updaten
LD A,(balls)
or A\ RET Z
LD B,A
LD HL,balldata
drawballoop2:
push BC
LD DE,yball
LDI\ LDI\ LDI\ LDI ;coordinaten laden
LDI\ LDI\ LDI\ LDI
push HL
CALL hit_detect_pad
CALL hit_detect_wall
CALL hit_detect_blocks
CALL update_ball_pos
;coordinaten terugplaatsen
POP HL
LD DE,-8
ADD HL,DE
EX DE,HL ;de = itemdata + nogwat
LD HL,yball
LDI\ LDI\ LDI\ LDI ;coordinaten laden
LDI\ LDI\ LDI\ LDI
EX DE,HL ;intemdata terugplaatsen in HL
POP BC
DJNZ drawballoop2
CALL update_item_pos
RET
hit_detect_pad:
LD A,(yball+1)
CP 58
RET C ;stoppen als de ball y groter is dan 60
;je moet eerst de afstond van de ball tot het batje berekenen, dat is ball-(pad+(lengt/2)
;het batje is 16 breed, dus je moet er -8 bij optellen
LD A,(xpad)
ADD A,8
LD B,A
LD A,(xball+1) ;ge kan aleen LD A,(addr) doen?
sub B
LD B,A
;nu moet je dit positief maken
bit 7,a
jr Z,skipz
CPL
INC A
skipz:
;nu moet je kijken of de afstand kleiner is dan 9
CP 9
RET nC
;je weet nu de afstand van de bal tot het midden van het batje, je berekent nu de nieuwe hoek
;met de formule: dx = dx + afstand * 10
;b bevat noig steeds de afstand
LD HL,(dx)
SLA B
SLA B
LD E,B
LD D,B
SRA D\ SRA D\ SRA D
SRA D\ SRA D\ SRA D\ SRA D
ADD HL,DE
LD (DX),HL
;nu kijk je of dy positief is
LD DE,(dy)
bit 7,D
RET NZ
LD HL,0
SBC HL,DE
LD (dy),HL
RET
hit_detect_wall:
LD A,(xball+1)
dec A
bit 7,A
JR Z,leftwall ;hij skipt hem dus..
LD DE,(dx)
bit 7,D
JR Z,leftwall
LD HL,0
SBC HL,DE ;nobody cares about 1/255 pixels...
LD (dx),HL
leftwall:
LD A,(xball+1)
sub 92
bit 7,A
JR NZ,rightwall
LD DE,(dx)
bit 7,D
JR NZ,rightwall
LD HL,0
SBC HL,DE ;nobody cares about 1/255 pixels...
LD (dx),HL
rightwall:
LD A,(yball+1)
CP 0
JR NZ,topwall
LD DE,(dy)
LD HL,0
SBC HL,DE
LD (DY),HL
topwall:
RET
update_ball_pos:
LD HL,(xball)
LD DE,(dx)
ADD HL,DE
LD (xball),HL
LD HL,(yball)
LD DE,(dy)
ADD HL,DE
LD (yball),HL
RET
; dy
; X
; Y LSB,Y MSB
; type # (sprite, #powerup)
; sprite location
UPDATE_ITEM_pos
LD A,(itemamount)
OR A
RET Z
LD B,A
LD IX,itemdata
Update_item_loop:
push BC
LD D,0
LD E,(IX)
LD H,(IX+3)
LD L,(IX+2)
ADD HL,DE
LD (IX+3),H
LD (IX+2),L
LD DE,7
ADD IX,DE
pop BC
DJNZ update_item_loop
RET
; #########################
; # HIT DETECT #
; #########################
hit_detect_blocks:;deze routine moet opgesplits worden in meerdere CALL's
;we spitten het op:
; hit op bovenkant
; hit op onderkant
; hit op rechterkant
; hit op linkerkant
;het is de bedoeling dat dit waterdicht is... je wilt hem niet in een blok hebben..
CALL top_hit
CALL bottom_hit
CALL Right_hit
CALL Left_hit
RET
top_hit:
LD A,(yball+1)
ADD A,3
LD L,0
LD B,6
div_by_6_loop:
INC L
SUB B
RET C ;als carry geflagd is, dan resulteerde a + -6 in een negatief getal, exit
JR NZ,div_by_6_loop ;als hij 0 is, raakt hij iets
;B bevat nu de correcte ypos in de array, yay
;maar de array is 5 hoog, dus als hij groter is dan 4, dan raakt hij helemaal niets
LD A,L
CP 5
RET NC ;als a-5 negatief is...
;vervolgens word gecheckt of dy wel positief is
LD A,(Dy+1)
bit 7,A
RET NZ ;exit als bit 7 is geset (dy is negatief)
;nu berekenen we de xpositie in de array, dat is x/8
LD A,(xball+1)
ADD A,2 ;midden van bal
SRA A
SRA A
SRA A
CALL calucatemappos
LD DE,(dy)
LD HL,0
SBC HL,DE
LD (DY),HL
RET
Bottom_hit:
LD A,(yball+1)
DEC A ;om het blokje te raken moet hij "erin" zitten
LD L,0
LD B,6
div_by_6_loop2:
INC L
SUB B
RET C ;als carry geflagd is, dan resulteerde a - 6 in een negatief getal, exit
JR NZ,div_by_6_loop2 ;loopen totdat hij resulteert in een 0 (lees: mod(x/6)=0
;B bevat nu de correcte ypos in de array, yay
;maar de array is 5 hoog, dus als hij groter is dan 4, dan raakt hij helemaal niets
LD A,L
CP 6
RET NC ;als a-5 negatief is...
DEC L
;vervolgens word gecheckt of dy wel negatief is
LD A,(Dy+1)
bit 7,A
RET Z ;exit als bit 7 is geset (dy is positief)
;nu berekenen we de xpositie in de array, dat is x/8
LD A,(xball+1)
ADD A,1 ;midden van bal
SRA A
SRA A
SRA A
CALL calucatemappos
LD DE,(dy)
LD HL,0
SBC HL,DE
LD (DY),HL
RET
right_hit: ;hij raakt een blok aan de rechterkant, dus A/8 = rest 0
LD A,(xball+1)
LD H,A
xor A ;zero A
OR A ;delen door 8, rest in A
RR H
RRA
RR H
RRA
RR H
RRA
CP 0
RET NZ ;stop als de rest geen 0 is
DEC H
;H bevat nu de correcte xpos in de array, yay
;vervolgens word gecheckt of dx wel negatief is
LD A,(Dx+1)
bit 7,A
RET Z ;exit als bit 7 is reset (dy is positief)
;nu berekenen we de ypositie in de array, dat is x/6
; de ypositie is nog steeds in L
LD L,-1 ;zero xpos
LD A,(yball+1)
ADD A,2 ;midden van bal
loopz:
INC L
ADD A,-6
JR C,loopz
LD A,L
CP 5
RET NC ;quit
LD A,H
CALL calucatemappos
LD DE,(dx)
LD HL,0
SBC HL,DE
LD (Dx),HL
RET
left_hit: ;hij raakt een blok aan de linkerkant, dus (A+3)/8 = rest 0
LD A,(xball+1)
ADD A,3
LD H,A
xor A ;zero A
OR A ;delen door 8, rest in A
RR H\ RRA
RR H\ RRA
RR H\ RRA
CP 0
RET NZ ;stop als de rest geen 0 is
;H bevat nu de correcte xpos in de array, yay
;vervolgens word gecheckt of dx wel negatief is
LD A,(Dx+1)
bit 7,A
RET NZ ;exit als bit 7 is geset (dy is negatief)
;nu berekenen we de ypositie in de array, dat is x/6
; de ypositie is nog steeds in L
LD L,-1 ;zero xpos
LD A,(yball+1)
ADD A,2 ;midden van bal
loopz1
INC L
ADD A,-6
JR C,loopz1
LD A,L
CP 5
RET NC
LD A,H
; LD A,0
; LD (currow),A
; LD (currow+1),A
; LD H,0
; BCALL(_dispHL)
; BCALL(_getkey)
; RET
CALL calucatemappos
LD DE,(dx)
LD HL,0
SBC HL,DE
LD (Dx),HL
RET
calucatemappos: ;X in A, Y in L
push AF
push HL
LD D,0
LD H,0
LD E,L
ADD HL,HL ;2
ADD HL,DE ;3
ADD HL,HL ;6
ADD HL,HL ;12
LD E,A ;xpos
ADD HL,DE
LD DE,map
ADD HL,DE
;HL bevat nu de correcte array positie, de we kijken wat erin zit
LD A,(HL)
;indien hij 0 is moeten we uiteraard stoppen
OR A
JR NZ,skip
POP AF ;verwijder data
POP HL
POP HL ;verwijder CALL, ga naar _hit detect xxxx
RET
skip:
LD B,A
LD (HL),0
pop HL
POP AF
CALL create_item
LD HL,plotsscreen
LD DE,plotsscreen+1
LD BC,5*6*12-1
LD (HL),0
LDIR ;wis buffer
CALL drawmap
RET
; #########################
; # ITEM ROUTINES #
; #########################
Create_item: ;X in A, Y in L, type in B
push AF
push HL
LD A,(itemamount)
INC A
LD (itemamount),A
DEC A
LD H,0
LD L,A
LD D,H
LD E,L
ADD HL,HL ;2
ADD HL,HL ;4
ADD HL,DE ;5
ADD HL,DE ;6
ADD HL,DE ;7
LD DE,itemdata
ADD HL,DE ;adres van nieuwe item data
LD A,B
POP BC
LD B,A
LD A,C
ADD A,A ;2
LD C,A
ADD A,A ;4
ADD A,C ;6
LD C,A
LD A,60
sub C ;64 - (y*6)
POP AF ;maak de coordinaten klaar
ADD A,A ;\
ADD A,A ;|maal 8
ADD A,A ;/
; C=y
; A=x
; B=type
LD (HL),32 ;Dy
INC HL\ LD (HL),A ;x
INC HL\ LD (HL),0 ;LSB ypos
INC HL\ LD (HL),C ;MSB ypos
INC HL\ LD (HL),B ;type, niets op dit moment
;nu moeten we, uit B, de correcte sprite positie berekenen
push HL
DEC B
LD A,B
ADD A,A
ADD A,A
LD D,0
LD E,A
LD HL,itemsprites
ADD HL,DE
EX DE,HL
POP HL
INC HL\ LD (HL),E ;itemsprites + 4
INC HL\ LD (HL),D ;itemsprites + 4 / 256
RET
Delete_items: ;y>64, then delete
;ypos is 4th byte
LD HL,itemdata+3 ;eerste item
LD A,(itemamount)
or A
RET Z ;exit als er geen item zijn
LD B,A
LD C,0 ;nth item
LD DE,7 ;object lengt
delete_items_loop
LD A,(HL) ;get msb y
CP 64 ;check for y > 64 (offscreen)
CALL z,delete_item
ADD HL,DE ;advance pointer
INC C ;advance to next item
DJNZ delete_items_loop
RET
delete_item ;deletes an item, N in C
push HL
push BC
push DE
LD A,(itemamount)
dec A ;itemamount begint bij 1, c bij 0
CP C
JR z,lastitem ;als je op het laatste item staat hoef je niets te veranderen
;aleen itemamount aanpassen
LD A,C
ADD A,A ;2
ADD A,A ;4
ADD A,C ;5
ADD A,C ;6
ADD A,C ;7
LD E,A
LD D,0
LD HL,itemdata
ADD HL,DE ;bevat itemadres
push HL ;sla bestemming op (DE)
LD DE,7
ADD HL,DE ;volgende item,
push HL ;sla data pointer op (HL)
;nu bereken je BC, dat is (itemamount - c) * 7
;c is nooit gelijk aan a
LD A,(itemamount)
DEC A
sub C
LD C,A
ADD A,A ;2
ADD A,A ;4
ADD A,C ;5
ADD A,C ;6
ADD A,C ;7
LD C,A
LD B,0
POP HL
POP DE
LDIR ;hehe
lastitem:
LD A,(itemamount)
DEC A
LD (itemamount),A
pop DE
pop BC
pop HL
DEC C
LD DE,-7
ADD HL,DE
LD DE,7
RET
; #########################
; # GETKEY #
; #########################
getkey:
LD A,%11111110
out (1),a
LD HL,xpad
nop\ nop
IN A,(1)
push AF
push AF
bit 1,A ;left
CALL Z,left
POP AF
BIT 2,A ;right
CALL Z,right
POP AF
bit 0,A ;left
JR Z,getkey
LD A,%11111101 ;FD
out (1),A
NOP\ NOP
in A,(1)
CP $BF
JR Z,exit
RET
left:
LD A,(HL)
CP 0
RET Z
DEC (HL)
RET
right:
LD A,(HL)
CP 10*8
RET Z
INC (HL)
RET
exit:
LD SP,(ssp)
RET
; #########################
; # GAME DATA #
; #########################
ssp:
.dw 0
xpad:
.db 40
yball: ;data is 8 bytes each, located in plotsscreen+140
.db 0,50
xball:
.db 0,30
dy:
.db -256/2,-1
dx:
.db -256/2,-1
balldata:
.db 0,50,0,35
.db -256/2,-1,-256/2,-1
.db 0,50,0,30
.db -256/2,-1,-256/2,-1
.db 0,50,0,40
.db -256/2,-1,-256/2,-1
.db 0,50,0,45
.db -256/2,-1,-256/2,-1
.db 0,50,0,50
.db -256/2,-1,-256/2,-1
.db 0,50,0,55
.db -256/2,-1,-256/2,-1
.db 0,50,0,60
.db -256/2,-1,-256/2,-1
.db 0,50,0,65
.db -256/2,-1,-256/2,-1
.db 0,50,0,70
.db -256/2,-1,-256/2,-1
.db 0,50,0,75
.db -256/2,-1,-256/2,-1
itemamount:
.db 0,0
balls:
.db 10
;itemdata:
; dx
; X
; Y LSB,Y MSB
; type # (sprite, #powerup)
; sprite location
ball:
.db %01100000
.db %11110000
.db %11010000
.db %01100000
pad:
.db %01111111
.db %11111111
.db %01111111
pad2:
.db %11111110
.db %11111111
.db %11111110
tempsprite:
.db 0,0,0,0,0,0
map:
.db 0,0,0,0,0,0,0,0,0,0,0,0
.db 0,2,0,1,2,1,1,2,1,0,2,0
.db 0,2,0,1,2,1,1,2,1,0,2,0
.db 0,2,0,1,2,1,1,2,1,0,2,0
.db 0,2,0,1,2,1,1,2,1,0,2,0
tiles:
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %10101011
.db %11010101
.db %10101011
.db %11010101
.db %11111111
itemsprites:
.db %01111110
.db %11111111
.db %11111111
.db %01111110
.db %01111110
.db %11010101
.db %10101011
.db %01111110
;###############################################################################
###########################
;###############################################################################
###########################
;###############################################################################
###########################
;###############################################################################
###########################
;-----> Copy the gbuf to the screen (fast)
;Input: nothing
;Output:graph buffer is copied to the screen
fastCopy:
DI
ld a,$80
out ($10),a
ld hl,plotsscreen-12-(-(12*64)+1)
ld a,$20
ld c,a
inc hl
dec hl
fastCopyAgain:
ld b,64
inc c
ld de,-(12*64)+1
out ($10),a
add hl,de
ld de,10
fastCopyLoop:
add hl,de
inc hl
inc hl
inc de
ld a,(hl)
out ($11),a
dec de
djnz fastCopyLoop
ld a,c
cp $2B+1
jr nz,fastCopyAgain
ret
putspritexor
; D = xpos
; E = ypos
; B = height
; IX = image address
; Start by doing vertical clipping
LD A, %11111111 ; Reset clipping mask
LD (clip_mask), A
LD A, E ; If ypos is negative
OR A ; try clipping the top
JP M, ClipTop ;
SUB 64 ; If ypos is >= 64
RET NC ; sprite is off-screen
NEG ; If (64 - ypos) > height
CP B ; don't need to clip
JR NC, VertClipDone ;
LD B, A ; Do bottom clipping by
JR VertClipDone ; setting height to (64 - ypos)
ClipTop:
LD A, B ; If ypos <= -height
NEG ; sprite is off-screen
SUB E ;
RET NC ;
PUSH AF
ADD A, B ; Get the number of clipped rows
LD E, 0 ; Set ypos to 0 (top of screen)
LD B, E ; Advance image data pointer
LD C, A ;
ADD IX, BC ;
POP AF
NEG ; Get the number of visible rows
LD B, A ; and set as height
VertClipDone:
; Now we're doing horizontal clipping
LD C, 0 ; Reset correction factor
LD A, D
CP -7 ; If 0 > xpos >= -7
JR NC, ClipLeft ; clip the left side
CP 96 ; If xpos >= 96
RET NC ; sprite is off-screen
CP 89 ; If 0 <= xpos < 89
JR C, HorizClipDone ; don't need to clip
ClipRight:
AND 7 ; Determine the clipping mask
LD C, A
LD A, %11111111
FindRightMask:
ADD A, A
DEC C
JR NZ, FindRightMask
LD (clip_mask), A
LD A, D
JR HorizClipDone
ClipLeft:
AND 7 ; Determine the clipping mask
LD C, A
LD A, %11111111
FindLeftMask:
ADD A, A
DEC C
JR NZ, FindLeftMask
CPL
LD (clip_mask), A
LD A, D
ADD A, 96 ; Set xpos so sprite will "spill over"
LD C, 12 ; Set correction
HorizClipDone:
; A = xpos
; E = ypos
; B = height
; IX = image address
; Now we can finally display the sprite.
LD H, 0
LD D, H
LD L, E
ADD HL, HL
ADD HL, DE
ADD HL, HL
ADD HL, HL
LD E, A
SRL E
SRL E
SRL E
ADD HL, DE
LD DE, PlotSScreen
ADD HL, DE
LD D, 0 ; Correct graph buffer address
LD E, C ; if clipping the left side
SBC HL, DE ;
AND 7
JR Z, _Aligned
LD C, A
LD DE, 11
_RowLoop:
PUSH BC
LD B, C
LD A, (clip_mask) ; Mask out the part of the sprite
AND (IX) ; to be horizontally clipped
LD C, 0
_ShiftLoop:
SRL A
RR C
DJNZ _ShiftLoop
XOR (HL)
LD (HL), A
INC HL
LD A, C
XOR (HL)
LD (HL), A
ADD HL, DE
INC IX
POP BC
DJNZ _RowLoop
RET
_Aligned:
LD DE, 12
_PutLoop:
LD A, (IX)
XOR (HL)
LD (HL), A
INC IX
ADD HL, DE
DJNZ _PutLoop
RET
clip_mask: .DB 0
.end
.end
i comented most stuff in dutch...
if you seach throughly, the only "saferam" area i am using is appbackupscreen and appbackupscreen + someting, bit that is not the probem
it crashed on previous tests, even before i added the item code
excuse my english
Last edited by Guest on 17 Dec 2008 03:13:30 pm; edited 1 time in total |