Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

LampInput.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // Lamp : Open source game middleware
00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //------------------------------------------------------------------------------
00019 
00020 /** @file
00021  * Lamp入力実装
00022  * @author Junpee
00023  */
00024 
00025 #include "LampBasic.h"
00026 #include "Input/System/LampInput.h"
00027 #include "Input/System/BufferedInput.h"
00028 #include "Input/Keyboard/KeyboardKey.h"
00029 #include "Input/Keyboard/Keyboard.h"
00030 #include "Input/Keyboard/KeyboardDevice.h"
00031 #include "Input/Mouse/Mouse.h"
00032 #include "Input/Mouse/MouseDevice.h"
00033 #include "Input/Joystick/Joystick.h"
00034 #include "Input/Joystick/JoystickDevice.h"
00035 #include "Core/InputOutput/BinaryFileWriter.h"
00036 #include "Core/InputOutput/BinaryFileReader.h"
00037 
00038 namespace Lamp{
00039 
00040 // ウィンドウハンドル
00041 HWND LampInput::windowHandle_ = NULL;
00042 // DirectInput
00043 DirectInput* LampInput::directInput_ = NULL;
00044 // 入力モード
00045 LampInput::InputMode LampInput::inputMode_ = LampInput::modePolling;
00046 // バッファ入力
00047 BufferedInput* LampInput::bufferedInput_ = NULL;
00048 
00049 // ログライタ
00050 BinaryWriter* LampInput::logWriter_ = NULL;
00051 // バイナリファイルライタ
00052 BinaryWriter* LampInput::binaryFileWriter_ = NULL;
00053 // ログリーダ
00054 BinaryReader* LampInput::logReader_ = NULL;
00055 // バイナリファイルリーダ
00056 BinaryReader* LampInput::binaryFileReader_ = NULL;
00057 
00058 // キーボード
00059 Keyboard* LampInput::keyboard_ = NULL;
00060 // キーボードデバイス
00061 KeyboardDevice* LampInput::keyboardDevice_ = NULL;
00062 // マウス
00063 Mouse* LampInput::mouse_ = NULL;
00064 // マウスデバイス
00065 MouseDevice* LampInput::mouseDevice_ = NULL;
00066 // ジョイスティック
00067 ArrayList<Joystick*> LampInput::joysticks_;
00068 // ジョイスティックデバイス
00069 ArrayList<JoystickDevice*> LampInput::joystickDevices_;
00070 
00071 // 初期化フラグ
00072 bool LampInput::isInitialized_ = false;
00073 // ログ取得中フラグ
00074 bool LampInput::isLogging_ = false;
00075 // ログ再生中フラグ
00076 bool LampInput::isLogPlaying_ = false;
00077 
00078 //------------------------------------------------------------------------------
00079 // 初期化、後始末
00080 //------------------------------------------------------------------------------
00081 // 初期化
00082 bool LampInput::initialize(
00083     HINSTANCE instanceHandle, HWND windowHandle, InputMode inputMode){
00084     if(isInitialized_){ return true; }
00085     Assert(inputMode_ == modePolling);
00086     windowHandle_ = windowHandle;
00087     LampCore::initialize();
00088     KeyboardKey::initializeKeyString();
00089     // DirectInput作成
00090     if(DirectXFailed(DirectInputCreate(instanceHandle, DIRECTINPUT_VERSION,
00091         DirectInputInterfaceID, (void**)&directInput_, NULL))){
00092         ErrorOut("LampInput::initialize() "
00093             "DirectInputの作成に失敗しました");
00094         return false;
00095     }
00096 
00097     // キーボードデバイスの作成
00098     DirectInputDevice* device;
00099     if(DirectXFailed(directInput_->CreateDevice(
00100         GUID_SysKeyboard, &device, NULL))){
00101         ErrorOut("LampInput::initialize() "
00102             "キーボードデバイスの初期化に失敗しました");
00103         return false;
00104     }
00105     keyboardDevice_ = new KeyboardDevice();
00106     if(!keyboardDevice_->initialize(device, windowHandle_)){ return false; }
00107     keyboard_ = new Keyboard(keyboardDevice_);
00108 
00109     // マウスデバイスの作成
00110     if(DirectXFailed(directInput_->CreateDevice(
00111         GUID_SysMouse, &device, NULL))){
00112         ErrorOut("LampInput::initialize() "
00113             "マウスデバイスの初期化に失敗しました");
00114         return false;
00115     }
00116     mouseDevice_ = new MouseDevice();
00117     if(!mouseDevice_->initialize(device, windowHandle_)){ return false; }
00118     mouse_ = new Mouse(mouseDevice_);
00119 
00120     // ジョイスティックデバイスの作成
00121     if(DirectXFailed(directInput_->EnumDevices(
00122         DirectInputDeviceClass_GameController, joystickEnumeration,
00123         NULL, DIEDFL_ATTACHEDONLY))){
00124         ErrorOut("LampInput::initialize() "
00125             "ジョイスティックデバイスの列挙に失敗しました");
00126         return false;
00127     }
00128     // 初期化フラグ立てる
00129     isInitialized_ = true;
00130     setInputMode(inputMode);
00131     return true;
00132 }
00133 //------------------------------------------------------------------------------
00134 // ジョイスティックの列挙コールバック
00135 int __stdcall LampInput::joystickEnumeration(
00136     const DIDEVICEINSTANCE* instance, void* userData){
00137     // デバイス作成
00138     DirectInputDevice* device;
00139     if(DirectXFailed(directInput_->CreateDevice(
00140         instance->guidInstance, &device, NULL))){
00141         ErrorOut("LampInput::joystickEnumeration() "
00142             "ジョイスティックデバイスの作成に失敗しました");
00143         return DIENUM_STOP;
00144     }
00145     // ジョイスティック初期化
00146     JoystickDevice* joystickDevice = new JoystickDevice();
00147     if(!joystickDevice->initialize(device, windowHandle_)){
00148         ErrorOut("LampInput::joystickEnumeration() "
00149             "ジョイスティックデバイスの初期化に失敗しました");
00150         return DIENUM_STOP;
00151     }
00152     joystickDevices_.add(joystickDevice);
00153     joysticks_.add(new Joystick(joystickDevice));
00154     return DIENUM_CONTINUE;
00155 }
00156 //------------------------------------------------------------------------------
00157 // 後始末
00158 void LampInput::finalize(){
00159     // ログ再生を停止する
00160     if(isLogPlaying()){ stopLog(); }
00161     // ログ取得を停止する
00162     if(isLogging()){ endLogging(); }
00163     // バッファ入力の後始末
00164     if(inputMode_ == modeBuffering){ finalizeBufferInput(); }
00165     // デバイス解放
00166     for(int i = joysticks_.getCount() - 1; i >= 0; i--){ delete joysticks_[i]; }
00167     joysticks_.clear();
00168     for(int i = joystickDevices_.getCount() - 1; i >= 0; i--){
00169         delete joystickDevices_[i];
00170     }
00171     joystickDevices_.clear();
00172     SafeDelete(mouse_);
00173     SafeDelete(mouseDevice_);
00174     SafeDelete(keyboard_);
00175     SafeDelete(keyboardDevice_);
00176     // DirectInput解放
00177     SafeRelease(directInput_);
00178     // 初期化フラグクリア
00179     isInitialized_ = false;
00180 }
00181 //------------------------------------------------------------------------------
00182 // クリア
00183 void LampInput::clear(){
00184     Assert(isInitialized_);
00185     keyboard_->clear();
00186     mouse_->clear();
00187     int joystickCount = joysticks_.getCount();
00188     for(int i = 0; i < joystickCount; i++){ joysticks_[i]->clear(); }
00189 }
00190 //------------------------------------------------------------------------------
00191 // バッファクリア
00192 void LampInput::bufferClear(){
00193     Assert(isInitialized_);
00194     Assert(inputMode_ == modeBuffering);
00195     while(bufferedInput_->hasMoreInput()){ bufferedInput_->nextInput(); }
00196     // バッファをクリアしてから現在の入力をクリアする
00197     clear();
00198 }
00199 //------------------------------------------------------------------------------
00200 // 入力モード
00201 //------------------------------------------------------------------------------
00202 // 入力モードの設定
00203 void LampInput::setInputMode(InputMode inputMode){
00204     Assert(isInitialized_);
00205     Assert(!isLogPlaying());
00206     Assert(!isLogging());
00207     if(inputMode_ == inputMode){ return; }
00208     // バッファ入力の後始末
00209     if(inputMode_ == modeBuffering){ finalizeBufferInput(); }
00210     inputMode_ = inputMode;
00211     // バッファ入力の初期化
00212     if(inputMode_ == modeBuffering){ initializeBufferInput(); }
00213 }
00214 //------------------------------------------------------------------------------
00215 // ポーリング入力
00216 //------------------------------------------------------------------------------
00217 // ポーリング
00218 bool LampInput::polling(){
00219     Assert(isInitialized_);
00220     Assert(inputMode_ == modePolling);
00221     bool result = true;
00222     if(!isLogPlaying_){
00223         // デバイスポーリング
00224         if(!devicePolling()){ result = false; }
00225     }else{
00226         // ログポーリング
00227         logPolling();
00228     }
00229     // ログの書き出し
00230     writeLog();
00231     return result;
00232 }
00233 //------------------------------------------------------------------------------
00234 // デバイスポーリング
00235 bool LampInput::devicePolling(){
00236     bool result = true;
00237     // キーボードのポーリング
00238     if(!keyboardDevice_->polling()){ result = false; }
00239     keyboard_->setNextState(keyboardDevice_->getKeyboardState());
00240 
00241     // マウスのポーリング
00242     if(!mouseDevice_->polling()){ result = false; }
00243     mouse_->setNextState(mouseDevice_->getMouseState());
00244 
00245     // ジョイスティックのポーリング
00246     int joystickDeviceCount = getJoystickDeviceCount();
00247     for(int i = 0; i < joystickDeviceCount; i++){
00248         JoystickDevice* joystickDevice = getJoystickDevice(i);
00249         if(!joystickDevice->polling()){ result = false; }
00250         getJoystick(i)->setNextState(joystickDevice->getJoystickState());
00251     }
00252     return result;
00253 }
00254 //------------------------------------------------------------------------------
00255 // ログポーリング
00256 void LampInput::logPolling(){
00257     // キーボードのログ読み込み
00258     KeyboardState keyboardState;
00259     keyboardState.readBinary(logReader_);
00260     keyboard_->setNextState(keyboardState);
00261 
00262     // マウスのログ読み込み
00263     MouseState mouseState;
00264     mouseState.readBinary(logReader_);
00265     mouse_->setNextState(mouseState);
00266 
00267     // ジョイスティックのログ読み込み
00268     int joystickCount = getJoystickCount();
00269     for(int i = 0; i < joystickCount; i++){
00270         JoystickState joystickState;
00271         joystickState.readBinary(logReader_);
00272         getJoystick(i)->setNextState(joystickState);
00273     }
00274 
00275     // ログ終端チェック
00276     if(logReader_->isEnd()){ stopLog(); }
00277 }
00278 //------------------------------------------------------------------------------
00279 // ログの書き出し
00280 void LampInput::writeLog(){
00281     if(!isLogging()){ return; }
00282     keyboard_->getState().writeBinary(logWriter_);
00283     mouse_->getState().writeBinary(logWriter_);
00284     int joystickCount = getJoystickCount();
00285     for(int i = 0; i < joystickCount; i++){
00286         getJoystick(i)->getState().writeBinary(logWriter_);
00287     }
00288 }
00289 //------------------------------------------------------------------------------
00290 // バッファ入力
00291 //------------------------------------------------------------------------------
00292 // バッファ入力初期化
00293 void LampInput::initializeBufferInput(){
00294     Assert(bufferedInput_ == NULL);
00295     // バッファ入力初期化
00296     bufferedInput_ = new BufferedInput();
00297     bufferedInput_->setKeyboard(keyboard_, keyboardDevice_);
00298     bufferedInput_->setMouse(mouse_, mouseDevice_);
00299     int joystickCount = joysticks_.getCount();
00300     for(int i = 0; i < joystickCount; i++){
00301         bufferedInput_->addJoystick(joysticks_[i], joystickDevices_[i]);
00302     }
00303     // バッファ入力開始
00304     bufferedInput_->start();
00305 }
00306 //------------------------------------------------------------------------------
00307 // バッファ入力後始末
00308 void LampInput::finalizeBufferInput(){
00309     Assert(bufferedInput_ != NULL);
00310     // バッファ入力終了
00311     bufferedInput_->stop();
00312     // バッファ入力後始末
00313     SafeDelete(bufferedInput_);
00314 }
00315 //------------------------------------------------------------------------------
00316 // 入力があるか
00317 bool LampInput::hasMoreInput(){
00318     Assert(isInitialized_);
00319     Assert(inputMode_ == modeBuffering);
00320     return bufferedInput_->hasMoreInput();
00321 }
00322 //------------------------------------------------------------------------------
00323 // 入力を待つ
00324 void LampInput::waitForInput(){
00325     while(true){
00326         if(hasMoreInput()){ return; }
00327         Thread::sleep(1);
00328     }
00329 }
00330 //------------------------------------------------------------------------------
00331 // 次の入力
00332 void LampInput::nextInput(){
00333     Assert(isInitialized_);
00334     Assert(inputMode_ == modeBuffering);
00335     bufferedInput_->nextInput();
00336 }
00337 //------------------------------------------------------------------------------
00338 // 入力数の取得
00339 int LampInput::getInputCount(){
00340     Assert(isInitialized_);
00341     Assert(inputMode_ == modeBuffering);
00342     return bufferedInput_->getInputCount();
00343 }
00344 //------------------------------------------------------------------------------
00345 // ログ取得
00346 //------------------------------------------------------------------------------
00347 // ログ取得の開始
00348 void LampInput::startLogging(const String& filePath){
00349     Assert(binaryFileWriter_ == NULL);
00350     binaryFileWriter_ = new BinaryFileWriter(filePath);
00351     startLogging(binaryFileWriter_);
00352 }
00353 //------------------------------------------------------------------------------
00354 // ログ取得の開始
00355 void LampInput::startLogging(BinaryWriter* binaryWriter){
00356     Assert(!isLogging_);
00357     Assert(logWriter_ == NULL);
00358     logWriter_ = binaryWriter;
00359     // ヘッダの書き出し
00360     logWriter_->writeString("LampInputLog");
00361     logWriter_->writeInt(getJoystickCount());
00362     InputMode inputMode = getInputMode();
00363     logWriter_->writeInt(inputMode);
00364     if(inputMode == modeBuffering){ bufferedInput_->startLogging(logWriter_); }
00365     isLogging_ = true;
00366 }
00367 //------------------------------------------------------------------------------
00368 // ログ取得の終了
00369 void LampInput::endLogging(){
00370     Assert(isLogging_);
00371     Assert(logWriter_ != NULL);
00372     isLogging_ = false;
00373     if(getInputMode() == modeBuffering){ bufferedInput_->endLogging(); }
00374     logWriter_->flush();
00375     logWriter_ = NULL;
00376     SafeDelete(binaryFileWriter_);
00377 }
00378 //------------------------------------------------------------------------------
00379 // ログ再生
00380 //------------------------------------------------------------------------------
00381 // ログ再生の開始
00382 void LampInput::playLog(const String& filePath){
00383     Assert(binaryFileReader_ == NULL);
00384     binaryFileReader_ = new BinaryFileReader(filePath);
00385     playLog(binaryFileReader_);
00386 }
00387 //------------------------------------------------------------------------------
00388 // ログ再生の開始
00389 void LampInput::playLog(BinaryReader* binaryReader){
00390     Assert(!isLogPlaying_);
00391     Assert(logReader_ == NULL);
00392     logReader_ = binaryReader;
00393     // ヘッダの読み込み
00394     String headerString = logReader_->readString();
00395     if(!headerString.equals("LampInputLog")){
00396         ErrorOut("LampInput::playLog LampInputLog形式のファイルではありません");
00397     }
00398     int joystickCount = logReader_->readInt();
00399     if(joystickCount != getJoystickCount()){
00400         ErrorOut("LampInput::playLog ジョイスティックの数が違います");
00401     }
00402     // 毎フレーム毎に入力モードを出力すれば動的切り替えにも対応可能
00403     // ただしLampInput使用するコード側がpollingとnextInputを使い分ける必要がある
00404     InputMode inputMode = (InputMode)logReader_->readInt();
00405     setInputMode(inputMode);
00406     if(inputMode == modeBuffering){ bufferedInput_->playLog(binaryReader); }
00407     isLogPlaying_ = true;
00408 }
00409 //------------------------------------------------------------------------------
00410 // ログ再生の停止
00411 void LampInput::stopLog(){
00412     Assert(isLogPlaying_);
00413     Assert(logReader_ != NULL);
00414     isLogPlaying_ = false;
00415     if(getInputMode() == modeBuffering){ bufferedInput_->stopLog(); }
00416     logReader_ = NULL;
00417     SafeDelete(binaryFileReader_);
00418 }
00419 //------------------------------------------------------------------------------
00420 // ウィンドウプロシージャ
00421 LRESULT LampInput::windowProcedure(
00422     HWND windowHandle, u_int message, WPARAM wParam, LPARAM lParam){
00423 /*
00424     switch(message){
00425     // ウィンドウのアクティブ、非アクティブに変更
00426     case WM_ACTIVATEAPP:
00427 bool minimized = ((int)HIWORD(wParam) != 0);
00428 //      if(mouse_->isExclusive()){
00429             if((LOWORD(wParam) != WA_INACTIVE)){
00430                 // ウィンドウがアクティブになったのでカーソルを消す
00431                 while(::ShowCursor(false) >= 0){}
00432             }else{
00433                 // ウィンドウがアクティブでなくなったのでカーソルを見せる
00434                 while(::ShowCursor(true) < 0){}
00435             }
00436 //      }
00437         break;
00438     }
00439 */
00440     return 0;
00441 }
00442 //------------------------------------------------------------------------------
00443 } // End of namespace Lamp
00444 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:31 2005 for Lamp by doxygen 1.3.2