cscg22-gearboy

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

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