Jump to content
Tursi

XB Flicker Routine

Recommended Posts

Has this been done before? Probably. Anyway, I put something together after talking about it in Retrospect's thread.

 

It's pretty simple, and it's NOT production ready. I don't know how to reserve VDP RAM in Extended BASIC, so I just stole some of the VDP Disk buffer space. Which in turn means that I think it's unsafe to use the disk system after loading this -- load any program BEFORE the CALL LINK, and BYE after it, don't ever try to save something. I can guarantee* it will be corrupted.

 

* guarantees not valid in most locations. I am trying to scare you so nobody ignores me and then complains that it corrupted their data 

 

Anyway, to use it, I recommend Classic99 as it doesn't use the disk buffers anyway, and I think my OBJ is a text file anyway. ;) If it's useful, maybe we can get @senior_falcon to help embed it correctly. ;) I hesitated to post it, but I don't intend to work on it any further.

 

(load your program or copy paste the test program below. LOAD FIRST, AS DISK SYSTEM IS UNSAFE TO USE AFTER.)

 

CALL INIT

CALL LOAD("DSK1.XB_FLICKER.OBJ")

CALL LINK("FLICK")

 

Test program instead of loading one:

5 CALL MAGNIFY(2)

10 CALL CLEAR

20 RANDOMIZE

30 FOR A=1 TO 28

40 CALL SPRITE(#A,64+A,2,100,A*8,RND*30-15,0)

50 NEXT A

60 GOTO 60

 

Basically, after the CALL LINK the original sprite attribute list gets copied up to >FF00, which is then set as the new sprite attribute list. Every frame it's copied with a different offset (skipping 4 sprites each frame). There are more clever and more specialized flicker routines, but this very simple one covers generic cases very well.

 





* Flicker for XB Sprites
* This is NOT a final version, this will break disk access
* (May work with Classic99's disk driver, but don't rely on it)
*
* -- PROOF OF CONCEPT ONLY --

    DEF FLICK

* XB equates
VMBR equ >202c
VMBW equ >2024

* sprite information
SNEW equ >3F00            * output vdp address
NEWMAX equ >3F70        * where it ends - must be same size as SMAX-SBASE
SBASE equ >0300            * where XB writes sprite data
SMAX equ >0370            * address where XB sprite data ends (28 sprites here)
GPLR11 equ >83F6        * GPLWS r11 for return
data    DATA >0000        * where we are in the rotation
wp      bss 32            * use a private workspace

    
FLICK
    mov r11,@GPLR11        * going to return on GPLWS, whatever it may be now
    lwpi wp
    
    li r0,>0300            * current sprite address
    mov r0,@data
    
    li r0,INT1            * load address of interrupt routine
    mov r0,@>83c4        * set it in the hook

* fall through into the interrupt once to make the first copy    
    
INT1
    li r12,SNEW            * output address
    mov @data,r0        * current position in the rotation
ILP
    li r1,wp+6            * use private R3-R10 (16 bytes = 4 sprites)
    li r2,16
    blwp @VMBR            * read XB sprite table
    
    ai r0,16            * write it rotated by 4 sprites
    ci r0,SMAX            * are we at the end?
    jne ISK
    li r0,SBASE            * back to beginning of table
ISK
    mov r0,@data        * save it
    mov r12,r0            * output address
    blwp @VMBW            * and write it
    mov @data,r0        * get back original table, at next offset
    
    ai r12,16            * next output
    ci r12,NEWMAX        * are we done?
    jne ILP                * loop if needed
    
    li r0,>d000            * write end of sprite table tag
    movb r0,@>8c00        * relies on VDP address still being valid!

    li r0,>fe85            * going to move SAL to >3F00 (disk buffers)
    movb r0,@>8c02
    swpb r0
    movb r0,@>8c02
    
    mov @data,r0        * once more to update the base
    ai r0,16            * 4 sprites later
    ci r0,SMAX            * check for end
    jne ISK2
    li r0,SBASE            * wrap around if end
ISK2
    mov r0,@data        * save it for next time
    
    lwpi >83E0            * GPLWS, just in case
    b *r11
    
    END

 

xb_flicker.zip

 

Short video sample - it would look better on a CRT where persistence helps. ;)

 

https://www.twitch.tv/videos/1071954473

 

  • Like 7
  • Thanks 4

Share this post


Link to post
Share on other sites

This is impressive stuff Tursi.  Whilst I've already gotten 80 percent of my Hunchback game done, I would like to use this for my next project which is a port of the Atari 2600 "Frankenstein's Monster" and I can see where I would benefit by using this.  Not just one screen 1 but on screen 2 where all the bats fly down the screen, most of those look to be more than 4 in a line.  With this routine the bats screen would be great!

  • Like 1

Share this post


Link to post
Share on other sites

This is the coolest!  We need to get this integrated into the compiler :)

 

Also...  Would it be possible to adjust it so that it skips a certain number of sprites?  For example, if a player doesn't want their own sprite to flicker at all...

  • Like 2

Share this post


Link to post
Share on other sites

Another feature I would like to have is the ability to use some bank switching mode for compiled games, to have more space to use (e.g for extra levels, etc). Of course it's possible to use the disk, but SSS are easy and fast to use (thanks to the FinalGROM).

 

Just to clarify, something like this for the SSS menu:

1 TI BASIC
2 MAIN GAME
3 GAME PART1
4 GAME PART2
etc.

 

The entries 3, 4, etc. should be hidden if possible. From MAIN GAME jump/run to PART1 program when needed, having the possibility to pass some information (just few variables for lives, score, etc.).

 

Is this technically feasible?

 

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, unhuman said:

This is the coolest!  We need to get this integrated into the compiler :)

 

Also...  Would it be possible to adjust it so that it skips a certain number of sprites?  For example, if a player doesn't want their own sprite to flicker at all...

I don't really know how this has been done even after reading Tursi's code but I suppose that might work if your sprite was always sprite #1 ? 

Share this post


Link to post
Share on other sites
5 hours ago, unhuman said:

This is the coolest!  We need to get this integrated into the compiler :)

 

Also...  Would it be possible to adjust it so that it skips a certain number of sprites?  For example, if a player doesn't want their own sprite to flicker at all...

I've done that myself in the past. As written it rotates by 4 at a time, which gives a minimal amount of time that a sprite is likely to be hidden, but means that blocks tend to flicker together instead of being more distributed. I've also tried stepping by 1 in the past, and reversing the order of the table every other frame. IMO simple is better, cause flicker always looks flickery anyway. ;)

 

But you could easily not rotate some sprites by changing the start and end points. :)

 

Also the code isn't very optimized... it could be tighter.

 

But again, I don't know how to properly allocate some VDP memory for XB to operate safely around it, so we'll need help to make it safe to use. :)

 

  • Like 5

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...