Jump to content

Photo

Sprite flicker in C


1 reply to this topic

#1 Kiwi OFFLINE  

Kiwi

    Stargunner

  • 1,682 posts

Posted Fri Mar 8, 2019 5:30 PM

The whole idea is to swap sprites data position in different table because sprite 0-3 have the highest priority.

#include <coleco.h>
#include <getput1.h>

#define chrgen  0x0000
#define coltab  0x2000
#define chrtab  0x1800
#define sprtab  0x3800
#define sprgen  0x1b00

byte a,b,e,d,x,y,i,j,c,ID,flicker,
aniframe,
playerx,playery;
byte objectID[6],objectx[6],objecty[6],objectc[6],objectp[6],objectb[6];
//create arrays that holds the ID,x,y,color,pattern and behavior.

const byte sampleSPRITE[] = {
    0x06,0x07,0x18,0x27,0x59,0x57,0xaf,0xaf,0x83,0xbf,0x81,0x5f,0x07,0x27,0x18,0x07,0xe0,0x18,0xe4,0xfa,0xfa,0x85,0xfd,0x81,0xfa,0x09,0xe4,0x18,0xe0,0x00,0x07,0x18,
    0x26,0x28,0x50,0x50,0x83,0x40,0x81,0x20,0x07,0x18,0x07,0x00,0x00,0xe0,0x18,0x04,0x04,0x85,0x02,0x81,0x04,0x12,0x18,0xe0,0x00,0x07,0x07,0x05,0x07,0x72,0xea,0xa1,
    0x0e,0x07,0x07,0x00,0x03,0x07,0x06,0x00,0x1e,0x82,0xc0,0x2c,0x8e,0x5d,0x54,0xa0,0x70,0xe0,0xe0,0x00,0xc0,0x60,0x30,0x1c,0x00,0x08,0x08,0x0a,0x78,0x8d,0x15,0x5e,
    0xb1,0x08,0x08,0x07,0x04,0x08,0x09,0x1f,0x21,0x20,0x20,0x2e,0x71,0xa2,0xab,0x5e,0x88,0x10,0x10,0xf0,0x20,0x90,0x4c,0x22,0x3c,0x82,0x03,0x3c,0x71,0xba,0x2a,0x05,
    0x0e,0x07,0x07,0x00,0x03,0x06,0x0c,0x38,0x00,0xe0,0xe0,0xa0,0xe0,0x4e,0x57,0x85,0x70,0xe0,0xe0,0x00,0xc0,0xe0,0x60,0x00,0x78,0x04,0x04,0x74,0x8e,0x45,0xd5,0x7a,
    0x11,0x08,0x08,0x0f,0x04,0x09,0x32,0x44,0x3c,0x10,0x10,0x50,0x1e,0xb1,0xa8,0x7a,0x8d,0x10,0x10,0xe0,0x20,0x10,0x90,0xf8,0x84,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xfe,
    0x00,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xfe,0x00,0xcd,0x00,0xff};

//Sweep Sprite is like a broom to sweep all sprites off to the bottom of the screen
//just 1 pixel above 208 to avoid the sprite termination flag.
void SweepSprites(void){

for (i=0;i!=32;i++){
	sprites[i].y = 207;
	
}
updatesprites(0,64);
}

//object behavior is script for the objects.  case 0, normally not in the list since it's my 
//free slot to allow spawn object,
//for this example, it only have the object stationary in a egg shape.
//case 1 animates the zombie and move the zombie from the top and to the bottom of the screen
//repeatly

void ObjectBehavior(void){
for(ID=0;ID!=6;ID++){
switch(objectID[ID]){
case 0:
objectp[ID]=0;
break;
case 1:
if(objectb[ID]==0){objecty[ID]--;}
if(objectb[ID]==1){objecty[ID]++;}
if(objecty[ID]==8){objectb[ID]=1;}
if(objecty[ID]==160){objectb[ID]=0;}
if(aniframe==0){objectp[ID]=8;}
if(aniframe==16){objectp[ID]=16;}
break;
}//switch
}//for
}//end objbeh

