whitespace fun: removed those pesky ^M characters

This commit is contained in:
Christian Kroll 2014-03-20 05:12:21 +01:00
parent 6c862db18d
commit ec2a705456
16 changed files with 2278 additions and 2278 deletions

View File

@ -1,18 +1,18 @@
//EEPPROM compatibility support for simulator //EEPPROM compatibility support for simulator
#ifdef AVR #ifdef AVR
#include <avr/eeprom.h> #include <avr/eeprom.h>
#else #else
#include <stdint.h> #include <stdint.h>
void eeprom_write_byte (uint8_t *p, uint8_t value); void eeprom_write_byte (uint8_t *p, uint8_t value);
void eeprom_write_word (uint16_t *p, uint16_t value); void eeprom_write_word (uint16_t *p, uint16_t value);
uint8_t eeprom_read_byte (const uint8_t *p); uint8_t eeprom_read_byte (const uint8_t *p);
uint16_t eeprom_read_word (const uint16_t *p); uint16_t eeprom_read_word (const uint16_t *p);
#define eeprom_busy_wait() #define eeprom_busy_wait()
#define EEMEM __attribute__((section(".eeprom"))) #define EEMEM __attribute__((section(".eeprom")))
#endif #endif

View File

@ -1,3 +1,3 @@
#define sei() #define sei()
#define cli() #define cli()

View File

@ -1,4 +1,4 @@
void display_loop(); void display_loop();
extern jmp_buf newmode_jmpbuf; extern jmp_buf newmode_jmpbuf;

View File

@ -1,22 +1,22 @@
ifeq ($(GAME_TETRIS_CORE),y) ifeq ($(GAME_TETRIS_CORE),y)
SUBDIRS += $(TOPDIR)/games/tetris SUBDIRS += $(TOPDIR)/games/tetris
endif endif
ifeq ($(GAME_SPACE_INVADERS),y) ifeq ($(GAME_SPACE_INVADERS),y)
SUBDIRS += $(TOPDIR)/games/space_invaders SUBDIRS += $(TOPDIR)/games/space_invaders
endif endif
ifeq ($(GAME_SNAKE),y) ifeq ($(GAME_SNAKE),y)
SUBDIRS += $(TOPDIR)/games/snake SUBDIRS += $(TOPDIR)/games/snake
endif endif
ifeq ($(ANIMATION_SNAKE),y) ifeq ($(ANIMATION_SNAKE),y)
ifneq ($(GAME_SNAKE),y) ifneq ($(GAME_SNAKE),y)
SUBDIRS += $(TOPDIR)/games/snake SUBDIRS += $(TOPDIR)/games/snake
endif endif
endif endif
ifeq ($(GAME_BREAKOUT),y) ifeq ($(GAME_BREAKOUT),y)
SUBDIRS += $(TOPDIR)/games/breakout SUBDIRS += $(TOPDIR)/games/breakout
endif endif

View File

