Jump to content
IGNORED

[coleco] Sprites Sample ( assembly codes listing )


newcoleco

Recommended Posts

Here, I'm posting a sample code concerning Sprites. If you have not see my previous posts (messages/videos) please do so in order to understand a few things.

 

For those who already see my messages, you know that this code is made based on TNIASM, a cross-compiler you can find in the Internet, used for example in the GameBoy homebrew scene for years.

 

I'm not gonna talk about the video settings, but about sprites.

 

The following listing doesn't move or change color a bunch of sprites... let's keep it simple and just display sprites on screen. In the video, I'm showing the evolution of this listing starting from 1 sprite to 3,5 and then 7 sprites. With 5 sprites, because the video chip doesn't show more than 4 sprites in a row, I've added a sprites flickering effect based the principle of a circular buffer with the sprites priority table. Other technics like simply swap to the highest priority the non showing sprite might be fast but raise the question why if another sprite (that we are not aware of) does also need to get a higher priority at the same time? That's why I'm using the solution shown here.

 

The table of sprite priorities is initialized with the numbers 0 to nbr_sprites-1, so if there is 5 sprites to show then the table of priorities is [0,1,2,3,4]. When the flickering effect is needed, the first sprite to be the 5th sprite in a row is retreived from the video register and used as a starting point for the circular buffer. For example, if always the 5th sprite condition occurs for a 5 priorities table, you get the following tables of priorities during time : [0,1,2,3,4] -> [4,0,1,2,3] -> [3,4,0,1,2] -> [2,3,4,0,1] -> [1,2,3,4,0] and so on. This makes all the 5 sprites flickering on screen. With the "swap only the 5th sprite to the highest priority" solution, only 2 sprites are flickering on screen, which seems to be a pretty good solution, but deny the possibility if there is a 6th sprite or even a 7th sprite. The flickering effect with 7 sprites, in this sample program, acts as follow : [0,1,2,3,4,5,6] -> [4,5,6,0,1,2,3] -> [1,2,3,4,5,6,0] -> [5,6,0,1,2,3,4] -> [2,3,4,5,6,0,1] -> [6,0,1,2,3,4,5] -> [3,4,5,6,0,1,2] and so on. Well, it should be this sequence, I can't be sure if the emulator you are using will gives you this sequence of sprites order and so this sprites flickering effect.

 

As usual, if you appreciate this program, if you find it useful, please consider voting and/or leave a message.

 

; Colecovision - Sprites Demo
; by Daniel Bienvenu, 2010

NBR_SPRITES: equ 7

fname "7sprites.rom"
cpu Z80
org $8000
dw $aa55,SprAttrib,$7000,0,0,Start
dw 0,0,0,0,0,0,0,0,0,0
ret
Nmi:
; Display Sprite(s)
ld a,NBR_SPRITES
call $1fc4 ; WR_SPR_NM_TBL
ld a,$d0
out ($be),a

; Get Video Status
call $1fdc ; READ_REGISTER
bit 6,a
jr z,DoNothing
and $1f ; keep only 5bits = sprite#
ld e,a
ld d,0
ld hl,($8004)
push hl
add hl,de
ld c,(hl) ; Get corresponding Sprite entry
pop hl
ld a,NBR_SPRITES
ld b,a
Reordering1:
ld (hl),c
inc hl
inc c
cp c
jr nz,Reordering2
ld c,0
Reordering2:
djnz Reordering1
DoNothing:
retn
Start:
call $1f85 ; MODE_1
call $1fd6 ; TURN_OFF_SOUND
; Clear VRAM
ld hl,0
ld de,$4000
xor a
call $1f82 ; FILL_VRAM
; Load Sprite Pattern
ld de,$3800
ld hl,HappyAlienBugFace
ld bc,32
call $1fdf ; WRITE_VRAM
; Init. Sprites Order
ld a,NBR_SPRITES
call $1fc1 ; INIT_SPR_ORDER
; Turn On Display + Enable NMI
ld bc,$01e2
call $1fd9 ; WRITE_REGISTER
TheEnd:
jp TheEnd

