![]() |
|
./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;
}
|