PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PokittoConsole.cpp Source File

PokittoConsole.cpp

Go to the documentation of this file.
00001 /**************************************************************************/
00002 /*!
00003     @file     PokittoConsole.cpp
00004     @author   Jonne Valola
00005 
00006     @section LICENSE
00007 
00008     Software License Agreement (BSD License)
00009 
00010     Copyright (c) 2016, Jonne Valola
00011     All rights reserved.
00012 
00013     Redistribution and use in source and binary forms, with or without
00014     modification, are permitted provided that the following conditions are met:
00015     1. Redistributions of source code must retain the above copyright
00016     notice, this list of conditions and the following disclaimer.
00017     2. Redistributions in binary form must reproduce the above copyright
00018     notice, this list of conditions and the following disclaimer in the
00019     documentation and/or other materials provided with the distribution.
00020     3. Neither the name of the copyright holders nor the
00021     names of its contributors may be used to endorse or promote products
00022     derived from this software without specific prior written permission.
00023 
00024     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
00025     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00028     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 */
00035 /**************************************************************************/
00036 
00037 #include "PokittoGlobs.h "
00038 #include "PokittoConsole.h "
00039 #include "PokittoFonts.h "
00040 #include "PokittoDisplay.h "
00041 
00042 Pokitto::Console pConsole;
00043 
00044 using namespace Pokitto;
00045 
00046 consmsg Console::msgbuf[CONSOLEBUFSIZE];
00047 uint8_t Console::conslast;
00048 uint8_t Console::consfirst;
00049 uint8_t Console::conspointer;
00050 uint16_t Console::conscounter;
00051 uint16_t Console::color;
00052 Display* Console::_display;
00053 uint8_t Console::mode;
00054 uint8_t Console::visible;
00055 unsigned char* Console::font;
00056 
00057 Console::Console() {
00058     conslast=consfirst=conspointer=conscounter=0;
00059     color=0xFFFF;
00060     font=(unsigned char*)fontMini;
00061     #if POK_CONSOLE_VISIBLE_AT_STARTUP > 0
00062         mode=CONS_OVERLAY|CONS_VISIBLE;
00063     #else
00064         mode=CONS_OVERLAY;//|CONS_VISIBLE;
00065     #endif
00066 }
00067 
00068 void Console::Toggle() {
00069     if (!conscounter) // conscounter is a debounce feature for console toggle
00070     {
00071         mode ^= CONS_VISIBLE;
00072         conscounter = CONS_TIMEOUT;
00073     }
00074 }
00075 
00076 
00077 void Console::AddMessage(uint8_t source, uint8_t msgtype) {
00078     AddMessage(source,msgtype, V_NONE,0);
00079 }
00080 
00081 
00082 void Console::AddMessage(uint8_t type, char* stringptr) {
00083     AddMessage(MSOURCE_USER,type,V_STRING, (uint32_t) stringptr);
00084 }
00085 
00086 
00087 void Console::AddMessage(uint8_t msgtype, uint8_t valtype, uint32_t val) {
00088     AddMessage(MSOURCE_USER,msgtype,valtype,val);
00089 }
00090 
00091 void Console::AddMessage(uint8_t source, uint8_t msgtype, uint8_t valtype, uint32_t val) {
00092     consmsg c;
00093     c.msgsource = source;
00094     c.msgtype = msgtype;
00095     c.valtype = valtype;
00096     c.val = val;
00097     msgbuf[conslast] = c;
00098     conslast++;
00099     if (conslast==CONSOLEBUFSIZE) conslast = 0; // wrap around the buffer
00100     consfirst = conslast + 1;
00101     if (consfirst == CONSOLEBUFSIZE) consfirst = 0;
00102 }
00103 
00104 void Console::Last() {
00105     conspointer = conslast;
00106 }
00107 
00108 void Console::RemoveLast() {
00109     Last();
00110     Previous();
00111     msgbuf[conspointer].msgsource = MSOURCE_USER;
00112     msgbuf[conspointer].msgtype = MSG_OK;
00113     msgbuf[conspointer].val = 0;
00114     msgbuf[conspointer].valtype = 0;
00115     conslast = conspointer;
00116 }
00117 
00118 void Console::First() {
00119     consmsg c;
00120     uint16_t outofbounds=0;
00121     conspointer = consfirst;
00122     c=GetMessage();
00123     while (!c.msgsource) {
00124         Next();
00125         c=GetMessage();
00126         outofbounds++;
00127         if (outofbounds==CONSOLEBUFSIZE) {
00128             conspointer = consfirst;
00129             break;
00130         }
00131     }
00132 }
00133 
00134 void Console::Previous() {
00135     if (conspointer==0) conspointer = CONSOLEBUFSIZE-1;
00136     else conspointer--;
00137 }
00138 
00139 void Console::Next() {
00140     if (conspointer==CONSOLEBUFSIZE-1) conspointer = 0;
00141     else conspointer++;
00142 }
00143 
00144 consmsg Console::GetMessage() {
00145     return msgbuf[conspointer];
00146 }
00147 
00148 void Console::PrintMessage() {
00149     consmsg c = msgbuf[conspointer];
00150     switch (c.msgsource) {
00151     case MSOURCE_APP:
00152         _display->print("App:");break;
00153     case MSOURCE_BATT:
00154         _display->print("Batt:");break;
00155     case MSOURCE_BTNA:
00156         _display->print("A:");break;
00157     case MSOURCE_BTNB:
00158         _display->print("B:");break;
00159     case MSOURCE_BTNC:
00160         _display->print("C:");break;
00161     case MSOURCE_BTNU:
00162         _display->print("Up:");break;
00163     case MSOURCE_BTND:
00164         _display->print("Down:");break;
00165     case MSOURCE_BTNL:
00166         _display->print("Left:");break;
00167     case MSOURCE_BTNR:
00168         _display->print("Right:");break;
00169     case MSOURCE_LCD:
00170         _display->print("LCD:");break;
00171     case MSOURCE_SD:
00172         _display->print("SD:");break;
00173     case MSOURCE_SOUND:
00174         _display->print("Sound:");break;
00175     case MSOURCE_TIMER:
00176         _display->print("Timer:");break;
00177     case MSOURCE_USER:
00178         _display->print("User:");break;
00179     case MSOURCE_COLLISION:
00180         _display->print("Hit:");break;
00181     default:
00182         return;
00183     }
00184 
00185     switch (c.msgtype) {
00186     case MSG_OK:
00187         _display->print("OK ");break;
00188     case MSG_INIT_OK:
00189         _display->print("INIT OK ");break;
00190     case MSG_INIT_FAIL:
00191         _display->print("INIT FAIL ");break;
00192     case MSG_WARNING:
00193         _display->print("WARNING ");break;
00194     case MSG_FATAL:
00195         _display->print("FATAL ");break;
00196     case MSG_GFX_MODE_CHANGE:
00197         _display->print("MODE ");break;
00198     case MSG_GFX_MODE_INVALID:
00199         _display->print("INVALID!");break;
00200     case MSG_NOT_ENOUGH_MEM:
00201        _display->print("NOT ENOUGH MEM ");break;
00202     case MSG_UP:
00203         _display->print("KEYUP");break;
00204     case MSG_DOWN:
00205         _display->print("KEYDOWN");break;
00206     case MSG_BREAK:
00207         _display->print("BREAK ");break;
00208     case MSG_YESNO:
00209         _display->print("YES(A)/NO(B)");break;
00210     case MSG_YES:
00211         _display->print("YES");break;
00212     case MSG_NO:
00213         _display->print("NO");break;
00214     case MSG_OBJECT:
00215         _display->print("OBJ1: ");break;
00216     case MSG_OBJECT2:
00217         _display->print("OBJ2: ");break;
00218     default:
00219         _display->print(" ");
00220     }
00221 
00222     switch (c.valtype) {
00223     case V_NONE:
00224         _display->println();break;
00225     case V_UINT8:
00226         _display->println((uint16_t)c.val);break;
00227     case V_INT8:
00228         _display->println((int16_t)c.val);break;
00229     case V_UINT16:
00230         _display->println((uint16_t)c.val);break;
00231     case V_INT16:
00232         _display->println((int16_t)c.val);break;
00233     case V_UINT32:
00234         _display->println((uint32_t)c.val);break;
00235     case V_INT32:
00236         _display->println((int32_t)c.val);break;
00237     case V_FLOAT:
00238         _display->println((float)c.val);break;
00239     case V_STRING:
00240         _display->println((char*)c.val);break;
00241     default:
00242         _display->println();
00243     }
00244 
00245     if (c.msgtype == MSG_BREAK || c.msgtype == MSG_YESNO) {
00246         #ifndef POK_SIM
00247         __disable_irq();    // Disable Interrupts
00248         #else
00249         pauseAudio(1);
00250         visible = false; // avoid loop in loop inside refreshDisplay
00251         simulator.wait_ms(300);
00252         #endif
00253         int rval=0;
00254         while(!rval) {
00255                 _buttons->pollButtons();
00256                 #ifdef POK_SIM
00257                     simulator.refreshDisplay();
00258                 #endif // POK_SIM
00259                 if (_buttons->aBtn()) rval = 1;
00260                 if (_buttons->bBtn()) rval = -1;
00261                 }
00262         /* now remove this message to prevent it from rerunning */
00263         if (c.msgtype == MSG_YESNO) {
00264             int8_t* v;
00265             v = (int8_t*) c.val; //c.val is a pointer to the memory location that receives answer
00266             *v = rval; // return value through pointer
00267             msgbuf[conspointer].msgsource = MSOURCE_USER;
00268             if (rval==1) msgbuf[conspointer].msgtype = MSG_YES;
00269             else msgbuf[conspointer].msgtype = MSG_NO;
00270         } else msgbuf[conspointer].msgsource = MSOURCE_NULL;
00271 
00272         #ifndef POK_SIM
00273         __enable_irq();     // Enable Interrupts
00274         #else
00275         pauseAudio(0);
00276         visible = true;
00277         #endif
00278     }
00279 }
00280 
00281 void Console::Draw() {
00282     unsigned char* oldfont;
00283     int16_t oldx,oldy;
00284     uint16_t oldcolor;
00285     uint8_t oldsize;
00286     oldfont = (unsigned char*) _display->font;
00287     oldx = _display->cursorX;
00288     oldy = _display->cursorY;
00289     oldcolor = _display->directcolor;
00290     oldsize = _display->fontSize;
00291     if (!(mode & CONS_OVERLAY)) _display->clearLCD();
00292     _display->setFont(font5x7);
00293     _display->fontSize=1;
00294     _display->setCursor(0,0);
00295     _display->directcolor=color;
00296     First();
00297     while(conspointer!=conslast) {
00298         PrintMessage();
00299         Next();
00300         if (GetMessage().msgsource==MSOURCE_NULL) break;
00301     }
00302     _display->font = oldfont;
00303     _display->fontSize = oldsize;
00304     _display->cursorX = oldx;
00305     _display->cursorY = oldy;
00306     _display->directcolor = oldcolor;
00307 }
00308 
00309 
00310 
00311 
00312 
00313