Implemented two players on single host, changed io processing to interrupt.
This commit is contained in:
143
src/game.c
143
src/game.c
@@ -4,17 +4,11 @@
|
|||||||
#include <color.h>
|
#include <color.h>
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
static pin_t pin_left;
|
|
||||||
static pin_t pin_right;
|
|
||||||
|
|
||||||
|
|
||||||
void game_init(game_t* game) {
|
void game_init(game_t* game) {
|
||||||
//Sysinit
|
//Sysinit
|
||||||
|
|
||||||
//gpio init (move to module?)
|
//gpio init
|
||||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC,ENABLE);
|
io_init();
|
||||||
pin_create(&pin_right, GPIOC, 7, true);
|
|
||||||
pin_create(&pin_left, GPIOI, 0, true);
|
|
||||||
|
|
||||||
//uart init
|
//uart init
|
||||||
|
|
||||||
@@ -24,8 +18,7 @@ void game_init(game_t* game) {
|
|||||||
|
|
||||||
//struct init
|
//struct init
|
||||||
game->state=prestart;
|
game->state=prestart;
|
||||||
game->host_id = 0;
|
game->ticks_per_pixel = SPEED_DEFAULT;
|
||||||
game->ticks_per_pixel = SPEED_SLOW;
|
|
||||||
game->ticks_leftover =0;
|
game->ticks_leftover =0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,14 +31,15 @@ void game_step(game_t* game, uint64_t deltaTime) {
|
|||||||
LCD_DrawRectF(10,10,100,50,GUI_COLOR_BLUE);
|
LCD_DrawRectF(10,10,100,50,GUI_COLOR_BLUE);
|
||||||
|
|
||||||
//wait on player to press start (host)
|
//wait on player to press start (host)
|
||||||
while(!pin_get(&pin_right));
|
while(!io_button_has_edge(BTN_START));
|
||||||
while(pin_get(&pin_right));
|
|
||||||
|
|
||||||
//send game start request to slave
|
//send game start request to slave
|
||||||
//wait on game accept response
|
//wait on game accept response
|
||||||
|
|
||||||
//setup
|
//setup
|
||||||
player_init(&(game->player[game->host_id]));
|
//void player_init(player_t* player, uint8_t btn_left, uint8_t btn_right, point_t pos, uint16_t color, direction_t direction);
|
||||||
|
player_init(&(game->player[0]), BTN_PLAYER_1_LEFT, BTN_PLAYER_1_RIGHT, (point_t){.x=10,.y=120}, GUI_COLOR_BLUE, right);
|
||||||
|
player_init(&(game->player[1]), BTN_PLAYER_2_LEFT, BTN_PLAYER_2_RIGHT, (point_t){.x=230,.y=120}, GUI_COLOR_RED, left);
|
||||||
|
|
||||||
|
|
||||||
//switch state
|
//switch state
|
||||||
@@ -54,65 +48,74 @@ void game_step(game_t* game, uint64_t deltaTime) {
|
|||||||
break;
|
break;
|
||||||
case running:
|
case running:
|
||||||
{
|
{
|
||||||
bool directionChange = false;
|
uint16_t ticks;
|
||||||
player_t* host_player = &(game->player[game->host_id]);
|
uint16_t pixels = 0;
|
||||||
if(pin_get(&pin_left)) {
|
|
||||||
while(pin_get(&pin_left));
|
|
||||||
host_player->direction= (host_player->direction + 3) % 4 ; // "decrement enum value"
|
|
||||||
directionChange = true;
|
|
||||||
} else if(pin_get(&pin_right)) {
|
|
||||||
while(pin_get(&pin_right));
|
|
||||||
host_player->direction= (host_player->direction + 1) % 4 ; // "increment enum value"
|
|
||||||
directionChange = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(directionChange) {
|
if(deltaTime) {
|
||||||
player_append_position(host_player,host_player->position);
|
|
||||||
}
|
ticks = game->ticks_leftover + deltaTime;
|
||||||
if(deltaTime) {
|
pixels = ticks / game->ticks_per_pixel;
|
||||||
uint16_t ticks = game->ticks_leftover + deltaTime;
|
|
||||||
uint16_t pixels = ticks / game->ticks_per_pixel;
|
game->ticks_leftover = ticks % game->ticks_per_pixel;
|
||||||
game->ticks_leftover = ticks % game->ticks_per_pixel;
|
}
|
||||||
if(pixels) {
|
|
||||||
point_t last_point = host_player->past_positions[host_player->num_positions-1];
|
for(int i = 0; i < PLAYER_COUNT; i++) {
|
||||||
switch(host_player->direction) {
|
|
||||||
case down:
|
bool directionChange = false;
|
||||||
host_player->position.y+=pixels;
|
player_t* player = &(game->player[i]);
|
||||||
LCD_DrawRectF( host_player->position.x,
|
|
||||||
last_point.y,
|
if(io_button_has_edge(player->btn_left)) {
|
||||||
PLAYER_WIDTH,
|
player->direction= (player->direction + (4 - 1)) % 4 ; // "decrement enum value"
|
||||||
host_player->position.y - last_point.y,
|
directionChange = true;
|
||||||
host_player->color);
|
} else if(io_button_has_edge(player->btn_right)) {
|
||||||
break;
|
player->direction= (player->direction + 1) % 4 ; // "increment enum value"
|
||||||
case left:
|
directionChange = true;
|
||||||
host_player->position.x-=pixels;
|
}
|
||||||
LCD_DrawRectF( host_player->position.x,
|
|
||||||
host_player->position.y,
|
if(directionChange) {
|
||||||
last_point.x -host_player->position.x,
|
player_append_position(player,player->position);
|
||||||
PLAYER_WIDTH,
|
}
|
||||||
host_player->color);
|
|
||||||
break;
|
if(pixels) {
|
||||||
case up:
|
point_t last_point = player->past_positions[player->num_positions-1];
|
||||||
host_player->position.y-=pixels;
|
switch(player->direction) {
|
||||||
LCD_DrawRectF( host_player->position.x,
|
case down:
|
||||||
host_player->position.y,
|
player->position.y+=pixels;
|
||||||
PLAYER_WIDTH,
|
LCD_DrawRectF( player->position.x,
|
||||||
last_point.y - host_player->position.y,
|
last_point.y,
|
||||||
host_player->color);
|
PLAYER_WIDTH,
|
||||||
break;
|
player->position.y - last_point.y,
|
||||||
case right:
|
player->color);
|
||||||
host_player->position.x+=pixels;
|
break;
|
||||||
LCD_DrawRectF( last_point.x,
|
case left:
|
||||||
host_player->position.y,
|
player->position.x-=pixels;
|
||||||
host_player->position.x - last_point.x,
|
LCD_DrawRectF( player->position.x,
|
||||||
PLAYER_WIDTH,
|
player->position.y,
|
||||||
host_player->color);
|
last_point.x -player->position.x,
|
||||||
break;
|
PLAYER_WIDTH,
|
||||||
}
|
player->color);
|
||||||
}
|
break;
|
||||||
}
|
case up:
|
||||||
}
|
player->position.y-=pixels;
|
||||||
|
LCD_DrawRectF( player->position.x,
|
||||||
|
player->position.y,
|
||||||
|
PLAYER_WIDTH,
|
||||||
|
last_point.y - player->position.y,
|
||||||
|
player->color);
|
||||||
|
break;
|
||||||
|
case right:
|
||||||
|
player->position.x+=pixels;
|
||||||
|
LCD_DrawRectF( last_point.x,
|
||||||
|
player->position.y,
|
||||||
|
player->position.x - last_point.x,
|
||||||
|
PLAYER_WIDTH,
|
||||||
|
player->color);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
src/game.h
16
src/game.h
@@ -5,16 +5,23 @@
|
|||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
#include"player.h"
|
#include"player.h"
|
||||||
|
|
||||||
#define PLAYER_COUNT 2
|
#define PLAYER_COUNT 2
|
||||||
#define PLAYER_WIDTH 3
|
#define PLAYER_WIDTH 0 // Don't change
|
||||||
#define SPEED_SLOW 10
|
#define SPEED_SLOW 10
|
||||||
|
#define SPEED_FAST 1
|
||||||
|
#define SPEED_DEFAULT (SPEED_SLOW)
|
||||||
|
|
||||||
|
#define BTN_START 0
|
||||||
|
#define BTN_PLAYER_1_LEFT 3
|
||||||
|
#define BTN_PLAYER_1_RIGHT 2
|
||||||
|
#define BTN_PLAYER_2_LEFT 1
|
||||||
|
#define BTN_PLAYER_2_RIGHT 0
|
||||||
|
|
||||||
typedef struct game_s{
|
typedef struct game_s{
|
||||||
//public section
|
//public section
|
||||||
|
|
||||||
uint16_t time; // seconds since game start
|
uint16_t time; // seconds since game start
|
||||||
int8_t winner_id;
|
int8_t winner_id;
|
||||||
uint8_t host_id;
|
|
||||||
uint8_t ticks_per_pixel;
|
uint8_t ticks_per_pixel;
|
||||||
player_t player[PLAYER_COUNT];
|
player_t player[PLAYER_COUNT];
|
||||||
|
|
||||||
@@ -24,7 +31,6 @@ typedef struct game_s{
|
|||||||
ended
|
ended
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
|
|
||||||
//private section ahead:
|
//private section ahead:
|
||||||
uint8_t ticks_leftover;
|
uint8_t ticks_leftover;
|
||||||
} game_t;
|
} game_t;
|
||||||
|
|||||||
54
src/io.c
54
src/io.c
@@ -1,6 +1,29 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
|
//-----------Local types & functions--------------------------
|
||||||
|
typedef struct pin_s {
|
||||||
|
GPIO_TypeDef* GPIO;
|
||||||
|
uint16_t pinmask;
|
||||||
|
bool input;
|
||||||
|
} pin_t;
|
||||||
|
|
||||||
|
static void pin_create(pin_t* pin, GPIO_TypeDef* GPIO, uint8_t pinnr, bool input);
|
||||||
|
static bool pin_get(pin_t* pin);
|
||||||
|
static void pin_set(pin_t* pin, bool status);
|
||||||
|
static void pin_toggle(pin_t* pin);
|
||||||
|
|
||||||
|
|
||||||
|
//-------------Local Variables-------------------------
|
||||||
|
static pin_t pin_t0;
|
||||||
|
static pin_t pin_t1;
|
||||||
|
static pin_t pin_t2;
|
||||||
|
static pin_t pin_t3;
|
||||||
|
|
||||||
|
static uint8_t new = 0;
|
||||||
|
static uint8_t old = 0;
|
||||||
|
static volatile uint8_t edg = 0;
|
||||||
|
|
||||||
|
//---------------Implementation --------------------------------
|
||||||
void pin_create(pin_t* pin, GPIO_TypeDef* GPIO, uint8_t pinnr, bool input) {
|
void pin_create(pin_t* pin, GPIO_TypeDef* GPIO, uint8_t pinnr, bool input) {
|
||||||
GPIO_InitTypeDef gi;
|
GPIO_InitTypeDef gi;
|
||||||
GPIO_StructInit(&gi);
|
GPIO_StructInit(&gi);
|
||||||
@@ -41,9 +64,38 @@ void pin_set(pin_t* pin, bool status) {
|
|||||||
|
|
||||||
void pin_toggle(pin_t* pin) {
|
void pin_toggle(pin_t* pin) {
|
||||||
if(!pin->input) {
|
if(!pin->input) {
|
||||||
set_pin(pin,!get_pin(pin));
|
pin_set(pin,!pin_get(pin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void io_init(void){
|
||||||
|
//gpio init
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC,ENABLE);
|
||||||
|
pin_create(&pin_t0, GPIOC, 7, true);
|
||||||
|
pin_create(&pin_t1, GPIOB, 15, true);
|
||||||
|
pin_create(&pin_t2, GPIOB, 14, true);
|
||||||
|
pin_create(&pin_t3, GPIOI, 0, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_process(void) {
|
||||||
|
new = pin_get(&pin_t0) |
|
||||||
|
pin_get(&pin_t1) << 1 |
|
||||||
|
pin_get(&pin_t2) << 2 |
|
||||||
|
pin_get(&pin_t3) << 3;
|
||||||
|
|
||||||
|
edg |= (new ^ old) & new; // detect positive edge
|
||||||
|
old = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool io_button_has_edge(uint8_t btnnumber) {
|
||||||
|
|
||||||
|
uint8_t bm = (1 << btnnumber);
|
||||||
|
bool status = ((edg & bm) > 0);
|
||||||
|
|
||||||
|
if(status){
|
||||||
|
edg &= ~bm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|||||||
18
src/io.h
18
src/io.h
@@ -1,17 +1,13 @@
|
|||||||
|
#ifndef IO_H
|
||||||
|
#define IO_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stm32f4xx.h>
|
#include <stm32f4xx.h>
|
||||||
|
|
||||||
typedef struct pin_s {
|
|
||||||
GPIO_TypeDef* GPIO;
|
|
||||||
uint16_t pinmask;
|
|
||||||
bool input;
|
|
||||||
} pin_t;
|
|
||||||
|
|
||||||
void pin_create(pin_t* pin, GPIO_TypeDef* GPIO, uint8_t pinnr, bool input);
|
|
||||||
bool pin_get(pin_t* pin);
|
|
||||||
void pin_set(pin_t* pin, bool status);
|
|
||||||
void pin_toggle(pin_t* pin);
|
|
||||||
|
|
||||||
|
|
||||||
|
void io_init(void);
|
||||||
|
void io_process(void);
|
||||||
|
bool io_button_has_edge(uint8_t btnnumber);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* IO_H */
|
||||||
|
|||||||
@@ -27,10 +27,10 @@
|
|||||||
#include <color.h>
|
#include <color.h>
|
||||||
#include <stm32f4xx_adc.h>
|
#include <stm32f4xx_adc.h>
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
#include "io.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
|
||||||
|
|
||||||
game_t gameobj;
|
game_t gameobj;
|
||||||
|
|
||||||
uint64_t ticks;
|
uint64_t ticks;
|
||||||
@@ -38,11 +38,11 @@ uint64_t lastTicks;
|
|||||||
|
|
||||||
void SysTick_Handler() {
|
void SysTick_Handler() {
|
||||||
ticks++;
|
ticks++;
|
||||||
|
io_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SYSCLK 168e6
|
||||||
#define SYSCLK 168e6
|
#define TICKS_PER_SECOND 100
|
||||||
#define TICKS_PER_SECOND 100
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
|||||||
16
src/player.c
16
src/player.c
@@ -1,19 +1,19 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include <color.h>
|
#include <color.h>
|
||||||
|
|
||||||
void player_init(player_t* player) {
|
void player_init(player_t* player, uint8_t btn_left, uint8_t btn_right,
|
||||||
player->id=0;
|
point_t pos, uint16_t color, direction_t direction) {
|
||||||
player->color = GUI_COLOR_BLUE;
|
player->color = color;
|
||||||
player->num_positions=1;
|
player->num_positions = 1;
|
||||||
player->position = (point_t){.x=10,.y=100};
|
player->position = pos;
|
||||||
player->past_positions[0] = player->position;
|
player->past_positions[0] = player->position;
|
||||||
player->direction = right;
|
player->direction = direction;
|
||||||
player->state = alive;
|
player->state = alive;
|
||||||
|
player->btn_left = btn_left;
|
||||||
|
player->btn_right = btn_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void player_append_position(player_t* player, point_t point) {
|
void player_append_position(player_t* player, point_t point) {
|
||||||
if(player->num_positions < max_positions) {
|
if(player->num_positions < max_positions) {
|
||||||
player->past_positions[player->num_positions++] = point;
|
player->past_positions[player->num_positions++] = point;
|
||||||
|
|||||||
20
src/player.h
20
src/player.h
@@ -1,11 +1,16 @@
|
|||||||
#ifndef PLAYER_H
|
#ifndef PLAYER_H
|
||||||
#define PLAYER_H
|
#define PLAYER_H
|
||||||
|
|
||||||
|
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
#include<stdint.h>
|
#include<stdint.h>
|
||||||
|
|
||||||
#define max_positions 320
|
#define max_positions 320
|
||||||
|
typedef enum direction_e {
|
||||||
|
right,
|
||||||
|
down,
|
||||||
|
left,
|
||||||
|
up
|
||||||
|
} direction_t;
|
||||||
|
|
||||||
typedef struct point_s{
|
typedef struct point_s{
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
@@ -14,16 +19,11 @@ typedef struct point_s{
|
|||||||
|
|
||||||
typedef struct player_s {
|
typedef struct player_s {
|
||||||
|
|
||||||
uint8_t id;
|
uint8_t btn_left;
|
||||||
|
uint8_t btn_right;
|
||||||
uint16_t color;
|
uint16_t color;
|
||||||
uint16_t num_positions;
|
uint16_t num_positions;
|
||||||
|
direction_t direction;
|
||||||
enum {
|
|
||||||
right,
|
|
||||||
down,
|
|
||||||
left,
|
|
||||||
up
|
|
||||||
} direction;
|
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
dead,
|
dead,
|
||||||
@@ -35,7 +35,7 @@ typedef struct player_s {
|
|||||||
|
|
||||||
} player_t;
|
} player_t;
|
||||||
|
|
||||||
void player_init(player_t* player); // reset all fields
|
void player_init(player_t* player, uint8_t btn_left, uint8_t btn_right, point_t pos, uint16_t color, direction_t direction); // reset all fields
|
||||||
void player_append_position(player_t* player, point_t point); // updates num_position and adds current position to the list
|
void player_append_position(player_t* player, point_t point); // updates num_position and adds current position to the list
|
||||||
|
|
||||||
#endif /* PLAYER_H */
|
#endif /* PLAYER_H */
|
||||||
|
|||||||
24
src/uart.h
24
src/uart.h
@@ -1,24 +0,0 @@
|
|||||||
#ifndef UART_H
|
|
||||||
#define UART_H
|
|
||||||
|
|
||||||
#include<stdint.h>
|
|
||||||
#include<stdlib.h>
|
|
||||||
#include<stdbool.h>
|
|
||||||
|
|
||||||
typedef struct uart_message_s{
|
|
||||||
uint16_t message_length;
|
|
||||||
uint8_t *message_data;
|
|
||||||
|
|
||||||
// Internal, do not touch!
|
|
||||||
bool __deleted;
|
|
||||||
} uart_message_t;
|
|
||||||
|
|
||||||
void uart_init(void);
|
|
||||||
void uart_transmit(uart_message_t *message); // transmit a message and frees it
|
|
||||||
bool uart_has_message(void); // checks if there is at least one msg available
|
|
||||||
void uart_message_free(uart_message_t *message); // frees a message
|
|
||||||
|
|
||||||
uart_message_t *uart_message_allocate(void); // allocate storage for a new message
|
|
||||||
uart_message_t *receive_message(void); // returns a message if available else null
|
|
||||||
|
|
||||||
#endif /* UART_H */
|
|
||||||
Reference in New Issue
Block a user