; prototype de test de collision au blitter
;
; OK - afficher une zone 256 couleurs avec OL, rempli de pixels
; OK - effacer la zone au blitter
; - sprite en 256 couleurs, masque 1 couleur = 1 type
; - ennemis
; - tirs ennemis
; - vaisseau joueur
; - tirs joueur
; - blitter 1 sprite sur la zone
; - blitter 1 autre sprite autre couleur
; - idem mais avec test de collision
; - determiner la couleur du pixel destination de collision
; - version GPU...
include "jaguar.inc"
CLEAR_BSS .equ 1 ; 1=efface toute la BSS jusqu a la fin de la ram utilis�e
ob_list_courante equ ((ENDRAM-$4000)+$2000) ; address of read list
nb_octets_par_ligne equ 320
nb_lignes equ 200
CLS equ 1
.opt "~Oall"
.text
.68000
move.l #INITSTACK, sp
move.w #%0000011011000111, VMODE ; 320x256 256c
;move.w #%0000011011000001, VMODE ; 320x256 / CRY / $6C7
move.w #$100,JOYSTICK
; clear BSS
.if CLEAR_BSS=1
; clear BSS
lea DEBUT_BSS,a0
lea FIN_RAM,a1
moveq #0,d0
boucle_clean_BSS:
move.b d0,(a0)+
cmp.l a0,a1
bne.s boucle_clean_BSS
; clear stack
lea INITSTACK-100,a0
lea INITSTACK,a1
moveq #0,d0
boucle_clean_BSS2:
move.b d0,(a0)+
cmp.l a0,a1
bne.s boucle_clean_BSS2
; clear object list
lea ob_list_courante,a0
lea ENDRAM,a1
moveq #0,d0
boucle_clean_BSS3:
move.b d0,(a0)+
cmp.l a0,a1
bne.s boucle_clean_BSS3
.endif
; mettons des couleurs
lea CLUT,a1
move.w #0,(a1)+ ; 0
move.w #$FF00,(a1)+
move.w #$71F0,(a1)+ ; 2
move.w #$FDFF,(a1)+
move.w #$FF0F,(a1)+ ; 4
move.w #$F00F,(a1)+
move.w #$F00F,(a1)+
move.w #$F00F,(a1)+
move.w #$FFFF,(a1)+ ; 8
move.w #$001F,(a1)+ ; couleur 9
;check ntsc ou pal:
moveq #0,d0
move.w JOYBUTS ,d0
move.l #26593900,frequence_Video_Clock ; PAL
move.l #415530,frequence_Video_Clock_divisee
btst #4,d0
beq.s jesuisenpal
jesuisenntsc:
move.l #26590906,frequence_Video_Clock ; NTSC
move.l #415483,frequence_Video_Clock_divisee
jesuisenpal:
bsr InitVideo ; Setup our video registers.
jsr copy_olist ; use Blitter to update active list from shadow
move.l #ob_list_courante,d0 ; set the object list pointer
swap d0
move.l d0,OLP
move.l #VBL,LEVEL0 ; Install 68K LEVEL0 handler
move.w a_vde,d0 ; Must be ODD
sub.w #16,d0
ori.w #1,d0
move.w d0,VI
move.w #%01,INT1 ; Enable video interrupts 11101
;and.w #%1111100011111111,sr ; 1111100011111111 => bits 8/9/10 = 0
and.w #$f8ff,sr
; remplit la zone memoire ecran avec des pixels
lea zone_fond,a0
lea fin_zone_fond,a1
boucle_pixels_fond:
;move.b #1,(a0)+
move.b #2,(a0)+
move.b #3,(a0)+
cmp.l a1,a0
blt.s boucle_pixels_fond
.if CLS=1
; effacer le fond au blitter
move.l #zone_fond,A1_BASE ; = DEST
move.l #0,A1_PIXEL
move.l #PIXEL8|XADDPHR|PITCH1,A1_FLAGS
move.w #1,d0
swap d0
move.l #fin_zone_fond-zone_fond,d1
move.w d1,d0
move.l d0,B_COUNT
move.l #LFU_ZERO,B_CMD
.endif
; -----------------------------------------------------------------------------------
; test de sprites en 1 passe:
;B_CMD :
;- SRCEN => activation de la lecture data source
;- DSTEN => activation de la lecture data destination
;- LFU_REPLACE => �crire SOURCE
;- DCOMPEN => activation du test "if B_PATD = source"
;B_PATD
;- initialis� avec la valeur "0x0000 0000 0000 0000" (64-bit)
move.l #zone_fond,A1_BASE ; = DEST
move.l #(40<<16)+100,A1_PIXEL ; X dest=32 / Y dest=40
move.l #PIXEL8|XADDPIX|PITCH1|WID320,A1_FLAGS
move.l #320,A1_CLIP
move.w #1,d0
swap d0
move.w #-16,d0
move.l d0,A1_STEP
move.l #0,A1_FSTEP
move.l #sprite_fond,A2_BASE ; = source =$08
move.l #0,A2_PIXEL
move.l #PIXEL8|XADDPIX|PITCH1|WID16,A2_FLAGS
move.l #$00,B_PATD
move.w #16,d0 ; 16 lignes
swap d0
move.w #16,d0 ; 16 pixels de largeur
move.l d0,B_COUNT
move.l #SRCEN|DSTEN|LFU_REPLACE|UPDA1|DCOMPEN,B_CMD
; -----------------------------------------------------------------------------------
; deuxieme test de collision, en 1 passe
; fond deja blitt� = destination = $08
; sprite source = $01
move.l #50,d7
move.l #20,d6
test_collision:
move.l #zone_fond,A1_BASE ; = DEST
; collision:
;move.l #(45<<16)+100+5,A1_PIXEL ; X dest=32 / Y dest=40
; pas de collision, les 4 pixels sont entre les 2 colonnes
;move.l #((40+16)<<16)+(100),A1_PIXEL ; X dest=32 / Y dest=40
move.w d6,d5
swap d5
move.w d7,d5
move.l d5, A1_PIXEL
move.l #PIXEL8|XADDPIX|PITCH1|WID320,A1_FLAGS
move.l #sprite_point,A2_BASE ; = source =$01
move.l #0,A2_PIXEL
move.l #PIXEL8|XADDPIX|PITCH1|WID16,A2_FLAGS
move.w #16,d0 ; 16 lignes
swap d0
move.w #16,d0 ; 16 pixels de largeur
move.l d0,B_COUNT
move.l #0, B_SRCD
move.l #0, B_SRCD+4
move.l #0, B_DSTD
move.l #0, B_DSTD+4
move.l #$08080808,B_PATD+4 ; KO : chercher 08 => collisions, meme quand pas de collisions
move.l #$08080808,B_PATD ; KO : chercher 08 => collisions, meme quand pas de collisions
move.l #%100,B_STOP
move.l #SRCEN|DSTEN|CMPDST|DCOMPEN|LFU_REPLACE|UPDA1,B_CMD
;move.l #SRCEN|DSTEN|CMPDST|DCOMPEN|LFU_SORD|UPDA1,B_CMD ; affiche les parties qui ne sont pas en collision
;move.l #SRCEN|DSTEN|CMPDST|DCOMPEN|LFU_D|UPDA1,B_CMD ; n'affiche rien
;move.l #SRCEN|DSTEN|LFU_SORD|UPDA1|UPDA2,B_CMD ; pas de test de collision, fais un OR
;move.l #SRCEN|DSTEN|CMPDST|LFU_D|UPDA1,B_CMD ; n'affiche rien
; recupere le status
move.l B_CMD,d0
and.l #%11,d0 ; bit0 : 1=idle, bit1 : 1=stopped
move.l vbl_counter, d5
btst #1,d0
bne.s .collision_found
move.w #0, BG
.wait_vbl:
move.l vbl_counter, d4
sub.l d5, d4
cmp.l #1, d4
blt.s .wait_vbl
add.w #1,d7
cmp.w #200, d7
bne test_collision
move.w #50, d7
add.w #1, d6
cmp.w #80, d6
bne test_collision
move.w #20, d6
bra test_collision
.collision_found:
move.l A1_PIXEL_R,d1 ; D1 = pos du stop
move.l A2_PIXEL_R,d2 ; D1 = pos du stop
move.w #$7000,BG
move.l #%010,B_STOP ; abort
move.l #$DEAD,d3
.loop:
move.l B_CMD, d4
btst #1,d4
beq .wait_vbl
move.l #%001,B_STOP
bra.s .loop
pas_de_collision2:
move.l A1_PIXEL_R,d1 ; D1 = pos du stop
move.l A2_PIXEL_R,d2 ; D1 = pos du stop
move.w #$00F0,BG
move.l #$3D0,d3
main:
lea zone_fond,a0
lea sprite_point,a1
move.l #1234, $1
bra.s main
;-----------------------------------------------------------------------------------
;--------------------------
; VBL
VBL:
movem.l d0-d7/a0-a6,-(a7)
;.if display_infos_debug=1
;add.w #1,BG ; debug pour voir si vivant
;.endif
;jsr copy_olist ; use Blitter to update active list from shadow
lea ob_liste_originale,a0
lea ob_list_courante,a1
lea fin_ob_liste_originale,a2
VBL_copie_OL:
move.l (a0)+,(a1)+
cmp.l a0,a2
bne.s VBL_copie_OL
addq.l #1,vbl_counter
move.w #$101,INT1 ; Signal we're done
move.w #$0,INT2
.exit:
movem.l (a7)+,d0-d7/a0-a6
rte
;----------------------------------
; recopie l object list dans la courante
copy_olist:
move.l #ob_list_courante,A1_BASE ; = DEST
move.l #$0,A1_PIXEL
move.l #PIXEL16|XADDPHR|PITCH1,A1_FLAGS
move.l #ob_liste_originale,A2_BASE ; = source
move.l #$0,A2_PIXEL
move.l #PIXEL16|XADDPHR|PITCH1,A2_FLAGS
move.w #1,d0
swap d0
move.l #fin_ob_liste_originale-ob_liste_originale,d1
move.w d1,d0
move.l d0,B_COUNT
move.l #LFU_REPLACE|SRCEN,B_CMD
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure: InitVideo
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Procedure: InitVideo (same as in vidinit.s)
; Build values for hdb, hde, vdb, and vde and store them.
; Original code by Atari, slight modifications and comments
; by Zerosquare / Jagware
InitVideo:
movem.l d0-d6,-(sp)
move.w CONFIG,d0 ; Also is joystick register
andi.w #VIDTYPE,d0 ; 0 = PAL, 1 = NTSC
beq palvals1
move.w #NTSC_HMID,d2
move.w #NTSC_WIDTH,d0
move.w #NTSC_VMID,d6
move.w #NTSC_HEIGHT,d4
bra calc_vals1
palvals1:
move.w #PAL_HMID,d2
move.w #PAL_WIDTH,d0
move.w #PAL_VMID,d6
move.w #PAL_HEIGHT,d4
calc_vals1:
; You can modify d0 and d4 here to set the area drawn
; by the OP (by default it fills the whole screen). It will
; be centered on the screen.
; Warning : the horizontal values are in video clock cycles,
; so don t forget to multiply the number of pixels by
; PWIDTH + 1
; Check also that the VDB and VDE values used for the first
; two stop objects in your object list are those calculated
; here
move.w d0,d1
asr #1,d1 ; Width/2
sub.w d1,d2 ; Mid - Width/2
add.w #4,d2 ; (Mid - Width/2)+4
sub.w #1,d1 ; Width/2 - 1
ori.w #$400,d1 ; (Width/2 - 1)|$400
move.w d1,a_hde
move.w d1,HDE
move.w d2,a_hdb
move.w d2,HDB1
move.w d2,HDB2
move.w d6,d5
sub.w d4,d5
moveq #0,d5
move.w d5,a_vdb
add.w d4,d6
move.w d6,a_vde
move.w a_vdb,VDB
move.w a_vde,VDE
movem.l (sp)+,d0-d6
rts
InitVideo2:
movem.l d0-d6,-(sp)
move.w #-1,ntsc_flag
move.l #50,_50ou60hertz
lea HDE,a1
lea HDB1,a2
lea HDB2,a3
lea VDB,a4
lea VDE,a5
lea VI,a6
move.w CONFIG,d0 ; Also is joystick register
andi.w #VIDTYPE,d0 ; 0 = PAL, 1 = NTSC
beq.s .palvals
; NTSC
.ntscvals:
moveq #0,d0
move.w #1,ntsc_flag
move.l #60,_50ou60hertz
move.w #$678,(a1) ;HDE
move.w #$CB,(a2) ;HDB1
move.w #$CB,(a3) ;HDB2
move.w #$40,(a4) ;VDB
move.w #$242,(a5) ;VDE
move.w #$242-16+1,d0
or.w #1,d0
move.w d0,(a6) ;VI
move.w #507,a_vde
bra.s .sortie
; PAL
.palvals:
moveq #0,d0
move.w #$66A,(a1) ;HDE
move.w #$B7,(a2) ;HDB1
move.w #$B7,(a3) ;HDB2
move.w #$28,(a4) ;VDB
move.w #$20A,(a5) ;VDE
move.w #$20A-16+1,d0
or.w #1,d0
move.w d0,(a6) ;VI
move.w #522,a_vde
.sortie:
move.l #0,BORD1 ; Black border
;move.w #0,BG ; Init line buffer to black
movem.l (sp)+,d0-d6
rts
; ------------------
; version invit reboot
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure: InitVideo (same as in vidinit.s)
;; Build values for hdb, hde, vdb, and vde and store them.
;;
InitVideo3:
movem.l d0-d6,-(sp)
move.w #-1,ntsc_flag
move.w CONFIG,d0 ; Also is joystick register
andi.w #VIDTYPE,d0 ; 0 = PAL, 1 = NTSC
beq palvals3
move.w #1,ntsc_flag
.ntscvals3: move.w #NTSC_HMID,d2
move.w #NTSC_WIDTH,d0
move.w #NTSC_VMID,d6
move.w #NTSC_HEIGHT,d4
bra calc_vals3
palvals3:
move.w #PAL_HMID,d2
move.w #PAL_WIDTH,d0
move.w #PAL_VMID+30,d6 ; +30 322
move.w #PAL_HEIGHT,d4
calc_vals3:
move.w d0,width
move.w d4,height
move.w d0,d1
asr #1,d1 ; Width/2
sub.w d1,d2 ; Mid - Width/2
add.w #4,d2 ; (Mid - Width/2)+4
sub.w #1,d1 ; Width/2 - 1
ori.w #$400,d1 ; (Width/2 - 1)|$400
move.w d1,a_hde
move.w d1,HDE
move.w d2,a_hdb
move.w d2,HDB1
move.w d2,HDB2
move.w d6,d5
sub.w d4,d5
add.w #16,d5
move.w d5,a_vdb
add.w d4,d6
move.w d6,a_vde
move.w d5,VDB
;move.w d6,VDE
move.w #$ffff,VDE
move.l #0,BORD1 ; Black border
move.w #0,BG ; Init line buffer to black
movem.l (sp)+,d0-d6
rts
.dphrase
.68000
ob_liste_originale: ; This is the label you will use to address this in 68K code
.objproc ; Engage the OP assembler
.org ob_list_courante ; Tell the OP assembler where the list will execute
;
;branch VC < 0, .stahp ; Branch to the STOP object if VC < 0
;branch VC > 310, .stahp ; Branch to the STOP object if VC > 241
; bitmap data addr, xloc, yloc, dwidth, iwidth, iheight, bpp, pallete idx, flags, firstpix, pitch
; zone 256c 8 bits
bitmap zone_fond, 20, 30, nb_octets_par_ligne/8, nb_octets_par_ligne/8, 200,3
;bitmap ecran1,16,24,40,40,255,3
;jump .haha
.stahp:
stop
.haha:
;jump .stahp
.68000
.dphrase
fin_ob_liste_originale:
.data
.dphrase
stoplist: dc.l 0,4
.phrase
sprite_fond:
; 16x16 256 couleurs
.rept 16
.rept 6
dc.b 8
.endr
dc.b 0,0,0,0
.rept 6
dc.b 8
.endr
.endr
fin_sprite_fond:
sprite_fond_mask:
; 16x16 256 couleurs
.rept 16
.rept 6
dc.b $0
.endr
dc.b $FF,$FF,$FF,$FF
.rept 6
dc.b $0
.endr
.endr
sprite_rond:
dc.b 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
dc.b 0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0
dc.b 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0
dc.b 0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0
dc.b 0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0
dc.b 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
dc.b 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0
dc.b 0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0
dc.b 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0
dc.b 0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0
dc.b 0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0
dc.b 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
sprite_point:
.rept 7
.rept 16
dc.b 0
.endr
.endr
dc.b 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0
dc.b 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0
.rept 7
.rept 16
dc.b 0
.endr
.endr
.bss
.phrase
DEBUT_BSS:
frequence_Video_Clock: ds.l 1
frequence_Video_Clock_divisee : ds.l 1
_50ou60hertz: ds.l 1
taille_liste_OP: ds.l 1
vbl_counter: ds.l 1
ntsc_flag: ds.w 1
a_hdb: ds.w 1
a_hde: ds.w 1
a_vdb: ds.w 1
a_vde: ds.w 1
width: ds.w 1
height: ds.w 1
.dphrase
zone_fond: ds.b 320*200
fin_zone_fond:
FIN_RAM:
.if 1=0
; blitter le sprite
; fond AND mask
move.l #zone_fond,A1_BASE ; = DEST
move.l #(40<<16)+32,A1_PIXEL ; X dest=32 / Y dest=40
move.l #PIXEL8|XADDPIX|PITCH1|WID320,A1_FLAGS
move.l #320,A1_CLIP
move.w #1,d0
swap d0
move.w #-16,d0
move.l d0,A1_STEP
move.l #0,A1_FSTEP
move.l #sprite_fond_mask,A2_BASE ; = source
move.l #0,A2_PIXEL
move.l #PIXEL8|XADDPIX|PITCH1|WID16,A2_FLAGS
move.w #16,d0 ; 16 lignes
swap d0
move.w #16,d0 ; 16 pixels de largeur
move.l d0,B_COUNT
move.l #SRCEN|DSTEN|LFU_SAD|UPDA1,B_CMD
wait_blitter1:
move.l B_CMD,d0 ;; wait for blitter to finish
ror.w #1,d0 ;; Check if blitter is idle
bcc.b wait_blitter1 ;; bit was clear -> busy
; fond OR sprite
move.l #zone_fond,A1_BASE ; = DEST
move.l #(0<<16)+0,A1_PIXEL ; X dest=32 / Y dest=40
;move.l #(40<<16)+32,A1_PIXEL ; X dest=32 / Y dest=40
move.l #PIXEL8|XADDPIX|PITCH1|WID320,A1_FLAGS
move.l #320,A1_CLIP
move.w #1,d0
swap d0
move.w #-16,d0
move.l d0,A1_STEP
move.l #0,A1_FSTEP
move.l #sprite_fond,A2_BASE ; = source
move.l #0,A2_PIXEL
move.l #PIXEL8|XADDPIX|PITCH1|WID16,A2_FLAGS
move.w #16,d0 ; 16 lignes
swap d0
move.w #16,d0 ; 16 pixels de largeur
move.l d0,B_COUNT
move.l #SRCEN|DSTEN|LFU_SORD|UPDA1,B_CMD
; or de sprite rond double triangle
; 48 = no collision
; 47 = collision
move.l #zone_fond,A1_BASE ; = DEST
move.l #(0<<16)+0+15,A1_PIXEL ; X dest=32 / Y dest=40
;move.l #(40<<16)+32+15,A1_PIXEL ; X dest=32 / Y dest=40
move.l #PIXEL8|XADDPIX|PITCH1|WID320,A1_FLAGS
move.l #320,A1_CLIP
move.w #1,d0
swap d0
move.w #-16,d0
move.l d0,A1_STEP
move.l #0,A1_FSTEP
move.l #sprite_rond,A2_BASE ; = source
move.l #0,A2_PIXEL
move.l #PIXEL8|XADDPIX|PITCH1|WID16,A2_FLAGS
move.w #16,d0 ; 16 lignes
swap d0
move.w #16,d0 ; 16 pixels de largeur
move.l d0,B_COUNT
move.l #SRCEN|DSTEN|LFU_SORD|UPDA1,B_CMD
; avec test de collision
;move.l #zone_fond,A1_BASE ; = DEST
move.l #(40<<16)+32+15,A1_PIXEL ; X dest=32 / Y dest=40
;move.l #PIXEL8|XADDPIX|PITCH1|WID320,A1_FLAGS
;move.l #320,A1_CLIP
;move.w #1,d0
;swap d0
;move.w #-16,d0
;move.l d0,A1_STEP
;move.l #0,A1_FSTEP
;move.l #sprite_rond,A2_BASE ; = source
;move.l #0,A2_PIXEL
;move.l #PIXEL8|XADDPIX|PITCH1|WID16,A2_FLAGS
;move.w #16,d0 ; 16 lignes
;swap d0
;move.w #16,d0 ; 16 pixels de largeur
;move.l d0,B_COUNT
move.l #$09090909,B_PATD
move.l #%100,B_STOP
move.l #CMPDST|DCOMPEN|DSTEN|LFU_D|UPDA1,B_CMD
move.l A1_PIXEL_R,d3 ; D1 = pos du stop
move.l A2_PIXEL_R,d4 ; D1 = pos du stop
; recupere le status
move.l B_CMD,d0
and.l #%11,d0 ; bit0 : 1=idle, bit1 : 1=stopped
btst #1,d0
beq.s pas_de_collision
move.w #$7700,BG ; 7700=violet
move.l #%010,B_STOP ; abort
nop
pas_de_collision:
move.l A1_PIXEL_R,d1 ; D1 = pos du stop
move.l A2_PIXEL_R,d2 ; D1 = pos du stop
; =6 pour objet a droite, 1 pixel de chevauchement
; =$000F0002 pour objet 1 pixel commun, position� a gauche
; au dessus : collision uniquement en bas a droite 1 pixel : 0806
; en dessous :
.endif