Explorar o código

Adds "animation" of running dino.

Denis Nelubin %!s(int64=3) %!d(string=hai) anos
pai
achega
cdfb8aedfb
Modificáronse 7 ficheiros con 75 adicións e 17 borrados
  1. 5 0
      Makefile
  2. 0 0
      assets/Dino.png
  3. BIN=BIN
      assets/DinoRun0.png
  4. BIN=BIN
      assets/DinoRun1.png
  5. 11 3
      assets_icons.c
  6. 3 1
      assets_icons.h
  7. 56 13
      trexrunner.c

+ 5 - 0
Makefile

@@ -8,6 +8,11 @@ build: $(FLIPPER_FIRMWARE_PATH)/applications_user/t-rex-runner
 launch: $(FLIPPER_FIRMWARE_PATH)/applications_user/t-rex-runner
 	cd $(FLIPPER_FIRMWARE_PATH) && ./fbt launch_app APPSRC=applications_user/t-rex-runner
 
+.PHONY: assets
+assets:
+	rm assets_icons.*
+	$(MAKE) assets_icons.c
+
 assets_icons.c: $(FLIPPER_FIRMWARE_PATH)/applications_user/t-rex-runner
 	cd $(FLIPPER_FIRMWARE_PATH) && ./scripts/assets.py icons applications_user/t-rex-runner/assets/ applications_user/t-rex-runner/
 

+ 0 - 0
assets/dino.png → assets/Dino.png


BIN=BIN
assets/DinoRun0.png


BIN=BIN
assets/DinoRun1.png


+ 11 - 3
assets_icons.c

@@ -2,8 +2,16 @@
 
 #include <gui/icon_i.h>
 
-const uint8_t _I_dino_0[] = {0x01,0x00,0x3d,0x00,0x80,0x7e,0x20,0xf0,0x0f,0xe4,0x3e,0x01,0xec,0x01,0x08,0x14,0x80,0x4b,0x7c,0x0a,0x0f,0xf2,0x07,0x01,0x9f,0x40,0x30,0x33,0xf8,0x07,0x0f,0xff,0x00,0xf3,0xef,0xe0,0x1f,0xf0,0x40,0x80,0x8b,0xfd,0x1f,0x0b,0x08,0x08,0x7f,0x01,0xf1,0xf8,0x0c,0x47,0xc1,0x06,0x80,0x58,0x20,0x90,0x09,0x00,0x08,0x6c,0x10,0xc8,0x00,};
-const uint8_t* const _I_dino[] = {_I_dino_0};
+const uint8_t _I_Dino_0[] = {0x01,0x00,0x3d,0x00,0x80,0x7e,0x20,0xf0,0x0f,0xe4,0x3e,0x01,0xec,0x01,0x08,0x14,0x80,0x4b,0x7c,0x0a,0x0f,0xf2,0x07,0x01,0x9f,0x40,0x30,0x33,0xf8,0x07,0x0f,0xff,0x00,0xf3,0xef,0xe0,0x1f,0xf0,0x40,0x80,0x8b,0xfd,0x1f,0x0b,0x08,0x08,0x7f,0x01,0xf1,0xf8,0x0c,0x47,0xc1,0x06,0x80,0x58,0x20,0x90,0x09,0x00,0x08,0x6c,0x10,0xc8,0x00,};
+const uint8_t* const _I_Dino[] = {_I_Dino_0};
 
-const Icon I_dino = {.width=20,.height=22,.frame_count=1,.frame_rate=0,.frames=_I_dino};
+const uint8_t _I_DinoRun0_0[] = {0x01,0x00,0x3b,0x00,0x80,0x7e,0x20,0xf0,0x0f,0xe4,0x3e,0x01,0xec,0x01,0x08,0x14,0x80,0x4b,0x7c,0x0a,0x0f,0xf2,0x07,0x01,0x9f,0x40,0x30,0x33,0xf8,0x07,0x0f,0xff,0x00,0xf3,0xef,0xe0,0x1f,0xf0,0x40,0x80,0x8b,0xfd,0x1f,0x0b,0x08,0x08,0x7f,0x01,0xf1,0xf8,0x0c,0x47,0xc1,0x0c,0x80,0x58,0x04,0xa3,0x20,0x01,0x08,0x14,0x80,};
+const uint8_t* const _I_DinoRun0[] = {_I_DinoRun0_0};
+
+const uint8_t _I_DinoRun1_0[] = {0x01,0x00,0x3b,0x00,0x80,0x7e,0x20,0xf0,0x0f,0xe4,0x3e,0x01,0xec,0x01,0x08,0x14,0x80,0x4b,0x7c,0x0a,0x0f,0xf2,0x07,0x01,0x9f,0x40,0x30,0x33,0xf8,0x07,0x0f,0xff,0x00,0xf3,0xef,0xe0,0x1f,0xf0,0x40,0x80,0x8b,0xfd,0x1f,0x0b,0x08,0x08,0x7f,0x01,0xf1,0xf8,0x0c,0x46,0xc1,0x06,0x80,0x70,0x20,0x82,0x61,0x01,0x14,0x32,0x00,};
+const uint8_t* const _I_DinoRun1[] = {_I_DinoRun1_0};
+
+const Icon I_Dino = {.width=20,.height=22,.frame_count=1,.frame_rate=0,.frames=_I_Dino};
+const Icon I_DinoRun0 = {.width=20,.height=22,.frame_count=1,.frame_rate=0,.frames=_I_DinoRun0};
+const Icon I_DinoRun1 = {.width=20,.height=22,.frame_count=1,.frame_rate=0,.frames=_I_DinoRun1};
 