SprAttrib:
db 82, 24,0,13 ; Y=82, X= 24, Pattern#0, Color=13
db 84, 56,0, 8 ; Y=84, X= 56, Pattern#0, Color=8
db 86, 88,0, 9 ; Y=86, X= 88, Pattern#0, Color=9
db 88,120,0,10 ; Y=88, X=120, Pattern#0, Color=10
db 90,152,0, 3 ; Y=90, X=152, Pattern#0, Color=3
db 92,184,0, 7 ; Y=92, X=184, Pattern#0, Color=7
db 94,216,0, 4 ; Y=94, X=216, Pattern#0, Color=4

HappyAlienBugFace:
db %00011000
db %01100100
db %11000011
db %00001111
db %00011001
db %00110000
db %00110110
db %01111111
db %01111111
db %01111111
db %01110000
db %00110000
db %00111000
db %00011110
db %00001111
db %00000011

db %00001100
db %00010010
db %11100011
db %11111001
db %11001100
db %10000110
db %10110110
db %11111111
db %11111111
db %11111111
db %00000111
db %00000110
db %00001110
db %00111100
db %11111000
db %11100000

 

http://www.youtube.com/watch?v=2dHoBzpOE6s

Edited by newcoleco
  • Like 2
Link to comment
Share on other sites

That video is very interesting. Assembly is very interesting programming language since you have more control over the machine. I did mess around with ASM for the Atari 2600, but I will mess around with the later since I want to finish programming the game I'm making for Colecovision.

 

I decided to try to program sprite flickering routine in C to my scratch program, Hello World. Please note, I'm playing around with 8x8 sprite_simple mode. Also, this isn't a serious program so do laugh if it is funny. I had to test 8x8 mode. For some reason, Centipede was able to display 8 sprites without flickering in NewColeco video, unless there's prosper mode for BlueMSX.

 

http://www.youtube.com/watch?v=jApljk09zX8

 

Last night, I figured out the how and when to use NMI. When this function was enabled while writing the, print_at(1,20,"The yellow ghost filled with lemonade is being controlled by joypad!!! RUN!!!");, text, It only drew, "The". When I nest that with disable_nmi() enable_nmi(). The text printed out completely.

 

Anyway here what I did. I declared x globally. Right after the local variable declaration in the main(), I put x=0. SpriteFlicker() is added to the NMI routine along with sprite update. Here's the code for the flicker routine...

 

static void SpriteFlicker(void)
{

sprites[0+x].x = 8;
sprites[0+x].y = 24;
sprites[0+x].pattern = 12;
sprites[0+x].colour = 2;
sprites[1+x].x = 16;
sprites[1+x].y = 24;
sprites[1+x].pattern = 12;
sprites[1+x].colour = 3;
sprites[2+x].x = 24;
sprites[2+x].y = 24;
sprites[2+x].pattern = 12;
sprites[2+x].colour = 4;
sprites[3+x].x = 32;
sprites[3+x].y = 24;
sprites[3+x].pattern = 12;
sprites[3+x].colour = 5;
sprites[4-x].x = 40;
sprites[4-x].y = 28;
sprites[4-x].pattern = 12;
sprites[4-x].colour = 6;
sprites[5-x].x = 48;
sprites[5-x].y = 28;
sprites[5-x].pattern = 12;
sprites[5-x].colour = 7;
sprites[6-x].x = 56;
sprites[6-x].y = 28;
sprites[6-x].pattern = 12;
sprites[6-x].colour = 8;
sprites[7-x].x = 64;
sprites[7-x].y = 28;
sprites[7-x].pattern = 12;
sprites[7-x].colour = 9;
	if(x==0)
	{
		x=4;
		goto here;
	}
	else
	{
		x=0;
		goto here;
	}	
here:
}

 

I think it is sloppy and slow, but it works. I think if I want to move these sprites, then their attributes will have to be variable instead of a fixed number.

Edited by Kiwi
Link to comment
Share on other sites

You have to understand this when you program in C : to access a value within a data structure, the program need to do a multiplication with teh size of the structure in order to access the right area. But, you can optimize this by moving around a pointer in the sprites table insted of using multiple times the way of accessing data with [ ].

 

I didn't try this code yet, but I think you'll get the idea pretty quickly.

 

 

