;---------------------------------------------------------------; ; ; ; Snail Maze ; ; Drawing routines ; ; ; ;---------------------------------------------------------------; ;------------------------------------------------ ; drawSnail - draw the player (snail) ; input: none ; output: none ;------------------------------------------------ drawSnail: ld hl,0 ld a,(dir) ld l,a add a,a add a,l ld l,a ld de,snailTable add hl,de ; HL => snailTable entry bcall(_lddehl) ; DE => sprite push de ld hl,(sx) ; L = grid x ld e,h ; E = grid y call getScreenPos inc de inc l ld a,(moveCount) bit 7,a call z,dsOffset pop ix ; IX => sprite call drawSprite ret dsOffset: ld b,a ld a,(dir) bit 1,a ; check which axis snail is moving on jr nz,dsmXaxis bit 0,a ; moving up or down? ld a,b ld c,9 jr z,dsmAfterNeg neg ld c,-2 dsmAfterNeg: add a,l ld l,a ; updated y pos push hl push de add a,c ld l,a ld ix,sprRectHoriz call drawSprite pop de pop hl ret dsmXaxis: push hl ex de,hl ; HL = unmodified x pos ld de,0 ld e,b ; DE = x offset bit 0,a ; moving left or right? jr nz,dsmLeft dsmRight: add hl,de ld bc,9 jr dsmXaxisDone dsmLeft: or a ; clear carry sbc hl,de ld bc,-2 dsmXaxisDone: ex de,hl ; DE = updated x pos pop hl ; L = y pos push hl push de ex de,hl add hl,bc ex de,hl ld ix,sprRectVert call drawSprite pop de pop hl ret ;------------------------------------------------ ; getScreenPos - convert maze grid position to actual screen position for drawing ; input: L = grid x ; E = grid y ; output: DE = x ; L = y ;------------------------------------------------ getScreenPos: ld h,TILE_SIZE mlt hl ld bc,MAZE_LEFT add hl,bc ; HL = x position on screen push hl ld d,TILE_SIZE mlt de ld hl,MAZE_TOP add hl,de ; L = y position on screen pop de ; DE = x ret ;------------------------------------------------ ; drawSprite - draw an 8bpp sprite ; input: DE = x ; L = y ; IX => sprite data ; output: none ;------------------------------------------------ drawSprite: ld a,(ix) ld (__dsw),a inc ix ld a,(ix) ld (__dsh),a inc ix push de ld h,160 mlt hl add hl,hl ; HL = offset to row ld de,vbuf add hl,de ; HL => row on vbuf pop de ; DE = x add hl,de ; HL => where to start drawing on vbuf ld c,$00 ; C = # rows to draw __dsh = $-1 dsOuter: push hl ld b,$00 ; B = # pixels per row __dsw = $-1 dsInner: ld a,(ix) ; A = sprite pixel ld (hl),a inc ix inc hl djnz dsInner pop hl push bc ld bc,320 add hl,bc ; HL => where to start drawing next row on vbuf pop bc dec c jr nz,dsOuter ret ;------------------------------------------------ ; copySprite - draw a sprite to top-left of vBuf and copy a portion to a position on vRam (used in the SEGA intro) ; input: B = x position of vBuf to start copy from ; C = width of copy ; DE = x position of vRam to display at ; IX => sprite data ; output: none ; notes: hardcoded height & destination y position because this routine is only used in the intro and all sprites are the same height and shown at the same row ;------------------------------------------------ copySprite: push de push bc ld de,0 ld l,0 call drawSprite pop bc ; B = source x, C = width ld de,0 ld e,b ld hl,vBuf add hl,de ; HL => byte of vBuf to start copy from ex (sp),hl ; HL = dest x ld de,vRam+(320*SEGA_Y) ; DE => dest row of vRam add hl,de ; HL => byte of vRam to start paste to pop de ; DE => byte of vBuf to start copy from ld b,SEGA_HEIGHT csOuter: push bc push hl push de csInner: ld a,(de) ld (hl),a inc de inc hl dec c jr nz,csInner pop hl ld bc,320 add hl,bc ex de,hl pop hl add hl,bc pop bc djnz csOuter ret ;------------------------------------------------ ; drawMaze - draw the maze on vBuf and slide it on to vRam ; input: none ; output: none ;------------------------------------------------ drawMaze: ld ix,maze ld b,MAZE_HEIGHT ; B = # rows to draw ld l,MAZE_TOP ; L = y coord to start on dmOuter: push bc push hl ld b,MAZE_WIDTH ; B = # columns to draw ld de,MAZE_LEFT ; DE = x coord to start on dmInner: push bc push ix push hl push de ld hl,0 ld l,(ix) ; HL = tile # push hl \ pop de add hl,hl add hl,de ; x3 ld de,tileTable add hl,de ; HL => tileTable entry bcall(_lddehl) ; DE => tile data push de pop ix ; IX => tile data pop de ; DE = x pop hl ; HL = y push hl push de call drawSprite ; draw sprite pop de ld hl,TILE_SIZE add hl,de ex de,hl ; DE = next x pop hl ; HL = y pop ix inc ix ; IX => next tile # pop bc djnz dmInner ; loop for this row pop hl ld de,TILE_SIZE add hl,de ; HL = next y pop bc djnz dmOuter ; draw right border ld hl,BORDER_RIGHT ; HL => where on vbuf to start drawing border ld de,320 ; DE = bytes to skip each loop ld bc,MAZE_HEIGHT*TILE_SIZE ; BC = # pixels to draw dmRight: ld (hl),C_WALL add hl,de dec bc ld a,b or c jr nz,dmRight ; draw bottom border ld hl,BORDER_BOTTOM ld bc,MAZE_WIDTH*TILE_SIZE+1 ; extra pixel to get bottom-right corner dmBottom: ld (hl),C_WALL inc hl dec bc ld a,c or b jr nz,dmBottom ; draw goal ld hl,(gx) ld e,h call getScreenPos inc de inc l ld ix,sprGoal call drawSprite ; do the slide effect ld bc,320 ; B = 320 frames of animation to perform ld hl,vBuf+(320*MAZE_TOP)+319 ; HL => right side of first row ld ix,vRam+(320*MAZE_TOP)+319 slideMaze: push bc push hl push ix ld b,MAZE_BOTTOM-MAZE_TOP+1 ; B = # pixels per column smLoop: ld a,(hl) ld (ix),a ld de,320 add hl,de add ix,de djnz smLoop ld bc,300 call waitBC pop ix \ dec ix pop hl \ dec hl pop bc \ dec bc bcall(_chkBCis0) jr nz,slideMaze ret .end