The following warnings occurred:
Warning [2] Undefined array key 0 - Line: 1677 - File: showthread.php PHP 8.2.31 (Linux)
File Line Function
/inc/class_error.php 157 errorHandler->error
/showthread.php 1677 errorHandler->error_callback
/showthread.php 916 buildtree




Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Stack Bug in ZXB 1.2.5-r1489 ?
#14
Sprite.bas: This is a sprite shifting routine by Johnatan Cauldwell. I modified it a bit so it could not only XOR graphics, but also AND, OR and stright PRINT. I only use the AND and XOR because I love masked graphics.

It's too slow ATM, so it flickers a lot (which is good for a game made for the crap games compo). I want to make a version that works in a backbuffer and then copy the buffer to screen. In fact that's what I am doing at the moment (the transfer routine), but it's my first ever assembler routine and I'm having problems Smile I'll post it when it's finished Smile

Code:
SUB psprite (xd as ubyte,yd as ubyte,gfx as uinteger) POKE @esprite,xd: POKE @esprite+1,yd: POKE Uinteger (@esprite+2),gfx POKE @xor1,121:POKE @xor2,122:POKE @xor3,123 gosub printsprite END SUB SUB xorsprite (xd as ubyte,yd as ubyte,gfx as uinteger) POKE @esprite,xd: POKE @esprite+1,yd: POKE Uinteger (@esprite+2),gfx POKE @xor1,169:POKE @xor2,170:POKE @xor3,171:POKE @mask+1,0: POKE @carry,167':POKE @esprite+5,7:'POKE @esprite+4,255':POKE @esprite+6,60 gosub printsprite END SUB SUB andsprite (xd as ubyte,yd as ubyte,gfx as uinteger) POKE @esprite,xd: POKE @esprite+1,yd: POKE Uinteger (@esprite+2),gfx POKE @xor1,161:POKE @xor2,162:POKE @xor3,163:POKE @mask+1,255:POKE @carry,0':POKE @esprite+5,0:POKE @esprite+4,246'230':POKE @esprite+6,0 gosub printsprite END SUB SUB orsprite (xd as ubyte,yd as ubyte,gfx as uinteger) POKE @esprite,xd: POKE @esprite+1,yd: POKE Uinteger (@esprite+2),gfx POKE @xor1,177:POKE @xor2,178:POKE @xor3,179 gosub printsprite END SUB SUB spriteh (h as ubyte) POKE @altura+1,h END SUB esprite: ASM xp: defb 0 yp: defb 0 gfxdir: defw 0 ; This is the sprite routine and expects coordinates in (c ,b) form, ; where c is the vertical coord from the top of the screen (0-176), and ; b is the horizontal coord from the left of the screen (0 to 240). ; Sprite data is stored as you'd expect in its unshifted form as this ; routine takes care of all the shifting itself. This means that sprite ; handling isn't particularly fast but the graphics only take 1/8th of the ; space they would require in pre-shifted form. ; On entry HL must point to the unshifted sprite data. sprit7: xor 7 ; complement last 3 bits. inc a ; add one for luck! sprit3: rl d ; rotate left... rl c ; ...into middle byte... rl e ; ...and finally into left character cell. dec a ; count shifts we've done. jr nz,sprit3 ; return until all shifts complete. ; Line of sprite image is now in e + c + d, we need it in form c + d + e. ld a,e ; left edge of image is currently in e. ld e,d ; put right edge there instead. ld d,c ; middle bit goes in d. ld c,a ; and the left edge back into c. jr sprit0 ; we've done the switch so transfer to screen. END ASM printsprite: ASM sprite: ld hl,(gfxdir) ld bc,(xp) ld (dispx),bc ; store coords in dispx for now. call scadd ; calculate screen address. END ASM altura: ASM ld a,16 ; height of sprite in pixels. sprit1: ex af,af' ; store loop counter. push de ; store screen address. ld c,(hl) ; first sprite graphic. inc hl ; increment poiinter to sprite data. ld d,(hl) ; next bit of sprite image. inc hl ; point to next row of sprite data. ld (sprtmp),hl ; store it for later. END ASM mask: ASM ld e,0 ; blank right byte for now. ld a,b ; b holds y position. and 7 ; how are we straddling character cells? jr z,sprit0 ; we're not straddling them, don't bother shifting. cp 8 ; 5 or more right shifts needed? jr nc,sprit7 ; yes, shift from left as it's quicker. end asm carry: asm and a ; oops, carry flag is set so clear it. sprit2: rr c ; rotate left byte right... rr d ; ...through middle byte... rr e ; ...into right byte. dec a ; one less shift to do. jr nz,sprit2 ; return until all shifts complete. sprit0: pop hl ; pop screen address from stack. ld a,(hl) ; what's there already. END ASM xor1: ASM xor c ; merge in image data. a9 169 a1 161 79 121 b1 177 ld (hl),a ; place onto screen. inc l ; next character cell to right please. ld a,(hl) ; what's there already. END ASM xor2: ASM xor d ; merge with middle bit of image. aa 170 a2 162 7a 122 b2 178 ld (hl),a ; put back onto screen. inc l ; next bit of screen area. ld a,(hl) ; what's already there. END ASM xor3: ASM xor e ; right edge of sprite image data. ab 171 a3 163 7b 123 b3 179 ld (hl),a ; plonk it on screen. ld a,(dispx) ; vertical coordinate. inc a ; next line down. ld (dispx),a ; store new position. and 63 ; are we moving to next third of screen? jr z,sprit4 ; yes so find next segment. and 7 ; moving into character cell below? jr z,sprit5 ; yes, find next row. dec l ; left 2 bytes. dec l ; not straddling 256-byte boundary here. inc h ; next row of this character cell. sprit6: ex de,hl ; screen address in de. ld hl,(sprtmp) ; restore graphic address. ex af,af' ; restore loop counter. dec a ; decrement it. jp nz,sprit1 ; not reached bottom of sprite yet to repeat. ret ; job done. sprit4: ld de,30 ; next segment is 30 bytes on. add hl,de ; add to screen address. jp sprit6 ; repeat. sprit5: ld de,63774 ; minus 1762. add hl,de ; subtract 1762 from physical screen address. jp sprit6 ; rejoin loop. ; This routine returns a screen address for (c, b) in de. scadd: ld a,c ; get vertical position. and 7 ; line 0-7 within character square. add a,64 ; 64 * 256 = 16384 (Start of screen display) ld d,a ; line * 256. ld a,c ; get vertical again. rrca ; multiply by 32. rrca rrca and 24 ; high byte of segment displacement. add a,d ; add to existing screen high byte. ld d,a ; that's the high byte sorted. ld a,c ; 8 character squares per segment. rlca ; 8 pixels per cell, mulplied by 4 = 32. rlca ; cell x 32 gives position within segment. and 224 ; make sure it's a multiple of 32. ld e,a ; vertical coordinate calculation done. ld a,b ; y coordinate. rrca ; only need to divide by 8. rrca rrca and 31 ; squares 0 - 31 across screen. add a,e ; add to total so far. ld e,a ; hl = address of screen. ret dispx: defb 0 ; general-use coordinates. dispy: defb 0 sprtmp: defw 0 ; sprite temporary address. END ASM
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 2 Guest(s)