function blahblah() {

 

sprite_t *pointer;

pointer = &sprite[x+0];

 

pointer.y = ...; /* equals to sprite[x+0].y = ... */

pointer.x = ...;

pointer.pattern = ...;

pointer.colour = ...;

 

pointer += 4; /* Because sprite_t size is 4. I don't know if it works under SDCC. */

 

pointer.y = ...; /* equals to sprite[x+1].y = ... */

pointer.x = ...;

pointer.pattern = ...;

pointer.colour = ...;

 

...

 

}

 

In C, [x+0] is calculated as x times 4 by adding 4 times the number x (or maybe it's x times adding the number 4, I can't remember) which takes a lot of time. So if you do this multiple times you multiply the time needed to proceed through your sprites flickering effect.

Link to comment
Share on other sites

I've taken time to continue my Sprites Sample program to add a simple movement with a ball bouncing effect.

 

; Colecovision - Sprites Demo
; by Daniel Bienvenu, 2010

NBR_SPRITES: equ 7

fname "7spritesmoving.rom"
cpu Z80
org $8000
dw $aa55,$7100,$7000,0,0,Start
dw 0,0,0,0,0,0,0,0,0,0
ret
Nmi:
; Display Sprite(s)
ld a,NBR_SPRITES
call $1fc4 ; WR_SPR_NM_TBL
ld a,$d0
out ($be),a

; Update Sprites position (for next time)
ld de,($8002)
ld hl,$7180
ld b,NBR_SPRITES
UpdateSpritesCoor:
ld a,160
call AddfromHLinDE
ld a,216
call AddfromHLinDE
inc de
inc de
djnz UpdateSpritesCoor
   
; Get Video Status
call $1fdc ; READ_REGISTER
bit 6,a
jr z,DoNothing
and $1f ; keep only 5bits = sprite#
ld e,a
ld d,0
ld hl,($8004)
push hl
add hl,de
ld c,(hl) ; Get corresponding Sprite entry
pop hl
ld a,NBR_SPRITES
ld b,a
reordering1:
ld (hl),c
inc hl
inc c
cp c
jr nz,reordering2
ld c,0
reordering2:
djnz reordering1
DoNothing:
retn

; Apply movement incrementation and bounce effect (max limit in register A)
AddfromHLinDE:
push bc
ld b,a
ld c,(hl)
ld a,(de)
add a,c
; if new position is lower than 24 or higher than max limit then bounce
cp 24
jr c,bounce
cp b
jr nc,bounce
jr endbounce
bounce:
ld a,c
neg
ld (hl),a
ld c,a
ld a,(de)
add a,c
endbounce:
ld (de),a
inc hl
inc de
pop bc
ret
   
Start:
call $1f85 ; MODE_1
call $1fd6 ; TURN_OFF_SOUND
; Clear VRAM
ld hl,0
ld de,$4000
xor a
call $1f82 ; FILL_VRAM
; Load Sprite Pattern
ld de,$3800
ld hl,HappyAlienBugFace
ld bc,32
call $1fdf ; WRITE_VRAM
; Init. Sprites Order
ld a,NBR_SPRITES
call $1fc1 ; INIT_SPR_ORDER
ld de,($8002)
ld hl,SprAttrib
ld bc,NBR_SPRITES*4
ldir
;ld hl,SprMovements ; Optim : HL already = SprMovements table address
ld de,$7180
ld bc,NBR_SPRITES*2
ldir
; Turn On Display + Enable NMI
ld bc,$01e2
call $1fd9 ; WRITE_REGISTER
TheEnd:
jp TheEnd

SprAttrib:
db 82, 24,0,13 ; Y=82, X= 24, Pattern#0, Color=13
db 84, 56,0, 8 ; Y=84, X= 56, Pattern#0, Color=8
db 86, 88,0, 9 ; Y=86, X= 88, Pattern#0, Color=9
db 88,120,0,10 ; Y=88, X=120, Pattern#0, Color=10
db 90,152,0, 3 ; Y=90, X=152, Pattern#0, Color=3
db 92,184,0, 7 ; Y=92, X=184, Pattern#0, Color=7
db 94,216,0, 4 ; Y=94, X=216, Pattern#0, Color=4
   
