Skip to content

Commit

Permalink
Merge branch 'levels'
Browse files Browse the repository at this point in the history
  • Loading branch information
mccreery committed May 7, 2019
2 parents 60bd289 + 53cd576 commit f1609ff
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 33 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ WARNINGS := -Wall -Wextra -pedantic \
-Wstrict-overflow=5 -fstrict-overflow -Winline
CWARNINGS := -Wstrict-prototypes -Wmissing-prototypes \
-Wold-style-definition -Wold-style-declaration
LINKFLAGS := -mmcu=$(MCU) -Os -Wl,--gc-sections
LINKFLAGS := -mmcu=$(MCU) -O3 -Wl,--gc-sections

COMMONFLAGS := $(WARNINGS) $(LINKFLAGS) -fdata-sections -ffunction-sections
CFLAGS := $(COMMONFLAGS) $(CWARNINGS) -std=gnu99
Expand Down Expand Up @@ -104,6 +104,10 @@ $(BUILD)/%_2: $(IMG)/%.png
mkdir -p $(dir $@)
$(MAGICK) $< -depth 2 -colorspace gray Y:$@

$(BUILD)/%_1: $(IMG)/%.png
mkdir -p $(dir $@)
$(MAGICK) $< -depth 1 -colorspace gray Y:$@

erase:
dfu-programmer $(MCU) erase

