00001
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028
00029 #include <SDL/SDL.h>
00030 #include <SDL/SDL_thread.h>
00031 #include <SDL/SDL_mixer.h>
00032
00033 #ifdef GAMEMOD
00034 #include <SDL/SDL_ttf.h>
00035 #endif
00036
00037 #include "sdlengine.h"
00038 #include "main.h"
00039 #include "images.h"
00040 #include "music.h"
00041 #include "lbaengine.h"
00042 #include "debug.h"
00043
00045 static void atexit_callback(void);
00046
00048 #define ORIGINAL_GAME_FREQUENCY 11025
00049
00050 #define HIGH_QUALITY_FREQUENCY 44100
00051
00053 SDL_Surface *screen=NULL;
00055 SDL_Surface *screenBuffer=NULL;
00057 SDL_Color screenColors[256];
00059 SDL_Surface *surfaceTable[16];
00060
00061
00063 short int skipedKey;
00065 short int pressedKey;
00066
00068 short int skipIntro;
00070 short int currentKey;
00072 short int key;
00073
00074 #ifdef GAMEMOD
00075 TTF_Font *font;
00076 #endif
00077
00079 static void atexit_callback(void)
00080 {
00081 stop_track_music();
00082 stop_midi_music();
00083 Mix_CloseAudio();
00084 SDL_Quit();
00085 }
00086
00088 void sdl_close()
00089 {
00090 stop_track_music();
00091 stop_midi_music();
00092 atexit(atexit_callback);
00093 }
00094
00097 int sdl_initialize()
00098 {
00099 unsigned char *keyboard;
00100 int size;
00101 int i;
00102 int freq;
00103
00104
00105 Uint32 rmask, gmask, bmask, amask;
00106
00107 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00108 rmask = 0xff000000;
00109 gmask = 0x00ff0000;
00110 bmask = 0x0000ff00;
00111 amask = 0x000000ff;
00112 #else
00113 rmask = 0x000000ff;
00114 gmask = 0x0000ff00;
00115 bmask = 0x00ff0000;
00116 amask = 0xff000000;
00117 #endif
00118
00119 if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
00120 {
00121 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
00122 exit(1);
00123 }
00124
00125 #ifdef GAMEMOD
00126 if (TTF_Init() < 0)
00127 {
00128 fprintf(stderr, "Couldn't initialize TTF: %s\n", SDL_GetError());
00129 exit(1);
00130 }
00131 atexit(TTF_Quit);
00132
00133 font = TTF_OpenFont("verdana.ttf", 12);
00134
00135 if (font == NULL)
00136 {
00137 fprintf(stderr, "Couldn't load %d pt font from %s: %s\n", 12, "verdana.ttf", SDL_GetError());
00138 exit(2);
00139 }
00140
00141 TTF_SetFontStyle(font, 0);
00142 #endif
00143
00144
00145
00146
00147
00148 if(cfgfile.Debug)
00149 {
00150 SDL_version compile_version;
00151 const SDL_version *link_version;
00152 SDL_VERSION(&compile_version);
00153 printf("Compiled with SDL version: %d.%d.%d\n", compile_version.major, compile_version.minor, compile_version.patch);
00154 link_version = SDL_Linked_Version();
00155 printf("Running with SDL version: %d.%d.%d\n\n", link_version->major, link_version->minor, link_version->patch);
00156 }
00157
00158 sdl_close();
00159
00160 printf("Initialising SDL device. Please wait...\n");
00161
00162
00163 if(cfgfile.UseHQSnd)
00164 freq = HIGH_QUALITY_FREQUENCY;
00165 else
00166 freq = ORIGINAL_GAME_FREQUENCY;
00167
00168 if(Mix_OpenAudio(freq, AUDIO_S16, 2, 4096) < 0)
00169 {
00170 printf("Mix_OpenAudio: %s\n", Mix_GetError());
00171 exit(1);
00172 }
00173
00174 printf("Initialising Sound device. Please wait...\n\n");
00175
00176 SDL_WM_SetCaption("Prequengine: a Little Big Adventure engine", "LBAPrequel");
00177 SDL_PumpEvents();
00178
00179 keyboard = SDL_GetKeyState(&size);
00180
00181 keyboard[SDLK_RETURN] = 0;
00182
00183 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE);
00184
00185 if (screen == NULL)
00186 {
00187 fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n\n", SDL_GetError());
00188 exit(1);
00189 }
00190
00191 for (i = 0; i < 16; i++)
00192 {
00193 surfaceTable[i] = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 32, rmask, gmask, bmask, 0);
00194 }
00195
00196 return 0;
00197 }
00198
00201 void fps_cycles(int fps)
00202 {
00203 SDL_Delay(1000 / (fps));
00204 lbaTime++;
00205 }
00206
00209 void delay(unsigned int time)
00210 {
00211 unsigned int startTicks = SDL_GetTicks();
00212 unsigned int stopTicks=0;
00213 skipIntro = 0;
00214 do
00215 {
00216 read_keys();
00217 if(skipIntro==1)
00218 break;
00219 stopTicks = SDL_GetTicks()-startTicks;
00220 SDL_Delay(1);
00221 lbaTime++;
00222 }while(stopTicks <= time);
00223 }
00224
00227 void set_palette(unsigned char * palette)
00228 {
00229 SDL_Color *screenColorsTemp = (SDL_Color *) palette;
00230
00231 SDL_SetColors(screenBuffer, screenColorsTemp, 0, 256);
00232 SDL_BlitSurface(screenBuffer, NULL, screen, NULL);
00233 SDL_UpdateRect(screen, 0, 0, 0, 0);
00234 }
00235
00237 void fade_black_2_white()
00238 {
00239 int i;
00240
00241 SDL_Color colorPtr[256];
00242
00243 SDL_UpdateRect(screen, 0, 0, 0, 0);
00244
00245 for (i = 0; i < 256; i += 3)
00246 {
00247 memset(colorPtr, i, 1024);
00248 SDL_SetPalette(screen, SDL_PHYSPAL, colorPtr, 0, 256);
00249 }
00250 }
00251
00253 void flip()
00254 {
00255 SDL_BlitSurface(screenBuffer, NULL, screen, NULL);
00256 SDL_UpdateRect(screen, 0, 0, 0, 0);
00257 }
00258
00264 void copy_block_phys(int left, int top, int right, int bottom)
00265 {
00266 SDL_Rect rectangle;
00267
00268 rectangle.x = left;
00269 rectangle.y = top;
00270 rectangle.w = right - left +1 ;
00271 rectangle.h = bottom - top +1 ;
00272
00273 SDL_BlitSurface(screenBuffer, &rectangle, screen, &rectangle);
00274 SDL_UpdateRect(screen, left, top, right - left +1, bottom - top+1);
00275 }
00276
00281 void init_screen_buffer(unsigned char *buffer, int width, int height)
00282 {
00283 screenBuffer = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8, SCREEN_WIDTH, 0, 0, 0, 0);
00284 }
00285
00289 void cross_fade(unsigned char *buffer, unsigned char *palette)
00290 {
00291 int i;
00292 SDL_Surface *backupSurface;
00293 SDL_Surface *newSurface;
00294 SDL_Surface *tempSurface;
00295 Uint32 rmask, gmask, bmask, amask;
00296
00297 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00298 rmask = 0xff000000;
00299 gmask = 0x00ff0000;
00300 bmask = 0x0000ff00;
00301 amask = 0x000000ff;
00302 #else
00303 rmask = 0x000000ff;
00304 gmask = 0x0000ff00;
00305 bmask = 0x00ff0000;
00306 amask = 0xff000000;
00307 #endif
00308
00309 backupSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 32, rmask, gmask, bmask, 0);
00310 newSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, SCREEN_WIDTH, SCREEN_HEIGHT, 32, rmask, gmask, bmask, 0);
00311
00312 tempSurface = SDL_CreateRGBSurfaceFrom(buffer, SCREEN_WIDTH, SCREEN_HEIGHT, 8, SCREEN_WIDTH, 0, 0, 0, 0);
00313 SDL_SetColors(tempSurface, (SDL_Color *) palette, 0, 256);
00314
00315 SDL_BlitSurface(screen, NULL, backupSurface, NULL);
00316 SDL_BlitSurface(tempSurface, NULL, newSurface, NULL);
00317
00318 for (i = 0; i < 8; i++)
00319 {
00320 SDL_BlitSurface(backupSurface, NULL, surfaceTable[i], NULL);
00321 SDL_SetAlpha(newSurface, SDL_SRCALPHA | SDL_RLEACCEL, i * 32);
00322 SDL_BlitSurface(newSurface, NULL, surfaceTable[i], NULL);
00323 SDL_BlitSurface(surfaceTable[i], NULL, screen, NULL);
00324 SDL_UpdateRect(screen, 0, 0, 0, 0);
00325 delay(50);
00326 }
00327
00328 SDL_BlitSurface(newSurface, NULL, screen, NULL);
00329 SDL_UpdateRect(screen, 0, 0, 0, 0);
00330
00331 SDL_FreeSurface(backupSurface);
00332 SDL_FreeSurface(newSurface);
00333 SDL_FreeSurface(tempSurface);
00334 }
00335
00337 void toggle_fullscreen()
00338 {
00339 cfgfile.FullScreen = 1 - cfgfile.FullScreen;
00340 SDL_FreeSurface(screen);
00341
00342 if (cfgfile.FullScreen)
00343 {
00344 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE);
00345 copy_screen(workVideoBuffer, frontVideoBuffer);
00346 convert_pal_2_RGBA(palette, paletteRGBA);
00347 set_palette((unsigned char*)paletteRGBA);
00348 SDL_ShowCursor(1);
00349 }
00350 else
00351 {
00352 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE|SDL_FULLSCREEN);
00353 copy_screen(workVideoBuffer, frontVideoBuffer);
00354 convert_pal_2_RGBA(palette, paletteRGBA);
00355 set_palette((unsigned char*)paletteRGBA);
00356 SDL_ShowCursor(0);
00357 }
00358 }
00359
00361 void read_keys()
00362 {
00363 SDL_Event event;
00364 int localKey;
00365 int i,j, size;
00366 int find = 0;
00367 short int temp;
00368 unsigned char temp2;
00369 char found = 0;
00370 unsigned char *keyboard;
00371
00372 localKey = 0;
00373
00374 pressedKey = 0;
00375 skipedKey = 0;
00376 skipIntro = 0;
00377
00378 SDL_PumpEvents();
00379
00380 keyboard = SDL_GetKeyState(&size);
00381
00382 for (j = 0; j < size; j++)
00383 {
00384 if (keyboard[j])
00385 {
00386 switch (j)
00387 {
00388 case SDLK_SPACE:
00389 localKey = 0x39;
00390 break;
00391 case SDLK_UP:
00392 case SDLK_KP8:
00393 localKey = 0x48;
00394 break;
00395 case SDLK_DOWN:
00396 case SDLK_KP2:
00397 localKey = 0x50;
00398 break;
00399 case SDLK_LEFT:
00400 case SDLK_KP4:
00401 localKey = 0x4B;
00402 break;
00403 case SDLK_RIGHT:
00404 case SDLK_KP6:
00405 localKey = 0x4D;
00406 break;
00407 #ifdef GAMEMOD
00408
00409 case SDLK_s:
00410 localKey = 's';
00411 break;
00412 case SDLK_x:
00413 localKey = 'x';
00414 break;
00415 case SDLK_z:
00416 localKey = 'z';
00417 break;
00418 case SDLK_c:
00419 localKey = 'c';
00420 break;
00421 #endif
00422 }
00423 }
00424 }
00425
00426 while (SDL_PollEvent(&event))
00427 {
00428 switch (event.type)
00429 {
00430 case SDL_MOUSEBUTTONDOWN:
00431 switch(event.button.button)
00432 {
00433 case SDL_BUTTON_RIGHT:
00434 rightMouse = 1;
00435 break;
00436 case SDL_BUTTON_LEFT:
00437 leftMouse = 1;
00438 break;
00439 }
00440 break;
00441 case SDL_KEYDOWN:
00442 switch(event.key.keysym.sym)
00443 {
00444 case SDLK_ESCAPE:
00445 localKey = 0x1;
00446 break;
00447 case SDLK_RETURN:
00448 localKey = 0x1C;
00449 break;
00450 case SDLK_LSHIFT:
00451 case SDLK_RSHIFT:
00452 localKey = 0x36;
00453 break;
00454 case SDLK_LALT:
00455 case SDLK_RALT:
00456 localKey = 0x38;
00457 break;
00458 case SDLK_LCTRL:
00459 case SDLK_RCTRL:
00460 localKey = 0x1D;
00461 break;
00462 case SDLK_PAGEUP:
00463 localKey = 0x49;
00464 break;
00465 case SDLK_p:
00466 localKey = 'p';
00467 break;
00468 case SDLK_h:
00469 localKey = 'h';
00470 break;
00471 case SDLK_j:
00472 localKey = 'j';
00473 break;
00474 case SDLK_w:
00475 localKey = 'w';
00476 break;
00477 case SDLK_F6:
00478 localKey = 0x40;
00479 break;
00480 case SDLK_F12:
00481 toggle_fullscreen();
00482 break;
00483
00484 #ifdef GAMEMOD
00485 case SDLK_r:
00486 localKey = 'r';
00487 break;
00488 case SDLK_f:
00489 localKey = 'f';
00490 break;
00491 case SDLK_t:
00492 localKey = 't';
00493 break;
00494 case SDLK_g:
00495 localKey = 'g';
00496 break;
00497 case SDLK_b:
00498 localKey = 'b';
00499 break;
00500 #endif
00501
00502
00503
00504 default:
00505 break;
00506 }
00507 break;
00508 }
00509 }
00510
00511 for (i = 0; i < 28; i++)
00512 {
00513 if (pressedKeyMap[i] == localKey)
00514 {
00515 find = i;
00516 found = 1;
00517 }
00518 }
00519
00520 if (found != 0)
00521 {
00522 temp = pressedKeyCharMap[find];
00523 temp2 = temp & 0x00FF;
00524
00525 if (temp2 == 0)
00526 {
00527
00528 if (!(localKey & 0x80))
00529 {
00530 pressedKey |= (temp & 0xFF00) >> 8;
00531 }
00532 else
00533 {
00534 pressedKey &= -((temp & 0xFF00) >> 8);
00535 }
00536 }
00537
00538 else
00539 {
00540 skipedKey |= (temp & 0xFF00) >> 8;
00541 }
00542 }
00543
00544
00545 skipIntro = localKey;
00546
00547
00548 }
00549
00550 #ifdef GAMEMOD
00551
00552 void ttf_draw_text(int X, int Y, char *string, int center)
00553 {
00554 SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
00555 SDL_Color *forecol = &white;
00556 SDL_Rect rectangle;
00557
00558 SDL_Surface *text;
00559
00560 text = TTF_RenderText_Solid(font, string, *forecol);
00561
00562 if(center)
00563 rectangle.x = X - (text->w/2);
00564 else
00565 rectangle.x = X;
00566 rectangle.y = Y - 2;
00567 rectangle.w = text->w;
00568 rectangle.h = text->h;
00569
00570 SDL_BlitSurface(text, NULL, screenBuffer, &rectangle);
00571 SDL_FreeSurface(text);
00572 }
00573
00574 void get_mouse_positions(MouseStatusStruct *mouseData)
00575 {
00576 SDL_GetMouseState(&mouseData->X, &mouseData->Y);
00577
00578 mouseData->left = leftMouse;
00579 mouseData->right = rightMouse;
00580
00581 leftMouse = 0;
00582 rightMouse = 0;
00583 }
00584
00585 #endif