Browse Source

adding menu and game support

feature/2015
tixiv 16 years ago
parent
commit
ce5ac2ef9a
  1. 7
      Makefile
  2. 119
      animations/snake.c
  3. 231
      avr5.x
  4. 4
      borg_hw/borg_hw_borg16.c
  5. 11
      borg_hw/config_borg16.in
  6. 19
      config.h
  7. 2
      defaults.mk
  8. 2
      depend.mk
  9. 4
      display_loop.c
  10. 12
      games/Makefile
  11. 138
      games/snake_game.c
  12. 16
      joystick.h
  13. 9
      menu/Makefile
  14. 74
      menu/menu.c
  15. 12
      menu/menu.h
  16. 5
      simulator/i386pe.x
  17. 3
      simulator/joystick.c
  18. 2
      simulator/joystick.h

7
Makefile

@ -15,8 +15,8 @@ SRC_SIM = \
LAUNCH_BOOTLOADER = launch-bootloader LAUNCH_BOOTLOADER = launch-bootloader
SERIAL = /dev/ttyUSB0 #SERIAL = /dev/ttyUSB0
SERIAL = COM5
export TOPDIR export TOPDIR
############################################################################## ##############################################################################
@ -40,6 +40,7 @@ include defaults.mk
@ echo "checking in which subdirs to build" @ echo "checking in which subdirs to build"
@ $(RM) -f $@ @ $(RM) -f $@
@ echo "SUBDIRS += animations" >> $@ @ echo "SUBDIRS += animations" >> $@
# @ echo "SUBDIRS += animations games menu" >> $@
@ (for subdir in `grep -e "^#define .*_SUPPORT" autoconf.h \ @ (for subdir in `grep -e "^#define .*_SUPPORT" autoconf.h \
| sed -e "s/^#define //" -e "s/_SUPPORT.*//" \ | sed -e "s/^#define //" -e "s/_SUPPORT.*//" \
| tr "[A-Z]\\n" "[a-z] " `; do \ | tr "[A-Z]\\n" "[a-z] " `; do \
@ -159,7 +160,7 @@ mrproper:
$(RM) -f autoconf.h .config config.mk .menuconfig.log .config.old $(RM) -f autoconf.h .config config.mk .menuconfig.log .config.old
sflash: $(TARGET).hex sflash: $(TARGET).hex
$(LAUNCH_BOOTLOADER) $(SERIAL) 115200 # $(LAUNCH_BOOTLOADER) $(SERIAL) 115200
avrdude -p m32 -b 115200 -u -c avr109 -P $(SERIAL) -U f:w:$< -F avrdude -p m32 -b 115200 -u -c avr109 -P $(SERIAL) -U f:w:$< -F
echo X > $(SERIAL) echo X > $(SERIAL)

119
animations/snake.c

@ -128,122 +128,3 @@ void snake(){
} }
} }
void snake_game() {
pixel pixels[64] = {{4, 14},{4, 13}};
pixel * head = &pixels[1];
pixel * tail = &pixels[0];
pixel old_head;
pixel apples[10];
uint8_t joy, joy_old=0xff, joy_cmd=0xff;
unsigned char x, y, dead = 0;
unsigned char apple_num = 0;
direction dir = up;
unsigned char apple_found = 0;
unsigned char j;
clear_screen(0);
// zeichne Rahmen
for (x = 0; x < NUM_COLS; x++) {
for (y = 0; y < NUM_ROWS; y++) {
if (((x == 0) || (x == NUM_COLS-1)) ||
((y == 0) || (y == NUM_ROWS-1))) {
setpixel((pixel) {x, y}, 3);
}
}
}
x = 0;
while (1) {
x++;
old_head = *head;
++head;
if (head == pixels + 64)
head = pixels;
if (joy_cmd == right) {
dir = direction_r(dir);
joy_cmd = 0xff;
} else if (joy_cmd == left) {
dir = direction_r(dir);
dir = direction_r(dir);
dir = direction_r(dir);
joy_cmd = 0xff;
}
// kopf einen weiter bewegen
*head = next_pixel(old_head, dir);
apple_found = 0;
// prŸfen ob man auf nen Apfel drauf ist
for (j = 0; j < apple_num; j++) {
if ( ( head->x == apples[j].x) &&
(head->y == apples[j].y) ){
apple_found = 1;
for(; j < apple_num - 1; j++) {
apples[j] = apples[j+1];
}
apple_num--;
goto apple_se;
}
}
if (get_pixel(*head)) {
dead = 1;
}
apple_se:
if (!dead) {
setpixel(*head, 3);
// setze neue €pfel
if ( (apple_num < 9) && (random8() < 10) ) {
pixel new_apple = (pixel) {(random8() % (NUM_COLS-2))+1,
(random8() % (NUM_ROWS-2))+1};
if (!get_pixel(new_apple)){
apples[apple_num++] = new_apple;
}
}
// lšsche Ende
if (!apple_found && !dead) {
clearpixel(*tail);
if (++tail == pixels + 64)
tail = pixels;
}
} else {
while (tail != head) {
clearpixel(*tail);
if ((++tail) > pixels + 64)
tail = pixels;
wait (60);
}
break;
}
for (j = 0; j < apple_num; j++) {
if (x % 2) {
setpixel(apples[j], 3);
} else {
clearpixel(apples[j]);
}
}
for(j=0;j<20;j++){
if(JOYISLEFT){
joy = left;
}else if(JOYISRIGHT){
joy = right;
}else{
joy = 0xff;
}
if(joy != joy_old){
joy_cmd = joy;
}
joy_old = joy;
wait (5);
}
}
}