SprMovements:
db 0,0
db 1,0
db 0,1
db -1,0
db 0,-1
db 1,1
db -1,-1

HappyAlienBugFace:
db %00011000
db %01100100
db %11000011
db %00001111
db %00011001
db %00110000
db %00110110
db %01111111
db %01111111
db %01111111
db %01110000
db %00110000
db %00111000
db %00011110
db %00001111
db %00000011

db %00001100
db %00010010
db %11100011
db %11111001
db %11001100
db %10000110
db %10110110
db %11111111
db %11111111
db %11111111
db %00000111
db %00000110
db %00001110
db %00111100
db %11111000
db %11100000

Edited by newcoleco
  • Like 1
Link to comment
Share on other sites

For some reason, Centipede was able to display 8 sprites without flickering in NewColeco video, unless there's prosper mode for BlueMSX.

 

There is on option in Blue Msx to reduce the flicking.

 

 

@newcoleco : your video are really great!.

 

I would love to see some example of use of Put_mobile put_semimobile etc... :) (if possible used from C!!)

Link to comment
Share on other sites

Please, keep in mind that sometimes a bunch of moving objects on screen may also be composed of characters which allow, for example, to put more ennemies (or ennemi parts) in a row without any flickering... like ennemies in Spectar and animals legs in Joust... but I'm not covering this subject here.

 

Terms like semi-mobile and mobile objects for the ColecoVision BIOS are refered as 16x16 graphics you can put on screen as characters but not limited to the 32x24 places you can put character. A semi-mobile object is simply lmited to moving into corridors of characters in horizontal and vertical, like in Spectar if you want. A mobile object is put anywhere on screen like a sprite but it's a bunch of characters. The objects routines use (if I remember correctly) the charset range $80-$FF to generate the characters that will be put on screen. I'll need to dig up into the documentation because I've never tried using the functions for moving objects before. It's better to use a more adapted solution for your needs because it's usually more optimized than a more generic function, so you may find using these mobile functions a bit painful, and if you want to use it under a project in C language, well you need to modify the header "crtcv.s" in order to set the work_space to an address where these functions can calculated freely whitout corrupting your game variables. In the devkit, I've actually set the work_space to be $7000-$701F which is not enough even for the semi-mobile objects... but it's just enough for the flip and rotate graphics manipulations functions.

Link to comment
Share on other sites

Please, keep in mind that sometimes a bunch of moving objects on screen may also be composed of characters which allow, for example, to put more ennemies (or ennemi parts) in a row without any flickering... like ennemies in Spectar and animals legs in Joust... but I'm not covering this subject here.

 

Terms like semi-mobile and mobile objects for the ColecoVision BIOS are refered as 16x16 graphics you can put on screen as characters but not limited to the 32x24 places you can put character. A semi-mobile object is simply lmited to moving into corridors of characters in horizontal and vertical, like in Spectar if you want. A mobile object is put anywhere on screen like a sprite but it's a bunch of characters. The objects routines use (if I remember correctly) the charset range $80-$FF to generate the characters that will be put on screen. I'll need to dig up into the documentation because I've never tried using the functions for moving objects before. It's better to use a more adapted solution for your needs because it's usually more optimized than a more generic function, so you may find using these mobile functions a bit painful, and if you want to use it under a project in C language, well you need to modify the header "crtcv.s" in order to set the work_space to an address where these functions can calculated freely whitout corrupting your game variables. In the devkit, I've actually set the work_space to be $7000-$701F which is not enough even for the semi-mobile objects... but it's just enough for the flip and rotate graphics manipulations functions.

 

About 2 years ago I was looking into the Colecovision BIOS using your superb documentation. I was fascinated by the many OS7 functions availabe.

So, I built a primitive disassembler and scanned many of the game roms for OS7 calls. Too my surprise only a few games were using a wider variety of OS7 calls.

Don't recall exactly, but I can't remember having found any game that used any of the "mobile" functions.

 

Then again that could have been due to my disassembler failing :P

 

I like many of the concepts used in OS7. I wonder why they weren't used by the developers as much.

 

Could it be because they didn't have the documentation? Could imagine that as an external colecovision developer you had to pay some $$$ for training and perhaps a license ?

