Another strange thing related to the "graphics overwriting" - apenao - 03-21-2010
I have polished a bit my sprite routine, writting it in just one file and erasing repeated code (it worked OK up to this point) and adding a new subroutine to set the background colour of the playing area. Wheter I use or not this routine (and even if I take it out of the sprite routine file and copy it in any part of the main program code) its causing the graphics behave strangely.
When I'm drawing the "show room" (the only one atm, where I'm trying the graphics and the movements) I call (via Gosub) the routines drawing the different parts, i.e.:
GOSUB ESQUINA -- DRAWS THE CORNERS
GOSUB HABITACINESCONPUERTA -- DRAWS THE "WALLS" AND THE DOORS
When I draw the decoration parts (i.e. a carpet, or different floor designs) I see one of the coordinates of the sprites is changed:
If I draw the carpet (GOSUB ALFOMBRA), then the transparent window has its Y coordinate changed, whatever the correct value is.
If I draw the star (GOSUB ESTRELLA), the main sprite's X coordinate is changed.
And so on. I'll copy the .bas files for the game and the library so you can check it changing between the decorations (MADERA, FLECHAIZDA,FLECHADERECHA,ESTRELLA,SUELOEQUIS,LABERINTO). Perhaps it makes any sense to you. I don't include the .rle file because its the same I sent you last time.
The main program:
Code: #include <sinclair.bas>
#include <keys.bas>
'pause 0
'declaracion variables
DIM UP AS UBYTE: DIM DOWN AS UBYTE: DIM LEFT AS UBYTE: DIM RIGHT AS UBYTE
DIM X AS UBYTE: DIM XA AS UBYTE: DIM Y AS UBYTE: DIM YA AS UBYTE
DIM FRAME AS UBYTE: DIM DIRECCION AS UBYTE
DIM XE AS UBYTE: DIM XEA AS UBYTE: DIM YE AS UBYTE: DIM YEA AS UBYTE: DIM XVENT AS UBYTE: DIM YVENT AS UBYTE
DIM FRAMEE AS UBYTE:DIM VERTICAL AS UBYTE: DIM HORIZONTAL AS UBYTE: DIM CONTADORE AS UBYTE: DIM DIRECCIONE AS UBYTE
DIM VELOCIDAD AS UBYTE:DIM VELOCIDADE AS UBYTE
DIM PAPELFONDO AS UBYTE
'mapeado {0:COLOR,1:N,2:E,3:S,4:O,5:TIPO_ESCENARIO,6:SUELO,7:DEC_IZDA,8:DEC_DCHA,9:MOB,10:VENT,11:SCRIPT1,12:SCRIPT2,13:VACIO,14:VACIO)
DIM MAPA (0 TO 1,0 TO 14) AS uByte => {{5,0,1,0,1,0,1,1,1,1,1,0,0,0,0 } , _
{6,0,1,1,1,1,2,2,2,1,1,0,0,0,0 }}
'pantalla
DIM PANTALLA AS UBYTE
LET PANTALLA=0
'variables
LET X=80:LET XA=80:LET Y=120:LET YA=120
LET FRAME=0: LET DIRECCION=0
LET XE=60:LET XEA=60:LET YE=88:LET YEA=88: LET XVENT=96:LET YVENT=160
LET FRAMEE=0:LET VERTICAL=1:LET HORIZONTAL=0: LET CONTADORE=0:LET DIRECCIONE=0
LET VELOCIDAD=1:LET VELOCIDADE=2
LET PAPELFONDO=5
'imprime pantalla
unchunk (@pantalla,16384,2614)
paper PAPELFONDO: ink O: bright 0
fondocolor (PAPELFONDO*8)
GOSUB ESQUINAS
GOSUB RODAPIECONPUERTA
GOSUB HABITACIONESCONPUERTA
GOSUB ESTRELLA
'preimpresion
xorsprite (30,90,@escudo1)
spriteh (24)
xorsprite (30,145,@armadura)
spriteh (12)
cpbuffer (XVENT,YVENT,@buser2)
spriteh (16)
cpbuffer (X,Y,@buser)
cpbuffer (XE,YE,@buser3)
andsprite (X,Y,@gentlecillo)
xorsprite (X,Y,@gentlecillo+32*8)
andsprite (XE,YE,@mayordomo)
xorsprite (XE,YE,@mayordomo+64)
spriteh (12)
andsprite (XVENT,YVENT,@ventana1)
xorsprite (XVENT,YVENT,@ventana1+32)
spriteh (16)
'BUCLE PRINCIPAL
bucle:
DO
GOSUB teclado
GOSUB mayordom
GOSUB impresion
LOOP
end
'lectura del teclado
teclado:
LET UP=MULTIKEYS(KEYQ)
LET DOWN=MULTIKEYS(KEYA)
LET LEFT=MULTIKEYS(KEYO)
LET RIGHT=MULTIKEYS(KEYP)
IF UP AND (X-16)>25 AND Y>101-(X/2) AND Y<138+(X/2)THEN LET X=X-VELOCIDAD: LET DIRECCION=1:END IF
IF DOWN AND X+16<120 THEN LET X=X+VELOCIDAD: LET DIRECCION=0: END IF
IF LEFT AND Y>101-(X/2) THEN LET Y=Y-VELOCIDAD: LET DIRECCION=3:END IF
IF RIGHT AND Y<138+(X/2) THEN LET Y=Y+VELOCIDAD: LET DIRECCION=2:END IF
IF UP+DOWN+LEFT+RIGHT>0 THEN LET FRAME=FRAME+1:IF FRAME>1 THEN LET FRAME=0:END IF:END IF
RETURN
mayordom:
LET XE=XE+(VERTICAL*VELOCIDADE)
LET YE=YE+(HORIZONTAL*VELOCIDADE)
'IF INT (RND*100)=1 THEN LET VERTICAL=1:END IF
'IF INT (RND*100)=1 THEN LET HORIZONTAL=1: END IF
IF XE<43 OR XE>103 THEN LET VERTICAL=VERTICAL*-1:END IF
IF YE<101-(XE/2) OR YE>138+(XE/2) THEN LET HORIZONTAL=HORIZONTAL*-1:END IF
'LET CONTADORE=CONTADORE +1:IF CONTADORE>100 THEN LET DIRECCIONE=INT (RND*2):LET CONTADOREE=0:GOSUB CAMBIODIRE:END IF
LET FRAMEE=FRAMEE+1: IF FRAMEE>1 THEN LET FRAMEE=0:END IF
RETURN
CAMBIODIRE:
IF DIRECCIONE=0 THEN LET VERTICAL=VERTICAL*(-1):LET HORIZONTAL=0:END IF
IF DIRECCIONE=1 THEN LET HORIZONTAL =HORIZONTAL*-1:LET VERTICAL=0:END IF
RETURN
impresion:
ASM
HALT
; Wait for scan line
LD BC,1137
fspRedrawloop:
DEC BC
LD A,B
OR C
JR NZ,fspRedrawloop
END ASM
rstbuffer (XA,YA,@buser)
rstbuffer (XEA,YEA,@buser3)
rstbuffer (XVENT,YVENT,@buser2)
cpbuffer (X,Y,@buser)
cpbuffer (XE,YE,@buser3)
cpbuffer (XVENT,YVENT,@buser2)
IF X<=XE THEN GOSUB GENTLE:GOSUB MAYORD:END IF
IF XE<X THEN GOSUB MAYORD:GOSUB GENTLE:END IF
GOSUB VENTAN
LET XA=X:LET YA=Y
LET XEA=XE:LET YEA=YE
RETURN
GENTLE:
andsprite (X,Y,@gentlecillo+(DIRECCION*64)+(FRAME*32))
xorsprite (X,Y,@gentlecillo+256+(DIRECCION*64)+(FRAME*32))
RETURN
MAYORD:
andsprite (XE,YE,@mayordomo+FRAMEE*32)
xorsprite (XE,YE,@mayordomo+64+(FRAMEE*32))
RETURN
VENTAN:
spriteh (12)
andsprite (XVENT,YVENT,@ventana1)
xorsprite (XVENT,YVENT,@ventana1+32)
spriteh (16)
RETURN
SUB FASTCALL ARQUITECTURA()
HABITACIONESCONPUERTA:
'pared inferior con puerta
plot 54,68:draw 65,0
draw 5,-2:draw 7,0:draw 5,2
draw 65,0
'papred izquierda con puerta
plot 48,75: draw 16,32
draw 0,20: draw 6,10:draw 0,-20
draw 9,18
'pared derecha con puerta
plot 52+128+26,75: draw -16,32
draw 0,20: draw -6,10:draw 0,-20
draw -9,18
'pared superior con puerta
plot 48+122,76+32+30: draw -36,0
draw 0,16:draw -15,0:draw 0,-16
draw -35,0
RETURN
RODAPIECONPUERTA:
'rodapie inferior con puerta
plot 55,70:draw 64,0
plot 56+64+16,70:draw 64,0
'rodapie izquierda con puerta
plot 50,75: draw 16,32
plot 50+16+6,75+32+10:draw 9,18
'rodapie derecha con puerta
plot 50+128+26,75: draw -16,32
plot 50+128+4,75+32+10:draw -9,18
'rodapie superior con puerta
plot 48+122,76+32+28:draw -35,0
plot 50+68,76+32+28: draw -34,0
RETURN
HABITACIONESSINPUERTA:
'pared inferior sin puerta
plot 54,68:draw 145,0
'pared izquierda sin puerta
plot 48,75: draw 30,60
'pared derecha sin puerta
plot 206,75: draw -30,60
'pared superior sin puerta
plot 170,138: draw -86,0
RETURN
RODAPIESSINPUERTA:
'rodapie inferior sin puerta
plot 55,70:draw 145,0
'rodapie izquierda sin puerta
plot 50,75: draw 30,60
'rodapie derecha sin puerta
plot 204,75: draw -30,60
'rodapie superior sin puerta
plot 170,136:draw -86,0
RETURN
ESQUINAS:
'esquina superior derecha
plot 175,136:draw -2,2:draw -2,0
plot 173,136:draw -1,0:draw -1,0
'esquina superior izquierda
plot 81,136:draw 1,0:draw 1,0
plot 79,136:draw 2,2:draw 2,0
'esquina inferior izquierda
plot 54,68:draw -4,2:draw -2,2:draw 0,2
plot 54,70:draw -3,2:draw -1,1:draw 0,1
'esquina inferior derecha
plot 200,68:draw 4,2:draw 2,2:draw 0,2
plot 200,70:draw 3,2:draw 1,1:draw 0,1
RETURN
SOTANOSINPUERTA:
'pared inferior sin puerta
plot 54,68:draw 30,-4:draw 20,2:draw 50,-3:draw 45,5
'pared izquierda sin puerta
plot 48,75: draw 5,23:draw 10,9:draw 5,19:draw 10,9
'pared derecha sin puerta
plot 206,75: draw -5,23:draw -10,9:draw -5,19:draw -10,9
'pared superior sin puerta
plot 170,138: draw -15,10: draw -8,-5:draw -20,6:draw -18,-8:draw -15,7:draw -10,-10
RETURN
RODAPIESOTANOSINPUERTA:
'rodapie inferior sin puerta
plot 55,70:draw 145,0
'rodapie izquierda sin puerta
plot 50,75: draw 30,60
'rodapie derecha sin puerta
plot 204,75: draw -30,60
'rodapie superior sin puerta
plot 170,136:draw -86,0
RETURN
SOTANOCONPUERTA:
'pared inferior con puerta
plot 54,68:draw 30,-4:draw 20,2:draw 15,-1:draw -1,-6:draw 5,-2:draw 6,1:draw 8,-1:draw -1,10:draw 35,-5:draw 28,6
'pared izquierda con puerta
plot 48,75: draw 2,20:draw 12,16
draw -2,10:draw -2,4:draw 7,2:draw 3,5:draw 0,-5:draw 2,-7
draw 2,12:draw 6,4
'pared derecha con puerta
plot 206,75: draw -2,20:draw -12,16
draw 2,10:draw 2,4:draw -7,2:draw -3,5:draw 0,-5:draw -2,-7
draw -2,12:draw -6,4
'pared superior con puerta
plot 170,138: draw -15,10: draw -8,-5:draw -15,6
draw 3,8:draw -2,-1:draw -8,1:draw -6,-4:draw 1,-12
draw -15,3:draw -10,-2:draw -5,4:draw -6,-8
RETURN
END SUB
ARQUITECTURA()
SUB FASTCALL DECORACION()
ALFOMBRA:
plot 72,80:draw 108,0:draw -20,48:draw -68,0:draw -20,-48
for triangulo=1 to 24 step 2:plot 72+triangulo*2,80+triangulo:draw 108-(4*triangulo),0:next
for triangulo=1 to 24 step 2:plot 92+triangulo,128-triangulo:draw 68-(2*triangulo),0:next
RETURN
ESTRELLA:
for estrella=0 to 1
plot 126+estrella,80: draw 30,40-estrella:draw -60,0:draw 30,-40+estrella
plot 126+estrella,130:draw -40,-35+estrella:draw 80,0:draw -40,35-estrella
next
RETURN
MADERA:
for suelo=0 to 15
plot 50+suelo*2,74+suelo*4: draw 153-(suelo*4),0
next
for suelo=0 to 15 step 2
plot 64+suelo*2,74+suelo*4: draw 1,3
plot 96+suelo,70+suelo*4: draw 0,4
plot 128,74+suelo*4: draw 0,4
plot 160-suelo,70+suelo*4: draw 0,4
plot 192-suelo*2,74+suelo*4: draw -1,3
next
RETURN
LABERINTO:
plot 62,78: draw 130,0:draw -26,52:draw -78,0
draw -22,-44:draw 112,0:draw -18,36:draw -64,0
draw -13,-26:draw 76,0: draw -8,16:draw -50,0
draw -4,-8:draw 48,0
RETURN
SUELOEQUIS:
FOR EQUIS=0 TO 2
PLOT 85+EQUIS,75+EQUIS: DRAW 15,0:DRAW 25,25:DRAW 25,-25:DRAW 15,0
DRAW -30,30:DRAW 22,25:DRAW -12,0:DRAW -20,-20:DRAW -20,20:DRAW -12,0:DRAW 22,-25:DRAw -30,-30
NEXT
RETURN
FLECHADERECHA:
FOR FLECHA=0 TO 2
PLOT 85+FLECHA,103+FLECHA: DRAW 30,0:DRAW -5,-20:DRAW 55,25
DRAW -46,20: DRAW -3,-12:DRAW -26,0:DRAW -5,-13
NEXT
RETURN
FLECHAIZDA:
FOR FLECH=0 TO 2
PLOT 170+FLECH,103+FLECH: DRAW -30,0:DRAW 5,-20:DRAW -55,25
DRAW 46,20: DRAW 3,-12:DRAW 26,0:DRAW 5,-13
NEXT
RETURN
END SUB
DECORACION()
END
SUB FASTCALL GRAFICOS()
#include "d:\basiclib\sprite2.bas"
'#include "d:\basiclib\spritebuffer.bas"
#include "d:\basiclib\unchunk.bas"
espare:
ASM
espare:
defS 32,0
END ASM
gentlecillo:
ASM
; ASM source file created by SevenuP v1.20
; SevenuP (C) Copyright 2002-2006 by Jaime Tejedor Gomez, aka Metalbrain
;GRAPHIC DATA:
;Pixel Size: ( 16, 16)
;Char Size: ( 2, 2)
;Frames: 8 q
;Sort Priorities: X char, Char line, Y char, Frame number, Mask
;Data Outputted: Gfx
;Interleave: Frames
;Mask: Yes, before graphic
gentlecillo2:
DEFB 240, 15,224, 7,224, 7,224, 7
DEFB 224, 7,224, 7,224, 7,192, 3
DEFB 128, 1,128, 1,128, 1,192, 3
DEFB 128, 7,128, 3,129, 3,129, 3
DEFB 240, 15,224, 7,224, 7,224, 7
DEFB 224, 7,224, 7,224, 7,192, 3
DEFB 128, 1,128, 1,128, 1,192, 3
DEFB 224, 1,192, 1,192,129,192,129
DEFB 240, 15,224, 7,224, 7,224, 7
DEFB 224, 7,224, 7,224, 7,192, 3
DEFB 128, 1,128, 1,128, 1,192, 3
DEFB 128, 7,129, 3,129, 3,129, 3
DEFB 240, 15,224, 7,224, 7,224, 7
DEFB 224, 7,224, 7,224, 7,192, 3
DEFB 128, 1,128, 1,128, 1,192, 3
DEFB 224, 1,192,129,192,129,192,129
DEFB 240, 15,224, 7,224, 7,224, 7
DEFB 224, 7,224, 7,224, 7,192, 3
DEFB 128, 1,128, 1,128, 1,192, 3
DEFB 224, 7,248, 3,248, 3,248, 3
DEFB 240, 15,224, 7,224, 7,224, 7
DEFB 224, 7,224, 7,224, 7,192, 3
DEFB 128, 1,128, 1,128, 1,192, 1
DEFB 224, 1,224, 1,224, 1,224, 3
DEFB 240, 15,224, 7,224, 7,224, 7
DEFB 224, 7,224, 7,224, 7,192, 3
DEFB 128, 1,128, 1,128, 1,192, 3
DEFB 224, 7,192, 31,192, 31,192, 31
DEFB 240, 15,224, 7,224, 7,224, 7
DEFB 224, 7,224, 7,224, 7,192, 3
DEFB 128, 1,128, 1,128, 1,128, 3
DEFB 128, 7,128, 7,128, 7,192, 7
DEFB 0, 0, 7,224, 15,240, 11,208
DEFB 12, 48, 15,240, 13,176, 15,240
DEFB 23,232, 57,156, 30,120, 7,240
DEFB 25,128, 44, 48, 60, 88, 0,120
DEFB 0, 0, 7,224, 15,240, 11,208
DEFB 12, 48, 15,240, 13,176, 15,240
DEFB 23,232, 57,156, 30,120, 15,224
DEFB 1,152, 12, 44, 22, 60, 30, 0
DEFB 0, 0, 7,224, 15,240, 11,208
DEFB 12, 48, 15,240, 15,240, 15,240
DEFB 23,232, 57,156, 30,120, 7,240
DEFB 25,128, 60, 48, 60,120, 0,120
DEFB 0, 0, 7,224, 15,240, 11,208
DEFB 12, 48, 15,240, 15,240, 15,240
DEFB 23,232, 57,156, 30,120, 15,224
DEFB 1,152, 12, 60, 30, 60, 30, 0
DEFB 0, 0, 7,224, 15,240, 11,208
DEFB 12, 48, 15,240, 15,208, 15,240
DEFB 23,232, 57,156, 30,120, 15,240
DEFB 0,192, 3, 48, 3,216, 3,224
DEFB 0, 0, 7,224, 15,240, 11,208
DEFB 12, 48, 15,240, 15,208, 15,240
DEFB 23,232, 57,156, 30,120, 15,240
DEFB 3,196, 12, 60, 14, 56, 7, 0
DEFB 0, 0, 7,224, 15,240, 11,208
DEFB 12, 48, 15,240, 11,240, 15,240
DEFB 23,232, 57,156, 30,120, 15,240
DEFB 3, 0, 12,192, 27,192, 7,192
DEFB 0, 0, 7,224, 15,240, 11,208
DEFB 12, 48, 15,240, 11,240, 15,240
DEFB 23,232, 57,156, 30,120, 15,240
DEFB 35,192, 60, 48, 28,112, 0,224
END ASM
espare3:
ASM
espare3:
; defs 24,0
END ASM
mayordomo:
ASM
mayordomo:
DEFB 224, 15,224, 15,224, 15,224, 15
DEFB 192, 7,128, 3,128, 3,128, 3
DEFB 128, 3,128, 3,128, 3,128, 3
DEFB 128, 3,128, 3,128, 3,224, 7
DEFB 240, 31,224, 15,224, 15,224, 15
DEFB 192, 7,128, 3,128, 3,128, 3
DEFB 128, 3,128, 3,128, 3,128, 3
DEFB 128, 3,128, 3,128, 3,224, 31
DEFB 7,192, 15,224, 10,160, 1, 0
DEFB 4, 64, 23,208, 38,200, 52, 88
DEFB 42,168, 51,152, 42,168, 51,152
DEFB 42,168, 57, 56, 12, 96, 0,112
DEFB 0, 0, 7,192, 15,224, 10,160
DEFB 1, 0, 20, 80, 39,200, 38,200
DEFB 52, 88, 41, 40, 50,152, 43,168
DEFB 50,152, 57, 56, 6,192, 14, 0
END ASM
ventana1:
ASM
ventana12:
DEFB 0, 0, 0, 0, 0, 0, 31,248
DEFB 31,248, 31,248, 31,248, 31,248
DEFB 31,248, 0, 0, 0, 0, 0, 0
DEFB 0, 0, 0, 0, 0, 0, 0, 0
DEFB 170,170, 85, 85,128, 3, 64, 3
DEFB 128, 3, 64, 3,128, 3, 64, 3
DEFB 128, 3, 64, 3,191,253,127,254
DEFB 0, 0, 0, 0, 0, 0, 0, 0
END ASM
escudo1:
ASM
escudolibra:
DEFB 0, 0,127,254,254,127,253,191
DEFB 122, 94,116, 46,116, 46,111,134
DEFB 36, 4, 47,132, 52, 12, 23,232
DEFB 24, 24, 15,240, 7,224, 1,128
END ASM
armadura:
ASM
relojpared:
DEFB 3,192, 14,176, 21, 88, 43,236
DEFB 52, 52, 41, 28, 89, 22,113, 10
DEFB 81,206,112, 10, 82, 78,114, 74
DEFB 82,238,119,106, 87, 14,112, 10
DEFB 95,246,106,170,127,254, 24, 24
DEFB 24, 24, 0, 0, 0, 0, 0, 0
END ASM
buser:
ASM
buser:
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
END ASM
buser2:
ASM
buser2:
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
END ASM
buser3:
ASM
buser3:
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
END ASM
pantalla:
asm
incbin "gentle.rle"
end asm
END SUB
GRAFICOS ()
The sprite libary (sprite2.bas):
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
SUB cpbuffer (xd as ubyte,yd as ubyte,buff as Uinteger)
POKE @buffer,xd:POKE @buffer+1,yd: POKE uinteger @buffer+5,buff
gosub copybuffer
END SUB
SUB rstbuffer (xd as ubyte,yd as ubyte,buff as Uinteger)
POKE @buffer,xd:POKE @buffer+1,yd: POKE uinteger @buffer+5,buff
gosub restorebuffer
END SUB
SUB cpattr (xd as ubyte, yd as ubyte, buff as Uinteger)
LET xattr=INT (xd/8): LET yattr=INT (yd/8): LET dirattr=22528+(32*xattr)+yattr
'POKE uinteger @buffer+5,buff
POKE buff,PEEK dirattr: POKE buff+1,PEEK (dirattr+1): POKE buff+2,PEEK (dirattr+2)
POKE buff+3,PEEK (dirattr+32): POKE buff+4,PEEK (dirattr+33): POKE buff+5,PEEK (dirattr+34)
POKE buff+6,PEEK (dirattr+64): POKE buff+7,PEEK (dirattr+65): POKE buff+8,PEEK (dirattr+66)
END SUB
SUB rstattr (xd as ubyte, yd as ubyte, buff as Uinteger)
LET xattr=INT (xd/8): LET yattr=INT (yd/8): LET dirattr=22528+(32*xattr)+yattr
'POKE uinteger @buffer+5,buff
POKE dirattr,PEEK buff: POKE dirattr+1,PEEK (buff+1): POKE dirattr+2,PEEK (buff+2)
POKE dirattr+32,PEEK (buff+3): POKE dirattr+33,PEEK (buff+4): POKE dirattr+34,PEEK (buff+5)
POKE dirattr+64,PEEK (buff+6): POKE dirattr+65,PEEK (buff+7): POKE dirattr+66,PEEK (buff+8)
END SUB
SUB fondocolor (col as ubyte)
POKE @dircol+1,col
ASM
ld a,14
ld hl,22630
lineacolor:
ld b,20
celdacolor:
END ASM
dircol:
ASM
ld (hl),12
inc hl
djnz celdacolor
ld DE,12
add hl,DE
dec a
jp nz,lineacolor
END ASM
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
buffer:
ASM
xcoord: defb 0
ycoord: defb 0
altura: defb 0
gfx: defw 0
buf: defw 0
END ASM
copybuffer:
ASM
copybuffer:
;rutina para copiar algo en algun sitio, más o menos.
; This routine returns a screen address for (c, b) in de.
ld bc,(xcoord)
call scadd
ld (gfx),de
ld b,16
ld HL,(gfx) ;apuntar a la primera celda de la pantalla
ld DE,(buf) ;apuntar al buffer
bucle3: ld a,(HL) ;capturo el grafico en a
;LD C,a ;y lo paso a C
;ld a,(HL) ;cargo en a el contenido de la celda destino
;xor C ;xoreo con lo que traigo del grafico
ld (DE),a ;lo pinto en (hasta aquí sale xdd)
inc L
inc E
ld a,(HL)
ld (DE),a
inc L
inc E
ld a,(HL)
ld (DE),a
dec L
dec L
call uphl
inc E
djnz bucle3
ret
END ASM
restorebuffer:
ASM
restorebuffer:
;rutina para copiar algo en algun sitio, más o menos.
; This routine returns a screen address for (c, b) in de.
ld bc,(xcoord)
call scadd
ld (gfx),de
ld b,16
ld HL,(gfx) ;apuntar a la primera celda del destino
ld DE,(buf) ;apuntar al origen
bucle2: ld a,(DE) ;capturo el grafico en a
;LD C,a ;y lo paso a C
;ld a,(HL) ;cargo en a el contenido de la celda destino
;xor C ;xoreo con lo que traigo del grafico
ld (HL),a ;lo pinto en la pantalla (hasta aquí sale xdd)
inc L
inc E
ld a,(DE)
ld (HL),a
inc L
inc E
ld a,(DE)
ld (HL),a
dec L
dec L
call uphl
inc E
djnz bucle2
ret
uphl:
inc h
ld a,h
and 7
ret nz
ld a,l
add a,32
ld l,a
ret c
ld a,h
sub 8
ld h,a
ret
END ASM
Re: Another strange thing related to the "graphics overwriting" - boriel - 03-21-2010
apenao Wrote:I have polished a bit my sprite routine, writting it in just one file and erasing repeated code (it worked OK up to this point) and adding a new subroutine to set the background colour of the playing area. Wheter I use or not this routine (and even if I take it out of the sprite routine file and copy it in any part of the main program code) its causing the graphics behave strangely.
When I'm drawing the "show room" (the only one atm, where I'm trying the graphics and the movements) I call (via Gosub) the routines drawing the different parts, i.e.:
GOSUB ESQUINA -- DRAWS THE CORNERS
GOSUB HABITACINESCONPUERTA -- DRAWS THE "WALLS" AND THE DOORS
When I draw the decoration parts (i.e. a carpet, or different floor designs) I see one of the coordinates of the sprites is changed:
If I draw the carpet (GOSUB ALFOMBRA), then the transparent window has its Y coordinate changed, whatever the correct value is.
If I draw the star (GOSUB ESTRELLA), the main sprite's X coordinate is changed. If I let the GOSUB ESTRELLA, I don't notice anything special. :?: If I use GOSUB ALFOMBRA, then the moving sprite gets corrupted.
It seems something is corrupting the stack frame, but I don't know what is it. I will investigate it further...
What I want to make clear is that those seems to be collateral effects, and might not be related to PLOT/DRAW at all, but for example, to stack or heap corruption. I see you use much inline asm blocks and gosubs, and this is not a good idea. You should make your routines directly callable from BASIC instead. I suggest you to try convert them using this:
- If the function takes a single parameter, just use SUB FASTCALL xxx(param as..) scheme. The parameter will came in A register (if it is ubyte), HL if it's 16 bits, HLDE if it's 32 bits and A BCDE if it's FLOAT (like ZX Spectrum ROM). You can use RET at any point inside a FASTCALL sub. If you use FUNCTION, it's the same, but those registers will be also used to get the RETURN VALUE.
- If the function takes more than one parameter, then it's better to use the normal (STDCALL) scheme. But guessing parameter addresses might by hard. So let the compiler TELL YOU.
Since you can tell the compiler to generate ASM, you can get the parameter addresses, creating a dummy SUB and getting it's asm:
Code: SUB dummyTest(param1 as Ubyte, param2 as Uinteger)
DIM b as Uinteger
param1 = 1
param2 = 2
b = 5
END SUB
Compiling with zxb -A test.bas will create test.asm, which reads:
Code: ...
29 _dummyTest:
30 push ix
31 ld ix, 0
32 add ix, sp
33 ld hl, 0
34 push hl
35 ld (ix+5), 1
36 ld (ix+6), 2
37 ld (ix+7), 0
38 ld (ix-2), 5
39 ld (ix-1), 0
40 _dummyTest__leave:
41 ld sp, ix
42 pop ix
43 exx
44 pop hl
45 pop bc
46 ex (sp), hl
47 exx
48 ret
This is your SUB compiled. Notice now what's happening. Line 35 stores 5 at (ix + 5). So (ix + 5) if addr of param1 (you can read and write at any param address). And param2 is (ix+6) (Low byte) and (ix+7) (high byte). Local variable b is at (ix - 2) (low byte) and (ix - 1) (high byte). Notice IX + n are used for parameters and IX - n for local vars.
WARNING: Unlike FASTCALL subroutines, you can't return with RET from an STDCALL SUB or FUNCTION. You must clean and restore the stack frame, so to return you must JUMP to _dummyTest__leave.
Now you can start an ASM... END ASM block inside the subroutine, using the (ix+n) addresses to get the values passed by the caller. This is the way the compiler works, and it's the way you should too. When you write code outside the subroutines, the compiler might move it to another location (even with optimization disabled). In fact, SUBs and FUNCTIONS are moved to the end of the program, before the variables memory zone.
Re: Another strange thing related to the "graphics overwriting" - boriel - 03-23-2010
Ok, I have tested your file. I removed the DEFS "spare", and your program worked ok to me. :?: :?: :?:
Also noticed you do "GOSUB ALFOMBRA", and so on, into a SUB body. This only works with labels inside FASTCALL functions and subrotines (as you do), but you shouldn't do that anyway. So:
Code: GOSUB label
...
SUB mySub
...
label:
...
RETURN : REM *CRASH*, because returns here tries to "restore" the stack.
END SUB
Incidentally, your program works *ok* to me. I'm not experiencing those glitches... :?: :?: :?:
Re: Another strange thing related to the "graphics overwriting" - boriel - 03-24-2010
After debugging your program for a LONG time, I've concluded that you use optimized sprite routines that relies on memory alignment addresses. I'm going to implement that (yes, an ALIGN n directive, so the code will be aligned to the closes n*ADDRESS code; this will be difficult to implement at the moment).
So basically, I discovered you have an INK O (instead of INK 0) sentence. By replacing it with INK 0, everything it's fixed. After a lot of tests, adding or removing NOPs to your code mades it to work ok or "dirty". These are alignment issues, and it seems to be on the sprite2.bas file. Probably you're using INC L and INC E instead of INC HL and INC DE or something. I guess that's the point. Other than that, your program is Ok.
A fast fix for that is to use "Spare" zones as you did: DEFS N, 0. Start from 1, and increase N until the program works ok.
¿Can you fix it?
Re: Another strange thing related to the "graphics overwriting" - apenao - 03-24-2010
Yep, it's fixed now
Sorry for the inconvenience. I'll check the sprite routine when I finish the map and the graphics. By now, I'm ok with the spare buffer solution.
Thanks a lot
Re: Another strange thing related to the "graphics overwriting" - britlion - 03-24-2010
Once again, Boriel goes above and beyond the call of duty.
We appreciate it!
Re: Another strange thing related to the "graphics overwriting" - boriel - 03-24-2010
Ok, if no more bugs until this weekend, I will close this release, and start 1.2.6 with new features.
|