BIFROST* ENGINE 1.2 released!
Another improved version of the BIFROST* ENGINE is now available! Download it here:
http://www.worldofspectrum.org/infoseekid.cgi?id=0027405
This version provides the following improvements:
Notice however that version 1.2 does not support drawing tiles at arbitrary hires rows yet. I decided to postpone this feature until release 1.3. This way, programs that don't need to draw tiles at arbitrary positions can benefit from version 1.2, which is smaller and faster due to optimizations that won't be possible in 1.3.
http://www.worldofspectrum.org/infoseekid.cgi?id=0027405
This version provides the following improvements:
- Everything is now optimized for both speed and size. The entire code is now 6656 bytes only, which is quite small considering that just the multicolor loop to render 18x18 positions take 41*18*8=5904 bytes. Even so, most routines available for the programmer are optimized for speed, using unrolled loops and a couple lookup tables.
- Programmers now have a few routines available to "manually" draw/change/erase multicolor tiles instantly on screen, so these changes will appear immediately at the next frame, instead of the usual delay a few frames later (at the next tile map refresh). Moreover, "manual" and "automated" drawing can be used together freely, so it's possible to make a tile image immediately appear at a certain location on screen, then use automated updates to let BIFROST* interrupts animate it automatically afterwards...
- Backward compatibility! Any program written for previous versions of BIFROST* will still work, except for updating the POKE and CALL addresses. Programmers using the interface libraries (for Boriel's ZX BASIC or z80dk) won't need to do anything at all, it will be enough to download the new interface libraries that I will provide this week.
Notice however that version 1.2 does not support drawing tiles at arbitrary hires rows yet. I decided to postpone this feature until release 1.3. This way, programs that don't need to draw tiles at arbitrary positions can benefit from version 1.2, which is smaller and faster due to optimizations that won't be possible in 1.3.
Post edited by Einar Saukas on
Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
Comments
http://www.worldofspectrum.org/infoseekid.cgi?id=0027405
The tile (multicolor sprite) format is the same as ZXodus. IMHO the easiest way is to design the tiles as Timex screens in ZX-Paintbrush, then import the images into ColorTILE according to the instructions provided by ZXodus.
Thanks! I hope so :)
Reading the original post I would assume that they will be available later in the week:
You are welcome!
I will also release the updated z88dk interface library soon...
; race the raster beam to update attributes at the right time race_raster: REPT 18, ROWREPT REPT 8 ld sp, $5833+(32*ROWREPT) ld bc, 0 ; columns 01 and 02 ld de, 0 ; columns 03 and 04 ld hl, 0 ; columns 05 and 06 exx ld de, 0 ; columns 07 and 08 ld hl, 0 ; columns 09 and 10 ld bc, 0 ; columns 17 and 18 push bc ld bc, 0 ; columns 15 and 16 push bc ld bc, 0 ; columns 13 and 14 push bc ld bc, 0 ; columns 11 and 12 push bc push hl push de exx push hl push de push bc ENDM ENDMBifrost does 18 columns, yes? This repeatedly plays race with 12, it appears? Unless I'm going blind...
No, it is pushing 18 bytes onto the stack, note that columns 17 + 18 are in the middle (read over this a few times before seeing it too... :-))
(Im going to make an editor)
Also could I have an example if inputting the sprite data manually please?
It's based on the idea of ZXodus Engine but the code is original. You've got a window of 144x144 pixels that support 8x1 mode.
You should take a look at ColorTILE then. It needs a Timex 2048 emulator though.
The ColorTILE format (as used by ZXodus and Bifrost*) is simple: Each tile is 32 bytes of in-order bitmap data followed by 32 bytes of in-order attribute data. The tile file can be up to 256 tiles in length (16K). Bifrost* sprites are made using multiple tiles. It's probably worth you taking a look at the ZXodus docs as a starting point.
Correct. Each 8x1 char line can have its own attribute (INK, PAPER, BRIGHT, and FLASH) instead of an attribute for every 8x8 char position.
Excellent!
All versions of BIFROST* and ZXodus use the same format, thus the same editor will work for both :)
From BIFROST* ENGINE's documentation:
Thank you!
http://www.worldofspectrum.org/infoseekid.cgi?id=0027405
Games List 2016 - Games List 2015 - Games List 2014
You are welcome! :)
I know it's about timing the swap, but I understood a sweep across the screen was 224 T states.
So I'd expected race_raster to be 224 t states long.
It seems to be 207, which is a big difference.
Einar: How does this keep time if it's not in the same time frame?
ld sp, $5833+(32*ROWREPT) 10
ld bc, 0 ; columns 01 and 02 10
ld de, 0 ; columns 03 and 04 10
ld hl, 0 ; columns 05 and 06 10
exx 4
ld de, 0 ; columns 07 and 08 10
ld hl, 0 ; columns 09 and 10 10
ld bc, 0 ; columns 17 and 18 10
push bc 11
ld bc, 0 ; columns 15 and 16 10
push bc 11
ld bc, 0 ; columns 13 and 14 10
push bc 11
ld bc, 0 ; columns 11 and 12 10
push bc 11
push hl 11
push de 11
exx 4
push hl 11
push de 11
push bc 11
Total 207
(Edit: Something to do with contention keeping it synched?)
obo explains it brilliantly here:
http://simonowen.com/blog/2011/09/29/zxodus-engine/
Edit: Gasman wasn't the first to discover the technique. There's prior art here on WoSf but sadly I forget who came up with it. Sorry!
From BIFROST* ENGINE's credits section:
AMW's original post can be found here.
I did the classic case of "post it and then realise what I was forgetting".
I'm still intrigued that the repeating code locks to the sync, though I know that contention can tend to make these tend to smooth out, which is about the only good thing there is about contention!
One wonders, since all the pushes head to the left, as the beam heads to the right, as the last byte drops in just before the beam hits it, if there isn't time to revisit the other end of the row as the beam runs along towards it.
Also, what if you changed the parameters to 4x2 pixel colour blocks, instead of 8x1.
My thinking is you could fullscreen the effect; but unless I miss my guess, the colour over both halves of the screen would have to be offset by a row.
Might make for some fairly spectacular screens, however - even at medium-high resolution.
Also: If you can chase the beam for 144 pixel rows, why not 192?
No, there's no time left at all. You can change where the 144 pixels are on the line but that's it of you want to have 8x1 with independent attributes.
doesn't help. You can push 144 pixels of attributes per line. You have to do the update after the previous line is drawn so there is nothing to be gained if you skip a line on the 48. On the 128 with 2 video RAM pages you can go beyond 144 pixels by flipping screens every two lines.
Fair enough.
Surely not - update left half of screen on top row of two, and right half of screen on bottom row of two. That is, as you stated in the first half, you can change where the hires pixels are.
Yes, this would mean the 8x2 blocks of colour are offset by one vertical pixel, with a vertical divide in the middle of the screen, as I noted. May still be useful for some purposes, however.
[Edit: Post post thought: This is easy for left half, then right half. And not possible for right half, then left half. :( Right. Weird offset half squares next ;]
What's the answer to the last comment? Why stop at 144 rows?
There's nothing to stop you doing all 192 rows of the screen, except the processor time and memory that gets swallowed up. In one frame you've effectively got 312 rows, of which you lose the first 56 waiting for the top border. So then another 100 rows of multicolour means you've already lost 50% of your processing power for running the game - although that's not counting any useful work you might be doing during the top border. Process all 192 rows and you'll find your main program running at half the speed of a ZX81.
One memory-saving trick is to prepare the first line of each attribute during the top border, then that leaves you 1 in 8 lines with nothing to do so you might be able to write a looped routine, instead of having every row hard-coded. But that comes at the cost of not being able to use the top border time for, say, redrawing sprites.
- IONIAN-GAMES.com -
I'm one of those people so I should have remembered it. But it's still true to say that on the 48 you can't update an attribute until it's been drawn. Remind me, are all 28 attributes independently programmable?
Not for 8x1, since the remaining time must be spent loading register values for the next line.
This would allow more columns, but I never tried to figure out how many.
Notice it actually means a generic 8x2 attribute render. The 4x2 pixel colour blocks you mentioned would be just one out of many possible ways to use it.
Technically that's easy. In BIFROST* source code, just need to change REPT 18, ROWREPT to the number of lines you want, then readjust address references accordingly.
However there are several reasons I decided to use 144 pixel rows in BIFROST*, just like ZXodus does: