|
Post by rmartins on Sept 10, 2015 20:13:50 GMT
Last night, I was looking at my sprite blitting code, and wondering, if there was any obvious improvement I could do  To allow sprites to be re-positioned in memory, during development, I have used relative references (pointers). However, by being relative, this means I have to do at least a 16 bit add, for each reference (one for pixel data, one for color data). Currently I use Sprite data structures, with an absolute address, since it's easier to use in assembly, but they have relative references to actual data. The current structure I use is as simple as: - Width in bytes (1 byte) - Height in Pixels (1 byte) - PixelRef (2 bytes/ 1 word) a relative address - ColorRef (2 bytes/ 1 word) a relative address PixelData or ColorData can be anywhere in memory, as long as it has an address above the data structure reference field (relative reference is just amount of bytes to add to current position). This is very flexible, because I can have a sprite that is 1 character wide by 3 characters high, but I might want to have a sprite that is just the top char or the middle one, or the bottom one. Think of sprite chars (8x8 pixel blocks) like lego. With this structure I can re-use the same pixel and/or color data (memory), as long as I define a structure for each. However the price to pay is the extra calcs on every sprite blit. But there is a quick and obvious solution, that will prevent me from having to add every time I blit, without using any extra memory. I can just do pre-calculations of these references, and replace the original relative references with absolute references, i.e. a simple 16 bit absolute address. It will work just like relocatable code. It allows me to still move sprites anywhere in memory, during development, so they are still relocatable. It maintains all the flexibility, since I can have the structure in one place, and data in another. And most importantly it also allows to later convert the game to ROM/Cartridge, by just copying structures into memory, leaving pixel and color data in ROM. Or I can then define final absolute locations too, without losing the flexibility during development. NOTE: I have a special side project, which is to create a ROM cartridge with the final game version. Planning for a standard ROM limits me to 16K. To have more than 16k ROM, I need a specially designed ROM/Cartridge, so that I can page it by software.
|
|
|
Post by rmartins on Sept 14, 2015 13:27:33 GMT
Weekend updates (part 1): - Implemented Reverse Blit Color - Fixed Wall bitmap - Lots of code refactoring  Slow but steady progress.
|
|
|
Post by rmartins on Sept 14, 2015 13:38:42 GMT
Weekend updates (Part 2): - Defined initial level datastructure - Created sample level, mimicking previous look - Implemented Level processing, replacing previous mockup  There is a nice balance between what as been removed from screen and the extra processing being done. NOTE: This version still has a small bug, that can be seen on the left, showing a yellow and white beam power emitter.
|
|
|
Post by rmartins on Sept 16, 2015 22:09:38 GMT
Some more progress: - Fixed previous level bug - Reviewed beam wall sprite (still have to support tiling) - Added BIG Number Font sprites - Some more code refactoring 
|
|
|
Post by Ivanzx on Sept 16, 2015 22:10:50 GMT
I like the numbers, and I also like that everything is taking shape 
|
|
|
Post by rmartins on Sept 21, 2015 19:24:09 GMT
 Implemented: - 4 pixel Sprite rotation, required for scrolling (left/right). NOTE: not visible on screenshot - Level positioning, i.e. show a distinct level portion depending on current "level window" position. - Next and Previous Level data navigation, will be used when scrolling. It's required to select which elements are part of the visible "level window". The screenshot, shows that clipping is not implemented yet, i.e. show only the portion of the sprite that is visible, and prevent it from overlapping to the opposite side. As can be clearly seen on the left edge, part of the elements (walls) showing up on the right, have overlapped to the left, and (a base) on the left, overlaps to the right edge. Clipping usually is a nasty thing to implement. Because it's hard to make it fast, with all the extra tests it has to perform.
|
|
|
Post by catweazle on Sept 22, 2015 9:16:16 GMT
It's looking great!  Regarding sprite clipping.. I expect you've probably already considered this trick: but how about shrinking the visible play area by the width of your sprites, and setting the attributes as black ink & paper? This way you don't have to clip at all, but sprites which go partially off the screen will look ok! 
|
|
|
Post by rmartins on Sept 22, 2015 11:42:45 GMT
It's looking great!  Regarding sprite clipping.. I expect you've probably already considered this trick: but how about shrinking the visible play area by the width of your sprites, and setting the attributes as black ink & paper? This way you don't have to clip at all, but sprites which go partially off the screen will look ok!  I have seen this trick mentioned and being used (I believe it was also mentioned in another thread in this forum somewhere), and it's a possible solution, since it works. However, it has several drawbacks. - You loose at least 2 chars in width (one on each side) - You have to limit yourself to sprites with a maximum width of 2 chars, or else you will have to loose more chars in usable width. - You also have to provide a special case, in your code for not "painting" attributes on these edge areas (black on black) Having the possibility to have sprites larger than 2 chars, gives a boost when blitting, since pre-calcs are done only once for all sprite columns, instead of once for each column, and also prevents masking/xoring of adjacent sprites (when scrolling), since I can have a single sprite with all the data. I was in fact thinking of using the black ink/paper trick, but for other purposes  I have been "cooking" a solution, that might be fast enough, since I only need to clip left or right, never both, (I have no need to clip top and bottom). It basically consists of a pre-calculation and an extra ADD in the blit loop. The current problem is that I have used all common registers in current implementation to make it fast, so I'm short on free registers  But I'll try to squeeze this extra feature in. I'll probably need to make 2 versions, a clip left and a clip right. Since I have reverse blits too, I will have do double up and make reverse clip versions too. I hope it will be fast enough. I would like to thank you catweazle for your input, this is one of the reasons I share this "blog", to debate solutions and points of view, eventually to reach a better solution.
|
|
|
Post by rmartins on Sept 23, 2015 0:34:35 GMT
While preparing some direct tests over new Clipping routine (PBLITC), I hit a wall   Zeus loads itself into top of memory (#E000-#FF00), and defines Symbol Space just below itself, which will grow downward like a stack. Application code is defined by default starting at #8000. So, in memory, we have something like this: #6000 - #7FFF » User application assembly (location defined with ORG directive, and assembly generated on compile) #8000 - #xxxx » Application source code, keeps growing up. #xxxx - #CFFF » Symbol Space (Managed by Zeus, while compiling), keeps growing down #E000 - #FF00 » Zeus assembly So when application source code grows, Symbol space also grows, and eventually they will meet, which will throw an "Out of Symbol Space". Possible Solutions ---------------------- Quick: Deleted unused code and/or comment unused definitions. Intermediate: Carefully move code lower in memory, if possible, using some mem copy voodoo. Progressive: Re-start Zeus with different parameters, and re-insert code. Hard: Start developing code in batches, since Zeus will always grab a reasonable chunk of memory. This forces me to compose the game in chunks, preventing me from using the nice and fast Zeus work flow, that I have been using so far. Futuristic: Start developing on a modern Z80 assembler on PC. NOTE: re-insert code is needed, because somewhere along development I trashed Basic system variables, and now it fails to return to basic, so I can not save source code using basic commands. Hack solution is to print source code, and save text code using printer emulation features.
|
|
|
Post by rmartins on Sept 23, 2015 0:56:14 GMT
Clipping tested and working !!!  Above the Big Numbers, I have 4 clipping tests (compare with bottom left complete base3 sprite, exactly below ball position) Above digit "0", clipping a Base3 to the left, showing only one byte wide Above digit "2", clipping a Base3 to the left, showing two bytes wide Above digit "7", clipping a Base3 to the right, showing two bytes wide Above digit "9", clipping a Base3 to the right, showing only one byte wide It worked first time, great  But I'm not 100% happy with the solution, I might have to change the entry and pre-calc, to minimize parameter data copy (check previous screenshot). It's not "elegant" to force parameters into global variables. Next, I just need to do edge math and call this clipping routine, and it should magically work  NOTE: During implementation of this routine, based on previous optimized blit routine, I found out that I can squeeze another T-state out of the main loop of the regular blit routine (but haven't changed it yet). Looking at the existing code with more restrictions, and requiring more features, made me look for other solutions, that I hadn't tough before. P.S. Can you guess which solution I went for "Out of Symbol Space" problem ? 
|
|
|
Post by Ivanzx on Oct 4, 2015 23:06:12 GMT
A lot of tech stuff which I think it is going to be very useful, thanks for the effort  By the way, how much, more or less, do you think is the game completed?
|
|
|
Post by rmartins on Oct 5, 2015 17:46:45 GMT
A lot of tech stuff which I think it is going to be very useful, thanks for the effort  By the way, how much, more or less, do you think is the game completed? I have been busy with real life, hence some lack of updates.  But my mind can't rest, so I have been scribbling on paper how to implement or solve a few issues, when a computer is not at hand.  Here is some evidence, on an afternoon snack recycled paper bag   Scribble of how to solve Left and Right Edge Clipping calcs. Regarding game completion I would say between 30% and 40%, not counting: Main Menu, Loading Screen, and Music support.
|
|
|
Post by rmartins on Oct 12, 2015 21:16:27 GMT
Progress report: - Fixed bug on reversed blit routine, that only happened near the left edge (column 0) in 2 very specific rows (guess which ones  - Implemented Clipping on Left Edge, but only for regular clip routines (color not implemented on clip, and no reverse blit clip yet ) - Designed a new Zapping Sprite and animation (not visible on screenshot, since it's not in code yet) 
|
|
|
Post by rmartins on Oct 14, 2015 15:58:25 GMT
Here is a small update, on the several test versions for zapping.  Which one is the best ? Still undecided. TIP: Zooming your browser page might help seeing the differences. Maybe I should slow it down a little. Here it's changing anim frame on every TV Frame (20ms). I think I'll try update anim frame once every two TV frames (40ms) EDIT: here is a 40ms version.  NOTES: From Left to Right (1...5), the first 4, animations have 5 frames, the 5th anim has 6 frames. Since 5th animation is longer, the other have one extra blank (no ray) frame, in the end. This can be clearly seen on the small metal electrode ball, which shows a larger period without "ionization". 
|
|
|
Post by climacus on Oct 14, 2015 18:35:24 GMT
Here is a small update, on the several test versions for zapping.  Which one is the best ? Still undecided. TIP: Zooming your browser page might help seeing the differences. Maybe I should slow it down a little. Here it's changing anim frame on every TV Frame (20ms). I think I'll try update anim frame once every two TV frames (40ms) EDIT: here is a 40ms version.  NOTES: From Left to Right (1...5), the first 4, animations have 5 frames, the 5th anim has 6 frames. Since 5th animation is longer, the other have one extra blank (no ray) frame, in the end. This can be clearly seen on the small metal electrode ball, which shows a larger period without "ionization".  I like 40m version. The 5th. Its a very good effect.
|
|