6,348 bytes added,
07:46, 13 March 2007 <pre>
;; This example demonstrates a method to plot sprites using the firmware
;; and the character set.
;;
;; - The sprites are defined using the character set matrices.
;;
;; - Each sprite is therefore composed of multiple 8x8 character matrices.
;;
;; - The display mode is set to mode 2 (640x200) which uses 1 bit per pixel
;; Each line of the character matrix is represented by 1 byte.
;;
;; - When the character is displayed in mode 2, each line of the character
;; matrix is written direct to the screen memory without conversion.
;; This is an important fact for this example.
;; (Normally, the character matrix data is converted into mode 1 or mode 2
;; pixel data)
;;
;; - The display mode is changed, without informing the firmware functions.
;; The characters will be plotting using the mode 2 method, regardless
;; of the forced video mode. This is an important fact for this example.
;;
;; If the character matrix data is setup so that each byte represents
;; a byte of mode 1 or mode 0 screen pixel data, then multi-coloured
;; sprites can be plotted, by the firmware, using the standard character
;; plot routines. The only problem, is that each character matrix
;; represents 4x8 pixels in mode 1, and 2x8 pixels in mode 0. So many
;; matrices may be required to hold the pixel data for each sprite.
;;
;; - graphics coordinates, if used, must be defined so that the sprite
;; is plotted on a byte boundary. e.g. x must be a integer multiple of 8.
;;
;; This method may be useful for plotting sprites for games in a
;; 1K games competition.
.scr_set_mode equ &bc0e
.mc_set_mode equ &bd1c
.km_read_char equ &bb09
.mc_wait_flyback equ &bd19
.txt_output equ &bb5a
.txt_set_matrix equ &bba8
.gra_move_absolute equ &bbc0
.gra_move_relative equ &bbc3
.gra_wr_char equ &bbfc
.scr_access equ &bc59
org &4000
nolist
;;-----------------------------------------------------------------------
;; set display mode 2
ld a,2
call scr_set_mode
;; force display mode 1
;; - the firmware will plot characters using the method for mode 2.
ld a,1
call mc_set_mode
;;-----------------------------------------------------------------------
;; set screen write mode to XOR
;;
;; - plot sprite using XOR to display, plot sprite using XOR in same position
;; to erase.
;; - if sprite moves over any other graphics, some pixels will change colour.
ld a,1
call scr_access
;;-----------------------------------------------------------------------
;; initialise sprite data
ld hl,pixel_data ;; location of character matrix data
ld a,248 ;; id of first character matrix
ld b,8 ;; number of characters to define matrix for
.sch
push af
push bc
push hl
call txt_set_matrix ;; set character matrix
pop hl
ld bc,8 ;; number of bytes per character matrix
add hl,bc
pop bc
pop af
inc a
djnz sch
;;--------------------------------------------------------------------------
;; plot sprite
ld a,248
ld de,(sprite_x)
ld hl,(sprite_y)
call draw_sprite
.loop
call mc_wait_flyback
;; erase sprite
ld a,248
ld de,(sprite_x)
ld hl,(sprite_y)
call draw_sprite
call controls
;; plot sprite (in new position
;; if sprite's coordinates have changed)
ld a,248
ld de,(sprite_x)
ld hl,(sprite_y)
call draw_sprite
jp loop
.controls
call km_read_char
ret nc
and &df
cp "Q"
jp z,moveup
cp "A"
jp z,movedown
cp "O"
jr z,moveleft
cp "P"
jr z,moveright
ret
;; adjust y coordinate of sprite
;; to move it up the screen.
;; - Each scan-line is 2 graphics y coordinates.
;; - origin of graphics coordinates is bottom-left
.moveup
ld hl,(sprite_y)
inc hl
inc hl
ld (sprite_y),hl
ret
;; adjust y coordinate of sprite
;; to move it down the screen.
.movedown
ld hl,(sprite_y)
dec hl
dec hl
ld (sprite_y),hl
ret
;; adjust x coordinate of sprite
;; to move it left accross the screen.
;; - each byte is 8 graphics x coordinates
.moveleft
ld hl,(sprite_x)
ld bc,8
or a
sbc hl,bc
ld (sprite_x),hl
ret
;; adjust x coordinate of sprite
;; to move it right accross screen
.moveright
ld hl,(sprite_x)
ld bc,8
add hl,bc
ld (sprite_x),hl
ret
;;-------------------------------------------------------------
;; A = id of first character used by sprite data
;; DE = x graphics coordinate
;; HL = y graphics coordinate
.draw_sprite
;; move to initial position
push af
call gra_move_absolute
pop af
ld b,2 ;; number of character matrices occupied by sprite in
;; y dimension
.ps1
push bc
push af
ld c,4 ;; number of character matrices occupied by sprite in
;; x dimension
.ps2
push bc
push af
;; plot character at graphics coordinate position
;; and update graphics coordinate position for next
;; character
call gra_wr_char
pop af
pop bc
add 2 ;; increment character id
;; (see character matrix usage below)
dec c
jr nz,ps2
;; adjust graphics character position for next row
;; of characters
ld de,-8*4
ld hl,-16
call gra_move_relative
pop af
;; increment character id
;; (see character matrix usage below)
inc a
pop bc
djnz ps1
ret
;;-----------------------------------------------------------------------
;; graphics coordinates for sprites position
.sprite_x defw 320
.sprite_y defw 100
;; sprite is:
;; - 16 mode 1 pixels wide = 4 bytes wide = 4 mode 2 characters wide
;; - 16 mode 1 pixels tall = 2 mode 2 characters tall
;;
;; sprite data is stored as:
;;
;; char 248 char 250 char 252 char 254
;; char 249 char 251 char 253 char 255
.pixel_data
defb &00 ;; char 248
defb &00
defb &10
defb &20
defb &40
defb &40
defb &80
defb &80
defb &80 ;; char 249
defb &80
defb &40
defb &51
defb &31
defb &10
defb &00
defb &00
defb &30 ;; char 250
defb &C0
defb &00
defb &00
defb &06
defb &0C
defb &0C
defb &04
defb &00 ;; char 251
defb &00
defb &AA
defb &55
defb &FF
defb &FD
defb &F2
defb &30
defb &C0 ;; char 252
defb &30
defb &00
defb &00
defb &00
defb &00
defb &00
defb &11
defb &22 ;; char 253
defb &55
defb &BA
defb &75
defb &FA
defb &F5
defb &F8
defb &C0
defb &00 ;; char 254
defb &00
defb &80
defb &40
defb &20
defb &20
defb &32
defb &76
defb &FA ;; char 255
defb &F4
defb &E8
defb &E4
defb &C8
defb &80
defb &00
defb &00
</pre>