at last sprites "work"
[ld45_start_nothing] / src / gfx.asm
index d352139..06ff5e4 100644 (file)
@@ -6,17 +6,19 @@
 ;    initializes the video hardware and graphics routines
 ; clear
 ;    clears the framebuffer (not vmem)
-;    clobbers: ax, cx, di
+;    clobbers: eax, ecx, edi
 ; swap_buffers
 ;    copies the framebuffer to video memory
-;    clobbers: ax, cx, di, si
+;    clobbers: eax, ecx, edi, esi
 ; wait_vsync
 ;    clobbers: al, dx
 ; set_palette_entry(idx[al], r[ah], g[bl], b[bh])
 ;    colors are 0-255
+       bits 32
+       section .text
 
-VIDMEM_SEG     equ 0a000h
-FRAMEBUF_SEG   equ 09000h
+%define GFX_ASM_
+%include "gfx.inc"
 
 REG_CRTC_STATUS        equ 3dah
 CRTC_VBLANK_BIT        equ 08h
@@ -24,40 +26,50 @@ CRTC_VBLANK_BIT     equ 08h
 REG_DAC_ADDR   equ 3c8h
 REG_DAC_DATA   equ 3c9h
 
-init_gfx:
-       ; video mode 13h (320x200 8bpp)
-       mov ax, 13h
-       int 10h
+       extern sprsheet
+       extern sprsheet_cmap
 
+       global init_gfx
+init_gfx:
        call clear
+
+       ; setup the spritesheet palette
+       mov esi, sprsheet_cmap
+       xor cl, cl
+.cmaploop:
+       mov al, cl
+       mov ah, [esi]
+       mov bl, [esi + 1]
+       mov bh, [esi + 2]
+       add esi, 3
+       call set_palette_entry
+       inc cl
+       jnz .cmaploop
+
+       ; force color 0 to black
+       xor ax, ax
+       xor bx, bx
+       call set_palette_entry
+
        ret
 
+       global clear
 clear:
-       push es
-       mov ax, FRAMEBUF_SEG
-       mov es, ax
-       xor di, di
-       xor ax, ax
-       mov cx, 16000
+       mov edi, FRAMEBUF_ADDR
+       xor eax, eax
+       mov ecx, 16000
        rep stosd
-       pop es
        ret
 
+       global swap_buffers
 swap_buffers:
-       push ds
-       push es
-       mov ax, FRAMEBUF_SEG
-       mov ds, ax
-       xor si, si
-       mov ax, VIDMEM_SEG
-       mov es, ax
-       xor di, di
-       mov cx, 16000
+       mov esi, FRAMEBUF_ADDR
+       mov edi, VIDMEM_ADDR
+       mov ecx, 16000
        rep movsd
-       pop es
-       pop ds
        ret
 
+       global wait_vsync
 wait_vsync:
        mov dx, REG_CRTC_STATUS
 .wait_vblank_end:
@@ -86,3 +98,50 @@ set_palette_entry:
        out dx, al
        pop dx
        ret
+
+       ; slow_sprite(int id, int x, int y)
+       ; assumptions: 32x32, one after the other, 0 is transparent
+       global slow_sprite
+slow_sprite:
+       push ebp
+       mov ebp, esp
+       pusha
+
+       mov eax, [ebp + 16]     ; ax <- y
+       sub eax, 16             ; ax <- y - 16 (center sprite vertically)
+       mov ebx, eax
+       shl eax, 8
+       shl ebx, 6
+       add eax, ebx            ; ax <- (y - 16) * 320
+       mov edi, [ebp + 12]     ; di <- x
+       sub edi, 16             ; di <- x - 16 (center sprite horizontally)
+       add edi, eax            ; di <- (y - 16) * 320 + (x - 16)
+       add edi, FRAMEBUF_ADDR
+
+       mov esi, sprsheet
+       ; calculate sprite id offset (each spr is 32*32=1k)
+       mov eax, [ebp + 8]
+       shl eax, 10
+       add esi, eax
+
+       mov ecx, 32
+.yloop:
+       xor ebx, ebx
+.xloop:
+       mov al, [esi]
+       cmp al, 0
+       ;jz .skip_pixel
+       mov [edi + ebx], al
+.skip_pixel:
+       inc esi
+       inc ebx
+       cmp ebx, 32
+       jnz .xloop
+
+       add edi, 320
+       dec ecx
+       jnz .yloop
+
+       popa
+       pop ebp
+       ret