@ -1,471 +1,471 @@
/** /**
* \defgroup Snake Snake, a casual game including a demo mode. * \defgroup Snake Snake, a casual game including a demo mode.
* *
* @{ * @{
*/ */
/** /**
* @file snake_game.c * @file snake_game.c
* @brief Implementation of the snake game. * @brief Implementation of the snake game.
* @author Peter Fuhrmann, Martin Ongsiek, Daniel Otte, Christian Kroll * @author Peter Fuhrmann, Martin Ongsiek, Daniel Otte, Christian Kroll
*/ */
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
#include "../../config.h" #include "../../config.h"
#include "../../compat/pgmspace.h" #include "../../compat/pgmspace.h"
#include "../../pixel.h" #include "../../pixel.h"
#include "../../random/prng.h" #include "../../random/prng.h"
#include "../../util.h" #include "../../util.h"
#include "../../joystick/joystick.h" #include "../../joystick/joystick.h"
#include "../../menu/menu.h" #include "../../menu/menu.h"
#include "snake_game.h" #include "snake_game.h"
#if defined MENU_SUPPORT && defined GAME_SNAKE #if defined MENU_SUPPORT && defined GAME_SNAKE
// snake icon (MSB is leftmost pixel) // snake icon (MSB is leftmost pixel)
static const uint8_t icon[8] PROGMEM = static const uint8_t icon[8] PROGMEM =
{0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xad, 0xa1, 0xbf}; {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xad, 0xa1, 0xbf};
game_descriptor_t snake_game_descriptor __attribute__((section(".game_descriptors"))) = game_descriptor_t snake_game_descriptor __attribute__((section(".game_descriptors"))) =
{ {
&snake_game, &snake_game,
icon, icon,
}; };
#endif #endif
/** /**
* If defined, joystick controls are NOT as "seen" by the snake but absolute, * If defined, joystick controls are NOT as "seen" by the snake but absolute,
* that is, if pressing up, snake goes up, etc. * that is, if pressing up, snake goes up, etc.
*/ */
#define SNAKE_NEWCONTROL #define SNAKE_NEWCONTROL
#if !defined USNAKE_MAX_LENGTH || defined DOXYGEN #if !defined USNAKE_MAX_LENGTH || defined DOXYGEN
/** The maximum length of the snake. */ /** The maximum length of the snake. */
#define USNAKE_MAX_LENGTH 64u #define USNAKE_MAX_LENGTH 64u
#endif #endif
#if !defined SNAKE_MAX_APPLES || defined DOXYGEN #if !defined SNAKE_MAX_APPLES || defined DOXYGEN
/** The maximum number of apples lying on the playing field. */ /** The maximum number of apples lying on the playing field. */
#define SNAKE_MAX_APPLES 10 #define SNAKE_MAX_APPLES 10
#endif #endif
#if !defined SNAKE_CYCLE_DELAY || defined DOXYGEN #if !defined SNAKE_CYCLE_DELAY || defined DOXYGEN
/** Delay (in ms) between every state change. */ /** Delay (in ms) between every state change. */
#define SNAKE_CYCLE_DELAY 100 #define SNAKE_CYCLE_DELAY 100
#endif #endif
#if !defined SNAKE_TERMINATION_DELAY || defined DOXYGEN #if !defined SNAKE_TERMINATION_DELAY || defined DOXYGEN
/** Delay (in ms) between every disappearing pixel of a dying snake. */ /** Delay (in ms) between every disappearing pixel of a dying snake. */
#define SNAKE_TERMINATION_DELAY 60 #define SNAKE_TERMINATION_DELAY 60
#endif #endif
/** The color of the surrounding border. */ /** The color of the surrounding border. */
#define SNAKE_COLOR_BORDER 3 #define SNAKE_COLOR_BORDER 3
/** The color of the snake. */ /** The color of the snake. */
#define SNAKE_COLOR_PROTAGONIST 3 #define SNAKE_COLOR_PROTAGONIST 3
/** The color of the apples. */ /** The color of the apples. */
#define SNAKE_COLOR_APPLE 3 #define SNAKE_COLOR_APPLE 3
/** /**
* Directions of the snake. * Directions of the snake.
*/ */
enum snake_dir_e enum snake_dir_e
{ {
SNAKE_DIR_UP, /**< Snake is heading up. */ SNAKE_DIR_UP, /**< Snake is heading up. */
SNAKE_DIR_RIGHT,/**< Snake is heading right. */ SNAKE_DIR_RIGHT,/**< Snake is heading right. */
SNAKE_DIR_DOWN, /**< Snake is heading down. */ SNAKE_DIR_DOWN, /**< Snake is heading down. */
SNAKE_DIR_LEFT, /**< Snake is heading left. */ SNAKE_DIR_LEFT, /**< Snake is heading left. */
SNAKE_DIR_NONE /**< Helper value for a "resting" joystick. */ SNAKE_DIR_NONE /**< Helper value for a "resting" joystick. */
}; };
#ifdef NDEBUG #ifdef NDEBUG
typedef uint8_t snake_dir_t; typedef uint8_t snake_dir_t;
#else #else
typedef enum snake_dir_e snake_dir_t; typedef enum snake_dir_e snake_dir_t;
#endif #endif
/** /**
* This structure represents the snake character itself. It keeps track of the * This structure represents the snake character itself. It keeps track of the
* snake's segments, its head and tail and the direction it is heading. * snake's segments, its head and tail and the direction it is heading.
*/ */
typedef struct snake_protagonist_s typedef struct snake_protagonist_s
{ {
pixel aSegments[USNAKE_MAX_LENGTH]; /**< All segments of the snake. */ pixel aSegments[USNAKE_MAX_LENGTH]; /**< All segments of the snake. */
uint8_t nHeadIndex; /**< Index of the head segment. */ uint8_t nHeadIndex; /**< Index of the head segment. */
uint8_t nTailIndex; /**< Index of the tail segment. */ uint8_t nTailIndex; /**< Index of the tail segment. */
snake_dir_t dir; /**< Direction of the snake. */ snake_dir_t dir; /**< Direction of the snake. */
} snake_protagonist_t; } snake_protagonist_t;
/** /**
* This structure keeps track of all apples which are on the playing field. * This structure keeps track of all apples which are on the playing field.
*/ */
typedef struct snake_apples_s typedef struct snake_apples_s
{ {
pixel aApples[SNAKE_MAX_APPLES]; /**< Positions of all existing apples. */ pixel aApples[SNAKE_MAX_APPLES]; /**< Positions of all existing apples. */
uint8_t nAppleCount; /**< Count of currently existing apples. */ uint8_t nAppleCount; /**< Count of currently existing apples. */
} snake_apples_t; } snake_apples_t;
/** /**
* This function returns the next position which is calculated from a given * This function returns the next position which is calculated from a given
* (current) position and a direction. * (current) position and a direction.
* @param pxNext The position we're going to leave. * @param pxNext The position we're going to leave.
* @param dir The direction that we are heading. * @param dir The direction that we are heading.
* @return The next position according the given direction. * @return The next position according the given direction.
*/ */
static pixel snake_nextDirection(pixel const pxNext, static pixel snake_nextDirection(pixel const pxNext,
snake_dir_t const dir) snake_dir_t const dir)
{ {
assert(dir < 4); assert(dir < 4);
static int8_t const nDelta[] = {0, -1, 0, 1, 0}; static int8_t const nDelta[] = {0, -1, 0, 1, 0};
return (pixel){pxNext.x + nDelta[dir], pxNext.y + nDelta[dir + 1]}; return (pixel){pxNext.x + nDelta[dir], pxNext.y + nDelta[dir + 1]};
} }
/** /**
* This function draws a border around the playing field. * This function draws a border around the playing field.
*/ */
static void snake_drawBorder(void) static void snake_drawBorder(void)
{ {
#if NUM_COLS == NUM_ROWS #if NUM_COLS == NUM_ROWS
for (uint8_t i = NUM_COLS; i--;) for (uint8_t i = NUM_COLS; i--;)
{ {
setpixel((pixel){i, 0}, SNAKE_COLOR_BORDER); setpixel((pixel){i, 0}, SNAKE_COLOR_BORDER);
setpixel((pixel){i, NUM_ROWS - 1}, SNAKE_COLOR_BORDER); setpixel((pixel){i, NUM_ROWS - 1}, SNAKE_COLOR_BORDER);
setpixel((pixel){0, i}, SNAKE_COLOR_BORDER); setpixel((pixel){0, i}, SNAKE_COLOR_BORDER);
setpixel((pixel){NUM_COLS -1, i}, SNAKE_COLOR_BORDER); setpixel((pixel){NUM_COLS -1, i}, SNAKE_COLOR_BORDER);
} }
#else #else
for (uint8_t x = NUM_COLS; x--;) for (uint8_t x = NUM_COLS; x--;)
{ {
setpixel((pixel){x, 0}, SNAKE_COLOR_BORDER); setpixel((pixel){x, 0}, SNAKE_COLOR_BORDER);
setpixel((pixel){x, NUM_ROWS - 1}, SNAKE_COLOR_BORDER); setpixel((pixel){x, NUM_ROWS - 1}, SNAKE_COLOR_BORDER);
} }
for (uint8_t y = NUM_ROWS; y--;) for (uint8_t y = NUM_ROWS; y--;)
{ {
setpixel((pixel){0, y}, SNAKE_COLOR_BORDER); setpixel((pixel){0, y}, SNAKE_COLOR_BORDER);
setpixel((pixel){NUM_COLS - 1, y}, SNAKE_COLOR_BORDER); setpixel((pixel){NUM_COLS - 1, y}, SNAKE_COLOR_BORDER);
} }
#endif #endif
} }
#ifdef GAME_SNAKE #ifdef GAME_SNAKE
/** /**
* This function translates hardware port information into joystick directions. * This function translates hardware port information into joystick directions.
* @return The current direction of the joystick. * @return The current direction of the joystick.
* @see snake_dir_e * @see snake_dir_e
*/ */
static snake_dir_t snake_queryJoystick(void) static snake_dir_t snake_queryJoystick(void)
{ {
snake_dir_t dirJoystick; snake_dir_t dirJoystick;
if (JOYISUP) if (JOYISUP)
{ {
dirJoystick = SNAKE_DIR_UP; dirJoystick = SNAKE_DIR_UP;
} }
else if (JOYISRIGHT) else if (JOYISRIGHT)
{ {
dirJoystick = SNAKE_DIR_RIGHT; dirJoystick = SNAKE_DIR_RIGHT;
} }
else if (JOYISDOWN) else if (JOYISDOWN)
{ {
dirJoystick = SNAKE_DIR_DOWN; dirJoystick = SNAKE_DIR_DOWN;
} }
else if (JOYISLEFT) else if (JOYISLEFT)
{ {
dirJoystick = SNAKE_DIR_LEFT; dirJoystick = SNAKE_DIR_LEFT;
} }
else else
{ {
dirJoystick = SNAKE_DIR_NONE; dirJoystick = SNAKE_DIR_NONE;
} }
return dirJoystick; return dirJoystick;
} }
#endif #endif
/** /**
* This function initializes the structure which represents the snake itself. * This function initializes the structure which represents the snake itself.
* @param pprotSnake The pointer the protagonist structure to be initialized. * @param pprotSnake The pointer the protagonist structure to be initialized.
*/ */
static void snake_initGameProtagonist(snake_protagonist_t *pprotSnake) static void snake_initGameProtagonist(snake_protagonist_t *pprotSnake)
{ {
pprotSnake->aSegments[0] = (pixel){NUM_COLS / 2, NUM_ROWS / 2}; pprotSnake->aSegments[0] = (pixel){NUM_COLS / 2, NUM_ROWS / 2};
pprotSnake->aSegments[1] = (pixel){NUM_COLS / 2, NUM_ROWS / 2 - 1}; pprotSnake->aSegments[1] = (pixel){NUM_COLS / 2, NUM_ROWS / 2 - 1};
pprotSnake->nTailIndex = 0; pprotSnake->nTailIndex = 0;
pprotSnake->nHeadIndex = 1; pprotSnake->nHeadIndex = 1;
pprotSnake->dir = SNAKE_DIR_UP; pprotSnake->dir = SNAKE_DIR_UP;
} }
#ifdef GAME_SNAKE #ifdef GAME_SNAKE
/** /**
* Determines the next direction of the snake depending on the joystick's input. * Determines the next direction of the snake depending on the joystick's input.
* @param pprotSnake A pointer to the structure of the protagonist. * @param pprotSnake A pointer to the structure of the protagonist.
* @param pdirLast Last joystick direction to recognize prolonged key presses. * @param pdirLast Last joystick direction to recognize prolonged key presses.
*/ */
static void snake_userControl(snake_protagonist_t *pprotSnake, static void snake_userControl(snake_protagonist_t *pprotSnake,
snake_dir_t *pdirLast) snake_dir_t *pdirLast)
{ {
snake_dir_t dirJoystick = snake_queryJoystick(); snake_dir_t dirJoystick = snake_queryJoystick();
#ifdef SNAKE_NEWCONTROL #ifdef SNAKE_NEWCONTROL
if (dirJoystick != SNAKE_DIR_NONE) if (dirJoystick != SNAKE_DIR_NONE)
{ {
// valid transitions can only be uneven // valid transitions can only be uneven
if ((pprotSnake->dir + dirJoystick) & 0x01) if ((pprotSnake->dir + dirJoystick) & 0x01)
{ {
pprotSnake->dir = dirJoystick; pprotSnake->dir = dirJoystick;
} }
} }
#else #else
if ((dirJoystick ^ *pdirLast) && (dirJoystick != SNAKE_DIR_NONE)) if ((dirJoystick ^ *pdirLast) && (dirJoystick != SNAKE_DIR_NONE))
{ {
// only left or right movements are valid // only left or right movements are valid
if (dirJoystick & 0x01) if (dirJoystick & 0x01)
{ {
// rotate through directions (either clockwise or counterclockwise) // rotate through directions (either clockwise or counterclockwise)
pprotSnake->dir = (pprotSnake->dir + pprotSnake->dir = (pprotSnake->dir +
(dirJoystick == SNAKE_DIR_LEFT ? 3 : 1)) % 4u; (dirJoystick == SNAKE_DIR_LEFT ? 3 : 1)) % 4u;
} }
} }
*pdirLast = dirJoystick; *pdirLast = dirJoystick;
#endif #endif
} }
#endif #endif
#ifdef ANIMATION_SNAKE #ifdef ANIMATION_SNAKE
/** /**
* This function approximates the next direction which may lead to an apple * This function approximates the next direction which may lead to an apple
* (with a particular probability). * (with a particular probability).
* @param pprotSnake A pointer to the hungry protagonist. * @param pprotSnake A pointer to the hungry protagonist.
* @param pApples A pointer to a bunch of apples. * @param pApples A pointer to a bunch of apples.
*/ */
static void snake_autoRoute(snake_protagonist_t *pprotSnake, static void snake_autoRoute(snake_protagonist_t *pprotSnake,
snake_apples_t *pApples) snake_apples_t *pApples)
{ {
pixel pxHead = pprotSnake->aSegments[pprotSnake->nHeadIndex]; pixel pxHead = pprotSnake->aSegments[pprotSnake->nHeadIndex];
if (random8() < 80) if (random8() < 80)
{ {
uint8_t nNextApple = 0; uint8_t nNextApple = 0;
if (pApples->nAppleCount) if (pApples->nAppleCount)
{ {
uint8_t nMinDist = UINT8_MAX; uint8_t nMinDist = UINT8_MAX;
for (uint8_t i = 0; i < pApples->nAppleCount; ++i) for (uint8_t i = 0; i < pApples->nAppleCount; ++i)
{ {
uint8_t nDistX; uint8_t nDistX;
if (pxHead.x > pApples->aApples[i].x) if (pxHead.x > pApples->aApples[i].x)
{ {
nDistX = pxHead.x - pApples->aApples[i].x; nDistX = pxHead.x - pApples->aApples[i].x;
} }
else else
{ {
nDistX = pApples->aApples[i].x - pxHead.x; nDistX = pApples->aApples[i].x - pxHead.x;
} }
uint8_t nDistY; uint8_t nDistY;
if (pxHead.y > pApples->aApples[i].y) if (pxHead.y > pApples->aApples[i].y)
{ {
nDistY = pxHead.y - pApples->aApples[i].y; nDistY = pxHead.y - pApples->aApples[i].y;
} }
else else
{ {
nDistY = pApples->aApples[i].y - pxHead.y; nDistY = pApples->aApples[i].y - pxHead.y;
} }
if ((nDistX + nDistY) < nMinDist) if ((nDistX + nDistY) < nMinDist)
{ {
nMinDist = nDistX + nDistY; nMinDist = nDistX + nDistY;
nNextApple = i; nNextApple = i;
} }
} }
if (pprotSnake->dir ^ 0x01) // vertical direction? if (pprotSnake->dir ^ 0x01) // vertical direction?
{ {
pprotSnake->dir = pApples->aApples[nNextApple].x > pxHead.x ? pprotSnake->dir = pApples->aApples[nNextApple].x > pxHead.x ?
SNAKE_DIR_LEFT : SNAKE_DIR_RIGHT; SNAKE_DIR_LEFT : SNAKE_DIR_RIGHT;
} }
else else
{ {
pprotSnake->dir = pApples->aApples[nNextApple].y > pxHead.y ? pprotSnake->dir = pApples->aApples[nNextApple].y > pxHead.y ?
SNAKE_DIR_DOWN : SNAKE_DIR_UP; SNAKE_DIR_DOWN : SNAKE_DIR_UP;
} }
} }
} }
for (uint8_t i = 0; i < 4; ++i) for (uint8_t i = 0; i < 4; ++i)
{ {
pixel pxTest = snake_nextDirection(pxHead, pprotSnake->dir); pixel pxTest = snake_nextDirection(pxHead, pprotSnake->dir);
if (get_pixel(pxTest)) if (get_pixel(pxTest))
{ {
for (uint8_t j = 0; j < pApples->nAppleCount; ++j) for (uint8_t j = 0; j < pApples->nAppleCount; ++j)
{ {
if ((pxTest.x == pApples->aApples[j].x) && if ((pxTest.x == pApples->aApples[j].x) &&
(pxTest.y == pApples->aApples[j].y)) (pxTest.y == pApples->aApples[j].y))
{ {
return; return;
} }
} }
pprotSnake->dir = (pprotSnake->dir + 1u) % 4u; pprotSnake->dir = (pprotSnake->dir + 1u) % 4u;
} }
else else
{ {
break; break;
} }
} }
} }
#endif #endif
/** /**
* Small animation that lets the dying snake disappear piece by piece. * Small animation that lets the dying snake disappear piece by piece.
* @param pprotSnake A pointer to the dying snake. * @param pprotSnake A pointer to the dying snake.
*/ */
static void snake_eliminateProtagonist(snake_protagonist_t *pprotSnake) static void snake_eliminateProtagonist(snake_protagonist_t *pprotSnake)
{ {
while (pprotSnake->nTailIndex != pprotSnake->nHeadIndex) while (pprotSnake->nTailIndex != pprotSnake->nHeadIndex)
{ {
clearpixel(pprotSnake->aSegments[pprotSnake->nTailIndex++]); clearpixel(pprotSnake->aSegments[pprotSnake->nTailIndex++]);
pprotSnake->nTailIndex %= USNAKE_MAX_LENGTH; pprotSnake->nTailIndex %= USNAKE_MAX_LENGTH;
wait(SNAKE_TERMINATION_DELAY); wait(SNAKE_TERMINATION_DELAY);
} }
} }
/** /**
* Initializes the structure that keeps track of all currently existing apples. * Initializes the structure that keeps track of all currently existing apples.
* @param pApples Pointer to the set of apples in question. * @param pApples Pointer to the set of apples in question.
*/ */
static void snake_initApples(snake_apples_t *pApples) static void snake_initApples(snake_apples_t *pApples)
{ {
pApples->nAppleCount = 0; pApples->nAppleCount = 0;
} }
/** /**
* Checks for an apple at a given position and removes it if there is one. * Checks for an apple at a given position and removes it if there is one.
* @param pApples The set of apples which are lying on the playing field. * @param pApples The set of apples which are lying on the playing field.
* @param pxHead The position to be tested. * @param pxHead The position to be tested.
* @return 0 if no apples were found, 1 otherwise * @return 0 if no apples were found, 1 otherwise
*/ */
static uint8_t snake_checkForApple(snake_apples_t *pApples, pixel pxHead) static uint8_t snake_checkForApple(snake_apples_t *pApples, pixel pxHead)
{ {
for (uint8_t i = pApples->nAppleCount; i--;) for (uint8_t i = pApples->nAppleCount; i--;)
{ {
if ((pxHead.x == pApples->aApples[i].x) && if ((pxHead.x == pApples->aApples[i].x) &&
(pxHead.y == pApples->aApples[i].y)) (pxHead.y == pApples->aApples[i].y))
{ {
for (; i < pApples->nAppleCount; ++i) for (; i < pApples->nAppleCount; ++i)
{ {
pApples->aApples[i] = pApples->aApples[i + 1]; pApples->aApples[i] = pApples->aApples[i + 1];
} }
--pApples->nAppleCount; --pApples->nAppleCount;
return 1; return 1;
} }
} }
return 0; return 0;
} }
/** /**
* Creates some new apples from time to time. * Creates some new apples from time to time.
* @param pApples Pointer to a set of apples. * @param pApples Pointer to a set of apples.
*/ */
static void snake_spawnApples(snake_apples_t *pApples) static void snake_spawnApples(snake_apples_t *pApples)
{ {
if ((pApples->nAppleCount < SNAKE_MAX_APPLES) && (random8() < 10)) if ((pApples->nAppleCount < SNAKE_MAX_APPLES) && (random8() < 10))
{ {
pixel pxApple = (pixel){(random8() % (NUM_COLS-2)) + 1, pixel pxApple = (pixel){(random8() % (NUM_COLS-2)) + 1,
(random8() % (NUM_ROWS - 2)) + 1}; (random8() % (NUM_ROWS - 2)) + 1};
if (!get_pixel(pxApple)) if (!get_pixel(pxApple))
{ {
pApples->aApples[pApples->nAppleCount++] = pxApple; pApples->aApples[pApples->nAppleCount++] = pxApple;
} }
} }
} }
/** /**
* The main loop (plus initialization) that both drives the game and the * The main loop (plus initialization) that both drives the game and the
* demo mode. * demo mode.
* @param bDemoMode 0 indicates game mode, 1 indicates demo mode * @param bDemoMode 0 indicates game mode, 1 indicates demo mode
*/ */
void snake_engine(uint8_t bDemoMode) void snake_engine(uint8_t bDemoMode)
{ {
// init // init
snake_protagonist_t protSnake; snake_protagonist_t protSnake;
snake_initGameProtagonist(&protSnake); snake_initGameProtagonist(&protSnake);
snake_apples_t apples; snake_apples_t apples;
snake_initApples(&apples); snake_initApples(&apples);
snake_dir_t dirLast = SNAKE_DIR_NONE; snake_dir_t dirLast = SNAKE_DIR_NONE;
// init screen // init screen
clear_screen(0); clear_screen(0);
snake_drawBorder(); snake_drawBorder();
for (uint8_t nAppleColor = 0; 1; nAppleColor ^= SNAKE_COLOR_APPLE) for (uint8_t nAppleColor = 0; 1; nAppleColor ^= SNAKE_COLOR_APPLE)
{ {
// determine new direction // determine new direction
#if defined ANIMATION_SNAKE && defined GAME_SNAKE #if defined ANIMATION_SNAKE && defined GAME_SNAKE
if (bDemoMode) if (bDemoMode)
{ {
snake_autoRoute(&protSnake, &apples); snake_autoRoute(&protSnake, &apples);
} }
else else
{ {
snake_userControl(&protSnake, &dirLast); snake_userControl(&protSnake, &dirLast);
} }
#elif defined ANIMATION_SNAKE #elif defined ANIMATION_SNAKE
snake_autoRoute(&protSnake, &apples); snake_autoRoute(&protSnake, &apples);
#else #else
snake_userControl(&protSnake, &dirLast); snake_userControl(&protSnake, &dirLast);
#endif #endif
// actually move head // actually move head
pixel pxOldHead = protSnake.aSegments[protSnake.nHeadIndex]; pixel pxOldHead = protSnake.aSegments[protSnake.nHeadIndex];
protSnake.nHeadIndex = (protSnake.nHeadIndex + 1u) % USNAKE_MAX_LENGTH; protSnake.nHeadIndex = (protSnake.nHeadIndex + 1u) % USNAKE_MAX_LENGTH;
protSnake.aSegments[protSnake.nHeadIndex] = protSnake.aSegments[protSnake.nHeadIndex] =
snake_nextDirection(pxOldHead, protSnake.dir); snake_nextDirection(pxOldHead, protSnake.dir);
// look if we have found an apple // look if we have found an apple
if (!snake_checkForApple(&apples, if (!snake_checkForApple(&apples,
protSnake.aSegments[protSnake.nHeadIndex])) protSnake.aSegments[protSnake.nHeadIndex]))
{ {
// quit game if we hit something which is not an apple // quit game if we hit something which is not an apple
if (get_pixel(protSnake.aSegments[protSnake.nHeadIndex])) if (get_pixel(protSnake.aSegments[protSnake.nHeadIndex]))
{ {
snake_eliminateProtagonist(&protSnake); snake_eliminateProtagonist(&protSnake);
return; return;
} }
// remove last segment // remove last segment
clearpixel(protSnake.aSegments[protSnake.nTailIndex]) clearpixel(protSnake.aSegments[protSnake.nTailIndex])
protSnake.nTailIndex = protSnake.nTailIndex =
(protSnake.nTailIndex + 1u) % USNAKE_MAX_LENGTH; (protSnake.nTailIndex + 1u) % USNAKE_MAX_LENGTH;
// new apples // new apples
snake_spawnApples(&apples); snake_spawnApples(&apples);
} }
// draw new head // draw new head
setpixel(protSnake.aSegments[protSnake.nHeadIndex], setpixel(protSnake.aSegments[protSnake.nHeadIndex],
SNAKE_COLOR_PROTAGONIST); SNAKE_COLOR_PROTAGONIST);
// draw apples // draw apples
for (uint8_t i = apples.nAppleCount; i--;) for (uint8_t i = apples.nAppleCount; i--;)
{ {
setpixel(apples.aApples[i], nAppleColor); setpixel(apples.aApples[i], nAppleColor);
} }
wait(SNAKE_CYCLE_DELAY); wait(SNAKE_CYCLE_DELAY);
} }
} }
/** /**
* Snake in game mode. * Snake in game mode.
*/ */
void snake_game(void) void snake_game(void)
{ {
snake_engine(0); snake_engine(0);
} }
/*@}*/ /*@}*/

