Skip to content

Commit 4eb3ccf

Browse files
authored
Merge pull request #18 from jblanked/dev_0.6
FlipWorld - v0.6
2 parents 49a7cd2 + 2763fa7 commit 4eb3ccf

19 files changed

+904
-1278
lines changed

README.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,9 @@ NPCs are friendly characters that players can interact with. Currently, you can
8080

8181
**v0.6**
8282
- New game features
83-
- Custom Controller Support
8483

8584
**v0.7**
86-
- ???
85+
- New game features
8786

8887
**v0.8**
8988
- Multiplayer support

alloc/alloc.c

+17-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ void *global_app;
1616
void flip_world_show_submenu()
1717
{
1818
FlipWorldApp *app = (FlipWorldApp *)global_app;
19-
if (app->submenu) {
19+
if (app->submenu)
20+
{
2021
view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewSubmenu);
2122
}
2223
}
@@ -51,10 +52,17 @@ FlipWorldApp *flip_world_app_alloc()
5152
{
5253
return NULL;
5354
}
54-
submenu_add_item(app->submenu, "Play", FlipWorldSubmenuIndexRun, callback_submenu_choices, app);
55+
if (!easy_flipper_set_submenu(&app->submenu_game, FlipWorldViewGameSubmenu, "Play", callback_to_submenu, &app->view_dispatcher))
56+
{
57+
return NULL;
58+
}
59+
submenu_add_item(app->submenu, "Play", FlipWorldSubmenuIndexGameSubmenu, callback_submenu_choices, app);
5560
submenu_add_item(app->submenu, "About", FlipWorldSubmenuIndexMessage, callback_submenu_choices, app);
5661
submenu_add_item(app->submenu, "Settings", FlipWorldSubmenuIndexSettings, callback_submenu_choices, app);
5762
//
63+
submenu_add_item(app->submenu_game, "Story", FlipWorldSubmenuIndexStory, callback_submenu_choices, app);
64+
submenu_add_item(app->submenu_game, "PvP", FlipWorldSubmenuIndexPvP, callback_submenu_choices, app);
65+
submenu_add_item(app->submenu_game, "PvE", FlipWorldSubmenuIndexPvE, callback_submenu_choices, app);
5866

5967
// Switch to the main view
6068
view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewSubmenu);
@@ -77,6 +85,11 @@ void flip_world_app_free(FlipWorldApp *app)
7785
view_dispatcher_remove_view(app->view_dispatcher, FlipWorldViewSubmenu);
7886
submenu_free(app->submenu);
7987
}
88+
if (app->submenu_game)
89+
{
90+
view_dispatcher_remove_view(app->view_dispatcher, FlipWorldViewGameSubmenu);
91+
submenu_free(app->submenu_game);
92+
}
8093
// Free Widget(s)
8194
if (app->widget_result)
8295
{
@@ -101,5 +114,6 @@ void flip_world_app_free(FlipWorldApp *app)
101114
furi_record_close(RECORD_GUI);
102115

103116
// free the app
104-
if (app) free(app);
117+
if (app)
118+
free(app);
105119
}

app.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ int32_t flip_world_main(void *p)
2424
return -1;
2525
}
2626

27-
if (!flipper_http_ping(fhttp))
27+
if (!flipper_http_send_command(fhttp, HTTP_CMD_PING))
2828
{
2929
FURI_LOG_E(TAG, "Failed to ping the device");
3030
flipper_http_free(fhttp);

application.fam

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ App(
1717
),
1818
fap_author="JBlanked",
1919
fap_weburl="https://github.com/jblanked/FlipWorld",
20-
fap_version="0.5",
20+
fap_version="0.6",
2121
)

assets/01-home.png

-5 Bytes
Loading

assets/CHANGELOG.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
## 0.6 (2025-03-10)
2+
- Fixed saving of player attributes so that it works as intended.
3+
- Updated the player's level and strength as XP increases.
4+
- Started implementing multiplayer (requires FlipperHTTP v1.7).
5+
- Fixed the display of user stats when switching worlds.
6+
17
## 0.5 (2025-01-31)
28
- Fixed saving errors.
39
- Improved memory allocation.
410
- Added NPCs.
511

