Christian Kroll
11 years ago
16 changed files with 2278 additions and 2278 deletions
@ -1,18 +1,18 @@ |
|||
|
|||
//EEPPROM compatibility support for simulator
|
|||
|
|||
#ifdef AVR |
|||
#include <avr/eeprom.h> |
|||
#else |
|||
#include <stdint.h> |
|||
|
|||
void eeprom_write_byte (uint8_t *p, uint8_t value); |
|||
void eeprom_write_word (uint16_t *p, uint16_t value); |
|||
|
|||
uint8_t eeprom_read_byte (const uint8_t *p); |
|||
uint16_t eeprom_read_word (const uint16_t *p); |
|||
|
|||
#define eeprom_busy_wait() |
|||
#define EEMEM __attribute__((section(".eeprom"))) |
|||
|
|||
#endif |
|||
|
|||
//EEPPROM compatibility support for simulator
|
|||
|
|||
#ifdef AVR |
|||
#include <avr/eeprom.h> |
|||
#else |
|||
#include <stdint.h> |
|||
|
|||
void eeprom_write_byte (uint8_t *p, uint8_t value); |
|||
void eeprom_write_word (uint16_t *p, uint16_t value); |
|||
|
|||
uint8_t eeprom_read_byte (const uint8_t *p); |
|||
uint16_t eeprom_read_word (const uint16_t *p); |
|||
|
|||
#define eeprom_busy_wait() |
|||
#define EEMEM __attribute__((section(".eeprom"))) |
|||
|
|||
#endif |
|||
|
@ -1,3 +1,3 @@ |
|||
|
|||
#define sei() |
|||
#define cli() |
|||
|
|||
#define sei() |
|||
#define cli() |
|||
|
@ -1,4 +1,4 @@ |
|||
|
|||
void display_loop(); |
|||
|
|||
extern jmp_buf newmode_jmpbuf; |
|||
|
|||
void display_loop(); |
|||
|
|||
extern jmp_buf newmode_jmpbuf; |
|||
|
@ -1,22 +1,22 @@ |
|||
|
|||
ifeq ($(GAME_TETRIS_CORE),y) |
|||
SUBDIRS += $(TOPDIR)/games/tetris |
|||
endif |
|||
|
|||
ifeq ($(GAME_SPACE_INVADERS),y) |
|||
SUBDIRS += $(TOPDIR)/games/space_invaders |
|||
endif |
|||
|
|||
ifeq ($(GAME_SNAKE),y) |
|||
SUBDIRS += $(TOPDIR)/games/snake |
|||
endif |
|||
|
|||
ifeq ($(ANIMATION_SNAKE),y) |
|||
ifneq ($(GAME_SNAKE),y) |
|||
SUBDIRS += $(TOPDIR)/games/snake |
|||
endif |
|||
endif |
|||
|
|||
ifeq ($(GAME_BREAKOUT),y) |
|||
SUBDIRS += $(TOPDIR)/games/breakout |
|||
endif |
|||
|
|||
ifeq ($(GAME_TETRIS_CORE),y) |
|||
SUBDIRS += $(TOPDIR)/games/tetris |
|||
endif |
|||
|
|||
ifeq ($(GAME_SPACE_INVADERS),y) |
|||
SUBDIRS += $(TOPDIR)/games/space_invaders |
|||
endif |
|||
|
|||
ifeq ($(GAME_SNAKE),y) |
|||
SUBDIRS += $(TOPDIR)/games/snake |
|||
endif |
|||
|
|||
ifeq ($(ANIMATION_SNAKE),y) |
|||
ifneq ($(GAME_SNAKE),y) |
|||
SUBDIRS += $(TOPDIR)/games/snake |
|||
endif |
|||
endif |
|||
|
|||
ifeq ($(GAME_BREAKOUT),y) |
|||
SUBDIRS += $(TOPDIR)/games/breakout |
|||
endif |
|||
|
@ -1,471 +1,471 @@ |
|||
/**
|
|||
* \defgroup Snake Snake, a casual game including a demo mode. |
|||
* |
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @file snake_game.c |
|||
* @brief Implementation of the snake game. |
|||
* @author Peter Fuhrmann, Martin Ongsiek, Daniel Otte, Christian Kroll |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
#include <stdint.h> |
|||
#include "../../config.h" |
|||
#include "../../compat/pgmspace.h" |
|||
#include "../../pixel.h" |
|||
#include "../../random/prng.h" |
|||
#include "../../util.h" |
|||
#include "../../joystick/joystick.h" |
|||
#include "../../menu/menu.h" |
|||
#include "snake_game.h" |
|||
|
|||
|
|||
#if defined MENU_SUPPORT && defined GAME_SNAKE |
|||
// snake icon (MSB is leftmost pixel)
|
|||
static const uint8_t icon[8] PROGMEM = |
|||
{0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xad, 0xa1, 0xbf}; |
|||
|
|||
game_descriptor_t snake_game_descriptor __attribute__((section(".game_descriptors"))) = |
|||
{ |
|||
&snake_game, |
|||
icon, |
|||
}; |
|||
#endif |
|||
|
|||
|
|||
/**
|
|||
* If defined, joystick controls are NOT as "seen" by the snake but absolute, |
|||
* that is, if pressing up, snake goes up, etc. |
|||
*/ |
|||
#define SNAKE_NEWCONTROL |
|||
|
|||
#if !defined USNAKE_MAX_LENGTH || defined DOXYGEN |
|||
/** The maximum length of the snake. */ |
|||
#define USNAKE_MAX_LENGTH 64u |
|||
#endif |
|||
|
|||
#if !defined SNAKE_MAX_APPLES || defined DOXYGEN |
|||
/** The maximum number of apples lying on the playing field. */ |
|||
#define SNAKE_MAX_APPLES 10 |
|||
#endif |
|||
|
|||
#if !defined SNAKE_CYCLE_DELAY || defined DOXYGEN |
|||
/** Delay (in ms) between every state change. */ |
|||
#define SNAKE_CYCLE_DELAY 100 |
|||
#endif |
|||
|
|||
#if !defined SNAKE_TERMINATION_DELAY || defined DOXYGEN |
|||
/** Delay (in ms) between every disappearing pixel of a dying snake. */ |
|||
#define SNAKE_TERMINATION_DELAY 60 |
|||
#endif |
|||
|
|||
/** The color of the surrounding border. */ |
|||
#define SNAKE_COLOR_BORDER 3 |
|||
/** The color of the snake. */ |
|||
#define SNAKE_COLOR_PROTAGONIST 3 |
|||
/** The color of the apples. */ |
|||
#define SNAKE_COLOR_APPLE 3 |
|||
|
|||
|
|||
/**
|
|||
* Directions of the snake. |
|||
*/ |
|||
enum snake_dir_e |
|||
{ |
|||
SNAKE_DIR_UP, /**< Snake is heading up. */ |
|||
SNAKE_DIR_RIGHT,/**< Snake is heading right. */ |
|||
SNAKE_DIR_DOWN, /**< Snake is heading down. */ |
|||
SNAKE_DIR_LEFT, /**< Snake is heading left. */ |
|||
SNAKE_DIR_NONE /**< Helper value for a "resting" joystick. */ |
|||
}; |
|||
#ifdef NDEBUG |
|||
typedef uint8_t snake_dir_t; |
|||
#else |
|||
typedef enum snake_dir_e snake_dir_t; |
|||
#endif |
|||
|
|||
/**
|
|||
* 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. |
|||
*/ |
|||
typedef struct snake_protagonist_s |
|||
{ |
|||
pixel aSegments[USNAKE_MAX_LENGTH]; /**< All segments of the snake. */ |
|||
uint8_t nHeadIndex; /**< Index of the head segment. */ |
|||
uint8_t nTailIndex; /**< Index of the tail segment. */ |
|||
snake_dir_t dir; /**< Direction of the snake. */ |
|||
} snake_protagonist_t; |
|||
|
|||
|
|||
/**
|
|||
* This structure keeps track of all apples which are on the playing field. |
|||
*/ |
|||
typedef struct snake_apples_s |
|||
{ |
|||
pixel aApples[SNAKE_MAX_APPLES]; /**< Positions of all existing apples. */ |
|||
uint8_t nAppleCount; /**< Count of currently existing apples. */ |
|||
} snake_apples_t; |
|||
|
|||
|
|||
/**
|
|||
* This function returns the next position which is calculated from a given |
|||
* (current) position and a direction. |
|||
* @param pxNext The position we're going to leave. |
|||
* @param dir The direction that we are heading. |
|||
* @return The next position according the given direction. |
|||
*/ |
|||
static pixel snake_nextDirection(pixel const pxNext, |
|||
snake_dir_t const dir) |
|||
{ |
|||
assert(dir < 4); |
|||
static int8_t const nDelta[] = {0, -1, 0, 1, 0}; |
|||
return (pixel){pxNext.x + nDelta[dir], pxNext.y + nDelta[dir + 1]}; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* This function draws a border around the playing field. |
|||
*/ |
|||
static void snake_drawBorder(void) |
|||
{ |
|||
#if NUM_COLS == NUM_ROWS |
|||
for (uint8_t i = NUM_COLS; i--;) |
|||
{ |
|||
setpixel((pixel){i, 0}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){i, NUM_ROWS - 1}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){0, i}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){NUM_COLS -1, i}, SNAKE_COLOR_BORDER); |
|||
} |
|||
#else |
|||
for (uint8_t x = NUM_COLS; x--;) |
|||
{ |
|||
setpixel((pixel){x, 0}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){x, NUM_ROWS - 1}, SNAKE_COLOR_BORDER); |
|||
} |
|||
for (uint8_t y = NUM_ROWS; y--;) |
|||
{ |
|||
setpixel((pixel){0, y}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){NUM_COLS - 1, y}, SNAKE_COLOR_BORDER); |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
#ifdef GAME_SNAKE |
|||
/**
|
|||
* This function translates hardware port information into joystick directions. |
|||
* @return The current direction of the joystick. |
|||
* @see snake_dir_e |
|||
*/ |
|||
static snake_dir_t snake_queryJoystick(void) |
|||
{ |
|||
snake_dir_t dirJoystick; |
|||
if (JOYISUP) |
|||
{ |
|||
dirJoystick = SNAKE_DIR_UP; |
|||
} |
|||
else if (JOYISRIGHT) |
|||
{ |
|||
dirJoystick = SNAKE_DIR_RIGHT; |
|||
} |
|||
else if (JOYISDOWN) |
|||
{ |
|||
dirJoystick = SNAKE_DIR_DOWN; |
|||
} |
|||
else if (JOYISLEFT) |
|||
{ |
|||
dirJoystick = SNAKE_DIR_LEFT; |
|||
} |
|||
else |
|||
{ |
|||
dirJoystick = SNAKE_DIR_NONE; |
|||
} |
|||
|
|||
return dirJoystick; |
|||
} |
|||
#endif |
|||
|
|||
/**
|
|||
* This function initializes the structure which represents the snake itself. |
|||
* @param pprotSnake The pointer the protagonist structure to be initialized. |
|||
*/ |
|||
static void snake_initGameProtagonist(snake_protagonist_t *pprotSnake) |
|||
{ |
|||
pprotSnake->aSegments[0] = (pixel){NUM_COLS / 2, NUM_ROWS / 2}; |
|||
pprotSnake->aSegments[1] = (pixel){NUM_COLS / 2, NUM_ROWS / 2 - 1}; |
|||
pprotSnake->nTailIndex = 0; |
|||
pprotSnake->nHeadIndex = 1; |
|||
pprotSnake->dir = SNAKE_DIR_UP; |
|||
} |
|||
|
|||
#ifdef GAME_SNAKE |
|||
/**
|
|||
* Determines the next direction of the snake depending on the joystick's input. |
|||
* @param pprotSnake A pointer to the structure of the protagonist. |
|||
* @param pdirLast Last joystick direction to recognize prolonged key presses. |
|||
*/ |
|||
static void snake_userControl(snake_protagonist_t *pprotSnake, |
|||
snake_dir_t *pdirLast) |
|||
{ |
|||
snake_dir_t dirJoystick = snake_queryJoystick(); |
|||
#ifdef SNAKE_NEWCONTROL |
|||
if (dirJoystick != SNAKE_DIR_NONE) |
|||
{ |
|||
// valid transitions can only be uneven
|
|||
if ((pprotSnake->dir + dirJoystick) & 0x01) |
|||
{ |
|||
pprotSnake->dir = dirJoystick; |
|||
} |
|||
} |
|||
#else |
|||
if ((dirJoystick ^ *pdirLast) && (dirJoystick != SNAKE_DIR_NONE)) |
|||
{ |
|||
// only left or right movements are valid
|
|||
if (dirJoystick & 0x01) |
|||
{ |
|||
// rotate through directions (either clockwise or counterclockwise)
|
|||
pprotSnake->dir = (pprotSnake->dir + |
|||
(dirJoystick == SNAKE_DIR_LEFT ? 3 : 1)) % 4u; |
|||
} |
|||
} |
|||
*pdirLast = dirJoystick; |
|||
#endif |
|||
} |
|||
#endif |
|||
|
|||
|
|||
#ifdef ANIMATION_SNAKE |
|||
/**
|
|||
* This function approximates the next direction which may lead to an apple |
|||
* (with a particular probability). |
|||
* @param pprotSnake A pointer to the hungry protagonist. |
|||
* @param pApples A pointer to a bunch of apples. |
|||
*/ |
|||
static void snake_autoRoute(snake_protagonist_t *pprotSnake, |
|||
snake_apples_t *pApples) |
|||
{ |
|||
pixel pxHead = pprotSnake->aSegments[pprotSnake->nHeadIndex]; |
|||
if (random8() < 80) |
|||
{ |
|||
uint8_t nNextApple = 0; |
|||
if (pApples->nAppleCount) |
|||
{ |
|||
uint8_t nMinDist = UINT8_MAX; |
|||
for (uint8_t i = 0; i < pApples->nAppleCount; ++i) |
|||
{ |
|||
uint8_t nDistX; |
|||
if (pxHead.x > pApples->aApples[i].x) |
|||
{ |
|||
nDistX = pxHead.x - pApples->aApples[i].x; |
|||
} |
|||
else |
|||
{ |
|||
nDistX = pApples->aApples[i].x - pxHead.x; |
|||
} |
|||
|
|||
uint8_t nDistY; |
|||
if (pxHead.y > pApples->aApples[i].y) |
|||
{ |
|||
nDistY = pxHead.y - pApples->aApples[i].y; |
|||
} |
|||
else |
|||
{ |
|||
nDistY = pApples->aApples[i].y - pxHead.y; |
|||
} |
|||
|
|||
if ((nDistX + nDistY) < nMinDist) |
|||
{ |
|||
nMinDist = nDistX + nDistY; |
|||
nNextApple = i; |
|||
} |
|||
} |
|||
if (pprotSnake->dir ^ 0x01) // vertical direction?
|
|||
{ |
|||
pprotSnake->dir = pApples->aApples[nNextApple].x > pxHead.x ? |
|||
SNAKE_DIR_LEFT : SNAKE_DIR_RIGHT; |
|||
} |
|||
else |
|||
{ |
|||
pprotSnake->dir = pApples->aApples[nNextApple].y > pxHead.y ? |
|||
SNAKE_DIR_DOWN : SNAKE_DIR_UP; |
|||
} |
|||
} |
|||
} |
|||
|
|||
for (uint8_t i = 0; i < 4; ++i) |
|||
{ |
|||
pixel pxTest = snake_nextDirection(pxHead, pprotSnake->dir); |
|||
if (get_pixel(pxTest)) |
|||
{ |
|||
for (uint8_t j = 0; j < pApples->nAppleCount; ++j) |
|||
{ |
|||
if ((pxTest.x == pApples->aApples[j].x) && |
|||
(pxTest.y == pApples->aApples[j].y)) |
|||
{ |
|||
return; |
|||
} |
|||
} |
|||
pprotSnake->dir = (pprotSnake->dir + 1u) % 4u; |
|||
} |
|||
else |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
#endif |
|||
|
|||
|
|||
/**
|
|||
* Small animation that lets the dying snake disappear piece by piece. |
|||
* @param pprotSnake A pointer to the dying snake. |
|||
*/ |
|||
static void snake_eliminateProtagonist(snake_protagonist_t *pprotSnake) |
|||
{ |
|||
while (pprotSnake->nTailIndex != pprotSnake->nHeadIndex) |
|||
{ |
|||
clearpixel(pprotSnake->aSegments[pprotSnake->nTailIndex++]); |
|||
pprotSnake->nTailIndex %= USNAKE_MAX_LENGTH; |
|||
wait(SNAKE_TERMINATION_DELAY); |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Initializes the structure that keeps track of all currently existing apples. |
|||
* @param pApples Pointer to the set of apples in question. |
|||
*/ |
|||
static void snake_initApples(snake_apples_t *pApples) |
|||
{ |
|||
pApples->nAppleCount = 0; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* 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 pxHead The position to be tested. |
|||
* @return 0 if no apples were found, 1 otherwise |
|||
*/ |
|||
static uint8_t snake_checkForApple(snake_apples_t *pApples, pixel pxHead) |
|||
{ |
|||
for (uint8_t i = pApples->nAppleCount; i--;) |
|||
{ |
|||
if ((pxHead.x == pApples->aApples[i].x) && |
|||
(pxHead.y == pApples->aApples[i].y)) |
|||
{ |
|||
for (; i < pApples->nAppleCount; ++i) |
|||
{ |
|||
pApples->aApples[i] = pApples->aApples[i + 1]; |
|||
} |
|||
--pApples->nAppleCount; |
|||
return 1; |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Creates some new apples from time to time. |
|||
* @param pApples Pointer to a set of apples. |
|||
*/ |
|||
static void snake_spawnApples(snake_apples_t *pApples) |
|||
{ |
|||
if ((pApples->nAppleCount < SNAKE_MAX_APPLES) && (random8() < 10)) |
|||
{ |
|||
pixel pxApple = (pixel){(random8() % (NUM_COLS-2)) + 1, |
|||
(random8() % (NUM_ROWS - 2)) + 1}; |
|||
if (!get_pixel(pxApple)) |
|||
{ |
|||
pApples->aApples[pApples->nAppleCount++] = pxApple; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* The main loop (plus initialization) that both drives the game and the |
|||
* demo mode. |
|||
* @param bDemoMode 0 indicates game mode, 1 indicates demo mode |
|||
*/ |
|||
void snake_engine(uint8_t bDemoMode) |
|||
{ |
|||
// init
|
|||
snake_protagonist_t protSnake; |
|||
snake_initGameProtagonist(&protSnake); |
|||
snake_apples_t apples; |
|||
snake_initApples(&apples); |
|||
snake_dir_t dirLast = SNAKE_DIR_NONE; |
|||
|
|||
// init screen
|
|||
clear_screen(0); |
|||
snake_drawBorder(); |
|||
|
|||
for (uint8_t nAppleColor = 0; 1; nAppleColor ^= SNAKE_COLOR_APPLE) |
|||
{ |
|||
// determine new direction
|
|||
#if defined ANIMATION_SNAKE && defined GAME_SNAKE |
|||
if (bDemoMode) |
|||
{ |
|||
snake_autoRoute(&protSnake, &apples); |
|||
} |
|||
else |
|||
{ |
|||
snake_userControl(&protSnake, &dirLast); |
|||
} |
|||
#elif defined ANIMATION_SNAKE |
|||
snake_autoRoute(&protSnake, &apples); |
|||
#else |
|||
snake_userControl(&protSnake, &dirLast); |
|||
#endif |
|||
|
|||
// actually move head
|
|||
pixel pxOldHead = protSnake.aSegments[protSnake.nHeadIndex]; |
|||
protSnake.nHeadIndex = (protSnake.nHeadIndex + 1u) % USNAKE_MAX_LENGTH; |
|||
protSnake.aSegments[protSnake.nHeadIndex] = |
|||
snake_nextDirection(pxOldHead, protSnake.dir); |
|||
|
|||
// look if we have found an apple
|
|||
if (!snake_checkForApple(&apples, |
|||
protSnake.aSegments[protSnake.nHeadIndex])) |
|||
{ |
|||
// quit game if we hit something which is not an apple
|
|||
if (get_pixel(protSnake.aSegments[protSnake.nHeadIndex])) |
|||
{ |
|||
snake_eliminateProtagonist(&protSnake); |
|||
return; |
|||
} |
|||
|
|||
// remove last segment
|
|||
clearpixel(protSnake.aSegments[protSnake.nTailIndex]) |
|||
protSnake.nTailIndex = |
|||
(protSnake.nTailIndex + 1u) % USNAKE_MAX_LENGTH; |
|||
|
|||
// new apples
|
|||
snake_spawnApples(&apples); |
|||
} |
|||
// draw new head
|
|||
setpixel(protSnake.aSegments[protSnake.nHeadIndex], |
|||
SNAKE_COLOR_PROTAGONIST); |
|||
|
|||
// draw apples
|
|||
for (uint8_t i = apples.nAppleCount; i--;) |
|||
{ |
|||
setpixel(apples.aApples[i], nAppleColor); |
|||
} |
|||
|
|||
wait(SNAKE_CYCLE_DELAY); |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* Snake in game mode. |
|||
*/ |
|||
void snake_game(void) |
|||
{ |
|||
snake_engine(0); |
|||
} |
|||
|
|||
/*@}*/ |
|||
/**
|
|||
* \defgroup Snake Snake, a casual game including a demo mode. |
|||
* |
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @file snake_game.c |
|||
* @brief Implementation of the snake game. |
|||
* @author Peter Fuhrmann, Martin Ongsiek, Daniel Otte, Christian Kroll |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
#include <stdint.h> |
|||
#include "../../config.h" |
|||
#include "../../compat/pgmspace.h" |
|||
#include "../../pixel.h" |
|||
#include "../../random/prng.h" |
|||
#include "../../util.h" |
|||
#include "../../joystick/joystick.h" |
|||
#include "../../menu/menu.h" |
|||
#include "snake_game.h" |
|||
|
|||
|
|||
#if defined MENU_SUPPORT && defined GAME_SNAKE |
|||
// snake icon (MSB is leftmost pixel)
|
|||
static const uint8_t icon[8] PROGMEM = |
|||
{0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xad, 0xa1, 0xbf}; |
|||
|
|||
game_descriptor_t snake_game_descriptor __attribute__((section(".game_descriptors"))) = |
|||
{ |
|||
&snake_game, |
|||
icon, |
|||
}; |
|||
#endif |
|||
|
|||
|
|||
/**
|
|||
* If defined, joystick controls are NOT as "seen" by the snake but absolute, |
|||
* that is, if pressing up, snake goes up, etc. |
|||
*/ |
|||
#define SNAKE_NEWCONTROL |
|||
|
|||
#if !defined USNAKE_MAX_LENGTH || defined DOXYGEN |
|||
/** The maximum length of the snake. */ |
|||
#define USNAKE_MAX_LENGTH 64u |
|||
#endif |
|||
|
|||
#if !defined SNAKE_MAX_APPLES || defined DOXYGEN |
|||
/** The maximum number of apples lying on the playing field. */ |
|||
#define SNAKE_MAX_APPLES 10 |
|||
#endif |
|||
|
|||
#if !defined SNAKE_CYCLE_DELAY || defined DOXYGEN |
|||
/** Delay (in ms) between every state change. */ |
|||
#define SNAKE_CYCLE_DELAY 100 |
|||
#endif |
|||
|
|||
#if !defined SNAKE_TERMINATION_DELAY || defined DOXYGEN |
|||
/** Delay (in ms) between every disappearing pixel of a dying snake. */ |
|||
#define SNAKE_TERMINATION_DELAY 60 |
|||
#endif |
|||
|
|||
/** The color of the surrounding border. */ |
|||
#define SNAKE_COLOR_BORDER 3 |
|||
/** The color of the snake. */ |
|||
#define SNAKE_COLOR_PROTAGONIST 3 |
|||
/** The color of the apples. */ |
|||
#define SNAKE_COLOR_APPLE 3 |
|||
|
|||
|
|||
/**
|
|||
* Directions of the snake. |
|||
*/ |
|||
enum snake_dir_e |
|||
{ |
|||
SNAKE_DIR_UP, /**< Snake is heading up. */ |
|||
SNAKE_DIR_RIGHT,/**< Snake is heading right. */ |
|||
SNAKE_DIR_DOWN, /**< Snake is heading down. */ |
|||
SNAKE_DIR_LEFT, /**< Snake is heading left. */ |
|||
SNAKE_DIR_NONE /**< Helper value for a "resting" joystick. */ |
|||
}; |
|||
#ifdef NDEBUG |
|||
typedef uint8_t snake_dir_t; |
|||
#else |
|||
typedef enum snake_dir_e snake_dir_t; |
|||
#endif |
|||
|
|||
/**
|
|||
* 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. |
|||
*/ |
|||
typedef struct snake_protagonist_s |
|||
{ |
|||
pixel aSegments[USNAKE_MAX_LENGTH]; /**< All segments of the snake. */ |
|||
uint8_t nHeadIndex; /**< Index of the head segment. */ |
|||
uint8_t nTailIndex; /**< Index of the tail segment. */ |
|||
snake_dir_t dir; /**< Direction of the snake. */ |
|||
} snake_protagonist_t; |
|||
|
|||
|
|||
/**
|
|||
* This structure keeps track of all apples which are on the playing field. |
|||
*/ |
|||
typedef struct snake_apples_s |
|||
{ |
|||
pixel aApples[SNAKE_MAX_APPLES]; /**< Positions of all existing apples. */ |
|||
uint8_t nAppleCount; /**< Count of currently existing apples. */ |
|||
} snake_apples_t; |
|||
|
|||
|
|||
/**
|
|||
* This function returns the next position which is calculated from a given |
|||
* (current) position and a direction. |
|||
* @param pxNext The position we're going to leave. |
|||
* @param dir The direction that we are heading. |
|||
* @return The next position according the given direction. |
|||
*/ |
|||
static pixel snake_nextDirection(pixel const pxNext, |
|||
snake_dir_t const dir) |
|||
{ |
|||
assert(dir < 4); |
|||
static int8_t const nDelta[] = {0, -1, 0, 1, 0}; |
|||
return (pixel){pxNext.x + nDelta[dir], pxNext.y + nDelta[dir + 1]}; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* This function draws a border around the playing field. |
|||
*/ |
|||
static void snake_drawBorder(void) |
|||
{ |
|||
#if NUM_COLS == NUM_ROWS |
|||
for (uint8_t i = NUM_COLS; i--;) |
|||
{ |
|||
setpixel((pixel){i, 0}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){i, NUM_ROWS - 1}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){0, i}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){NUM_COLS -1, i}, SNAKE_COLOR_BORDER); |
|||
} |
|||
#else |
|||
for (uint8_t x = NUM_COLS; x--;) |
|||
{ |
|||
setpixel((pixel){x, 0}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){x, NUM_ROWS - 1}, SNAKE_COLOR_BORDER); |
|||
} |
|||
for (uint8_t y = NUM_ROWS; y--;) |
|||
{ |
|||
setpixel((pixel){0, y}, SNAKE_COLOR_BORDER); |
|||
setpixel((pixel){NUM_COLS - 1, y}, SNAKE_COLOR_BORDER); |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
#ifdef GAME_SNAKE |
|||
/**
|
|||
* This function translates hardware port information into joystick directions. |
|||
* @return The current direction of the joystick. |
|||
* @see snake_dir_e |
|||
*/ |
|||
static snake_dir_t snake_queryJoystick(void) |
|||
{ |
|||
snake_dir_t dirJoystick; |
|||
if (JOYISUP) |
|||
{ |
|||
dirJoystick = SNAKE_DIR_UP; |
|||
} |
|||
else if (JOYISRIGHT) |
|||
{ |
|||
dirJoystick = SNAKE_DIR_RIGHT; |
|||
} |
|||
else if (JOYISDOWN) |
|||
{ |
|||
dirJoystick = SNAKE_DIR_DOWN; |
|||
} |
|||
else if (JOYISLEFT) |
|||
{ |
|||
dirJoystick = SNAKE_DIR_LEFT; |
|||
} |
|||
else |
|||
{ |
|||
dirJoystick = SNAKE_DIR_NONE; |
|||
} |
|||
|
|||
return dirJoystick; |
|||
} |
|||
#endif |
|||
|
|||
/**
|
|||
* This function initializes the structure which represents the snake itself. |
|||
* @param pprotSnake The pointer the protagonist structure to be initialized. |
|||
*/ |
|||
static void snake_initGameProtagonist(snake_protagonist_t *pprotSnake) |
|||
{ |
|||
pprotSnake->aSegments[0] = (pixel){NUM_COLS / 2, NUM_ROWS / 2}; |
|||
pprotSnake->aSegments[1] = (pixel){NUM_COLS / 2, NUM_ROWS / 2 - 1}; |
|||
pprotSnake->nTailIndex = 0; |
|||
pprotSnake->nHeadIndex = 1; |
|||
pprotSnake->dir = SNAKE_DIR_UP; |
|||
} |
|||
|
|||
#ifdef GAME_SNAKE |
|||
/**
|
|||
* Determines the next direction of the snake depending on the joystick's input. |
|||
* @param pprotSnake A pointer to the structure of the protagonist. |
|||
* @param pdirLast Last joystick direction to recognize prolonged key presses. |
|||
*/ |
|||
static void snake_userControl(snake_protagonist_t *pprotSnake, |
|||
snake_dir_t *pdirLast) |
|||
{ |
|||
snake_dir_t dirJoystick = snake_queryJoystick(); |
|||
#ifdef SNAKE_NEWCONTROL |
|||
if (dirJoystick != SNAKE_DIR_NONE) |
|||
{ |
|||
// valid transitions can only be uneven
|
|||
if ((pprotSnake->dir + dirJoystick) & 0x01) |
|||
{ |
|||
pprotSnake->dir = dirJoystick; |
|||
} |
|||
} |
|||
#else |
|||
if ((dirJoystick ^ *pdirLast) && (dirJoystick != SNAKE_DIR_NONE)) |
|||
{ |
|||
// only left or right movements are valid
|
|||
if (dirJoystick & 0x01) |
|||
{ |
|||
// rotate through directions (either clockwise or counterclockwise)
|
|||
pprotSnake->dir = (pprotSnake->dir + |
|||
(dirJoystick == SNAKE_DIR_LEFT ? 3 : 1)) % 4u; |
|||
} |
|||
} |
|||
*pdirLast = dirJoystick; |
|||
#endif |
|||
} |
|||
#endif |
|||
|
|||
|
|||
#ifdef ANIMATION_SNAKE |
|||
/**
|
|||
* This function approximates the next direction which may lead to an apple |
|||
* (with a particular probability). |
|||
* @param pprotSnake A pointer to the hungry protagonist. |
|||
* @param pApples A pointer to a bunch of apples. |
|||
*/ |
|||
static void snake_autoRoute(snake_protagonist_t *pprotSnake, |
|||
snake_apples_t *pApples) |
|||
{ |
|||
pixel pxHead = pprotSnake->aSegments[pprotSnake->nHeadIndex]; |
|||
if (random8() < 80) |
|||
{ |
|||
uint8_t nNextApple = 0; |
|||
if (pApples->nAppleCount) |
|||
{ |
|||
uint8_t nMinDist = UINT8_MAX; |
|||
for (uint8_t i = 0; i < pApples->nAppleCount; ++i) |
|||
{ |
|||
uint8_t nDistX; |
|||
if (pxHead.x > pApples->aApples[i].x) |
|||
{ |
|||
nDistX = pxHead.x - pApples->aApples[i].x; |
|||
} |
|||
else |
|||
{ |
|||
nDistX = pApples->aApples[i].x - pxHead.x; |
|||
} |
|||
|
|||
uint8_t nDistY; |
|||
if (pxHead.y > pApples->aApples[i].y) |
|||
{ |
|||
nDistY = pxHead.y - pApples->aApples[i].y; |
|||
} |
|||
else |
|||
{ |
|||
nDistY = pApples->aApples[i].y - pxHead.y; |
|||
} |
|||
|
|||
if ((nDistX + nDistY) < nMinDist) |
|||
{ |
|||
nMinDist = nDistX + nDistY; |
|||
nNextApple = i; |
|||
} |
|||
} |
|||
if (pprotSnake->dir ^ 0x01) // vertical direction?
|
|||
{ |
|||
pprotSnake->dir = pApples->aApples[nNextApple].x > pxHead.x ? |
|||
SNAKE_DIR_LEFT : SNAKE_DIR_RIGHT; |
|||
} |
|||
else |
|||
{ |
|||
pprotSnake->dir = pApples->aApples[nNextApple].y > pxHead.y ? |
|||
SNAKE_DIR_DOWN : SNAKE_DIR_UP; |
|||
} |
|||
} |
|||
} |
|||
|
|||
for (uint8_t i = 0; i < 4; ++i) |
|||
{ |
|||
pixel pxTest = snake_nextDirection(pxHead, pprotSnake->dir); |
|||
if (get_pixel(pxTest)) |
|||
{ |
|||
for (uint8_t j = 0; j < pApples->nAppleCount; ++j) |
|||
{ |
|||
if ((pxTest.x == pApples->aApples[j].x) && |
|||
(pxTest.y == pApples->aApples[j].y)) |
|||
{ |
|||
return; |
|||
} |
|||
} |
|||
pprotSnake->dir = (pprotSnake->dir + 1u) % 4u; |
|||
} |
|||
else |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
#endif |
|||
|
|||
|
|||
/**
|
|||
* Small animation that lets the dying snake disappear piece by piece. |
|||
* @param pprotSnake A pointer to the dying snake. |
|||
*/ |
|||
static void snake_eliminateProtagonist(snake_protagonist_t *pprotSnake) |
|||
{ |
|||
while (pprotSnake->nTailIndex != pprotSnake->nHeadIndex) |
|||
{ |
|||
clearpixel(pprotSnake->aSegments[pprotSnake->nTailIndex++]); |
|||
pprotSnake->nTailIndex %= USNAKE_MAX_LENGTH; |
|||
wait(SNAKE_TERMINATION_DELAY); |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Initializes the structure that keeps track of all currently existing apples. |
|||
* @param pApples Pointer to the set of apples in question. |
|||
*/ |
|||
static void snake_initApples(snake_apples_t *pApples) |
|||
{ |
|||
pApples->nAppleCount = 0; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* 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 pxHead The position to be tested. |
|||
* @return 0 if no apples were found, 1 otherwise |
|||
*/ |
|||
static uint8_t snake_checkForApple(snake_apples_t *pApples, pixel pxHead) |
|||
{ |
|||
for (uint8_t i = pApples->nAppleCount; i--;) |
|||
{ |
|||
if ((pxHead.x == pApples->aApples[i].x) && |
|||
(pxHead.y == pApples->aApples[i].y)) |
|||
{ |
|||
for (; i < pApples->nAppleCount; ++i) |
|||
{ |
|||
pApples->aApples[i] = pApples->aApples[i + 1]; |
|||
} |
|||
--pApples->nAppleCount; |
|||
return 1; |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Creates some new apples from time to time. |
|||
* @param pApples Pointer to a set of apples. |
|||
*/ |
|||
static void snake_spawnApples(snake_apples_t *pApples) |
|||
{ |
|||
if ((pApples->nAppleCount < SNAKE_MAX_APPLES) && (random8() < 10)) |
|||
{ |
|||
pixel pxApple = (pixel){(random8() % (NUM_COLS-2)) + 1, |
|||
(random8() % (NUM_ROWS - 2)) + 1}; |
|||
if (!get_pixel(pxApple)) |
|||
{ |
|||
pApples->aApples[pApples->nAppleCount++] = pxApple; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* The main loop (plus initialization) that both drives the game and the |
|||
* demo mode. |
|||
* @param bDemoMode 0 indicates game mode, 1 indicates demo mode |
|||
*/ |
|||
void snake_engine(uint8_t bDemoMode) |
|||
{ |
|||
// init
|
|||
snake_protagonist_t protSnake; |
|||
snake_initGameProtagonist(&protSnake); |
|||
snake_apples_t apples; |
|||
snake_initApples(&apples); |
|||
snake_dir_t dirLast = SNAKE_DIR_NONE; |
|||
|
|||
// init screen
|
|||
clear_screen(0); |
|||
snake_drawBorder(); |
|||
|
|||
for (uint8_t nAppleColor = 0; 1; nAppleColor ^= SNAKE_COLOR_APPLE) |
|||
{ |
|||
// determine new direction
|
|||
#if defined ANIMATION_SNAKE && defined GAME_SNAKE |
|||
if (bDemoMode) |
|||
{ |
|||
snake_autoRoute(&protSnake, &apples); |
|||
} |
|||
else |
|||
{ |
|||
snake_userControl(&protSnake, &dirLast); |
|||
} |
|||
#elif defined ANIMATION_SNAKE |
|||
snake_autoRoute(&protSnake, &apples); |
|||
#else |
|||
snake_userControl(&protSnake, &dirLast); |
|||
#endif |
|||
|
|||
// actually move head
|
|||
pixel pxOldHead = protSnake.aSegments[protSnake.nHeadIndex]; |
|||
protSnake.nHeadIndex = (protSnake.nHeadIndex + 1u) % USNAKE_MAX_LENGTH; |
|||
protSnake.aSegments[protSnake.nHeadIndex] = |
|||
snake_nextDirection(pxOldHead, protSnake.dir); |
|||
|
|||
// look if we have found an apple
|
|||
if (!snake_checkForApple(&apples, |
|||
protSnake.aSegments[protSnake.nHeadIndex])) |
|||
{ |
|||
// quit game if we hit something which is not an apple
|
|||
if (get_pixel(protSnake.aSegments[protSnake.nHeadIndex])) |
|||
{ |
|||
snake_eliminateProtagonist(&protSnake); |
|||
return; |
|||
} |
|||
|
|||
// remove last segment
|
|||
clearpixel(protSnake.aSegments[protSnake.nTailIndex]) |
|||
protSnake.nTailIndex = |
|||
(protSnake.nTailIndex + 1u) % USNAKE_MAX_LENGTH; |
|||
|
|||
// new apples
|
|||
snake_spawnApples(&apples); |
|||
} |
|||
// draw new head
|
|||
setpixel(protSnake.aSegments[protSnake.nHeadIndex], |
|||
SNAKE_COLOR_PROTAGONIST); |
|||
|
|||
// draw apples
|
|||
for (uint8_t i = apples.nAppleCount; i--;) |
|||
{ |
|||
setpixel(apples.aApples[i], nAppleColor); |
|||
} |
|||
|
|||
wait(SNAKE_CYCLE_DELAY); |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* Snake in game mode. |
|||
*/ |
|||
void snake_game(void) |
|||
{ |
|||
snake_engine(0); |
|||
} |
|||
|
|||
/*@}*/ |
|||
|
@ -1,40 +1,40 @@ |
|||
|
|||
// Makros for simplified single pin io access.
|
|||
|
|||
#define PORT_(port) PORT ## port |
|||
#define DDR_(port) DDR ## port |
|||
#define PIN_(port) PIN ## port |
|||
|
|||
#define PORT(port) PORT_(port) |
|||
#define DDRR(port) DDR_(port) |
|||
#define PINN(port) PIN_(port) |
|||
|
|||
#define SET_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_OFF(p) PORT(p##_PORT) &= ~(1<<p##_BIT) |
|||
#define INPUT(p) ((PINN(p##_PORT) & (1<<p##_BIT)) != 0) |
|||
|
|||
|
|||
/*
|
|||
Use Like this: |
|||
|
|||
|
|||
#define LED_PORT C |
|||
#define LED_BIT 7 |
|||
|
|||
#define SWITCH_PORT B |
|||
#define SWITCH_BIT 0 |
|||
|
|||
int main(){ |
|||
SET_DDR(LED); //set to output
|
|||
OUTPUT_ON(SWITCH); //turn on pullup
|
|||
|
|||
if(INPUT(SWITCH)){ |
|||
OUTPUT_ON(LED); |
|||
}else{ |
|||
OUTPUT_OFF(LED); |
|||
} |
|||
} |
|||
|
|||
*/ |
|||
|
|||
// Makros for simplified single pin io access.
|
|||
|
|||
#define PORT_(port) PORT ## port |
|||
#define DDR_(port) DDR ## port |
|||
#define PIN_(port) PIN ## port |
|||
|
|||
#define PORT(port) PORT_(port) |
|||
#define DDRR(port) DDR_(port) |
|||
#define PINN(port) PIN_(port) |
|||
|
|||
#define SET_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_OFF(p) PORT(p##_PORT) &= ~(1<<p##_BIT) |
|||
#define INPUT(p) ((PINN(p##_PORT) & (1<<p##_BIT)) != 0) |
|||
|
|||
|
|||
/*
|
|||
Use Like this: |
|||
|
|||
|
|||
#define LED_PORT C |
|||
#define LED_BIT 7 |
|||
|
|||
#define SWITCH_PORT B |
|||
#define SWITCH_BIT 0 |
|||
|
|||
int main(){ |
|||
SET_DDR(LED); //set to output
|
|||
OUTPUT_ON(SWITCH); //turn on pullup
|
|||
|
|||
if(INPUT(SWITCH)){ |
|||
OUTPUT_ON(LED); |
|||
}else{ |
|||
OUTPUT_OFF(LED); |
|||
} |
|||
} |
|||
|
|||
*/ |
|||
|
@ -1,4 +1,4 @@ |
|||
|
|||
void joy_init(){ |
|||
|
|||
} |
|||
|
|||
void joy_init(){ |
|||
|
|||
} |
|||
|
@ -1,7 +1,7 @@ |
|||
|
|||
#define DDR(port) (*(volatile uint8_t*)((&port)-1)) |
|||
#define PIN(port) (*(volatile uint8_t*)((&port)-2)) |
|||
|
|||
#define DDR_FROM_PIN(pin) (*(volatile uint8_t*)((&pin)+1)) |
|||
|
|||
#define PORT_FROM_PIN(pin) (*(volatile uint8_t*)((&pin)+2)) |
|||
|
|||
#define DDR(port) (*(volatile uint8_t*)((&port)-1)) |
|||
#define PIN(port) (*(volatile uint8_t*)((&port)-2)) |
|||
|
|||
#define DDR_FROM_PIN(pin) (*(volatile uint8_t*)((&pin)+1)) |
|||
|
|||
#define PORT_FROM_PIN(pin) (*(volatile uint8_t*)((&pin)+2)) |
|||
|
@ -1,11 +1,11 @@ |
|||
MAKETOPDIR = ../.. |
|||
|
|||
TARGET = objects |
|||
|
|||
include $(MAKETOPDIR)/defaults.mk |
|||
|
|||
SRC = rfm12.c borg_rfm12.c |
|||
|
|||
include $(MAKETOPDIR)/rules.mk |
|||
TARGET = objects |
|||
|
|||
include $(MAKETOPDIR)/defaults.mk |
|||
|
|||
SRC = rfm12.c borg_rfm12.c |
|||
|
|||
include $(MAKETOPDIR)/rules.mk |
|||
|
|||
include $(MAKETOPDIR)/depend.mk |
|||
|
@ -1,36 +1,36 @@ |
|||
|
|||
#include <avr/io.h> |
|||
#include <util/delay.h> |
|||
|
|||
#include "rfm12.h" |
|||
|
|||
volatile uint8_t rfm12_joystick_val; |
|||
|
|||
void borg_rfm12_tick(){ |
|||
if (rfm12_rx_status() == STATUS_COMPLETE) |
|||
{ |
|||
|
|||
//uart_putstr ("new packet:\r\n");
|
|||
|
|||
uint8_t * bufp = rfm12_rx_buffer(); |
|||
|
|||
// dump buffer contents to uart
|
|||
if(rfm12_rx_len() >= 1){ |
|||
//-> F2 F1 RT LF DN UP
|
|||
|
|||
rfm12_joystick_val = *bufp; |
|||
} |
|||
|
|||
// tell the implementation that the buffer
|
|||
// can be reused for the next data.
|
|||
rfm12_rx_clear(); |
|||
} |
|||
|
|||
rfm12_tick(); |
|||
|
|||
} |
|||
|
|||
void borg_rfm12_init(){ |
|||
_delay_ms(200);//the rfm12 seems to need this
|
|||
rfm12_init(); |
|||
} |
|||
|
|||
#include <avr/io.h> |
|||
#include <util/delay.h> |
|||
|
|||
#include "rfm12.h" |
|||
|
|||
volatile uint8_t rfm12_joystick_val; |
|||
|
|||
void borg_rfm12_tick(){ |
|||
if (rfm12_rx_status() == STATUS_COMPLETE) |
|||
{ |
|||
|
|||
//uart_putstr ("new packet:\r\n");
|
|||
|
|||
uint8_t * bufp = rfm12_rx_buffer(); |
|||
|
|||
// dump buffer contents to uart
|
|||
if(rfm12_rx_len() >= 1){ |
|||
//-> F2 F1 RT LF DN UP
|
|||
|
|||
rfm12_joystick_val = *bufp; |
|||
} |
|||
|
|||
// tell the implementation that the buffer
|
|||
// can be reused for the next data.
|
|||
rfm12_rx_clear(); |
|||
} |
|||
|
|||
rfm12_tick(); |
|||
|
|||
} |
|||
|
|||
void borg_rfm12_init(){ |
|||
_delay_ms(200);//the rfm12 seems to need this
|
|||
rfm12_init(); |
|||
} |
|||
|
@ -1,6 +1,6 @@ |
|||
|
|||
void borg_rfm12_init(); |
|||
void borg_rfm12_tick(); |
|||
|
|||
extern volatile uint8_t rfm12_joystick_val; |
|||
|
|||
|
|||
void borg_rfm12_init(); |
|||
void borg_rfm12_tick(); |
|||
|
|||
extern volatile uint8_t rfm12_joystick_val; |
|||
|
|||
|
@ -1,439 +1,439 @@ |
|||
#include "font.h" |
|||
|
|||
unsigned int PROGMEM fontIndex_small6[] = { |
|||
0, /* */ |
|||
1, /* ! */ |
|||
2, /* " */ |
|||
5, /* # */ |
|||
10, /* $ */ |
|||
13, /* % */ |
|||
17, /* & */ |
|||
21, /* ' */ |
|||
22, /* ( */ |
|||
24, /* ) */ |
|||
26, /* * */ |
|||
28, /* + */ |
|||
31, /* , */ |
|||
32, /* - */ |
|||
34, /* . */ |
|||
35, /* / */ |
|||
37, /* 0 */ |
|||
41, /* 1 */ |
|||
43, /* 2 */ |
|||
47, /* 3 */ |
|||
51, /* 4 */ |
|||
55, /* 5 */ |
|||
58, /* 6 */ |
|||
62, /* 7 */ |
|||
65, /* 8 */ |
|||
69, /* 9 */ |
|||
73, /* : */ |
|||
74, /* ; */ |
|||
75, /* < */ |
|||
78, /* = */ |
|||
81, /* > */ |
|||
84, /* ? */ |
|||
88, /* @ */ |
|||
95, /* A */ |
|||
100, /* B */ |
|||
105, /* C */ |
|||
110, /* D */ |
|||
115, /* E */ |
|||
119, /* F */ |
|||
123, /* G */ |
|||
128, /* H */ |
|||
132, /* I */ |
|||
133, /* J */ |
|||
136, /* K */ |
|||
140, /* L */ |
|||
143, /* M */ |
|||
150, /* N */ |
|||
155, /* O */ |
|||
160, /* P */ |
|||
164, /* Q */ |
|||
169, /* R */ |
|||
174, /* S */ |
|||
178, /* T */ |
|||
182, /* U */ |
|||
187, /* V */ |
|||
192, /* W */ |
|||
199, /* X */ |
|||
204, /* Y */ |
|||
209, /* Z */ |
|||
213, /* [ */ |
|||
215, /* \ */ |
|||
217, /* ] */ |
|||
219, /* ^ */ |
|||
222, /* _ */ |
|||
226, /* ` */ |
|||
228, /* a */ |
|||
231, /* b */ |
|||
235, /* c */ |
|||
238, /* d */ |
|||
242, /* e */ |
|||
245, /* f */ |
|||
247, /* g */ |
|||
251, /* h */ |
|||
254, /* i */ |
|||
255, /* j */ |
|||
256, /* k */ |
|||
259, /* l */ |
|||
260, /* m */ |
|||
265, /* n */ |
|||
268, /* o */ |
|||
272, /* p */ |
|||
276, /* q */ |
|||
280, /* r */ |
|||
282, /* s */ |
|||
285, /* t */ |
|||
287, /* u */ |
|||
290, /* v */ |
|||
293, /* w */ |
|||
298, /* x */ |
|||
301, /* y */ |
|||
304, /* z */ |
|||
307, /* { */ |
|||
309, /* | */ |
|||
310, /* } */ |
|||
312, /* ~ */ |
|||
316, /* ß */ |
|||
321, /* ä */ |
|||
324, /* ö */ |
|||
328, /* ü */ |
|||
331 |
|||
}; |
|||
|
|||
unsigned char PROGMEM fontData_small6[] = { |
|||
0x00, /* */ |
|||
0x2f, /* # #### */ |
|||
0x03, /* ## */ |
|||
0x00, /* */ |
|||
0x03, /* ## */ |
|||
0x12, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x12, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x12, /* # # */ |
|||
0x26, /* # ## */ |
|||
0x7f, /* ####### */ |
|||
0x32, /* ## # */ |
|||
0x13, /* # ## */ |
|||
0x0b, /* # ## */ |
|||
0x34, /* ## # */ |
|||
0x32, /* ## # */ |
|||
0x1a, /* ## # */ |
|||
0x25, /* # # # */ |
|||
0x1a, /* ## # */ |
|||
0x28, /* # # */ |
|||
0x03, /* ## */ |
|||
0x7e, /* ###### */ |
|||
0x81, /* # # */ |
|||
0x81, /* # # */ |
|||
0x7e, /* ###### */ |
|||
0x03, /* ## */ |
|||
0x03, /* ## */ |
|||
0x08, /* # */ |
|||
0x1c, /* ### */ |
|||
0x08, /* # */ |
|||
0x60, /* ## */ |
|||
0x08, /* # */ |
|||
0x08, /* # */ |
|||
0x20, /* # */ |
|||
0x38, /* ### */ |
|||
0x07, /* ### */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x1e, /* #### */ |
|||
0x02, /* # */ |
|||
0x3f, /* ###### */ |
|||
0x32, /* ## # */ |
|||
0x29, /* # # # */ |
|||
0x29, /* # # # */ |
|||
0x26, /* # ## */ |
|||
0x12, /* # # */ |
|||
0x21, /* # # */ |
|||
0x25, /* # # # */ |
|||
0x1a, /* ## # */ |
|||
0x18, /* ## */ |
|||
0x16, /* # ## */ |
|||
0x3f, /* ###### */ |
|||
0x10, /* # */ |
|||
0x27, /* # ### */ |
|||
0x25, /* # # # */ |
|||
0x19, /* ## # */ |
|||
0x1e, /* #### */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x18, /* ## */ |
|||
0x01, /* # */ |
|||
0x3d, /* #### # */ |
|||
0x03, /* ## */ |
|||
0x1a, /* ## # */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x1a, /* ## # */ |
|||
0x12, /* # # */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x1e, /* #### */ |
|||
0x24, /* # # */ |
|||
0x64, /* ## # */ |
|||
0x08, /* # */ |
|||
0x14, /* # # */ |
|||
0x22, /* # # */ |
|||
0x14, /* # # */ |
|||
0x14, /* # # */ |
|||
0x14, /* # # */ |
|||
0x22, /* # # */ |
|||
0x14, /* # # */ |
|||
0x08, /* # */ |
|||
0x02, /* # */ |
|||
0x29, /* # # # */ |
|||
0x05, /* # # */ |
|||
0x02, /* # */ |
|||
0x1c, /* ### */ |
|||
0x22, /* # # */ |
|||
0x49, /* # # # */ |
|||
0x55, /* # # # # */ |
|||
0x59, /* # ## # */ |
|||
0x12, /* # # */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x0b, /* # ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x3f, /* ###### */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x1a, /* ## # */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x12, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x1e, /* #### */ |
|||
0x3f, /* ###### */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x21, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x05, /* # # */ |
|||
0x05, /* # # */ |
|||
0x01, /* # */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x29, /* # # # */ |
|||
0x3a, /* ### # */ |
|||
0x3f, /* ###### */ |
|||
0x04, /* # */ |
|||
0x04, /* # */ |
|||
0x3f, /* ###### */ |
|||
0x3f, /* ###### */ |
|||
0x30, /* ## */ |
|||
0x20, /* # */ |
|||
0x1f, /* ##### */ |
|||
0x3f, /* ###### */ |
|||
0x0c, /* ## */ |
|||
0x12, /* # # */ |
|||
0x21, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x20, /* # */ |
|||
0x20, /* # */ |
|||
0x3f, /* ###### */ |
|||
0x03, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x03, /* ## */ |
|||
0x3f, /* ###### */ |
|||
0x3f, /* ###### */ |
|||
0x03, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x3f, /* ###### */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x1e, /* #### */ |
|||
0x3f, /* ###### */ |
|||
0x09, /* # # */ |
|||
0x09, /* # # */ |
|||
0x06, /* ## */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x29, /* # # # */ |
|||
0x11, /* # # */ |
|||
0x2e, /* # ### */ |
|||
0x3f, /* ###### */ |
|||
0x09, /* # # */ |
|||
0x09, /* # # */ |
|||
0x09, /* # # */ |
|||
0x36, /* ## ## */ |
|||
0x12, /* # # */ |
|||
0x25, /* # # # */ |
|||
0x29, /* # # # */ |
|||
0x12, /* # # */ |
|||
0x01, /* # */ |
|||
0x3f, /* ###### */ |
|||
0x01, /* # */ |
|||
0x01, /* # */ |
|||
0x1f, /* ##### */ |
|||
0x20, /* # */ |
|||
0x20, /* # */ |
|||
0x20, /* # */ |
|||
0x1f, /* ##### */ |
|||
0x03, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x03, /* ## */ |
|||
0x03, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x03, /* ## */ |
|||
0x21, /* # # */ |
|||
0x12, /* # # */ |
|||
0x0c, /* ## */ |
|||
0x12, /* # # */ |
|||
0x21, /* # # */ |
|||
0x01, /* # */ |
|||
0x02, /* # */ |
|||
0x3c, /* #### */ |
|||
0x02, /* # */ |
|||
0x01, /* # */ |
|||
0x31, /* ## # */ |
|||
0x29, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x23, /* # ## */ |
|||
0x7f, /* ####### */ |
|||
0x41, /* # # */ |
|||
0x07, /* ### */ |
|||
0x38, /* ### */ |
|||
0x41, /* # # */ |
|||
0x7f, /* ####### */ |
|||
0x02, /* # */ |
|||
0x01, /* # */ |
|||
0x02, /* # */ |
|||
0x40, /* # */ |
|||
0x40, /* # */ |
|||
0x40, /* # */ |
|||
0x40, /* # */ |
|||
0x00, /* */ |
|||
0x01, /* # */ |
|||
0x14, /* # # */ |
|||
0x24, /* # # */ |
|||
0x38, /* ### */ |
|||
0x3f, /* ###### */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x28, /* # # */ |
|||
0x3e, /* ##### */ |
|||
0x05, /* # # */ |
|||
0x18, /* ## */ |
|||
0xa4, /* # # # */ |
|||
0xa4, /* # # # */ |
|||
0x7c, /* ##### */ |
|||
0x3f, /* ###### */ |
|||
0x04, /* # */ |
|||
0x38, /* ### */ |
|||
0x3d, /* #### # */ |
|||
0xfd, /* ###### # */ |
|||
0x3f, /* ###### */ |
|||
0x08, /* # */ |
|||
0x34, /* ## # */ |
|||
0x3f, /* ###### */ |
|||
0x3c, /* #### */ |
|||
0x04, /* # */ |
|||
0x3c, /* #### */ |
|||
0x04, /* # */ |
|||
0x38, /* ### */ |
|||
0x3c, /* #### */ |
|||
0x04, /* # */ |
|||
0x38, /* ### */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0xfc, /* ###### */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0xfc, /* ###### */ |
|||
0x3c, /* #### */ |
|||
0x04, /* # */ |
|||
0x28, /* # # */ |
|||
0x24, /* # # */ |
|||
0x14, /* # # */ |
|||
0x1e, /* #### */ |
|||
0x24, /* # # */ |
|||
0x1c, /* ### */ |
|||
0x20, /* # */ |
|||
0x3c, /* #### */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x9c, /* # ### */ |
|||
0x60, /* ## */ |
|||
0x1c, /* ### */ |
|||
0x34, /* ## # */ |
|||
0x24, /* # # */ |
|||
0x2c, /* # ## */ |
|||
0x08, /* # */ |
|||
0x77, /* ### ### */ |
|||
0x7f, /* ####### */ |
|||
0x77, /* ### ### */ |
|||
0x08, /* # */ |
|||
0x01, /* # */ |
|||
0x02, /* # */ |
|||
0x01, /* # */ |
|||
0x02, /* # */ |
|||
0x3e, /* ##### */ |
|||
0x05, /* # # */ |
|||
0x26, /* # ## */ |
|||
0x18, /* ## */ |
|||
0x19, /* ## # */ |
|||
0x24, /* # # */ |
|||
0x29, /* # # # */ |
|||
0x19, /* ## # */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x19, /* ## # */ |
|||
0x1d, /* ### # */ |
|||
0x20, /* # */ |
|||
0x3d, /* #### # */ |
|||
}; |
|||
|
|||
font font_small6 = {8, fontIndex_small6, fontData_small6, ' ', '~', '.', 1}; |
|||
#include "font.h" |
|||
|
|||
unsigned int PROGMEM fontIndex_small6[] = { |
|||
0, /* */ |
|||
1, /* ! */ |
|||
2, /* " */ |
|||
5, /* # */ |
|||
10, /* $ */ |
|||
13, /* % */ |
|||
17, /* & */ |
|||
21, /* ' */ |
|||
22, /* ( */ |
|||
24, /* ) */ |
|||
26, /* * */ |
|||
28, /* + */ |
|||
31, /* , */ |
|||
32, /* - */ |
|||
34, /* . */ |
|||
35, /* / */ |
|||
37, /* 0 */ |
|||
41, /* 1 */ |
|||
43, /* 2 */ |
|||
47, /* 3 */ |
|||
51, /* 4 */ |
|||
55, /* 5 */ |
|||
58, /* 6 */ |
|||
62, /* 7 */ |
|||
65, /* 8 */ |
|||
69, /* 9 */ |
|||
73, /* : */ |
|||
74, /* ; */ |
|||
75, /* < */ |
|||
78, /* = */ |
|||
81, /* > */ |
|||
84, /* ? */ |
|||
88, /* @ */ |
|||
95, /* A */ |
|||
100, /* B */ |
|||
105, /* C */ |
|||
110, /* D */ |
|||
115, /* E */ |
|||
119, /* F */ |
|||
123, /* G */ |
|||
128, /* H */ |
|||
132, /* I */ |
|||
133, /* J */ |
|||
136, /* K */ |
|||
140, /* L */ |
|||
143, /* M */ |
|||
150, /* N */ |
|||
155, /* O */ |
|||
160, /* P */ |
|||
164, /* Q */ |
|||
169, /* R */ |
|||
174, /* S */ |
|||
178, /* T */ |
|||
182, /* U */ |
|||
187, /* V */ |
|||
192, /* W */ |
|||
199, /* X */ |
|||
204, /* Y */ |
|||
209, /* Z */ |
|||
213, /* [ */ |
|||
215, /* \ */ |
|||
217, /* ] */ |
|||
219, /* ^ */ |
|||
222, /* _ */ |
|||
226, /* ` */ |
|||
228, /* a */ |
|||
231, /* b */ |
|||
235, /* c */ |
|||
238, /* d */ |
|||
242, /* e */ |
|||
245, /* f */ |
|||
247, /* g */ |
|||
251, /* h */ |
|||
254, /* i */ |
|||
255, /* j */ |
|||
256, /* k */ |
|||
259, /* l */ |
|||
260, /* m */ |
|||
265, /* n */ |
|||
268, /* o */ |
|||
272, /* p */ |
|||
276, /* q */ |
|||
280, /* r */ |
|||
282, /* s */ |
|||
285, /* t */ |
|||
287, /* u */ |
|||
290, /* v */ |
|||
293, /* w */ |
|||
298, /* x */ |
|||
301, /* y */ |
|||
304, /* z */ |
|||
307, /* { */ |
|||
309, /* | */ |
|||
310, /* } */ |
|||
312, /* ~ */ |
|||
316, /* ß */ |
|||
321, /* ä */ |
|||
324, /* ö */ |
|||
328, /* ü */ |
|||
331 |
|||
}; |
|||
|
|||
unsigned char PROGMEM fontData_small6[] = { |
|||
0x00, /* */ |
|||
0x2f, /* # #### */ |
|||
0x03, /* ## */ |
|||
0x00, /* */ |
|||
0x03, /* ## */ |
|||
0x12, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x12, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x12, /* # # */ |
|||
0x26, /* # ## */ |
|||
0x7f, /* ####### */ |
|||
0x32, /* ## # */ |
|||
0x13, /* # ## */ |
|||
0x0b, /* # ## */ |
|||
0x34, /* ## # */ |
|||
0x32, /* ## # */ |
|||
0x1a, /* ## # */ |
|||
0x25, /* # # # */ |
|||
0x1a, /* ## # */ |
|||
0x28, /* # # */ |
|||
0x03, /* ## */ |
|||
0x7e, /* ###### */ |
|||
0x81, /* # # */ |
|||
0x81, /* # # */ |
|||
0x7e, /* ###### */ |
|||
0x03, /* ## */ |
|||
0x03, /* ## */ |
|||
0x08, /* # */ |
|||
0x1c, /* ### */ |
|||
0x08, /* # */ |
|||
0x60, /* ## */ |
|||
0x08, /* # */ |
|||
0x08, /* # */ |
|||
0x20, /* # */ |
|||
0x38, /* ### */ |
|||
0x07, /* ### */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x1e, /* #### */ |
|||
0x02, /* # */ |
|||
0x3f, /* ###### */ |
|||
0x32, /* ## # */ |
|||
0x29, /* # # # */ |
|||
0x29, /* # # # */ |
|||
0x26, /* # ## */ |
|||
0x12, /* # # */ |
|||
0x21, /* # # */ |
|||
0x25, /* # # # */ |
|||
0x1a, /* ## # */ |
|||
0x18, /* ## */ |
|||
0x16, /* # ## */ |
|||
0x3f, /* ###### */ |
|||
0x10, /* # */ |
|||
0x27, /* # ### */ |
|||
0x25, /* # # # */ |
|||
0x19, /* ## # */ |
|||
0x1e, /* #### */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x18, /* ## */ |
|||
0x01, /* # */ |
|||
0x3d, /* #### # */ |
|||
0x03, /* ## */ |
|||
0x1a, /* ## # */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x1a, /* ## # */ |
|||
0x12, /* # # */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x1e, /* #### */ |
|||
0x24, /* # # */ |
|||
0x64, /* ## # */ |
|||
0x08, /* # */ |
|||
0x14, /* # # */ |
|||
0x22, /* # # */ |
|||
0x14, /* # # */ |
|||
0x14, /* # # */ |
|||
0x14, /* # # */ |
|||
0x22, /* # # */ |
|||
0x14, /* # # */ |
|||
0x08, /* # */ |
|||
0x02, /* # */ |
|||
0x29, /* # # # */ |
|||
0x05, /* # # */ |
|||
0x02, /* # */ |
|||
0x1c, /* ### */ |
|||
0x22, /* # # */ |
|||
0x49, /* # # # */ |
|||
0x55, /* # # # # */ |
|||
0x59, /* # ## # */ |
|||
0x12, /* # # */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x0b, /* # ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x3f, /* ###### */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x1a, /* ## # */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x12, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x1e, /* #### */ |
|||
0x3f, /* ###### */ |
|||
0x25, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x21, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x05, /* # # */ |
|||
0x05, /* # # */ |
|||
0x01, /* # */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x29, /* # # # */ |
|||
0x3a, /* ### # */ |
|||
0x3f, /* ###### */ |
|||
0x04, /* # */ |
|||
0x04, /* # */ |
|||
0x3f, /* ###### */ |
|||
0x3f, /* ###### */ |
|||
0x30, /* ## */ |
|||
0x20, /* # */ |
|||
0x1f, /* ##### */ |
|||
0x3f, /* ###### */ |
|||
0x0c, /* ## */ |
|||
0x12, /* # # */ |
|||
0x21, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x20, /* # */ |
|||
0x20, /* # */ |
|||
0x3f, /* ###### */ |
|||
0x03, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x03, /* ## */ |
|||
0x3f, /* ###### */ |
|||
0x3f, /* ###### */ |
|||
0x03, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x3f, /* ###### */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x21, /* # # */ |
|||
0x1e, /* #### */ |
|||
0x3f, /* ###### */ |
|||
0x09, /* # # */ |
|||
0x09, /* # # */ |
|||
0x06, /* ## */ |
|||
0x1e, /* #### */ |
|||
0x21, /* # # */ |
|||
0x29, /* # # # */ |
|||
0x11, /* # # */ |
|||
0x2e, /* # ### */ |
|||
0x3f, /* ###### */ |
|||
0x09, /* # # */ |
|||
0x09, /* # # */ |
|||
0x09, /* # # */ |
|||
0x36, /* ## ## */ |
|||
0x12, /* # # */ |
|||
0x25, /* # # # */ |
|||
0x29, /* # # # */ |
|||
0x12, /* # # */ |
|||
0x01, /* # */ |
|||
0x3f, /* ###### */ |
|||
0x01, /* # */ |
|||
0x01, /* # */ |
|||
0x1f, /* ##### */ |
|||
0x20, /* # */ |
|||
0x20, /* # */ |
|||
0x20, /* # */ |
|||
0x1f, /* ##### */ |
|||
0x03, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x03, /* ## */ |
|||
0x03, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x03, /* ## */ |
|||
0x21, /* # # */ |
|||
0x12, /* # # */ |
|||
0x0c, /* ## */ |
|||
0x12, /* # # */ |
|||
0x21, /* # # */ |
|||
0x01, /* # */ |
|||
0x02, /* # */ |
|||
0x3c, /* #### */ |
|||
0x02, /* # */ |
|||
0x01, /* # */ |
|||
0x31, /* ## # */ |
|||
0x29, /* # # # */ |
|||
0x25, /* # # # */ |
|||
0x23, /* # ## */ |
|||
0x7f, /* ####### */ |
|||
0x41, /* # # */ |
|||
0x07, /* ### */ |
|||
0x38, /* ### */ |
|||
0x41, /* # # */ |
|||
0x7f, /* ####### */ |
|||
0x02, /* # */ |
|||
0x01, /* # */ |
|||
0x02, /* # */ |
|||
0x40, /* # */ |
|||
0x40, /* # */ |
|||
0x40, /* # */ |
|||
0x40, /* # */ |
|||
0x00, /* */ |
|||
0x01, /* # */ |
|||
0x14, /* # # */ |
|||
0x24, /* # # */ |
|||
0x38, /* ### */ |
|||
0x3f, /* ###### */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x3f, /* ###### */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x28, /* # # */ |
|||
0x3e, /* ##### */ |
|||
0x05, /* # # */ |
|||
0x18, /* ## */ |
|||
0xa4, /* # # # */ |
|||
0xa4, /* # # # */ |
|||
0x7c, /* ##### */ |
|||
0x3f, /* ###### */ |
|||
0x04, /* # */ |
|||
0x38, /* ### */ |
|||
0x3d, /* #### # */ |
|||
0xfd, /* ###### # */ |
|||
0x3f, /* ###### */ |
|||
0x08, /* # */ |
|||
0x34, /* ## # */ |
|||
0x3f, /* ###### */ |
|||
0x3c, /* #### */ |
|||
0x04, /* # */ |
|||
0x3c, /* #### */ |
|||
0x04, /* # */ |
|||
0x38, /* ### */ |
|||
0x3c, /* #### */ |
|||
0x04, /* # */ |
|||
0x38, /* ### */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0xfc, /* ###### */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0xfc, /* ###### */ |
|||
0x3c, /* #### */ |
|||
0x04, /* # */ |
|||
0x28, /* # # */ |
|||
0x24, /* # # */ |
|||
0x14, /* # # */ |
|||
0x1e, /* #### */ |
|||
0x24, /* # # */ |
|||
0x1c, /* ### */ |
|||
0x20, /* # */ |
|||
0x3c, /* #### */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x30, /* ## */ |
|||
0x0c, /* ## */ |
|||
0x24, /* # # */ |
|||
0x18, /* ## */ |
|||
0x24, /* # # */ |
|||
0x9c, /* # ### */ |
|||
0x60, /* ## */ |
|||
0x1c, /* ### */ |
|||
0x34, /* ## # */ |
|||
0x24, /* # # */ |
|||
0x2c, /* # ## */ |
|||
0x08, /* # */ |
|||
0x77, /* ### ### */ |
|||
0x7f, /* ####### */ |
|||
0x77, /* ### ### */ |
|||
0x08, /* # */ |
|||
0x01, /* # */ |
|||
0x02, /* # */ |
|||
0x01, /* # */ |
|||
0x02, /* # */ |
|||
0x3e, /* ##### */ |
|||
0x05, /* # # */ |
|||
0x26, /* # ## */ |
|||
0x18, /* ## */ |
|||
0x19, /* ## # */ |
|||
0x24, /* # # */ |
|||
0x29, /* # # # */ |
|||
0x19, /* ## # */ |
|||
0x24, /* # # */ |
|||
0x24, /* # # */ |
|||
0x19, /* ## # */ |
|||
0x1d, /* ### # */ |
|||
0x20, /* # */ |
|||
0x3d, /* #### # */ |
|||
}; |
|||
|
|||
font font_small6 = {8, fontIndex_small6, fontData_small6, ' ', '~', '.', 1}; |
|||
|
File diff suppressed because it is too large
@ -1,324 +1,324 @@ |
|||
/**
|
|||
* \defgroup unixsimulator Simulation of the Borg API for UNIX like platforms. |
|||
*/ |
|||
/*@{*/ |
|||
|
|||
/**
|
|||
* @file main.c |
|||
* @brief Simulator for Unix like platforms. |
|||
* @author Martin Ongsiek, Peter Fuhrmann, Christian Kroll |
|||
*/ |
|||
|
|||
#ifdef OSX_ |
|||
#include <GLUT/glut.h> |
|||
#else |
|||
#include <GL/glut.h> |
|||
#endif |
|||
#include <pthread.h> |
|||
#include <stdlib.h> |
|||
#include <sys/time.h> |
|||
#include <sys/types.h> |
|||
#include <unistd.h> |
|||
|
|||
#include <stdio.h> |
|||
#include <setjmp.h> |
|||
|
|||
#include "../config.h" |
|||
#include "../display_loop.h" |
|||
#include "trackball.h" |
|||
|
|||
/** Number of bytes per row. */ |
|||
#define LINEBYTES (((NUM_COLS - 1) / 8) + 1) |
|||
|
|||
/** Fake port for simulating joystick input. */ |
|||
volatile unsigned char fakeport; |
|||
/** Flag which indicates if wait should jump to the menu if fire is pressed. */ |
|||
volatile unsigned char waitForFire; |
|||
/** The simulated frame buffer of the borg. */ |
|||
volatile unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; |
|||
/** Jump buffer which leads directly the menu. */ |
|||
extern jmp_buf newmode_jmpbuf; |
|||
|
|||
/** Width of the window. */ |
|||
int WindWidth; |
|||
/** Height of the window. */ |
|||
int WindHeight; |
|||
|
|||
/** Rotation of the x-axis of the scene. */ |
|||
float view_rotx = 0; |
|||
/** Rotation of the y-axis of the scene. */ |
|||
float view_roty = 0; |
|||
/** Rotation of the z-axis of the scene. */ |
|||
float view_rotz = 0; |
|||
|
|||
/** GLUT window handle. */ |
|||
int win; |
|||
|
|||
|
|||
/**
|
|||
* Simple wait function. |
|||
* @param ms The requested delay in milliseconds. |
|||
*/ |
|||
void wait(unsigned int ms) { |
|||
if (waitForFire) { |
|||
if (fakeport & 0x01) { |
|||
longjmp(newmode_jmpbuf, 43); |
|||
} |
|||
} |
|||
|
|||
usleep(ms * 1000); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Draw a LED in the given color (which is a list). |
|||
* @param color List which contains a sphere. |
|||
* @param pos_x x-coordinate |
|||
* @param pos_y y-coordinate |
|||
* @param pos_z z-coordinate |
|||
*/ |
|||
void drawLED(int color, float pos_x, float pos_y, float pos_z) { |
|||
glPushMatrix(); |
|||
glTranslatef(pos_x, pos_y, pos_z); |
|||
glCallList(color); |
|||
glPopMatrix(); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Draws the LED matrix. |
|||
*/ |
|||
void display(void) { |
|||
int x, y, z, level, color; |
|||
tbReshape(WindWidth, WindHeight); |
|||
glClear(GL_COLOR_BUFFER_BIT); |
|||
glPushMatrix(); |
|||
glTranslatef(NUM_COLS * 2., 0., NUM_ROWS * 2.); |
|||
tbMatrix(); |
|||
glRotatef(view_rotx, 1.0, 0.0, 0.0); |
|||
glRotatef(view_roty, 0.0, 1.0, 0.0); |
|||
glRotatef(view_rotz, 0.0, 0.0, 1.0); |
|||
glTranslatef(-NUM_COLS * 2, 0., -NUM_ROWS * 2.); |
|||
for (x = 0; x < 1; x++) { |
|||
for (y = 0; y < NUM_COLS; y++) { |
|||
for (z = 0; z < NUM_ROWS; z++) { |
|||
color = 0; |
|||
for (level = 0; level < NUMPLANE; level++) { |
|||
if (pixmap[level][z % NUM_ROWS][y / 8] & (1 << y % 8)) { |
|||
color = level + 1; |
|||
} |
|||
} |
|||
drawLED(color, (float) y * 4.0, (float) x * 4.0, |
|||
(float) (NUM_ROWS - 1 - z) * 4.0); |
|||
} |
|||
} |
|||
} |
|||
glPopMatrix(); |
|||
glutSwapBuffers(); |
|||
|
|||
usleep(20000); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Handler for processing key presses. |
|||
* @param key The pressed key encoded in ASCII. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
void keyboard(unsigned char key, int x, int y) { |
|||
switch (key) { |
|||
case 'q': |
|||
printf("Quit\n"); |
|||
glutDestroyWindow(win); |
|||
exit(0); |
|||
break; |
|||
case ' ': |
|||
fakeport |= 0x01; |
|||
break; |
|||
case 'a': |
|||
fakeport |= 0x02; |
|||
break; |
|||
case 'd': |
|||
fakeport |= 0x04; |
|||
break; |
|||
case 's': |
|||
fakeport |= 0x08; |
|||
break; |
|||
case 'w': |
|||
fakeport |= 0x10; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Handler for processing key releases. |
|||
* @param key The released key encoded in ASCII. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
void keyboardup(unsigned char key, int x, int y) { |
|||
switch (key) { |
|||
case ' ': |
|||
fakeport &= ~0x01; |
|||
break; |
|||
case 'a': |
|||
fakeport &= ~0x02; |
|||
break; |
|||
case 'd': |
|||
fakeport &= ~0x04; |
|||
break; |
|||
case 's': |
|||
fakeport &= ~0x08; |
|||
break; |
|||
case 'w': |
|||
fakeport &= ~0x10; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Relays mouse position and button state to the trackball implementation. |
|||
* @param button Currently monitored button. |
|||
* @param state State of that button. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
void mouse(int button, int state, int x, int y) { |
|||
tbMouse(button, state, x, y); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Relays motion request to the trackball implementation. |
|||
* @param x X-position for the motion direction. |
|||
* @param y Y-position for the motion direction. |
|||
*/ |
|||
void motion(int x, int y) { |
|||
tbMotion(x, y); |
|||
} |
|||
|
|||
/**
|
|||
* Updating the window size. |
|||
* @param width Width of the window. |
|||
* @param height Height of the window. |
|||
*/ |
|||
void reshape(int width, int height) { |
|||
|
|||
tbReshape(width, height); |
|||
|
|||
glViewport(0, 0, width, height); |
|||
|
|||
glMatrixMode(GL_PROJECTION); |
|||
glLoadIdentity(); |
|||
gluPerspective(60.0, (float) WindWidth / (float) WindWidth, 5., 1000.); |
|||
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); |
|||
glMatrixMode(GL_MODELVIEW); |
|||
glLoadIdentity(); |
|||
|
|||
WindWidth = width; |
|||
WindHeight = height; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Handler for special keys (the arrow keys in particular) for adjusting the |
|||
* view angle of the scene. |
|||
* @param k The pressed special key using GLUT's nomenclature. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
static void special(int k, int x, int y) { |
|||
switch (k) { |
|||
case GLUT_KEY_UP: |
|||
view_rotx += 5.0; |
|||
break; |
|||
case GLUT_KEY_DOWN: |
|||
view_rotx -= 5.0; |
|||
break; |
|||
case GLUT_KEY_LEFT: |
|||
view_rotz += 5.0; |
|||
break; |
|||
case GLUT_KEY_RIGHT: |
|||
view_rotz -= 5.0; |
|||
break; |
|||
default: |
|||
return; |
|||
} |
|||
glutPostRedisplay(); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Entry point for starting the display loop thread. |
|||
* @param unused Not used. Only here to satisfy signature constraints. |
|||
*/ |
|||
void *display_loop_run(void * unused) { |
|||
display_loop(); |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Main function for the simulator. |
|||
* @param argc The argument count. |
|||
* @param argv Command line arguments. |
|||
* @return Exit codem, always zero. |
|||
*/ |
|||
int main(int argc, char **argv) { |
|||
WindHeight = 700; |
|||
WindWidth = 700; |
|||
glutInit(&argc, argv); |
|||
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); |
|||
glutInitWindowSize(WindHeight, WindWidth); |
|||
win = glutCreateWindow("16x16 Borg Simulator"); |
|||
|
|||
// callback
|
|||
glutDisplayFunc(display); |
|||
glutIdleFunc(display); |
|||
glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF); |
|||
glutKeyboardFunc(keyboard); |
|||
glutKeyboardUpFunc(keyboardup); |
|||
glutSpecialFunc(special); |
|||
glutMouseFunc(mouse); |
|||
glutMotionFunc(motion); |
|||
|
|||
// clearcolor & main loop
|
|||
glClearColor(0, 0, 0, 1.0); |
|||
gluPerspective(60.0, (float) WindWidth / (float) WindWidth, 5., 1000.); |
|||
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); |
|||
|
|||
// init Call List for LED
|
|||
GLUquadric* quad = gluNewQuadric(); |
|||
glNewList(0, GL_COMPILE); |
|||
glColor4f(0.8, 0.0, 0.0, 1.); |
|||
gluSphere(quad, 1.0, 12, 12); |
|||
glEndList(); |
|||
glNewList(1, GL_COMPILE); |
|||
glColor4f(0.5, 0.0, 0.0, 1.); |
|||
gluSphere(quad, 1.4, 12, 12); |
|||
glEndList(); |
|||
glNewList(2, GL_COMPILE); |
|||
glColor4f(0.7, 0.0, 0.0, 1.); |
|||
gluSphere(quad, 1.55, 12, 12); |
|||
glEndList(); |
|||
glNewList(3, GL_COMPILE); |
|||
glColor4f(1.00, 0.0, 0.0, 1.); |
|||
gluSphere(quad, 1.7, 12, 12); |
|||
glEndList(); |
|||
|
|||
tbInit(GLUT_LEFT_BUTTON); |
|||
tbAnimate(GL_FALSE); |
|||
|
|||
pthread_t simthread; |
|||
pthread_create(&simthread, NULL, display_loop_run, NULL); |
|||
|
|||
glutMainLoop(); |
|||
return 0; |
|||
} |
|||
|
|||
/*@}*/ |
|||
/**
|
|||
* \defgroup unixsimulator Simulation of the Borg API for UNIX like platforms. |
|||
*/ |
|||
/*@{*/ |
|||
|
|||
/**
|
|||
* @file main.c |
|||
* @brief Simulator for Unix like platforms. |
|||
* @author Martin Ongsiek, Peter Fuhrmann, Christian Kroll |
|||
*/ |
|||
|
|||
#ifdef OSX_ |
|||
#include <GLUT/glut.h> |
|||
#else |
|||
#include <GL/glut.h> |
|||
#endif |
|||
#include <pthread.h> |
|||
#include <stdlib.h> |
|||
#include <sys/time.h> |
|||
#include <sys/types.h> |
|||
#include <unistd.h> |
|||
|
|||
#include <stdio.h> |
|||
#include <setjmp.h> |
|||
|
|||
#include "../config.h" |
|||
#include "../display_loop.h" |
|||
#include "trackball.h" |
|||
|
|||
/** Number of bytes per row. */ |
|||
#define LINEBYTES (((NUM_COLS - 1) / 8) + 1) |
|||
|
|||
/** Fake port for simulating joystick input. */ |
|||
volatile unsigned char fakeport; |
|||
/** Flag which indicates if wait should jump to the menu if fire is pressed. */ |
|||
volatile unsigned char waitForFire; |
|||
/** The simulated frame buffer of the borg. */ |
|||
volatile unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; |
|||
/** Jump buffer which leads directly the menu. */ |
|||
extern jmp_buf newmode_jmpbuf; |
|||
|
|||
/** Width of the window. */ |
|||
int WindWidth; |
|||
/** Height of the window. */ |
|||
int WindHeight; |
|||
|
|||
/** Rotation of the x-axis of the scene. */ |
|||
float view_rotx = 0; |
|||
/** Rotation of the y-axis of the scene. */ |
|||
float view_roty = 0; |
|||
/** Rotation of the z-axis of the scene. */ |
|||
float view_rotz = 0; |
|||
|
|||
/** GLUT window handle. */ |
|||
int win; |
|||
|
|||
|
|||
/**
|
|||
* Simple wait function. |
|||
* @param ms The requested delay in milliseconds. |
|||
*/ |
|||
void wait(unsigned int ms) { |
|||
if (waitForFire) { |
|||
if (fakeport & 0x01) { |
|||
longjmp(newmode_jmpbuf, 43); |
|||
} |
|||
} |
|||
|
|||
usleep(ms * 1000); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Draw a LED in the given color (which is a list). |
|||
* @param color List which contains a sphere. |
|||
* @param pos_x x-coordinate |
|||
* @param pos_y y-coordinate |
|||
* @param pos_z z-coordinate |
|||
*/ |
|||
void drawLED(int color, float pos_x, float pos_y, float pos_z) { |
|||
glPushMatrix(); |
|||
glTranslatef(pos_x, pos_y, pos_z); |
|||
glCallList(color); |
|||
glPopMatrix(); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Draws the LED matrix. |
|||
*/ |
|||
void display(void) { |
|||
int x, y, z, level, color; |
|||
tbReshape(WindWidth, WindHeight); |
|||
glClear(GL_COLOR_BUFFER_BIT); |
|||
glPushMatrix(); |
|||
glTranslatef(NUM_COLS * 2., 0., NUM_ROWS * 2.); |
|||
tbMatrix(); |
|||
glRotatef(view_rotx, 1.0, 0.0, 0.0); |
|||
glRotatef(view_roty, 0.0, 1.0, 0.0); |
|||
glRotatef(view_rotz, 0.0, 0.0, 1.0); |
|||
glTranslatef(-NUM_COLS * 2, 0., -NUM_ROWS * 2.); |
|||
for (x = 0; x < 1; x++) { |
|||
for (y = 0; y < NUM_COLS; y++) { |
|||
for (z = 0; z < NUM_ROWS; z++) { |
|||
color = 0; |
|||
for (level = 0; level < NUMPLANE; level++) { |
|||
if (pixmap[level][z % NUM_ROWS][y / 8] & (1 << y % 8)) { |
|||
color = level + 1; |
|||
} |
|||
} |
|||
drawLED(color, (float) y * 4.0, (float) x * 4.0, |
|||
(float) (NUM_ROWS - 1 - z) * 4.0); |
|||
} |
|||
} |
|||
} |
|||
glPopMatrix(); |
|||
glutSwapBuffers(); |
|||
|
|||
usleep(20000); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Handler for processing key presses. |
|||
* @param key The pressed key encoded in ASCII. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
void keyboard(unsigned char key, int x, int y) { |
|||
switch (key) { |
|||
case 'q': |
|||
printf("Quit\n"); |
|||
glutDestroyWindow(win); |
|||
exit(0); |
|||
break; |
|||
case ' ': |
|||
fakeport |= 0x01; |
|||
break; |
|||
case 'a': |
|||
fakeport |= 0x02; |
|||
break; |
|||
case 'd': |
|||
fakeport |= 0x04; |
|||
break; |
|||
case 's': |
|||
fakeport |= 0x08; |
|||
break; |
|||
case 'w': |
|||
fakeport |= 0x10; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Handler for processing key releases. |
|||
* @param key The released key encoded in ASCII. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
void keyboardup(unsigned char key, int x, int y) { |
|||
switch (key) { |
|||
case ' ': |
|||
fakeport &= ~0x01; |
|||
break; |
|||
case 'a': |
|||
fakeport &= ~0x02; |
|||
break; |
|||
case 'd': |
|||
fakeport &= ~0x04; |
|||
break; |
|||
case 's': |
|||
fakeport &= ~0x08; |
|||
break; |
|||
case 'w': |
|||
fakeport &= ~0x10; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Relays mouse position and button state to the trackball implementation. |
|||
* @param button Currently monitored button. |
|||
* @param state State of that button. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
void mouse(int button, int state, int x, int y) { |
|||
tbMouse(button, state, x, y); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Relays motion request to the trackball implementation. |
|||
* @param x X-position for the motion direction. |
|||
* @param y Y-position for the motion direction. |
|||
*/ |
|||
void motion(int x, int y) { |
|||
tbMotion(x, y); |
|||
} |
|||
|
|||
/**
|
|||
* Updating the window size. |
|||
* @param width Width of the window. |
|||
* @param height Height of the window. |
|||
*/ |
|||
void reshape(int width, int height) { |
|||
|
|||
tbReshape(width, height); |
|||
|
|||
glViewport(0, 0, width, height); |
|||
|
|||
glMatrixMode(GL_PROJECTION); |
|||
glLoadIdentity(); |
|||
gluPerspective(60.0, (float) WindWidth / (float) WindWidth, 5., 1000.); |
|||
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); |
|||
glMatrixMode(GL_MODELVIEW); |
|||
glLoadIdentity(); |
|||
|
|||
WindWidth = width; |
|||
WindHeight = height; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Handler for special keys (the arrow keys in particular) for adjusting the |
|||
* view angle of the scene. |
|||
* @param k The pressed special key using GLUT's nomenclature. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
static void special(int k, int x, int y) { |
|||
switch (k) { |
|||
case GLUT_KEY_UP: |
|||
view_rotx += 5.0; |
|||
break; |
|||
case GLUT_KEY_DOWN: |
|||
view_rotx -= 5.0; |
|||
break; |
|||
case GLUT_KEY_LEFT: |
|||
view_rotz += 5.0; |
|||
break; |
|||
case GLUT_KEY_RIGHT: |
|||
view_rotz -= 5.0; |
|||
break; |
|||
default: |
|||
return; |
|||
} |
|||
glutPostRedisplay(); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Entry point for starting the display loop thread. |
|||
* @param unused Not used. Only here to satisfy signature constraints. |
|||
*/ |
|||
void *display_loop_run(void * unused) { |
|||
display_loop(); |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Main function for the simulator. |
|||
* @param argc The argument count. |
|||
* @param argv Command line arguments. |
|||
* @return Exit codem, always zero. |
|||
*/ |
|||
int main(int argc, char **argv) { |
|||
WindHeight = 700; |
|||
WindWidth = 700; |
|||
glutInit(&argc, argv); |
|||
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); |
|||
glutInitWindowSize(WindHeight, WindWidth); |
|||
win = glutCreateWindow("16x16 Borg Simulator"); |
|||
|
|||
// callback
|
|||
glutDisplayFunc(display); |
|||
glutIdleFunc(display); |
|||
glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF); |
|||
glutKeyboardFunc(keyboard); |
|||
glutKeyboardUpFunc(keyboardup); |
|||
glutSpecialFunc(special); |
|||
glutMouseFunc(mouse); |
|||
glutMotionFunc(motion); |
|||
|
|||
// clearcolor & main loop
|
|||
glClearColor(0, 0, 0, 1.0); |
|||
gluPerspective(60.0, (float) WindWidth / (float) WindWidth, 5., 1000.); |
|||
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); |
|||
|
|||
// init Call List for LED
|
|||
GLUquadric* quad = gluNewQuadric(); |
|||
glNewList(0, GL_COMPILE); |
|||
glColor4f(0.8, 0.0, 0.0, 1.); |
|||
gluSphere(quad, 1.0, 12, 12); |
|||
glEndList(); |
|||
glNewList(1, GL_COMPILE); |
|||
glColor4f(0.5, 0.0, 0.0, 1.); |
|||
gluSphere(quad, 1.4, 12, 12); |
|||
glEndList(); |
|||
glNewList(2, GL_COMPILE); |
|||
glColor4f(0.7, 0.0, 0.0, 1.); |
|||
gluSphere(quad, 1.55, 12, 12); |
|||
glEndList(); |
|||
glNewList(3, GL_COMPILE); |
|||
glColor4f(1.00, 0.0, 0.0, 1.); |
|||
gluSphere(quad, 1.7, 12, 12); |
|||
glEndList(); |
|||
|
|||
tbInit(GLUT_LEFT_BUTTON); |
|||
tbAnimate(GL_FALSE); |
|||
|
|||
pthread_t simthread; |
|||
pthread_create(&simthread, NULL, display_loop_run, NULL); |
|||
|
|||
glutMainLoop(); |
|||
return 0; |
|||
} |
|||
|
|||
/*@}*/ |
|||
|
@ -1,295 +1,295 @@ |
|||
/**
|
|||
* \addtogroup unixsimulator |
|||
*/ |
|||
/*@{*/ |
|||
|
|||
/**
|
|||
* Simple trackball-like motion adapted (ripped off) from projtex.c |
|||
* (written by David Yu and David Blythe). See the SIGGRAPH '96 |
|||
* Advanced OpenGL course notes. |
|||
* |
|||
* |
|||
* Usage: |
|||
* |
|||
* o call tbInit() in before any other tb call |
|||
* o call tbReshape() from the reshape callback |
|||
* o call tbMatrix() to get the trackball matrix rotation |
|||
* o call tbStartMotion() to begin trackball movememt |
|||
* o call tbStopMotion() to stop trackball movememt |
|||
* o call tbMotion() from the motion callback |
|||
* o call tbAnimate(GL_TRUE) if you want the trackball to continue |
|||
* spinning after the mouse button has been released |
|||
* o call tbAnimate(GL_FALSE) if you want the trackball to stop |
|||
* spinning after the mouse button has been released |
|||
* |
|||
* Typical setup: |
|||
* |
|||
* |
|||
* void |
|||
* init(void) |
|||
* { |
|||
* tbInit(GLUT_MIDDLE_BUTTON); |
|||
* tbAnimate(GL_TRUE); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* reshape(int width, int height) |
|||
* { |
|||
* tbReshape(width, height); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* display(void) |
|||
* { |
|||
* glPushMatrix(); |
|||
* |
|||
* tbMatrix(); |
|||
* . . . draw the scene . . . |
|||
* |
|||
* glPopMatrix(); |
|||
* } |
|||
* |
|||
* void |
|||
* mouse(int button, int state, int x, int y) |
|||
* { |
|||
* tbMouse(button, state, x, y); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* motion(int x, int y) |
|||
* { |
|||
* tbMotion(x, y); |
|||
* . . . |
|||
* } |
|||
* |
|||
* int |
|||
* main(int argc, char** argv) |
|||
* { |
|||
* . . . |
|||
* init(); |
|||
* glutReshapeFunc(reshape); |
|||
* glutDisplayFunc(display); |
|||
* glutMouseFunc(mouse); |
|||
* glutMotionFunc(motion); |
|||
* . . . |
|||
* } |
|||
* |
|||
* @file trackball.c |
|||
* @brief Helper functions for the UNIX platform Borg simulator. |
|||
* @author Martin Ongsiek, David Yu, David Blythe |
|||
*/ |
|||
|
|||
/* includes */ |
|||
#include <math.h> |
|||
#include <assert.h> |
|||
#ifdef OSX_ |
|||
# include <GLUT/glut.h> |
|||
#else |
|||
# include <GL/glut.h> |
|||
#endif |
|||
#include "trackball.h" |
|||
|
|||
|
|||
/* globals */ |
|||
static GLuint tb_lasttime; |
|||
static GLfloat tb_lastposition[3]; |
|||
|
|||
static GLfloat tb_angle = 0.0; |
|||
static GLfloat tb_axis[3]; |
|||
static GLfloat tb_transform[4][4]; |
|||
|
|||
static GLuint tb_width; |
|||
static GLuint tb_height; |
|||
|
|||
static GLint tb_button = -1; |
|||
static GLboolean tb_tracking = GL_FALSE; |
|||
static GLboolean tb_animate = GL_TRUE; |
|||
|
|||
|
|||
/* functions */ |
|||
|
|||
/**
|
|||
* Project x and y onto a hemisphere centered within given width and height. |
|||
* @param x X-coordinate |
|||
* @param y Y-coordinate |
|||
* @param width Width of the hemisphere. |
|||
* @param height Width of the hemisphere. |
|||
* @param v Vector where the projection is performed on. |
|||
*/ |
|||
static void _tbPointToVector(int x, int y, int width, int height, float v[3]) { |
|||
float d, a; |
|||
|
|||
/* project x, y onto a hemisphere centered within width, height. */ |
|||
v[0] = (2.0 * x - width) / width; |
|||
v[1] = (height - 2.0 * y) / height; |
|||
d = sqrt(v[0] * v[0] + v[1] * v[1]); |
|||
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]); |
|||
v[0] *= a; |
|||
v[1] *= a; |
|||
v[2] *= a; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Redisplay current window contents. |
|||
*/ |
|||
static void _tbAnimate(void) { |
|||
glutPostRedisplay(); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Starts trackball movement depending on the mouse position. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
* @param button Not used. |
|||
* @param time Elapsed time. |
|||
*/ |
|||
void _tbStartMotion(int x, int y, int button, int time) { |
|||
assert(tb_button != -1); |
|||
|
|||
tb_tracking = GL_TRUE; |
|||
tb_lasttime = time; |
|||
_tbPointToVector(x, y, tb_width, tb_height, tb_lastposition); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Stops trackball movement. |
|||
* @param button Not used |
|||
* @param time Not used. |
|||
*/ |
|||
void _tbStopMotion(int button, unsigned time) { |
|||
assert(tb_button != -1); |
|||
|
|||
tb_tracking = GL_FALSE; |
|||
|
|||
if (time == tb_lasttime && tb_animate) { |
|||
glutIdleFunc(_tbAnimate); |
|||
} else { |
|||
tb_angle = 0.0; |
|||
if (tb_animate) { |
|||
glutIdleFunc(0); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
/**
|
|||
* Starts or stops the spinning movement of the trackball. |
|||
* @param animate GL_TRUE for starting and GL_FALSE for stopping the animation. |
|||
*/ |
|||
void tbAnimate(GLboolean animate) { |
|||
tb_animate = animate; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Has to be called before any other tb call. |
|||
* @param button Mouse button state. |
|||
*/ |
|||
void tbInit(GLuint button) { |
|||
tb_button = button; |
|||
tb_angle = 0.0; |
|||
|
|||
/* put the identity in the trackball transform */ |
|||
glPushMatrix(); |
|||
glLoadIdentity(); |
|||
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tb_transform); |
|||
glPopMatrix(); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Gets the tb matrix rotation. |
|||
*/ |
|||
void tbMatrix() { |
|||
assert(tb_button != -1); |
|||
|
|||
glPushMatrix(); |
|||
glLoadIdentity(); |
|||
glRotatef(tb_angle, -tb_axis[0], tb_axis[2], tb_axis[1]); |
|||
glMultMatrixf((GLfloat *) tb_transform); |
|||
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tb_transform); |
|||
glPopMatrix(); |
|||
|
|||
glMultMatrixf((GLfloat *) tb_transform); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Reshape callback function for determining the window size. |
|||
* @param width Width of the trackball. |
|||
* @param height Height of the trackball. |
|||
*/ |
|||
void tbReshape(int width, int height) { |
|||
assert(tb_button != -1); |
|||
|
|||
tb_width = width; |
|||
tb_height = height; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Starts motion depending on mouse position and button state. |
|||
* @param button The button whose state has changed. |
|||
* @param state The state of that button. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
void tbMouse(int button, int state, int x, int y) { |
|||
assert(tb_button != -1); |
|||
|
|||
if (state == GLUT_DOWN && button == tb_button) |
|||
_tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); |
|||
else if (state == GLUT_UP && button == tb_button) |
|||
_tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME)); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Starts a rotating scene motion to the given coordinates. |
|||
* @param x The x-coordinate. |
|||
* @param y The y-coordinate. |
|||
*/ |
|||
void tbMotion(int x, int y) { |
|||
GLfloat current_position[3], dx, dy, dz; |
|||
|
|||
assert(tb_button != -1); |
|||
|
|||
if (tb_tracking == GL_FALSE) |
|||
return; |
|||
|
|||
_tbPointToVector(x, y, tb_width, tb_height, current_position); |
|||
|
|||
/* calculate the angle to rotate by (directly proportional to the
|
|||
length of the mouse movement */ |
|||
dx = current_position[0] - tb_lastposition[0]; |
|||
dy = current_position[1] - tb_lastposition[1]; |
|||
dz = current_position[2] - tb_lastposition[2]; |
|||
tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); |
|||
|
|||
/* calculate the axis of rotation (cross product) */ |
|||
tb_axis[0] = tb_lastposition[1] * current_position[2] |
|||
- tb_lastposition[2] * current_position[1]; |
|||
tb_axis[1] = tb_lastposition[2] * current_position[0] |
|||
- tb_lastposition[0] * current_position[2]; |
|||
tb_axis[2] = tb_lastposition[0] * current_position[1] |
|||
- tb_lastposition[1] * current_position[0]; |
|||
|
|||
/* reset for next time */ |
|||
tb_lasttime = glutGet(GLUT_ELAPSED_TIME); |
|||
tb_lastposition[0] = current_position[0]; |
|||
tb_lastposition[1] = current_position[1]; |
|||
tb_lastposition[2] = current_position[2]; |
|||
|
|||
/* remember to draw new position */ |
|||
glutPostRedisplay(); |
|||
} |
|||
|
|||
/*@}*/ |
|||
/**
|
|||
* \addtogroup unixsimulator |
|||
*/ |
|||
/*@{*/ |
|||
|
|||
/**
|
|||
* Simple trackball-like motion adapted (ripped off) from projtex.c |
|||
* (written by David Yu and David Blythe). See the SIGGRAPH '96 |
|||
* Advanced OpenGL course notes. |
|||
* |
|||
* |
|||
* Usage: |
|||
* |
|||
* o call tbInit() in before any other tb call |
|||
* o call tbReshape() from the reshape callback |
|||
* o call tbMatrix() to get the trackball matrix rotation |
|||
* o call tbStartMotion() to begin trackball movememt |
|||
* o call tbStopMotion() to stop trackball movememt |
|||
* o call tbMotion() from the motion callback |
|||
* o call tbAnimate(GL_TRUE) if you want the trackball to continue |
|||
* spinning after the mouse button has been released |
|||
* o call tbAnimate(GL_FALSE) if you want the trackball to stop |
|||
* spinning after the mouse button has been released |
|||
* |
|||
* Typical setup: |
|||
* |
|||
* |
|||
* void |
|||
* init(void) |
|||
* { |
|||
* tbInit(GLUT_MIDDLE_BUTTON); |
|||
* tbAnimate(GL_TRUE); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* reshape(int width, int height) |
|||
* { |
|||
* tbReshape(width, height); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* display(void) |
|||
* { |
|||
* glPushMatrix(); |
|||
* |
|||
* tbMatrix(); |
|||
* . . . draw the scene . . . |
|||
* |
|||
* glPopMatrix(); |
|||
* } |
|||
* |
|||
* void |
|||
* mouse(int button, int state, int x, int y) |
|||
* { |
|||
* tbMouse(button, state, x, y); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* motion(int x, int y) |
|||
* { |
|||
* tbMotion(x, y); |
|||
* . . . |
|||
* } |
|||
* |
|||
* int |
|||
* main(int argc, char** argv) |
|||
* { |
|||
* . . . |
|||
* init(); |
|||
* glutReshapeFunc(reshape); |
|||
* glutDisplayFunc(display); |
|||
* glutMouseFunc(mouse); |
|||
* glutMotionFunc(motion); |
|||
* . . . |
|||
* } |
|||
* |
|||
* @file trackball.c |
|||
* @brief Helper functions for the UNIX platform Borg simulator. |
|||
* @author Martin Ongsiek, David Yu, David Blythe |
|||
*/ |
|||
|
|||
/* includes */ |
|||
#include <math.h> |
|||
#include <assert.h> |
|||
#ifdef OSX_ |
|||
# include <GLUT/glut.h> |
|||
#else |
|||
# include <GL/glut.h> |
|||
#endif |
|||
#include "trackball.h" |
|||
|
|||
|
|||
/* globals */ |
|||
static GLuint tb_lasttime; |
|||
static GLfloat tb_lastposition[3]; |
|||
|
|||
static GLfloat tb_angle = 0.0; |
|||
static GLfloat tb_axis[3]; |
|||
static GLfloat tb_transform[4][4]; |
|||
|
|||
static GLuint tb_width; |
|||
static GLuint tb_height; |
|||
|
|||
static GLint tb_button = -1; |
|||
static GLboolean tb_tracking = GL_FALSE; |
|||
static GLboolean tb_animate = GL_TRUE; |
|||
|
|||
|
|||
/* functions */ |
|||
|
|||
/**
|
|||
* Project x and y onto a hemisphere centered within given width and height. |
|||
* @param x X-coordinate |
|||
* @param y Y-coordinate |
|||
* @param width Width of the hemisphere. |
|||
* @param height Width of the hemisphere. |
|||
* @param v Vector where the projection is performed on. |
|||
*/ |
|||
static void _tbPointToVector(int x, int y, int width, int height, float v[3]) { |
|||
float d, a; |
|||
|
|||
/* project x, y onto a hemisphere centered within width, height. */ |
|||
v[0] = (2.0 * x - width) / width; |
|||
v[1] = (height - 2.0 * y) / height; |
|||
d = sqrt(v[0] * v[0] + v[1] * v[1]); |
|||
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]); |
|||
v[0] *= a; |
|||
v[1] *= a; |
|||
v[2] *= a; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Redisplay current window contents. |
|||
*/ |
|||
static void _tbAnimate(void) { |
|||
glutPostRedisplay(); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Starts trackball movement depending on the mouse position. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
* @param button Not used. |
|||
* @param time Elapsed time. |
|||
*/ |
|||
void _tbStartMotion(int x, int y, int button, int time) { |
|||
assert(tb_button != -1); |
|||
|
|||
tb_tracking = GL_TRUE; |
|||
tb_lasttime = time; |
|||
_tbPointToVector(x, y, tb_width, tb_height, tb_lastposition); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Stops trackball movement. |
|||
* @param button Not used |
|||
* @param time Not used. |
|||
*/ |
|||
void _tbStopMotion(int button, unsigned time) { |
|||
assert(tb_button != -1); |
|||
|
|||
tb_tracking = GL_FALSE; |
|||
|
|||
if (time == tb_lasttime && tb_animate) { |
|||
glutIdleFunc(_tbAnimate); |
|||
} else { |
|||
tb_angle = 0.0; |
|||
if (tb_animate) { |
|||
glutIdleFunc(0); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
/**
|
|||
* Starts or stops the spinning movement of the trackball. |
|||
* @param animate GL_TRUE for starting and GL_FALSE for stopping the animation. |
|||
*/ |
|||
void tbAnimate(GLboolean animate) { |
|||
tb_animate = animate; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Has to be called before any other tb call. |
|||
* @param button Mouse button state. |
|||
*/ |
|||
void tbInit(GLuint button) { |
|||
tb_button = button; |
|||
tb_angle = 0.0; |
|||
|
|||
/* put the identity in the trackball transform */ |
|||
glPushMatrix(); |
|||
glLoadIdentity(); |
|||
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tb_transform); |
|||
glPopMatrix(); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Gets the tb matrix rotation. |
|||
*/ |
|||
void tbMatrix() { |
|||
assert(tb_button != -1); |
|||
|
|||
glPushMatrix(); |
|||
glLoadIdentity(); |
|||
glRotatef(tb_angle, -tb_axis[0], tb_axis[2], tb_axis[1]); |
|||
glMultMatrixf((GLfloat *) tb_transform); |
|||
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) tb_transform); |
|||
glPopMatrix(); |
|||
|
|||
glMultMatrixf((GLfloat *) tb_transform); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Reshape callback function for determining the window size. |
|||
* @param width Width of the trackball. |
|||
* @param height Height of the trackball. |
|||
*/ |
|||
void tbReshape(int width, int height) { |
|||
assert(tb_button != -1); |
|||
|
|||
tb_width = width; |
|||
tb_height = height; |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Starts motion depending on mouse position and button state. |
|||
* @param button The button whose state has changed. |
|||
* @param state The state of that button. |
|||
* @param x X-position of the mouse pointer. |
|||
* @param y Y-position of the mouse pointer. |
|||
*/ |
|||
void tbMouse(int button, int state, int x, int y) { |
|||
assert(tb_button != -1); |
|||
|
|||
if (state == GLUT_DOWN && button == tb_button) |
|||
_tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); |
|||
else if (state == GLUT_UP && button == tb_button) |
|||
_tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME)); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Starts a rotating scene motion to the given coordinates. |
|||
* @param x The x-coordinate. |
|||
* @param y The y-coordinate. |
|||
*/ |
|||
void tbMotion(int x, int y) { |
|||
GLfloat current_position[3], dx, dy, dz; |
|||
|
|||
assert(tb_button != -1); |
|||
|
|||
if (tb_tracking == GL_FALSE) |
|||
return; |
|||
|
|||
_tbPointToVector(x, y, tb_width, tb_height, current_position); |
|||
|
|||
/* calculate the angle to rotate by (directly proportional to the
|
|||
length of the mouse movement */ |
|||
dx = current_position[0] - tb_lastposition[0]; |
|||
dy = current_position[1] - tb_lastposition[1]; |
|||
dz = current_position[2] - tb_lastposition[2]; |
|||
tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); |
|||
|
|||
/* calculate the axis of rotation (cross product) */ |
|||
tb_axis[0] = tb_lastposition[1] * current_position[2] |
|||
- tb_lastposition[2] * current_position[1]; |
|||
tb_axis[1] = tb_lastposition[2] * current_position[0] |
|||
- tb_lastposition[0] * current_position[2]; |
|||
tb_axis[2] = tb_lastposition[0] * current_position[1] |
|||
- tb_lastposition[1] * current_position[0]; |
|||
|
|||
/* reset for next time */ |
|||
tb_lasttime = glutGet(GLUT_ELAPSED_TIME); |
|||
tb_lastposition[0] = current_position[0]; |
|||
tb_lastposition[1] = current_position[1]; |
|||
tb_lastposition[2] = current_position[2]; |
|||
|
|||
/* remember to draw new position */ |
|||
glutPostRedisplay(); |
|||
} |
|||
|
|||
/*@}*/ |
|||
|
@ -1,99 +1,99 @@ |
|||
/**
|
|||
* \addtogroup unixsimulator |
|||
*/ |
|||
/*@{*/ |
|||
|
|||
/**
|
|||
* Simple trackball-like motion adapted (ripped off) from projtex.c |
|||
* (written by David Yu and David Blythe). See the SIGGRAPH '96 |
|||
* Advanced OpenGL course notes. |
|||
* |
|||
* |
|||
* Usage: |
|||
* |
|||
* o call tbInit() in before any other tb call |
|||
* o call tbReshape() from the reshape callback |
|||
* o call tbMatrix() to get the trackball matrix rotation |
|||
* o call tbStartMotion() to begin trackball movememt |
|||
* o call tbStopMotion() to stop trackball movememt |
|||
* o call tbMotion() from the motion callback |
|||
* o call tbAnimate(GL_TRUE) if you want the trackball to continue |
|||
* spinning after the mouse button has been released |
|||
* o call tbAnimate(GL_FALSE) if you want the trackball to stop |
|||
* spinning after the mouse button has been released |
|||
* |
|||
* Typical setup: |
|||
* |
|||
* |
|||
* void |
|||
* init(void) |
|||
* { |
|||
* tbInit(GLUT_MIDDLE_BUTTON); |
|||
* tbAnimate(GL_TRUE); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* reshape(int width, int height) |
|||
* { |
|||
* tbReshape(width, height); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* display(void) |
|||
* { |
|||
* glPushMatrix(); |
|||
* |
|||
* tbMatrix(); |
|||
* . . . draw the scene . . . |
|||
* |
|||
* glPopMatrix(); |
|||
* } |
|||
* |
|||
* void |
|||
* mouse(int button, int state, int x, int y) |
|||
* { |
|||
* tbMouse(button, state, x, y); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* motion(int x, int y) |
|||
* { |
|||
* tbMotion(x, y); |
|||
* . . . |
|||
* } |
|||
* |
|||
* int |
|||
* main(int argc, char** argv) |
|||
* { |
|||
* . . . |
|||
* init(); |
|||
* glutReshapeFunc(reshape); |
|||
* glutDisplayFunc(display); |
|||
* glutMouseFunc(mouse); |
|||
* glutMotionFunc(motion); |
|||
* . . . |
|||
* } |
|||
* |
|||
* @file trackball.h |
|||
* @brief Header file for helper functions for the UNIX platform Borg simulator. |
|||
* @author Martin Ongsiek, David Yu, David Blythe |
|||
*/ |
|||
|
|||
|
|||
/* functions */ |
|||
void tbInit(GLuint button); |
|||
|
|||
void tbMatrix(void); |
|||
|
|||
void tbReshape(int width, int height); |
|||
|
|||
void tbMouse(int button, int state, int x, int y); |
|||
|
|||
void tbMotion(int x, int y); |
|||
|
|||
void tbAnimate(GLboolean animate); |
|||
|
|||
/*@}*/ |
|||
/**
|
|||
* \addtogroup unixsimulator |
|||
*/ |
|||
/*@{*/ |
|||
|
|||
/**
|
|||
* Simple trackball-like motion adapted (ripped off) from projtex.c |
|||
* (written by David Yu and David Blythe). See the SIGGRAPH '96 |
|||
* Advanced OpenGL course notes. |
|||
* |
|||
* |
|||
* Usage: |
|||
* |
|||
* o call tbInit() in before any other tb call |
|||
* o call tbReshape() from the reshape callback |
|||
* o call tbMatrix() to get the trackball matrix rotation |
|||
* o call tbStartMotion() to begin trackball movememt |
|||
* o call tbStopMotion() to stop trackball movememt |
|||
* o call tbMotion() from the motion callback |
|||
* o call tbAnimate(GL_TRUE) if you want the trackball to continue |
|||
* spinning after the mouse button has been released |
|||
* o call tbAnimate(GL_FALSE) if you want the trackball to stop |
|||
* spinning after the mouse button has been released |
|||
* |
|||
* Typical setup: |
|||
* |
|||
* |
|||
* void |
|||
* init(void) |
|||
* { |
|||
* tbInit(GLUT_MIDDLE_BUTTON); |
|||
* tbAnimate(GL_TRUE); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* reshape(int width, int height) |
|||
* { |
|||
* tbReshape(width, height); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* display(void) |
|||
* { |
|||
* glPushMatrix(); |
|||
* |
|||
* tbMatrix(); |
|||
* . . . draw the scene . . . |
|||
* |
|||
* glPopMatrix(); |
|||
* } |
|||
* |
|||
* void |
|||
* mouse(int button, int state, int x, int y) |
|||
* { |
|||
* tbMouse(button, state, x, y); |
|||
* . . . |
|||
* } |
|||
* |
|||
* void |
|||
* motion(int x, int y) |
|||
* { |
|||
* tbMotion(x, y); |
|||
* . . . |
|||
* } |
|||
* |
|||
* int |
|||
* main(int argc, char** argv) |
|||
* { |
|||
* . . . |
|||
* init(); |
|||
* glutReshapeFunc(reshape); |
|||
* glutDisplayFunc(display); |
|||
* glutMouseFunc(mouse); |
|||
* glutMotionFunc(motion); |
|||
* . . . |
|||
* } |
|||
* |
|||
* @file trackball.h |
|||
* @brief Header file for helper functions for the UNIX platform Borg simulator. |
|||
* @author Martin Ongsiek, David Yu, David Blythe |
|||
*/ |
|||
|
|||
|
|||
/* functions */ |
|||
void tbInit(GLuint button); |
|||
|
|||
void tbMatrix(void); |
|||
|
|||
void tbReshape(int width, int height); |
|||
|
|||
void tbMouse(int button, int state, int x, int y); |
|||
|
|||
void tbMotion(int x, int y); |
|||
|
|||
void tbAnimate(GLboolean animate); |
|||
|
|||
/*@}*/ |
|||
|
Loading…
Reference in new issue