Software sprites?

Basic and Machine Language

Moderator: Moderators

User avatar
rhurst
Omega Star Commander
Posts: 1304
Joined: Thu Jan 31, 2008 2:12 pm
Website: https://robert.hurst-ri.us
Location: Providence, RI
Occupation: Office of the CIO

Software sprites?

Postby rhurst » Sun Jan 04, 2009 11:41 am

Is anyone interested in a generalized API to provide software sprite rendering on VIC? I am considering in writing that code for possible integration into a future game. I might just do it anyways for the mental exercise, but it would help my motivation if a single soul out there thought it may help him/her with a future game.

I already have a simple 8-sprite routine written. And I have some new lessons learned from the updated Quikman maze to integrate. But, I'd like to see how well it can perform with the addition of doubling height, width, both, and allowing for multiple "banks" of sprites, i.e, potentially allowing for up to 256 "simple" sprites, 64 "common" sprites, or 32 "multicolor" sprites, etc.

User avatar
Mike
Herr VC
Posts: 3001
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Postby Mike » Sun Jan 04, 2009 1:40 pm

Some random thoughts:

- compatible with "normal" text display.

- sprite size of 16x24 pixels (i.e. 3x4 chars),

- pixels can either be white, black, or transparent, requiring a mask,

- possible for a sprite to be partially off-screen,

- sprites are drawn from a character pool, in a copy of the regular charset. Used are characters xx-127, and yy-255 (so, where a character is used for a sprite, its reverse also is),

- flicker-free redraw, with priorities, i.e. new, unused chars from the pool are prepared for the old position, and new position of the sprite, and then written instantly. This will quite possibly require an off-screen map (-> which leads to a natural number of max. 8 sprites) - signifying on which position sprite #x is visible. (-> also usable for sprite collision check?),

- 8x12 = 96 + (12 for old position) + (12 for new position) ~= 120 chars -> 64..127, and 192..255 used for sprites,

- routine should check regularily, whether normal text chars have overwritten a sprite, regenerating that position (and taking the new char into account). (what happens, when the screen is scrolled?)

Greetings,

Michael

Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Postby Legacy » Sun Jan 04, 2009 2:23 pm

i'll have some sprite, its lemony

User avatar
Mike
Herr VC
Posts: 3001
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Postby Mike » Sun Jan 04, 2009 2:34 pm

very cool

eslapion
ultimate expander
Posts: 4262
Joined: Fri Jun 23, 2006 7:50 pm
Location: Canada
Occupation: 8bit addict

Postby eslapion » Mon Jan 05, 2009 5:47 pm

In a thread on Lemon64, Dr. Bob, the creator of Lunar Leeper indicated he created virtual sprites on the VIC by XORing the "sprite" graphics on top of the background graphics.
No one can do everything. Everyone can do something.

User avatar
Mike
Herr VC
Posts: 3001
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Postby Mike » Tue Jan 06, 2009 5:49 am

This effectively implies a bitmapped screen. The size of the object then can be arbitrary large, and they can easily be erased by drawing them on the same place a second time. You need to decide, whether you pre-store all 8 possible shifts in x direction, or make real-time shifts.

But (and this is a great But), XOR'd objects are also a quite cheap solution, as those objects are not really independant off other screen content. When two of those overlap, corresponding pixels erase out. Over a block of foreground pixels, they appear inverse, if the screen has a chequered pattern you might not recognize them at all.

To get sensible a screen-independance, a sprite must remember the screen content beneath it, and be able to restore it. A sprite, which forces pixels to foreground colour will take the definitions of the underlying chars, write these into a mini-bitmap, OR in its own pattern, define new chars from it, store away the old content, and write its own chars on the text screen.

If you want sprites, that not only can force pixels to foreground, but also to background, you need a pattern and mask definition. The source is first ANDed with the mask, and then EORed with the pattern:

Code: Select all

source  mask    pattern result
0       0       0       0
0       0       1       1
0       1       0       0
0       1       1       1
1       0       0       0
1       0       1       1
1       1       0       1
1       1       1       0

You see, the combination (mask=0, pattern=0) forces pixels to background, (mask=0, pattern=1) forces pixels to foreground, and (mask=1, pattern=0) makes that sprite pixel transparent. (mask=1, pattern=1) reproduces the XOR behaviour for that pixel.

Michael

User avatar
ral-clan
plays wooden flutes
Posts: 3520
Joined: Thu Jan 26, 2006 2:01 pm
Location: Canada

Postby ral-clan » Tue Jan 06, 2009 8:17 am

eslapion wrote:In a thread on Lemon64, Dr. Bob, the creator of Lunar Leeper indicated he created virtual sprites on the VIC by XORing the "sprite" graphics on top of the background graphics.


