00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00030
00031
00032
00033
00034
00035 #include "stratagus.h"
00036
00037 #ifdef DEBUG
00038 #include <signal.h>
00039 #endif
00040
00041 #include <map>
00042 #include <string>
00043
00044 #include <stdlib.h>
00045 #include <string.h>
00046
00047 #include <limits.h>
00048 #ifndef _MSC_VER
00049 #include <sys/time.h>
00050 #include <sys/types.h>
00051 #include <unistd.h>
00052 #endif
00053
00054 #ifdef USE_WIN32
00055 #include "net_lowlevel.h"
00056 #endif
00057
00058 #include "video.h"
00059 #include "font.h"
00060 #include "interface.h"
00061 #include "network.h"
00062 #include "ui.h"
00063 #include "sound_server.h"
00064 #include "sound.h"
00065 #include "interface.h"
00066 #include "minimap.h"
00067 #include "widgets.h"
00068 #include "editor.h"
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 SDL_Surface *TheScreen;
00079
00080 static SDL_Rect Rects[100];
00081 static int NumRects;
00082 GLint GLMaxTextureSize;
00083 bool GLTextureCompressionSupported;
00084 bool UseGLTextureCompression;
00085
00086 static std::map<int, std::string> Key2Str;
00087 static std::map<std::string, int> Str2Key;
00088
00089 static int FrameTicks;
00090 static int FrameRemainder;
00091 static int FrameFraction;
00092
00093 const EventCallback *Callbacks;
00094
00095
00096
00097
00098
00099
00100 PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glCompressedTexImage3DARB;
00101 PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
00102 PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glCompressedTexImage1DARB;
00103 PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glCompressedTexSubImage3DARB;
00104 PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glCompressedTexSubImage2DARB;
00105 PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glCompressedTexSubImage1DARB;
00106 PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
00107
00108
00109
00110
00111
00118 void SetVideoSync(void)
00119 {
00120 int ms;
00121
00122 if (VideoSyncSpeed) {
00123 ms = (1000 * 1000 / CYCLES_PER_SECOND) / VideoSyncSpeed;
00124 } else {
00125 ms = INT_MAX;
00126 }
00127 SkipFrames = ms / 400;
00128 while (SkipFrames && ms / SkipFrames < 200) {
00129 --SkipFrames;
00130 }
00131 ms /= SkipFrames + 1;
00132
00133 FrameTicks = ms / 10;
00134 FrameRemainder = ms % 10;
00135 DebugPrint("frames %d - %d.%dms\n" _C_ SkipFrames _C_ ms / 10 _C_ ms % 10);
00136 }
00137
00138
00139
00140
00141
00145 static bool IsExtensionSupported(const char *extension)
00146 {
00147 const GLubyte *extensions = NULL;
00148 const GLubyte *start;
00149 GLubyte *ptr, *terminator;
00150 int len;
00151
00152
00153 ptr = (GLubyte *)strchr(extension, ' ');
00154 if (ptr || *extension == '\0') {
00155 return false;
00156 }
00157
00158 extensions = glGetString(GL_EXTENSIONS);
00159 len = strlen(extension);
00160 start = extensions;
00161 while (true) {
00162 ptr = (GLubyte *)strstr((const char *)start, extension);
00163 if (!ptr) {
00164 break;
00165 }
00166
00167 terminator = ptr + len;
00168 if (ptr == start || *(ptr - 1) == ' ') {
00169 if (*terminator == ' ' || *terminator == '\0') {
00170 return true;
00171 }
00172 }
00173 start = terminator;
00174 }
00175 return false;
00176 }
00177
00181 static void InitOpenGLExtensions()
00182 {
00183
00184 if (IsExtensionSupported("GL_ARB_texture_compression"))
00185 {
00186 glCompressedTexImage3DARB =
00187 (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)SDL_GL_GetProcAddress("glCompressedTexImage3DARB");
00188 glCompressedTexImage2DARB =
00189 (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)SDL_GL_GetProcAddress("glCompressedTexImage2DARB");
00190 glCompressedTexImage1DARB =
00191 (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)SDL_GL_GetProcAddress("glCompressedTexImage1DARB");
00192 glCompressedTexSubImage3DARB =
00193 (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)SDL_GL_GetProcAddress("glCompressedTexSubImage3DARB");
00194 glCompressedTexSubImage2DARB =
00195 (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)SDL_GL_GetProcAddress("glCompressedTexSubImage2DARB");
00196 glCompressedTexSubImage1DARB =
00197 (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)SDL_GL_GetProcAddress("glCompressedTexSubImage1DARB");
00198 glGetCompressedTexImageARB =
00199 (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)SDL_GL_GetProcAddress("glGetCompressedTexImageARB");
00200
00201 if (glCompressedTexImage3DARB && glCompressedTexImage2DARB &&
00202 glCompressedTexImage1DARB && glCompressedTexSubImage3DARB &&
00203 glCompressedTexSubImage2DARB && glCompressedTexSubImage1DARB &&
00204 glGetCompressedTexImageARB)
00205 {
00206 GLTextureCompressionSupported = true;
00207 }
00208 else
00209 {
00210 GLTextureCompressionSupported = false;
00211 }
00212 }
00213 }
00214
00218 static void InitOpenGL(void)
00219 {
00220 InitOpenGLExtensions();
00221
00222 glViewport(0, 0, (GLsizei)Video.Width, (GLsizei)Video.Height);
00223 glMatrixMode(GL_PROJECTION);
00224 glLoadIdentity();
00225 glOrtho(0, Video.Width, Video.Height, 0, -1, 1);
00226 glMatrixMode(GL_MODELVIEW);
00227 glLoadIdentity();
00228 glTranslatef(0.375, 0.375, 0.);
00229
00230 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00231 glClearDepth(1.0f);
00232 glShadeModel(GL_FLAT);
00233 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00234 glEnable(GL_BLEND);
00235 glEnable(GL_TEXTURE_2D);
00236 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00237 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00238 glEnable(GL_LINE_SMOOTH);
00239 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00240
00241 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GLMaxTextureSize);
00242 if (GLMaxTextureSize == 0) {
00243
00244 #if 0
00245 glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
00246 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
00247 glGetTexLevelParameterfv(GL_PROXY_TEXTURE_2D, 0,
00248 GL_TEXTURE_INTERNAL_FORMAT, &internalFormat);
00249 #endif
00250 fprintf(stderr, "GL_MAX_TEXTURE_SIZE is 0, using 256 by default\n");
00251 GLMaxTextureSize = 256;
00252 }
00253 }
00254
00255 void ReloadOpenGL()
00256 {
00257 InitOpenGL();
00258 ReloadGraphics();
00259 ReloadFonts();
00260 UI.Minimap.Reload();
00261 }
00262
00263 #if defined(DEBUG) && !defined(USE_WIN32)
00264 static void CleanExit(int signum)
00265 {
00266
00267 SDL_Quit();
00268
00269 signal(SIGABRT, SIG_DFL);
00270
00271 abort();
00272 }
00273 #endif
00274
00278 static void InitKey2Str()
00279 {
00280 Str2Key[_("esc")] = SDLK_ESCAPE;
00281
00282 if (!Key2Str.empty()) {
00283 return;
00284 }
00285
00286 int i;
00287 char str[20];
00288
00289 Key2Str[SDLK_BACKSPACE] = "backspace";
00290 Key2Str[SDLK_TAB] = "tab";
00291 Key2Str[SDLK_CLEAR] = "clear";
00292 Key2Str[SDLK_RETURN] = "return";
00293 Key2Str[SDLK_PAUSE] = "pause";
00294 Key2Str[SDLK_ESCAPE] = "escape";
00295 Key2Str[SDLK_SPACE] = " ";
00296 Key2Str[SDLK_EXCLAIM] = "!";
00297 Key2Str[SDLK_QUOTEDBL] = "\"";
00298 Key2Str[SDLK_HASH] = "#";
00299 Key2Str[SDLK_DOLLAR] = "$";
00300 Key2Str[SDLK_AMPERSAND] = "&";
00301 Key2Str[SDLK_QUOTE] = "'";
00302 Key2Str[SDLK_LEFTPAREN] = "(";
00303 Key2Str[SDLK_RIGHTPAREN] = ")";
00304 Key2Str[SDLK_ASTERISK] = "*";
00305 Key2Str[SDLK_PLUS] = "+";
00306 Key2Str[SDLK_COMMA] = ",";
00307 Key2Str[SDLK_MINUS] = "-";
00308 Key2Str[SDLK_PERIOD] = ".";
00309 Key2Str[SDLK_SLASH] = "/";
00310
00311 str[1] = '\0';
00312 for (i = SDLK_0; i <= SDLK_9; ++i) {
00313 str[0] = i;
00314 Key2Str[i] = str;
00315 }
00316
00317 Key2Str[SDLK_COLON] = ":";
00318 Key2Str[SDLK_SEMICOLON] = ";";
00319 Key2Str[SDLK_LESS] = "<";
00320 Key2Str[SDLK_EQUALS] = "=";
00321 Key2Str[SDLK_GREATER] = ">";
00322 Key2Str[SDLK_QUESTION] = "?";
00323 Key2Str[SDLK_AT] = "@";
00324 Key2Str[SDLK_LEFTBRACKET] = "[";
00325 Key2Str[SDLK_BACKSLASH] = "\\";
00326 Key2Str[SDLK_RIGHTBRACKET] = "]";
00327 Key2Str[SDLK_BACKQUOTE] = "`";
00328
00329 str[1] = '\0';
00330 for (i = SDLK_a; i <= SDLK_z; ++i) {
00331 str[0] = i;
00332 Key2Str[i] = str;
00333 }
00334
00335 Key2Str[SDLK_DELETE] = "delete";
00336
00337 for (i = SDLK_KP0; i <= SDLK_KP9; ++i) {
00338 sprintf_s(str, sizeof(str), "kp_%d", i - SDLK_KP0);
00339 Key2Str[i] = str;
00340 }
00341
00342 Key2Str[SDLK_KP_PERIOD] = "kp_period";
00343 Key2Str[SDLK_KP_DIVIDE] = "kp_divide";
00344 Key2Str[SDLK_KP_MULTIPLY] = "kp_multiply";
00345 Key2Str[SDLK_KP_MINUS] = "kp_minus";
00346 Key2Str[SDLK_KP_PLUS] = "kp_plus";
00347 Key2Str[SDLK_KP_ENTER] = "kp_enter";
00348 Key2Str[SDLK_KP_EQUALS] = "kp_equals";
00349 Key2Str[SDLK_UP] = "up";
00350 Key2Str[SDLK_DOWN] = "down";
00351 Key2Str[SDLK_RIGHT] = "right";
00352 Key2Str[SDLK_LEFT] = "left";
00353 Key2Str[SDLK_INSERT] = "insert";
00354 Key2Str[SDLK_HOME] = "home";
00355 Key2Str[SDLK_END] = "end";
00356 Key2Str[SDLK_PAGEUP] = "pageup";
00357 Key2Str[SDLK_PAGEDOWN] = "pagedown";
00358
00359 for (i = SDLK_F1; i <= SDLK_F15; ++i) {
00360 sprintf_s(str, sizeof(str), "f%d", i - SDLK_F1 + 1);
00361 Key2Str[i] = str;
00362 sprintf_s(str, sizeof(str), "F%d", i - SDLK_F1 + 1);
00363 Str2Key[str] = i;
00364 }
00365
00366 Key2Str[SDLK_HELP] = "help";
00367 Key2Str[SDLK_PRINT] = "print";
00368 Key2Str[SDLK_SYSREQ] = "sysreq";
00369 Key2Str[SDLK_BREAK] = "break";
00370 Key2Str[SDLK_MENU] = "menu";
00371 Key2Str[SDLK_POWER] = "power";
00372 Key2Str[SDLK_EURO] = "euro";
00373 Key2Str[SDLK_UNDO] = "undo";
00374 }
00375
00379 void InitVideoSdl(void)
00380 {
00381 Uint32 flags;
00382
00383 if (SDL_WasInit(SDL_INIT_VIDEO) == 0) {
00384 if (SDL_Init(
00385 #ifdef DEBUG
00386 SDL_INIT_NOPARACHUTE |
00387 #endif
00388 SDL_INIT_AUDIO | SDL_INIT_VIDEO |
00389 SDL_INIT_TIMER) < 0 ) {
00390 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
00391 exit(1);
00392 }
00393
00394
00395
00396 atexit(SDL_Quit);
00397
00398
00399
00400 #if defined(DEBUG) && !defined(USE_WIN32)
00401 signal(SIGSEGV, CleanExit);
00402 signal(SIGABRT, CleanExit);
00403 #endif
00404
00405 SDL_WM_SetCaption("Bos Wars", "Bos Wars");
00406 }
00407
00408
00409
00410 flags = 0;
00411
00412
00413 if (Video.FullScreen) {
00414 flags |= SDL_FULLSCREEN;
00415 }
00416 if (UseOpenGL) {
00417 flags |= SDL_OPENGL;
00418 }
00419
00420 if (!Video.Width || !Video.Height) {
00421 Video.Width = 640;
00422 Video.Height = 480;
00423 }
00424
00425 TheScreen = SDL_SetVideoMode(Video.Width, Video.Height, Video.Depth, flags);
00426 if (TheScreen && (TheScreen->format->BitsPerPixel != 16 &&
00427 TheScreen->format->BitsPerPixel != 32)) {
00428
00429 TheScreen = SDL_SetVideoMode(Video.Width, Video.Height, 16, flags);
00430 }
00431 if (TheScreen == NULL) {
00432 fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
00433 Video.Width, Video.Height, Video.Depth, SDL_GetError());
00434 exit(1);
00435 }
00436
00437 Video.FullScreen = (TheScreen->flags & SDL_FULLSCREEN) ? 1 : 0;
00438 Video.Depth = TheScreen->format->BitsPerPixel;
00439
00440
00441 SDL_ShowCursor(0);
00442
00443
00444 SDL_EnableUNICODE(1);
00445
00446 if (UseOpenGL) {
00447 InitOpenGL();
00448 }
00449
00450 InitKey2Str();
00451
00452 ColorBlack = Video.MapRGB(TheScreen->format, 0, 0, 0);
00453 ColorDarkGreen = Video.MapRGB(TheScreen->format, 48, 100, 4);
00454 ColorBlue = Video.MapRGB(TheScreen->format, 0, 0, 252);
00455 ColorOrange = Video.MapRGB(TheScreen->format, 248, 140, 20);
00456 ColorWhite = Video.MapRGB(TheScreen->format, 252, 248, 240);
00457 ColorGray = Video.MapRGB(TheScreen->format, 128, 128, 128);
00458 ColorRed = Video.MapRGB(TheScreen->format, 252, 0, 0);
00459 ColorGreen = Video.MapRGB(TheScreen->format, 0, 252, 0);
00460 ColorYellow = Video.MapRGB(TheScreen->format, 252, 252, 0);
00461
00462 UI.MouseWarpX = UI.MouseWarpY = -1;
00463 }
00464
00471 int VideoValidResolution(int w, int h)
00472 {
00473 return SDL_VideoModeOK(w, h, TheScreen->format->BitsPerPixel, TheScreen->flags);
00474 }
00475
00484 void InvalidateArea(int x, int y, int w, int h)
00485 {
00486 if (!UseOpenGL) {
00487 Assert(NumRects != sizeof(Rects) / sizeof(*Rects));
00488 Assert(x >= 0 && y >= 0 && x + w <= Video.Width && y + h <= Video.Height);
00489 Rects[NumRects].x = x;
00490 Rects[NumRects].y = y;
00491 Rects[NumRects].w = w;
00492 Rects[NumRects].h = h;
00493 ++NumRects;
00494 }
00495 }
00496
00500 void Invalidate(void)
00501 {
00502 if (!UseOpenGL) {
00503 Rects[0].x = 0;
00504 Rects[0].y = 0;
00505 Rects[0].w = Video.Width;
00506 Rects[0].h = Video.Height;
00507 NumRects = 1;
00508 }
00509 }
00510
00517 static void SdlDoEvent(const EventCallback *callbacks, const SDL_Event *event)
00518 {
00519 switch (event->type) {
00520 case SDL_MOUSEBUTTONDOWN:
00521 InputMouseButtonPress(callbacks, SDL_GetTicks(),
00522 event->button.button);
00523 break;
00524
00525 case SDL_MOUSEBUTTONUP:
00526 InputMouseButtonRelease(callbacks, SDL_GetTicks(),
00527 event->button.button);
00528 break;
00529
00530
00531
00532 case SDL_MOUSEMOTION:
00533 InputMouseMove(callbacks, SDL_GetTicks(),
00534 event->motion.x, event->motion.y);
00535
00536 if ((UI.MouseWarpX != -1 || UI.MouseWarpY != -1) &&
00537 (event->motion.x != UI.MouseWarpX ||
00538 event->motion.y != UI.MouseWarpY)) {
00539 int xw = UI.MouseWarpX;
00540 int yw = UI.MouseWarpY;
00541 UI.MouseWarpX = -1;
00542 UI.MouseWarpY = -1;
00543 SDL_WarpMouse(xw, yw);
00544 }
00545 break;
00546
00547 case SDL_ACTIVEEVENT:
00548 if (event->active.state & SDL_APPMOUSEFOCUS) {
00549 static bool InMainWindow = true;
00550
00551 if (InMainWindow && !event->active.gain) {
00552 InputMouseExit(callbacks, SDL_GetTicks());
00553 }
00554 InMainWindow = (event->active.gain != 0);
00555 }
00556 if (event->active.state & SDL_APPACTIVE) {
00557 static bool IsVisible = true;
00558 static bool DoTogglePause = false;
00559
00560 if (IsVisible && !event->active.gain) {
00561 IsVisible = false;
00562 if (!GamePaused) {
00563 DoTogglePause = true;
00564 UiTogglePause();
00565 }
00566 } else if (!IsVisible && event->active.gain) {
00567 IsVisible = true;
00568 if (GamePaused && DoTogglePause) {
00569 DoTogglePause = false;
00570 UiTogglePause();
00571 }
00572 if (UseOpenGL) {
00573 Video.ResizeScreen(Video.Width, Video.Height);
00574 }
00575 }
00576 }
00577 break;
00578
00579 case SDL_KEYDOWN:
00580 InputKeyButtonPress(callbacks, SDL_GetTicks(),
00581 event->key.keysym.sym, event->key.keysym.unicode);
00582 break;
00583
00584 case SDL_KEYUP:
00585 InputKeyButtonRelease(callbacks, SDL_GetTicks(),
00586 event->key.keysym.sym, event->key.keysym.unicode);
00587 break;
00588
00589 case SDL_QUIT:
00590 Exit(0);
00591 break;
00592 }
00593
00594 if (callbacks == GetCallbacks()) {
00595 handleInput(event);
00596 }
00597 }
00598
00602 void SetCallbacks(const EventCallback *callbacks)
00603 {
00604 Callbacks = callbacks;
00605 }
00606
00610 const EventCallback *GetCallbacks()
00611 {
00612 return Callbacks;
00613 }
00614
00625 void WaitEventsOneFrame()
00626 {
00627 struct timeval tv;
00628 fd_set rfds;
00629 fd_set wfds;
00630 Socket maxfd;
00631 int i;
00632 int s;
00633 SDL_Event event[1];
00634 Uint32 ticks;
00635 int interrupts;
00636
00637 ++FrameCounter;
00638
00639 ticks = SDL_GetTicks();
00640 if (ticks > NextFrameTicks) {
00641 ++SlowFrameCounter;
00642 }
00643
00644 InputMouseTimeout(GetCallbacks(), ticks);
00645 InputKeyTimeout(GetCallbacks(), ticks);
00646 CursorAnimate(ticks);
00647
00648 interrupts = 0;
00649
00650 for (;;) {
00651
00652
00653
00654 ticks = SDL_GetTicks();
00655 if (!interrupts && ticks < NextFrameTicks) {
00656 SDL_Delay(NextFrameTicks - ticks);
00657 ticks = SDL_GetTicks();
00658 }
00659 while (ticks >= NextFrameTicks) {
00660 ++interrupts;
00661 FrameFraction += FrameRemainder;
00662 if (FrameFraction > 10) {
00663 FrameFraction -= 10;
00664 ++NextFrameTicks;
00665 }
00666 NextFrameTicks += FrameTicks;
00667 }
00668
00669
00670
00671
00672 maxfd = 0;
00673 tv.tv_sec = tv.tv_usec = 0;
00674 FD_ZERO(&rfds);
00675 FD_ZERO(&wfds);
00676
00677
00678
00679
00680 if (IsNetworkGame()) {
00681 if (NetworkFildes > maxfd) {
00682 maxfd = NetworkFildes;
00683 }
00684 FD_SET(NetworkFildes, &rfds);
00685 }
00686
00687 #if 0
00688 s = select(maxfd + 1, &rfds, &wfds, NULL,
00689 (i = SDL_PollEvent(event)) ? &tv : NULL);
00690 #else
00691
00692
00693
00694
00695
00696
00697
00698 s = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
00699 i = SDL_PollEvent(event);
00700 #endif
00701
00702 if (i) {
00703 SdlDoEvent(GetCallbacks(), event);
00704 }
00705
00706 if (s > 0) {
00707
00708
00709
00710 if (IsNetworkGame() && FD_ISSET(NetworkFildes, &rfds) ) {
00711 GetCallbacks()->NetworkEvent();
00712 }
00713 }
00714
00715
00716
00717
00718 if (!i && s <= 0 && interrupts) {
00719 break;
00720 }
00721 }
00722 handleInput(NULL);
00723
00724 if (!SkipGameCycle--) {
00725 SkipGameCycle = SkipFrames;
00726 }
00727
00728 if (!UseOpenGL && (GameRunning || Editor.Running || PatchEditorRunning)) {
00729 Video.ClearScreen();
00730 }
00731 }
00732
00736 void RealizeVideoMemory(void)
00737 {
00738 if (UseOpenGL) {
00739 SDL_GL_SwapBuffers();
00740 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00741 } else {
00742 if (NumRects) {
00743 SDL_UpdateRects(TheScreen, NumRects, Rects);
00744 NumRects = 0;
00745 }
00746 }
00747 HideCursor();
00748 }
00749
00753 void SdlLockScreen(void)
00754 {
00755 if (!UseOpenGL) {
00756 if (SDL_MUSTLOCK(TheScreen)) {
00757 SDL_LockSurface(TheScreen);
00758 }
00759 }
00760 }
00761
00765 void SdlUnlockScreen(void)
00766 {
00767 if (!UseOpenGL) {
00768 if (SDL_MUSTLOCK(TheScreen)) {
00769 SDL_UnlockSurface(TheScreen);
00770 }
00771 }
00772 }
00773
00777 const char *SdlKey2Str(int key)
00778 {
00779 return Key2Str[key].c_str();
00780 }
00781
00785 int Str2SdlKey(const char *str)
00786 {
00787 InitKey2Str();
00788
00789 std::map<int, std::string>::iterator i;
00790 for (i = Key2Str.begin(); i != Key2Str.end(); ++i) {
00791 if (!strcasecmp(str, (*i).second.c_str())) {
00792 return (*i).first;
00793 }
00794 }
00795 std::map<std::string, int>::iterator i2;
00796 for (i2 = Str2Key.begin(); i2 != Str2Key.end(); ++i2) {
00797 if (!strcasecmp(str, (*i2).first.c_str())) {
00798 return (*i2).second;
00799 }
00800 }
00801 return 0;
00802 }
00803
00807 bool SdlGetGrabMouse(void)
00808 {
00809 return SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON;
00810 }
00811
00817 void ToggleGrabMouse(int mode)
00818 {
00819 bool grabbed = SdlGetGrabMouse();
00820
00821 if (mode <= 0 && grabbed) {
00822 SDL_WM_GrabInput(SDL_GRAB_OFF);
00823 } else if (mode >= 0 && !grabbed) {
00824 SDL_WM_GrabInput(SDL_GRAB_ON);
00825 }
00826 }
00827
00831 void ToggleFullScreen(void)
00832 {
00833 #ifdef USE_WIN32
00834 long framesize;
00835 SDL_Rect clip;
00836 Uint32 flags;
00837 int w;
00838 int h;
00839 int bpp;
00840 unsigned char *pixels = NULL;
00841 SDL_Color *palette = NULL;
00842 int ncolors = 0;
00843
00844 if (!TheScreen) {
00845 return;
00846 }
00847
00848 flags = TheScreen->flags;
00849 w = TheScreen->w;
00850 h = TheScreen->h;
00851 bpp = TheScreen->format->BitsPerPixel;
00852
00853 if (!SDL_VideoModeOK(w, h, bpp, flags ^ SDL_FULLSCREEN)) {
00854 return;
00855 }
00856
00857 SDL_GetClipRect(TheScreen, &clip);
00858
00859
00860 framesize = w * h * TheScreen->format->BytesPerPixel;
00861
00862 if (!UseOpenGL) {
00863 if (!(pixels = new unsigned char[framesize])) {
00864 return;
00865 }
00866 SDL_LockSurface(TheScreen);
00867 memcpy(pixels, TheScreen->pixels, framesize);
00868
00869 if (TheScreen->format->palette) {
00870 ncolors = TheScreen->format->palette->ncolors;
00871 if (!(palette = new SDL_Color[ncolors])) {
00872 delete[] pixels;
00873 return;
00874 }
00875 memcpy(palette, TheScreen->format->palette->colors,
00876 ncolors * sizeof(SDL_Color));
00877 }
00878 SDL_UnlockSurface(TheScreen);
00879 }
00880
00881 TheScreen = SDL_SetVideoMode(w, h, bpp, flags ^ SDL_FULLSCREEN);
00882 if (!TheScreen) {
00883 TheScreen = SDL_SetVideoMode(w, h, bpp, flags);
00884 if (!TheScreen) {
00885 if (!UseOpenGL) {
00886 delete[] pixels;
00887 delete[] palette;
00888 }
00889 fprintf(stderr, "Toggle to fullscreen, crashed all\n");
00890 Exit(-1);
00891 }
00892 }
00893
00894
00895
00896 SDL_ShowCursor(SDL_ENABLE);
00897 SDL_ShowCursor(SDL_DISABLE);
00898
00899 if (UseOpenGL) {
00900 ReloadOpenGL();
00901 } else {
00902 SDL_LockSurface(TheScreen);
00903 memcpy(TheScreen->pixels, pixels, framesize);
00904 delete[] pixels;
00905
00906 if (TheScreen->format->palette) {
00907
00908 SDL_SetPalette(TheScreen, SDL_LOGPAL, palette, 0, ncolors);
00909 delete[] palette;
00910 }
00911 SDL_UnlockSurface(TheScreen);
00912 }
00913
00914 SDL_SetClipRect(TheScreen, &clip);
00915
00916 Invalidate();
00917 #else // !USE_WIN32
00918 SDL_WM_ToggleFullScreen(TheScreen);
00919 #endif
00920
00921 Video.FullScreen = (TheScreen->flags & SDL_FULLSCREEN) ? 1 : 0;
00922 }
00923