Tyler Weaver
/
qp_hangman
Hangman game using qp a 16x2 LCD and joystick.
Revision 0:1521c946a57b, committed 2012-02-08
- Comitter:
- tylerjw
- Date:
- Wed Feb 08 22:20:11 2012 +0000
- Child:
- 1:4efaebc256d3
- Commit message:
- Problems with lib/qp, please help!
Player class hasn\t been developed yet.
BSP is still missing some features.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/TextLCD/#44f34c09bd37
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bsp.cpp Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,137 @@ +#include "qp_port.h" +#include "hangman.h" +#include "bsp.h" +#include "LPC17xx.h" +#include "mbed.h" + +enum ISR_Priorities { // ISR priorities from highest urgency to lowest + BUTTON_PRIO, + SYSTICK_PRIO, +}; + + +#define LED_PORT LPC_GPIO1 +#define LED1_BIT (1U << 18) +#define LED2_BIT (1U << 20) +#define LED3_BIT (1U << 21) +#define LED4_BIT (1U << 23) + +//............................................................................ +extern "C" void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform the QK kernel of entering the ISR + +#ifdef Q_SPY + uint32_t volatile dummy = SysTick->CTRL; // clear the COUNTFLAG in SysTick + l_tickTime += l_tickPeriod; // account for the clock rollover +#endif + + QF::TICK(&l_SysTick_Handler); // process all armed time events + + QK_ISR_EXIT(); // inform the QK kernel of exiting the ISR +} + +//............................................................................ +void BSP_init(void) { + SystemInit(); // initialize the clocking system + + // set LED port to output + LED_PORT->FIODIR |= (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT); + + // clear the LEDs + LED_PORT->FIOCLR = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT); + + QS_OBJ_DICTIONARY(&l_SysTick_Handler); +} + +//............................................................................ +void BSP_lcdScrollIn(char* line1, char* line2) { +// scroller algorithm + lcd.cls(); + char output1[17]; + char output2[17]; + for ( int i = 0; i < 17; i++) { + output1[i] = ' '; + output2[i] = ' '; + } + for (int i = 0; i < 17; i++) { + for (int col = 0; col < 17; col++) { + + if (col >= i) { + output1[col] = ' '; + output2[col] = ' '; + } else { + output1[col] = (line1[col+(16-i)]); + output2[col] = (line2[col+(16-i)]); + } + lcd.locate(col,0); + lcd.putc(output1[col]); + lcd.locate(col,1); + lcd.putc(output2[col]); + } + wait(0.4); + } +} + +//............................................................................ +void BSP_lcdUpdate(char* line1,char* line2) { + uint8_t length1 = strlen(line1); + uint8_t length2 = strlen(line2); + if (length1 > length2) + length1 = length2; + lcd.cls(); + if (length1 < 17) + for (int col = 0; col < 17 && col < length1; col++) { + lcd.locate(col,0); + lcd.putc(*(line1+col)); + lcd.locate(col,1); + lcd.putc(*(line2+col)); + } + else + for (int col = 0; col < 17; col++) { + lcd.locate(col,0); + lcd.putc(*(line1+col)); + lcd.locate(col,1); + lcd.putc(*(line2+col)); + } +} + +//............................................................................ +void QF::onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // set priorities of all interrupts in the system... + NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIO); + //NVIC_SetPriority(EINT0_IRQn, GPIOPORTA_PRIO); + + //NVIC_EnableIRQ(EINT0_IRQn); +} +//............................................................................ +void QF::onCleanup(void) { +} +//............................................................................ +void QK::onIdle(void) { + + QF_INT_LOCK(dummy); + LED_PORT->FIOSET = LED4_BIT; // turn the LED4 on + __NOP(); // delay a bit to see some light intensity + __NOP(); + __NOP(); + __NOP(); + LED_PORT->FIOCLR = LED4_BIT; // turn the LED4 off + QF_INT_UNLOCK(dummy); + + __WFI(); +} + +//............................................................................ +void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file, int line) { + (void)file; // avoid compiler warning + (void)line; // avoid compiler warning + QF_INT_LOCK(dummy); // make sure that all interrupts are disabled + // light up all LEDs + LED_PORT->FIOSET = (LED1_BIT | LED2_BIT | LED3_BIT | LED4_BIT); + + for (;;) { // NOTE: replace the loop with reset for final version + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bsp.h Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,13 @@ +#ifndef bsp_h +#define bsp_h + +#include "TextLCD.h" + +#define BSP_TICKS_PER_SEC 100 // system clock tick rate + +TextLCD lcd(p10, p11, p17, p18, p19, p20); // rs, e, d4-d7 + +void BSP_init(void); +void BSP_lcdScrollIn(char*, char*); // display functions +void BSP_lcdUpdate(char*,char*); +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hangman.h Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,29 @@ +#ifndef hangman_h +#define hangman_h + +#include "bsp.h" + +enum HangmanSignals { + START_SIG, + PLAY_SIG, + SELECT_SIG, + WIN_SIG, + LOOSE_SIG, + FINISHED_SIG, + TERMINATE_SIG, + MAX_PUB_SIG, + + SCROLL_SIG, + MAX_SIG +}; + +struct HostEvt : public QEvent { + int scroll_pos; // +1 - up, 0 - nochange, -1 - down +}; + +enum { MAX_LETTERS = 8 }; // max wrong letters before loosing + +extern QActive * const AO_Player; // active object "opaque" pointers +extern QActive * const AO_Host; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host.cpp Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,185 @@ +#include "qp_port.h" +#include "hangman.h" +#include "bsp.h" + +class Host : public QActive { +private: + char* word; + uint8_t selected_word; + uint8_t num_letters; + uint8_t incorrect_letters; + char* used_letters; + + char letter; + char output1[17]; // buffer for display + char output2[17]; + +public: + Host(); + +private: + static QState initial(Host *me, QEvent const *e); + static QState welcome(Host *me, QEvent const *e); + static QState playing(Host *me, QEvent const *e); +}; + +#define BANK_SIZE 4 +char* const word_bank[] = { "hangmann", "global", "micro", "sensor" }; +char* const win_msg = " You Win!"; +char* const loose_msg = " You suck!"; +char* const press_play_msg = "Push to continue"; + + +// Local objects ------------------------------------------------------------- +static Host l_host; // local Host object + +// Public-scope objects ------------------------------------------------------ +QActive * const AO_Host = &l_host; // "opaque" AO pointer + +//............................................................................ +Host::Host() : QActive((QStateHandler)&Host::initial) { +} + +//............................................................................ +QState Host::initial(Host *me, QEvent const *e) { + + QS_OBJ_DICTIONARY(&l_host); + QS_FUN_DICTIONARY(&QHsm::top); + QS_FUN_DICTIONARY(&Host::initial); + QS_FUN_DICTIONARY(&Host::playing); + + QS_SIG_DICTIONARY(TERMINATE_SIG, 0); // global signal + + QS_SIG_DICTIONARY(START_SIG, me); // signals for Host + QS_SIG_DICTIONARY(SCROLL_SIG, me); + QS_SIG_DICTIONARY(SELECT_SIG, me); + + me->subscribe(TERMINATE_SIG); + + // output welcome message + BSP_lcdUpdate("Push btn to play mbed hangman!",""); + wait(2.0); // pause for 2 seconds + + return Q_TRAN(&Host::welcome); +} + +//............................................................................ +QState Host::welcome(Host *me, QEvent const *e) { + HostEvt *pe; + + switch (e->sig) { + case START_SIG: { + uint8_t idx; + + // init the game + time_t seconds = time(NULL); + me->selected_word = seconds % BANK_SIZE; + me->word = word_bank[me->selected_word]; + me->num_letters = strlen(me->word); + me->incorrect_letters = 0; + for (int i = 0; i < 17; i++) { // clear output + me->output1[i] = ' '; + me->output2[i] = ' '; + } + + for (idx = 0; idx < me->num_letters; idx++) { + me->output1[idx] = '_'; + } + for (; idx < 16; idx++) { + me->output1[idx] = ' '; + } + me->letter = 'a'; + idx = 16; + me->output1[idx] = me->letter; + // clear output2 + for (idx = 0; idx < 17; idx++) + me->output2[idx] = ' '; + + BSP_lcdUpdate(me->output1, me->output2); // update display + + // post play to player + pe = Q_NEW(HostEvt, PLAY_SIG); + pe->scroll_pos = 0; // center + QF::PUBLISH(pe, me); + + return Q_TRAN(&Host::playing); + } + case TERMINATE_SIG: { + QF::stop(); + return Q_HANDLED(); + } + } + return Q_SUPER(&QHsm::top); +} + +//............................................................................ +QState Host::playing(Host *me, QEvent const *e) { + + HostEvt *pe; + + switch (e->sig) { + case SCROLL_SIG: { + if (((HostEvt const *)e)->scroll_pos < 0) { // go down + if (me->letter == 'a') // wrap around + me->letter = 'z'; + else + me->letter--; + } else if (((HostEvt const *)e)->scroll_pos > 0) { // go up + if (me->letter == 'z') // wrap around + me->letter = 'a'; + else + me->letter++; + } + me->output1[16] = me->letter; + BSP_lcdUpdate(me->output1,me->output2); + + return Q_HANDLED(); + } + case SELECT_SIG: { + // test for letter in word + char * pch; + pch=strchr(me->word,me->letter); + if (pch != NULL) { // found in word + do { + me->word[pch-me->word] = ' '; + me->output1[pch-me->word] = me->letter; + pch=strchr(pch+1,me->letter); + } while (pch!=NULL); + // update screen + BSP_lcdUpdate(me->output1,me->output2); + // test for win + if (strpbrk(me->word,"abcdefghijklmnopqrs") == NULL) { // win! + BSP_lcdScrollIn(win_msg, press_play_msg); // win msg + // post play to player + HostEvt *pe = Q_NEW(HostEvt, WIN_SIG); + pe->scroll_pos = 0; // center + QF::PUBLISH(pe, me); + + // go to welcome state + return Q_TRAN(&Host::welcome); + } + } else { + if (++me->incorrect_letters >= MAX_LETTERS) { // loose + BSP_lcdScrollIn(loose_msg, press_play_msg); // message + // post play to player + HostEvt *pe = Q_NEW(HostEvt, WIN_SIG); + pe->scroll_pos = 0; // center + QF::PUBLISH(pe, me); + + // go to welcome state + return Q_TRAN(&Host::welcome); + } else { + // post to used letters + me->output2[me->incorrect_letters-1] = (char)(me->letter - 33); // make uppercase + BSP_lcdUpdate(me->output1,me->output2); // update screen + } + } + return Q_HANDLED(); + } + case TERMINATE_SIG: { + QF::stop(); + return Q_HANDLED(); + } + } + return Q_SUPER(&QHsm::top); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,12 @@ +#include "mbed.h" + +DigitalOut myled(LED1); + +int main() { + while(1) { + myled = 1; + wait(0.2); + myled = 0; + wait(0.2); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/14f4805c468c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qp.lib Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/QL/code/qp/#934bb9eea80b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qp_config.h Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,10 @@ +#ifndef qp_config_h +#define qp_config_h + +// enable preemptive QK kernel +#define QK_PREEMPTIVE + +// define maximum number of active objects +#define QF_MAX_ACTIVE + +#endif \ No newline at end of file