View File

@ -1,40 +1,40 @@
// Makros for simplified single pin io access. // Makros for simplified single pin io access.
#define PORT_(port) PORT ## port #define PORT_(port) PORT ## port
#define DDR_(port) DDR ## port #define DDR_(port) DDR ## port
#define PIN_(port) PIN ## port #define PIN_(port) PIN ## port
#define PORT(port) PORT_(port) #define PORT(port) PORT_(port)
#define DDRR(port) DDR_(port) #define DDRR(port) DDR_(port)
#define PINN(port) PIN_(port) #define PINN(port) PIN_(port)
#define SET_DDR(p) DDRR(p##_PORT) |= (1<<p##_BIT) #define SET_DDR(p) DDRR(p##_PORT) |= (1<<p##_BIT)
#define CLEAR_DDR(p) DDRR(p##_PORT) &= ~(1<<p##_BIT) #define CLEAR_DDR(p) DDRR(p##_PORT) &= ~(1<<p##_BIT)
#define OUTPUT_ON(p) PORT(p##_PORT) |= (1<<p##_BIT) #define OUTPUT_ON(p) PORT(p##_PORT) |= (1<<p##_BIT)
#define OUTPUT_OFF(p) PORT(p##_PORT) &= ~(1<<p##_BIT) #define OUTPUT_OFF(p) PORT(p##_PORT) &= ~(1<<p##_BIT)
#define INPUT(p) ((PINN(p##_PORT) & (1<<p##_BIT)) != 0) #define INPUT(p) ((PINN(p##_PORT) & (1<<p##_BIT)) != 0)
/* /*
Use Like this: Use Like this:
#define LED_PORT C #define LED_PORT C
#define LED_BIT 7 #define LED_BIT 7
#define SWITCH_PORT B #define SWITCH_PORT B
#define SWITCH_BIT 0 #define SWITCH_BIT 0
int main(){ int main(){
SET_DDR(LED); //set to output SET_DDR(LED); //set to output
OUTPUT_ON(SWITCH); //turn on pullup OUTPUT_ON(SWITCH); //turn on pullup
if(INPUT(SWITCH)){ if(INPUT(SWITCH)){
OUTPUT_ON(LED); OUTPUT_ON(LED);
}else{ }else{
OUTPUT_OFF(LED); OUTPUT_OFF(LED);
} }
} }
*/ */

View File

@ -1,4 +1,4 @@
void joy_init(){ void joy_init(){
} }

View File

@ -1,7 +1,7 @@
#define DDR(port) (*(volatile uint8_t*)((&port)-1)) #define DDR(port) (*(volatile uint8_t*)((&port)-1))
#define PIN(port) (*(volatile uint8_t*)((&port)-2)) #define PIN(port) (*(volatile uint8_t*)((&port)-2))
#define DDR_FROM_PIN(pin) (*(volatile uint8_t*)((&pin)+1)) #define DDR_FROM_PIN(pin) (*(volatile uint8_t*)((&pin)+1))
#define PORT_FROM_PIN(pin) (*(volatile uint8_t*)((&pin)+2)) #define PORT_FROM_PIN(pin) (*(volatile uint8_t*)((&pin)+2))

