19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Simple program: Create a blank window, wait for keypress, quit. 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Please see the SDL documentation for details on using the SDL API: 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /Developer/Documentation/SDL/docs.html 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#include "SDL.h" 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallextern void Atlantis_Init (); 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallextern void Atlantis_Reshape (int w, int h); 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallextern void Atlantis_Animate (); 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallextern void Atlantis_Display (); 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_Surface *gScreen; 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void initAttributes () 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Setup attributes we want for the OpenGL context 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int value; 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Don't set color bit sizes (SDL_GL_RED_SIZE, etc) 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Mac OS X will always use 8-8-8-8 ARGB for 32-bit screens and 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // 5-5-5 RGB for 16-bit screens 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Request a 16-bit depth buffer (without this, there is no depth buffer) 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall value = 16; 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, value); 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Request double-buffered OpenGL 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // The fact that windows are double-buffered on Mac OS X has no effect 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // on OpenGL double buffering. 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall value = 1; 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, value); 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void printAttributes () 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Print out attributes of the context we created 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int nAttr; 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i; 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int attr[] = { SDL_GL_RED_SIZE, SDL_GL_BLUE_SIZE, SDL_GL_GREEN_SIZE, 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GL_ALPHA_SIZE, SDL_GL_BUFFER_SIZE, SDL_GL_DEPTH_SIZE }; 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall char *desc[] = { "Red size: %d bits\n", "Blue size: %d bits\n", "Green size: %d bits\n", 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "Alpha size: %d bits\n", "Color buffer size: %d bits\n", 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "Depth bufer size: %d bits\n" }; 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nAttr = sizeof(attr) / sizeof(int); 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < nAttr; i++) { 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int value; 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GL_GetAttribute (attr[i], &value); 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printf (desc[i], value); 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void createSurface (int fullscreen) 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 flags = 0; 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flags = SDL_OPENGL; 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (fullscreen) 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall flags |= SDL_FULLSCREEN; 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Create window 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gScreen = SDL_SetVideoMode (640, 480, 0, flags); 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (gScreen == NULL) { 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf (stderr, "Couldn't set 640x480 OpenGL video mode: %s\n", 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GetError()); 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Quit(); 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall exit(2); 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void initGL () 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Atlantis_Init (); 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Atlantis_Reshape (gScreen->w, gScreen->h); 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void drawGL () 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Atlantis_Animate (); 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Atlantis_Display (); 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void mainLoop () 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Event event; 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int done = 0; 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int fps = 24; 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int delay = 1000/fps; 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int thenTicks = -1; 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int nowTicks; 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( !done ) { 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check for events */ 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( SDL_PollEvent (&event) ) { 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (event.type) { 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_MOUSEMOTION: 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_MOUSEBUTTONDOWN: 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_KEYDOWN: 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Any keypress quits the app... */ 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_QUIT: 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall done = 1; 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Draw at 24 hz 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // This approach is not normally recommended - it is better to 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // use time-based animation and run as fast as possible 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall drawGL (); 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GL_SwapBuffers (); 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Time how long each draw-swap-delay cycle takes 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // and adjust delay to get closer to target framerate 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (thenTicks > 0) { 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall nowTicks = SDL_GetTicks (); 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall delay += (1000/fps - (nowTicks-thenTicks)); 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall thenTicks = nowTicks; 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (delay < 0) 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall delay = 1000/fps; 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else { 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall thenTicks = SDL_GetTicks (); 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Delay (delay); 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint main(int argc, char *argv[]) 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Init SDL video subsystem 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_Init (SDL_INIT_VIDEO) < 0 ) { 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Couldn't initialize SDL: %s\n", 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GetError()); 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall exit(1); 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Set GL context attributes 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall initAttributes (); 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Create GL context 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall createSurface (0); 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Get GL context attributes 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall printAttributes (); 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Init GL state 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall initGL (); 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Draw, get events... 1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mainLoop (); 1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // Cleanup 1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Quit(); 1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 180