Skip to content

Commit

Permalink
Latest RM1120-2148-0.420.0-3428098 on PATREON - UPD pinball0
Browse files Browse the repository at this point in the history
  • Loading branch information
RogueMaster committed Nov 21, 2024
2 parents 44d09f8 + 66e5cca commit b62c96d
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 33 deletions.
2 changes: 1 addition & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ This software is for experimental purposes only and is not meant for any illegal

- Last Synced/Checked OFW, changes in [commits](https://github.com/flipperdevices/flipperzero-firmware/commits/dev): `2024-11-20 21:48 EST`
- Last Synced/Checked Unleashed, changes in [changelog](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/blob/420/CHANGELOG.md): `2024-11-20 21:48 EST`
- Updated: [Pinball0 v0.2 (By rdefeo)](https://github.com/rdefeo/pinball0)
- Updated: [CANBUS v1.1.4 (By ElectronicCats)](https://github.com/ElectronicCats/flipper-MCP2515-CANBUS)
- Updated: [Pinball0 v0.2 (By rdefeo)](https://github.com/rdefeo/pinball0)
- Coming Soon: OFW: [Storage: remove LFS #3577](https://github.com/flipperdevices/flipperzero-firmware/pull/3577) [FuriEventLoop Pt.2 #3703](https://github.com/flipperdevices/flipperzero-firmware/pull/3703) [#3824](https://github.com/flipperdevices/flipperzero-firmware/pull/3824) [#3836](https://github.com/flipperdevices/flipperzero-firmware/pull/3836) [#3834](https://github.com/flipperdevices/flipperzero-firmware/pull/3834) [#3830](https://github.com/flipperdevices/flipperzero-firmware/pull/3834) [#3837](https://github.com/flipperdevices/flipperzero-firmware/pull/3837) [#3849](https://github.com/flipperdevices/flipperzero-firmware/pull/3849) [#3852](https://github.com/flipperdevices/flipperzero-firmware/pull/3852) [#3879](https://github.com/flipperdevices/flipperzero-firmware/pull/3879) [#3875](https://github.com/flipperdevices/flipperzero-firmware/pull/3875) [#3859](https://github.com/flipperdevices/flipperzero-firmware/pull/3859) [#3863](https://github.com/flipperdevices/flipperzero-firmware/pull/3863) [#3866](https://github.com/flipperdevices/flipperzero-firmware/pull/3866) [#3865](https://github.com/flipperdevices/flipperzero-firmware/pull/3865) [#3887](https://github.com/flipperdevices/flipperzero-firmware/pull/3887) [#3892](https://github.com/flipperdevices/flipperzero-firmware/pull/3892) [#3909](https://github.com/flipperdevices/flipperzero-firmware/pull/3909) [#3881](https://github.com/flipperdevices/flipperzero-firmware/pull/3881) [#3942](https://github.com/flipperdevices/flipperzero-firmware/pull/3942) [#3841](https://github.com/flipperdevices/flipperzero-firmware/pull/3841) [#3950](https://github.com/flipperdevices/flipperzero-firmware/pull/3950) [#3952](https://github.com/flipperdevices/flipperzero-firmware/pull/3952) [#3958](https://github.com/flipperdevices/flipperzero-firmware/pull/3958) [#3963](https://github.com/flipperdevices/flipperzero-firmware/pull/3963) [#3971](https://github.com/flipperdevices/flipperzero-firmware/pull/3971) [#3961](https://github.com/flipperdevices/flipperzero-firmware/pull/3961) [#3906](https://github.com/flipperdevices/flipperzero-firmware/pull/3906) [#3978](https://github.com/flipperdevices/flipperzero-firmware/pull/3978) [#3980](https://github.com/flipperdevices/flipperzero-firmware/pull/3980)

<a name="release">
Expand Down
12 changes: 9 additions & 3 deletions applications/external/pinball0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This is a BETA release!! Still a work in progress...
* Rollover items
* Sounds! Blinky lights! Annoying vibrations!
* Customizable notification settings: sound, LED, vibration
* Idle timeout to save battery - will exit after ~120 seconds of no key-presses

## Controls
* **Ok** to release the ball
Expand All @@ -34,17 +35,22 @@ I find it easiest to hold the flipper with both hands so I can hit left/right wi
## Settings
The **SETTINGS** menu will be the "last" table listed. You can Enable / Disable the following: Sound, LED light, Vibration, and Manual mode. Move Up/Down to select your setting and press **OK** to toggle. Settings are saved in `/data/.pinball0.conf` as a native Flipper Format file. **Back** will return you to the main menu.

**Manual** mode allows you to move the ball using the directional pad _before_ the ball is launched. This is useful for testing and may be removed in the future. May result in unexpected behavior.
**Debug** mode allows you to move the ball using the directional pad _before_ the ball is launched. This is useful for testing and may be removed in the future. May result in unexpected behavior. It also displays test tables on the main menu. The test tables will only show/hide after you exit and restart the app. This feature is mainly for me - lol.

## Tables
Pinball0 ships with several default tables. These tables are automatically deployed into the assets folder (`/apps_data/pinball0`). Tables are simple JSON which means you can define your own! Your tables should be stored in the data folder (`/apps_data/pinball0`). **The default tables may change over time.**
Pinball0 ships with several default tables. These tables are automatically deployed into the assets folder (`/apps_data/pinball0`) on your SD card. Tables are simple JSON which means you can define your own! Your tables should be stored in the data folder (`/apps_data/pinball0`). On the main menu, tables are sorted alphabetically. In order to "force" a sorting order, you can prepend any filename with `NN_` where `NN` is between `00` and `99`. When the files are displayed on the menu, if they start with `NN_`, that will be stripped - but their sorted order will be preserved.

> The default tables may change over time.
In **Debug** mode, test tables will be shown. A test table is one that begins with the text `dbg`. Given that you can prefix table names for sorting purposes, here are two valid table filenames for a test table called `my FLIPS`: `dbg my FLIPS.json` and `04_dbg my FLIPS.json`. In both cases it will be displayed as `dbg my FLIPS` on the menu. I doubt that you will use this feature, but I'm documenting it anyway.


### File Format
Table units are specified at a 10x scale. This means our table is **630 x 1270** in size (as the F0 display is 64 pixels x 128 pixels). Our origin is in the top-left at 0, 0. Check out the default tables in the `assets/tables` folder for example usage.

The JSON can include comments - because why not!

> **DISCLAIMER:** The file format may change from release to release. Sorry. There is some basic error checking when reading / parsing the table files. If the error is serious enough, you will see an error message in the app. Otherwise, check the console logs. For those familiar with `ufbt`, simply run `ufbt cli` and issue the `log` command. Then launch Pinball0. All informational and higher logs will be displayed.
> **DISCLAIMER:** The file format may change from release to release. Sorry. There is some basic error checking when reading / parsing the table files. If the error is serious enough, you will see an error message in the app. Otherwise, check the console logs. For those familiar with `ufbt`, simply run `ufbt cli` and issue the `log` command. Then launch Pinball0. All informational and higher logs will be displayed. These logs are useful when reporting bugs/issues!
#### lives : object (optional)
Defines how many lives/balls you start with, and display information
Expand Down
49 changes: 31 additions & 18 deletions applications/external/pinball0/pinball0.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
#define GRAVITY 3.0f // 9.8f
#define PHYSICS_SUB_STEPS 5
#define GAME_FPS 30
#define TABLE_BUMP_AMOUNT 0.3l

#define MANUAL_ADJUSTMENT 20
#define IDLE_TIMEOUT 120 * 1000 // 120 seconds * 1000 ticks/sec

#define PINBALL_SETTINGS_FILENAME ".pinball0.conf"
#define PINBALL_SETTINGS_PATH APP_DATA_PATH(PINBALL_SETTINGS_FILENAME)
#define PINBALL_SETTINGS_FILE_TYPE "Pinball0 Settings File"
#define PINBALL_SETTINGS_FILE_VERSION 1

namespace {
uint32_t idle_start;

void pinball_load_settings(PinballApp* pb) {
FlipperFormat* fff_settings = flipper_format_file_alloc(pb->storage);
FuriString* tmp_str = furi_string_alloc();
Expand All @@ -33,7 +35,7 @@ void pinball_load_settings(PinballApp* pb) {
pb->settings.sound_enabled = true;
pb->settings.led_enabled = true;
pb->settings.vibrate_enabled = true;
pb->settings.manual_mode = false;
pb->settings.debug_mode = false;
pb->selected_setting = 0;
pb->max_settings = 4;

Expand Down Expand Up @@ -61,8 +63,8 @@ void pinball_load_settings(PinballApp* pb) {
if(flipper_format_read_uint32(fff_settings, "Vibrate", &tmp_data32, 1)) {
pb->settings.vibrate_enabled = (tmp_data32 == 0) ? false : true;
}
if(flipper_format_read_uint32(fff_settings, "Manual", &tmp_data32, 1)) {
pb->settings.manual_mode = (tmp_data32 == 0) ? false : true;
if(flipper_format_read_uint32(fff_settings, "Debug", &tmp_data32, 1)) {
pb->settings.debug_mode = (tmp_data32 == 0) ? false : true;
}

} while(false);
Expand Down Expand Up @@ -101,16 +103,17 @@ void pinball_save_settings(PinballApp* pb) {
FURI_LOG_E(TAG, "SETTINGS: Failed to write 'Vibrate'");
break;
}
tmp_data32 = pb->settings.manual_mode ? 1 : 0;
if(!flipper_format_write_uint32(fff_settings, "Manual", &tmp_data32, 1)) {
FURI_LOG_E(TAG, "SETTINGS: Failed to write 'Manual'");
tmp_data32 = pb->settings.debug_mode ? 1 : 0;
if(!flipper_format_write_uint32(fff_settings, "Debug", &tmp_data32, 1)) {
FURI_LOG_E(TAG, "SETTINGS: Failed to write 'Debug'");
break;
}
} while(false);

flipper_format_file_close(fff_settings);
flipper_format_free(fff_settings);
}
};

void solve(PinballApp* pb, float dt) {
Table* table = pb->table;
Expand All @@ -126,7 +129,6 @@ void solve(PinballApp* pb, float dt) {
}
for(auto& b : table->balls) {
// We multiply GRAVITY by dt since gravity is based on seconds
FURI_LOG_I(TAG, "GRAVI-TAYYY");
b.accelerate(Vec2(0, GRAVITY * bump_amt * sub_dt));
}
}
Expand Down Expand Up @@ -384,9 +386,9 @@ static void pinball_draw_callback(Canvas* const canvas, void* ctx) {
}
y += 12;

canvas_draw_str_aligned(canvas, 10, y, AlignLeft, AlignTop, "Manual");
canvas_draw_str_aligned(canvas, 10, y, AlignLeft, AlignTop, "Debug");
canvas_draw_circle(canvas, x, y + 3, 4);
if(pb->settings.manual_mode) {
if(pb->settings.debug_mode) {
canvas_draw_disc(canvas, x, y + 3, 2);
}
if(pb->selected_setting == 3) {
Expand Down Expand Up @@ -461,6 +463,7 @@ extern "C" int32_t pinball0_app(void* p) {

float dt = 0.0f;
uint32_t last_frame_time = furi_get_tick();
idle_start = last_frame_time;

FURI_LOG_I(TAG, "Starting event loop");
PinballEvent event;
Expand Down Expand Up @@ -489,7 +492,7 @@ extern "C" int32_t pinball0_app(void* p) {
case InputKeyRight: {
app->keys[InputKeyRight] = true;

if(app->settings.manual_mode && app->table->balls_released == false) {
if(app->settings.debug_mode && app->table->balls_released == false) {
app->table->balls[0].p.x += MANUAL_ADJUSTMENT;
app->table->balls[0].prev_p.x += MANUAL_ADJUSTMENT;
}
Expand All @@ -507,7 +510,7 @@ extern "C" int32_t pinball0_app(void* p) {
case InputKeyLeft: {
app->keys[InputKeyLeft] = true;

if(app->settings.manual_mode && app->table->balls_released == false) {
if(app->settings.debug_mode && app->table->balls_released == false) {
app->table->balls[0].p.x -= MANUAL_ADJUSTMENT;
app->table->balls[0].prev_p.x -= MANUAL_ADJUSTMENT;
}
Expand All @@ -531,9 +534,10 @@ extern "C" int32_t pinball0_app(void* p) {
// we only set the key if it's a 'press' to ensure
// a single table "bump"
app->keys[InputKeyUp] = true;

notify_table_bump(app);
}
if(app->settings.manual_mode && app->table->balls_released == false) {
if(app->settings.debug_mode && app->table->balls_released == false) {
app->table->balls[0].p.y -= MANUAL_ADJUSTMENT;
app->table->balls[0].prev_p.y -= MANUAL_ADJUSTMENT;
}
Expand All @@ -556,7 +560,7 @@ extern "C" int32_t pinball0_app(void* p) {
switch(app->game_mode) {
case GM_Playing:
app->keys[InputKeyDown] = true;
if(app->settings.manual_mode && app->table->balls_released == false) {
if(app->settings.debug_mode && app->table->balls_released == false) {
app->table->balls[0].p.y += MANUAL_ADJUSTMENT;
app->table->balls[0].prev_p.y += MANUAL_ADJUSTMENT;
}
Expand Down Expand Up @@ -610,7 +614,7 @@ extern "C" int32_t pinball0_app(void* p) {
app->settings.vibrate_enabled = !app->settings.vibrate_enabled;
break;
case 3:
app->settings.manual_mode = !app->settings.manual_mode;
app->settings.debug_mode = !app->settings.debug_mode;
break;
default:
break;
Expand Down Expand Up @@ -654,6 +658,8 @@ extern "C" int32_t pinball0_app(void* p) {
break;
}
}
// a key was pressed, reset idle counter
idle_start = furi_get_tick();
}
}
solve(app, dt);
Expand All @@ -672,8 +678,15 @@ extern "C" int32_t pinball0_app(void* p) {
view_port_update(view_port);
furi_mutex_release(app->mutex);

// game timing
uint32_t time_lapsed = furi_get_tick() - last_frame_time;
// game timing + idle check
uint32_t current_tick = furi_get_tick();
if(current_tick - idle_start >= IDLE_TIMEOUT) {
FURI_LOG_W(TAG, "Idle timeout! Exiting Pinball0...");
app->processing = false;
break;
}

uint32_t time_lapsed = current_tick - last_frame_time;
dt = time_lapsed / 1000.0f;
while(dt < 1.0f / GAME_FPS) {
time_lapsed = furi_get_tick() - last_frame_time;
Expand Down
4 changes: 3 additions & 1 deletion applications/external/pinball0/pinball0.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ typedef struct PinballApp {
bool sound_enabled;
bool vibrate_enabled;
bool led_enabled;
bool manual_mode;
bool debug_mode;
} settings;
int selected_setting;
int max_settings;

uint32_t idle_start; // tick count (time) of last key press

// system objects
Storage* storage;
NotificationApp* notify; // allows us to blink/buzz during game
Expand Down
41 changes: 31 additions & 10 deletions applications/external/pinball0/table.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ void table_table_list_init(void* ctx) {
// sort tables by original filename

const char* paths[] = {APP_ASSETS_PATH("tables"), APP_DATA_PATH("tables")};
const size_t ext_len_max = 32;
char ext[ext_len_max];

for(size_t p = 0; p < 2; p++) {
const char* path = paths[p];
Expand All @@ -92,25 +94,44 @@ void table_table_list_init(void* ctx) {
dir_walk_set_recursive(dir_walk, false);
if(dir_walk_open(dir_walk, path)) {
while(dir_walk_read(dir_walk, table_path, NULL) == DirWalkOK) {
FURI_LOG_I(TAG, furi_string_get_cstr(table_path));
// set display 'name' and 'filename'
TableMenuItem tmi;
path_extract_extension(table_path, ext, ext_len_max);
if(strcmp(ext, ".json") != 0) {
FURI_LOG_W(
TAG, "Skipping non-json file: %s", furi_string_get_cstr(table_path));
continue;
}
const char* cpath = furi_string_get_cstr(table_path);
tmi.filename = furi_string_alloc_set_str(cpath);

tmi.name = furi_string_alloc();
path_extract_filename_no_ext(cpath, tmi.name);
FuriString* filename_no_ext = furi_string_alloc();
path_extract_filename_no_ext(cpath, filename_no_ext);

// If filename starts with XX_ (for custom sorting) strip the prefix
char c = furi_string_get_char(tmi.name, 2);
char c = furi_string_get_char(filename_no_ext, 2);
if(c == '_') {
char a = furi_string_get_char(tmi.name, 0);
char b = furi_string_get_char(tmi.name, 1);
char a = furi_string_get_char(filename_no_ext, 0);
char b = furi_string_get_char(filename_no_ext, 1);
if(a >= '0' && a <= '9' && b >= '0' && b <= '9') {
furi_string_right(tmi.name, 3);
furi_string_right(filename_no_ext, 3);
}
}

if(!pb->settings.debug_mode &&
!strncmp("dbg", furi_string_get_cstr(filename_no_ext), 3)) {
furi_string_free(filename_no_ext);
continue;
}

FURI_LOG_I(
TAG,
"Found table: name=%s | path=%s",
furi_string_get_cstr(filename_no_ext),
furi_string_get_cstr(table_path));

// set display 'name' and 'filename'
TableMenuItem tmi;
tmi.filename = furi_string_alloc_set_str(cpath);
tmi.name = filename_no_ext;

// Insert in sorted order
size_t i = 0;
auto it = pb->table_list.menu_items.begin();
Expand Down

0 comments on commit b62c96d

Please sign in to comment.