// C Header File // Created 12/5/2002; 9:48:22 PM /****************************************************************************** * * project name: STARS * initial date: 06/06/2000 * author: thomas.nussbaumer@peem.com * description: starfield effect demonstration * Edited for Oblivion by Malcolm Smith * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * NOTE: depends on TIGCC Standard Library 2.0 to compile * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * compile with: tigcc -O2 stars.c * * ----------------------------------------------------------------------------- * Revision History * ----------------------------------------------------------------------------- * * v1.00: 16/06/2000 * initial version * *******************************************************************************/ /*---------------------------------------------------------------------------*/ /* some constants defining the look of the starfield */ /*---------------------------------------------------------------------------*/ #define XOFFSET (LCD_WIDTH/2) #define YOFFSET (LCD_HEIGHT/2) #define MAX_STAR_X 16000 #define MAX_STAR_Y 16000 #define ZDECREMENT 4 #define BORDER_BLACK 100 #define BORDER_GRAY 140 static inline void Intro(void); static inline void DrawStars(void); extern unsigned char mask_values[8]; void CreateStar(int index); #ifndef __INTRO_H__ #define __INTRO_H__ // array used to lookup mask values for single pixels of a byte in a bitplane unsigned char mask_values[8] = { (unsigned char)~0x80,~0x40,~0x20,~0x10,~0x08,~0x04,~0x02,~0x1 }; /*===========================================================================*/ /* initializes star with given index */ /*===========================================================================*/ void CreateStar(int index) { register GameGlobals *ggg asm("a4") = gg; ggg->stars[index].x=random_long(MAX_STAR_X)-MAX_STAR_X/2; ggg->stars[index].y=random_long(MAX_STAR_X)-MAX_STAR_Y/2; ggg->stars[index].z=ggg->zoffset; } // macro returns the address of tile nr of plane p from array data #define TILEADDR_TITLE(p,nr) &(title[p*128+64*nr]) #define TILEADDR_TITLEMASK(nr) &(titlemask[64*nr]) /*===========================================================================*/ /* delete star at old position/calculate new position/draw new position */ /*===========================================================================*/ static inline void DrawStars(void) { register GameGlobals *ggg asm("a4") = gg; int offset; unsigned char mask; int drawx; int drawy; int i; FastCopyScreen(ggg->textplane,ggg->BGlight); FastCopyScreen(ggg->textplane,ggg->BGdark); for (i=0;istars[i].x / ggg->stars[i].z + XOFFSET; if (drawx < 0 || drawx >= LCD_WIDTH) { CreateStar(i); continue; } //--------------------------------- // calculate new drawing y position // and check if it out of screen //--------------------------------- drawy = ggg->stars[i].y / ggg->stars[i].z + YOFFSET; if (drawy < 0 || drawy >= LCD_HEIGHT) { CreateStar(i); continue; } //--------------------------------- // calculate byte offset of pixel //--------------------------------- offset = drawy * 30 + (drawx >> 3); mask = mask_values[drawx % 8]; //----------------------------------- // set pixel in plane 1 and plane2 //----------------------------------- *(ggg->BGlight+offset) &= mask; *(ggg->BGdark+offset) &= mask; //----------------------------------- // decrement z and check if we must // generate a new star //----------------------------------- ggg->stars[i].z -= ZDECREMENT; if (ggg->stars[i].z <= 0) CreateStar(i); } } /*===========================================================================*/ /* main routine: where all the fun starts ... */ /*===========================================================================*/ static inline void Intro(void) { register GameGlobals *ggg asm("a4") = gg; unsigned int i; short first = TRUE; if(!ggg->cfg.intro) return; //--------------------------------------------- // setup initial star positions //--------------------------------------------- for (i=0;istars[i].x=random_long(MAX_STAR_X)-MAX_STAR_X/2; ggg->stars[i].y=random_long(MAX_STAR_X)-MAX_STAR_X/2; ggg->stars[i].z=random_long(ZOFFSET)+1; } memset(ggg->textplane,0xFF,LCD_SIZE); #define MYH 64 //--------------------------------------------- // main loop //--------------------------------------------- short x1 = (short)((LCD_WIDTH/2)-33); short x2 = (short)((LCD_WIDTH/2)-1); short y = (short)((LCD_HEIGHT/2)-(MYH/2)-1); do { contrast(); DrawStars(); GraySprite32_AND(x1,y,MYH, titlemask,titlemask,ggg->BGlight,ggg->BGdark); GraySprite32_AND(x2,y,MYH, titlemask+64,titlemask+64,ggg->BGlight,ggg->BGdark); GraySprite32_OR(x1,y,MYH, title,title+128,ggg->BGlight,ggg->BGdark); GraySprite32_OR(x2,y,MYH, title+64,title+128+64,ggg->BGlight,ggg->BGdark); if(first) { register GameGlobals *ggg asm("a4") = gg; first = FALSE; dissolveGSFromTo(ggg->BGlight,ggg->BGdark,ggg->plane1,ggg->plane2); } else { FastCopyScreen(ggg->BGlight,ggg->plane1); FastCopyScreen(ggg->BGdark,ggg->plane2); } } while (!_rowread(0) || _keytest(RR_PLUS) || _keytest(RR_MINUS)); FAT_AllKeysReleased(); } #endif