We designed a two player hangman game with the graphics running on a VGA and the text being displayed on the Text LCD. The input is from a PS2 keyboard. One user enters a word which must be guessed by the second user. A buzzer is also included to indicate winning or losing.
#include "mbed.h"
#include "TFT_4DGL.h"
#include <stdarg.h>
#include "TextLCD.h"
#include <stdio.h>
#include "PS2Keyboard.h"
#include <string>
#include "beep.h"
Beep speaker(p22);
// overwrite 4DGL library screen size settings in TFT_4DGL.h
#define SIZE_X 479
#define SIZE_Y 639
TFT_4DGL ecran(p13,p14,p21); // serial tx, serial rx, reset pin;
TextLCD lcd(p24, p26, p27, p28, p29, p30);
PS2Keyboard ps2kb(p12, p11);
int outputrow = 1;
int j = 0;
char buffer[20480]; //working at 4608
char printbuf[256];
int linenum=1;
void myprintf1(int row_no,const char* format, ...)
{
char dest[256];
if(j>80) {
j=0;
}
va_list argptr;
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
for ( int i = 0; i < 256; i++) {
buffer[256*j+i]= dest[i];
}
j++;
int linenum = j;
for (int k = 0; k <256; k++) {
printbuf[k] = buffer[256*(linenum-1)+k];
}
// ecran.rectangle(0, 8*outputrow, 100, 8*outputrow+31, BLACK);
ecran.text_string( dest, row_no , 2 , FONT_8X8, WHITE);
wait(.1);
outputrow+= 2;
if(outputrow>58) {
outputrow =1;
}
}
void myprintf(const char* format, ...)
{
char dest[256];
if(j>80) {
j=0;
}
va_list argptr;
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
for ( int i = 0; i < 256; i++) {
buffer[256*j+i]= dest[i];
}
j++;
int linenum = j;
for (int k = 0; k <256; k++) {
printbuf[k] = buffer[256*(linenum-1)+k];
}
// ecran.rectangle(0, 8*outputrow, 100, 8*outputrow+31, BLACK);
ecran.text_string( dest, 2 , outputrow , FONT_8X8, WHITE);
wait(.1);
outputrow+= 2;
if(outputrow>58) {
outputrow =1;
}
}
PS2Keyboard::keyboard_event_t evt_kb;
int shift, ctrl, alt, numlock = 0, capslock = 0;
char kb_getc()
{
char ascii;
ascii = 0;
while(ascii == 0) {
if (ps2kb.processing(&evt_kb)) {
lcd.locate(0, 1);
//for (int i = 0; i < evt_kb.length; i++) {
// lcd.printf("%02X", evt_kb.scancode[i]);
// }
//for (int i = 0; i < 16 - evt_kb.length * 2; i++) {
// lcd.printf("-");
//}
if ( evt_kb.length == 1) {
switch (evt_kb.scancode[0]) {
//Keyboard mode key -Make-
case (0x12) :
shift = 1;
lcd.locate(11,0);
lcd.putc('S');
break;
case (0x59) :
shift = 1;
lcd.locate(11,0);
lcd.putc('S');
break;
case (0x14) :
ctrl = 1;
lcd.locate(12,0);
lcd.putc('C');
break;
case (0x11) :
alt = 1;
lcd.locate(13,0);
lcd.putc('A');
break;
case (0x77) :
numlock = (numlock) == 0 ? 1 : 0;
if (numlock == 1) {
lcd.locate(14,0);
lcd.putc('N');
} else {
lcd.locate(14,0);
lcd.putc(' ');
}
break;
case (0x58) :
capslock = (shift) == 1 ? !capslock : capslock;
if (capslock == 1) lcd.locate(15,0), lcd.putc('L');
else lcd.locate(15,0), lcd.putc(' ');
break;
//Character keys(ASCII) -Make-
case (0x29) :
ascii = ' ';
break; //space
case (0x0D) :
ascii = 0x09;
break; //tab
case (0x66) :
ascii = 0x08;
break; //BS
case (0x5A) :
ascii = 0x0D;
break; //ENTER
case (0x76) :
ascii = 0x1B;
break; //ESC
case (0x1C) :
ascii = (shift + capslock) == 1 ? 'A' : 'a';
break;
case (0x32) :
ascii = (shift + capslock) == 1 ? 'B' : 'b';
break;
case (0x21) :
ascii = (shift + capslock) == 1 ? 'C' : 'c';
break;
case (0x23) :
ascii = (shift + capslock) == 1 ? 'D' : 'd';
break;
case (0x24) :
ascii = (shift + capslock) == 1 ? 'E' : 'e';
break;
case (0x2B) :
ascii = (shift + capslock) == 1 ? 'F' : 'f';
break;
case (0x34) :
ascii = (shift + capslock) == 1 ? 'G' : 'g';
break;
case (0x33) :
ascii = (shift + capslock) == 1 ? 'H' : 'h';
break;
case (0x43) :
ascii = (shift + capslock) == 1 ? 'I' : 'i';
break;
case (0x3B) :
ascii = (shift + capslock) == 1 ? 'J' : 'j';
break;
case (0x42) :
ascii = (shift + capslock) == 1 ? 'K' : 'k';
break;
case (0x4B) :
ascii = (shift + capslock) == 1 ? 'L' : 'l';
break;
case (0x3A) :
ascii = (shift + capslock) == 1 ? 'M' : 'm';
break;
case (0x31) :
ascii = (shift + capslock) == 1 ? 'N' : 'n';
break;
case (0x44) :
ascii = (shift + capslock) == 1 ? 'O' : 'o';
break;
case (0x4D) :
ascii = (shift + capslock) == 1 ? 'P' : 'p';
break;
case (0x15) :
ascii = (shift + capslock) == 1 ? 'Q' : 'q';
break;
case (0x2D) :
ascii = (shift + capslock) == 1 ? 'R' : 'r';
break;
case (0x1B) :
ascii = (shift + capslock) == 1 ? 'S' : 's';
break;
case (0x2C) :
ascii = (shift + capslock) == 1 ? 'T' : 't';
break;
case (0x3C) :
ascii = (shift + capslock) == 1 ? 'U' : 'u';
break;
case (0x2A) :
ascii = (shift + capslock) == 1 ? 'V' : 'v';
break;
case (0x1D) :
ascii = (shift + capslock) == 1 ? 'W' : 'w';
break;
case (0x22) :
ascii = (shift + capslock) == 1 ? 'X' : 'x';
break;
case (0x35) :
ascii = (shift + capslock) == 1 ? 'Y' : 'y';
break;
case (0x1A) :
ascii = (shift + capslock) == 1 ? 'Z' : 'z';
break;
case (0x45) :
ascii = shift == 1 ? '0' : '0';
break;
case (0x16) :
ascii = shift == 1 ? '!' : '1';
break;
case (0x1E) :
ascii = shift == 1 ? '"' : '2';
break;
case (0x26) :
ascii = shift == 1 ? '#' : '3';
break;
case (0x25) :
ascii = shift == 1 ? '$' : '4';
break;
case (0x2E) :
ascii = shift == 1 ? '%' : '5';
break;
case (0x36) :
ascii = shift == 1 ? '&' : '6';
break;
case (0x3D) :
ascii = shift == 1 ? '\'' : '7';
break;
case (0x3E) :
ascii = shift == 1 ? '(' : '8';
break;
case (0x46) :
ascii = shift == 1 ? ')' : '9';
break;
case (0x4E) :
ascii = shift == 1 ? '=' : '-';
break;
case (0x7B) :
ascii = shift == 1 ? '-' : '-';
break;
case (0x4A) :
ascii = shift == 1 ? '?' : '/';
break;
case (0x41) :
ascii = shift == 1 ? '<' : ',';
break;
case (0x49) :
ascii = shift == 1 ? '>' : '.';
break;
case (0x6A) :
ascii = shift == 1 ? '|' : '\\';
break;
case (0x5B) :
ascii = shift == 1 ? '{' : '[';
break;
case (0x5D) :
ascii = shift == 1 ? '}' : ']';
break;
case (0x4C) :
ascii = shift == 1 ? '+' : ';';
break;
case (0x79) :
ascii = shift == 1 ? '+' : '+';
break;
case (0x51) :
ascii = shift == 1 ? '_' : '\\';
break;
case (0x54) :
ascii = shift == 1 ? '`' : '@';
break;
case (0x55) :
ascii = shift == 1 ? '~' : '^';
break;
case (0x7C) :
ascii = shift == 1 ? '*' : '*';
break;
case (0x52) :
ascii = shift == 1 ? '*' : ':';
break;
//Function keys -Make-
case (0x05) :
ascii = 0x05;
break; //F1
case (0x06) :
ascii = 0x06;
break; //F2
case (0x04) :
ascii = 0x04;
break; //F3
case (0x0C) :
ascii = 0x12;
break; //F4
case (0x03) :
ascii = 0x03;
break; //F5
case (0x0B) :
ascii = 0x11;
break; //F6
case (0x83) :
ascii = 0x13;
break; //F7
case (0x0A) :
ascii = 0x10;
break; //F8
case (0x01) :
ascii = 0x01;
break; //F9
case (0x09) :
ascii = 0x02;
break; //F10
case (0x78) :
ascii = 0x14;
break; //F11
case (0x07) :
ascii = 0x07;
break; //F12
//Tenkeys -Make-
case (0x75) :
ascii = numlock == 1 ? '8' : 0x15;
break; //UP
case (0x72) :
ascii = numlock == 1 ? '2' : 0x16;
break; //DOWN
case (0x6B) :
ascii = numlock == 1 ? '4' : 0x17;
break; //LEFT
case (0x74) :
ascii = numlock == 1 ? '6' : 0x18;
break; //RIGHT
case (0x6C) :
ascii = numlock == 1 ? '7' : 0x1C;
break; //HOME
case (0x69) :
ascii = numlock == 1 ? '1' : 0x1D;
break; //END
case (0x70) :
ascii = numlock == 1 ? '0' : 0x1E;
break; //INS
case (0x7D) :
ascii = numlock == 1 ? '9' : 0x19;
break; //PAGE UP
case (0x7A) :
ascii = numlock == 1 ? '3' : 0x1A;
break; //PAGE DOWN
case (0x71) :
ascii = numlock == 1 ? '.' : 0x7F;
break; //DEL
case (0x73) :
ascii = numlock == 1 ? '5' : '5';
break;
}
} else {
//Keyboard mode key -Break- F0xx
if ( evt_kb.length == 2 && evt_kb.scancode[0] == 0xF0) {
switch (evt_kb.scancode[1]) {
case (0x12) :
shift = 0;
lcd.locate(11,0);
lcd.putc(' ');
break;
case (0x59) :
shift = 0;
lcd.locate(11,0);
lcd.putc(' ');
break;
case (0x14) :
ctrl = 0;
lcd.locate(12,0);
lcd.putc(' ');
break;
case (0x11) :
alt = 0;
lcd.locate(13,0);
lcd.putc(' ');
break;
}
} else {
//Keyboard right mode keys, Arrow, Del -Make- E0xx
if ( evt_kb.length == 2 && evt_kb.scancode[0] == 0xE0) {
switch (evt_kb.scancode[1]) {
case (0x14) :
ctrl = 0;
lcd.locate(12,0);
lcd.putc(' ');
break;
case (0x11) :
alt = 0;
lcd.locate(13,0);
lcd.putc(' ');
break;
case (0x4A) :
ascii = '/';
break;
case (0x75) :
ascii = 0x15;
break; //UP
case (0x72) :
ascii = 0x16;
break; //DOWN
case (0x6B) :
ascii = 0x17;
break; //LEFT
case (0x74) :
ascii = 0x18;
break; //RIGHT
case (0x70) :
ascii = 0x1E;
break; //INSERT
case (0x71) :
ascii = 0x7F;
break; //DEL
case (0x5A) :
ascii = 0x0D;
break; //ENTER
}
} else {
//Keyboard right mode keys -Break- E0F0xx
if ( evt_kb.length == 3 && evt_kb.scancode[0] == 0xE0 && evt_kb.scancode[1] == 0xF0) {
switch (evt_kb.scancode[2]) {
case (0x14) :
ctrl = 0;
lcd.locate(12,0);
lcd.putc(' ');
break;
case (0x11) :
alt = 0;
lcd.locate(13,0);
lcd.putc(' ');
break;
}
}
}
}
}
}
} //while(ascii == 0)
return ascii;
} //kb_getc()
int main()
{
ecran.baudrate(115200);
ecran.display_control(0x0c, 0x01);
int col_count=1;
ecran.cls();
int chk_blank=0;
int wrong_count=0;
char chr[100];
char yn;
char ans[100], ans_temp;
int i=0;
int blank=0;
lcd.locate(0, 0);
bool end_cond = false;
int trial=10;
bool count= false;
while (1) {
if(!count) {
//first player
myprintf("Enter a Word");
while(chr[i]!=0x0D) {
i++;
chr[i] = kb_getc();
}
if(chr[i]==0x0D) {
count=true;
// i--;
}
for(int k=1; k<i; k++) {
if((chr[k] =='a')||(chr[k] =='e')||(chr[k] =='i')||(chr[k] =='o')||(chr[k] =='u')) {
ans[k]=chr[k];
} else {
ans[k]='_';
}
}
wait(.2);
for(int u=1; u<i; u++)
if(ans[u] == '_')
blank++;
ans[0]=' ';
lcd.locate(0,0);
lcd.cls();
for(int z=1; z<i; z++)
lcd.printf("%c",ans[z]);
lcd.printf(" ");
}
else {
//2nd player
ans[i]='\0';
if(trial>0) {
myprintf("enter char");
ans_temp = kb_getc();
for(int h=1; h<i; h++) {
if(ans_temp==chr[h]) {
chk_blank++;
ans[h]=chr[h];
} else
wrong_count++;
}
if(wrong_count==(i-1))
trial--;
myprintf("trial %i",trial);
switch(trial) {
case 0:
ecran.rectangle(410,322 ,415, 362 , WHITE);
//break;
case 1:
ecran.rectangle(440,322 ,435, 362 , WHITE);
//break;
case 2:
ecran.rectangle(408, 280,375, 285 , WHITE);
//break;
case 3:
ecran.rectangle(442, 280,475, 285 , WHITE);
//break;
case 4: //ecran.ellipse(425,290 ,5,30,WHITE);
ecran.circle(425,280,15,WHITE);
ecran.rectangle(440, 280,410, 320 , WHITE);
case 5:
ecran.circle(425,255,10,WHITE);
//break;
case 6:
ecran.pixel(425,250, BLUE);
ecran.line(425, 240, 425,200,BLUE);
//break;
case 7:
ecran.pixel(425,200, WHITE);
ecran.line(325, 200, 425,200,WHITE);
// break;
case 8:
ecran.pixel(325, 200, GREEN);
ecran.line(325, 200, 325,350,GREEN);
// break;
case 9:
ecran.line(300, 400, 325,350,RED);
ecran.line(350, 400, 325,350,RED);
ecran.pixel(325,350, RED);
ecran.pixel(300,400, RED);
ecran.pixel(350,400, RED);
//break;
// default:myprintf("correct");
}
wrong_count=0;
lcd.cls();
lcd.locate(0, 0);
for(int z=1; z<(i+1); z++)
lcd.printf("%c",ans[z]);
lcd.printf(" ");
if(blank==chk_blank) {
lcd.cls();
//lcd.printf("You win");
myprintf("You Win");
lcd.printf("You Win");
speaker.beep(100, .1);
wait(.1);
speaker.beep(100, .1);
wait(.1);
speaker.beep(100, .1);
wait(.1);
speaker.beep(100, .1);
wait(.1);
speaker.beep(100, .1);
wait(.1);
speaker.beep(100, .1);
end_cond=true;
}
//lcd.printf("%d trial ",trial);
} else {
lcd.cls();
lcd.printf("GAME OVER");
myprintf("GAME OVER");
speaker.beep(90, .5);
end_cond=true;
}
}
//ecran.cls();
if(end_cond==true) {
//myprintf("gng here");
ecran.cls();
myprintf("Play Again?");
yn=kb_getc();
//myprintf("you entered %c",yn);
if(yn=='y') {
//wait(.1);
//wait(.1);
trial=10;
count=false;
i=0;
end_cond=false;
}
else {
myprintf("bye");
return(-1);
}
}
}
return 0;
}