Another reason could have been that the publisher wanted to make a game available for multiple Z80 / TMS9918 platforms (e.g. MSX) and then it would not make sense to use any platform dependant BIOS calls.

Link to comment
Share on other sites

Don't recall exactly, but I can't remember having found any game that used any of the "mobile" functions.

You should start a topic with this subject of the most commonly and rarely used routines for the CV bios.

 

As for mobile and semi-mobile routines, I think there were used in Donkey Kong and Freezy, but don't quote me on that.

 

 

Too my surprise only a few games were using a wider variety of OS7 calls.

 

...

 

Could it be because they didn't have the documentation? Could imagine that as an external colecovision developer you had too pay some $$$ for training and perhaps a license ?

Yes, the documentation wasn't free. I remember someone saying that they pretty much had to use at first reverse engineering methods to figure out what they can do with this game system. But I think paying for the documentation came with the license, so in order to make games for the game system, the developpers had to pay for the documentation, even if they decided to use pretty much nothing of what is in the ColecoVision bios. Again, I'm not 100% sure, so don't quote me on that too.

 

 

Just for the fun of it. Here are 3 games I took a closer look at. If you scroll to the end of the files you'll find a list of OS7 routines that were found by the scanner.
I'm kinda surprised that you didn't bring up a listing from a game like Q*Bert where sounds aren't played through the sound manager system in the ColecoVision bios.

 

But yes, they tend to use what they find useful for the game project and make their own routines for the rest, which gives usually a better result because it fits perfectly the needs instead of being too generic and then slower than wanted. See these bios routines as a toolbox... to make an analogy, it's not necessary to use all your tools to build a bed or fix your car.

Edited by newcoleco
Link to comment
Share on other sites

  • 2 weeks later...
  • 8 months later...

hi guys, I am not a Z80 expert but when I am going through your code and try to understand where is actually the flickering happening? the reordering routine does what?

I don't know if it's clear but...

 

The reordering routine set a new "priority order" for the sprites. The top priority gives the advantage to the sprite to be shown without a problem screen. So if at least one sprite is the 5th sprite in a row, and so not displayed properly on screen, its number is set in the video register. Then we get its number and adjust the "priority" table to make this sprite the first one to be displayed. That's what the reordering code do. The routine that display the sprites on screen based ont the "priorities" table is the call $1fc4, a ColecoVision BIOS function named "WR_SPR_NM_TBL" for Write Sprite Name Table... or if you prefer, updating the sprites attributes (Y,X,Pattern#,Color) in the order defined by the table modified (or not) by the reordering routine.

Link to comment
Share on other sites

Thanks...

 

but can you comment the part in your source? because I played around with multiplexing sprites some years ago but on A8. so i discovered the ringbuffer approach on msx machines. why do I find this approach interesting? because A8 has 4 hardware sprites per scanline limit, too...

Link to comment
Share on other sites

Nmi:
       ; Display Sprite(s) based on the priority table
       ld a,NBR_SPRITES
       call $1fc4 ; WR_SPR_NM_TBL

       ; Add the infamous $D0 that tells the video chip that there is no more sprites to display
       ld a,$d0
       out ($be),a

...

   
       ; Get Video Status
       call $1fdc ; READ_REGISTER

       ; If there is no 5th sprite issue, do nothing
       bit 6,a
       jr z,DoNothing

       ; Otherwise filter to get the sprite#
       and $1f ; keep only 5bits = sprite#

       ; Get the corresponding sprite entry from the priority table
       ld e,a
       ld d,0
       ld hl,($8004)
       add hl,de ; Add offset to the table address
       ld c,(hl) ; Get corresponding Sprite entry

       ; Do a sprites rotation, starting with the sprite that was identified as the 5th sprite
       ld hl,($8004)
       ld a,NBR_SPRITES
       ld b,a
reordering1:
       ld (hl),c
       inc hl
       inc c
       ; If the next sprite ID correspond to the number of sprites, set it instead as ID 0
       cp c
       jr nz,reordering2
       ld c,0
reordering2:
       djnz reordering1
DoNothing:
       retn

 

