inputmanager.mm (7074B)
1/* 2 * Gearboy - Nintendo Game Boy Emulator 3 * Copyright (C) 2012 Ignacio Sanchez 4 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * any later version. 9 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see http://www.gnu.org/licenses/ 17 * 18 */ 19 20#include "inputmanager.h" 21 22InputManager::InputManager() 23{ 24 m_fInputRate = 0.15f; 25 m_Timer.Start(); 26} 27 28InputManager::~InputManager() 29{ 30} 31 32void InputManager::Update(void) 33{ 34 while (!m_RegionEventResponseQueue.empty()) 35 { 36 stRegionEventResponse event = m_RegionEventResponseQueue.front(); 37 m_RegionEventResponseQueue.pop(); 38 39 event.pCallback->Execute(event.parameter, event.id); 40 } 41} 42 43void InputManager::AddCircleRegionEvent(float x, float y, float radius, InputCallbackGeneric* pCallback, int id, bool receiveMoveEvent) 44{ 45 stRegionEvent tmp; 46 47 tmp.receiveMoveEvent = receiveMoveEvent; 48 tmp.region = new CircleRegion(x, y, radius); 49 tmp.regionType = REGION_CIRCLE; 50 tmp.pCallback = pCallback; 51 tmp.pressed = false; 52 tmp.pActualTouch = NULL; 53 tmp.id = id; 54 55 m_RegionEventVector.push_back(tmp); 56} 57 58void InputManager::AddRectRegionEvent(float x, float y, float width, float height, InputCallbackGeneric* pCallback, int id, bool receiveMoveEvent) 59{ 60 stRegionEvent tmp; 61 62 tmp.receiveMoveEvent = receiveMoveEvent; 63 tmp.region = new RectRegion(x, y, width, height); 64 tmp.regionType = REGION_RECT; 65 tmp.pCallback = pCallback; 66 tmp.pressed = false; 67 tmp.pActualTouch = NULL; 68 tmp.id = id; 69 70 m_RegionEventVector.push_back(tmp); 71} 72 73void InputManager::ClearRegionEvents(void) 74{ 75 int size = static_cast<int>(m_RegionEventVector.size()); 76 77 for (int i = 0; i < size; i++) 78 { 79 SafeDelete(m_RegionEventVector[i].region); 80 } 81 82 m_RegionEventVector.clear(); 83 84 while (!m_RegionEventResponseQueue.empty()) 85 { 86 m_RegionEventResponseQueue.pop(); 87 } 88} 89 90void InputManager::HandleTouch(UITouch* touch, UIView* view) 91{ 92 CGPoint location = [touch locationInView : view]; 93 CGPoint previousLocation; 94 95 if (touch.phase == UITouchPhaseMoved) 96 previousLocation = [touch previousLocationInView : view]; 97 else 98 previousLocation = location; 99 100 TRegionEventVector::size_type size = m_RegionEventVector.size(); 101 102 for (u32 i = 0; i < size; i++) 103 { 104 stRegionEvent regionEvent = m_RegionEventVector[i]; 105 106 stRegionEventResponse event; 107 event.pCallback = regionEvent.pCallback; 108 event.id = regionEvent.id; 109 110 bool sendEvent = false; 111 112 if (touch.phase == UITouchPhaseMoved) 113 { 114 if (regionEvent.region->PointInRegion(previousLocation.x, previousLocation.y)) 115 { 116 if (!regionEvent.region->PointInRegion(location.x, location.y)) 117 { 118 if (regionEvent.pressed) 119 { 120 event.parameter.type = PRESS_END; 121 regionEvent.pressed = false; 122 sendEvent = true; 123 } 124 } 125 else 126 { 127 if (regionEvent.pressed && regionEvent.receiveMoveEvent) 128 { 129 if (m_Timer.GetActualTime() > m_fInputRate) 130 { 131 m_Timer.Start(); 132 133 event.parameter.type = PRESS_MOVE; 134 if (regionEvent.regionType == REGION_RECT) 135 { 136 event.parameter.vector = Vec3(location.x, location.y, 0.0f); 137 } 138 else 139 { 140 Vec3 point = Vec3(location.x, location.y, 0.0f); 141 event.parameter.vector = point - regionEvent.region->GetPosition(); 142 } 143 m_RegionEventVector[i].pActualTouch = touch; 144 sendEvent = true; 145 } 146 } 147 else if (!regionEvent.pressed) 148 { 149 150 event.parameter.type = PRESS_START; 151 if (regionEvent.regionType == REGION_RECT) 152 { 153 event.parameter.vector = Vec3(location.x, location.y, 0.0f); 154 } 155 else 156 { 157 Vec3 point = Vec3(location.x, location.y, 0.0f); 158 event.parameter.vector = point - regionEvent.region->GetPosition(); 159 } 160 regionEvent.pressed = true; 161 m_RegionEventVector[i].pActualTouch = touch; 162 sendEvent = true; 163 } 164 } 165 } 166 } 167 else if (touch.phase == UITouchPhaseBegan) 168 { 169 if (regionEvent.region->PointInRegion(previousLocation.x, previousLocation.y)) 170 { 171 if (!regionEvent.pressed) 172 { 173 event.parameter.type = PRESS_START; 174 if (regionEvent.regionType == REGION_RECT) 175 { 176 event.parameter.vector = Vec3(previousLocation.x, previousLocation.y, 0.0f); 177 } 178 else 179 { 180 Vec3 point = Vec3(previousLocation.x, previousLocation.y, 0.0f); 181 event.parameter.vector = point - regionEvent.region->GetPosition(); 182 } 183 regionEvent.pressed = true; 184 m_RegionEventVector[i].pActualTouch = touch; 185 sendEvent = true; 186 187 UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; 188 [generator impactOccurred]; 189 } 190 } 191 } 192 else if ((touch.phase == UITouchPhaseEnded) || (touch.phase == UITouchPhaseCancelled)) 193 { 194 if (regionEvent.pActualTouch == touch) 195 { 196 if (regionEvent.pressed) 197 { 198 event.parameter.type = PRESS_END; 199 regionEvent.pressed = false; 200 sendEvent = true; 201 } 202 } 203 } 204 205 if (sendEvent) 206 { 207 m_RegionEventVector[i].pressed = regionEvent.pressed; 208 209 m_RegionEventResponseQueue.push(event); 210 } 211 } 212} 213 214