612
## 0.4 (2025-01-23)
713
- Added an In-Game menu.
8-
- Added New controls (HOLD OK to access the In-Game menu, PRESS BACK to exit the menu, and HOLD BACK to leave the game).
9-
- Added option to choose player weapon in the Game Settings.
14+
- Added new controls (HOLD OK to access the In-Game menu, PRESS BACK to exit the menu, and HOLD BACK to leave the game).
15+
- Added option to choose player's weapon in the Game Settings.
1016
- Added transition icon for switching worlds.
1117
- Doubled the size of each world (from 384x192 to 768x384).
1218
- Improved memory allocation.

assets/README.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,9 @@ NPCs are friendly characters that players can interact with. Currently, you can
7979

8080
**v0.6**
8181
- New game features
82-
- Custom Controller Support
8382

8483
**v0.7**
85-
- ???
84+
- New game features
8685

8786
**v0.8**
8887
- Multiplayer support

callback/callback.c

+56-43
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// FURI_LOG_DEV will log only during app development. Be sure that Settings/System/Log Device is "LPUART"; so we dont use serial port.
1212
#ifdef DEVELOPMENT
1313
#define FURI_LOG_DEV(tag, format, ...) furi_log_print_format(FuriLogLevelInfo, tag, format, ##__VA_ARGS__)
14-
#define DEV_CRASH() furi_crash()
14+
#define DEV_CRASH() furi_crash()
1515
#else
1616
#define FURI_LOG_DEV(tag, format, ...)
1717
#define DEV_CRASH()
@@ -430,7 +430,7 @@ static bool alloc_variable_item_list(void *context, uint32_t view_id)
430430
char _game_fps[8];
431431
if (load_char("Game-FPS", _game_fps, sizeof(_game_fps)))
432432
{
433-
int index = is_str(_game_fps, "30") ? 0 : is_str(_game_fps, "60") ? 1
433+
int index = is_str(_game_fps, "30") ? 0 : is_str(_game_fps, "60") ? 1
434434
: is_str(_game_fps, "120") ? 2
435435
: is_str(_game_fps, "240") ? 3
436436
: 0;
@@ -441,62 +441,63 @@ static bool alloc_variable_item_list(void *context, uint32_t view_id)
441441
if (load_char("Game-VGM-X", _game_vgm_x, sizeof(_game_vgm_x)))
442442
{
443443
int vgm_x = atoi(_game_vgm_x);
444-
int index = vgm_x == -2 ? 0 :
445-
vgm_x == -1 ? 1 :
446-
vgm_x == 0 ? 2 :
447-
vgm_x == 1 ? 3 :
448-
vgm_x == 2 ? 4 :
449-
vgm_x == 3 ? 5 :
450-
vgm_x == 4 ? 6 :
451-
vgm_x == 5 ? 7 :
452-
vgm_x == 6 ? 8 :
453-
vgm_x == 7 ? 9 :
454-
vgm_x == 8 ? 10 :
455-
vgm_x == 9 ? 11 :
456-
vgm_x == 10 ? 12 :
457-
2;
444+
int index = vgm_x == -2 ? 0 : vgm_x == -1 ? 1
445+
: vgm_x == 0 ? 2
446+
: vgm_x == 1 ? 3
447+
: vgm_x == 2 ? 4
448+
: vgm_x == 3 ? 5
449+
: vgm_x == 4 ? 6
450+
: vgm_x == 5 ? 7
451+
: vgm_x == 6 ? 8
452+
: vgm_x == 7 ? 9
453+
: vgm_x == 8 ? 10
454+
: vgm_x == 9 ? 11
455+
: vgm_x == 10 ? 12
456+
: 2;
458457
variable_item_set_current_value_index(app->variable_item_game_vgm_x, index);
459458
variable_item_set_current_value_text(app->variable_item_game_vgm_x, vgm_levels[index]);
460459
}
461460
char _game_vgm_y[8];
462461
if (load_char("Game-VGM-Y", _game_vgm_y, sizeof(_game_vgm_y)))
463462
{
464463
int vgm_y = atoi(_game_vgm_y);
465-
int index = vgm_y == -2 ? 0 :
466-
vgm_y == -1 ? 1 :
467-
vgm_y == 0 ? 2 :
468-
vgm_y == 1 ? 3 :
469-
vgm_y == 2 ? 4 :
470-
vgm_y == 3 ? 5 :
471-
vgm_y == 4 ? 6 :
472-
vgm_y == 5 ? 7 :
473-
vgm_y == 6 ? 8 :
474-
vgm_y == 7 ? 9 :
475-
vgm_y == 8 ? 10 :
476-
vgm_y == 9 ? 11 :
477-
vgm_y == 10 ? 12 :
478-
2;
464+
int index = vgm_y == -2 ? 0 : vgm_y == -1 ? 1
465+
: vgm_y == 0 ? 2
466+
: vgm_y == 1 ? 3
467+
: vgm_y == 2 ? 4
468+
: vgm_y == 3 ? 5
469+
: vgm_y == 4 ? 6
470+
: vgm_y == 5 ? 7
471+
: vgm_y == 6 ? 8
472+
: vgm_y == 7 ? 9
473+
: vgm_y == 8 ? 10
474+
: vgm_y == 9 ? 11
475+
: vgm_y == 10 ? 12
476+
: 2;
479477
variable_item_set_current_value_index(app->variable_item_game_vgm_y, index);
480478
variable_item_set_current_value_text(app->variable_item_game_vgm_y, vgm_levels[index]);
481479
}
482480
char _game_screen_always_on[8];
483481
if (load_char("Game-Screen-Always-On", _game_screen_always_on, sizeof(_game_screen_always_on)))
484482
{
485-
int index = is_str(_game_screen_always_on, "No") ? 0 : is_str(_game_screen_always_on, "Yes") ? 1 : 0;
483+
int index = is_str(_game_screen_always_on, "No") ? 0 : is_str(_game_screen_always_on, "Yes") ? 1
484+
: 0;
486485
variable_item_set_current_value_text(app->variable_item_game_screen_always_on, yes_or_no_choices[index]);
487486
variable_item_set_current_value_index(app->variable_item_game_screen_always_on, index);
488487
}
489488
char _game_sound_on[8];
490489
if (load_char("Game-Sound-On", _game_sound_on, sizeof(_game_sound_on)))
491490
{
492-
int index = is_str(_game_sound_on, "No") ? 0 : is_str(_game_sound_on, "Yes") ? 1 : 0;
491+
int index = is_str(_game_sound_on, "No") ? 0 : is_str(_game_sound_on, "Yes") ? 1
492+
: 0;
493493
variable_item_set_current_value_text(app->variable_item_game_sound_on, yes_or_no_choices[index]);
494494
variable_item_set_current_value_index(app->variable_item_game_sound_on, index);
495495
}
496496
char _game_vibration_on[8];
497497
if (load_char("Game-Vibration-On", _game_vibration_on, sizeof(_game_vibration_on)))
498498
{
499-
int index = is_str(_game_vibration_on, "No") ? 0 : is_str(_game_vibration_on, "Yes") ? 1 : 0;
499+
int index = is_str(_game_vibration_on, "No") ? 0 : is_str(_game_vibration_on, "Yes") ? 1
500+
: 0;
500501
variable_item_set_current_value_text(app->variable_item_game_vibration_on, yes_or_no_choices[index]);
501502
variable_item_set_current_value_index(app->variable_item_game_vibration_on, index);
502503
}
@@ -737,7 +738,8 @@ void free_all_views(void *context, bool should_free_variable_item_list, bool sho
737738
}
738739
}
739740