Lunar Leeper has some of the best, smoothest hi-res graphics ever made for a VIC-20 game...so if this is the way you guys choose to go, I think the results will be very nice.

User avatar
rhurst
Omega Star Commander
Posts: 1304
Joined: Thu Jan 31, 2008 2:12 pm
Website: https://robert.hurst-ri.us
Location: Providence, RI
Occupation: Office of the CIO

Postby rhurst » Tue Jan 06, 2009 12:00 pm

First, thanks for the responses and interesting points. I will check out this Lunar Leeper reference to visualize what it is doing and what is capable. If necessary, I'll peek into the code.

My objective here is not to go bloated by way of a screen bitmap, but allow the programmer flexibility with the advantages of VIC custom & ROM characters. I have spent 2-hours drafting an objective, requirements, and API which I will (eventually) clean up and post for feedback.

Mike, you seem to have some robust ideas as to where you would like to see something like this go. Do you have a specific implementation that you are thinking to do? Regardless, I am definitely thinking the same way on:

- compatible with "normal" text display.
- possible for a sprite to be partially off-screen
- sprites are drawn from a character pool, in a copy of the regular charset.
- routine should check regularily, whether normal text chars have overwritten a sprite, regenerating that position (and taking the new char into account).


But no so (at least to start) with:

- sprite size of 16x24 pixels (i.e. 3x4 chars),
- pixels can either be white, black, or transparent, requiring a mask,
- flicker-free redraw, with priorities


In particular, I am thinker lighter-weight and general purpose to cover (hopefully) broader needs. Also, you mentioned flicker-free, but I did not think that is technically possible with VIC, because of the lack of a raster interrupt -- like on C64 -- or am I mistaken and some technique to do that is available? Of course, optimizing to reduce flickering (off-screen rendering and pulling from a dynamic character pool) will be implemented as long as size & speed is not impacted by it too much. The game needs CPU cycles, too!

My draft allows for (unlimited) sprite "banks" of eight each, and sprite sizes of 8x8, 8x16, 16x8, and 16x16. As far as collision-detection and transparency techniques are concerned, that might be included as an adhoc API call (not integrated), because those can be expensive operations in software that are might be better managed by the programmer. After all, this is a 1-mhz processor and VIC is slick but not quick!

Thanks, and please post more thoughts. I appreciate any feedback.[/quote]

User avatar
Mike
Herr VC
Posts: 3001
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Postby Mike » Tue Jan 06, 2009 1:12 pm

rhurst wrote:Mike, you seem to have some robust ideas as to where you would like to see something like this go. Do you have a specific implementation that you are thinking to do?

Some time ago one other Denial member brought up the Topic 'Sprites in ML', where, ultimately, the program Sprit-imation was discussed. That package went already quite far in the right direction. It even had an API callable from ML, and a BASIC extension included. But it had problems with flicker-free redraws if more than 1 sprite was displayed.
But no so (at least to start) with:
sprite size of 16x24 pixels (i.e. 3x4 chars), [...] pixels can either be white, black, or transparent, requiring a mask, [...] flicker-free redraw, with priorities

Like tea can brewed in different strenghts. :)
Of course, optimizing to reduce flickering (off-screen rendering and pulling from a dynamic character pool) will be implemented as long as size & speed is not impacted by it too much.

Which will do 99% of flicker-free without using raster-IRQ's, ...
flicker-free, but I did not think that is technically possible with VIC, because of the lack of a raster interrupt -- like on C64 -- or am I mistaken and some technique to do that is available?

... and one could sync a VIA IRQ to the raster beam, and thus force the update be done while the raster beam is outside the visible area - in the down, and top border. ;) That would give the remaining 1%.
My draft allows for (unlimited) sprite "banks" of eight each,

Is is not quite clear to me, what you mean with these "banks". Could you explain?

Greetings,

Michael

User avatar
rhurst
Omega Star Commander
Posts: 1304
Joined: Thu Jan 31, 2008 2:12 pm
Website: https://robert.hurst-ri.us
Location: Providence, RI
Occupation: Office of the CIO

Postby rhurst » Wed Jan 07, 2009 1:57 pm

I read that thread about spritimation ... the BASIC wedges sound compelling to integrate, too, but only after the ML API is declared a success.

As stated before, I have a very good 8-sprite routine now for unexpanded VIC. And I later modified that routine, so it is optimized for the fixed-width maze game in quikman2k8. I would like to expand the original routine's scope, but allow it to be more generalized / flexible to make for easy integration -- little to zero mods required by the game programmer. These enhanced sprite rendering routines might even allow for it to reside in an unexpanded VIC, for small games requiring a limited number of active sprites. Or, a fully-stocked VIC to make use of MANY active sprites and animations.

