mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-12 19:43:33 -07:00
Get rid of duplicate Game (2048)
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 159 B |
@@ -1,12 +0,0 @@
|
||||
App(
|
||||
appid="2048",
|
||||
name="2048 (Original)",
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
entry_point="game_2048_app",
|
||||
cdefines=["APP_2048_GAME"],
|
||||
requires=["gui"],
|
||||
stack_size=2 * 1024,
|
||||
order=10,
|
||||
fap_icon="2048.png",
|
||||
fap_category="Games",
|
||||
)
|
||||
@@ -1,155 +0,0 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <gui/canvas.h>
|
||||
|
||||
/* 7px 3 width digit font by Sefjor
|
||||
* digit encoding example
|
||||
*7 ¦¦¦ 111
|
||||
*6 ¦ ¦ 101
|
||||
*5 ¦ ¦ 101
|
||||
*4 ¦ ¦ 101
|
||||
*3 ¦ ¦ 101
|
||||
*2 ¦ ¦ 101
|
||||
*1 ¦¦¦ 111
|
||||
*0 000 this string is empty, used to align
|
||||
* ? ? ?
|
||||
* FE 82 FE //0
|
||||
*/
|
||||
|
||||
static uint8_t font[10][3] = {
|
||||
{0xFE, 0x82, 0xFE}, // 0;
|
||||
{0x00, 0xFE, 0x00}, // 1;
|
||||
{0xF2, 0x92, 0x9E}, // 2;
|
||||
{0x92, 0x92, 0xFE}, // 3;
|
||||
{0x1E, 0x10, 0xFE}, // 4;
|
||||
{0x9E, 0x92, 0xF2}, // 5;
|
||||
{0xFE, 0x92, 0xF2}, // 6;
|
||||
{0x02, 0x02, 0xFE}, // 7;
|
||||
{0xFE, 0x92, 0xFE}, // 8;
|
||||
{0x9E, 0x92, 0xFE}, // 9;
|
||||
};
|
||||
|
||||
#define FONT_HEIGHT 8
|
||||
#define FONT_WIDTH 3
|
||||
|
||||
static void game_2048_draw_black_point(Canvas* const canvas, uint8_t x, uint8_t y) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_dot(canvas, x, y);
|
||||
}
|
||||
|
||||
static void game_2048_draw_white_square(Canvas* const canvas, uint8_t x, uint8_t y) {
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_box(canvas, x, y, 15 - 1, 15 - 3);
|
||||
}
|
||||
|
||||
static void _game_2048_draw_column(
|
||||
Canvas* const canvas,
|
||||
int digit,
|
||||
int coord_x,
|
||||
int coord_y,
|
||||
uint8_t column) {
|
||||
for(int x = 0; x < FONT_HEIGHT; ++x) {
|
||||
bool is_filled = (font[digit][column] >> x) & 0x1;
|
||||
if(is_filled) {
|
||||
game_2048_draw_black_point(canvas, coord_x, coord_y + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
_game_2048_draw_digit(Canvas* const canvas, uint8_t digit, uint8_t coord_x, uint8_t coord_y) {
|
||||
uint8_t x_shift = 0;
|
||||
|
||||
if(digit != 1) {
|
||||
for(int column = 0; column < FONT_WIDTH; column++) {
|
||||
_game_2048_draw_column(canvas, digit, coord_x + column, coord_y, column);
|
||||
}
|
||||
x_shift = 3;
|
||||
} else {
|
||||
_game_2048_draw_column(canvas, digit, coord_x, coord_y, true);
|
||||
x_shift = 1;
|
||||
}
|
||||
|
||||
return x_shift;
|
||||
}
|
||||
|
||||
/* We drawing text field with 1px white border
|
||||
* at given coords. Total size is:
|
||||
* x = 9 = 1 + 7 + 1
|
||||
* y = 1 + total text width + 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns array of digits and it's size,
|
||||
* digits should be at least 4 size
|
||||
* works from 1 to 9999
|
||||
*/
|
||||
static void _game_2048_parse_number(uint16_t number, uint8_t* digits, uint8_t* size) {
|
||||
*size = 0;
|
||||
uint16_t divider = 1000;
|
||||
//find first digit, result is highest divider
|
||||
while(number / divider == 0) {
|
||||
divider /= 10;
|
||||
if(divider == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; divider != 0; i++) {
|
||||
digits[i] = number / divider;
|
||||
number %= divider;
|
||||
*size += 1;
|
||||
divider /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t _game_2048_calculate_shift(uint16_t num) {
|
||||
uint8_t shift = 0;
|
||||
switch(num) {
|
||||
case 1:
|
||||
shift = 7;
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
shift = 6;
|
||||
break;
|
||||
case 16:
|
||||
shift = 5;
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
shift = 4;
|
||||
break;
|
||||
case 128:
|
||||
shift = 3;
|
||||
break;
|
||||
case 256:
|
||||
shift = 2;
|
||||
break;
|
||||
case 512:
|
||||
shift = 3;
|
||||
break;
|
||||
case 1024:
|
||||
shift = 2;
|
||||
break;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
void game_2048_draw_number(Canvas* const canvas, uint8_t x, uint8_t y, int number) {
|
||||
uint8_t digits[4];
|
||||
uint8_t size;
|
||||
|
||||
_game_2048_parse_number(number, digits, &size);
|
||||
if(number > 512) {
|
||||
game_2048_draw_white_square(canvas, x, y);
|
||||
}
|
||||
|
||||
x += _game_2048_calculate_shift(number);
|
||||
y += 4;
|
||||
for(int i = 0; i < size; ++i) {
|
||||
x += _game_2048_draw_digit(canvas, digits[i], x, y);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#include <gui/canvas.h>
|
||||
|
||||
void game_2048_draw_number(Canvas* const canvas, uint8_t x, uint8_t y, int number);
|
||||
@@ -1,495 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <gui/gui.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
#define DEBUG false
|
||||
/*
|
||||
0 empty
|
||||
1 2
|
||||
2 4
|
||||
3 8
|
||||
4 16
|
||||
5 32
|
||||
6 64
|
||||
7 128
|
||||
8 256
|
||||
9 512
|
||||
10 1024
|
||||
11 2048
|
||||
12 4096
|
||||
...
|
||||
*/
|
||||
typedef uint8_t cell_state;
|
||||
|
||||
/* DirectionLeft <--
|
||||
┌╌╌╌╌┐┌╌╌╌╌┐┌╌╌╌╌┐┌╌╌╌╌┐
|
||||
╎ ╎╎ ╎╎ ╎╎ ╎
|
||||
└╌╌╌╌┘└╌╌╌╌┘└╌╌╌╌┘└╌╌╌╌┘
|
||||
┌╌╌╌╌┐┌╌╌╌╌┐┌╌╌╌╌┐┌╌╌╌╌┐
|
||||
╎ ╎╎ ╎╎ ╎╎ ╎
|
||||
└╌╌╌╌┘└╌╌╌╌┘└╌╌╌╌┘└╌╌╌╌┘
|
||||
┌╌╌┌╌╌╌╌┐╌╌┐┌╌╌╌╌┐┌╌╌╌╌┐
|
||||
╎ 2╎ 2 ╎ ╎╎ ╎╎ ╎
|
||||
└╌╌└╌╌╌╌┘╌╌┘└╌╌╌╌┘└╌╌╌╌┘
|
||||
┌╌╌┌╌╌╌╌┐┌╌╌┌╌╌╌╌┐┌╌╌╌╌┐
|
||||
╎ 4╎ 4 ╎╎ 2╎ 2 ╎╎ ╎
|
||||
└╌╌└╌╌╌╌┘└╌╌└╌╌╌╌┘└╌╌╌╌┘
|
||||
*/
|
||||
typedef enum {
|
||||
DirectionIdle,
|
||||
DirectionUp,
|
||||
DirectionRight,
|
||||
DirectionDown,
|
||||
DirectionLeft,
|
||||
} Direction;
|
||||
|
||||
typedef struct {
|
||||
uint8_t y; // 0 <= y <= 3
|
||||
uint8_t x; // 0 <= x <= 3
|
||||
} Point;
|
||||
|
||||
typedef struct {
|
||||
uint32_t gameScore;
|
||||
uint32_t highScore;
|
||||
} Score;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
+----X
|
||||
|
|
||||
| field[x][y]
|
||||
Y
|
||||
*/
|
||||
uint8_t field[4][4];
|
||||
|
||||
uint8_t next_field[4][4];
|
||||
|
||||
Score score; // original scoring
|
||||
|
||||
Direction direction;
|
||||
/*
|
||||
field {
|
||||
animation-timing-function: linear;
|
||||
animation-duration: 300ms;
|
||||
}
|
||||
*/
|
||||
uint32_t animation_start_ticks;
|
||||
|
||||
Point keyframe_from[4][4];
|
||||
|
||||
Point keyframe_to[4][4];
|
||||
|
||||
bool debug;
|
||||
|
||||
} GameState;
|
||||
|
||||
#define XtoPx(x) (33 + x * 15)
|
||||
|
||||
#define YtoPx(x) (1 + y * 15)
|
||||
|
||||
static void game_2048_render_callback(Canvas* const canvas, ValueMutex* const vm) {
|
||||
const GameState* game_state = acquire_mutex(vm, 25);
|
||||
if(game_state == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Before the function is called, the state is set with the canvas_reset(canvas)
|
||||
|
||||
if(game_state->direction == DirectionIdle) {
|
||||
for(uint8_t y = 0; y < 4; y++) {
|
||||
for(uint8_t x = 0; x < 4; x++) {
|
||||
uint8_t field = game_state->field[y][x];
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_frame(canvas, XtoPx(x), YtoPx(y), 16, 16);
|
||||
if(field != 0) {
|
||||
game_2048_draw_number(canvas, XtoPx(x), YtoPx(y), 1 << field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// display score
|
||||
char buffer[12];
|
||||
snprintf(buffer, sizeof(buffer), "%lu", game_state->score.gameScore);
|
||||
canvas_draw_str_aligned(canvas, 127, 8, AlignRight, AlignBottom, buffer);
|
||||
|
||||
if(game_state->score.highScore > 0) {
|
||||
char buffer2[12];
|
||||
snprintf(buffer2, sizeof(buffer2), "%lu", game_state->score.highScore);
|
||||
canvas_draw_str_aligned(canvas, 127, 62, AlignRight, AlignBottom, buffer2);
|
||||
}
|
||||
} else { // if animation
|
||||
// for animation
|
||||
// (osKernelGetSysTimerCount() - game_state->animation_start_ticks) / osKernelGetSysTimerFreq();
|
||||
|
||||
// TODO: end animation event/callback/set AnimationIdle
|
||||
}
|
||||
|
||||
release_mutex(vm, game_state);
|
||||
}
|
||||
|
||||
static void
|
||||
game_2048_input_callback(const InputEvent* const input_event, FuriMessageQueue* event_queue) {
|
||||
furi_assert(event_queue);
|
||||
|
||||
furi_message_queue_put(event_queue, input_event, FuriWaitForever);
|
||||
}
|
||||
|
||||
// if return false then Game Over
|
||||
static bool game_2048_set_new_number(GameState* const game_state) {
|
||||
uint8_t empty = 0;
|
||||
for(uint8_t y = 0; y < 4; y++) {
|
||||
for(uint8_t x = 0; x < 4; x++) {
|
||||
if(game_state->field[y][x] == 0) {
|
||||
empty++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(empty == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(empty == 1) {
|
||||
// If it is 1 move before losing, we help the player and get rid of randomness.
|
||||
for(uint8_t y = 0; y < 4; y++) {
|
||||
for(uint8_t x = 0; x < 4; x++) {
|
||||
if(game_state->field[y][x] == 0) {
|
||||
bool haveFour =
|
||||
// +----X
|
||||
// |
|
||||
// | field[x][y], 0 <= x, y <= 3
|
||||
// Y
|
||||
|
||||
// up == 4 or
|
||||
(y > 0 && game_state->field[y - 1][x] == 2) ||
|
||||
// right == 4 or
|
||||
(x < 3 && game_state->field[y][x + 1] == 2) ||
|
||||
// down == 4
|
||||
(y < 3 && game_state->field[y + 1][x] == 2) ||
|
||||
// left == 4
|
||||
(x > 0 && game_state->field[y][x - 1] == 2);
|
||||
|
||||
if(haveFour) {
|
||||
game_state->field[y][x] = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
game_state->field[y][x] = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t target = rand() % empty;
|
||||
uint8_t twoOrFore = rand() % 4 < 3;
|
||||
for(uint8_t y = 0; y < 4; y++) {
|
||||
for(uint8_t x = 0; x < 4; x++) {
|
||||
if(game_state->field[y][x] == 0) {
|
||||
if(target == 0) {
|
||||
if(twoOrFore) {
|
||||
game_state->field[y][x] = 1; // 2^1 == 2 75%
|
||||
} else {
|
||||
game_state->field[y][x] = 2; // 2^2 == 4 25%
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
target--;
|
||||
}
|
||||
}
|
||||
}
|
||||
exit:
|
||||
return true;
|
||||
}
|
||||
|
||||
// static void game_2048_process_row(uint8_t before[4], uint8_t *(after[4])) {
|
||||
// // move 1 row left.
|
||||
// for(uint8_t i = 0; i <= 2; i++) {
|
||||
// if(before[i] != 0 && before[i] == before[i + 1]) {
|
||||
// before[i]++;
|
||||
// before[i + 1] = 0;
|
||||
// i++;
|
||||
// }
|
||||
// }
|
||||
// for(uint8_t i = 0, j = 0; i <= 3; i++) {
|
||||
// if (before[i] != 0) {
|
||||
// before[j] = before[i];
|
||||
// i++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
static void game_2048_process_move(GameState* const game_state) {
|
||||
memset(game_state->next_field, 0, sizeof(game_state->next_field));
|
||||
// +----X
|
||||
// |
|
||||
// | field[x][y], 0 <= x, y <= 3
|
||||
// Y
|
||||
|
||||
// up
|
||||
if(game_state->direction == DirectionUp) {
|
||||
for(uint8_t x = 0; x < 4; x++) {
|
||||
uint8_t next_y = 0;
|
||||
for(int8_t y = 0; y < 4; y++) {
|
||||
uint8_t field = game_state->field[y][x];
|
||||
if(field == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(game_state->next_field[next_y][x] == 0) {
|
||||
game_state->next_field[next_y][x] = field;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(field == game_state->next_field[next_y][x]) {
|
||||
game_state->next_field[next_y][x]++;
|
||||
game_state->score.gameScore += pow(2, game_state->next_field[next_y][x]);
|
||||
if(game_state->next_field[next_y][x] == 11 && !game_state->debug) {
|
||||
DOLPHIN_DEED(getRandomDeed());
|
||||
} // get some xp for making a 2048 tile
|
||||
next_y++;
|
||||
continue;
|
||||
}
|
||||
|
||||
next_y++;
|
||||
game_state->next_field[next_y][x] = field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// right
|
||||
if(game_state->direction == DirectionRight) {
|
||||
for(uint8_t y = 0; y < 4; y++) {
|
||||
uint8_t next_x = 3;
|
||||
for(int8_t x = 3; x >= 0; x--) {
|
||||
uint8_t field = game_state->field[y][x];
|
||||
if(field == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(game_state->next_field[y][next_x] == 0) {
|
||||
game_state->next_field[y][next_x] = field;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(field == game_state->next_field[y][next_x]) {
|
||||
game_state->next_field[y][next_x]++;
|
||||
game_state->score.gameScore += pow(2, game_state->next_field[y][next_x]);
|
||||
if(game_state->next_field[y][next_x] == 11 && !game_state->debug) {
|
||||
DOLPHIN_DEED(getRandomDeed());
|
||||
} // get some xp for making a 2048 tile
|
||||
next_x--;
|
||||
continue;
|
||||
}
|
||||
|
||||
next_x--;
|
||||
game_state->next_field[y][next_x] = field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// down
|
||||
if(game_state->direction == DirectionDown) {
|
||||
for(uint8_t x = 0; x < 4; x++) {
|
||||
uint8_t next_y = 3;
|
||||
for(int8_t y = 3; y >= 0; y--) {
|
||||
uint8_t field = game_state->field[y][x];
|
||||
if(field == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(game_state->next_field[next_y][x] == 0) {
|
||||
game_state->next_field[next_y][x] = field;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(field == game_state->next_field[next_y][x]) {
|
||||
game_state->next_field[next_y][x]++;
|
||||
game_state->score.gameScore += pow(2, game_state->next_field[next_y][x]);
|
||||
if(game_state->next_field[next_y][x] == 11 && !game_state->debug) {
|
||||
DOLPHIN_DEED(getRandomDeed());
|
||||
} // get some xp for making a 2048 tile
|
||||
next_y--;
|
||||
continue;
|
||||
}
|
||||
|
||||
next_y--;
|
||||
game_state->next_field[next_y][x] = field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0, 0, 1, 1
|
||||
// 1, 0, 0, 0
|
||||
|
||||
// left
|
||||
if(game_state->direction == DirectionLeft) {
|
||||
for(uint8_t y = 0; y < 4; y++) {
|
||||
uint8_t next_x = 0;
|
||||
for(uint8_t x = 0; x < 4; x++) {
|
||||
uint8_t field = game_state->field[y][x];
|
||||
if(field == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(game_state->next_field[y][next_x] == 0) {
|
||||
game_state->next_field[y][next_x] = field;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(field == game_state->next_field[y][next_x]) {
|
||||
game_state->next_field[y][next_x]++;
|
||||
game_state->score.gameScore += pow(2, game_state->next_field[y][next_x]);
|
||||
if(game_state->next_field[y][next_x] == 11 && !game_state->debug) {
|
||||
DOLPHIN_DEED(getRandomDeed());
|
||||
} // get some xp for making a 2048 tile
|
||||
next_x++;
|
||||
continue;
|
||||
}
|
||||
|
||||
next_x++;
|
||||
game_state->next_field[y][next_x] = field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <debug>
|
||||
game_state->direction = DirectionIdle;
|
||||
memcpy(game_state->field, game_state->next_field, sizeof(game_state->field));
|
||||
// </debug>
|
||||
}
|
||||
|
||||
static void game_2048_restart(GameState* const game_state) {
|
||||
game_state->debug = DEBUG;
|
||||
|
||||
// check score
|
||||
if(game_state->score.gameScore > game_state->score.highScore) {
|
||||
game_state->score.highScore = game_state->score.gameScore;
|
||||
}
|
||||
|
||||
// clear all cells
|
||||
for(uint8_t y = 0; y < 4; y++) {
|
||||
for(uint8_t x = 0; x < 4; x++) {
|
||||
game_state->field[y][x] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// start next game
|
||||
game_state->score.gameScore = 0;
|
||||
game_2048_set_new_number(game_state);
|
||||
game_2048_set_new_number(game_state);
|
||||
}
|
||||
|
||||
int32_t game_2048_app(void* p) {
|
||||
UNUSED(p);
|
||||
int32_t return_code = 0;
|
||||
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
||||
|
||||
GameState* game_state = malloc(sizeof(GameState));
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, game_state, sizeof(GameState))) {
|
||||
return_code = 255;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(
|
||||
view_port, (ViewPortDrawCallback)game_2048_render_callback, &state_mutex);
|
||||
view_port_input_callback_set(
|
||||
view_port, (ViewPortInputCallback)game_2048_input_callback, event_queue);
|
||||
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
game_state->direction = DirectionIdle;
|
||||
game_2048_restart(game_state);
|
||||
|
||||
if(game_state->debug) {
|
||||
game_state->field[0][0] = 0;
|
||||
game_state->field[0][1] = 0;
|
||||
game_state->field[0][2] = 0;
|
||||
game_state->field[0][3] = 0;
|
||||
|
||||
game_state->field[1][0] = 1;
|
||||
game_state->field[1][1] = 2;
|
||||
game_state->field[1][2] = 3;
|
||||
game_state->field[1][3] = 4;
|
||||
|
||||
game_state->field[2][0] = 5;
|
||||
game_state->field[2][1] = 6;
|
||||
game_state->field[2][2] = 7;
|
||||
game_state->field[2][3] = 8;
|
||||
|
||||
game_state->field[3][0] = 9;
|
||||
game_state->field[3][1] = 10;
|
||||
game_state->field[3][2] = 11;
|
||||
game_state->field[3][3] = 12;
|
||||
}
|
||||
|
||||
InputEvent event;
|
||||
for(bool loop = true; loop;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
GameState* game_state = (GameState*)acquire_mutex_block(&state_mutex);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == InputTypeShort) {
|
||||
switch(event.key) {
|
||||
case InputKeyUp:
|
||||
game_state->direction = DirectionUp;
|
||||
game_2048_process_move(game_state);
|
||||
game_2048_set_new_number(game_state);
|
||||
break;
|
||||
case InputKeyDown:
|
||||
game_state->direction = DirectionDown;
|
||||
game_2048_process_move(game_state);
|
||||
game_2048_set_new_number(game_state);
|
||||
break;
|
||||
case InputKeyRight:
|
||||
game_state->direction = DirectionRight;
|
||||
game_2048_process_move(game_state);
|
||||
game_2048_set_new_number(game_state);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
game_state->direction = DirectionLeft;
|
||||
game_2048_process_move(game_state);
|
||||
game_2048_set_new_number(game_state);
|
||||
break;
|
||||
case InputKeyOk:
|
||||
game_state->direction = DirectionIdle;
|
||||
break;
|
||||
case InputKeyBack:
|
||||
loop = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(event.type == InputTypeLong) {
|
||||
if(event.key == InputKeyOk) {
|
||||
game_state->direction = DirectionIdle;
|
||||
game_2048_restart(game_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, game_state);
|
||||
}
|
||||
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
delete_mutex(&state_mutex);
|
||||
|
||||
free_and_exit:
|
||||
free(game_state);
|
||||
furi_message_queue_free(event_queue);
|
||||
|
||||
return return_code;
|
||||
}
|
||||
Reference in New Issue
Block a user