sdlVideo.cpp

00001 /*
00002   SDL(Video)の初期化
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "sdlVideo.h"
00008 #include "userInput.h"
00009 #include "deleteObjects.h"
00010 #include <limits.h>
00011 
00012 
00013 UserInput::userInput_t UserInput::state;
00014 bool SDL_Video::activated = false;
00015 bool SDL_Video::fullscreen = false;
00016 SDL_Surface *SDL_Video::screen = NULL;
00017 SDL_mutex *SDL_Video::mutex = NULL;
00018 std::map<char,SDL_Video::drawList> SDL_Video::draws;
00019 Uint32 SDL_Video::pre_ticks = SDL_GetTicks();
00020 bool SDL_Video::cursor_hide = false;
00021 int SDL_Video::wait_msec_max = INT_MAX;
00022 int SDL_Video::wait_msec = INT_MAX;
00023 SDL_Video::call_t SDL_Video::callback = NULL;
00024 bool SDL_Video::initialized = false;
00025 std::vector<FocusComponentInterface*> SDL_Video::inputList;
00026 int SDL_Video::input_index = 0;
00027 bool SDL_Video::fullscreen_trigger = false;
00028 
00029 
00030 SDL_Surface* SDL_Video::createScreen(void) {
00031   Uint32 mode = SDL_HWSURFACE | SDL_DOUBLEBUF;
00032   if (fullscreen) {
00033     mode |= SDL_FULLSCREEN;
00034   }
00035   return SDL_SetVideoMode(ScreenWidth, ScreenHeight, 32, mode);
00036 }
00037 
00038 
00039 int SDL_Video::updateThread(void* dummy) {
00040   UserInput& userInput = UserInput::getObject();
00041 
00042   bool activated_check = true;
00043   while (activated_check) {
00044     lock();
00045     activated_check = activated;
00046     if (!activated_check) {
00047       unlock();
00048       continue;
00049     }
00050 
00051     // 入力情報の更新
00052     Uint32 ticks = SDL_GetTicks();
00053     userInput.internal_update();
00054     // TAB によるフォーカス切り替え
00055     if (userInput.state.tab_pressed) {
00056       toggleFocus();
00057     }
00058     if (userInput.toggle_fullscreen || fullscreen_trigger) {
00059       if (fullscreen_trigger) {
00060         fullscreen_trigger = false;
00061       } else {
00062         fullscreen = !fullscreen;
00063       }
00064       // スクリーンのリサイズ
00065       screen = createScreen();
00066 
00067       // カーソルの描画/隠蔽
00068       wait_msec = wait_msec_max;
00069       SDL_ShowCursor(SDL_ENABLE);
00070       cursor_hide = false;
00071     }
00072 
00073     if (fullscreen) {
00074       if (userInput.state.mouse_moved) {
00075         wait_msec = wait_msec_max;
00076         if (cursor_hide) {
00077           SDL_ShowCursor(SDL_ENABLE);
00078           cursor_hide = false;
00079         }
00080       } else {
00081         wait_msec -= ticks - pre_ticks;
00082         if (wait_msec < 0 && !cursor_hide) {
00083           SDL_ShowCursor(SDL_DISABLE);
00084           cursor_hide = true;
00085         }
00086       }
00087     }
00088 
00089     // 描画要素の再描画
00090     for (std::map<char,drawList>::iterator mit = draws.begin();
00091          mit != draws.end(); ++mit) {
00092       for (drawList::iterator lit = mit->second.begin();
00093            lit != mit->second.end();) {
00094         bool alive = (*lit)->draw(ticks, userInput);
00095         if (alive) {
00096           ++lit;
00097         } else {
00098           lit = mit->second.erase(lit);
00099         }
00100       }
00101     }
00102     pre_ticks = ticks;
00103     userInput.keys_sys.clear();
00104     userInput.sdl_keys_sys.clear();
00105     userInput.sdl_mods_sys.clear();
00106 
00107     // 登録してある関数の実行
00108     if (callback) {
00109       callback(ticks);
00110     }
00111     SDL_Flip(screen);
00112     unlock();
00113 
00114     SDL_Delay(1000 / FPS);
00115   }
00116   return 0;
00117 }
00118 
00119 
00120 void SDL_Video::registerEventHandler(call_t function) {
00121   callback = function;
00122 }
00123 
00124 
00125 SDL_Video::SDL_Video(void)
00126   : SDL_Base(),
00127     thread(NULL), titleName(NULL), iconSurface(NULL), active_ticks(0) {
00128   if (!initialized) {
00129     pre_ticks = SDL_GetTicks();
00130     wait_msec = wait_msec_max;
00131     mutex = SDL_CreateMutex();
00132     fullscreen = false;
00133     initialized = true;
00134   }
00135 }
00136 
00137 
00138 SDL_Video::~SDL_Video(void) {
00139   if (initialized) {
00140     activate(false);
00141     SDL_DestroyMutex(mutex);
00142 
00143     if (titleName) {
00144       delete [] titleName;
00145     }
00146 
00147     if (iconSurface) {
00148       SDL_FreeSurface(iconSurface);
00149     }
00150     initialized = false;
00151   }
00152 }
00153 
00154 
00155 void SDL_Video::lock(void) {
00156   SDL_LockMutex(mutex);
00157 }
00158 
00159 
00160 void SDL_Video::unlock(void) {
00161   SDL_UnlockMutex(mutex);
00162 }
00163 
00164 
00165 void SDL_Video::activate(bool on) {
00166   if (activated == on) {
00167     return;
00168   }
00169 
00170   if (!activated) {
00171     if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
00172       throw SDL_Exception();
00173     }
00174     if (iconSurface) {
00175       SDL_WM_SetIcon(iconSurface, NULL);
00176     }
00177     screen = createScreen();
00178     active_ticks = SDL_GetTicks();
00179     if (screen) {
00180       // 表示更新用スレッドの起動
00181       if (!thread) {
00182         activated = true;
00183         thread = SDL_CreateThread(SDL_Video::updateThread, this);
00184       }
00185       if (titleName) {
00186         SDL_WM_SetCaption(titleName, NULL);
00187       }
00188     }
00189   } else {
00190     // 表示更新用スレッドの終了を待つ
00191     lock();
00192     activated = false;
00193     unlock();
00194     if (thread) {
00195       SDL_WaitThread(thread, NULL);
00196       thread = NULL;
00197     }
00198     SDL_QuitSubSystem(SDL_INIT_VIDEO);
00199     active_ticks = 0;
00200   }
00201 }
00202 
00203 
00204 void SDL_Video::setTitle(const char *title, const char *icon) {
00205   if (titleName) {
00206     delete [] titleName;
00207   }
00208   if (title) {
00209     titleName = new char [strlen(title) + 1];
00210     sprintf(titleName, "%s", title);
00211   }
00212 
00213   if (iconSurface) {
00214     SDL_FreeSurface(iconSurface);
00215   }
00216   if (icon) {
00217     iconSurface = SDL_LoadBMP(icon);
00218   }
00219 }
00220 
00221 
00222 void SDL_Video::autoHideCursor(int waitMsec) {
00223   wait_msec_max = waitMsec;
00224   wait_msec = wait_msec_max;
00225 }
00226 
00227 
00228 void SDL_Video::blitSurface(SDL_Surface* surface,
00229                             const VXV::Rect& size, const VXV::Grid& pos) {
00230   SDL_Rect sdl_size, sdl_pos;
00231   sdl_size.x = size.x;
00232   sdl_size.y = size.y;
00233   sdl_size.w = size.w;
00234   sdl_size.h = size.h;
00235   sdl_pos.x = pos.x;
00236   sdl_pos.y = pos.y;
00237   SDL_BlitSurface(surface, &sdl_size, screen, &sdl_pos);
00238 }
00239 
00240 
00241 void SDL_Video::fillRect(const VXV::Rect& rect, unsigned long color) {
00242   Uint32 sdl_color = SDL_MapRGBA(SDL_Video::screen->format,
00243                                  static_cast<Uint8>((color >> 24) & 0xff),
00244                                  static_cast<Uint8>((color >> 16) & 0xff),
00245                                  static_cast<Uint8>((color >>  8) & 0xff),
00246                                  static_cast<Uint8>(color & 0xff));
00247   SDL_Rect sdl_rect;
00248   sdl_rect.x = rect.x;
00249   sdl_rect.y = rect.y;
00250   sdl_rect.w = rect.w;
00251   sdl_rect.h = rect.h;
00252 
00253   SDL_FillRect(screen, &sdl_rect, sdl_color);
00254 }
00255 
00256 
00257 unsigned long SDL_Video::getTicks(void) {
00258   if (active_ticks == 0) {
00259     return 0;
00260   }
00261   return (SDL_GetTicks() - active_ticks);
00262 }
00263 
00264 
00265 void SDL_Video::changeFocus(void) {
00266   if ((input_index < 0) ||
00267       (input_index >= static_cast<int>(inputList.size()))) {
00268     input_index = 0;
00269   }
00270 
00271   inputList[input_index]->endFocus();
00272   if (++input_index >= static_cast<int>(inputList.size())) {
00273     input_index = 0;
00274   }
00275   inputList[input_index]->beginFocus();
00276 }
00277 
00278 
00279 void SDL_Video::delInputComponent(ComponentInterface* component) {
00280   std::vector<FocusComponentInterface*>::iterator it
00281     = find(inputList.begin(), inputList.end(), component);
00282   if (it != inputList.end()) {
00283     int del_index = inputList.begin() - it;
00284     if (input_index == del_index) {
00285       changeFocus();
00286       --input_index;
00287     } else if (input_index > del_index) {
00288       --input_index;
00289     }
00290     inputList.erase(it);
00291 
00292     if (input_index < 0) {
00293       input_index = inputList.empty() ? 0 : inputList.size() -1;
00294     }
00295   }
00296 }
00297 
00298 
00299 void SDL_Video::toggleFocus(void) {
00300   if (inputList.empty()) {
00301     return;
00302   }
00303   changeFocus();
00304 }
00305 
00306 
00307 void SDL_Video::setFocus(FocusComponentInterface* component) {
00308   std::vector<FocusComponentInterface*>::iterator it
00309     = find(inputList.begin(), inputList.end(), component);
00310   if (it != inputList.end()) {
00311     inputList[input_index]->endFocus();
00312     input_index = it - inputList.begin() -1;
00313     changeFocus();
00314   }
00315 }
00316 

Generated on Mon Apr 13 22:52:02 2009 by  doxygen 1.5.7.1