740-
if (should_free_submenu_settings) free_submenu_settings(app);
741+
if (should_free_submenu_settings)
742+
free_submenu_settings(app);
741743
}
742744
static bool fetch_world_list(FlipperHTTP *fhttp)
743745
{
@@ -760,7 +762,7 @@ static bool fetch_world_list(FlipperHTTP *fhttp)
760762
snprintf(fhttp->file_path, sizeof(fhttp->file_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/world_list.json");
761763

762764
fhttp->save_received_data = true;
763-
return flipper_http_get_request_with_headers(fhttp, "https://www.flipsocial.net/api/world/v5/list/10/", "{\"Content-Type\":\"application/json\"}");
765+
return flipper_http_request(fhttp, GET, "https://www.flipsocial.net/api/world/v5/list/10/", "{\"Content-Type\":\"application/json\"}", NULL);
764766
}
765767
// we will load the palyer stats from the API and save them
766768
// in player_spawn game method, it will load the player stats that we saved
@@ -795,7 +797,7 @@ static bool fetch_player_stats(FlipperHTTP *fhttp)
795797

796798
snprintf(fhttp->file_path, sizeof(fhttp->file_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/data/player/player_stats.json");
797799
fhttp->save_received_data = true;
798-
return flipper_http_get_request_with_headers(fhttp, url, "{\"Content-Type\":\"application/json\"}");
800+
return flipper_http_request(fhttp, GET, url, "{\"Content-Type\":\"application/json\"}", NULL);
799801
}
800802

801803
// static bool fetch_app_update(FlipperHTTP *fhttp)
@@ -919,7 +921,7 @@ static bool _fetch_game(DataLoaderModel *model)
919921
}
920922
char payload[256];
921923
snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"password\":\"%s\"}", username, password);
922-
return flipper_http_post_request_with_headers(model->fhttp, "https://www.flipsocial.net/api/user/login/", "{\"Content-Type\":\"application/json\"}", payload);
924+
return flipper_http_request(model->fhttp, POST, "https://www.flipsocial.net/api/user/login/", "{\"Content-Type\":\"application/json\"}", payload);
923925
}
924926
else if (model->request_index == 1)
925927
{
@@ -957,7 +959,7 @@ static bool _fetch_game(DataLoaderModel *model)
957959
char payload[172];
958960
snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"password\":\"%s\"}", username, password);
959961
model->title = "Registering...";
960-
return flipper_http_post_request_with_headers(model->fhttp, "https://www.flipsocial.net/api/user/register/", "{\"Content-Type\":\"application/json\"}", payload);
962+
return flipper_http_request(model->fhttp, POST, "https://www.flipsocial.net/api/user/register/", "{\"Content-Type\":\"application/json\"}", payload);
961963
}
962964
else
963965
{
@@ -1015,7 +1017,7 @@ static bool _fetch_game(DataLoaderModel *model)
10151017
snprintf(url, sizeof(url), "https://www.flipsocial.net/api/world/v5/get/world/%s/", furi_string_get_cstr(first_world));
10161018
furi_string_free(world_list);
10171019
furi_string_free(first_world);
1018-
return flipper_http_get_request_with_headers(model->fhttp, url, "{\"Content-Type\":\"application/json\"}");
1020+
return flipper_http_request(model->fhttp, GET, url, "{\"Content-Type\":\"application/json\"}", NULL);
10191021
}
10201022
FURI_LOG_E(TAG, "Unknown request index");
10211023
return false;
@@ -1187,7 +1189,19 @@ void callback_submenu_choices(void *context, uint32_t index)
11871189
}
11881190
switch (index)
11891191
{
1190-
case FlipWorldSubmenuIndexRun:
1192+
case FlipWorldSubmenuIndexGameSubmenu:
1193+
view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewGameSubmenu);
1194+
break;
1195+
case FlipWorldSubmenuIndexStory:
1196+
game_mode_index = 2; // GAME_MODE_STORY
1197+
easy_flipper_dialog("Unavailable", "\nStory mode is not ready yet.\nPress BACK to return.");
1198+
break;
1199+
case FlipWorldSubmenuIndexPvP:
1200+
game_mode_index = 1; // GAME_MODE_PVP
1201+
easy_flipper_dialog("Unavailable", "\nPvP mode is not ready yet.\nPress BACK to return.");
1202+
break;
1203+
case FlipWorldSubmenuIndexPvE:
1204+
game_mode_index = 0; // GAME_MODE_PVE
11911205
free_all_views(app, true, true);
11921206
if (!is_enough_heap(60000))
11931207
{
@@ -1248,7 +1262,6 @@ void callback_submenu_choices(void *context, uint32_t index)
12481262
easy_flipper_dialog("Error", "Failed to start game thread. Press BACK to return.");
12491263
return;
12501264
}
1251-
12521265
}
12531266
else
12541267
{
@@ -1615,7 +1628,7 @@ static bool _fetch_worlds(DataLoaderModel *model)
16151628
furi_record_close(RECORD_STORAGE);
16161629
snprintf(model->fhttp->file_path, sizeof(model->fhttp->file_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/world_list_full.json");
16171630
model->fhttp->save_received_data = true;
1618-
return flipper_http_get_request_with_headers(model->fhttp, "https://www.flipsocial.net/api/world/v5/get/10/", "{\"Content-Type\":\"application/json\"}");
1631+
return flipper_http_request(model->fhttp, GET, "https://www.flipsocial.net/api/world/v5/get/10/", "{\"Content-Type\":\"application/json\"}", NULL);
16191632
}
16201633
static char *_parse_worlds(DataLoaderModel *model)
16211634
{
@@ -1797,7 +1810,7 @@ void loader_draw_callback(Canvas *canvas, void *model)
17971810
}
17981811

17991812
DataLoaderModel *data_loader_model = (DataLoaderModel *)model;
1800-
SerialState http_state = data_loader_model->fhttp->state;
1813+
HTTPState http_state = data_loader_model->fhttp->state;
18011814
DataState data_state = data_loader_model->data_state;
18021815
char *title = data_loader_model->title;
18031816

flip_world.c

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ int player_sprite_index = 1;
1010
char *vgm_levels[] = {"-2", "-1", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
1111
int vgm_x_index = 2;
1212
int vgm_y_index = 2;
13+
int game_mode_index = 0;
1314
float atof_(const char *nptr) { return (float)strtod(nptr, NULL); }
1415
float atof_furi(const FuriString *nptr) { return atof_(furi_string_get_cstr(nptr)); }
1516
bool is_str(const char *src, const char *dst) { return strcmp(src, dst) == 0; }

flip_world.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515
//
1616

1717
#define TAG "FlipWorld"
18-
#define VERSION 0.5
18+
#define VERSION 0.6
1919
#define VERSION_TAG TAG " " FAP_VERSION
2020

2121
// Define the submenu items for our FlipWorld application
2222
typedef enum
2323
{
24-
FlipWorldSubmenuIndexRun, // Click to run the FlipWorld application
24+
FlipWorldSubmenuIndexPvE,
25+
FlipWorldSubmenuIndexStory,
26+
FlipWorldSubmenuIndexPvP,
27+
FlipWorldSubmenuIndexGameSubmenu,
2528
FlipWorldSubmenuIndexMessage,
2629
FlipWorldSubmenuIndexSettings,
2730
FlipWorldSubmenuIndexWiFiSettings,
@@ -33,6 +36,7 @@ typedef enum
3336
typedef enum
3437
{
3538
FlipWorldViewSubmenu, // The submenu
39+
FlipWorldViewGameSubmenu, // The game submenu
3640
FlipWorldViewMessage, // The about, loading screen
3741
FlipWorldViewSettings, // The settings screen
3842
FlipWorldViewVariableItemList, // The variable item list screen
@@ -58,6 +62,7 @@ typedef struct
5862
ViewDispatcher *view_dispatcher; // Switches between our views
5963
View *view_message; // The about, loading screen
6064
Submenu *submenu; // The submenu
65+
Submenu *submenu_game; // The game submenu
6166
Submenu *submenu_settings; // The settings submenu
6267
VariableItemList *variable_item_list; // The variable item list (settngs)
6368
VariableItem *variable_item_wifi_ssid; // The variable item for WiFi SSID
@@ -92,6 +97,7 @@ extern int player_sprite_index;
9297
extern char *vgm_levels[];
9398
extern int vgm_x_index;
9499
extern int vgm_y_index;
100+
extern int game_mode_index;
95101
float atof_(const char *nptr);
96102
float atof_furi(const FuriString *nptr);
97103
bool is_str(const char *src, const char *dst);

0 commit comments

Comments
 (0)