View File

@ -1,11 +1,11 @@
MAKETOPDIR = ../.. MAKETOPDIR = ../..
TARGET = objects TARGET = objects
include $(MAKETOPDIR)/defaults.mk include $(MAKETOPDIR)/defaults.mk
SRC = rfm12.c borg_rfm12.c SRC = rfm12.c borg_rfm12.c
include $(MAKETOPDIR)/rules.mk include $(MAKETOPDIR)/rules.mk
include $(MAKETOPDIR)/depend.mk include $(MAKETOPDIR)/depend.mk

View File

@ -1,36 +1,36 @@
#include <avr/io.h> #include <avr/io.h>
#include <util/delay.h> #include <util/delay.h>
#include "rfm12.h" #include "rfm12.h"
volatile uint8_t rfm12_joystick_val; volatile uint8_t rfm12_joystick_val;
void borg_rfm12_tick(){ void borg_rfm12_tick(){
if (rfm12_rx_status() == STATUS_COMPLETE) if (rfm12_rx_status() == STATUS_COMPLETE)
{ {
//uart_putstr ("new packet:\r\n"); //uart_putstr ("new packet:\r\n");
uint8_t * bufp = rfm12_rx_buffer(); uint8_t * bufp = rfm12_rx_buffer();
// dump buffer contents to uart // dump buffer contents to uart
if(rfm12_rx_len() >= 1){ if(rfm12_rx_len() >= 1){
//-> F2 F1 RT LF DN UP //-> F2 F1 RT LF DN UP
rfm12_joystick_val = *bufp; rfm12_joystick_val = *bufp;
} }
// tell the implementation that the buffer // tell the implementation that the buffer
// can be reused for the next data. // can be reused for the next data.
rfm12_rx_clear(); rfm12_rx_clear();
} }
rfm12_tick(); rfm12_tick();
} }
void borg_rfm12_init(){ void borg_rfm12_init(){
_delay_ms(200);//the rfm12 seems to need this _delay_ms(200);//the rfm12 seems to need this
rfm12_init(); rfm12_init();
} }

View File

@ -1,6 +1,6 @@
void borg_rfm12_init(); void borg_rfm12_init();
void borg_rfm12_tick(); void borg_rfm12_tick();
extern volatile uint8_t rfm12_joystick_val; extern volatile uint8_t rfm12_joystick_val;

View File