231
avr5.x

@ -0,0 +1,231 @@
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = 128K
data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
}
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
}
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
}
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
}
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
}
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
}
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
/* Internal text space or external memory. */
.text :
{
*(.vectors)
KEEP(*(.vectors))
/* For data that needs to reside in the lower 64k of progmem. */
*(.progmem.gcc*)
*(.progmem*)
. = ALIGN(2);
__trampolines_start = . ;
/* The jump trampolines for the 16-bit limited relocs will reside here. */
*(.trampolines)
*(.trampolines*)
__trampolines_end = . ;
/* For future tablejump instruction arrays for 3 byte pc devices.
We don't relax jump/call instructions within these sections. */
*(.jumptables)
*(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
__ctors_start = . ;
*(.ctors)
__ctors_end = . ;
__dtors_start = . ;
*(.dtors)
__dtors_end = . ;
KEEP(SORT(*)(.ctors))
KEEP(SORT(*)(.dtors))
/* From this point on, we don't bother about wether the insns are
below or above the 16 bits boundary. */
*(.init0) /* Start here after reset. */
KEEP (*(.init0))
*(.init1)
KEEP (*(.init1))
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init2))
*(.init3)
KEEP (*(.init3))
*(.init4) /* Initialize data and BSS. */
KEEP (*(.init4))
*(.init5)
KEEP (*(.init5))
*(.init6) /* C++ constructors. */
KEEP (*(.init6))
*(.init7)
KEEP (*(.init7))
*(.init8)
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
*(.text)
. = ALIGN(2);
*(.text.*)
. = ALIGN(2);
*(.fini9) /* _exit() starts here. */
KEEP (*(.fini9))
*(.fini8)
KEEP (*(.fini8))
*(.fini7)
KEEP (*(.fini7))
*(.fini6) /* C++ destructors. */
KEEP (*(.fini6))
*(.fini5)
KEEP (*(.fini5))
*(.fini4)
KEEP (*(.fini4))
*(.fini3)
KEEP (*(.fini3))
*(.fini2)
KEEP (*(.fini2))
*(.fini1)
KEEP (*(.fini1))
*(.fini0) /* Infinite loop after program termination. */
KEEP (*(.fini0))
_etext = . ;
} > text
.data : AT (ADDR (.text) + SIZEOF (.text))
{
PROVIDE (__data_start = .) ;
*(.data)
*(.data*)
*(.rodata) /* We need to include .rodata here if gcc is used */
*(.rodata*) /* with -fdata-sections. */
*(.gnu.linkonce.d*)
__game_descriptors_start__ = . ;
*(.game_descriptors)
__game_descriptors_end__ = . ;
. = ALIGN(2);
_edata = . ;
PROVIDE (__data_end = .) ;
} > data
.bss SIZEOF(.data) + ADDR(.data) :
{
PROVIDE (__bss_start = .) ;
*(.bss)
*(.bss*)
*(COMMON)
PROVIDE (__bss_end = .) ;
} > data
__data_load_start = LOADADDR(.data);
__data_load_end = __data_load_start + SIZEOF(.data);
/* Global data not cleared after reset. */
.noinit SIZEOF(.bss) + ADDR(.bss) :
{
PROVIDE (__noinit_start = .) ;
*(.noinit*)
PROVIDE (__noinit_end = .) ;
_end = . ;
PROVIDE (__heap_start = .) ;
} > data
.eeprom :
{
*(.eeprom*)
__eeprom_end = . ;
} > eeprom
.fuse :
{
KEEP(*(.fuse))
KEEP(*(.lfuse))
KEEP(*(.hfuse))
KEEP(*(.efuse))
} > fuse
.lock :
{
KEEP(*(.lock*))
} > lock
.signature :
{
KEEP(*(.signature*))
} > signature
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