In words now, if there is no 5th sprite issue, the priority table stay the way it is. Otherwise, the routine I've coded here place the sprite detected as the 5th sprite to be the top priority by putting its ID as the first one in the priority table. The followed sprite IDs are in order the way you seem to have already experimented by using a ringbuffer if you like. The effect is of course displayed at the beggining of the next NMI interuption.

 

The initialization of the priority table for sprites is done in the main coding part, not in the NMI routine of course, and it's done by a call to a Coleco BIOS routine. And that's it!

Link to comment
Share on other sites

and as far as I know the video chip sets 5th bit?

You are talking here about the video status register we have to read everytime and in which we can get a valuable information. Yes, it's supposed to be the 5th bit...

 

The video status register is structured into 3 flags, 1 bit each, and a sprite # (from 0 to 31) in 5 bits.

 

Please note that bits are numbered according to the power of 2 they represent, so the lowest bit is also named bit-0 (2^0 = 1), and the highest bit (in a byte) is named bit-7 (2^7 = 128).

 

FLAGS

 

Bit 7 (aka INT-eruption) is set when the screen is refreshed, because my engine is coded into the NMI part, this information is useless.

 

Bit 6 (aka C-ollision) is set when there is a sprite collision, unfortunately you don't know which sprite made the collision.

 

Bit 5 (aka 5th-sprite) is set when there is a 5th sprite issue, and the sprite number (from 0 to 31) is set into 5 bits (bit 4, bit 3, bit 2, bit 1 and bit 0).

 

So, I'm wrongly checking bit 6 for the 5th sprite issue... good observation! I'm wondering now why my code sample is working... maybe it's by luck or my source documentation is wrong (I don't think so) or you can't trust emulators or a mix of all these probabilities.

 

As for the sorting algorithm, I'm not trying to order sprites by sorting them but by shifting their priorities... this is the fastest and easiest way to deal with it. It's just a simple loop to cover the number of sprites, with almost no cpu usage each loop. So, it's really fast, but can't be the proper one to use for each project.

Link to comment
Share on other sites

ok. Daniel, now it gets interesting as you mentioned no sorting...

 

what if in worst case all 32 sprites are sitting on the same line? the video hardware will mark the first 5th sprite? so you assume that all others are on the same then afterwards?

 

what if you have 6 on the same line while sprite 7-32 are having no 5th sprite issue at all?

 

I played around with some sprite multiplexer on c64 and a8 and most of them sort the sprites by y-axis and then perfom checks if sprite limit is reached for each scanline or screen zone.

 

and ring buffer method is used mainly on MSX/TI/COLECO machines.

 

A8 has 4 sprite hardware per scanline but no hardware is detecting the bandwith but this could be done by software no problem at all. I only know one Atari800 game... check out Joust which uses ring buffer IMHO.

 

thanks for explaining more...

Link to comment
Share on other sites

Ok, I will try with something more visual. Suppose the following list the table of sprites priorities, telling simply which sprite to display first, second, etc.

 

The initial state :

  1. 0
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 7
  9. 8
  10. 9

 

The ColecoVision BIOS routine look at this table and "display" the sprites in this order : first it's sprite#0, then sprite#1, etc. Let's suppose the video register tells you that the 7th sprite it displayed on screen do have an issue of 5th sprite in a row and so didn't display entirely on screen. My alorithm look for the sprite# is the 7th sprite in the prority table, instantly we get sprite#6. Then, my algorithm constuct the next table of sprites priorities like this, staring with sprite#6.

 

 

New state, starting with sprite#6 :

  1. 6
  2. 7
  3. 8
  4. 9
  5. 0
  6. 1
  7. 2
  8. 3
  9. 4
  10. 5

 

Because it's the first sprite to be displayed on screen, sprite#6 is displayed properly, no 5th sprite issue for this one. You bet that there is still a 5th sprite issue if these sprites are pretty much at the same positions as before on screen, but this time it's not sprite#6 that will have an issue.

 

The way my algorithm build up the new table of priorities is simply : first it's sprite#6, increment, second it's sprite#7, increment, third it's sprite#8, increment, fourth it's sprite#9, increment *warning next sprite# can't be 10*, fifth it's sprite#0, increment, and so on. As you can see, there is no sorting, it's just shifting the sprites order, nothing complex to keep it runs fast.

 