The notion behind sprite "banks" is to allow the programmer to have multiple 8-sprite allocations, with varying sizes, colors, and modes of operations. For example, it would be possible to have sprite bank0 to have two player ships at 8x16 pixels multi-colored, shooting up to 3-shots each using a single pixel in an 8x8 sprite ... ship1 + 3-shots + ship2 + 3-shots = 8 sprites. Sprite bank1 can have another 8 sprites, say a couple of floating asteroids, a space station to dock with, a spaceman to rescue, an alien ship firing, etc.

Clearly, the more active sprites you have at once on the screen, the more custom characters will get consumed, probably requiring that the game code be written in another 4K/8K block, leaving a sizeable portion of VIC's $1000-$1FFF RAM free for these graphics.

I am also thinking about "allowing" for sprites to automagically interlace, i.e., when two hires sprites happen to overlap, this effect significantly reduces color clash at the expense of reasonable flicker. Or, to interlace them if multiple banks of big sprites are in active use, and there are not enough (> 128) custom characters left in the pool to display all of them at once. For example, I would like to see how VIC can handle a single-pixel sprite, rendered inside an 8x8 cell, but exploding 256 of them (128x2 interlaced) into a starburst effect... this would require 32 banks of 8-sprites. While that is an inefficient implementation, and it may even prove to suck, why not write the API to allow for that kind of contingency?

Hopefully, if it is written well, the 6502 assembler code can be made relocatable, so that it may even port nicely to C16, Plus/4, C64, and C128 that have larger memory, color, and resolution.

User avatar
Mike
Herr VC
Posts: 3001
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Postby Mike » Thu Jan 08, 2009 6:17 am

rhurst wrote:I read that thread about spritimation ... the BASIC wedges sound compelling to integrate, too, but only after the ML API is declared a success.

Agreed.
The notion behind sprite "banks" is to allow the programmer to have multiple 8-sprite allocations, with varying sizes, colors, and modes of operations. [...]

But why do you want to seperate the definitions at all? What is supposed to happen, when sprites of different "banks" interact on screen?
Clearly, the more active sprites you have at once on the screen, the more custom characters will get consumed, probably requiring that the game code be written in another 4K/8K block, leaving a sizeable portion of VIC's $1000-$1FFF RAM free for these graphics.

I'm gladly willing to put the time-space trade-off wide into the direction of fast routines at the expense of memory, for this application.
For example, I would like to see how VIC can handle a single-pixel sprite, rendered inside an 8x8 cell, but exploding 256 of them (128x2 interlaced) into a starburst effect...

IMO, this effect calls for a bitmapped implementation. A table-driven address-calculation for a single pixel in a bitmap looks like this ...

Code: Select all

; X, Y: co-ordinates
TXA:PHA:LSR:LSR:LSR:TAX
LDA table_lo,X:STA xx:LDA table_hi,X:STA xx+1
PLA:AND #$07:TAX
LDA (xx),Y:EOR two_powers,X:STA (xx),Y

which takes roughly 50 cycles per pixel. They must be drawn twice to delete them again. 1000000 cycles per second / 100 cycles per pixel = 10000 pixels per seconds, which gives 166 pixels per frame, with 60 frames per seconds assumed. This excluded any necessary housekeeping action such as calculating the pixel co-ors, and feeding the point-set routine above with those, so we're more likely off with a ~80 particle effect.

Another implementation could use 64 chars with each 1 pixel set at all possible positions. Did you mean this? Well, then:

Code: Select all

; X, Y: co-ordinates
TYA:PHA:LSR:LSR:LSR:TAY
LDA line_lo,Y:STA xx:LDA line_hi,Y:STA xx+1
PLA:AND #$07:STA char
TXA:PHA:AND #$07:ASL:ASL:ASL:ORA char:STA char
PLA:LSR:LSR:LSR:TAY
LDA char:STA (xx),Y

... which takes more cycles for setting a pixel, but erasing them is easier (by clearing the text screen). In the end, that routine might be a little faster, however if two (or more) points end up in the same char, the last one plotted takes precedence.

User avatar
Ivanhoe76
Vic 20 Enthusiast
Posts: 182
Joined: Fri Sep 28, 2007 11:17 am

Postby Ivanhoe76 » Thu Jan 08, 2009 8:01 am

I'm really poor programming in machine language so I cannot suggest any enhancements but I'm imagining what could be done with this routine... A wonderful world is spreading out.... a world full of games of any type... go on guys, all my regards!!!
No one should tolerate death and violence because tolerance will generate habit.

User avatar
rhurst
Omega Star Commander
Posts: 1304
Joined: Thu Jan 31, 2008 2:12 pm
Website: https://robert.hurst-ri.us
Location: Providence, RI
Occupation: Office of the CIO