/*
Sprite rotation is rolled up routine that reorder the sprites every frame.
In this example, I'm using 1 color sprites.  2 color sprites is a slightly different method of 
flickering.  Flickering is a case by case for each games because I have to predict how many
sprites going to be on a scanline.
 
 Normally loading the 1 color sprites forward 1 frame, and backward the other frame. 
This will give you the scanline flickering on LCD screen. 

*/

void SpriteRotation(void){
switch(flicker){
case 0:
for(ID=0;ID!=6;ID++){
sprites[1+ID].y = objecty[ID];
sprites[1+ID].x = objectx[ID];
sprites[1+ID].colour=objectc[ID];
sprites[1+ID].pattern=objectp[ID];
}
flicker=1;
break;
case 1:
for(ID=0;ID!=6;ID++){
sprites[6-ID].y = objecty[ID];
sprites[6-ID].x = objectx[ID];
sprites[6-ID].colour=objectc[ID];
sprites[6-ID].pattern=objectp[ID];
}
flicker=0;
break;

}//switch
}//end function

void main(void){
screen_mode_2_text();
screen_on();
disable_nmi();
rle2vram(sampleSPRITE,0x3800);
playerx=120;playery=72;
//rle2vram(?,0x0000);
//duplicate_pattern();
//rle2vram(?,0x2000);

SweepSprites();//Move all sprites, without this.  The other sprites position is at
//x=0,y=0.  On cartridge, these would unknown state.



//setting up the sprites using loop to type less stuff and save cartridge space.
for(ID=0;ID!=6;ID++){
objectx[ID]=40+16*ID;
objecty[ID]=88;
objectc[ID]=15;
}
//setting up the behavior
objectb[0] = 0; 
objectb[2] = 0;
objectb[4] = 0;
objectb[1] = 1;
objectb[3] = 1;
objectb[5] = 1;
enable_nmi();
a=1;//putting 1 into a to activate the while loop.
while(a==1){
delay(1);//waits for vertical retrace, keeps the game at 60 fps
updatesprites(0,64);//must be (0,64) 
SpriteRotation();
ObjectBehavior();

aniframe++;
if(aniframe>=32){aniframe=0;}

if(joypad_1&FIRE1){
for(ID=0;ID!=6;ID++){
objectID[ID]=1;
objectc[ID]=12;
}
}//turn zombies into egg

if(joypad_1&FIRE2){
for(ID=0;ID!=6;ID++){
objectID[ID]=0;
objectc[ID]=15;
}
}//activate zombies

if(joypad_1&UP){
playery--;
}

if(joypad_1&DOWN){
playery++;
}

if(joypad_1&RIGHT){
playerx++;
}

if(joypad_1&LEFT){
playerx--;
}

//flicking the player using sprite pattern number 0 and 31.
//This way, your player is always visible to the gamer.
if(flicker==0){
sprites[0].y = playery;
sprites[0].x = playerx;
sprites[0].colour = 12;
sprites[0].pattern = 0;
sprites[31].y = playery;
sprites[31].x = playerx;
sprites[31].colour = 15;
sprites[31].pattern = 4;
}
if(flicker==1){
sprites[31].y = playery;
sprites[31].x = playerx;
sprites[31].colour = 12;
sprites[31].pattern = 0;
sprites[0].y = playery;
sprites[0].x = playerx;
sprites[0].colour = 15;
sprites[0].pattern = 4;
}

}//while
}


void nmi(){


}//leave blank

Edited by Kiwi, Fri Mar 8, 2019 5:35 PM.


#2 Serguei2 OFFLINE  

Serguei2

    Dragonstomper

  • 785 posts
  • Location:Canada

Posted Fri Mar 8, 2019 6:28 PM

Great stuff Kiwi. I like it.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users