;############## CMonster by Patrick Davidson - graphics rendering routines #define SPRITE(width,height) .db width/2,height ;############## Clear the screen (in black, of course!) Clear_Screen: ld hl,$D40000 ld (hl),0 ld de,$D40001 ld bc,320*240*2-1 ldir ret .block (256-($ & 255)) ; %RRRRRGGG,%GGGBBBBB color_table: .db %00000000,%00000000 ; 0 = black .db %00000000,%00000000 ; .db %11000110,%00011000 ; 2 = light gray .db %11111111,%11111111 ; 3 = white .db %11111100,%11111111 ; 4 = bright purple .db %00000000,%00000000 ; .db %00000000,%00000000 ; .db %11111000,%00000000 ; 7 = red .db %00000000,%00000000 ; .db %00000000,%00000000 ; .db %00000000,%00000000 ; .db %00000000,%00000000 ; .db %00000000,%00000000 ; .db %00000000,%00000000 ; .db %00000000,%00000000 ; .db %00000000,%00000000 ; Clear_Below_Tiles: ld hl,$D40000+(320*128*2) ld de,$D40001+(320*128*2) ld (hl),0 ld bc,320*104*2-1 ldir ret ;############## Draw solid color bricks ; B = X coordinate (0-19) ; A = Y coordinate (0-29) ; DE = color Draw_Brick: push de push bc push af cp 16 jr nc,no_brick push de call Find_Brick pop de and (hl) jr nz,brick_remains no_brick: ld de,0 brick_remains: pop af ; A = brick row add a,a add a,a add a,a ; A = screen Y smc_brick_line_offset: add a,0 ld hl,0 ld l,a push hl pop bc ; BC = Y add hl,hl add hl,hl ; HL = 4 * Y add hl,bc ; HL = 5 * Y add hl,hl add hl,hl ; HL = 20 * Y pop bc ; B = brick column ld a,b ld bc,0 ld c,a ; BC = brick column add hl,bc ; HL = 20 * Y + brick column add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ; HL = 640 * Y + 32 * brick column ld bc,$D40000 add hl,bc smc_brick_row_count: ld a,8 next_brick_row: ld b,16 next_brick_column: ld (hl),d inc hl ld (hl),e inc hl djnz next_brick_column ld bc,(320-16)*2 add hl,bc dec a jr nz,next_brick_row pop de ret Draw_Brick_Set_Normal: xor a ld (smc_brick_line_offset+1),a ld a,8 ld (smc_brick_row_count+1),a ret Draw_Brick_Set_Single_Line: ld (smc_brick_line_offset+1),a ld a,1 ld (smc_brick_row_count+1),a ret ;############## Draw a sprite ; A = sprite's height (only needed for clipped version) ; B = X coordinate divided by 2 ; L = Y coordinate ; DE -> sprite (first byte is the width / 2, second byte is height) Draw_Sprite_Check_Clip_Below_16: add a,l ; A = bottom Y coordinate + 1 cp 233 jr c,Draw_Sprite_16 ld a,232 sub l ; A = remaining lines to draw ret c ret z push af call Get_Screen_Start ld a,(de) ld (smc_sprite_column_count+1),a inc de ld a,(de) inc de pop af jr draw_sprite_ready Draw_Sprite_16: call Get_Screen_Start ld a,(de) ld (smc_sprite_column_count+1),a inc de ld a,(de) inc de draw_sprite_ready: ld b,a next_sprite_row_draw: push bc push hl smc_sprite_column_count: ld b,5 next_sprite_column_draw: push bc ld bc,color_table ld a,(de) rra rra rra and %1110 ld c,a inc bc ld a,(bc) ld (hl),a dec bc inc hl ld a,(bc) ld (hl),a inc hl ld a,(de) inc de rla and %1110 ld c,a inc bc ld a,(bc) ld (hl),a dec bc inc hl ld a,(bc) ld (hl),a inc hl pop bc djnz next_sprite_column_draw pop hl ld bc,640 add hl,bc pop bc djnz next_sprite_row_draw ret Erase_Sprite_Check_Clip_Below: add a,l ; A = bottom Y coordinate + 1 cp 233 jr c,Erase_Sprite ld a,232 sub l ; A = remaining lines to draw ret c ret z push af call Get_Screen_Start ld a,(de) ld (smc_erase_column_count+1),a inc de ld a,(de) pop af jr erase_sprite_ready Erase_Sprite: call Get_Screen_Start ld a,(de) ld (smc_erase_column_count+1),a inc de ld a,(de) inc de erase_sprite_ready: ld b,a xor a ld de,640 next_sprite_row_erase: push bc push hl smc_erase_column_count: ld b,5 next_sprite_column_erase: ld (hl),a inc hl ld (hl),a inc hl ld (hl),a inc hl ld (hl),a inc hl djnz next_sprite_column_erase pop hl add hl,de pop bc djnz next_sprite_row_erase ret Get_Screen_Start: push de ld a,l ld hl,0 ld l,a push hl pop de add hl,hl add hl,hl add hl,de ; HL = 5 * Y add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ; HL = 160 * Y ld e,b add hl,de ; HL = 160 * Y + X add hl,hl add hl,hl ; HL = 640 * Y + 4 * X ld de,$D40000 add hl,de pop de ret