1 //////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // Nestopia - NES/Famicom emulator written in C++ 4 // 5 // Copyright (C) 2003-2008 Martin Freij 6 // 7 // This file is part of Nestopia. 8 // 9 // Nestopia is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation; either version 2 of the License, or 12 // (at your option) any later version. 13 // 14 // Nestopia is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with Nestopia; if not, write to the Free Software 21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 // 23 //////////////////////////////////////////////////////////////////////////////////////// 24 25 #include "language/resource.h" 26 #include "NstApplicationException.hpp" 27 #include "NstWindowCustom.hpp" 28 29 namespace Nestopia 30 { 31 namespace Window 32 { 33 Custom::Timers Custom::timers; 34 Timer(const TimerCallback & t)35 Custom::Timer::Timer(const TimerCallback& t) 36 : TimerCallback(t) {} 37 StartTimer(const TimerCallback timer,const uint duration) const38 void Custom::StartTimer(const TimerCallback timer,const uint duration) const 39 { 40 NST_ASSERT( hWnd ); 41 42 uint id = 0; 43 44 for (Timers::ConstIterator it(timers.Begin()), end(timers.End()); ; ++it, ++id) 45 { 46 if (it == end) 47 { 48 timers.PushBack( timer ); 49 break; 50 } 51 else if (*it == timer) 52 { 53 break; 54 } 55 } 56 57 timers[id].active = true; 58 59 if (!::SetTimer( hWnd, id, duration, &TimerProc )) 60 throw Application::Exception( IDS_ERR_FAILED, L"SetTimer()" ); 61 } 62 StopTimer(const TimerCallback timer) const63 bool Custom::StopTimer(const TimerCallback timer) const 64 { 65 for (Timers::Iterator it(timers.Begin()), end(timers.End()); it != end; ++it) 66 { 67 if (*it == timer && it->active) 68 { 69 it->active = false; 70 ::KillTimer( hWnd, it - timers.Begin() ); 71 return true; 72 } 73 } 74 75 return false; 76 } 77 78 #ifdef NST_MSVC_OPTIMIZE 79 #pragma optimize("t", on) 80 #endif 81 TimerProc(HWND const hWnd,uint,const UINT_PTR id,DWORD)82 void CALLBACK Custom::TimerProc(HWND const hWnd,uint,const UINT_PTR id,DWORD) 83 { 84 NST_ASSERT( id < timers.Size() ); 85 86 const uint next = timers[id](); 87 88 if (timers[id].active) 89 { 90 if (next == 0) 91 { 92 timers[id].active = false; 93 ::KillTimer( hWnd, id ); 94 } 95 else if (next != 1) 96 { 97 ::SetTimer( hWnd, id, next, &TimerProc ); 98 } 99 } 100 } 101 102 #ifdef NST_MSVC_OPTIMIZE 103 #pragma optimize("t", on) 104 #endif 105 } 106 } 107