Programming:Plotting a sprite using character matrices
From CPCWiki - THE Amstrad CPC encyclopedia!
;; 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