|
@@ -2,26 +2,15 @@
|
|
|
#include <gui/gui.h>
|
|
#include <gui/gui.h>
|
|
|
#include <gui/elements.h>
|
|
#include <gui/elements.h>
|
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
|
|
|
+#include <storage/storage.h>
|
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
|
#include <input/input.h>
|
|
#include <input/input.h>
|
|
|
#include <furi_hal.h>
|
|
#include <furi_hal.h>
|
|
|
#include <slotmachine_icons.h>
|
|
#include <slotmachine_icons.h>
|
|
|
|
|
|
|
|
-const Icon* slot_frames[] = {
|
|
|
|
|
- &I_x2,
|
|
|
|
|
- &I_x3,
|
|
|
|
|
- &I_x4,
|
|
|
|
|
- &I_x2_2,
|
|
|
|
|
- &I_x5
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-const uint8_t slot_coef[] = {
|
|
|
|
|
- 2,
|
|
|
|
|
- 3,
|
|
|
|
|
- 4,
|
|
|
|
|
- 2,
|
|
|
|
|
- 5
|
|
|
|
|
-};
|
|
|
|
|
|
|
+const Icon* slot_frames[] = {&I_x2, &I_x3, &I_x4, &I_x2_2, &I_x5};
|
|
|
|
|
+
|
|
|
|
|
+const uint8_t slot_coef[] = {2, 3, 4, 2, 5};
|
|
|
|
|
|
|
|
typedef struct {
|
|
typedef struct {
|
|
|
uint8_t x, y, value, times, speed;
|
|
uint8_t x, y, value, times, speed;
|
|
@@ -29,7 +18,7 @@ typedef struct {
|
|
|
} SlotColumn;
|
|
} SlotColumn;
|
|
|
|
|
|
|
|
int COLUMNS_COUNT = 4;
|
|
int COLUMNS_COUNT = 4;
|
|
|
-const MAX_COLUMNS_COUNT = 4;
|
|
|
|
|
|
|
+int MAX_COLUMNS_COUNT = 4;
|
|
|
|
|
|
|
|
typedef struct {
|
|
typedef struct {
|
|
|
Gui* gui; // container gui
|
|
Gui* gui; // container gui
|
|
@@ -39,25 +28,53 @@ typedef struct {
|
|
|
uint16_t bet;
|
|
uint16_t bet;
|
|
|
double money, winamount;
|
|
double money, winamount;
|
|
|
SlotColumn* columns[4];
|
|
SlotColumn* columns[4];
|
|
|
- bool winview;
|
|
|
|
|
|
|
+ bool winview, loseview;
|
|
|
} SlotMachineApp;
|
|
} SlotMachineApp;
|
|
|
|
|
|
|
|
|
|
+typedef struct {
|
|
|
|
|
+ int highscore;
|
|
|
|
|
+} SlotsHighscore;
|
|
|
|
|
+
|
|
|
#define START_MONEY 1500;
|
|
#define START_MONEY 1500;
|
|
|
#define START_BET 300;
|
|
#define START_BET 300;
|
|
|
-#define RAND_MAX 5;
|
|
|
|
|
|
|
+#define SLOTS_RAND_MAX 5;
|
|
|
#define DEFAULT_SPEED 16;
|
|
#define DEFAULT_SPEED 16;
|
|
|
|
|
+#define HIGHSCORES_FILENAME EXT_PATH("apps/Games/slotmachine.save")
|
|
|
|
|
|
|
|
uint8_t DEFAULT_SPINNING_TIMES = 10;
|
|
uint8_t DEFAULT_SPINNING_TIMES = 10;
|
|
|
|
|
+static SlotsHighscore highscore;
|
|
|
|
|
|
|
|
-void game_results(SlotMachineApp* app) {
|
|
|
|
|
- int matches[] = {
|
|
|
|
|
- 0,
|
|
|
|
|
- 0,
|
|
|
|
|
- 0,
|
|
|
|
|
- 0,
|
|
|
|
|
- 0
|
|
|
|
|
- };
|
|
|
|
|
|
|
+static bool highscores_load() {
|
|
|
|
|
+ Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
|
|
|
+ File* file = storage_file_alloc(storage);
|
|
|
|
|
|
|
|
|
|
+ uint16_t bytes_readed = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (storage_file_open(file, HIGHSCORES_FILENAME, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
|
|
|
|
+ bytes_readed = storage_file_read(file, &highscore, sizeof(SlotsHighscore));
|
|
|
|
|
+ }
|
|
|
|
|
+ storage_file_close(file);
|
|
|
|
|
+ storage_file_free(file);
|
|
|
|
|
+ furi_record_close(RECORD_STORAGE);
|
|
|
|
|
+
|
|
|
|
|
+ return bytes_readed == sizeof(SlotsHighscore);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void highscores_save() {
|
|
|
|
|
+ Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
|
|
|
+
|
|
|
|
|
+ File* file = storage_file_alloc(storage);
|
|
|
|
|
+
|
|
|
|
|
+ if (storage_file_open(file, HIGHSCORES_FILENAME, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
|
|
|
|
|
+ storage_file_write(file, &highscore, sizeof(SlotsHighscore));
|
|
|
|
|
+ }
|
|
|
|
|
+ storage_file_close(file);
|
|
|
|
|
+ storage_file_free(file);
|
|
|
|
|
+ furi_record_close(RECORD_STORAGE);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void game_results(SlotMachineApp* app) {
|
|
|
|
|
+ int matches[] = {0, 0, 0, 0, 0};
|
|
|
double total = 0;
|
|
double total = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < COLUMNS_COUNT; i++) {
|
|
for (int i = 0; i < COLUMNS_COUNT; i++) {
|
|
@@ -74,6 +91,15 @@ void game_results(SlotMachineApp* app) {
|
|
|
app->money += total;
|
|
app->money += total;
|
|
|
app->winamount = total;
|
|
app->winamount = total;
|
|
|
app->winview = true;
|
|
app->winview = true;
|
|
|
|
|
+
|
|
|
|
|
+ if (total > highscore.highscore) {
|
|
|
|
|
+ highscore.highscore = total;
|
|
|
|
|
+ highscores_save();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (app->money < 10) {
|
|
|
|
|
+ app->loseview = true;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -90,7 +116,7 @@ void draw_container(Canvas* canvas) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool checkIsSpinning(SlotMachineApp* slotmachine) {
|
|
bool checkIsSpinning(SlotMachineApp* slotmachine) {
|
|
|
- for (int i = 0; i< COLUMNS_COUNT; i++) {
|
|
|
|
|
|
|
+ for (int i = 0; i < COLUMNS_COUNT; i++) {
|
|
|
if (slotmachine->columns[i]->spining) return true;
|
|
if (slotmachine->columns[i]->spining) return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -119,19 +145,23 @@ void slotmachine_draw_callback(Canvas* canvas, void* ctx) {
|
|
|
|
|
|
|
|
canvas_set_font(canvas, FontPrimary);
|
|
canvas_set_font(canvas, FontPrimary);
|
|
|
canvas_draw_str(canvas, 2, 10, "Slots");
|
|
canvas_draw_str(canvas, 2, 10, "Slots");
|
|
|
- Icon* litl_icon = &I_little_coin;
|
|
|
|
|
|
|
+ const Icon* litl_icon = &I_little_coin;
|
|
|
canvas_draw_icon(canvas, 30, 3, litl_icon);
|
|
canvas_draw_icon(canvas, 30, 3, litl_icon);
|
|
|
|
|
|
|
|
char moneyStr[15];
|
|
char moneyStr[15];
|
|
|
snprintf(moneyStr, sizeof(moneyStr), "$%.0f", slotmachine->money);
|
|
snprintf(moneyStr, sizeof(moneyStr), "$%.0f", slotmachine->money);
|
|
|
|
|
|
|
|
|
|
+ char highscoresStr[25];
|
|
|
|
|
+ snprintf(highscoresStr, sizeof(highscoresStr), "HS:$%d", highscore.highscore);
|
|
|
|
|
+
|
|
|
char betStr[7];
|
|
char betStr[7];
|
|
|
snprintf(betStr, sizeof(betStr), "$%d", slotmachine->bet);
|
|
snprintf(betStr, sizeof(betStr), "$%d", slotmachine->bet);
|
|
|
|
|
|
|
|
canvas_set_font(canvas, FontSecondary);
|
|
canvas_set_font(canvas, FontSecondary);
|
|
|
- canvas_draw_str(canvas, 45, 10, moneyStr);
|
|
|
|
|
|
|
+ canvas_draw_str(canvas, 40, 10, moneyStr);
|
|
|
canvas_draw_str(canvas, 2, canvas_height(canvas) - 3, "Bet:");
|
|
canvas_draw_str(canvas, 2, canvas_height(canvas) - 3, "Bet:");
|
|
|
canvas_draw_str(canvas, 20, canvas_height(canvas) - 3, betStr);
|
|
canvas_draw_str(canvas, 20, canvas_height(canvas) - 3, betStr);
|
|
|
|
|
+ canvas_draw_str(canvas, 75, 10, highscoresStr);
|
|
|
|
|
|
|
|
if (slotmachine->winview) {
|
|
if (slotmachine->winview) {
|
|
|
char winamountStr[30];
|
|
char winamountStr[30];
|
|
@@ -143,7 +173,14 @@ void slotmachine_draw_callback(Canvas* canvas, void* ctx) {
|
|
|
|
|
|
|
|
furi_mutex_release(slotmachine->model_mutex);
|
|
furi_mutex_release(slotmachine->model_mutex);
|
|
|
return;
|
|
return;
|
|
|
- }
|
|
|
|
|
|
|
+ } else if (slotmachine->loseview) {
|
|
|
|
|
+ canvas_set_font(canvas, FontPrimary);
|
|
|
|
|
+ canvas_draw_str(canvas, 2, 35, "You lose ;(");
|
|
|
|
|
+ drawButton(canvas, 95, 52, "Ok", false);
|
|
|
|
|
+
|
|
|
|
|
+ furi_mutex_release(slotmachine->model_mutex);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
for (int i = 0; i < COLUMNS_COUNT; i++) {
|
|
for (int i = 0; i < COLUMNS_COUNT; i++) {
|
|
|
if (slotmachine->columns[i]->spining) {
|
|
if (slotmachine->columns[i]->spining) {
|
|
@@ -153,7 +190,7 @@ void slotmachine_draw_callback(Canvas* canvas, void* ctx) {
|
|
|
slotmachine->columns[i]->y = 13;
|
|
slotmachine->columns[i]->y = 13;
|
|
|
slotmachine->columns[i]->times--;
|
|
slotmachine->columns[i]->times--;
|
|
|
slotmachine->columns[i]->speed--;
|
|
slotmachine->columns[i]->speed--;
|
|
|
- slotmachine->columns[i]->value = rand() % RAND_MAX;
|
|
|
|
|
|
|
+ slotmachine->columns[i]->value = rand() % SLOTS_RAND_MAX;
|
|
|
|
|
|
|
|
if (slotmachine->columns[i]->times == 0) {
|
|
if (slotmachine->columns[i]->times == 0) {
|
|
|
slotmachine->columns[i]->y = 23;
|
|
slotmachine->columns[i]->y = 23;
|
|
@@ -196,6 +233,7 @@ SlotMachineApp* slotmachine_app_alloc() {
|
|
|
app->money = START_MONEY;
|
|
app->money = START_MONEY;
|
|
|
app->bet = START_BET;
|
|
app->bet = START_BET;
|
|
|
app->winview = false;
|
|
app->winview = false;
|
|
|
|
|
+ app->loseview = false;
|
|
|
app->winamount = 0;
|
|
app->winamount = 0;
|
|
|
|
|
|
|
|
int x = 7;
|
|
int x = 7;
|
|
@@ -233,6 +271,9 @@ int32_t slotmachine_app(void* p) {
|
|
|
SlotMachineApp* slotmachine = slotmachine_app_alloc();
|
|
SlotMachineApp* slotmachine = slotmachine_app_alloc();
|
|
|
InputEvent input;
|
|
InputEvent input;
|
|
|
|
|
|
|
|
|
|
+ if (!highscores_load()) {
|
|
|
|
|
+ memset(&highscore, 0, sizeof(highscore));
|
|
|
|
|
+ }
|
|
|
// endless input cycle
|
|
// endless input cycle
|
|
|
while(furi_message_queue_get(slotmachine->input_queue, &input, FuriWaitForever) == FuriStatusOk) {
|
|
while(furi_message_queue_get(slotmachine->input_queue, &input, FuriWaitForever) == FuriStatusOk) {
|
|
|
// if thread idle - take it
|
|
// if thread idle - take it
|
|
@@ -243,19 +284,20 @@ int32_t slotmachine_app(void* p) {
|
|
|
// exit on back button
|
|
// exit on back button
|
|
|
furi_mutex_release(slotmachine->model_mutex);
|
|
furi_mutex_release(slotmachine->model_mutex);
|
|
|
break;
|
|
break;
|
|
|
- } else if (input.key == InputKeyOk && input.type == InputTypeShort && slotmachine->winview) {
|
|
|
|
|
|
|
+ } else if (input.key == InputKeyOk && input.type == InputTypeShort && (slotmachine->winview || slotmachine->loseview)) {
|
|
|
slotmachine->winview = false;
|
|
slotmachine->winview = false;
|
|
|
|
|
+ slotmachine->loseview = false;
|
|
|
} else if (input.key == InputKeyOk && input.type == InputTypeShort && slotmachine->bet <= slotmachine->money) {
|
|
} else if (input.key == InputKeyOk && input.type == InputTypeShort && slotmachine->bet <= slotmachine->money) {
|
|
|
COLUMNS_COUNT = rand() % 3 + 2;
|
|
COLUMNS_COUNT = rand() % 3 + 2;
|
|
|
slotmachine->money -= slotmachine->bet;
|
|
slotmachine->money -= slotmachine->bet;
|
|
|
slotmachine->columns[0]->spining = true;
|
|
slotmachine->columns[0]->spining = true;
|
|
|
|
|
|
|
|
- for (int i = 0; i< COLUMNS_COUNT; i++) {
|
|
|
|
|
|
|
+ for (int i = 0; i < COLUMNS_COUNT; i++) {
|
|
|
slotmachine->columns[i]->times = DEFAULT_SPINNING_TIMES;
|
|
slotmachine->columns[i]->times = DEFAULT_SPINNING_TIMES;
|
|
|
slotmachine->columns[i]->speed = DEFAULT_SPEED;
|
|
slotmachine->columns[i]->speed = DEFAULT_SPEED;
|
|
|
}
|
|
}
|
|
|
} else if (input.key == InputKeyUp) {
|
|
} else if (input.key == InputKeyUp) {
|
|
|
- if (slotmachine->bet + 10 < slotmachine->money) {
|
|
|
|
|
|
|
+ if (slotmachine->bet + 10 <= slotmachine->money) {
|
|
|
slotmachine->bet += 10;
|
|
slotmachine->bet += 10;
|
|
|
}
|
|
}
|
|
|
} else if (input.key == InputKeyDown) {
|
|
} else if (input.key == InputKeyDown) {
|