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 //------------------------------------------------------------------------------