cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

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}