@ -1,439 +1,439 @@
#include "font.h" #include "font.h"
unsigned int PROGMEM fontIndex_small6[] = { unsigned int PROGMEM fontIndex_small6[] = {
0, /* */ 0, /* */
1, /* ! */ 1, /* ! */
2, /* " */ 2, /* " */
5, /* # */ 5, /* # */
10, /* $ */ 10, /* $ */
13, /* % */ 13, /* % */
17, /* & */ 17, /* & */
21, /* ' */ 21, /* ' */
22, /* ( */ 22, /* ( */
24, /* ) */ 24, /* ) */
26, /* * */ 26, /* * */
28, /* + */ 28, /* + */
31, /* , */ 31, /* , */
32, /* - */ 32, /* - */
34, /* . */ 34, /* . */
35, /* / */ 35, /* / */
37, /* 0 */ 37, /* 0 */
41, /* 1 */ 41, /* 1 */
43, /* 2 */ 43, /* 2 */
47, /* 3 */ 47, /* 3 */
51, /* 4 */ 51, /* 4 */
55, /* 5 */ 55, /* 5 */
58, /* 6 */ 58, /* 6 */
62, /* 7 */ 62, /* 7 */
65, /* 8 */ 65, /* 8 */
69, /* 9 */ 69, /* 9 */
73, /* : */ 73, /* : */
74, /* ; */ 74, /* ; */
75, /* < */ 75, /* < */
78, /* = */ 78, /* = */
81, /* > */ 81, /* > */
84, /* ? */ 84, /* ? */
88, /* @ */ 88, /* @ */
95, /* A */ 95, /* A */
100, /* B */ 100, /* B */
105, /* C */ 105, /* C */
110, /* D */ 110, /* D */
115, /* E */ 115, /* E */
119, /* F */ 119, /* F */
123, /* G */ 123, /* G */
128, /* H */ 128, /* H */
132, /* I */ 132, /* I */
133, /* J */ 133, /* J */
136, /* K */ 136, /* K */
140, /* L */ 140, /* L */
143, /* M */ 143, /* M */
150, /* N */ 150, /* N */
155, /* O */ 155, /* O */
160, /* P */ 160, /* P */
164, /* Q */ 164, /* Q */
169, /* R */ 169, /* R */
174, /* S */ 174, /* S */
178, /* T */ 178, /* T */
182, /* U */ 182, /* U */
187, /* V */ 187, /* V */
192, /* W */ 192, /* W */
199, /* X */ 199, /* X */
204, /* Y */ 204, /* Y */
209, /* Z */ 209, /* Z */
213, /* [ */ 213, /* [ */
215, /* \ */ 215, /* \ */
217, /* ] */ 217, /* ] */
219, /* ^ */ 219, /* ^ */
222, /* _ */ 222, /* _ */
226, /* ` */ 226, /* ` */
228, /* a */ 228, /* a */
231, /* b */ 231, /* b */
235, /* c */ 235, /* c */
238, /* d */ 238, /* d */
242, /* e */ 242, /* e */
245, /* f */ 245, /* f */
247, /* g */ 247, /* g */
251, /* h */ 251, /* h */
254, /* i */ 254, /* i */
255, /* j */ 255, /* j */
256, /* k */ 256, /* k */
259, /* l */ 259, /* l */
260, /* m */ 260, /* m */
265, /* n */ 265, /* n */
268, /* o */ 268, /* o */
272, /* p */ 272, /* p */
276, /* q */ 276, /* q */
280, /* r */ 280, /* r */
282, /* s */ 282, /* s */
285, /* t */ 285, /* t */
287, /* u */ 287, /* u */
290, /* v */ 290, /* v */
293, /* w */ 293, /* w */
298, /* x */ 298, /* x */
301, /* y */ 301, /* y */
304, /* z */ 304, /* z */
307, /* { */ 307, /* { */
309, /* | */ 309, /* | */
310, /* } */ 310, /* } */
312, /* ~ */ 312, /* ~ */
316, /* ß */ 316, /* ß */
321, /* ä */ 321, /* ä */
324, /* ö */ 324, /* ö */
328, /* ü */ 328, /* ü */
331 331
}; };
unsigned char PROGMEM fontData_small6[] = { unsigned char PROGMEM fontData_small6[] = {
0x00, /* */ 0x00, /* */
0x2f, /* # #### */ 0x2f, /* # #### */
0x03, /* ## */ 0x03, /* ## */
0x00, /* */ 0x00, /* */
0x03, /* ## */ 0x03, /* ## */
0x12, /* # # */ 0x12, /* # # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x12, /* # # */ 0x12, /* # # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x12, /* # # */ 0x12, /* # # */
0x26, /* # ## */ 0x26, /* # ## */
0x7f, /* ####### */ 0x7f, /* ####### */
0x32, /* ## # */ 0x32, /* ## # */
0x13, /* # ## */ 0x13, /* # ## */
0x0b, /* # ## */ 0x0b, /* # ## */
0x34, /* ## # */ 0x34, /* ## # */
0x32, /* ## # */ 0x32, /* ## # */
0x1a, /* ## # */ 0x1a, /* ## # */
0x25, /* # # # */ 0x25, /* # # # */
0x1a, /* ## # */ 0x1a, /* ## # */
0x28, /* # # */ 0x28, /* # # */
0x03, /* ## */ 0x03, /* ## */
0x7e, /* ###### */ 0x7e, /* ###### */
0x81, /* # # */ 0x81, /* # # */
0x81, /* # # */ 0x81, /* # # */
0x7e, /* ###### */ 0x7e, /* ###### */
0x03, /* ## */ 0x03, /* ## */
0x03, /* ## */ 0x03, /* ## */
0x08, /* # */ 0x08, /* # */
0x1c, /* ### */ 0x1c, /* ### */
0x08, /* # */ 0x08, /* # */
0x60, /* ## */ 0x60, /* ## */
0x08, /* # */ 0x08, /* # */
0x08, /* # */ 0x08, /* # */
0x20, /* # */ 0x20, /* # */
0x38, /* ### */ 0x38, /* ### */
0x07, /* ### */ 0x07, /* ### */
0x1e, /* #### */ 0x1e, /* #### */
0x21, /* # # */ 0x21, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x1e, /* #### */ 0x1e, /* #### */
0x02, /* # */ 0x02, /* # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x32, /* ## # */ 0x32, /* ## # */
0x29, /* # # # */ 0x29, /* # # # */
0x29, /* # # # */ 0x29, /* # # # */
0x26, /* # ## */ 0x26, /* # ## */
0x12, /* # # */ 0x12, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x25, /* # # # */ 0x25, /* # # # */
0x1a, /* ## # */ 0x1a, /* ## # */
0x18, /* ## */ 0x18, /* ## */
0x16, /* # ## */ 0x16, /* # ## */
0x3f, /* ###### */ 0x3f, /* ###### */
0x10, /* # */ 0x10, /* # */
0x27, /* # ### */ 0x27, /* # ### */
0x25, /* # # # */ 0x25, /* # # # */
0x19, /* ## # */ 0x19, /* ## # */
0x1e, /* #### */ 0x1e, /* #### */
0x25, /* # # # */ 0x25, /* # # # */
0x25, /* # # # */ 0x25, /* # # # */
0x18, /* ## */ 0x18, /* ## */
0x01, /* # */ 0x01, /* # */
0x3d, /* #### # */ 0x3d, /* #### # */
0x03, /* ## */ 0x03, /* ## */
0x1a, /* ## # */ 0x1a, /* ## # */
0x25, /* # # # */ 0x25, /* # # # */
0x25, /* # # # */ 0x25, /* # # # */
0x1a, /* ## # */ 0x1a, /* ## # */
0x12, /* # # */ 0x12, /* # # */
0x25, /* # # # */ 0x25, /* # # # */
0x25, /* # # # */ 0x25, /* # # # */
0x1e, /* #### */ 0x1e, /* #### */
0x24, /* # # */ 0x24, /* # # */
0x64, /* ## # */ 0x64, /* ## # */
0x08, /* # */ 0x08, /* # */
0x14, /* # # */ 0x14, /* # # */
0x22, /* # # */ 0x22, /* # # */
0x14, /* # # */ 0x14, /* # # */
0x14, /* # # */ 0x14, /* # # */
0x14, /* # # */ 0x14, /* # # */
0x22, /* # # */ 0x22, /* # # */
0x14, /* # # */ 0x14, /* # # */
0x08, /* # */ 0x08, /* # */
0x02, /* # */ 0x02, /* # */
0x29, /* # # # */ 0x29, /* # # # */
0x05, /* # # */ 0x05, /* # # */
0x02, /* # */ 0x02, /* # */
0x1c, /* ### */ 0x1c, /* ### */
0x22, /* # # */ 0x22, /* # # */
0x49, /* # # # */ 0x49, /* # # # */
0x55, /* # # # # */ 0x55, /* # # # # */
0x59, /* # ## # */ 0x59, /* # ## # */
0x12, /* # # */ 0x12, /* # # */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x0b, /* # ## */ 0x0b, /* # ## */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x3f, /* ###### */ 0x3f, /* ###### */
0x25, /* # # # */ 0x25, /* # # # */
0x25, /* # # # */ 0x25, /* # # # */
0x25, /* # # # */ 0x25, /* # # # */
0x1a, /* ## # */ 0x1a, /* ## # */
0x1e, /* #### */ 0x1e, /* #### */
0x21, /* # # */ 0x21, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x12, /* # # */ 0x12, /* # # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x21, /* # # */ 0x21, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x1e, /* #### */ 0x1e, /* #### */
0x3f, /* ###### */ 0x3f, /* ###### */
0x25, /* # # # */ 0x25, /* # # # */
0x25, /* # # # */ 0x25, /* # # # */
0x21, /* # # */ 0x21, /* # # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x05, /* # # */ 0x05, /* # # */
0x05, /* # # */ 0x05, /* # # */
0x01, /* # */ 0x01, /* # */
0x1e, /* #### */ 0x1e, /* #### */
0x21, /* # # */ 0x21, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x29, /* # # # */ 0x29, /* # # # */
0x3a, /* ### # */ 0x3a, /* ### # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x04, /* # */ 0x04, /* # */
0x04, /* # */ 0x04, /* # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x3f, /* ###### */ 0x3f, /* ###### */
0x30, /* ## */ 0x30, /* ## */
0x20, /* # */ 0x20, /* # */
0x1f, /* ##### */ 0x1f, /* ##### */
0x3f, /* ###### */ 0x3f, /* ###### */
0x0c, /* ## */ 0x0c, /* ## */
0x12, /* # # */ 0x12, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x20, /* # */ 0x20, /* # */
0x20, /* # */ 0x20, /* # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x03, /* ## */ 0x03, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x03, /* ## */ 0x03, /* ## */
0x3f, /* ###### */ 0x3f, /* ###### */
0x3f, /* ###### */ 0x3f, /* ###### */
0x03, /* ## */ 0x03, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x3f, /* ###### */ 0x3f, /* ###### */
0x1e, /* #### */ 0x1e, /* #### */
0x21, /* # # */ 0x21, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x1e, /* #### */ 0x1e, /* #### */
0x3f, /* ###### */ 0x3f, /* ###### */
0x09, /* # # */ 0x09, /* # # */
0x09, /* # # */ 0x09, /* # # */
0x06, /* ## */ 0x06, /* ## */
0x1e, /* #### */ 0x1e, /* #### */
0x21, /* # # */ 0x21, /* # # */
0x29, /* # # # */ 0x29, /* # # # */
0x11, /* # # */ 0x11, /* # # */
0x2e, /* # ### */ 0x2e, /* # ### */
0x3f, /* ###### */ 0x3f, /* ###### */
0x09, /* # # */ 0x09, /* # # */
0x09, /* # # */ 0x09, /* # # */
0x09, /* # # */ 0x09, /* # # */
0x36, /* ## ## */ 0x36, /* ## ## */
0x12, /* # # */ 0x12, /* # # */
0x25, /* # # # */ 0x25, /* # # # */
0x29, /* # # # */ 0x29, /* # # # */
0x12, /* # # */ 0x12, /* # # */
0x01, /* # */ 0x01, /* # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x01, /* # */ 0x01, /* # */
0x01, /* # */ 0x01, /* # */
0x1f, /* ##### */ 0x1f, /* ##### */
0x20, /* # */ 0x20, /* # */
0x20, /* # */ 0x20, /* # */
0x20, /* # */ 0x20, /* # */
0x1f, /* ##### */ 0x1f, /* ##### */
0x03, /* ## */ 0x03, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x03, /* ## */ 0x03, /* ## */
0x03, /* ## */ 0x03, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x03, /* ## */ 0x03, /* ## */
0x21, /* # # */ 0x21, /* # # */
0x12, /* # # */ 0x12, /* # # */
0x0c, /* ## */ 0x0c, /* ## */
0x12, /* # # */ 0x12, /* # # */
0x21, /* # # */ 0x21, /* # # */
0x01, /* # */ 0x01, /* # */
0x02, /* # */ 0x02, /* # */
0x3c, /* #### */ 0x3c, /* #### */
0x02, /* # */ 0x02, /* # */
0x01, /* # */ 0x01, /* # */
0x31, /* ## # */ 0x31, /* ## # */
0x29, /* # # # */ 0x29, /* # # # */
0x25, /* # # # */ 0x25, /* # # # */
0x23, /* # ## */ 0x23, /* # ## */
0x7f, /* ####### */ 0x7f, /* ####### */
0x41, /* # # */ 0x41, /* # # */
0x07, /* ### */ 0x07, /* ### */
0x38, /* ### */ 0x38, /* ### */
0x41, /* # # */ 0x41, /* # # */
0x7f, /* ####### */ 0x7f, /* ####### */
0x02, /* # */ 0x02, /* # */
0x01, /* # */ 0x01, /* # */
0x02, /* # */ 0x02, /* # */
0x40, /* # */ 0x40, /* # */
0x40, /* # */ 0x40, /* # */
0x40, /* # */ 0x40, /* # */
0x40, /* # */ 0x40, /* # */
0x00, /* */ 0x00, /* */
0x01, /* # */ 0x01, /* # */
0x14, /* # # */ 0x14, /* # # */
0x24, /* # # */ 0x24, /* # # */
0x38, /* ### */ 0x38, /* ### */
0x3f, /* ###### */ 0x3f, /* ###### */
0x24, /* # # */ 0x24, /* # # */
0x24, /* # # */ 0x24, /* # # */
0x18, /* ## */ 0x18, /* ## */
0x18, /* ## */ 0x18, /* ## */
0x24, /* # # */ 0x24, /* # # */
0x24, /* # # */ 0x24, /* # # */
0x18, /* ## */ 0x18, /* ## */
0x24, /* # # */ 0x24, /* # # */
0x24, /* # # */ 0x24, /* # # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x18, /* ## */ 0x18, /* ## */
0x24, /* # # */ 0x24, /* # # */
0x28, /* # # */ 0x28, /* # # */
0x3e, /* ##### */ 0x3e, /* ##### */
0x05, /* # # */ 0x05, /* # # */
0x18, /* ## */ 0x18, /* ## */
0xa4, /* # # # */ 0xa4, /* # # # */
0xa4, /* # # # */ 0xa4, /* # # # */
0x7c, /* ##### */ 0x7c, /* ##### */
0x3f, /* ###### */ 0x3f, /* ###### */
0x04, /* # */ 0x04, /* # */
0x38, /* ### */ 0x38, /* ### */
0x3d, /* #### # */ 0x3d, /* #### # */
0xfd, /* ###### # */ 0xfd, /* ###### # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x08, /* # */ 0x08, /* # */
0x34, /* ## # */ 0x34, /* ## # */
0x3f, /* ###### */ 0x3f, /* ###### */
0x3c, /* #### */ 0x3c, /* #### */
0x04, /* # */ 0x04, /* # */
0x3c, /* #### */ 0x3c, /* #### */
0x04, /* # */ 0x04, /* # */
0x38, /* ### */ 0x38, /* ### */
0x3c, /* #### */ 0x3c, /* #### */
0x04, /* # */ 0x04, /* # */
0x38, /* ### */ 0x38, /* ### */
0x18, /* ## */ 0x18, /* ## */
0x24, /* # # */ 0x24, /* # # */
0x24, /* # # */ 0x24, /* # # */
0x18, /* ## */ 0x18, /* ## */
0xfc, /* ###### */ 0xfc, /* ###### */
0x24, /* # # */ 0x24, /* # # */
0x24, /* # # */ 0x24, /* # # */
0x18, /* ## */ 0x18, /* ## */
0x18, /* ## */ 0x18, /* ## */
0x24, /* # # */ 0x24, /* # # */
0x24, /* # # */ 0x24, /* # # */
0xfc, /* ###### */ 0xfc, /* ###### */
0x3c, /* #### */ 0x3c, /* #### */
0x04, /* # */ 0x04, /* # */
0x28, /* # # */ 0x28, /* # # */
0x24, /* # # */ 0x24, /* # # */
0x14, /* # # */ 0x14, /* # # */
0x1e, /* #### */ 0x1e, /* #### */
0x24, /* # # */ 0x24, /* # # */
0x1c, /* ### */ 0x1c, /* ### */
0x20, /* # */ 0x20, /* # */
0x3c, /* #### */ 0x3c, /* #### */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x30, /* ## */ 0x30, /* ## */
0x0c, /* ## */ 0x0c, /* ## */
0x24, /* # # */ 0x24, /* # # */
0x18, /* ## */ 0x18, /* ## */
0x24, /* # # */ 0x24, /* # # */
0x9c, /* # ### */ 0x9c, /* # ### */
0x60, /* ## */ 0x60, /* ## */
0x1c, /* ### */ 0x1c, /* ### */
0x34, /* ## # */ 0x34, /* ## # */
0x24, /* # # */ 0x24, /* # # */
0x2c, /* # ## */ 0x2c, /* # ## */
0x08, /* # */ 0x08, /* # */
0x77, /* ### ### */ 0x77, /* ### ### */
0x7f, /* ####### */ 0x7f, /* ####### */
0x77, /* ### ### */ 0x77, /* ### ### */
0x08, /* # */ 0x08, /* # */
0x01, /* # */ 0x01, /* # */
0x02, /* # */ 0x02, /* # */
0x01, /* # */ 0x01, /* # */
0x02, /* # */ 0x02, /* # */
0x3e, /* ##### */ 0x3e, /* ##### */
0x05, /* # # */ 0x05, /* # # */
0x26, /* # ## */ 0x26, /* # ## */
0x18, /* ## */ 0x18, /* ## */
0x19, /* ## # */ 0x19, /* ## # */
0x24, /* # # */ 0x24, /* # # */
0x29, /* # # # */ 0x29, /* # # # */
0x19, /* ## # */ 0x19, /* ## # */
0x24, /* # # */ 0x24, /* # # */
0x24, /* # # */ 0x24, /* # # */
0x19, /* ## # */ 0x19, /* ## # */
0x1d, /* ### # */ 0x1d, /* ### # */
0x20, /* # */ 0x20, /* # */
0x3d, /* #### # */ 0x3d, /* #### # */
}; };
font font_small6 = {8, fontIndex_small6, fontData_small6, ' ', '~', '.', 1}; font font_small6 = {8, fontIndex_small6, fontData_small6, ' ', '~', '.', 1};