4
borg_hw/borg_hw_borg16.c

@ -51,7 +51,7 @@ inline void nextrow(uint8_t row){
if (row == 0){ if (row == 0){
//Zeile 0: Das erste Schieberegister initialisieren //Zeile 0: Das erste Schieberegister initialisieren
#ifndef INVERSE_ROWS #ifndef INVERT_ROWS
ROWPORT&= ~(1<<PIN_MCLR); ROWPORT&= ~(1<<PIN_MCLR);
ROWPORT|= (1<<PIN_MCLR); ROWPORT|= (1<<PIN_MCLR);
ROWPORT|= (1<<PIN_DATA); ROWPORT|= (1<<PIN_DATA);
@ -104,7 +104,7 @@ inline void rowshow(unsigned char row, unsigned char plane){
tmp = pixmap[plane][row][0]; tmp = pixmap[plane][row][0];
tmp1 = pixmap[plane][row][1]; tmp1 = pixmap[plane][row][1];
#endif #endif
#ifdef REVERSED_HARDWARE #ifdef REVERSE_COLS
tmp = (tmp >> 4) | (tmp << 4); tmp = (tmp >> 4) | (tmp << 4);
tmp = ((tmp & 0xcc) >> 2) | ((tmp & 0x33)<< 2); //0xcc = 11001100, 0x33 = 00110011 tmp = ((tmp & 0xcc) >> 2) | ((tmp & 0x33)<< 2); //0xcc = 11001100, 0x33 = 00110011
tmp = ((tmp & 0xaa) >> 1) | ((tmp & 0x55)<< 1); //0xaa = 10101010, 0x55 = 1010101 tmp = ((tmp & 0xaa) >> 1) | ((tmp & 0x55)<< 1); //0xaa = 10101010, 0x55 = 1010101

11
borg_hw/config_borg16.in

@ -74,4 +74,15 @@ choice 'DATA Pin' \
Pin7 7" \ Pin7 7" \
'Pin7' PIN_DATA 'Pin7' PIN_DATA
comment "fixing hardwareproblems in software"
bool "reverse cols" REVERSE_COLS n
bool "invert rows " INVERT_ROWS n
comment "for borg jacket"
bool "interlaced rows" INTERLACED_ROWS n
bool "interlaced cols" INTERLACED_COLS n
endmenu endmenu

19
config.h

@ -12,13 +12,8 @@
#define SNAKE_DELAY 100 #define SNAKE_DELAY 100
//#define SCROLLTEXT_STRING_SIZE 128 /*
//#define SCROLLTEXT_FONT font_arial8 #define BORG_CAN
//#define SCROLLTEXT_DEFAULT "</#www.das-labor.org"
//#define SCROLL_X_SPEED 20
//#define SCROLL_Y_SPEED 20
//#define BORG_CAN
// spi.[ch] defines // spi.[ch] defines
#define SPI_HARDWARE #define SPI_HARDWARE
@ -40,18 +35,10 @@
#define CAN_RX_BUFFER_SIZE 2 //only used for Interrupt #define CAN_RX_BUFFER_SIZE 2 //only used for Interrupt
#define CAN_TX_BUFFER_SIZE 2 //only used for Interrupt #define CAN_TX_BUFFER_SIZE 2 //only used for Interrupt
#define F_MCP F_CPU #define F_MCP F_CPU
*/
#define INIT_EEPROM #define INIT_EEPROM
//#define UART_BAUD_RATE 115200L //#define UART_BAUD_RATE 115200L
#define REVERSED_HARDWARE
//#define INVERSE_ROWS
//#define INTERLACED_ROWS
//#define INTERLACED_COLS
#endif /* CONFIG_H_ */ #endif /* CONFIG_H_ */

2
defaults.mk

@ -22,7 +22,7 @@ CFLAGS ?= -Wall -W -Wno-unused-parameter -Wno-sign-compare
CFLAGS += -g -Os -std=gnu99 -fgnu89-inline CFLAGS += -g -Os -std=gnu99 -fgnu89-inline
# flags for the linker # flags for the linker
LDFLAGS += -mmcu=$(MCU) LDFLAGS += -mmcu=$(MCU) -T avr5.x
############################################################################# #############################################################################

2
depend.mk

@ -45,4 +45,4 @@ if test -s $@.new; then mv -f $@.new $@; else rm -f $@.new; fi
endef endef
obj_sim/%.d: %.c ; $(make-deps-sim) obj_sim/%.d: %.c ; @ $(make-deps-sim)

4
display_loop.c

@ -30,7 +30,11 @@ void display_loop(){
mode = setjmp(newmode_jmpbuf); mode = setjmp(newmode_jmpbuf);
oldOldmode = oldMode; oldOldmode = oldMode;
#ifdef JOYSTICK_SUPPORT
waitForFire = 1; waitForFire = 1;
#endif
for(;;){ for(;;){
oldMode = mode; oldMode = mode;
switch(mode++) { switch(mode++) {

12
games/Makefile

@ -0,0 +1,12 @@
TARGET = libanimations.a
TOPDIR = ..
include $(TOPDIR)/defaults.mk
#ifeq ($(GAME_SNAKE),y)
SRC += snake_game.c
#endif
include $(TOPDIR)/rules.mk

138
games/snake_game.c

@ -0,0 +1,138 @@
#include "../config.h"
#include "../compat/pgmspace.h"
#include "../menu/menu.h"
#include "../pixel.h"
#include "../random/prng.h"
#include "../util.h"
#include "../joystick.h"
// MSB is leftmost pixel
static uint8_t icon[8] PROGMEM =
{0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xad, 0xa1, 0xbf}; // Snake icon
void snake_game();
game_descriptor_t snake_game_descriptor __attribute__((section(".game_descriptors"))) ={
&snake_game,
icon,
};
void snake_game() {
pixel pixels[64] = {{4, 14},{4, 13}};
pixel * head = &pixels[1];
pixel * tail = &pixels[0];
pixel old_head;
pixel apples[10];
uint8_t joy, joy_old=0xff, joy_cmd=0xff;
unsigned char x, y, dead = 0;
unsigned char apple_num = 0;
direction dir = up;
unsigned char apple_found = 0;
unsigned char j;
clear_screen(0);
// zeichne Rahmen
for (x = 0; x < NUM_COLS; x++) {
for (y = 0; y < NUM_ROWS; y++) {
if (((x == 0) || (x == NUM_COLS-1)) ||
((y == 0) || (y == NUM_ROWS-1))) {
setpixel((pixel) {x, y}, 3);
}
}
}
x = 0;
while (1) {
x++;
old_head = *head;
++head;
if (head == pixels + 64)
head = pixels;
if (joy_cmd == right) {
dir = direction_r(dir);
joy_cmd = 0xff;
} else if (joy_cmd == left) {
dir = direction_r(dir);
dir = direction_r(dir);
dir = direction_r(dir);
joy_cmd = 0xff;
}
// kopf einen weiter bewegen
*head = next_pixel(old_head, dir);
apple_found = 0;
// pr?fen ob man auf nen Apfel drauf ist
for (j = 0; j < apple_num; j++) {
if ( ( head->x == apples[j].x) &&
(head->y == apples[j].y) ){
apple_found = 1;
for(; j < apple_num - 1; j++) {
apples[j] = apples[j+1];
}
apple_num--;
goto apple_se;
}
}
if (get_pixel(*head)) {
dead = 1;
}
apple_se:
if (!dead) {
setpixel(*head, 3);
// setze neue ?pfel
if ( (apple_num < 9) && (random8() < 10) ) {
pixel new_apple = (pixel) {(random8() % (NUM_COLS-2))+1,
(random8() % (NUM_ROWS-2))+1};
if (!get_pixel(new_apple)){
apples[apple_num++] = new_apple;
}
}
// l?sche Ende
if (!apple_found && !dead) {
clearpixel(*tail);
if (++tail == pixels + 64)
tail = pixels;
}
} else {
while (tail != head) {
clearpixel(*tail);
if ((++tail) > pixels + 64)
tail = pixels;
wait (60);
}
break;
}
for (j = 0; j < apple_num; j++) {
if (x % 2) {
setpixel(apples[j], 3);
} else {
clearpixel(apples[j]);
}
}
for(j=0;j<20;j++){
if(JOYISLEFT){
joy = left;
}else if(JOYISRIGHT){
joy = right;
}else{
joy = 0xff;
}
if(joy != joy_old){
joy_cmd = joy;
}
joy_old = joy;
wait (5);
}
}
}

16
joystick.h

@ -1,9 +1,11 @@
#ifndef JOYSTICK_H #ifndef JOYSTICK_H
#define JOYSTICK_H #define JOYSTICK_H
unsigned char waitForFire; extern unsigned char waitForFire;
void joy_init(); void joy_init();
#ifdef AVR
#define BITFIRE PD3 #define BITFIRE PD3
#define BITRIGHT PB3 #define BITRIGHT PB3
#define BITLEFT PB2 #define BITLEFT PB2
@ -16,4 +18,16 @@ void joy_init();
#define JOYISDOWN (!(PINB & (1<<BITDOWN))) #define JOYISDOWN (!(PINB & (1<<BITDOWN)))
#define JOYISUP (!(PINB & (1<<BITUP))) #define JOYISUP (!(PINB & (1<<BITUP)))
#else
extern unsigned char fakeport;
#define JOYISFIRE (0x01 & fakeport)
#define JOYISLEFT (0x02 & fakeport)
#define JOYISRIGHT (0x04 & fakeport)
#define JOYISDOWN (0x08 & fakeport)
#define JOYISUP (0x10 & fakeport)
#endif
#endif // JOYSTICK_H #endif // JOYSTICK_H

9
menu/Makefile

@ -0,0 +1,9 @@
TARGET = libanimations.a
TOPDIR = ..
include $(TOPDIR)/defaults.mk
SRC = menu.c
include $(TOPDIR)/rules.mk

74
menu/menu.c

@ -8,24 +8,21 @@
#include <inttypes.h> #include <inttypes.h>
// architecture dependent stuff // architecture dependent stuff
#ifdef __AVR__ #include "../compat/pgmspace.h"
#include <avr/pgmspace.h>
#define WAIT(ms) wait(ms)
#else
#define PROGMEM
#define WAIT(ms) myWait(ms)
#endif
#include "menu.h" #include "menu.h"
#include "config.h" #include "../config.h"
#include "util.h" #include "../util.h"
#include "pixel.h" #include "../pixel.h"
#include "joystick.h" #include "../joystick.h"
#include "snake.h"
#include "tetris/logic.h"
#include "invaders2.h" extern game_descriptor_t _game_descriptors_start__[];
extern game_descriptor_t _game_descriptors_end__[];
// defines // defines
#define MENU_ITEM_MAX (((int)_game_descriptors_end__ - (int)_game_descriptors_start__)/sizeof(game_descriptor_t))
#define MENU_WIDTH_ICON 8 #define MENU_WIDTH_ICON 8
#define MENU_HEIGHT_ICON 8 #define MENU_HEIGHT_ICON 8
#define MENU_WIDTH_DELIMITER 2 #define MENU_WIDTH_DELIMITER 2
@ -48,11 +45,11 @@ void menu()
// wait as long the fire button is pressed to prevent unwanted selections // wait as long the fire button is pressed to prevent unwanted selections
while (JOYISFIRE) while (JOYISFIRE)
{ {
WAIT(MENU_POLL_INTERVAL); wait(MENU_POLL_INTERVAL);
} }
// set initial menu item // set initial menu item
static menu_item_t miSelection = MENU_ITEM_TETRIS; static uint8_t miSelection = 0;
// scroll in currently selected menu item // scroll in currently selected menu item
menu_animate(MENU_PREVITEM(miSelection), MENU_DIRECTION_LEFT); menu_animate(MENU_PREVITEM(miSelection), MENU_DIRECTION_LEFT);
@ -66,27 +63,17 @@ void menu()
// prevent unwanted selections // prevent unwanted selections
while (JOYISFIRE) while (JOYISFIRE)
{ {
WAIT(MENU_POLL_INTERVAL); wait(MENU_POLL_INTERVAL);
} }
// work against the chatter effects of dump joysticks // work against the chatter effects of dump joysticks
WAIT(MENU_WAIT_CHATTER); wait(MENU_WAIT_CHATTER);
// call corresponding function // call corresponding function
switch (miSelection)
{ _game_descriptors_start__[miSelection].run();
case MENU_ITEM_SNAKE:
snake_game();
break;
case MENU_ITEM_SPACEINVADERS:
borg_invaders();
break;
case MENU_ITEM_TETRIS:
tetris();
break;
default:
break;
}
break; break;
} }
// change selected item and do some scrolling // change selected item and do some scrolling
else if (JOYISRIGHT) else if (JOYISRIGHT)
@ -109,7 +96,7 @@ void menu()
// return if timeout is reached // return if timeout is reached
else else
{ {
WAIT(MENU_POLL_INTERVAL); wait(MENU_POLL_INTERVAL);
if (--nMenuIterations == 0) if (--nMenuIterations == 0)
break; break;
} }
@ -119,23 +106,24 @@ void menu()
return; return;
} }
uint8_t menu_getIconPixel(menu_item_t item, int8_t x, int8_t y)
uint8_t menu_getIconPixel(uint8_t item, int8_t x, int8_t y)
{ {
/*
// MSB is leftmost pixel // MSB is leftmost pixel
static uint8_t nIcon[][8] PROGMEM = static uint8_t nIcon[][8] PROGMEM =
{{0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xad, 0xa1, 0xbf}, // Snake icon {{0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xad, 0xa1, 0xbf}, // Snake icon
{0x66, 0x18, 0x3c, 0x5a, 0xff, 0xbd, 0xa5, 0x18}, // Invaders icon {0x66, 0x18, 0x3c, 0x5a, 0xff, 0xbd, 0xa5, 0x18}, // Invaders icon
{0x0f, 0x0f, 0xc3, 0xdb, 0xdb, 0xc3, 0xf0, 0xf0}}; // Tetris icon {0x0f, 0x0f, 0xc3, 0xdb, 0xdb, 0xc3, 0xf0, 0xf0}}; // Tetris icon
*/
// is x within the icon or do we have reached the delimiter? // is x within the icon or do we have reached the delimiter?
if (x < MENU_WIDTH_ICON) if (x < MENU_WIDTH_ICON)
{ {
// return pixel // return pixel
#ifdef __AVR__ return (0x80 >> x) & pgm_read_word(&_game_descriptors_start__[item].icon[y]);
return (0x80 >> x) & pgm_read_word(&nIcon[item][y]);
#else
return (0x80 >> x) & nIcon[item][y];
#endif
} }
else else
{ {
@ -144,7 +132,7 @@ uint8_t menu_getIconPixel(menu_item_t item, int8_t x, int8_t y)
} }
} }
void menu_animate(menu_item_t miInitial, menu_direction_t direction) void menu_animate(uint8_t miInitial, menu_direction_t direction)
{ {
int16_t nWait= MENU_WAIT_INITIAL; int16_t nWait= MENU_WAIT_INITIAL;
@ -152,7 +140,7 @@ void menu_animate(menu_item_t miInitial, menu_direction_t direction)
int8_t nWidthSide = (NUM_COLS - MENU_WIDTH_ICON) / 2; int8_t nWidthSide = (NUM_COLS - MENU_WIDTH_ICON) / 2;
// determine the icon at the leftmost position // determine the icon at the leftmost position
menu_item_t mi = miInitial + MENU_ITEM_MAX; uint8_t mi = miInitial + MENU_ITEM_MAX;
int8_t nBack = nWidthSide / (MENU_WIDTH_ICON + MENU_WIDTH_DELIMITER); int8_t nBack = nWidthSide / (MENU_WIDTH_ICON + MENU_WIDTH_DELIMITER);
if ((nWidthSide % (MENU_WIDTH_ICON + MENU_WIDTH_DELIMITER)) != 0) if ((nWidthSide % (MENU_WIDTH_ICON + MENU_WIDTH_DELIMITER)) != 0)
{ {
@ -203,7 +191,7 @@ void menu_animate(menu_item_t miInitial, menu_direction_t direction)
int8_t y; int8_t y;
for (y = 0; y < MENU_HEIGHT_ICON; ++y) for (y = 0; y < MENU_HEIGHT_ICON; ++y)
{ {
menu_item_t miCurrent = mi; uint8_t miCurrent = mi;
int8_t nIconOffset = nInitialSideOffset; int8_t nIconOffset = nInitialSideOffset;
int8_t x; int8_t x;
for (x = 0; x < NUM_COLS; ++x) for (x = 0; x < NUM_COLS; ++x)
@ -231,7 +219,7 @@ void menu_animate(menu_item_t miInitial, menu_direction_t direction)
} }
// wait between the frames so that the animation can be seen // wait between the frames so that the animation can be seen
WAIT(nWait); wait(nWait);
// animation speed can be throtteled // animation speed can be throtteled
nWait += MENU_WAIT_INCREMENT; nWait += MENU_WAIT_INCREMENT;
} }

12
menu/menu.h

@ -8,6 +8,7 @@
#include <inttypes.h> #include <inttypes.h>
/*
typedef enum menu_item_t typedef enum menu_item_t
{ {
MENU_ITEM_SNAKE, MENU_ITEM_SNAKE,
@ -16,6 +17,7 @@ typedef enum menu_item_t
MENU_ITEM_MAX // fake entry to mark the end MENU_ITEM_MAX // fake entry to mark the end
} }
menu_item_t; menu_item_t;
*/
typedef enum menu_direction_t typedef enum menu_direction_t
{ {
@ -25,9 +27,15 @@ typedef enum menu_direction_t
} }
menu_direction_t; menu_direction_t;
typedef struct{
void(*run)(void);
uint8_t * icon;
}game_descriptor_t;
void menu(); void menu();
void menu_animate(menu_item_t currentItem, menu_direction_t direction); void menu_animate(uint8_t currentItem, menu_direction_t direction);
uint8_t menu_getIconPixel(menu_item_t item, int8_t x, int8_t y); uint8_t menu_getIconPixel(uint8_t item, int8_t x, int8_t y);
void menu_setpixel(int8_t x, int8_t y, int8_t isSet); void menu_setpixel(int8_t x, int8_t y, int8_t isSet);
#endif /*MENU_H_*/ #endif /*MENU_H_*/

5
simulator/i386pe.x

@ -38,7 +38,10 @@ SECTIONS
*(.data2) *(.data2)
*(SORT(.data$*)) *(SORT(.data$*))
*(.jcr) *(.jcr)
__data_end__ = . ; __game_descriptors_start__ = . ;
*(.game_descriptors)
__game_descriptors_end__ = . ;
__data_end__ = . ;
*(.data_cygwin_nocopy) *(.data_cygwin_nocopy)
} }
.rdata BLOCK(__section_alignment__) : .rdata BLOCK(__section_alignment__) :

3
simulator/joystick.c

@ -1,5 +1,8 @@
#include "joystick.h" #include "joystick.h"
unsigned char fakeport;
// fake function since our keybord doesn't need any initialisation // fake function since our keybord doesn't need any initialisation
void joy_init() void joy_init()
{ {

2
simulator/joystick.h

@ -1,7 +1,7 @@
#ifndef JOYSTICK_H_ #ifndef JOYSTICK_H_
#define JOYSTICK_H_ #define JOYSTICK_H_
unsigned char fakeport; extern unsigned char fakeport;
#define JOYISFIRE (0x01 & fakeport) #define JOYISFIRE (0x01 & fakeport)
#define JOYISLEFT (0x02 & fakeport) #define JOYISLEFT (0x02 & fakeport)

Loading…
Cancel
Save