In the case of 32 sprites on screen, there is just more possibilities to get a 5th sprite issue, the algorithm doesn't change really, except for the number of sprites to show and consider when it's time to reorder them in the sprites priority table.

 

If I understand the video chip documentation correctly, in case of many 5th (or even 6th, 7th...) sprite issues, it's the first one detected based on the scanlines that is registered in the video register status. Scanlines are from top to bottom, left to right. It's not something we control, it's hardware stuff we have to deal with.

 

You may want to force a certain order that is different than what my solution provides, and as I said my routines presented here in these codes aren't necessary appropriate for any projects, and so you have to make some experimentations first, more thinking than simply reusing again and again a solution like the one I'm suggesting here and hope it works.

Link to comment
Share on other sites

ok. assume following... you have 32 virtual sprites. like in Konami games...so the VDP detects the 5th sprite but not more... so you would need to do it via software?

 

so calculating the overlappings? or how is Konami working with it's ring buffer?

Link to comment
Share on other sites

ok. assume following... you have 32 virtual sprites. like in Konami games...so the VDP detects the 5th sprite but not more... so you would need to do it via software?

 

so calculating the overlappings? or how is Konami working with it's ring buffer?

It all depends on what you want to accomplish... I'm not sure what you are looking for either. Anyway, overall my solution is very simple and works fine for some cases, it's enough complex to introduce people to the principle of sprites flickering. I've said already that it's not proper for every projects, it's not a miracle solution, but it does the job regardless of the number of sprites.

 

If we consider a 32 sprites case, which is the limit for this video chip, the case of flickering sprites is always a question of what is the "best looking" result. My solution provides a quick solution that flickers only a small number of sprites. For some games, a solution like this isn't appropriate, and a more "ghostly" effect is done by flickering pretty much all sprites all the time and the idea is to avoid some sprites to be too often not shown properly on screen by giving somehow an equal chance for every sprite. Also, it may be considered important to not flicker the player's avatar (or spaceship or whatever) because there can be an issue of not knowing where it is on screen... and so on about special cases, what you want to accomplish, etc.

 

There are other things than sprites in a videogame project that are also important to deal with, so it's important to not use too much CPU time for sprites. And because each programmer and each videogame project are different, if it's important for a project to know all the 5th, 6th, 7th sprites cases, of course the coding for sprites (including the flickering effect) will be more complex, using more CPU time. I'm telling you that you can't do it, like what you suggested in you last message, I'm simply telling you that it might not be necessary. For certain game engines that need a lot of calculations, a too complex approach will slow down the rendering which is not good. So you have to decide what is more important and code it well, and simplify what isn't that important in order to make the videogame run fast. If you simply use the same sprites flickering effect for every project, it may be fine for your needs, but a more specific approach depending on the project specifications is always a better idea but need of course more coding to do (compared to re-using the same codes again and again). And if you are looking for a simple approach that runs fast, my solution is pretty much the best one around, but again may not be suitable for your needs.

 

As for Konami routines, I have no clue... ask those who made ports of Konami games.

 

I hope this answer all your questions regarding my ColecoVision sprites sample assembly codes listing.

Edited by newcoleco
Link to comment
Share on other sites

  • 8 months later...

Busy evening - got the current version of zasm to compile on my MacBook Pro and started work on a mode file (syntax coloring rules) for jEdit.

 

Dropped in your sample from the first post

post-3056-0-71144700-1328674323_thumb.png

 

and after commenting out fname and cpu, voila

post-3056-0-77357300-1328674327_thumb.png

(yes, the flicker works as expected)

 

Now to start learning Z80 assembly!

 

 

Wonder how long until my SD cart arrives(I ordered it last Tuesday). Anticipation :D

Link to comment
Share on other sites

Busy evening - got the current version of zasm to compile on my MacBook Pro and started work on a mode file (syntax coloring rules) for jEdit.

Any chance of getting a copy of zasm for mac and your jedit mode file? Not sure if I would ever be able to do anything with it, but figure it doesn't hurt to have around. Years ago I started working on trying to code a CV game in C on my PC, but now I use a mac and don't know if there are any mac tools for CV coding. Yes I know I could run xp in bootcamp or in a VM, but really don't want to.

Edited by evg2000
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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