File diff suppressed because it is too large Load Diff

View File

@ -1,324 +1,324 @@
/** /**
* \defgroup unixsimulator Simulation of the Borg API for UNIX like platforms. * \defgroup unixsimulator Simulation of the Borg API for UNIX like platforms.
*/ */
/*@{*/ /*@{*/
/** /**
* @file main.c * @file main.c
* @brief Simulator for Unix like platforms. * @brief Simulator for Unix like platforms.
* @author Martin Ongsiek, Peter Fuhrmann, Christian Kroll * @author Martin Ongsiek, Peter Fuhrmann, Christian Kroll
*/ */
#ifdef OSX_ #ifdef OSX_
#include <GLUT/glut.h> #include <GLUT/glut.h>
#else #else
#include <GL/glut.h> #include <GL/glut.h>
#endif #endif
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <setjmp.h> #include <setjmp.h>
#include "../config.h" #include "../config.h"
#include "../display_loop.h" #include "../display_loop.h"
#include "trackball.h" #include "trackball.h"
/** Number of bytes per row. */ /** Number of bytes per row. */
#define LINEBYTES (((NUM_COLS - 1) / 8) + 1) #define LINEBYTES (((NUM_COLS - 1) / 8) + 1)
/** Fake port for simulating joystick input. */ /** Fake port for simulating joystick input. */
volatile unsigned char fakeport; volatile unsigned char fakeport;
/** Flag which indicates if wait should jump to the menu if fire is pressed. */ /** Flag which indicates if wait should jump to the menu if fire is pressed. */
volatile unsigned char waitForFire; volatile unsigned char waitForFire;
/** The simulated frame buffer of the borg. */ /** The simulated frame buffer of the borg. */
volatile unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; volatile unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
/** Jump buffer which leads directly the menu. */ /** Jump buffer which leads directly the menu. */
extern jmp_buf newmode_jmpbuf; extern jmp_buf newmode_jmpbuf;
/** Width of the window. */ /** Width of the window. */
int WindWidth; int WindWidth;
/** Height of the window. */ /** Height of the window. */
int WindHeight; int WindHeight;
/** Rotation of the x-axis of the scene. */ /** Rotation of the x-axis of the scene. */
float view_rotx = 0; float view_rotx = 0;
/** Rotation of the y-axis of the scene. */ /** Rotation of the y-axis of the scene. */
float view_roty = 0; float view_roty = 0;
/** Rotation of the z-axis of the scene. */ /** Rotation of the z-axis of the scene. */
float view_rotz = 0; float view_rotz = 0;
/** GLUT window handle. */ /** GLUT window handle. */
int win; int win;
/** /**
* Simple wait function. * Simple wait function.
* @param ms The requested delay in milliseconds. * @param ms The requested delay in milliseconds.
*/ */
void wait(unsigned int ms) { void wait(unsigned int ms) {
if (waitForFire) { if (waitForFire) {
if (fakeport & 0x01) { if (fakeport & 0x01) {
longjmp(newmode_jmpbuf, 43); longjmp(newmode_jmpbuf, 43);
} }
} }
usleep(ms * 1000); usleep(ms * 1000);
} }
/** /**
* Draw a LED in the given color (which is a list). * Draw a LED in the given color (which is a list).
* @param color List which contains a sphere. * @param color List which contains a sphere.
* @param pos_x x-coordinate * @param pos_x x-coordinate
* @param pos_y y-coordinate * @param pos_y y-coordinate
* @param pos_z z-coordinate * @param pos_z z-coordinate
*/ */
void drawLED(int color, float pos_x, float pos_y, float pos_z) { void drawLED(int color, float pos_x, float pos_y, float pos_z) {
glPushMatrix(); glPushMatrix();
glTranslatef(pos_x, pos_y, pos_z); glTranslatef(pos_x, pos_y, pos_z);
glCallList(color); glCallList(color);
glPopMatrix(); glPopMatrix();
} }
/** /**
* Draws the LED matrix. * Draws the LED matrix.
*/ */
void display(void) { void display(void) {
int x, y, z, level, color; int x, y, z, level, color;
tbReshape(WindWidth, WindHeight); tbReshape(WindWidth, WindHeight);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix(); glPushMatrix();
glTranslatef(NUM_COLS * 2., 0., NUM_ROWS * 2.); glTranslatef(NUM_COLS * 2., 0., NUM_ROWS * 2.);
tbMatrix(); tbMatrix();
glRotatef(view_rotx, 1.0, 0.0, 0.0); glRotatef(view_rotx, 1.0, 0.0, 0.0);
glRotatef(view_roty, 0.0, 1.0, 0.0); glRotatef(view_roty, 0.0, 1.0, 0.0);
glRotatef(view_rotz, 0.0, 0.0, 1.0); glRotatef(view_rotz, 0.0, 0.0, 1.0);
glTranslatef(-NUM_COLS * 2, 0., -NUM_ROWS * 2.); glTranslatef(-NUM_COLS * 2, 0., -NUM_ROWS * 2.);
for (x = 0; x < 1; x++) { for (x = 0; x < 1; x++) {
for (y = 0; y < NUM_COLS; y++) { for (y = 0; y < NUM_COLS; y++) {
for (z = 0; z < NUM_ROWS; z++) { for (z = 0; z < NUM_ROWS; z++) {
color = 0; color = 0;
for (level = 0; level < NUMPLANE; level++) { for (level = 0; level < NUMPLANE; level++) {
if (pixmap[level][z % NUM_ROWS][y / 8] & (1 << y % 8)) { if (pixmap[level][z % NUM_ROWS][y / 8] & (1 << y % 8)) {
color = level + 1; color = level + 1;
} }
} }
drawLED(color, (float) y * 4.0, (float) x * 4.0, drawLED(color, (float) y * 4.0, (float) x * 4.0,
(float) (NUM_ROWS - 1 - z) * 4.0); (float) (NUM_ROWS - 1 - z) * 4.0);
} }
} }
} }
glPopMatrix(); glPopMatrix();
glutSwapBuffers(); glutSwapBuffers();
usleep(20000); usleep(20000);
} }
/** /**
* Handler for processing key presses. * Handler for processing key presses.
* @param key The pressed key encoded in ASCII. * @param key The pressed key encoded in ASCII.
* @param x X-position of the mouse pointer. * @param x X-position of the mouse pointer.
* @param y Y-position of the mouse pointer. * @param y Y-position of the mouse pointer.
*/ */
void keyboard(unsigned char key, int x, int y) { void keyboard(unsigned char key, int x, int y) {
switch (key) { switch (key) {
case 'q': case 'q':
printf("Quit\n"); printf("Quit\n");
glutDestroyWindow(win); glutDestroyWindow(win);
exit(0); exit(0);
break; break;
case ' ': case ' ':
fakeport |= 0x01; fakeport |= 0x01;
break; break;
case 'a': case 'a':
fakeport |= 0x02; fakeport |= 0x02;
break; break;
case 'd': case 'd':
fakeport |= 0x04; fakeport |= 0x04;
break; break;
case 's': case 's':
fakeport |= 0x08; fakeport |= 0x08;
break; break;
case 'w': case 'w':
fakeport |= 0x10; fakeport |= 0x10;
break; break;
} }
} }
/** /**
* Handler for processing key releases. * Handler for processing key releases.
* @param key The released key encoded in ASCII. * @param key The released key encoded in ASCII.
* @param x X-position of the mouse pointer. * @param x X-position of the mouse pointer.
* @param y Y-position of the mouse pointer. * @param y Y-position of the mouse pointer.
*/ */
void keyboardup(unsigned char key, int x, int y) { void keyboardup(unsigned char key, int x, int y) {
switch (key) { switch (key) {
case ' ': case ' ':
fakeport &= ~0x01; fakeport &= ~0x01;
break; break;
case 'a': case 'a':
fakeport &= ~0x02; fakeport &= ~0x02;
break; break;
case 'd': case 'd':
fakeport &= ~0x04; fakeport &= ~0x04;
break; break;
case 's': case 's':
fakeport &= ~0x08; fakeport &= ~0x08;
break; break;
case 'w': case 'w':
fakeport &= ~0x10; fakeport &= ~0x10;
break; break;
} }
} }
/** /**
* Relays mouse position and button state to the trackball implementation. * Relays mouse position and button state to the trackball implementation.
* @param button Currently monitored button. * @param button Currently monitored button.
* @param state State of that button. * @param state State of that button.
* @param x X-position of the mouse pointer. * @param x X-position of the mouse pointer.
* @param y Y-position of the mouse pointer. * @param y Y-position of the mouse pointer.
*/ */
void mouse(int button, int state, int x, int y) { void mouse(int button, int state, int x, int y) {
tbMouse(button, state, x, y); tbMouse(button, state, x, y);
} }
/** /**
* Relays motion request to the trackball implementation. * Relays motion request to the trackball implementation.
* @param x X-position for the motion direction. * @param x X-position for the motion direction.
* @param y Y-position for the motion direction. * @param y Y-position for the motion direction.
*/ */
void motion(int x, int y) { void motion(int x, int y) {
tbMotion(x, y); tbMotion(x, y);
} }
/** /**
* Updating the window size. * Updating the window size.
* @param width Width of the window. * @param width Width of the window.
* @param height Height of the window. * @param height Height of the window.
*/ */
void reshape(int width, int height) { void reshape(int width, int height) {
tbReshape(width, height); tbReshape(width, height);
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
gluPerspective(60.0, (float) WindWidth / (float) WindWidth, 5., 1000.); gluPerspective(60.0, (float) WindWidth / (float) WindWidth, 5., 1000.);
gluLookAt(NUM_ROWS * 2., NUM_ROWS * 2. + 50., NUM_COLS * 2., NUM_ROWS * 2., gluLookAt(NUM_ROWS * 2., NUM_ROWS * 2. + 50., NUM_COLS * 2., NUM_ROWS * 2.,
NUM_ROWS * 2., NUM_COLS * 2., 0.0, 0.0, 1.0); NUM_ROWS * 2., NUM_COLS * 2., 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
WindWidth = width; WindWidth = width;
WindHeight = height; WindHeight = height;
} }
/** /**
* Handler for special keys (the arrow keys in particular) for adjusting the * Handler for special keys (the arrow keys in particular) for adjusting the
* view angle of the scene. * view angle of the scene.
* @param k The pressed special key using GLUT's nomenclature. * @param k The pressed special key using GLUT's nomenclature.
* @param x X-position of the mouse pointer. * @param x X-position of the mouse pointer.
* @param y Y-position of the mouse pointer. * @param y Y-position of the mouse pointer.
*/ */
static void special(int k, int x, int y) { static void special(int k, int x, int y) {
switch (k) { switch (k) {
case GLUT_KEY_UP: case GLUT_KEY_UP:
view_rotx += 5.0; view_rotx += 5.0;
break; break;
case GLUT_KEY_DOWN: case GLUT_KEY_DOWN:
view_rotx -= 5.0; view_rotx -= 5.0;
break; break;
case GLUT_KEY_LEFT: case GLUT_KEY_LEFT:
view_rotz += 5.0; view_rotz += 5.0;
break; break;
case GLUT_KEY_RIGHT: case GLUT_KEY_RIGHT:
view_rotz -= 5.0; view_rotz -= 5.0;
break; break;
default: default:
return; return;
} }
glutPostRedisplay(); glutPostRedisplay();
} }
/** /**
* Entry point for starting the display loop thread. * Entry point for starting the display loop thread.
* @param unused Not used. Only here to satisfy signature constraints. * @param unused Not used. Only here to satisfy signature constraints.
*/ */
void *display_loop_run(void * unused) { void *display_loop_run(void * unused) {
display_loop(); display_loop();
return 0; return 0;
} }
/** /**
* Main function for the simulator. * Main function for the simulator.
* @param argc The argument count. * @param argc The argument count.
* @param argv Command line arguments. * @param argv Command line arguments.
* @return Exit codem, always zero. * @return Exit codem, always zero.
*/ */
int main(int argc, char **argv) { int main(int argc, char **argv) {
WindHeight = 700; WindHeight = 700;
WindWidth = 700; WindWidth = 700;
glutInit(&argc, argv); glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(WindHeight, WindWidth); glutInitWindowSize(WindHeight, WindWidth);
win = glutCreateWindow("16x16 Borg Simulator"); win = glutCreateWindow("16x16 Borg Simulator");
// callback // callback
glutDisplayFunc(display); glutDisplayFunc(display);
glutIdleFunc(display); glutIdleFunc(display);
glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF); glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF);
glutKeyboardFunc(keyboard); glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardup); glutKeyboardUpFunc(keyboardup);
glutSpecialFunc(special); glutSpecialFunc(special);
glutMouseFunc(mouse); glutMouseFunc(mouse);
glutMotionFunc(motion); glutMotionFunc(motion);
// clearcolor & main loop // clearcolor & main loop
glClearColor(0, 0, 0, 1.0); glClearColor(0, 0, 0, 1.0);
gluPerspective(60.0, (float) WindWidth / (float) WindWidth, 5., 1000.); gluPerspective(60.0, (float) WindWidth / (float) WindWidth, 5., 1000.);
gluLookAt(NUM_COLS * 2., NUM_COLS * 2. + 50., NUM_ROWS * 2., NUM_COLS * 2., gluLookAt(NUM_COLS * 2., NUM_COLS * 2. + 50., NUM_ROWS * 2., NUM_COLS * 2.,
NUM_COLS * 2., NUM_ROWS * 2., 0.0, 0.0, 1.0); NUM_COLS * 2., NUM_ROWS * 2., 0.0, 0.0, 1.0);
// init Call List for LED // init Call List for LED
GLUquadric* quad = gluNewQuadric(); GLUquadric* quad = gluNewQuadric();
glNewList(0, GL_COMPILE); glNewList(0, GL_COMPILE);
glColor4f(0.8, 0.0, 0.0, 1.); glColor4f(0.8, 0.0, 0.0, 1.);
gluSphere(quad, 1.0, 12, 12); gluSphere(quad, 1.0, 12, 12);
glEndList(); glEndList();
glNewList(1, GL_COMPILE); glNewList(1, GL_COMPILE);
glColor4f(0.5, 0.0, 0.0, 1.); glColor4f(0.5, 0.0, 0.0, 1.);
gluSphere(quad, 1.4, 12, 12); gluSphere(quad, 1.4, 12, 12);
glEndList(); glEndList();
glNewList(2, GL_COMPILE); glNewList(2, GL_COMPILE);
glColor4f(0.7, 0.0, 0.0, 1.); glColor4f(0.7, 0.0, 0.0, 1.);
gluSphere(quad, 1.55, 12, 12); gluSphere(quad, 1.55, 12, 12);
glEndList(); glEndList();
glNewList(3, GL_COMPILE); glNewList(3, GL_COMPILE);
glColor4f(1.00, 0.0, 0.0, 1.); glColor4f(1.00, 0.0, 0.0, 1.);
gluSphere(quad, 1.7, 12, 12); gluSphere(quad, 1.7, 12, 12);
glEndList(); glEndList();
tbInit(GLUT_LEFT_BUTTON); tbInit(GLUT_LEFT_BUTTON);
tbAnimate(GL_FALSE); tbAnimate(GL_FALSE);
pthread_t simthread; pthread_t simthread;
pthread_create(&simthread, NULL, display_loop_run, NULL); pthread_create(&simthread, NULL, display_loop_run, NULL);
glutMainLoop(); glutMainLoop();
return 0; return 0;
} }
/*@}*/ /*@}*/

