BIFROST* ENGINE 1.2 released!

edited February 2015 in Brand new software
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:
  • 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.
This functionality is better explained in the new documentation section "Advanced Programming" that I'm finishing to write (I will upload it in an hour or so).

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.
«13456

Comments

  • edited July 2012
    Nice work. It's going to be a while before I go back to ZXodus II so hopefully we can look forward to some Bifrost* games in the mean time. :)
  • edited July 2012
    thanks, how does one design sprites for this engine?
  • edited July 2012
    The corresponding documentation is now available here:

    http://www.worldofspectrum.org/infoseekid.cgi?id=0027405
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    slenkar wrote: »
    thanks, how does one design sprites for this engine?

    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.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    aowen wrote: »
    Nice work. It's going to be a while before I go back to ZXodus II so hopefully we can look forward to some Bifrost* games in the mean time. :)

    Thanks! I hope so :)
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    Where is the .bas file, so I can use this in boriels basic?
  • edited July 2012
    slenkar wrote: »
    Where is the .bas file, so I can use this in boriels basic?

    Reading the original post I would assume that they will be available later in the week:
    , it will be enough to download the new interface libraries that I will provide this week.
  • edited July 2012
    The interface library for Boriel's ZX BASIC is now available here!
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    thanks, im gonna check this out
  • edited July 2012
    slenkar wrote: »
    thanks, im gonna check this out

    You are welcome!

    I will also release the updated z88dk interface library soon...
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    I'm a bit confused with the source:
    ; 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
    ENDM
    

    Bifrost does 18 columns, yes? This repeatedly plays race with 12, it appears? Unless I'm going blind...
  • edited July 2012
    Gedlion wrote: »
    I'm a bit confused with the source:


    Bifrost 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... :-))
  • edited July 2012
    Doh! Yes. Blind.
  • edited July 2012
    Bifrost allows you to have 2 colors on each 8x1 line?

    (Im going to make an editor)

    Also could I have an example if inputting the sprite data manually please?
  • edited July 2012
    slenkar wrote: »
    Bifrost allows you to have 2 colors on each 8x1 line?

    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.
    (Im going to make an editor)

    You should take a look at ColorTILE then. It needs a Timex 2048 emulator though.
    Also could I have an example if inputting the sprite data manually please?

    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.
  • edited July 2012
    slenkar wrote: »
    Bifrost allows you to have 2 colors on each 8x1 line?

    Correct. Each 8x1 char line can have its own attribute (INK, PAPER, BRIGHT, and FLASH) instead of an attribute for every 8x8 char position.

    slenkar wrote: »
    (Im going to make an editor)

    Excellent!

    All versions of BIFROST* and ZXodus use the same format, thus the same editor will work for both :)

    slenkar wrote: »
    Also could I have an example if inputting the sprite data manually please?

    From BIFROST* ENGINE's documentation:
    Each tile occupies 64 bytes, storing 32 bytes of bitmap (16 pairs from top to bottom) followed by 32 bytes of attributes (stored in the same order).
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    Great news Einar! The Spectrumpedia has been updated accordingly ;)

    Thank you!
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    The updated library interface for z88dk is now available:

    http://www.worldofspectrum.org/infoseekid.cgi?id=0027405
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    Timmy wrote: »
    Thank you. I might be needing this soon. :)

    You are welcome! :)
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    I'm still trying to work out this trick :)

    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?)
  • edited July 2012
    Gedlion wrote: »
    I'm still trying to work out this trick :)

    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!
  • edited July 2012
    aowen wrote: »
    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:
    Original 18 columns multicolor method by
    Matt Westcott (gasman) and AMW.

    AMW's original post can be found here.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited July 2012
    AH. Yes, thanks Andrew.

    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?
  • edited July 2012
    Gedlion wrote: »
    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.

    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.
    Also, what if you changed the parameters to 4x2 pixel colour blocks, instead of 8x1.
    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.
  • edited July 2012
    aowen wrote: »
    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.

    Fair enough.
    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.

    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?
  • edited July 2012
    I think some people around here have already seen me doing wider stable 8x2 multicolour on a 48K Spectrum, though I haven't shown anyone the code. I can do 24-character wide fairly easily now with looped code and a moveable buffer pointer, and 28-wide if I really push the timing with everything unrolled and fixed addresses. And that's still copying from a linear buffer. Using LD/PUSH it might even be possible to do the full width. And that's not doing a half-and-half split-level. That's filling in attributes for a row behind the raster, then completing that row before the raster comes round again. Kind of like Joffa's screen scrolling, but on a line-by-line basis.

    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.
    Joefish
    - IONIAN-GAMES.com -
  • edited July 2012
    joefish wrote: »
    I think some people around here have already seen me doing wider stable 8x2 multicolour on a 48K Spectrum.

    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?
  • edited July 2012
    Gedlion wrote: »
    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.

    Not for 8x1, since the remaining time must be spent loading register values for the next line.

    Gedlion wrote: »
    Also, what if you changed the parameters to 4x2 pixel colour blocks, instead of 8x1.

    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.

    Gedlion wrote: »
    Also: If you can chase the beam for 144 pixel rows, why not 192?

    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:
    • A square multicolor area simply looks better. Making it taller gives the impression that it's too narrow, and making it shorter gives the impression it's too small (there's an interesting discussion about this kind of subject here).

    • BIFROST* routine exits immediately after finishing to render the multicolor area, thus leaving as much CPU time for the user program as possible. Even so, this makes the user program about 3.5 times slower than normal. Rendering more rows would reduce even more the CPU time available for the user program.

    • Moving the multicolor area up (to the first row) would look bad, since it would touch the upper border. Moreover, BIFROST* anti-flickering mechanism requires the first row for perfect synchronization (which is the reason the graphics never flicker even in BASIC).

    • Overall I think ZXodus already made the best possible choice for size and position of the multicolor area, and keeping BIFROST* compatible should also helps the development of tools and editors that will work the same for both.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
Sign In or Register to comment.