Expand Down
Binary file added img/levels.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion programs.mk
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
snake_OBJECTS := $(call objs,*) $(call objs,**/*) \
segment24x32_2 snake_2 sqr8x8_2
segment24x32_2 snake_2 sqr8x8_2 levels_1
93 changes: 83 additions & 10 deletions src/snake/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "grid.h"
#include "hw/buttons.h"
#include "hw/display.h"
#include "levels.h"
#include "markers.h"
#include "rng.h"
#include "scoreio.h"
Expand All @@ -24,14 +25,20 @@ static const point_t DIRECTIONS[4] = {
bool demo;

static point_t demo_apples[] PROGMEM = {
{15, 6},
{10, 8},
{25, 9},
{2, 20}
{11, 12},
{28, 18},
{15, 29},
{1, 28},
{25, 3}
};
static uint8_t apple_index;

point_t get_demo_apple(void) {
static uint8_t level_countdown;
static uint8_t level;
static int8_t step;
static char level_text[] = "LEVEL XX";

static point_t get_demo_apple(void) {
point_t apple;

for(uint8_t i = 0; i < sizeof(apple); i++) {
Expand Down Expand Up @@ -76,21 +83,78 @@ static void place_apple(void) {
pos.x = -1;
}

while(pos.x == -1 || read_cell(pos) == SNAKE_COLOR) {
while(pos.x == -1 || read_cell(pos) != 0) {
pos.x = rng8() & GRID_MASK;
pos.y = rng8() & GRID_MASK;
}

write_cell(pos, APPLE_COLOR);
}

static void start_level(void) {
uint16_t real_score = get_score(score);
level = real_score >> 4;
load_level(level & 3);

uint8_t tens = level / 10;
level_text[sizeof(level_text) - 3] = '0' + tens;
level_text[sizeof(level_text) - 2] = '0' + (level - tens * 10);

// Increase speed every time the levels repeat
step = 5 - (level >> 2);
if(step < 0) step = 0;

clear_turns();
tail = head = (marker_t){{1, 1}, {0, 1}};
tail.position.y -= get_score(score) + 1;

int8_t y = tail.position.y + 1;
if(y < 0) y = 0;

for(; y <= head.position.y; y++) {
write_cell((point_t){tail.position.x, y}, SNAKE_COLOR);
}
level_countdown = 175;
place_apple();
}

void tick_board(void) {
static uint8_t step_counter;

if(level_countdown > 0) {
--level_countdown;

// Don't draw level number on the demo
if(!demo && (level_countdown & 31) == 0) {
init_font_sqr();

if((level_countdown & 63) == 0) {
draw_string(LCD_SIZE.y / 2, 0, level_text, CENTER);
} else {
font_blitter = blit_clear;
draw_string(LCD_SIZE.y / 2, 0, level_text, CENTER);
font_blitter = blit_2_palette;
}

init_font_seg();
}
return;
}

if(demo) {
tick_anybutton();
} else {
process_buttons();
}
if(frame_counter & 3 || tick_func_last == tick_board) return;

// We've been switched out
if(tick_func_last == tick_board) return;

if(++step_counter == step) {
step_counter = 0;
} else {
return;
}

move_head();
bool eaten_apple = read_cell(head.position) == APPLE_COLOR;
Expand All @@ -99,13 +163,23 @@ void tick_board(void) {
// Handle previous apple eaten
int8_t i = increment_score(&score);
draw_score_suffix(SCORE_LEFT, SCORE_Y, score, i);

if((get_score(score) & 15) == 0) {
if(demo) {
// Don't let the demo get past level 0
context_switch(setup_mainmenu, tick_mainmenu);
} else {
start_level();
}
return;
}
} else {
// Clear up tail
move_tail();
write_cell(tail.position, 0);
}

if(read_cell(head.position) == SNAKE_COLOR) {
if(!eaten_apple && read_cell(head.position) != 0) {
// Game over
if(demo) {
context_switch(setup_mainmenu, tick_mainmenu);
Expand Down Expand Up @@ -152,6 +226,5 @@ void setup_board(void) {
draw_score_suffix(SCORE_RIGHT, SCORE_Y, hiscores[0], 0);
if(demo) init_font_sqr();

clear_grid();
place_apple();
start_level();
}
25 changes: 25 additions & 0 deletions src/snake/levels.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "blob.h"
#include "grid.h"
#include "levels.h"

#define LEVEL_BYTES (32*32 / 8)
#define OBSTACLE_COLOR (0x7475)

USEBLOB(levels_1);

void load_level(uint8_t level) {
clear_grid();
if(level == 0) return;

const uint8_t * level_data = BLOB(levels_1) + LEVEL_BYTES * (level - 1);

for(uint8_t y = 0; y < 32; y++) {
for(uint8_t x = 0; x < 32; x += 8) {
uint8_t b = pgm_read_byte(level_data++);

for(uint8_t i = 0; i < 8; i++) {
write_cell((point_t){x + i, y}, b >> (7 - i) & 1 ? OBSTACLE_COLOR : 0);
}
}
}
}
11 changes: 11 additions & 0 deletions src/snake/levels.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef LEVELS_H_
#define LEVELS_H_

#include <stdint.h>

/**
* Loads the given level into the grid.
*/
void load_level(uint8_t level);

#endif
63 changes: 42 additions & 21 deletions src/snake/markers.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,32 @@

// Simple square
static marker_t demo_moves[] PROGMEM = {
{{16, 24}, {1, 0}},
{{26, 24}, {0, 1}},
{{26, 6}, {-1, 0}},
{{5, 6}, {0, 1}},
{{5, 13}, {1, 0}},
{{11, 13}, {0, -1}},
{{11, 11}, {-1, 0}},
{{8, 11}, {0, -1}},
{{8, 8}, {1, 0}},
{{21, 8}, {0, 1}},
{{21, 16}, {1, 0}},
{{25, 16}, {0, -1}},
{{25, 8}, {1, 0}},
{{2, 8}, {0, 1}},
{{2, 26}, {1, 0}},
{{12, 26}, {0, -1}},
{{12, 16}, {1, 0}},
{{16, 16}, {0, 1}}
{{1, 6}, {1, 0}},
{{4, 6}, {0, -1}},
{{4, 29}, {1, 0}},
{{18, 29}, {0, -1}},
{{18, 19}, {1, 0}},
{{24, 19}, {0, -1}},
{{24, 14}, {-1, 0}},
{{18, 14}, {0, -1}},
{{18, 11}, {1, 0}},
{{23, 11}, {0, 1}},
{{23, 13}, {1, 0}},
{{5, 13}, {0, 1}},
{{5, 16}, {-1, 0}},
{{28, 16}, {0, 1}},
{{28, 19}, {1, 0}},
{{2, 19}, {0, -1}},
{{2, 18}, {1, 0}},
{{7, 18}, {0, -1}},
{{7, 12}, {1, 0}},
{{13, 12}, {0, -1}},
{{13, 3}, {1, 0}},
{{29, 3}, {0, -1}},
{{29, 30}, {-1, 0}},
{{25, 30}, {0, -1}},
{{25, 27}, {1, 0}},
{{1, 27}, {0, 1}}
};
static marker_t demo_move;
static uint8_t demo_index;
Expand Down Expand Up @@ -57,9 +65,22 @@ void setup_markers(void) {
move_head();
}

static inline void apply_direction(marker_t * marker) {
marker->position.x = (marker->position.x + marker->direction.x) & GRID_MASK;
marker->position.y = (marker->position.y + marker->direction.y) & GRID_MASK;
static void apply_direction(marker_t * marker) {
if(marker->direction.x > 0) {
++marker->position.x;
if(marker->position.x == GRID_SIZE) { marker->position.x = 0; }
} else if(marker->direction.x < 0) {
--marker->position.x;
if(marker->position.x == -1) { marker->position.x = GRID_SIZE - 1; }
}

if(marker->direction.y > 0) {
++marker->position.y;
if(marker->position.y == GRID_SIZE) { marker->position.y = 0; }
} else if(marker->direction.y < 0) {
--marker->position.y;
if(marker->position.y == -1) { marker->position.y = GRID_SIZE - 1; }
}
}

void move_head(void) {
Expand Down
7 changes: 7 additions & 0 deletions src/snake/scoreio.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,11 @@ static inline void get_score_text(const score_t score, char * const str) {
str[4] = '\0';
}

static inline uint16_t get_score(const score_t score) {
return score.score[0] * 1000 +
score.score[1] * 100 +
score.score[2] * 10 +
score.score[3];
}

#endif

0 comments on commit f1609ff

Please sign in to comment.