View File

@ -1,295 +1,295 @@
/** /**
* \addtogroup unixsimulator * \addtogroup unixsimulator
*/ */
/*@{*/ /*@{*/
/** /**
* Simple trackball-like motion adapted (ripped off) from projtex.c * Simple trackball-like motion adapted (ripped off) from projtex.c
* (written by David Yu and David Blythe). See the SIGGRAPH '96 * (written by David Yu and David Blythe). See the SIGGRAPH '96
* Advanced OpenGL course notes. * Advanced OpenGL course notes.
* *
* *
* Usage: * Usage:
* *
* o call tbInit() in before any other tb call * o call tbInit() in before any other tb call
* o call tbReshape() from the reshape callback * o call tbReshape() from the reshape callback
* o call tbMatrix() to get the trackball matrix rotation * o call tbMatrix() to get the trackball matrix rotation
* o call tbStartMotion() to begin trackball movememt * o call tbStartMotion() to begin trackball movememt
* o call tbStopMotion() to stop trackball movememt * o call tbStopMotion() to stop trackball movememt
* o call tbMotion() from the motion callback * o call tbMotion() from the motion callback
* o call tbAnimate(GL_TRUE) if you want the trackball to continue * o call tbAnimate(GL_TRUE) if you want the trackball to continue
* spinning after the mouse button has been released * spinning after the mouse button has been released
* o call tbAnimate(GL_FALSE) if you want the trackball to stop * o call tbAnimate(GL_FALSE) if you want the trackball to stop
* spinning after the mouse button has been released * spinning after the mouse button has been released
* *
* Typical setup: * Typical setup:
* *
* *
* void * void
* init(void) * init(void)
* { * {
* tbInit(GLUT_MIDDLE_BUTTON); * tbInit(GLUT_MIDDLE_BUTTON);
* tbAnimate(GL_TRUE); * tbAnimate(GL_TRUE);
* . . . * . . .
* } * }
* *
* void * void
* reshape(int width, int height) * reshape(int width, int height)
* { * {
* tbReshape(width, height); * tbReshape(width, height);
* . . . * . . .
* } * }
* *
* void * void
* display(void) * display(void)
* { * {
* glPushMatrix(); * glPushMatrix();
* *
* tbMatrix(); * tbMatrix();
* . . . draw the scene . . . * . . . draw the scene . . .
* *
* glPopMatrix(); * glPopMatrix();
* } * }
* *
* void * void
* mouse(int button, int state, int x, int y) * mouse(int button, int state, int x, int y)
* { * {
* tbMouse(button, state, x, y); * tbMouse(button, state, x, y);
* . . . * . . .
* } * }
* *
* void * void
* motion(int x, int y) * motion(int x, int y)
* { * {
* tbMotion(x, y); * tbMotion(x, y);
* . . . * . . .
* } * }
* *
* int * int
* main(int argc, char** argv) * main(int argc, char** argv)
* { * {
* . . . * . . .
* init(); * init();
* glutReshapeFunc(reshape); * glutReshapeFunc(reshape);
* glutDisplayFunc(display); * glutDisplayFunc(display);
* glutMouseFunc(mouse); * glutMouseFunc(mouse);
* glutMotionFunc(motion); * glutMotionFunc(motion);
* . . . * . . .
* } * }
* *
* @file trackball.c * @file trackball.c
* @brief Helper functions for the UNIX platform Borg simulator. * @brief Helper functions for the UNIX platform Borg simulator.
* @author Martin Ongsiek, David Yu, David Blythe * @author Martin Ongsiek, David Yu, David Blythe
*/ */
/* includes */ /* includes */
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#ifdef OSX_ #ifdef OSX_
# include <GLUT/glut.h> # include <GLUT/glut.h>
#else #else
# include <GL/glut.h> # include <GL/glut.h>
#endif #endif
#include "trackball.h" #include "trackball.h"
/* globals */ /* globals */
static GLuint tb_lasttime; static GLuint tb_lasttime;
static GLfloat tb_lastposition[3]; static GLfloat tb_lastposition[3];
static GLfloat tb_angle = 0.0; static GLfloat tb_angle = 0.0;
static GLfloat tb_axis[3]; static GLfloat tb_axis[3];
static GLfloat tb_transform[4][4]; static GLfloat tb_transform[4][4];
static GLuint tb_width; static GLuint tb_width;
static GLuint tb_height; static GLuint tb_height;
static GLint tb_button = -1; static GLint tb_button = -1;
static GLboolean tb_tracking = GL_FALSE; static GLboolean tb_tracking = GL_FALSE;
static GLboolean tb_animate = GL_TRUE; static GLboolean tb_animate = GL_TRUE;
/* functions */ /* functions */
/** /**
* Project x and y onto a hemisphere centered within given width and height. * Project x and y onto a hemisphere centered within given width and height.
* @param x X-coordinate * @param x X-coordinate
* @param y Y-coordinate * @param y Y-coordinate
* @param width Width of the hemisphere. * @param width Width of the hemisphere.
* @param height Width of the hemisphere. * @param height Width of the hemisphere.
* @param v Vector where the projection is performed on. * @param v Vector where the projection is performed on.
*/ */
static void _tbPointToVector(int x, int y, int width, int height, float v[3]) { static void _tbPointToVector(int x, int y, int width, int height, float v[3]) {
float d, a; float d, a;
/* project x, y onto a hemisphere centered within width, height. */ /* project x, y onto a hemisphere centered within width, height. */
v[0] = (2.0 * x - width) / width; v[0] = (2.0 * x - width) / width;
v[1] = (height - 2.0 * y) / height; v[1] = (height - 2.0 * y) / height;
d = sqrt(v[0] * v[0] + v[1] * v[1]); d = sqrt(v[0] * v[0] + v[1] * v[1]);
v[2] = cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0)); v[2] = cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0));
a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
v[0] *= a; v[0] *= a;
v[1] *= a; v[1] *= a;
v[2] *= a; v[2] *= a;
} }
/** /**
* Redisplay current window contents. * Redisplay current window contents.
*/ */
static void _tbAnimate(void) { static void _tbAnimate(void) {
glutPostRedisplay(); glutPostRedisplay();
} }
/** /**
* Starts trackball movement depending on the mouse position. * Starts trackball movement depending on the mouse position.
* @param x X-position of the mouse pointer. * @param x X-position of the mouse pointer.
* @param y Y-position of the mouse pointer. * @param y Y-position of the mouse pointer.
* @param button Not used. * @param button Not used.
* @param time Elapsed time. * @param time Elapsed time.
*/ */
void _tbStartMotion(int x, int y, int button, int time) { void _tbStartMotion(int x, int y, int button, int time) {
assert(tb_button != -1); assert(tb_button != -1);
tb_tracking = GL_TRUE; tb_tracking = GL_TRUE;
tb_lasttime = time; tb_lasttime = time;
_tbPointToVector(x, y, tb_width, tb_height, tb_lastposition); _tbPointToVector(x, y, tb_width, tb_height, tb_lastposition);
} }
/** /**
* Stops trackball movement. * Stops trackball movement.
* @param button Not used * @param button Not used
* @param time Not used. * @param time Not used.
*/ */
void _tbStopMotion(int button, unsigned time) { void _tbStopMotion(int button, unsigned time) {
assert(tb_button != -1); assert(tb_button != -1);
tb_tracking = GL_FALSE; tb_tracking = GL_FALSE;
if (time == tb_lasttime && tb_animate) { if (time == tb_lasttime && tb_animate) {
glutIdleFunc(_tbAnimate); glutIdleFunc(_tbAnimate);
} else { } else {
tb_angle = 0.0; tb_angle = 0.0;
if (tb_animate) { if (tb_animate) {
glutIdleFunc(0); glutIdleFunc(0);
} }
} }
} }
/** /**
* Starts or stops the spinning movement of the trackball. * Starts or stops the spinning movement of the trackball.
* @param animate GL_TRUE for starting and GL_FALSE for stopping the animation. * @param animate GL_TRUE for starting and GL_FALSE for stopping the animation.
*/ */
void tbAnimate(GLboolean animate) { void tbAnimate(GLboolean animate) {
tb_animate = animate; tb_animate = animate;
} }
/** /**
* Has to be called before any other tb call. * Has to be called before any other tb call.
* @param button Mouse button state. * @param button Mouse button state.
*/ */
void tbInit(GLuint button) { void tbInit(GLuint button) {
tb_button = button; tb_button = button;
tb_angle = 0.0; tb_angle = 0.0;
/* put the identity in the trackball transform */ /* put the identity in the trackball transform */
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tb_transform); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tb_transform);
glPopMatrix(); glPopMatrix();
} }
/** /**
* Gets the tb matrix rotation. * Gets the tb matrix rotation.
*/ */
void tbMatrix() { void tbMatrix() {
assert(tb_button != -1); assert(tb_button != -1);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glRotatef(tb_angle, -tb_axis[0], tb_axis[2], tb_axis[1]); glRotatef(tb_angle, -tb_axis[0], tb_axis[2], tb_axis[1]);
glMultMatrixf((GLfloat *) tb_transform); glMultMatrixf((GLfloat *) tb_transform);
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tb_transform); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tb_transform);
glPopMatrix(); glPopMatrix();
glMultMatrixf((GLfloat *) tb_transform); glMultMatrixf((GLfloat *) tb_transform);
} }
/** /**
* Reshape callback function for determining the window size. * Reshape callback function for determining the window size.
* @param width Width of the trackball. * @param width Width of the trackball.
* @param height Height of the trackball. * @param height Height of the trackball.
*/ */
void tbReshape(int width, int height) { void tbReshape(int width, int height) {
assert(tb_button != -1); assert(tb_button != -1);
tb_width = width; tb_width = width;
tb_height = height; tb_height = height;
} }
/** /**
* Starts motion depending on mouse position and button state. * Starts motion depending on mouse position and button state.
* @param button The button whose state has changed. * @param button The button whose state has changed.
* @param state The state of that button. * @param state The state of that button.
* @param x X-position of the mouse pointer. * @param x X-position of the mouse pointer.
* @param y Y-position of the mouse pointer. * @param y Y-position of the mouse pointer.
*/ */
void tbMouse(int button, int state, int x, int y) { void tbMouse(int button, int state, int x, int y) {
assert(tb_button != -1); assert(tb_button != -1);
if (state == GLUT_DOWN && button == tb_button) if (state == GLUT_DOWN && button == tb_button)
_tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); _tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
else if (state == GLUT_UP && button == tb_button) else if (state == GLUT_UP && button == tb_button)
_tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME)); _tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME));
} }
/** /**
* Starts a rotating scene motion to the given coordinates. * Starts a rotating scene motion to the given coordinates.
* @param x The x-coordinate. * @param x The x-coordinate.
* @param y The y-coordinate. * @param y The y-coordinate.
*/ */
void tbMotion(int x, int y) { void tbMotion(int x, int y) {
GLfloat current_position[3], dx, dy, dz; GLfloat current_position[3], dx, dy, dz;
assert(tb_button != -1); assert(tb_button != -1);
if (tb_tracking == GL_FALSE) if (tb_tracking == GL_FALSE)
return; return;
_tbPointToVector(x, y, tb_width, tb_height, current_position); _tbPointToVector(x, y, tb_width, tb_height, current_position);
/* calculate the angle to rotate by (directly proportional to the /* calculate the angle to rotate by (directly proportional to the
length of the mouse movement */ length of the mouse movement */
dx = current_position[0] - tb_lastposition[0]; dx = current_position[0] - tb_lastposition[0];
dy = current_position[1] - tb_lastposition[1]; dy = current_position[1] - tb_lastposition[1];
dz = current_position[2] - tb_lastposition[2]; dz = current_position[2] - tb_lastposition[2];
tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz);
/* calculate the axis of rotation (cross product) */ /* calculate the axis of rotation (cross product) */
tb_axis[0] = tb_lastposition[1] * current_position[2] tb_axis[0] = tb_lastposition[1] * current_position[2]
- tb_lastposition[2] * current_position[1]; - tb_lastposition[2] * current_position[1];
tb_axis[1] = tb_lastposition[2] * current_position[0] tb_axis[1] = tb_lastposition[2] * current_position[0]
- tb_lastposition[0] * current_position[2]; - tb_lastposition[0] * current_position[2];
tb_axis[2] = tb_lastposition[0] * current_position[1] tb_axis[2] = tb_lastposition[0] * current_position[1]
- tb_lastposition[1] * current_position[0]; - tb_lastposition[1] * current_position[0];
/* reset for next time */ /* reset for next time */
tb_lasttime = glutGet(GLUT_ELAPSED_TIME); tb_lasttime = glutGet(GLUT_ELAPSED_TIME);
tb_lastposition[0] = current_position[0]; tb_lastposition[0] = current_position[0];
tb_lastposition[1] = current_position[1]; tb_lastposition[1] = current_position[1];
tb_lastposition[2] = current_position[2]; tb_lastposition[2] = current_position[2];
/* remember to draw new position */ /* remember to draw new position */
glutPostRedisplay(); glutPostRedisplay();
} }
/*@}*/ /*@}*/

