home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * MATRIX.C
- *
- * (Simon Hern, August 1993 - June 1995)
- *
- * Matrix demo - animation of viewer gliding above an infinite tiled floor (!)
- *
- * Uses graphics routines in MTXCODE.ASM and table in ANGSINES.ASM
- *
- */
-
- #include <stdlib.h>
- #include <time.h>
- #include <conio.h>
- #include <fcntl.h>
- #include <dos.h>
- #include <math.h>
- #include <string.h>
- #include <alloc.h>
-
-
-
- /* CONSTANT DEFINITIONS */
-
- #define PI 3.141592654L
-
- /* Number of possible directions to move/look in */
- #define ANGLES 1024L
-
- /* Screen dimensions */
- #define SCR_HEIGHT 200L
- #define SCR_WIDTH 320L
-
- /* Viewer's perspective - distance of virtual eye from screen (pixels) */
- #define VIEW_DIST 512L
-
- /* Number of bytes used for tile image (one full segment!) */
- /* (This size is to save having to clip coordinate variables */
- /* - just use 8 bit variables. Bit of a waste of memory tho) */
- #define TILE_SIZE 256L*256L
-
-
-
- /* STRUCTURE DECLARATIONS */
-
- /* Structure for holding one palette setting */
- typedef struct {
- char red;
- char green;
- char blue;
- } RGBvals;
-
-
-
- /* Structure associating names with predefined colours */
- typedef struct {
- char * name;
- RGBvals colour;
- } NamedColour;
-
- #define COLOURS 21
-
- NamedColour Colours[COLOURS] = {
- { "black", { 0, 0, 0 } },
- { "blue", { 0, 0, 63 } }, { "darkblue", { 0, 0, 31 } },
- { "red", { 63, 0, 0 } }, { "darkred", { 31, 0, 0 } },
- { "magenta", { 63, 0, 63 } }, { "darkmagenta", { 31, 0, 31 } },
- { "green", { 0, 63, 0 } }, { "darkgreen", { 0, 31, 0 } },
- { "cyan", { 0, 63, 63 } }, { "darkcyan", { 0, 31, 31 } },
- { "yellow", { 63, 63, 0 } }, { "darkyellow", { 31, 31, 0 } },
- { "white", { 63, 63, 63 } },
- { "orange", { 63, 31, 0 } }, { "darkorange", { 31, 15, 0 } },
- { "pink", { 63, 0, 31 } }, { "darkpink", { 31, 0, 15 } },
- { "violet", { 47, 0, 63 } },
- { "turquoise", { 0, 63, 31 } },
- { "grey", { 31, 31, 31 } }
- };
-
-
-
- /* Structure for predefined colour sets - named colours, one for the sky */
- /* and two for the tiles */
- typedef struct {
- char * tile1;
- char * tile2;
- char * sky;
- } ColourSet;
-
- #define COLOUR_CHOICES 8
-
- ColourSet ScreenColours[COLOUR_CHOICES] = {
- { "red", "blue", "cyan" },
- { "green", "blue", "darkyellow" },
- { "orange", "black", "darkmagenta" },
- { "white", "blue", "violet" },
- { "black", "white", "blue" },
- { "yellow", "violet", "grey" },
- { "grey", "darkred", "orange" },
- { "yellow", "blue", "darkgreen" },
- };
-
-
-
- /* FUNCTION DECLARATIONS */
-
- int Animate();
- void MoveMatrix();
- void PaintSky();
- void PaintTile();
- int LoadTile(char * fname);
- void BlurPalette();
- void GoBlack();
-
- void Message();
- void Error(char * comment);
-
- void AllocateMemory();
- void FreeMemory();
-
- void MakeDistances();
- void MakeBlurs();
-
- void CommandArguments(int argc, char * argv[]);
- void ChooseColours();
-
- char * ReadColour(RGBvals * dest, char * str);
- void ListSkyColours(char * dest);
- void ListTileColours(char * dest);
-
- float Sin(int a);
- float Cos(int a);
-
-
-
- /* EXTERNAL (ASSEMBLER) FUNCTIONS */
-
- /* ScreenOn: mode 13h - 320*200 in 256 colours */
- extern void ScreenOn(void);
-
- /* ScreenOff: text mode */
- extern void ScreenOff(void);
-
- /* SetPalette: set some or all of palette */
- extern void SetPalette(RGBvals near *, int start, int number);
-
- /* DisplayMatrix: draw Matrix in bottom half of screen */
- extern void DisplayMatrix(int angle, int xpos, int ypos);
-
- extern int AngleSines[ANGLES];
-
-
-
- /* GLOBAL VARIABLES */
-
- char far * Tile; /* Pointer to tile image (must start on segment boundary */
- char far * ScrBuffer; /* Screen buffer for animated part of screen */
- int * Distances; /* Array of precalculated values, one for each line drawn */
- unsigned char * Blurs; /* Array of 'blur' factors for fading near horizon */
- RGBvals * Palette; /* Complete 256 value palette to be used */
-
- char far * Tile_alloc; /* Start of areas of memory allocated for Tile, */
- char far * ScrBuffer_alloc; /* ScrBuffer and Distances arrays. An overlap */
- char * Distances_alloc; /* is allowed for aligning with segment bounds */
-
-
- RGBvals SkyColour = { -1, -1, -1 }; /* Brightest colour in the sky */
- int DullSky; /* Flag: sky fades up slowly, never reaches full brightness */
-
- RGBvals TileColour1 = { -1, -1, -1 }; /* Colour at middle of tile */
- RGBvals TileColour2 = { -1, -1, -1 }; /* Colour at edge of tile */
-
- RGBvals BlurColour; /* Colour to fade tiles to when nearing horizon */
-
-
- int XPos, YPos; /* Position of observer relative to a tile */
- int Angle; /* Direction observer is facing */
-
- int TimerDelay = 0; /* Seconds demo runs for, or no timer if zero */
- int StopMessage = 0; /* Flag: suppress display of end credits */
- char * PicFile = NULL; /* Name of file to load for tile image */
-
-
-
-
-
- /* CODE STARTS HERE */
-
- enum { RET_ESCAPE = 1, RET_TIME = 0 };
-
- int main(int argc, char * argv[]) {
-
- int ret_code;
-
- randomize();
-
- CommandArguments(argc, argv);
- ChooseColours();
-
- AllocateMemory();
-
- MakeDistances();
- MakeBlurs();
-
- ScreenOn();
- GoBlack();
-
- PaintSky();
- if ( PicFile == NULL || LoadTile(PicFile) == 0 ) PaintTile();
- BlurPalette();
-
- XPos = random(256);
- YPos = random(256);
- Angle = random(ANGLES);
- DisplayMatrix(Angle, XPos, YPos);
-
- SetPalette(Palette, 0, 256);
-
- ret_code = Animate();
-
- ScreenOff();
-
- FreeMemory();
-
- if ( ! StopMessage ) Message();
- return ret_code;
- }
-
-
-
- /* Run the animation until either a key is pressed (return RET_ESCAPE) */
- /* or the time TimerDelay runs out (return RET_TIME) */
-
- int Animate() {
- time_t start_time = time(NULL);
-
- for (;;) {
-
- MoveMatrix();
- DisplayMatrix(Angle, XPos, YPos);
-
- if ( kbhit() ) {
- while ( kbhit() ) getch();
- return RET_ESCAPE;
- }
-
- if ( TimerDelay && (time(NULL) - start_time) > TimerDelay ) {
- return RET_TIME;
- }
-
- }
- }
-
-
-
- /* Move the matrix position [XPos, YPos, Angle] (global vars) by one step */
- /* Angular velocity swings left then right (as a sine wave) holding on at */
- /* its peak value for a random time */
- /* Point moves in the direction of Angle with speed (both forwards and */
- /* backwards) varying randomly */
- /* Additional 'drift' motion occurs in a direction perpendicular to Angle */
-
- #define MAX_ANGVEL 7
- #define MAX_SPEED 50
- #define DRIFT_STRENGTH 0.7
-
- void MoveMatrix() {
-
- static int angvel, angvel_sign;
- static int peak_angvel = 0;
- static int cycle_step, cycle_length, peak_hold;
-
- static int speed = MAX_SPEED/3, speed_dest = MAX_SPEED/3;
- static int speed_hold = 0;
-
- static int drift;
- static int drift_step = 0, drift_length = 0;
- static float drift_peak;
-
- /* Change viewing angle */
-
- if ( peak_angvel == 0 ) {
- peak_angvel = random(3*MAX_ANGVEL/4 + 1) + MAX_ANGVEL/4;
- angvel_sign = 2*random(2) - 1;
- cycle_length = (2 + peak_angvel + random(10)) * 2;
- cycle_step = 0;
- peak_hold = random(150) + 15*(MAX_ANGVEL-peak_angvel);
- }
-
- if ( cycle_step > cycle_length ) {
- peak_angvel = random(3*MAX_ANGVEL/4 + 1) + MAX_ANGVEL/4;
- angvel_sign = -angvel_sign;
- cycle_length = (2 + peak_angvel + random(10)) * 2;
- cycle_step = 0;
- peak_hold = random(150) + 15*(MAX_ANGVEL-peak_angvel);
- }
-
- if ( cycle_step == cycle_length ) angvel = 0;
- else angvel = angvel_sign *
- (peak_angvel * Sin( (cycle_step*ANGLES/2) / cycle_length ) + 1);
-
- if ( cycle_step == cycle_length/2 && peak_hold > 0 ) peak_hold--;
- else cycle_step++;
-
- Angle = ( Angle + angvel ) & (ANGLES-1);
-
- /* Move point in direction of Angle */
-
- if ( speed == speed_dest ) {
- if ( speed_hold > 0 ) speed_hold--;
- else {
- speed_dest = random(2*MAX_SPEED/3 + 1) + MAX_SPEED/3;
- speed_dest *= 2*random(2) - 1;
- speed_hold = random(40) + 10;
- }
- }
-
- if ( speed < speed_dest ) speed++;
- if ( speed > speed_dest ) speed--;
-
- XPos = ( XPos + (int)(speed*Cos(Angle)) ) & 255;
- YPos = ( YPos + (int)(speed*Sin(Angle)) ) & 255;
-
- /* Drift perpendicular to Angle */
-
- if ( drift_step == drift_length ) {
- drift_step = 0;
- drift_length = 25 + random(75);
- drift_peak = DRIFT_STRENGTH * ( random(21) - 10 ) / 10.0;
- } else {
- drift_step++;
- }
-
- drift = drift_peak*speed * Sin( (ANGLES * drift_step) / drift_length );
-
- XPos = ( XPos - (int)(drift*Sin(Angle)) ) & 255;
- YPos = ( YPos + (int)(drift*Cos(Angle)) ) & 255;
- }
-
-
-
- /* Draw sky pattern on top half of screen and set palette values 0-63 */
- /* Colour of sky determined by SkyColour structure and DullSky flag */
-
- void PaintSky() {
- int col1, col2, col3, col4;
- char far * scr_ptr;
- char far * scr_ptr2;
- int i, j, k;
-
- /* Paint the sky */
- if ( DullSky ) {
-
- /* Sky brightens slowly */
- scr_ptr = MK_FP(0xA000, 0);
- for ( j = 0 ; j < 320 ; j++ ) {
- col1 = ( random(7) == 0 );
- col2 = ( random(8) < 3 );
- col3 = ( random(8) >= 3 );
- col4 = ( random(7) != 0 );
- scr_ptr2 = scr_ptr;
- k = j;
- for ( i = 0 ; i < 25 ; i++ ) {
- *(scr_ptr2+k) = col1+i;
- *(scr_ptr2+320+k) = col2+i;
- *(scr_ptr2+640+k) = col3+i;
- *(scr_ptr2+960+k) = col4+i;
- scr_ptr2 += 1280;
- k += 37;
- if ( k >= 320 ) k -= 320;
- }
- }
-
- } else {
-
- /* Sky brightens quickly */
- scr_ptr = MK_FP(0xA000, 0);
- for ( j = 0 ; j < 320 ; j++ ) {
- col1 = ( random(3) == 0 );
- col2 = ( random(3) != 0 );
- scr_ptr2 = scr_ptr;
- k = j;
- for ( i = 0 ; i < 50 ; i++ ) {
- *(scr_ptr2+k) = col1+i;
- *(scr_ptr2+320+k) = col2+i;
- scr_ptr2 += 640;
- k += 37;
- if ( k >= 320 ) k -= 320;
- }
- }
-
- }
-
- /* Choose palette colours 0 to 63 */
- for ( i = 0 ; i < 64 ; i++ ) {
- Palette[i].red = (SkyColour.red * i)/63;
- Palette[i].green = (SkyColour.green * i)/63;
- Palette[i].blue = (SkyColour.blue * i)/63;
- }
-
- }
-
-
-
- /* Draw simple image on tile using colours 0-31 */
- /* Set up first (unblurred) section of palette, colours 64-95 */
- /* Pick colour to blur to when approaching horizon */
-
- void PaintTile() {
- char far * topl, far * topr, far * left, far * lefb;
- unsigned char col;
- int i, j;
-
- /* Draw piccy on Tile */
- col = 0;
- for ( j=31 ; j >= 0 ; j-- ) {
- topl = (char far *) Tile + 4*j;
- topr = (char far *) Tile + 252 - 4*j;
- left = (char far *) Tile + ((4*j)<<8);
- lefb = (char far *) Tile + ((252-4*j)<<8);
- for ( i = 0 ; i < 256 ; i++ ) {
- *(topl) = *(topl+1) = *(topl+2) = *(topl+3)
- = *(topr) = *(topr+1) = *(topr+2) = *(topr+3) = col;
- *(left) = *(left+256) = *(left+512) = *(left+768)
- = *(lefb) = *(lefb+256) = *(lefb+512) = *(lefb+768) = col;
- topl += 256;
- topr += 256;
- left += 1;
- lefb += 1;
- }
- col++;
- }
-
- /* Choose palette colours 64 to 95 */
- for ( i = 0 ; i < 32 ; i++ ) {
- Palette[64+i].red = TileColour2.red +
- ((TileColour1.red - TileColour2.red) * i) / 31;
- Palette[64+i].green = TileColour2.green +
- ((TileColour1.green - TileColour2.green) * i) / 31;
- Palette[64+i].blue = TileColour2.blue +
- ((TileColour1.blue - TileColour2.blue) * i) / 31;
- }
-
- /* Set colour to blur to */
- BlurColour.red = (TileColour1.red + TileColour2.red)/2;
- BlurColour.green = (TileColour1.green + TileColour2.green)/2;
- BlurColour.blue = (TileColour1.blue + TileColour2.blue)/2;
- }
-
-
-
- /* Load a tile image from a file */
- /* fname.BIN is a 256*256 bitmap using colours 0-31 only */
- /* fname.PAL is a 32 value palette for the image */
- /* Sets BlurColour to average shade in palette */
-
- int LoadTile(char * fname) {
- char * file_name;
- int handle;
- unsigned nread;
- char far * t_ptr = (char far *) Tile;
- int i;
- int r,g,b;
-
- file_name = (char *) malloc(strlen(fname)+4);
- strcpy(file_name, fname);
- strcat(file_name, ".BIN");
- if ( _dos_open(file_name, O_RDONLY, &handle) != 0 ) return 0;
-
- if ( _dos_read(handle, (void far *)t_ptr, 32768L, &nread) != 0 ) return 0;
- if ( _dos_read(handle, (void far *)(t_ptr+32768L), 32768L, &nread)
- != 0 ) return 0;
-
- _dos_close(handle);
-
- strcpy(file_name+strlen(file_name)-4, ".PAL");
- if ( _dos_open(file_name, O_RDONLY, &handle) != 0 ) return 0;
-
- if ( _dos_read(handle, (void far *)(Palette+64), 3*32L, &nread)
- != 0 ) return 0;
-
- _dos_close(handle);
-
- free(file_name);
-
- r = g = b = 0;
- for ( i = 0 ; i < 32 ; i++ ) {
- r += Palette[64+i].red;
- g += Palette[64+i].green;
- b += Palette[64+i].blue;
- }
- BlurColour.red = r/32;
- BlurColour.green = g/32;
- BlurColour.blue = b/32;
-
- return 1;
- }
-
-
-
- /* Fill in blurred sections of palette */
- /* Colour ranges 96-127, 128-159, ..., 224-255 are the same as range 64-95 */
- /* but faded progressively closer to the colour BlurColour */
- /* These blurred colours are used to fade the tile pattern near the horizon */
-
- void BlurPalette() {
- int i, j;
- int c;
-
- for ( i = 3 ; i < 8 ; i++ ) {
- j = (i-2);
- if ( j > 2 ) j = j*2 - 2;
- for ( c = 0 ; c < 32 ; c++ ) {
- Palette[c+32*i].red = Palette[c+64].red +
- ((BlurColour.red - Palette[c+64].red) * j)/9;
- Palette[c+32*i].green = Palette[c+64].green +
- ((BlurColour.green - Palette[c+64].green) * j)/9;
- Palette[c+32*i].blue = Palette[c+64].blue +
- ((BlurColour.blue - Palette[c+64].blue) * j)/9;
- }
- }
-
- }
-
-
-
- /* All palette colours set to black, Palette zeroed */
-
- void GoBlack() {
- int i;
- for ( i = 0 ; i < 256 ; i++ )
- Palette[i].red = Palette[i].green = Palette[i].blue = 0;
- SetPalette(Palette, 0, 256);
- }
-
-
-
- /* Display exit message */
-
- void Message() {
- puts(
- "MATRIX DEMO \n"
- "Simon Hern (22 Harrington Drive, Bedford, MK41 8DB, England)\n"
- "July 1990, August 1993, September 1994, June 1995\n\n"
- "Command line options:\n"
- " /s - Suppress this message\n"
- " /t:<delay> - Time-out after <delay> seconds (default 120)\n"
- " /0:<col> - Select sky colour (/0 for list of colours)\n"
- " /1:<col1>;<col2> - Select tile colours (/1 for list of colours)\n"
- " /p:<fname> - Load tile image from file (/p for details)"
- );
- }
-
-
-
- /* Terminate with error message */
-
- void Error(char * comment) {
- ScreenOff();
- printf("Error: %s\n", comment);
- exit(1);
- }
-
-
-
- /* Allocate memory for the arrays Tile, ScrBuffer, Distances, Blurs, Palette */
- /* The first three of these need to be aligned in memory, so a little extra */
- /* memory is allocated to them to make sure they fit the alignment */
-
- void AllocateMemory() {
- unsigned seg, off;
-
- /* Tile: far, aligned to segment boundary */
- Tile_alloc = (char far *) farmalloc(TILE_SIZE + 16);
- if ( Tile_alloc == NULL ) Error("Insufficient memory for Tile array");
- seg = FP_SEG(Tile_alloc) + (FP_OFF(Tile_alloc) >> 4) + 1;
- Tile = (char far *) MK_FP(seg, 0);
-
- /* ScrBuffer: far, aligned to segment boundary */
- ScrBuffer_alloc = (char far *) farmalloc(SCR_WIDTH*SCR_HEIGHT/2 + 16);
- if ( ScrBuffer_alloc == NULL ) Error("Insufficient memory for ScrBuffer array");
- seg = FP_SEG(ScrBuffer_alloc) + (FP_OFF(ScrBuffer_alloc) >> 4) + 1;
- ScrBuffer = (char far *) MK_FP(seg, 0);
-
- /* Distances: near, aligned to word boundary */
- Distances_alloc = (char *) malloc(sizeof(int)*SCR_HEIGHT/2 + 1);
- if ( Distances_alloc == NULL ) Error("Insufficient memory for Distances array");
- off = (unsigned) Distances_alloc;
- Distances = (int *) ( off + (off&1) );
-
- /* Blurs: near, non-aligned */
- Blurs = (unsigned char *) malloc(SCR_HEIGHT/2);
- if ( Blurs == NULL ) Error("Insufficient memory for Blurs array");
-
- /* Palette: near, non-aligned */
- Palette = (RGBvals *) malloc(256*sizeof(RGBvals));
- if ( Palette == NULL ) Error("Insufficient memory for Palette array");
-
- }
-
-
-
- /* Release the memory allocated by AllocateMemory() */
-
- void FreeMemory() {
- farfree(Tile_alloc);
- farfree(ScrBuffer_alloc);
- free(Distances_alloc);
- free(Blurs);
- free(Palette);
- }
-
-
-
- /* Generate the array of Distances */
- /* There is one value (a signed int/word) for each line of the image */
- /* The value is the distance of the middle point on the line from */
- /* the observer when projected down onto the plane of tiles */
- /* The values for the top two lines are bigger than 16 bits will store - */
- /* arbitrary large numbers are used instead since they make no difference */
-
- void MakeDistances() {
- int i;
- for ( i = 2 ; i < SCR_HEIGHT/2 ; i++ ) {
- /* Viewer's eye is taken to be height SCR_HEIGHT/2 above the plane */
- Distances[i] = ( VIEW_DIST * (long)SCR_HEIGHT / 2 ) / ( i + 0.5 );
- }
- Distances[0] = 32767;
- Distances[1] = 28000;
- }
-
-
-
- /* A Blur value is used for each line of the image on the screen */
- /* The Blur is the top 3 bits of an 8 bit number (greater than 63) */
- /* and is added to the points in the tile image to select which part of */
- /* the "blurred" palette is to be used */
- /* The bottom line of the image is unblurred, the top line very blurred */
-
- void MakeBlurs() {
- int i;
- int v;
- for ( i = 0 ; i < 100 ; i++ ) {
- /* The formula here was created through lots of trial and error */
- v = log( (double) 100.0 / (2+i+0.5) ) / log( (double) 2 );
- if ( v > 5 ) v = 5;
- Blurs[i] = ( 2 + v ) << 5;
- }
- }
-
-
-
- /* Parse the command line arguments */
- /* (Global variables updated) */
-
- #define TIMER_DEFAULT 120
-
- char * fmessage = "No filename given\n\n"
- " /p:<fname> - Load tile image from file\n"
- " where <fname>.BIN is a 256*256 bitmap using colours 0-31,\n"
- " <fname>.PAL is a 32 colour palette for the picture";
-
- void CommandArguments(int argc, char * argv[]) {
- int parm;
- char * start, * end;
- char err[80*25]; /* String for holding screen length error message */
-
- for ( parm = 1 ; parm < argc ; parm++ ) {
- if ( argv[parm][0] == '/' || argv[parm][0] == '-' ) {
- switch (argv[parm][1]) {
-
- /* "/t:delay" - set timer delay (in seconds) */
- /* 0 for no timer, 120 by default */
- case 't':
- case 'T':
- start = argv[parm] + 2;
- if ( *start == ':' ) start++;
- TimerDelay = TIMER_DEFAULT;
- if ( *start != '\0' ) {
- TimerDelay = atoi(start);
- if ( TimerDelay < 0 ) TimerDelay = 0;
- }
- break;
-
- /* "/s" - switch off end message */
- case 's':
- case 'S':
- StopMessage = 1;
- break;
-
- /* "/p:fname" - name file to load tile image from */
- case 'p':
- case 'P':
- start = argv[parm] + 2;
- if ( *start == ':' ) start++;
- PicFile = start;
- if ( *PicFile == '\0' ) Error(fmessage);
- break;
-
- /* "/0:colour" - choose sky colour (by colour name) */
- /* name prefix 'dark' specifies a dull sky */
- case '0':
- start = argv[parm]+2;
- if ( *start == ':' ) start++;
- if ( strnicmp(start, "dark", 4) == 0 ) {
- start += 4;
- DullSky = 1;
- } else DullSky = 0;
- end = ReadColour(&SkyColour, start);
- if ( *end != '\0' || end == start ) {
- sprintf(err, "Invalid sky colour selection %s\n\n", argv[parm]);
- ListSkyColours(err + strlen(err));
- Error(err);
- }
- break;
-
- /* "/1:col1;col2" - choose tile colours (by colour name) */
- case '1':
- start = argv[parm]+2;
- if ( *start == ':' ) start++;
- end = ReadColour(&TileColour1, start);
- if ( *end != ';' || end == start ) {
- sprintf(err, "Invalid tile colour selection %s\n\n", argv[parm]);
- ListTileColours(err + strlen(err));
- Error(err);
- }
- start = end+1;
- end = ReadColour(&TileColour2, start);
- if ( *end != '\0' || end == start ) {
- sprintf(err, "Invalid tile colour selection %s\n\n", argv[parm]);
- ListTileColours(err + strlen(err));
- Error(err);
- }
- break;
-
- default:
- sprintf(err, "Unrecognized command line argument %s", argv[parm]);
- Error(err);
- break;
-
- }
- } else {
- sprintf(err, "Unrecognized command line argument %s", argv[parm]);
- Error(err);
- }
- }
-
- }
-
-
-
- /* If not already selected, choose tile and sky colours */
- /* (Colour schemes used are defined in 'ScreenColour' table) */
-
- void ChooseColours() {
- int colour_set;
- char * start, * end;
-
- colour_set = random(101)%COLOUR_CHOICES;
-
- if ( TileColour1.red == -1 ) {
- start = ScreenColours[colour_set].tile1;
- end = ReadColour(&TileColour1, start);
- if ( *end != '\0' || end == start ) Error("Bad colour defined in ScreenColours table");
- }
-
- if ( TileColour2.red == -1 ) {
- start = ScreenColours[colour_set].tile2;
- end = ReadColour(&TileColour2, start);
- if ( *end != '\0' || end == start ) Error("Bad colour defined in ScreenColours table");
- }
-
- if ( SkyColour.red == -1 ) {
- start = ScreenColours[colour_set].sky;
- if ( strnicmp(start, "dark", 4) == 0 ) {
- start += 4;
- DullSky = 1;
- } else DullSky = 0;
- end = ReadColour(&SkyColour, start);
- if ( *end != '\0' || end == start ) Error("Bad colour defined in ScreenColours table");
- }
- }
-
-
-
- /* Set 'dest' to colour named in string */
- /* Return pointer to end of string if a match is found */
- /* (Names and values are defined in 'Colours' table) */
-
- char * ReadColour(RGBvals * dest, char * str) {
- int i;
-
- for ( i = 0 ; i < COLOURS ; i ++ ) {
- if ( strnicmp(str, Colours[i].name, strlen(Colours[i].name)) == 0 ) {
- dest->red = Colours[i].colour.red;
- dest->green = Colours[i].colour.green;
- dest->blue = Colours[i].colour.blue;
- return str + strlen(Colours[i].name);
- }
- }
-
- return str;
- }
-
-
-
- /* Add to end of string some text on how to select the sky colour */
-
- void ListSkyColours(char * dest) {
- int i, c=0;
-
- strcat(dest, "Set sky colour: \"/0:<colour>\"\n");
- strcat(dest, "\nColours:\n");
-
- for ( i = 0 ; i < COLOURS ; i++ ) {
- if ( strnicmp(Colours[i].name, "dark", 4) != 0 ) {
- if ( c > 60 ) {
- strcat(dest, "\n");
- c = 0;
- }
- strcat(dest, " ");
- strcat(dest, Colours[i].name);
- c += strlen(Colours[i].name) + 4;
- if ( c > 60 ) {
- strcat(dest, "\n");
- c = 0;
- }
- strcat(dest, " dark");
- strcat(dest, Colours[i].name);
- c += strlen(Colours[i].name) + 8;
- }
- }
-
- strcat(dest, "\n");
- }
-
-
-
- /* Add to end of string some text on how to select the tile colours */
-
- void ListTileColours(char * dest) {
- int i, c=0;
-
- strcat(dest, "Set tile colours: \"/1:<outside>;<inside>\"\n");
- strcat(dest, "\nColours:\n");
-
- for ( i = 0 ; i < COLOURS ; i++ ) {
- if ( c > 60 ) {
- strcat(dest, "\n");
- c = 0;
- }
- strcat(dest, " ");
- strcat(dest, Colours[i].name);
- c += strlen(Colours[i].name) + 4;
- }
-
- strcat(dest, "\n");
- }
-
-
-
- /* Fast sine calculation using precalculated table */
- /* Angles scaled from 0 to (ANGLES-1) around circle */
-
- float Sin(int a) {
- a = a & (ANGLES-1);
- return ( (float)AngleSines[a] / 32767.0 );
- }
-
-
-
- /* Fast cosine calculation using precalculated table */
- /* Angles scaled from 0 to (ANGLES-1) around circle */
-
- float Cos(int a) {
- a = ( a + ANGLES/4 ) & (ANGLES-1);
- return ( (float)AngleSines[a] / 32767.0 );
- }
-
-
-
-