EmulatorInput.mm (9309B)
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 "EmulatorInput.h" 21#import "Emulator.h" 22 23EmulatorInput::EmulatorInput(Emulator* pEmulator) 24{ 25 m_pEmulator = pEmulator; 26 m_pInputCallbackController = new InputCallback<EmulatorInput> (this, &EmulatorInput::InputController); 27 m_pInputCallbackButtons = new InputCallback<EmulatorInput> (this, &EmulatorInput::InputButtons); 28} 29 30EmulatorInput::~EmulatorInput() 31{ 32 SafeDelete(m_pInputCallbackController); 33 SafeDelete(m_pInputCallbackButtons); 34} 35 36void EmulatorInput::Init() 37{ 38 InputManager::Instance().ClearRegionEvents(); 39 for (int i = 0; i < 4; i++) 40 m_bController[i] = false; 41 42 CGFloat scale; 43 if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { 44 scale=[[UIScreen mainScreen] scale]; 45 } else { 46 scale=1; 47 } 48 49 BOOL retina; 50 retina = (scale != 1); 51 52 if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 53 { 54 if (retina) 55 { 56 CGRect screenBounds = [[UIScreen mainScreen] bounds]; 57 58 switch ((int)screenBounds.size.height) 59 { 60 case 480: 61 { 62 // iPhone 4 63 InputManager::Instance().AddCircleRegionEvent(280.0f, 325.0f, 30.0f, m_pInputCallbackButtons, 1, false); 64 InputManager::Instance().AddCircleRegionEvent(233.0f, 345.0f, 30.0f, m_pInputCallbackButtons, 2, false); 65 InputManager::Instance().AddCircleRegionEvent(182.0f, 390.0f, 25.0f, m_pInputCallbackButtons, 3, false); 66 InputManager::Instance().AddCircleRegionEvent(128.0f, 390.0f, 25.0f, m_pInputCallbackButtons, 4, false); 67 InputManager::Instance().AddCircleRegionEvent(57.0f, 342.0f, 50.0f, m_pInputCallbackController, 0, true); 68 break; 69 } 70 case 568: 71 { 72 // iPhone 5 73 InputManager::Instance().AddCircleRegionEvent(257.0f, 354.0f, 35.0f, m_pInputCallbackButtons, 1, false); 74 InputManager::Instance().AddCircleRegionEvent(203.0f, 380.0f, 35.0f, m_pInputCallbackButtons, 2, false); 75 InputManager::Instance().AddCircleRegionEvent(181.0f, 462.0f, 30.0f, m_pInputCallbackButtons, 3, false); 76 InputManager::Instance().AddCircleRegionEvent(129.0f, 462.0f, 30.0f, m_pInputCallbackButtons, 4, false); 77 InputManager::Instance().AddCircleRegionEvent(76.0f, 370.0f, 52.0f, m_pInputCallbackController, 0, true); 78 break; 79 } 80 case 667: 81 { 82 // iPhone 6 83 InputManager::Instance().AddCircleRegionEvent(301.0f, 421.0f, 42.0f, m_pInputCallbackButtons, 1, false); 84 InputManager::Instance().AddCircleRegionEvent(236.0f, 451.0f, 42.0f, m_pInputCallbackButtons, 2, false); 85 InputManager::Instance().AddCircleRegionEvent(214.0f, 550.0f, 35.0f, m_pInputCallbackButtons, 3, false); 86 InputManager::Instance().AddCircleRegionEvent(150.0f, 550.0f, 35.0f, m_pInputCallbackButtons, 4, false); 87 InputManager::Instance().AddCircleRegionEvent(87.0f, 439.0f, 75.0f, m_pInputCallbackController, 0, true); 88 break; 89 } 90 case 736: 91 { 92 // iPhone 6 Plus 93 InputManager::Instance().AddCircleRegionEvent(334.0f, 470.0f, 45.0f, m_pInputCallbackButtons, 1, false); 94 InputManager::Instance().AddCircleRegionEvent(262.0f, 503.0f, 45.0f, m_pInputCallbackButtons, 2, false); 95 InputManager::Instance().AddCircleRegionEvent(235.0f, 613.0f, 40.0f, m_pInputCallbackButtons, 3, false); 96 InputManager::Instance().AddCircleRegionEvent(163.0f, 613.0f, 40.0f, m_pInputCallbackButtons, 4, false); 97 InputManager::Instance().AddCircleRegionEvent(94.0f, 491.0f, 75.0f, m_pInputCallbackController, 0, true); 98 break; 99 } 100 } 101 } 102 else 103 { 104 InputManager::Instance().AddCircleRegionEvent(256.0f, 316.0f, 29.0f, m_pInputCallbackButtons, 1, false); 105 InputManager::Instance().AddCircleRegionEvent(213.0f, 337.0f, 29.0f, m_pInputCallbackButtons, 2, false); 106 InputManager::Instance().AddCircleRegionEvent(167.0f, 397.0f, 25.0f, m_pInputCallbackButtons, 3, false); 107 InputManager::Instance().AddCircleRegionEvent(121.0f, 397.0f, 25.0f, m_pInputCallbackButtons, 4, false); 108 InputManager::Instance().AddCircleRegionEvent(80.0f, 331.0f, 50.0f, m_pInputCallbackController, 0, true); 109 } 110 } 111 else 112 { 113 if (retina) 114 { 115 InputManager::Instance().AddCircleRegionEvent(674.0f, 660.0f, 78.0f, m_pInputCallbackButtons, 1, false); 116 InputManager::Instance().AddCircleRegionEvent(544.0f, 721.0f, 78.0f, m_pInputCallbackButtons, 2, false); 117 InputManager::Instance().AddCircleRegionEvent(408.0f, 891.0f, 60.0f, m_pInputCallbackButtons, 3, false); 118 InputManager::Instance().AddCircleRegionEvent(276.0f, 891.0f, 60.0f, m_pInputCallbackButtons, 4, false); 119 InputManager::Instance().AddCircleRegionEvent(151.0f, 699.0f, 110.0f, m_pInputCallbackController, 0, true); 120 } 121 else 122 { 123 InputManager::Instance().AddCircleRegionEvent(614.0f, 623.0f, 64.0f, m_pInputCallbackButtons, 1, false); 124 InputManager::Instance().AddCircleRegionEvent(510.0f, 671.0f, 64.0f, m_pInputCallbackButtons, 2, false); 125 InputManager::Instance().AddCircleRegionEvent(400.0f, 809.0f, 50.0f, m_pInputCallbackButtons, 3, false); 126 InputManager::Instance().AddCircleRegionEvent(293.0f, 809.0f, 50.0f, m_pInputCallbackButtons, 4, false); 127 InputManager::Instance().AddCircleRegionEvent(192.0f, 653.0f, 100.0f, m_pInputCallbackController, 0, true); 128 } 129 } 130} 131 132void EmulatorInput::InputController(stInputCallbackParameter parameter, int id) 133{ 134 bool bNewController[4]; 135 for (int i = 0; i < 4; i++) 136 bNewController[i] = false; 137 138 if (parameter.type != PRESS_END) 139 { 140 float length = parameter.vector.length(); 141 142 float minLength = 25.0f; 143 144 if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 145 { 146 minLength = 11.0f; 147 } 148 149 if (length >= minLength) 150 { 151 float angle = atan2f(parameter.vector.x, -parameter.vector.y) * 57.29577951f; 152 153 bNewController[0] = ((angle >= 35.0f) && (angle <= 145.0f)); 154 bNewController[1] = ((angle <= -35.0f) && (angle >= -145.0f)); 155 bNewController[2] = ((angle >= -55.0f) && (angle <= 55.0f)); 156 bNewController[3] = ((angle >= 125.0f) || (angle <= -125.0f)); 157 } 158 } 159 160 for (int i = 0; i < 4; i++) 161 { 162 if (bNewController[i] != m_bController[i]) 163 { 164 m_bController[i] = bNewController[i]; 165 166 Gameboy_Keys key = Gameboy_Keys::Select_Key; 167 168 switch (i) 169 { 170 case 0: 171 key = Gameboy_Keys::Right_Key; 172 break; 173 case 1: 174 key = Gameboy_Keys::Left_Key; 175 break; 176 case 2: 177 key = Gameboy_Keys::Up_Key; 178 break; 179 case 3: 180 key = Gameboy_Keys::Down_Key; 181 break; 182 } 183 184 if (m_bController[i]) 185 { 186 [m_pEmulator keyPressed:key]; 187 } 188 else 189 { 190 [m_pEmulator keyReleased:key]; 191 } 192 } 193 } 194} 195 196void EmulatorInput::InputButtons(stInputCallbackParameter parameter, int id) 197{ 198 Gameboy_Keys key; 199 200 switch (id) { 201 case 1: 202 key = Gameboy_Keys::A_Key; 203 break; 204 case 2: 205 key = Gameboy_Keys::B_Key; 206 break; 207 case 3: 208 key = Gameboy_Keys::Start_Key; 209 break; 210 case 4: 211 key = Gameboy_Keys::Select_Key; 212 break; 213 default: 214 return; 215 } 216 217 if (parameter.type == PRESS_START) 218 { 219 Log("press %d", id); 220 [m_pEmulator keyPressed:key]; 221 } 222 else if (parameter.type == PRESS_END) 223 { 224 Log("release %d", id); 225 [m_pEmulator keyReleased:key]; 226 } 227}