+ 3 - 1
assets_icons.h

@@ -2,4 +2,6 @@
 
 #include <gui/icon.h>
 
-extern const Icon I_dino;
+extern const Icon I_Dino;
+extern const Icon I_DinoRun0;
+extern const Icon I_DinoRun1;

+ 56 - 13
trexrunner.c

@@ -6,6 +6,9 @@
 
 #include "assets_icons.h"
 
+#define DINO_START_X 0
+#define DINO_START_Y 42
+
 typedef enum {
     EventTypeTick,
     EventTypeKey,
@@ -16,6 +19,26 @@ typedef struct {
     InputEvent input;
 } PluginEvent;
 
+typedef struct {
+  FuriTimer* timer;
+  int dino_run_step;
+} GameState;
+
+static void timer_callback(void* ctx) {
+  GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25);
+  if (game_state == NULL) {
+    return;
+  }
+
+  if (game_state->dino_run_step == 0) {
+    game_state->dino_run_step = 1;
+  } else {
+    game_state->dino_run_step = 0;
+  }
+
+  release_mutex((ValueMutex*)ctx, game_state);
+}
+
 static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
     furi_assert(event_queue);
 
@@ -24,10 +47,24 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
 }
 
 static void render_callback(Canvas* const canvas, void* ctx) {
-  UNUSED(ctx);
+  const GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25);
+  if (game_state == NULL) {
+    return;
+  }
 
 //  canvas_draw_xbm(canvas, 0, 0, dino_width, dino_height, dino_bits);
-  canvas_draw_icon(canvas, 0, 0, &I_dino);
+//  canvas_draw_icon(canvas, 0, 0, &I_dino);
+  if (game_state->dino_run_step == 0) {
+    canvas_draw_icon(canvas, DINO_START_X, DINO_START_Y, &I_DinoRun0);
+  } else {
+    canvas_draw_icon(canvas, DINO_START_X, DINO_START_Y, &I_DinoRun1);
+  }
+
+  release_mutex((ValueMutex*)ctx, game_state);
+}
+
+static void game_state_init(GameState* const game_state) {
+  game_state->dino_run_step = 0;
 }
 
 int32_t trexrunner_app(void* p) {
@@ -35,18 +72,24 @@ int32_t trexrunner_app(void* p) {
 
   FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
 
-//  ValueMutex state_mutex;
-//  if (!init_mutex(&state_mutex, minesweeper_state, sizeof(minesweeper_state))) {
-//      FURI_LOG_E("t-rex runner", "cannot create mutex\r\n");
-//        free(minesweeper_state);
-//      return 255;
-//  }
+  GameState* game_state = malloc(sizeof(GameState));
+  game_state_init(game_state);
+
+  ValueMutex state_mutex;
+  if (!init_mutex(&state_mutex, game_state, sizeof(game_state))) {
+      FURI_LOG_E("T-rex runner", "cannot create mutex\r\n");
+        free(game_state);
+      return 255;
+  }
   // BEGIN IMPLEMENTATION
 
   // Set system callbacks
   ViewPort* view_port = view_port_alloc();
-  view_port_draw_callback_set(view_port, render_callback, view_port);
+  view_port_draw_callback_set(view_port, render_callback, &state_mutex);
   view_port_input_callback_set(view_port, input_callback, event_queue);
+  game_state->timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, &state_mutex);
+
+  furi_timer_start(game_state->timer, (uint32_t) furi_kernel_get_tick_frequency() * 0.4);
 
   // Open GUI and register view_port
   Gui* gui = furi_record_open("gui");
@@ -78,7 +121,7 @@ int32_t trexrunner_app(void* p) {
       ;
     }
     view_port_update(view_port);
-//    release_mutex(&state_mutex, minesweeper_state);
+    release_mutex(&state_mutex, game_state);
   }
 
   view_port_enabled_set(view_port, false);
@@ -86,9 +129,9 @@ int32_t trexrunner_app(void* p) {
   furi_record_close("gui");
   view_port_free(view_port);
   furi_message_queue_free(event_queue);
-//  delete_mutex(&state_mutex);
-//  furi_timer_free(minesweeper_state->timer);
-//  free(minesweeper_state);
+  delete_mutex(&state_mutex);
+  furi_timer_free(game_state->timer);
+  free(game_state);
 
   return 0;
 }