Platform library for RETRO

Dependents:   RETRO_RickGame

Committer:
Architect
Date:
Sun Mar 01 05:29:45 2015 +0000
Revision:
0:6f26c31d8573
RetroPlatform Library for RETRO gaming system

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Architect 0:6f26c31d8573 1 /*
Architect 0:6f26c31d8573 2 * (C) Copyright 2015 Valentin Ivanov. All rights reserved.
Architect 0:6f26c31d8573 3 *
Architect 0:6f26c31d8573 4 * This file is part of the RetroPlatform Library
Architect 0:6f26c31d8573 5 *
Architect 0:6f26c31d8573 6 * The RetroPlatform Library is free software: you can redistribute it and/or modify
Architect 0:6f26c31d8573 7 * it under the terms of the GNU Lesser General Public License as published by
Architect 0:6f26c31d8573 8 * the Free Software Foundation, either version 3 of the License, or
Architect 0:6f26c31d8573 9 * (at your option) any later version.
Architect 0:6f26c31d8573 10 *
Architect 0:6f26c31d8573 11 * This program is distributed in the hope that it will be useful,
Architect 0:6f26c31d8573 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Architect 0:6f26c31d8573 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Architect 0:6f26c31d8573 14 * GNU Lesser General Public License for more details.
Architect 0:6f26c31d8573 15 *
Architect 0:6f26c31d8573 16 * You should have received a copy of the GNU Lesser General Public License
Architect 0:6f26c31d8573 17 * along with this program. If not, see <http://www.gnu.org/licenses/>
Architect 0:6f26c31d8573 18 *
Architect 0:6f26c31d8573 19 * This library is inspired by Gamebuino Library (http://gamebuino.com)
Architect 0:6f26c31d8573 20 * from Aurélien Rodot.
Architect 0:6f26c31d8573 21 */
Architect 0:6f26c31d8573 22 #include "Retro.h"
Architect 0:6f26c31d8573 23 #include "us_ticker_api.h"
Architect 0:6f26c31d8573 24
Architect 0:6f26c31d8573 25 const uint16_t OKSequence[] = {0x0005,0x138,0x168,0x0000};
Architect 0:6f26c31d8573 26 const uint16_t CancelSequence[] = {0x0005,0x168,0x138,0x0000};
Architect 0:6f26c31d8573 27 const uint16_t TickSequence[] = {0x0045,0x168,0x0000};
Architect 0:6f26c31d8573 28
Architect 0:6f26c31d8573 29 DigitalIn Retro::pin[NUM_BTN] = {
Architect 0:6f26c31d8573 30 DigitalIn(P0_14, PullUp), //left
Architect 0:6f26c31d8573 31 DigitalIn(P0_11, PullUp), //right
Architect 0:6f26c31d8573 32 DigitalIn(P0_12, PullUp), //down
Architect 0:6f26c31d8573 33 DigitalIn(P0_13, PullUp), //up
Architect 0:6f26c31d8573 34 DigitalIn(P0_16, PullUp), //robot
Architect 0:6f26c31d8573 35 DigitalIn(P0_1, PullUp) //ship
Architect 0:6f26c31d8573 36 };
Architect 0:6f26c31d8573 37
Architect 0:6f26c31d8573 38 Retro::Retro(): display(
Architect 0:6f26c31d8573 39 P0_19,
Architect 0:6f26c31d8573 40 P0_20,
Architect 0:6f26c31d8573 41 P0_7,
Architect 0:6f26c31d8573 42 P0_21,
Architect 0:6f26c31d8573 43 P0_22,
Architect 0:6f26c31d8573 44 P1_15,
Architect 0:6f26c31d8573 45 P0_2,
Architect 0:6f26c31d8573 46 LCD_ST7735::RGB), leftEye(P0_9,false), rightEye(P0_8,false)
Architect 0:6f26c31d8573 47 {
Architect 0:6f26c31d8573 48 initialize();
Architect 0:6f26c31d8573 49 }
Architect 0:6f26c31d8573 50
Architect 0:6f26c31d8573 51
Architect 0:6f26c31d8573 52 void Retro::initialize()
Architect 0:6f26c31d8573 53 {
Architect 0:6f26c31d8573 54 timePerFrame = 50000;
Architect 0:6f26c31d8573 55 frameStartUs = us_ticker_read();
Architect 0:6f26c31d8573 56
Architect 0:6f26c31d8573 57 display.setOrientation(LCD_ST7735::Rotate270, false);
Architect 0:6f26c31d8573 58 display.setForegroundColor(Color565::White);
Architect 0:6f26c31d8573 59 display.setBackgroundColor(Color565::Black);
Architect 0:6f26c31d8573 60
Architect 0:6f26c31d8573 61 sound.initialize();
Architect 0:6f26c31d8573 62 sound.setVolume(1);
Architect 0:6f26c31d8573 63
Architect 0:6f26c31d8573 64 setFrameRate(20);
Architect 0:6f26c31d8573 65 }
Architect 0:6f26c31d8573 66
Architect 0:6f26c31d8573 67 void Retro::setFrameRate(uint8_t fps)
Architect 0:6f26c31d8573 68 {
Architect 0:6f26c31d8573 69 timePerFrame = 1000000 / fps;
Architect 0:6f26c31d8573 70 sound.prescaler = fps / 20;
Architect 0:6f26c31d8573 71 sound.prescaler = max(1, sound.prescaler);
Architect 0:6f26c31d8573 72 }
Architect 0:6f26c31d8573 73
Architect 0:6f26c31d8573 74 bool once = false;
Architect 0:6f26c31d8573 75
Architect 0:6f26c31d8573 76 bool Retro::update()
Architect 0:6f26c31d8573 77 {
Architect 0:6f26c31d8573 78 uint32_t current_time = us_ticker_read();
Architect 0:6f26c31d8573 79 frameDurationUs = current_time - frameStartUs;
Architect 0:6f26c31d8573 80
Architect 0:6f26c31d8573 81 if( frameDurationUs > timePerFrame ) {
Architect 0:6f26c31d8573 82 frameStartUs = current_time;
Architect 0:6f26c31d8573 83
Architect 0:6f26c31d8573 84
Architect 0:6f26c31d8573 85 once = false;
Architect 0:6f26c31d8573 86
Architect 0:6f26c31d8573 87 readButtons();
Architect 0:6f26c31d8573 88 return true;
Architect 0:6f26c31d8573 89 } else {
Architect 0:6f26c31d8573 90 if( !once ) {
Architect 0:6f26c31d8573 91 once = true;
Architect 0:6f26c31d8573 92 sound.update();
Architect 0:6f26c31d8573 93
Architect 0:6f26c31d8573 94 }
Architect 0:6f26c31d8573 95 return false;
Architect 0:6f26c31d8573 96 }
Architect 0:6f26c31d8573 97 }
Architect 0:6f26c31d8573 98
Architect 0:6f26c31d8573 99 void Retro::playOK()
Architect 0:6f26c31d8573 100 {
Architect 0:6f26c31d8573 101 sound.playSequence(OKSequence,0);
Architect 0:6f26c31d8573 102 }
Architect 0:6f26c31d8573 103
Architect 0:6f26c31d8573 104 void Retro::playCancel()
Architect 0:6f26c31d8573 105 {
Architect 0:6f26c31d8573 106 sound.playSequence(CancelSequence,0);
Architect 0:6f26c31d8573 107 }
Architect 0:6f26c31d8573 108
Architect 0:6f26c31d8573 109 void Retro::playTick()
Architect 0:6f26c31d8573 110 {
Architect 0:6f26c31d8573 111 sound.playSequence(TickSequence,0);
Architect 0:6f26c31d8573 112 }
Architect 0:6f26c31d8573 113
Architect 0:6f26c31d8573 114 bool Retro::collideCheck( int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
Architect 0:6f26c31d8573 115 {
Architect 0:6f26c31d8573 116 return !( x2 >= x1+w1 || x1 >= x2+w2 || y2 >= y1+h1 || y1 >= y2 + h2 );
Architect 0:6f26c31d8573 117 }
Architect 0:6f26c31d8573 118
Architect 0:6f26c31d8573 119 //Buttons
Architect 0:6f26c31d8573 120 void Retro::readButtons()
Architect 0:6f26c31d8573 121 {
Architect 0:6f26c31d8573 122 for (uint8_t thisButton = 0; thisButton < NUM_BTN; thisButton++) {
Architect 0:6f26c31d8573 123 if ( pin[thisButton].read() == 0 ) {
Architect 0:6f26c31d8573 124 _state[thisButton]++;
Architect 0:6f26c31d8573 125 } else {
Architect 0:6f26c31d8573 126 if (_state[thisButton] == 0)
Architect 0:6f26c31d8573 127 continue;
Architect 0:6f26c31d8573 128 if (_state[thisButton] == 0xFF)
Architect 0:6f26c31d8573 129 _state[thisButton] = 0;
Architect 0:6f26c31d8573 130 else
Architect 0:6f26c31d8573 131 _state[thisButton] = 0xFF;
Architect 0:6f26c31d8573 132 }
Architect 0:6f26c31d8573 133 }
Architect 0:6f26c31d8573 134 }
Architect 0:6f26c31d8573 135
Architect 0:6f26c31d8573 136 bool Retro::pressed(uint8_t button)
Architect 0:6f26c31d8573 137 {
Architect 0:6f26c31d8573 138 if (_state[button] == 1)
Architect 0:6f26c31d8573 139 return true;
Architect 0:6f26c31d8573 140 else
Architect 0:6f26c31d8573 141 return false;
Architect 0:6f26c31d8573 142 }
Architect 0:6f26c31d8573 143
Architect 0:6f26c31d8573 144 bool Retro::released(uint8_t button)
Architect 0:6f26c31d8573 145 {
Architect 0:6f26c31d8573 146 if (_state[button] == 0xFF)
Architect 0:6f26c31d8573 147 return true;
Architect 0:6f26c31d8573 148 else
Architect 0:6f26c31d8573 149 return false;
Architect 0:6f26c31d8573 150 }
Architect 0:6f26c31d8573 151
Architect 0:6f26c31d8573 152 bool Retro::held(uint8_t button, uint8_t time)
Architect 0:6f26c31d8573 153 {
Architect 0:6f26c31d8573 154 if(_state[button] == (time+1))
Architect 0:6f26c31d8573 155 return true;
Architect 0:6f26c31d8573 156 else
Architect 0:6f26c31d8573 157 return false;
Architect 0:6f26c31d8573 158 }
Architect 0:6f26c31d8573 159
Architect 0:6f26c31d8573 160 bool Retro::repeat(uint8_t button, uint8_t period)
Architect 0:6f26c31d8573 161 {
Architect 0:6f26c31d8573 162 if (period <= 1) {
Architect 0:6f26c31d8573 163 if ((_state[button] != 0xFF) && (_state[button]))
Architect 0:6f26c31d8573 164 return true;
Architect 0:6f26c31d8573 165 } else {
Architect 0:6f26c31d8573 166 if ((_state[button] != 0xFF) && ((_state[button] % period) == 1))
Architect 0:6f26c31d8573 167 return true;
Architect 0:6f26c31d8573 168 }
Architect 0:6f26c31d8573 169 return false;
Architect 0:6f26c31d8573 170 }
Architect 0:6f26c31d8573 171
Architect 0:6f26c31d8573 172 uint8_t Retro::timeHeld(uint8_t button)
Architect 0:6f26c31d8573 173 {
Architect 0:6f26c31d8573 174 if(_state[button] != 0xFF)
Architect 0:6f26c31d8573 175 return _state[button];
Architect 0:6f26c31d8573 176 else
Architect 0:6f26c31d8573 177 return 0;
Architect 0:6f26c31d8573 178
Architect 0:6f26c31d8573 179 }