View File

@ -1,99 +1,99 @@
/** /**
* \addtogroup unixsimulator * \addtogroup unixsimulator
*/ */
/*@{*/ /*@{*/
/** /**
* Simple trackball-like motion adapted (ripped off) from projtex.c * Simple trackball-like motion adapted (ripped off) from projtex.c
* (written by David Yu and David Blythe). See the SIGGRAPH '96 * (written by David Yu and David Blythe). See the SIGGRAPH '96
* Advanced OpenGL course notes. * Advanced OpenGL course notes.
* *
* *
* Usage: * Usage:
* *
* o call tbInit() in before any other tb call * o call tbInit() in before any other tb call
* o call tbReshape() from the reshape callback * o call tbReshape() from the reshape callback
* o call tbMatrix() to get the trackball matrix rotation * o call tbMatrix() to get the trackball matrix rotation
* o call tbStartMotion() to begin trackball movememt * o call tbStartMotion() to begin trackball movememt
* o call tbStopMotion() to stop trackball movememt * o call tbStopMotion() to stop trackball movememt
* o call tbMotion() from the motion callback * o call tbMotion() from the motion callback
* o call tbAnimate(GL_TRUE) if you want the trackball to continue * o call tbAnimate(GL_TRUE) if you want the trackball to continue
* spinning after the mouse button has been released * spinning after the mouse button has been released
* o call tbAnimate(GL_FALSE) if you want the trackball to stop * o call tbAnimate(GL_FALSE) if you want the trackball to stop
* spinning after the mouse button has been released * spinning after the mouse button has been released
* *
* Typical setup: * Typical setup:
* *
* *
* void * void
* init(void) * init(void)
* { * {
* tbInit(GLUT_MIDDLE_BUTTON); * tbInit(GLUT_MIDDLE_BUTTON);
* tbAnimate(GL_TRUE); * tbAnimate(GL_TRUE);
* . . . * . . .
* } * }
* *
* void * void
* reshape(int width, int height) * reshape(int width, int height)
* { * {
* tbReshape(width, height); * tbReshape(width, height);
* . . . * . . .
* } * }
* *
* void * void
* display(void) * display(void)
* { * {
* glPushMatrix(); * glPushMatrix();
* *
* tbMatrix(); * tbMatrix();
* . . . draw the scene . . . * . . . draw the scene . . .
* *
* glPopMatrix(); * glPopMatrix();
* } * }
* *
* void * void
* mouse(int button, int state, int x, int y) * mouse(int button, int state, int x, int y)
* { * {
* tbMouse(button, state, x, y); * tbMouse(button, state, x, y);
* . . . * . . .
* } * }
* *
* void * void
* motion(int x, int y) * motion(int x, int y)
* { * {
* tbMotion(x, y); * tbMotion(x, y);
* . . . * . . .
* } * }
* *
* int * int
* main(int argc, char** argv) * main(int argc, char** argv)
* { * {
* . . . * . . .
* init(); * init();
* glutReshapeFunc(reshape); * glutReshapeFunc(reshape);
* glutDisplayFunc(display); * glutDisplayFunc(display);
* glutMouseFunc(mouse); * glutMouseFunc(mouse);
* glutMotionFunc(motion); * glutMotionFunc(motion);
* . . . * . . .
* } * }
* *
* @file trackball.h * @file trackball.h
* @brief Header file for helper functions for the UNIX platform Borg simulator. * @brief Header file for helper functions for the UNIX platform Borg simulator.
* @author Martin Ongsiek, David Yu, David Blythe * @author Martin Ongsiek, David Yu, David Blythe
*/ */
/* functions */ /* functions */
void tbInit(GLuint button); void tbInit(GLuint button);
void tbMatrix(void); void tbMatrix(void);
void tbReshape(int width, int height); void tbReshape(int width, int height);
void tbMouse(int button, int state, int x, int y); void tbMouse(int button, int state, int x, int y);
void tbMotion(int x, int y); void tbMotion(int x, int y);
void tbAnimate(GLboolean animate); void tbAnimate(GLboolean animate);
/*@}*/ /*@}*/