|
./configure;make;make install |
-mwindows -lmingw32 -lopengl32 -lglu32 -lglaux -lSDLmain -lSDL -lSDL_ttf |
#include <SDL.h> #include <SDL_ttf.h> #include <SDL_audio.h> |
INCS = -I/usr/include/SDL LIBS = -L/usr/lib64/GL -L/usr/lib64/SDL -lSDL -lSDL_ttf -lGL -lGLU |
AC_CHECK_LIB([GL], [glEnable]) AC_CHECK_LIB([GLU], [gluLookAt]) AC_CHECK_LIB([SDL], [SDL_Init]) AC_CHECK_LIB([SDL_ttf], [TTF_Init]) |
if(SDL_Init(SDL_INIT_VIDEO| SDL_INIT_TIMER | SDL_INIT_AUDIO)<0) // Init The SDL Library, The VIDEO, AUDIO, TIMER Subsystem { Log("Unable to open SDL: %s\n", SDL_GetError() ); // If SDL Can't Be Initialized exit(1); // Get Out Of Here. Sorry. } atexit(SDL_Quit)// SDL's Been init, Now We're Making Sure Thet SDL_Quit Will Be Called In Case of exit() |
void TerminateApplication() // Terminate The Application { static SDL_Event Q; // We're Sending A SDL_QUIT Event Q.type = SDL_QUIT; // To The SDL Event Queue if(SDL_PushEvent(&Q) == -1) // Try Send The Event { Log("SDL_QUIT event can't be pushed: %s\n", SDL_GetError() ); // And Eventually Report Errors exit(1); // And Exit } } |
SDL_Surface *Screen; //SDL screen structure |
BOOL CreateWindowGL(int W, int H, int B, Uint32 F) // This Code Creates Our OpenGL Window { SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); // In order to use SDL_OPENGLBLIT we have to SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); // set GL attributes first SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // colors and doublebuffering if(!(Screen = SDL_SetVideoMode(W, H, B, F))) // We're Using SDL_SetVideoMode To Create The Window return false; // If It Fails, We're Returning False SDL_FillRect(Screen, NULL, SDL_MapRGBA(Screen->format,0,0,0,0)); // A key event! We have to open the Screen Alpha Channel! ... Vflags = SDL_HWSURFACE|SDL_OPENGLBLIT| SDL_FULLSCREEN; // We Want A Hardware Surface And Special OpenGLBlit Mode ... CreateWindowGL(SCREEN_W, SCREEN_H, SCREEN_BPP, Vflags); ... |
Desktop = SDL_GetVideoInfo(); Screen_W = Desktop->current_w; Screen_H = Desktop->current_h; for(bpp = 32; bpp > 8; bpp -= 8) { Screen = SDL_SetVideoMode(Screen_W , Screen_H , bpp, Vflags); if(Screen != NULL) { Screen_BPP = bpp; break; } } |
int modes[][2] = { {2048,1152}, {1920, 1200}, {1600, 1200}, {1280, 1024}, {1280, 768}, {1280, 720}, {1024, 768}, {1024, 600}, {800, 600}, {720, 576}, {720, 480}, {640, 480} }; ... #if ((SDL_MAJOR_VERSION > 1) || (SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION > 2) || (SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL > 9)) //SDL version > 1.3.10, get video info and hunt for pixel depth ... #else Log("libSDL v.%d.%d.%d doesn't support SDL_GetVideoInfo(), testing video modes... \n",SDL_MAJOR_VERSION, SDL_MINOR_VERSION,SDL_PATCHLEVEL); // Hunt for video modes while((Screen == NULL) && (n < 12)) { for(bpp = 32; bpp > 8; bpp -= 8) { Screen = SDL_SetVideoMode(modes[n][0], modes[n][1], bpp, Vflags); if(Screen != NULL) { Screen_W = modes[n][0]; Screen_H = modes[n][1]; Screen_BPP = bpp; break; } } n++; } #endif |
SDL_Event E; |
typedef struct {//mouse struct int x; int y; BOOL leftclick; } mousecntl;// We Call It mousecntl Uint8 *keys;// A Pointer To An Array That Will Contain The Keyboard Snapshot |
while(looping == TRUE)// And While It's looping { if(SDL_PollEvent(&E))// We're Fetching The First Event Of The Queue { switch(E.type)// And Processing It { . . . case SDL_KEYDOWN:// Someone Has Pressed A Key? keys = SDL_GetKeyState(NULL);//Take A SnapShot Of The Keyboard break;// And Break; case SDL_MOUSEMOTION: mouse.x = E.motion.x; mouse.y = E.motion.y; break; case SDL_MOUSEBUTTONDOWN: mouse.leftclick = TRUE;//we are firing break; case SDL_MOUSEBUTTONUP://we stopped firing mouse.leftclick = FALSE; break; default:break; } } else// No Events To Poll? (SDL_PollEvent()==0?) { . . . //the real game core . . . |
enum {//all bitmaps enumerated BMP_BG_1, BMP_BG_2, BMP_BG_3, BMP_BG_4, ... N_BMP }; const char * Bmp_files[N_BMP] = { "arka1", "arka2", "arka3", "arka4", ... }; |
SDL_Surface Texture[N_BMP]; |
for(i = 0; i < N_BMP;i++) { sprintf(filename, "./textures/%s.bmp", Bmp_files[i]); Texture[i] = *SDL_LoadBMP(filename); |
SDL_SetColorKey(&(Texture[i]), SDL_SRCCOLORKEY|SDL_RLEACCEL,SDL_MapRGB(Texture[i].format, 0, 0, 0) ); |
void ready_display(SDL_Surface * window) { static SDL_Rect logo_rect={0,0,0,0}; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_FillRect(window, &logo_rect, SDL_MapRGBA(window->format,0,0,0,0)); logo_rect.w = (Sint16)Texture[BMP_LOGO].w; logo_rect.h = (Sint16)Texture[BMP_LOGO].h; logo_rect.y = 100; logo_rect.x = 200; SDL_BlitSurface(&(Texture[BMP_LOGO]), NULL, window, &logo_rect);// And finally blit and update SDL_UpdateRects(window, 1, &logo_rect); } |
if ( (Texture[i].w & (Texture[i].w - 1)) != 0 ) Log("warning: image.bmp's width is not a power of 2\n"); if ( (Texture[i].h & (Texture[i].h - 1)) != 0 ) Log("warning: image.bmp's height is not a power of 2\n"); |
bpp = Texture[i].format->BytesPerPixel; if (bpp == 4) // contains an alpha channel { if (Texture[i].format->Rmask == 0x000000ff) texture_format = GL_RGBA; else texture_format = GL_BGRA; } else if (bpp == 3) // no alpha channel { if (Texture[i].format->Rmask == 0x000000ff) texture_format = GL_RGB; else texture_format = GL_BGR; } else { Log("warning: the image is not truecolor.. this will probably break\n"); // this error should not go unhandled } |
glTexImage2D(GL_TEXTURE_2D, 0, bpp, Texture[i].w, Texture[i].h, 0, texture_format, GL_UNSIGNED_BYTE, Texture[i].pixels); |
// Compute the next power of two: 2^i < x <= 2^(i+1) = y int nextpoweroftwo(int x) { double y; y = pow(2, ceil(log(x) / log(2))); return (int)y; } |
void pills::display() { extern unsigned int Font_Size; if(active) { GLUquadricObj * base = gluNewQuadric(); glPushMatrix(); glEnable(GL_TEXTURE_2D); glColor3f(col.x, col.y, col.z); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTranslatef(place.x,place.y, place.z); gluQuadricTexture(base, GL_TRUE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Font_Size, Font_Size, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);//An SDL_Surface where the pill texture gets rendered //from TTF_RenderText glPushMatrix(); glPushMatrix(); glRotatef(rotx, -1.0f, 0.0f, 0.0f); glRotatef(90.0f, 0.0f, 1.0f, 0.0f); glMatrixMode(GL_TEXTURE); glPushMatrix(); glTranslatef(len/2, 0.0f, 0.0f); glRotatef(90.0f, 0.0f, 0.0f, 1.0f); glRotatef(180.0f, 1.0f, 0.0f, 0.0f); gluCylinder(base, rad, rad, len, 12, 12); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glColor3f(col.x, col.y, col.z); glDisable(GL_TEXTURE_2D); glPushMatrix(); glTranslatef(0, 0.0f, 0.0f); gluSphere(base, rad, 12, 12); glPopMatrix(); glPushMatrix(); glTranslatef(len, 0.0f, 0.0f); gluSphere(base, rad, 12, 12); glPopMatrix(); glPopMatrix(); glPopMatrix(); } } |
if (TTF_Init() == -1)//init TTF { Log(TTF_GetError()); Log(":Unable to initialize SDL_ttf\n"); return FALSE; } |
TTF_Font *DejaVuSans; DejaVuSans = TTF_OpenFont("DejaVuSans.ttf", size); |
SDL_Color white = {255,255,255,128}; |
typedef struct { SDL_Surface *T; SDL_Rect src; char msg[MAXLINE]; }text2d; |
void printText(SDL_Surface *S, text2d * text, int x, int y, char * buf, ...) {//print a c formatted string @ x, y extern TTF_Font *DejaVuSans; extern SDL_Color white;// = {255,255,255,128}; va_list Arg;// We're Using The Same As The printf() Family, A va_list // To Substitute The Tokens Like %s With Their Value In The Output va_start(Arg, buf); // We Start The List vsprintf(text->msg,buf, Arg); va_end(Arg); // We End The List text->T = TTF_RenderText_Solid(DejaVuSans,text->msg,white); text->src.w = text->T->w; text->src.h = text->T->h; text->src.x = x; text->src.y = y; } |
// Draw SDL_ttf rendered text to an OpenGL texture void DrawOpenGLText(text2d* text) { SDL_Surface *s, *p; int h, w; float xx, yy; p = text->T; w = nextpoweroftwo(p->w); h = nextpoweroftwo(p->h); xx = SCENE_MIN + 2 * SCENE_MAX * text->src.x / Screen_W; yy = -SCENE_MIN + 2 * SCENE_MAX * text->src.y / Screen_H; s = SDL_CreateRGBSurface(p->flags, w, h, Screen_BPP, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); SDL_SetColorKey(s, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGBA(s->format, 0, 0, 0, 0)); SDL_BlitSurface(p, 0, s, 0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, TextureID[N_BMP]);//use warp ID + 1 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, s->pixels); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2f(1.0f, 1.0f); glVertex3f(xx + Font_Size * w / Screen_W, yy - Font_Size * h / Screen_H, -SCENE_AIR); glTexCoord2f(1.0f, 0.0f); glVertex3f(xx + Font_Size * w / Screen_W, yy, -SCENE_AIR); glTexCoord2f(0.0f, 0.0f); glVertex3f(xx, yy, -SCENE_AIR); glTexCoord2f(0.0f, 1.0f); glVertex3f(xx, yy - Font_Size * h / Screen_H, -SCENE_AIR); glEnd(); glDisable(GL_TEXTURE_2D); SDL_FreeSurface(s); } |
SDL_AudioSpec Audio; //Our very own audio format specification ... /* Set 16-bit stereo audio at 22Khz */ Audio.freq = 22050; Audio.format = AUDIO_S16; Audio.channels = 2; Audio.samples = 512; Audio.callback = mixer; Audio.userdata = NULL; |
if ( SDL_OpenAudio(&Audio, NULL) &t; 0 ) { Log( "Unable to open audio: %s\n", SDL_GetError()); exit(1); } SDL_PauseAudio(0);//start playing whatever gets in the buffers |
struct sample { Uint8 *data; Uint32 dpos; Uint32 dlen; } Soundbuffer[NUM_BUFFERS]; /*sound buffers: Standard SDL only works with double buffering, therefore NUM_BUFFERS = 2*/ |
enum {//all sounds WAV_ALIEN, WAV_BOUNCE0, WAV_BOUNCE1, WAV_ENLARGE, WAV_GO, WAV_INTRO, ... N_WAV }; const char * Wav_files[N_WAV] = { "alien", "bounce0", "bounce1", "enlarge", "go", "intro", ... |
int loadSounds() { int i; char filename[MAXLINE]; Uint8 *data; Uint32 dlen; extern SDL_AudioSpec Audio; extern SDL_AudioCVT Wave[N_WAV]; for(i = 0; i < N_WAV; i++) {// Load the sound file and convert it to 16-bit stereo at 22kHz sprintf(filename, "./sounds/%s.wav", Wav_files[i]); if ( SDL_LoadWAV(filename, &Audio, &data, &dlen) == NULL ) { Log( "Couldn't load %s: %s\n", filename, SDL_GetError()); return FALSE; } SDL_BuildAudioCVT(&(Wave[i]), Audio.format, Audio.channels, Audio.freq, AUDIO_S16, 2, 22050); Wave[i].buf = (Uint8*)malloc(dlen*Wave[i].len_mult); memcpy(Wave[i].buf, data, dlen); Wave[i].len = dlen; SDL_ConvertAudio(&Wave[i]); SDL_FreeWAV(data); } return TRUE; } |
BOOL PlaySDLSound(int wavidx) { int index; Uint8 *data; Uint32 dlen; // Look for an empty (or finished) sound slot for ( index=0; index < NUM_BUFFERS; ++index ) { if ( Soundbuffer[index].dpos == Soundbuffer[index].dlen ) break; //found } if ( index == NUM_BUFFERS ) return FALSE; //failed, buffer is full //our available waves are already converted since loading time // Put the sound data in the slot (it starts playing immediately) Soundbuffer[index].data = Wave[wavidx].buf; Soundbuffer[index].dlen = Wave[wavidx].len_cvt; Soundbuffer[index].dpos = 0; return TRUE; } |
void mixer(void *udata, Uint8 *stream, int len) {//mixes maximum len bytes from the sound channels onto the stream int i; Uint32 amount;//how much is left from a sound to play? for ( i=0; i < NUM_BUFFERS; ++i ) { amount = (Soundbuffer[i].dlen-Soundbuffer[i].dpos); if ( amount > len ) amount = len; //amount cannot be more than len SDL_MixAudio(stream, &Soundbuffer[i].data[Soundbuffer[i].dpos], amount, SDL_MIX_MAXVOLUME); Soundbuffer[i].dpos += amount; } } |
double minmspf = 40; // = 1000/fps ... while(looping == TRUE) // And While It's looping { ... toc = SDL_GetTicks(); // Get Present Ticks Update(toc-tic, keys, &mouse); // And Update The Motions And Data //toc - tic is milliseconds per frame //from this we calculate the motion smoothing factor ms10 (moving average ms in last 10 frames) ms10 = moving_average(toc-tic,msperframe,10); delay = minmspf - toc+tic; if(delay > 0) { SDL_Delay(delay); } tic = toc; ... } |
animate() { ... //animate x += speedx * ms10*minmspf/1000;// max FPS ... |
double moving_average(double x, double * a, int size) {//moving average of 10 (size) samples, a must be allocated with size values int i; double sum = x; for(i = size-1;i>0;i--) { a[i] = a[i-1]; sum += a[i]; } a[0] = x; return sum/size; } |