![]() |
|
PutTile16x16 Pixels + Attributes - Printable Version +- Boriel Basic Forum (https://forum.boriel.com) +-- Forum: Compilers and Computer Languages (https://forum.boriel.com/forumdisplay.php?fid=12) +--- Forum: ZX Basic Compiler (https://forum.boriel.com/forumdisplay.php?fid=11) +---- Forum: How-To & Tutorials (https://forum.boriel.com/forumdisplay.php?fid=13) +---- Thread: PutTile16x16 Pixels + Attributes (/showthread.php?tid=227) Pages:
1
2
|
Re: PutTile16x16 Pixels + Attributes - britlion - 2010-05-31 Okay. This is faster. it's also quite a lot longer! I had to hand time this at about 8.5 seconds for 80 loops. Which means it takes about 5.3 frames to fill the screen once. (Your 8 loop test would take about 42 frames). I can't use the frames counter to time it, because Interrupts HAVE to be disabled. I hope around 3 times faster is good? This could probably be optimized slightly better, I don't think I'm using passed in parameters well. I also think you might be able to see how the fourspriter code was made to go quite a lot faster... Code: SUB putTile(x as uByte, y as uByte, graphicsAddr as uInteger)
poke @ptx+1,x
poke @pty+1,y
poke Uinteger @ptgraddr+1,graphicsAddr
ptDataPoint:
asm
JP pt_start
ptstackSave:
defb 0,0
pt_start:
ld a,i
push af ; Save interrupt status.
; Routine to save the background to the buffer
DI ; we really, really, REALLY can NOT be having interrupts while the stack and IX and IY are pointed elsewhere.
PUSH IX
PUSH IY
end asm
ptgraddr:
asm
ld HL, 65535 ; Self modifying code should load this with the graphics address.
;; Print sprites routine
LD (ptstackSave), SP ; Save Stack Pointer
LD SP,HL ; now SP points at the start of the graphics.
; This function returns the address into HL of the screen address
end asm
ptx:
asm
ld a,0 ; Load in x
ld IYH, a ; save it
ld l,a
end asm
pty:
asm
ld a,0 ; Load in y
ld IYL, a ; save it
ld d,a
and 24
add a,64
ld h,a
ld a,d
and 7
rrca
rrca
rrca
or l
add a,2 ; Need to be to the right so backwards writing pushes land properly.
ld l,a
; SO now, HL -> Screen address, and SP -> Graphics. Time to start loading.
POP BC ; Row 0
POP DE ; row 1
EX AF,AF'
POP AF ; row 2
EX AF,AF'
EXX
POP BC ; row 3
POP DE ; row 4
POP HL ; row 5
EXX
; All right. We're loaded. Time to dump!
LD IX,0
ADD IX,SP ; Save our stack pointer into IX
LD SP,HL ; point at the screen.
PUSH BC ; row 0
INC H
LD SP,HL
PUSH DE ; row 1
INC H
LD SP,HL
EX AF,AF'
PUSH AF ; row 2
INC H
LD SP,HL
EXX
PUSH BC ; row 3
EXX
INC H
LD SP,HL
EXX
PUSH DE ; row 4
EXX
INC H
LD SP,HL
EXX
PUSH HL ; ROW 5
EXX
; We're empty. Time to load up again.
LD SP,IX
POP BC ; ROW 6
POP DE ; ROW 7
EX AF,AF'
POP AF ; ROW 8
EX AF,AF'
EXX
POP BC ; ROW 9
POP DE ; ROW 10
POP HL ; ROW 11
EXX
; and we're loaded up again! Time to dump this graphic on the screen.
LD IX,0
ADD IX,SP ; save SP in IX
INC H
LD SP,HL
PUSH BC ; ROW 6
INC H
LD SP,HL
PUSH DE ; ROW 7
DEC HL
DEC HL
; Aha. Snag. We're at the bottom of a character. What's the next address down?
ld a,l
and 224
cp 224
jp z,ptSameThird3
ptNextThird3:
ld de,1760
and a
sbc hl,de
jp ptAddrDone3
ptSameThird3:
ld de,32
and a
adc hl,de
ptAddrDone3:
INC HL
INC HL
LD SP,HL
EX AF,AF'
PUSH AF ; ROW 8
INC H
LD SP,HL
EXX
PUSH BC ; ROW 9
EXX
INC H
LD SP,HL
EXX
PUSH DE ; ROW 10
EXX
INC H
LD SP,HL
EXX
PUSH HL ; ROW 11
EXX
; Okay. Registers empty. Reload time!
LD SP,IX
POP BC ; ROW 12
POP DE ; ROW 13
EXX
POP BC ; ROW 14
POP DE ; ROW 15
POP HL ; Top Attrs
EXX
EX AF,AF'
POP AF ; Bottom Attrs
EX AF,AF'
; and the last dump to screen
INC H
LD SP,HL
PUSH BC
INC H
LD SP,HL
PUSH DE
INC H
LD SP,HL
EXX
PUSH BC
EXX
INC H
LD SP,HL
EXX
PUSH DE
EXX
end asm
#line 222
asm
; Pixels done. Just need to do the attributes.
; So set HL to the attr address:
ld a,IYL ;ypos
rrca
rrca
rrca ; Multiply by 32
ld l,a ; Pass to L
and 3 ; Mask with 00000011
add a,88 ; 88 * 256 = 22528 - start of attributes.
ld h,a ; Put it in the High Byte
ld a,l ; We get y value *32
and 224 ; Mask with 11100000
ld l,a ; Put it in L
ld a,IYH ; xpos
adc a,l ; Add it to the Low byte
ld l,a ; Put it back in L, and we're done. HL=Address.
INC HL ; we need to be to the right of the ATTR point as pushes write backwards.
INC HL
; attr
LD SP,HL
EXX
PUSH HL ; top row
EXX
LD HL,34 ; we need to move down to the next row. We already backed up 2, so we add 34.
ADD HL,SP
LD SP,HL
EX AF,AF' ; bottom row
PUSH AF
ptNextSprite2:
; done. Cleanup.
LD SP,(ptstackSave) ; put our stack back together.
; done all 4 final clean up
POP IY
POP IX
POP AF ; recover interrupt status
JP PO, pt_nointerrupts ; skip EI if we didn't have them enabled to begin with.
EI ; Okay. We put everything back.
pt_nointerrupts:
END ASM
END SUB
dim x,y as ubyte
dim adr as Uinteger
adr=0
for y=0 to 11
for x=0 to 15
putTile(x<<1,y<<1,adr)
'adr=adr+36
next x
next yRe: PutTile16x16 Pixels + Attributes - boriel - 2010-05-31 britlion Wrote:Oh, so it's not passing the first value in the stack - stdcall passes it in the register AND in the stack, which is a little confusing.You CAN, but you SHOULD NOT, unless you really manage the stack yourself. :roll: If you use FASTCALL in a function with 2 or more params, or a function with local vars, it will crash your program. Re: PutTile16x16 Pixels + Attributes - britlion - 2010-05-31 boriel Wrote:You CAN, but you SHOULD NOT, unless you really manage the stack yourself. :roll: If you use FASTCALL in a function with 2 or more params, or a function with local vars, it will crash your program. So YOU get to break all the rules? We kids never have any fun. :-) Understood. Re: PutTile16x16 Pixels + Attributes - LCD - 2010-06-01 britlion Wrote:Okay. This is faster. it's also quite a lot longer!Britlion, this is great! That's what I call "fast". I wonder a bit why the tiles from ROM at position 0 looks different in your version than from mine. I don't care anyyway because I can adapt my BorIDE Tile editor then for it, if the format is different. Now with THAT fast PutTile routine we can write very fast games. Re: PutTile16x16 Pixels + Attributes - britlion - 2010-06-01 LCD Wrote:Britlion, this is great! That's what I call "fast". I wonder a bit why the tiles from ROM at position 0 looks different in your version than from mine. I don't care anyyway because I can adapt my BorIDE Tile editor then for it, if the format is different. Now with THAT fast PutTile routine we can write very fast games. LCD: This isn't exactly well tested yet. It could be putting out bad data. :-) Congratulations on being a beta tester! Re: PutTile16x16 Pixels + Attributes - LCD - 2010-06-01 britlion Wrote:Now it is tested. You have attribute after complete bitmap date, I had Attribute after each Line of date, so I fixed this in my version. Thanks...LCD Wrote:Britlion, this is great! That's what I call "fast". I wonder a bit why the tiles from ROM at position 0 looks different in your version than from mine. I don't care anyyway because I can adapt my BorIDE Tile editor then for it, if the format is different. Now with THAT fast PutTile routine we can write very fast games. Re: PutTile16x16 Pixels + Attributes - britlion - 2010-06-01 I'm glad it's working for you! Didn't realise you had attributes there. Would be too hard to make the code do that, I guess, owing to the method of access. You could do attributes first, or last, but not middle. It did seem to make more sense to go in order of lowest memory address to highest, somehow. You can get about 20% of the tiles changed inside one screen refresh, so it doesn't really matter too much which way round that happens. Glad you like it. Now I'm intrigued as to what you are doing with it.... Re: PutTile16x16 Pixels + Attributes - britlion - 2010-06-01 boriel Wrote:The problem here is __ATTR_ADDR is taking into account a configurable SCREEN_ADDRESS variable (previously discussed here). So if you want your program to work in a variable screen address, you should work considering 0 offset an adding (SCREEN_ADDRESS) at the end, so should change it this way: Boriel - if you put in the limit that any screen address has to be 256-byte aligned (and really, it should be. That's the whole point of INC H going to the next line in a character), then you could just tweak the add A,88 there to add in the "page number" instead.... no? I think that would be a better result, allowing for a variable screen address. Incidentally, why have a variable screen address? For writing to a shadow screen? If it's about other computers....they won't have the screen layout of a spectrum anyway! Re: PutTile16x16 Pixels + Attributes - LCD - 2010-06-01 britlion Wrote:I'm glad it's working for you! Didn't realise you had attributes there. Would be too hard to make the code do that, I guess, owing to the method of access. You could do attributes first, or last, but not middle. It did seem to make more sense to go in order of lowest memory address to highest, somehow. You can get about 20% of the tiles changed inside one screen refresh, so it doesn't really matter too much which way round that happens.No need to change anything, I love it. The 20% change is no problem if I use delta-scrolling (means: draw only tiles if they are changed). The routine is fast enough for my needs. britlion Wrote:Glad you like it. Now I'm intrigued as to what you are doing with it....First, it will be included in the code library of BorIDE together with PutChar and PutBlock, and then I will write one or two games using it.
Re: PutTile16x16 Pixels + Attributes - oblo - 2018-11-22 Hi all I'm trying to use britlion's putTile library but I'm getting screen garbage instead of a defined 2x2 UDG. For instance, please look at this code that defines a 2x2 circle: Code: Dim circulo(31) As uByte => { _
0, 63, 64, 67, 79, 79, 95, 95, _ REM bloque circulo 1 de 4
0,252, 2,194,242,242,250,250, _
95, 95, 79, 79, 67, 64, 63, 0, _
250,250,242,242,194, 2,252, 0 _
}
Poke uInteger 23675, (@circulo (0))
putTile (10,10,@circulo)Instead of printing a 2x2 circle with an outside square, it prints some screen garbage, including flashing sprites, so I must be reading and/or writing in a wrong memory address. Please, could you tell me what is the right way to deal with putTile and 2x2 sprites? Thanks and regards Re: PutTile16x16 Pixels + Attributes - britlion - 2018-11-23 You don't have enough data, for starters. It's years since I wrote it, so I'm going back to first principles - but right at the very top it says: ' Routine to place a 16 pixel by 16 pixel "Tile" onto the screen at character position x,y from adddress given. ' Data must be in the format of 16 bit rows, followed by attribute data. So, given I think it requires 68 bytes of data, it's clear that since you're only giving it 64 (scratch that. 32), you're going to get some random colour data. Also, I think you are giving it UDG, rather than 16 bit rows? Should be: 0,0, _ 63,252, _ 64,2, _ 67,194 _ 79,242, _ ... ... colour byte, colour byte, colour byte, colour byte I think. You are also doing a DIM of 32 bytes in your code there, and trying to put 64 bytes into it.... - that's a bit weird. So looks like you are actually defining a 1x2 half circle and giving it 32 bytes of extra data that's ignored? That would explain garbage on screen, I think. As well as the data not being ordered correctly. Code: Dim circulo(31)I don't think you should use an array. I don't know what extra data is in the array that might make it break. I'd just use an ASM block with an @pointer in it. Then it's raw data. Re: PutTile16x16 Pixels + Attributes - oblo - 2018-11-23 Thanks britlion, so I forgot to add more data and that's why isn't working I'll try it again, but in the meantime I was testing your FourSpriter (<!-- l --><a class="postlink-local" href="https://forum.boriel.com/how-to-tutorials/topic400.html">how-to-tutorials/topic400.html</a><!-- l --> and <!-- l --><a class="postlink-local" href="https://forum.boriel.com/how-to-tutorials/topic397.html">how-to-tutorials/topic397.html</a><!-- l -->) and it works very good for what I'm looking for.Cheers |