Postby rhurst » Thu Jan 08, 2009 9:50 am

Great feedback, thanks!
But why do you want to separate the definitions at all? What is supposed to happen, when sprites of different "banks" interact on screen?

Generalization and flexibility. All active sprites, regardless of bank definition origin, will have to interact with each other, if the desired video effect is to be achieved. While it is yet to be proven, I get the sense that separating them into banks like this will allow for easier integration into a broader scope of games, both small and large.
IMO, this effect calls for a bit-mapped implementation.

Yeah, my example was just a lofty use-case to expand upon how generalized this routine set might be, that's all. This effort won't replace the expert from hand-coding / optimizing their own graphics and animations, because a generalized API cannot account for the objectives of every implementation. So, if it gets to a point where these software sprites are moderately fast for the number of active sprites requested, 96% flicker-free, and optimized to reduce color-clashing -- I would think the limited number of home-brew programmers out there might find it useful for their purposes. And you never know how it might evolve afterward from more implementations.

At the very least, I will write a large test application for demo purposes, complete with documentation and source. If it excites me enough, I can see me writing more VIC games using it, and remain quick enough to satisfy my short attention span. :wink:
I'm gladly willing to put the time-space trade-off wide into the direction of fast routines at the expense of memory, for this application.

Yes, working for unexpanded VIC is not a primary objective, so I am not looking toward making it a requirement. If possible, it would be cool to glean a "lite" version out of it, as either separate source or possibly through assembler directives on one source.

So all of that said, I would like to propose a little time over the coming week or so to produce some alpha code for people to play with. I will post that progress here, and either off my VIC tribute page or a separate link if it gets bigger. I welcome anyone to contribute, criticize, request, applaud, etc. -- as long as it remains fun!

User avatar
rhurst
Omega Star Commander
Posts: 1304
Joined: Thu Jan 31, 2008 2:12 pm
Website: https://robert.hurst-ri.us
Location: Providence, RI
Occupation: Office of the CIO

Postby rhurst » Sun Feb 01, 2009 4:45 pm

FYI, I have made some head-way into this little project. I got Mike's raster timing stuff tweaked by some other code, and it now works with PAL mode (tested under VICE), too. Nifty tricks!

I anticipate three APIs will come out of this project: full-buffered, fast-buffered, and a lite version for unexpanded use.

The full-buffered one will mainly be worked on, as I am interested primarily by what VIC can do. Most of the built-in RAM ($1000 - $1FFF) will be required to use this API, so expanded RAM or ROM is required for the program and data.

The fast-buffered version will require less of the built-in RAM, but not nearly enough to make it useful for unexpanded use. I should be able to make a reasonable "lite" version from fast -- and it should be more dynamic than my original code, although probably not as fast.

User avatar
rhurst
Omega Star Commander
Posts: 1304
Joined: Thu Jan 31, 2008 2:12 pm
Website: https://robert.hurst-ri.us
Location: Providence, RI
Occupation: Office of the CIO

Postby rhurst » Sun Feb 08, 2009 12:15 pm

I have a lot going on (83yr old mother-in-law is hospitalized, her house got broken into, wife car repairs, replaced our washing machine, configuring new bladecenter at work, etc.) :(

... so I had very little time to work on this. That said, I optimized my time in waiting rooms and train rides, and made progress this past week anyways! :D

I have the first of nine possible character matrix layouts working. The work should get progressively easier as I code each, as it'll get more and more optimized along the way. Follows are the layouts:

Code: Select all

Sprite Matrix
-------------    ----- float -----
HxW     fixed     X     Y      X&Y
8x8      @        @A    @      @B
                        A      AC

8x16     @A       @AB   @B     @BD
                        AC     ACE

16x8     @        @B    @      @C
         A        AC    A      AD
                        B      BE

16x16    @B       @BD   @C     @CF
         AC       ACE   AD     ADG
                        BE     BEH

The first column (fixed) represent when "float" is off for both X & Y directions -- simple character cell rendering with playfield.

The next two, float X or float Y, allows for sprite to freely move in the X or Y direction. Good for maze games & shooters which require limited motion.

Float X&Y means the sprite can be rendered anywhere within the visible screen area. All float modes allow for "clipping" will allow for the sprite to move partially to wholly off-screen.

Triple video/color buffering is in place, making for interesting effects. "POKE" to the video gets written to a separate playfield/color buffer, which maintains a dirty bitmap for faster updates to the dual screen/color buffers.

Even though I account for the multicolor bit as a sprite attribute, this first pass at this will not have sprite masking; only simple OR'ing with sprite and playfield.


Return to “Programming”

Who is online

Users browsing this forum: No registered users and 3 guests