Initial Demo OS
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
#include "apps.h"
|
||||
#include "os_gfx.h"
|
||||
#include "os_status.h"
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "esp_timer.h"
|
||||
|
||||
static uint8_t s_view_mode = 0;
|
||||
|
||||
static void clock_init(void)
|
||||
{
|
||||
s_view_mode = 0;
|
||||
}
|
||||
|
||||
static void clock_enter(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void clock_update(uint32_t delta_ms)
|
||||
{
|
||||
sys_status_t status;
|
||||
sys_status_get(&status);
|
||||
|
||||
sys_gfx_draw_status_bar(&status);
|
||||
|
||||
uint32_t sec = status.uptime_sec % 60;
|
||||
uint32_t min = (status.uptime_sec / 60) % 60;
|
||||
uint32_t hrs = (status.uptime_sec / 3600);
|
||||
|
||||
char time_str[16];
|
||||
char sub_str[20];
|
||||
|
||||
if (s_view_mode == 0) {
|
||||
snprintf(time_str, sizeof(time_str), "%02lu:%02lu:%02lu", (unsigned long)hrs, (unsigned long)min, (unsigned long)sec);
|
||||
sys_gfx_draw_str_5x7(12, 11, time_str, COLOR_WHITE);
|
||||
|
||||
snprintf(sub_str, sizeof(sub_str), "RAM:%luK", (unsigned long)(status.free_heap / 1024));
|
||||
sys_gfx_draw_str_3x5(4, 21, sub_str, COLOR_WHITE);
|
||||
|
||||
snprintf(sub_str, sizeof(sub_str), "CPU:160M");
|
||||
sys_gfx_draw_str_3x5(40, 21, sub_str, COLOR_WHITE);
|
||||
|
||||
sys_gfx_draw_progress_bar(4, 27, 64, 4, (uint8_t)((sec * 100) / 59));
|
||||
sys_gfx_draw_action_bar("C:MODE", "H:HOME");
|
||||
} else if (s_view_mode == 1) {
|
||||
snprintf(time_str, sizeof(time_str), "%02lu:%02lu", (unsigned long)min, (unsigned long)sec);
|
||||
sys_gfx_draw_str_5x7(18, 14, time_str, COLOR_WHITE);
|
||||
sys_gfx_draw_str_5x7(19, 14, time_str, COLOR_WHITE);
|
||||
|
||||
snprintf(sub_str, sizeof(sub_str), "UP:%luh %lum", (unsigned long)hrs, (unsigned long)min);
|
||||
sys_gfx_draw_str_3x5(12, 24, sub_str, COLOR_WHITE);
|
||||
sys_gfx_draw_action_bar("C:MODE", "H:HOME");
|
||||
} else {
|
||||
snprintf(sub_str, sizeof(sub_str), "UP:%02lu:%02lu:%02lu", (unsigned long)hrs, (unsigned long)min, (unsigned long)sec);
|
||||
sys_gfx_draw_str_3x5(3, 10, sub_str, COLOR_WHITE);
|
||||
|
||||
snprintf(sub_str, sizeof(sub_str), "HEAP:%lu B", (unsigned long)status.free_heap);
|
||||
sys_gfx_draw_str_3x5(3, 17, sub_str, COLOR_WHITE);
|
||||
|
||||
snprintf(sub_str, sizeof(sub_str), "MINH:%lu B", (unsigned long)status.min_free_heap);
|
||||
sys_gfx_draw_str_3x5(3, 24, sub_str, COLOR_WHITE);
|
||||
|
||||
sys_gfx_draw_action_bar("C:MODE", "H:HOME");
|
||||
}
|
||||
}
|
||||
|
||||
static void clock_handle_input(input_action_t action)
|
||||
{
|
||||
if (action == INPUT_ACTION_CLICK) {
|
||||
s_view_mode = (s_view_mode + 1) % 3;
|
||||
} else if (action == INPUT_ACTION_LONG_PRESS) {
|
||||
sys_gfx_show_toast("Mode Saved", 600);
|
||||
}
|
||||
}
|
||||
|
||||
static void clock_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
const sys_app_t g_app_clock = {
|
||||
.id = "clock",
|
||||
.name = "Clock",
|
||||
.init = clock_init,
|
||||
.enter = clock_enter,
|
||||
.update = clock_update,
|
||||
.handle_input = clock_handle_input,
|
||||
.exit = clock_exit,
|
||||
};
|
||||
@@ -0,0 +1,137 @@
|
||||
#include "apps.h"
|
||||
#include "os_gfx.h"
|
||||
#include "os_status.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define GROUND_Y 34
|
||||
|
||||
typedef enum {
|
||||
GAME_STATE_READY,
|
||||
GAME_STATE_PLAYING,
|
||||
GAME_STATE_OVER
|
||||
} game_state_t;
|
||||
|
||||
static game_state_t s_game_state = GAME_STATE_READY;
|
||||
static int16_t s_player_y = GROUND_Y;
|
||||
static int16_t s_player_vy = 0;
|
||||
static bool s_is_jumping = false;
|
||||
|
||||
static int16_t s_obs_x = 72;
|
||||
static int16_t s_obs_h = 6;
|
||||
static uint16_t s_score = 0;
|
||||
static uint16_t s_high_score = 0;
|
||||
|
||||
static void game_reset(void)
|
||||
{
|
||||
s_player_y = GROUND_Y;
|
||||
s_player_vy = 0;
|
||||
s_is_jumping = false;
|
||||
s_obs_x = 72;
|
||||
s_obs_h = 5 + (rand() % 4);
|
||||
s_score = 0;
|
||||
}
|
||||
|
||||
static void game_init(void)
|
||||
{
|
||||
s_game_state = GAME_STATE_READY;
|
||||
s_high_score = 0;
|
||||
game_reset();
|
||||
}
|
||||
|
||||
static void game_enter(void)
|
||||
{
|
||||
s_game_state = GAME_STATE_READY;
|
||||
game_reset();
|
||||
}
|
||||
|
||||
static void game_update(uint32_t delta_ms)
|
||||
{
|
||||
sys_gfx_draw_line(0, GROUND_Y + 1, OLED_WIDTH - 1, GROUND_Y + 1, COLOR_WHITE);
|
||||
|
||||
if (s_game_state == GAME_STATE_READY) {
|
||||
sys_gfx_draw_str_5x7(10, 8, "TINY JUMP", COLOR_WHITE);
|
||||
sys_gfx_draw_str_3x5(8, 20, "CLICK TO START", COLOR_WHITE);
|
||||
sys_gfx_draw_action_bar("C:JUMP", "H:HOME");
|
||||
sys_gfx_fill_rect(8, GROUND_Y - 5, 5, 5, COLOR_WHITE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_game_state == GAME_STATE_PLAYING) {
|
||||
if (s_is_jumping) {
|
||||
s_player_y += s_player_vy;
|
||||
s_player_vy += 1;
|
||||
if (s_player_y >= GROUND_Y) {
|
||||
s_player_y = GROUND_Y;
|
||||
s_player_vy = 0;
|
||||
s_is_jumping = false;
|
||||
}
|
||||
}
|
||||
|
||||
s_obs_x -= 3;
|
||||
if (s_obs_x < -4) {
|
||||
s_obs_x = 72 + (rand() % 16);
|
||||
s_obs_h = 5 + (rand() % 5);
|
||||
s_score++;
|
||||
if (s_score > s_high_score) s_high_score = s_score;
|
||||
}
|
||||
|
||||
if (s_obs_x <= 13 && (s_obs_x + 3) >= 8) {
|
||||
if ((s_player_y - 1) >= (GROUND_Y - s_obs_h + 1)) {
|
||||
s_game_state = GAME_STATE_OVER;
|
||||
sys_gfx_show_toast("GAME OVER", 800);
|
||||
}
|
||||
}
|
||||
|
||||
sys_gfx_fill_rect(8, s_player_y - 5, 5, 5, COLOR_WHITE);
|
||||
sys_gfx_fill_rect(s_obs_x, GROUND_Y - s_obs_h + 1, 3, s_obs_h, COLOR_WHITE);
|
||||
|
||||
char score_str[12];
|
||||
snprintf(score_str, sizeof(score_str), "SC:%u", s_score);
|
||||
sys_gfx_draw_str_3x5(45, 1, score_str, COLOR_WHITE);
|
||||
|
||||
} else if (s_game_state == GAME_STATE_OVER) {
|
||||
sys_gfx_draw_str_5x7(12, 6, "GAME OVER", COLOR_WHITE);
|
||||
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "SCORE: %u", s_score);
|
||||
sys_gfx_draw_str_3x5(16, 17, buf, COLOR_WHITE);
|
||||
|
||||
snprintf(buf, sizeof(buf), "BEST: %u", s_high_score);
|
||||
sys_gfx_draw_str_3x5(16, 24, buf, COLOR_WHITE);
|
||||
|
||||
sys_gfx_draw_action_bar("C:RESTART", "H:HOME");
|
||||
}
|
||||
}
|
||||
|
||||
static void game_handle_input(input_action_t action)
|
||||
{
|
||||
if (action == INPUT_ACTION_CLICK) {
|
||||
if (s_game_state == GAME_STATE_READY) {
|
||||
s_game_state = GAME_STATE_PLAYING;
|
||||
game_reset();
|
||||
} else if (s_game_state == GAME_STATE_PLAYING) {
|
||||
if (!s_is_jumping) {
|
||||
s_is_jumping = true;
|
||||
s_player_vy = -5;
|
||||
}
|
||||
} else if (s_game_state == GAME_STATE_OVER) {
|
||||
s_game_state = GAME_STATE_PLAYING;
|
||||
game_reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void game_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
const sys_app_t g_app_game = {
|
||||
.id = "game",
|
||||
.name = "Tiny Jump",
|
||||
.init = game_init,
|
||||
.enter = game_enter,
|
||||
.update = game_update,
|
||||
.handle_input = game_handle_input,
|
||||
.exit = game_exit,
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "apps.h"
|
||||
#include "os_gfx.h"
|
||||
#include "os_status.h"
|
||||
#include "os_oled.h"
|
||||
#include <stdio.h>
|
||||
#include "esp_system.h"
|
||||
|
||||
#define SETTINGS_COUNT 4
|
||||
static const char *s_menu_items[SETTINGS_COUNT] = {
|
||||
"Contrast",
|
||||
"Invert",
|
||||
"Status Bar",
|
||||
"Reboot"
|
||||
};
|
||||
|
||||
static size_t s_selected_idx = 0;
|
||||
static uint8_t s_contrast_level = 3;
|
||||
static bool s_inverted = false;
|
||||
|
||||
static void apply_contrast(void)
|
||||
{
|
||||
uint8_t val = 255;
|
||||
if (s_contrast_level == 0) val = 30;
|
||||
else if (s_contrast_level == 1) val = 100;
|
||||
else if (s_contrast_level == 2) val = 180;
|
||||
oled_driver_set_contrast(val);
|
||||
}
|
||||
|
||||
static void settings_init(void)
|
||||
{
|
||||
s_selected_idx = 0;
|
||||
s_contrast_level = 3;
|
||||
s_inverted = false;
|
||||
}
|
||||
|
||||
static void settings_enter(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void settings_update(uint32_t delta_ms)
|
||||
{
|
||||
sys_status_t status;
|
||||
sys_status_get(&status);
|
||||
sys_gfx_draw_status_bar(&status);
|
||||
|
||||
sys_gfx_draw_menu(9, s_menu_items, SETTINGS_COUNT, s_selected_idx);
|
||||
sys_gfx_draw_action_bar("C:NEXT", "H:TOGGLE");
|
||||
}
|
||||
|
||||
static void settings_handle_input(input_action_t action)
|
||||
{
|
||||
if (action == INPUT_ACTION_CLICK) {
|
||||
s_selected_idx = (s_selected_idx + 1) % SETTINGS_COUNT;
|
||||
} else if (action == INPUT_ACTION_DOUBLE_CLICK) {
|
||||
if (s_selected_idx == 0) s_selected_idx = SETTINGS_COUNT - 1;
|
||||
else s_selected_idx--;
|
||||
} else if (action == INPUT_ACTION_LONG_PRESS) {
|
||||
switch (s_selected_idx) {
|
||||
case 0:
|
||||
s_contrast_level = (s_contrast_level + 1) % 4;
|
||||
apply_contrast();
|
||||
sys_gfx_show_toast("Contrast Chg", 600);
|
||||
break;
|
||||
case 1:
|
||||
s_inverted = !s_inverted;
|
||||
oled_driver_set_invert(s_inverted);
|
||||
sys_gfx_show_toast(s_inverted ? "Inverted" : "Normal", 600);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
bool vis = sys_status_is_status_bar_visible();
|
||||
sys_status_set_status_bar_visible(!vis);
|
||||
sys_gfx_show_toast(!vis ? "Bar: ON" : "Bar: OFF", 600);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
sys_gfx_show_toast("Rebooting...", 1000);
|
||||
sys_gfx_flush();
|
||||
esp_restart();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void settings_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
const sys_app_t g_app_settings = {
|
||||
.id = "settings",
|
||||
.name = "Settings",
|
||||
.init = settings_init,
|
||||
.enter = settings_enter,
|
||||
.update = settings_update,
|
||||
.handle_input = settings_handle_input,
|
||||
.exit = settings_exit,
|
||||
};
|
||||
@@ -0,0 +1,96 @@
|
||||
#include "apps.h"
|
||||
#include "os_gfx.h"
|
||||
#include "os_status.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_system.h"
|
||||
#include "esp_chip_info.h"
|
||||
#include "esp_flash.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#define HISTORY_LEN 40
|
||||
static uint8_t s_heap_history[HISTORY_LEN] = {0};
|
||||
static size_t s_history_count = 0;
|
||||
static uint8_t s_view = 0;
|
||||
|
||||
static void sysmon_init(void)
|
||||
{
|
||||
s_history_count = 0;
|
||||
memset(s_heap_history, 50, sizeof(s_heap_history));
|
||||
}
|
||||
|
||||
static void sysmon_enter(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void sysmon_update(uint32_t delta_ms)
|
||||
{
|
||||
sys_status_t status;
|
||||
sys_status_get(&status);
|
||||
sys_gfx_draw_status_bar(&status);
|
||||
|
||||
static uint32_t sample_timer = 0;
|
||||
sample_timer += delta_ms;
|
||||
if (sample_timer >= 200) {
|
||||
sample_timer = 0;
|
||||
uint32_t kb = status.free_heap / 1024;
|
||||
uint8_t norm_val = (kb > 300) ? 100 : (uint8_t)((kb * 100) / 300);
|
||||
|
||||
if (s_history_count < HISTORY_LEN) {
|
||||
s_heap_history[s_history_count++] = norm_val;
|
||||
} else {
|
||||
memmove(&s_heap_history[0], &s_heap_history[1], HISTORY_LEN - 1);
|
||||
s_heap_history[HISTORY_LEN - 1] = norm_val;
|
||||
}
|
||||
}
|
||||
|
||||
char buf[24];
|
||||
|
||||
if (s_view == 0) {
|
||||
snprintf(buf, sizeof(buf), "RAM:%luK", (unsigned long)(status.free_heap / 1024));
|
||||
sys_gfx_draw_str_3x5(3, 9, buf, COLOR_WHITE);
|
||||
|
||||
snprintf(buf, sizeof(buf), "TASKS:%u", (unsigned int)uxTaskGetNumberOfTasks());
|
||||
sys_gfx_draw_str_3x5(40, 9, buf, COLOR_WHITE);
|
||||
|
||||
sys_gfx_draw_sparkline(3, 16, 66, 14, s_heap_history, s_history_count, 100);
|
||||
sys_gfx_draw_action_bar("C:VIEW", "H:HOME");
|
||||
} else {
|
||||
esp_chip_info_t chip;
|
||||
esp_chip_info(&chip);
|
||||
uint32_t flash_size = 0;
|
||||
esp_flash_get_size(NULL, &flash_size);
|
||||
|
||||
sys_gfx_draw_str_3x5(3, 9, "ESP32-C3 RISC-V", COLOR_WHITE);
|
||||
|
||||
snprintf(buf, sizeof(buf), "REV:%d CORES:%d", chip.revision, chip.cores);
|
||||
sys_gfx_draw_str_3x5(3, 16, buf, COLOR_WHITE);
|
||||
|
||||
snprintf(buf, sizeof(buf), "FLASH:%lu MB", (unsigned long)(flash_size / (1024 * 1024)));
|
||||
sys_gfx_draw_str_3x5(3, 23, buf, COLOR_WHITE);
|
||||
|
||||
sys_gfx_draw_action_bar("C:VIEW", "H:HOME");
|
||||
}
|
||||
}
|
||||
|
||||
static void sysmon_handle_input(input_action_t action)
|
||||
{
|
||||
if (action == INPUT_ACTION_CLICK) {
|
||||
s_view = (s_view + 1) % 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void sysmon_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
const sys_app_t g_app_sysmon = {
|
||||
.id = "sysmon",
|
||||
.name = "Sys Monitor",
|
||||
.init = sysmon_init,
|
||||
.enter = sysmon_enter,
|
||||
.update = sysmon_update,
|
||||
.handle_input = sysmon_handle_input,
|
||||
.exit = sysmon_exit,
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef APPS_H
|
||||
#define APPS_H
|
||||
|
||||
#include "os_app.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const sys_app_t g_app_clock;
|
||||
extern const sys_app_t g_app_sysmon;
|
||||
extern const sys_app_t g_app_settings;
|
||||
extern const sys_app_t g_app_game;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // APPS_H
|
||||
Reference in New Issue
Block a user