19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * testpalette.c 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * A simple test of runtime palette modification for animation 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * (using the SDL_SetPalette() API). 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdio.h> 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdlib.h> 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <string.h> 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <math.h> 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* This isn't in the Windows headers */ 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef M_PI 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define M_PI 3.14159265358979323846 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL.h" 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* screen size */ 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SCRW 640 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SCRH 480 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define NBOATS 5 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SPEED 2 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MIN 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MIN(a, b) ((a) < (b) ? (a) : (b)) 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef MAX 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define MAX(a, b) ((a) > (b) ? (a) : (b)) 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * wave colours: Made by taking a narrow cross-section of a wave picture 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * in Gimp, saving in PPM ascii format and formatting with Emacs macros. 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Color wavemap[] = { 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {0,2,103}, {0,7,110}, {0,13,117}, {0,19,125}, 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {0,25,133}, {0,31,141}, {0,37,150}, {0,43,158}, 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {0,49,166}, {0,55,174}, {0,61,182}, {0,67,190}, 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {0,73,198}, {0,79,206}, {0,86,214}, {0,96,220}, 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {5,105,224}, {12,112,226}, {19,120,227}, {26,128,229}, 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {33,135,230}, {40,143,232}, {47,150,234}, {54,158,236}, 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {61,165,238}, {68,173,239}, {75,180,241}, {82,188,242}, 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {89,195,244}, {96,203,246}, {103,210,248}, {112,218,250}, 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {124,224,250}, {135,226,251}, {146,229,251}, {156,231,252}, 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {167,233,252}, {178,236,252}, {189,238,252}, {200,240,252}, 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {211,242,252}, {222,244,252}, {233,247,252}, {242,249,252}, 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {237,250,252}, {209,251,252}, {174,251,252}, {138,252,252}, 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {102,251,252}, {63,250,252}, {24,243,252}, {7,225,252}, 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {4,203,252}, {3,181,252}, {2,158,252}, {1,136,251}, 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {0,111,248}, {0,82,234}, {0,63,213}, {0,50,192}, 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall {0,39,172}, {0,28,152}, {0,17,132}, {0,7,114} 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void quit(int rc) 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Quit(); 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall exit(rc); 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void sdlerr(char *when) 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "SDL error: %s: %s\n", when, SDL_GetError()); 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit(1); 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* create a background surface */ 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface *make_bg(SDL_Surface *screen, int startcol) 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *bg = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 8, 0, 0, 0, 0); 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(!bg) 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("creating background surface"); 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* set the palette to the logical screen palette so that blits 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall won't be translated */ 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetColors(bg, screen->format->palette->colors, 0, 256); 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Make a wavy background pattern using colours 0-63 */ 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(SDL_LockSurface(bg) < 0) 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("locking background"); 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(i = 0; i < SCRH; i++) { 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *p = (Uint8 *)bg->pixels + i * bg->pitch; 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int j, d; 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall d = 0; 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(j = 0; j < SCRW; j++) { 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int v = MAX(d, -2); 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall v = MIN(v, 2); 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(i > 0) 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall v += p[-bg->pitch] + 65 - startcol; 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall p[j] = startcol + (v & 63); 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall d += ((rand() >> 3) % 3) - 1; 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UnlockSurface(bg); 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(bg); 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Return a surface flipped horisontally. Only works for 8bpp; 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * extension to arbitrary bitness is left as an exercise for the reader. 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface *hflip(SDL_Surface *s) 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *z = SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, 8, 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0, 0, 0, 0); 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* copy palette */ 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetColors(z, s->format->palette->colors, 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 0, s->format->palette->ncolors); 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(SDL_LockSurface(s) < 0 || SDL_LockSurface(z) < 0) 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("locking flip images"); 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(i = 0; i < s->h; i++) { 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int j; 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *from = (Uint8 *)s->pixels + i * s->pitch; 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *to = (Uint8 *)z->pixels + i * z->pitch + s->w - 1; 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(j = 0; j < s->w; j++) 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall to[-j] = from[j]; 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UnlockSurface(z); 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UnlockSurface(s); 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return z; 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint main(int argc, char **argv) 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Color cmap[256]; 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *screen; 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *bg; 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *boat[2]; 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned vidflags = 0; 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned start; 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int fade_max = 400; 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int fade_level, fade_dir; 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int boatcols, frames, i, red; 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int boatx[NBOATS], boaty[NBOATS], boatdir[NBOATS]; 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int gamma_fade = 0; 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int gamma_ramp = 0; 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(SDL_Init(SDL_INIT_VIDEO) < 0) 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("initialising SDL"); 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(--argc) { 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ++argv; 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(strcmp(*argv, "-hw") == 0) 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vidflags |= SDL_HWSURFACE; 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if(strcmp(*argv, "-fullscreen") == 0) 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall vidflags |= SDL_FULLSCREEN; 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if(strcmp(*argv, "-nofade") == 0) 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fade_max = 1; 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if(strcmp(*argv, "-gamma") == 0) 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gamma_fade = 1; 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else if(strcmp(*argv, "-gammaramp") == 0) 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gamma_ramp = 1; 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "usage: testpalette " 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall " [-hw] [-fullscreen] [-nofade] [-gamma] [-gammaramp]\n"); 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit(1); 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Ask explicitly for 8bpp and a hardware palette */ 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if((screen = SDL_SetVideoMode(SCRW, SCRH, 8, vidflags | SDL_HWPALETTE)) == NULL) { 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "error setting %dx%d 8bpp indexed mode: %s\n", 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SCRW, SCRH, SDL_GetError()); 1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit(1); 1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (vidflags & SDL_FULLSCREEN) SDL_ShowCursor (SDL_FALSE); 1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if((boat[0] = SDL_LoadBMP("sail.bmp")) == NULL) 1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("loading sail.bmp"); 1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We've chosen magenta (#ff00ff) as colour key for the boat */ 1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetColorKey(boat[0], SDL_SRCCOLORKEY | SDL_RLEACCEL, 1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_MapRGB(boat[0]->format, 0xff, 0x00, 0xff)); 1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boatcols = boat[0]->format->palette->ncolors; 1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boat[1] = hflip(boat[0]); 1859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetColorKey(boat[1], SDL_SRCCOLORKEY | SDL_RLEACCEL, 1869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_MapRGB(boat[1]->format, 0xff, 0x00, 0xff)); 1879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 1899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * First set the physical screen palette to black, so the user won't 1909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * see our initial drawing on the screen. 1919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 1929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memset(cmap, 0, sizeof(cmap)); 1939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetPalette(screen, SDL_PHYSPAL, cmap, 0, 256); 1949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 1969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Proper palette management is important when playing games with the 1979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * colormap. We have divided the palette as follows: 1989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 1999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * index 0..(boatcols-1): used for the boat 2009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * index boatcols..(boatcols+63): used for the waves 2019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 2029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetPalette(screen, SDL_LOGPAL, 2039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boat[0]->format->palette->colors, 0, boatcols); 2049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetPalette(screen, SDL_LOGPAL, wavemap, boatcols, 64); 2059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* 2079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Now the logical screen palette is set, and will remain unchanged. 2089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * The boats already have the same palette so fast blits can be used. 2099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 2109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memcpy(cmap, screen->format->palette->colors, 256 * sizeof(SDL_Color)); 2119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* save the index of the red colour for later */ 2139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall red = SDL_MapRGB(screen->format, 0xff, 0x00, 0x00); 2149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bg = make_bg(screen, boatcols); /* make a nice wavy background surface */ 2169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* initial screen contents */ 2189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(SDL_BlitSurface(bg, NULL, screen, NULL) < 0) 2199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("blitting background to screen"); 2209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Flip(screen); /* actually put the background on screen */ 2219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* determine initial boat placements */ 2239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(i = 0; i < NBOATS; i++) { 2249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boatx[i] = (rand() % (SCRW + boat[0]->w)) - boat[0]->w; 2259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boaty[i] = i * (SCRH - boat[0]->h) / (NBOATS - 1); 2269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boatdir[i] = ((rand() >> 5) & 1) * 2 - 1; 2279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall start = SDL_GetTicks(); 2309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall frames = 0; 2319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fade_dir = 1; 2329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fade_level = 0; 2339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall do { 2349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Event e; 2359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Rect updates[NBOATS]; 2369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Rect r; 2379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int redphase; 2389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* A small event loop: just exit on any key or mouse button event */ 2409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while(SDL_PollEvent(&e)) { 2419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(e.type == SDL_KEYDOWN || e.type == SDL_QUIT 2429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall || e.type == SDL_MOUSEBUTTONDOWN) { 2439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(fade_dir < 0) 2449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fade_level = 0; 2459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fade_dir = -1; 2469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* move boats */ 2509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(i = 0; i < NBOATS; i++) { 2519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int old_x = boatx[i]; 2529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* update boat position */ 2539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boatx[i] += boatdir[i] * SPEED; 2549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(boatx[i] <= -boat[0]->w || boatx[i] >= SCRW) 2559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boatdir[i] = -boatdir[i]; 2569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* paint over the old boat position */ 2589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r.x = old_x; 2599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r.y = boaty[i]; 2609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r.w = boat[0]->w; 2619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r.h = boat[0]->h; 2629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(SDL_BlitSurface(bg, &r, screen, &r) < 0) 2639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("blitting background"); 2649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* construct update rectangle (bounding box of old and new pos) */ 2669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall updates[i].x = MIN(old_x, boatx[i]); 2679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall updates[i].y = boaty[i]; 2689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall updates[i].w = boat[0]->w + SPEED; 2699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall updates[i].h = boat[0]->h; 2709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* clip update rectangle to screen */ 2719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(updates[i].x < 0) { 2729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall updates[i].w += updates[i].x; 2739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall updates[i].x = 0; 2749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(updates[i].x + updates[i].w > SCRW) 2769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall updates[i].w = SCRW - updates[i].x; 2779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(i = 0; i < NBOATS; i++) { 2809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* paint boat on new position */ 2819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r.x = boatx[i]; 2829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall r.y = boaty[i]; 2839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(SDL_BlitSurface(boat[(boatdir[i] + 1) / 2], NULL, 2849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall screen, &r) < 0) 2859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("blitting boat"); 2869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* cycle wave palette */ 2899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(i = 0; i < 64; i++) 2909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap[boatcols + ((i + frames) & 63)] = wavemap[i]; 2919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(fade_dir) { 2939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade the entire palette in/out */ 2949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fade_level += fade_dir; 2959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(gamma_fade) { 2979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade linearly in gamma level (lousy) */ 2989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall float level = (float)fade_level / fade_max; 2999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(SDL_SetGamma(level, level, level) < 0) 3009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("setting gamma"); 3019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else if(gamma_ramp) { 3039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade using gamma ramp (better) */ 3049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 ramp[256]; 3059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(i = 0; i < 256; i++) 3069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ramp[i] = (i * fade_level / fade_max) << 8; 3079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(SDL_SetGammaRamp(ramp, ramp, ramp) < 0) 3089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sdlerr("setting gamma ramp"); 3099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 3119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Fade using direct palette manipulation (best) */ 3129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memcpy(cmap, screen->format->palette->colors, 3139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall boatcols * sizeof(SDL_Color)); 3149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for(i = 0; i < boatcols + 64; i++) { 3159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap[i].r = cmap[i].r * fade_level / fade_max; 3169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap[i].g = cmap[i].g * fade_level / fade_max; 3179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap[i].b = cmap[i].b * fade_level / fade_max; 3189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if(fade_level == fade_max) 3219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fade_dir = 0; 3229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* pulse the red colour (done after the fade, for a night effect) */ 3259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall redphase = frames % 64; 3269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cmap[red].r = (int)(255 * sin(redphase * M_PI / 63)); 3279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetPalette(screen, SDL_PHYSPAL, cmap, 0, boatcols + 64); 3299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* update changed areas of the screen */ 3319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UpdateRects(screen, NBOATS, updates); 3329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall frames++; 3339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } while(fade_level > 0); 3349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf("%d frames, %.2f fps\n", 3369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall frames, 1000.0 * frames / (SDL_GetTicks() - start)); 3379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (vidflags & SDL_FULLSCREEN) SDL_ShowCursor (SDL_TRUE); 3399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Quit(); 3409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 3419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 3429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 343