add some games, make DOOM somewhat playable
68
applications/plugins/doom/README.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Doom Flipper Zero edition
|
||||
|
||||
<div style="text-align:center"><img src="assets/intro-screen.png"/></div>
|
||||
|
||||
## Will it run Doom?
|
||||
As tradition goes, Doom is being ported to almost every possible embedded electronic device. Therefore I did an attempt to come up with something close to Doom and still compatible on the Flipper Zero's hardware.<br> This is not the actual Doom game but a port made from yet another Doom port to the Arduino Nano (https://github.com/daveruiz/doom-nano/). This port is basically a raycasting engine, using Doom sprites.<br>
|
||||
This version is very basic and might be improved over time.
|
||||
|
||||
## How to install on Flipper Zero
|
||||
During the porting process, minor changes were made to the workings (and build options) of the current firmware. These changes are documented here and are necessary in order to get a working firmware build that contains this Doom port.
|
||||
### Modifying the firmware & build options
|
||||
* In the `sites/cc.scons` add the following values to the `CCFLAGS` section:
|
||||
```
|
||||
...
|
||||
"-Wno-unused-parameter",
|
||||
"-Wno-type-limits",
|
||||
"-Wno-unused-variable",
|
||||
...
|
||||
```
|
||||
* In `applications/gui/canvas_i.h` comment out the following line:<br>
|
||||
`uint8_t* canvas_get_buffer(Canvas* canvas);` --> `//uint8_t* canvas_get_buffer(Canvas* canvas);`
|
||||
|
||||
* In `applications/gui/canvas.h` add the following lines:
|
||||
```
|
||||
uint8_t* canvas_get_buffer(Canvas* canvas);
|
||||
void canvas_draw_icon_bitmap(Canvas* canvas, uint8_t x, uint8_t y, int16_t w, int16_t h, const Icon* icon);
|
||||
```
|
||||
* In `applications/gui/canvas.c` add the following function:
|
||||
```
|
||||
void canvas_draw_icon_bitmap(Canvas* canvas, uint8_t x, uint8_t y, int16_t w, int16_t h, const Icon* icon){
|
||||
furi_assert(canvas);
|
||||
furi_assert(icon);
|
||||
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
uint8_t* icon_data = NULL;
|
||||
furi_hal_compress_icon_decode(icon_get_data(icon), &icon_data);
|
||||
u8g2_DrawXBM(&canvas->fb, x, y, w, h, icon_data);
|
||||
}
|
||||
```
|
||||
|
||||
### Installing the plugin in the firmware
|
||||
* Make a folder called Doom in the applications folder. Add all the source files (also the compiled folder and it's files) in the Doom folder.
|
||||
* Make the `applications/meta/application.fam` look like the following:
|
||||
```
|
||||
App(
|
||||
appid="basic_plugins",
|
||||
name="Basic applications for plug-in menu",
|
||||
apptype=FlipperAppType.METAPACKAGE,
|
||||
provides=[
|
||||
...
|
||||
"doom_game",
|
||||
...
|
||||
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
If all went well the only thing left to do is building the firmware and installing it to the Flipper.
|
||||
|
||||
## Screenshots
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
15
applications/plugins/doom/application.fam
Normal file
@@ -0,0 +1,15 @@
|
||||
App(
|
||||
appid="game_doom",
|
||||
name="DOOM",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="doom_app",
|
||||
cdefines=["APP_DOOM_GAME"],
|
||||
requires=[
|
||||
"gui",
|
||||
"music_player",
|
||||
],
|
||||
stack_size=4 * 1024,
|
||||
order=75,
|
||||
fap_icon="doom_10px.png",
|
||||
fap_category="Games",
|
||||
)
|
||||
BIN
applications/plugins/doom/assets/door2.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
applications/plugins/doom/assets/door_inv.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
applications/plugins/doom/assets/fire_inv.png
Normal file
|
After Width: | Height: | Size: 583 B |
BIN
applications/plugins/doom/assets/fireball_inv.png
Normal file
|
After Width: | Height: | Size: 418 B |
BIN
applications/plugins/doom/assets/fireball_mask_inv.png
Normal file
|
After Width: | Height: | Size: 388 B |
BIN
applications/plugins/doom/assets/gradient_inv.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
applications/plugins/doom/assets/gun_inv.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
applications/plugins/doom/assets/gun_mask_inv.png
Normal file
|
After Width: | Height: | Size: 847 B |
BIN
applications/plugins/doom/assets/imp_inv.png
Normal file
|
After Width: | Height: | Size: 903 B |
BIN
applications/plugins/doom/assets/imp_mask_inv.png
Normal file
|
After Width: | Height: | Size: 958 B |
BIN
applications/plugins/doom/assets/intro-screen.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
applications/plugins/doom/assets/item_inv.png
Normal file
|
After Width: | Height: | Size: 417 B |
BIN
applications/plugins/doom/assets/item_mask_inv.png
Normal file
|
After Width: | Height: | Size: 383 B |
BIN
applications/plugins/doom/assets/screenshot-imp2.jpg
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
applications/plugins/doom/assets/screenshot-intro2.jpg
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
applications/plugins/doom/assets/screenshot-medkit2.jpg
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
applications/plugins/doom/assets/screenshot-start2.jpg
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
applications/plugins/doom/assets/screenshot1.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
applications/plugins/doom/assets/screenshot2.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
applications/plugins/doom/assets/screenshot3.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
403
applications/plugins/doom/compiled/assets_icons.c
Normal file
@@ -0,0 +1,403 @@
|
||||
#include "assets_icons.h"
|
||||
|
||||
#include <gui/icon_i.h>
|
||||
|
||||
// Inverted icons
|
||||
|
||||
const uint8_t _I_fire_inv_0[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x40, 0xee, 0x00, 0x80, 0xe6, 0x00,
|
||||
0x80, 0xa7, 0x01, 0x80, 0xc7, 0x03, 0x40, 0x45, 0x03, 0xe0, 0x41, 0x07, 0xf8, 0x82, 0x9f, 0xb9,
|
||||
0x01, 0x3e, 0x7c, 0x00, 0x7a, 0x6e, 0x00, 0x56, 0x1c, 0x00, 0x6c, 0xf4, 0x01, 0x3a, 0x6c, 0x00,
|
||||
0x7e, 0xfc, 0x00, 0x1a, 0x08, 0x00, 0x3c, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
const uint8_t* const _I_fire_inv[] = {_I_fire_inv_0};
|
||||
|
||||
const uint8_t _I_gun_inv_0[] = {
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x80, 0x23, 0x00, 0x00, 0x40,
|
||||
0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x57, 0x00, 0x00, 0x20, 0x8b, 0x00, 0x00,
|
||||
0x90, 0x11, 0x01, 0x00, 0x98, 0x00, 0x00, 0x00, 0xb0, 0x43, 0x01, 0x00, 0x94, 0x81, 0x03,
|
||||
0x00, 0xd0, 0x45, 0x04, 0x00, 0x8c, 0x02, 0x02, 0x00, 0xc4, 0x00, 0x03, 0x00, 0xc8, 0x00,
|
||||
0x02, 0x00, 0x4e, 0x40, 0x00, 0x00, 0x92, 0x00, 0x02, 0x80, 0x07, 0x15, 0x04, 0xe0, 0x8f,
|
||||
0x00, 0x0c, 0xd0, 0x9d, 0x07, 0x17, 0xe0, 0x3a, 0xc0, 0x3f, 0xe0, 0xf7, 0xff, 0x77, 0xe0,
|
||||
0xae, 0xfe, 0x4b, 0xd8, 0xdd, 0xff, 0x4d, 0x88, 0xea, 0xbe, 0x26, 0x4c, 0xf5, 0xff, 0x17,
|
||||
0xc8, 0xfa, 0xae, 0x0b, 0xcc, 0xff, 0xdf, 0x19, 0xe8, 0xeb, 0xa7, 0x00, 0xd8, 0xf1, 0x4d,
|
||||
0x0c, 0xc0, 0xbe, 0x1a, 0x08, 0xf6, 0xfd, 0x37, 0x04,
|
||||
};
|
||||
const uint8_t* const _I_gun_inv[] = {_I_gun_inv_0};
|
||||
|
||||
const uint8_t _I_gun_mask_inv_0[] = {
|
||||
0x01, 0x00, 0x53, 0x00, 0x00, 0x0c, 0x38, 0x04, 0x38, 0x09, 0xf8, 0x0c, 0x78, 0x17, 0xf0,
|
||||
0x18, 0xf8, 0x00, 0x67, 0xff, 0x01, 0xaf, 0xc3, 0xff, 0x01, 0x80, 0x7e, 0x3f, 0xf0, 0x38,
|
||||
0x07, 0xf0, 0x0e, 0x40, 0x31, 0x03, 0x8f, 0xfb, 0xff, 0x07, 0x01, 0x94, 0x3c, 0x0e, 0xc0,
|
||||
0x35, 0xff, 0x85, 0xc8, 0x06, 0x30, 0x7e, 0x00, 0x0c, 0x61, 0xe2, 0xe1, 0xff, 0xc7, 0xc5,
|
||||
0xc3, 0xff, 0x9f, 0x80, 0xca, 0xfe, 0x03, 0x2f, 0xf8, 0x0c, 0xc6, 0xc2, 0x03, 0x4b, 0xf8,
|
||||
0xa8, 0x42, 0xe2, 0x03, 0x28, 0xf8, 0x1e, 0x80, 0x68, 0x1e, 0x28, 0x78,
|
||||
};
|
||||
const uint8_t* const _I_gun_mask_inv[] = {_I_gun_mask_inv_0};
|
||||
|
||||
const uint8_t _I_logo_inv_0[] = {
|
||||
0x01, 0x00, 0x71, 0x01, 0x00, 0x44, 0x0a, 0x21, 0x00, 0xc0, 0x48, 0x20, 0x91, 0x0c, 0x05, 0x20,
|
||||
0x14, 0x30, 0x80, 0x71, 0x80, 0x8e, 0x03, 0x00, 0x85, 0x40, 0x22, 0x98, 0x8a, 0x00, 0x20, 0x60,
|
||||
0xa0, 0x83, 0xa8, 0x50, 0x20, 0xd8, 0x00, 0x41, 0xcd, 0x01, 0x03, 0x82, 0xc3, 0xc3, 0x61, 0xf0,
|
||||
0xa8, 0xf0, 0x44, 0x6c, 0x14, 0x68, 0x26, 0x16, 0x3b, 0x0a, 0x89, 0xcd, 0x24, 0x14, 0x0a, 0x96,
|
||||
0x32, 0x1b, 0x11, 0x85, 0xc4, 0x62, 0x92, 0x00, 0x88, 0xe1, 0x30, 0xb1, 0x18, 0x54, 0x46, 0x6d,
|
||||
0x28, 0xa0, 0x70, 0x82, 0x23, 0x51, 0xa5, 0x54, 0x62, 0x90, 0x1b, 0x05, 0x0b, 0x19, 0x15, 0x89,
|
||||
0x86, 0x86, 0x69, 0x42, 0xb0, 0xf5, 0xb2, 0x9a, 0x58, 0xac, 0xae, 0xaf, 0x35, 0x85, 0x50, 0xb8,
|
||||
0xda, 0x69, 0x6d, 0x6e, 0x95, 0x9b, 0x9b, 0x50, 0xac, 0x9c, 0xac, 0x6e, 0x36, 0x37, 0x2b, 0xad,
|
||||
0xed, 0xa2, 0x41, 0xa1, 0xd7, 0x6b, 0x42, 0x23, 0x3f, 0xdb, 0x75, 0xad, 0x5d, 0x6c, 0x2c, 0x37,
|
||||
0xbf, 0x5b, 0x0d, 0x0e, 0x5a, 0xc5, 0xca, 0xdb, 0xef, 0x6b, 0xf6, 0xea, 0xff, 0xde, 0x6d, 0x4d,
|
||||
0xfb, 0x75, 0xe5, 0xfb, 0xfd, 0xde, 0xfe, 0x6d, 0xe7, 0xb9, 0x7b, 0xba, 0xff, 0xdb, 0xfd, 0xaf,
|
||||
0xbf, 0x77, 0xc7, 0xd9, 0xf3, 0x5f, 0x79, 0xed, 0x3c, 0x10, 0x3f, 0x79, 0x7d, 0xbf, 0x9f, 0xed,
|
||||
0xff, 0xf7, 0xe7, 0x5f, 0xff, 0xbd, 0xae, 0xbd, 0xd6, 0xfe, 0xdf, 0x62, 0x34, 0xbf, 0xdf, 0xde,
|
||||
0x77, 0x6b, 0xe9, 0x7f, 0xbf, 0xf5, 0x38, 0x77, 0xe7, 0xef, 0x7b, 0xb9, 0xf4, 0xbf, 0x7f, 0xde,
|
||||
0xbd, 0xb8, 0x34, 0x3f, 0xbb, 0x5f, 0xbb, 0xff, 0xff, 0xbf, 0xda, 0x80, 0x63, 0xfb, 0xa1, 0xfe,
|
||||
0xc1, 0x05, 0xdf, 0x11, 0x8f, 0xce, 0xdd, 0xf2, 0xff, 0xff, 0x40, 0xe3, 0xff, 0xf3, 0xfd, 0xe9,
|
||||
0x42, 0xb1, 0xfc, 0x84, 0xc4, 0x32, 0x3f, 0xbb, 0xf0, 0x10, 0x7e, 0x60, 0x82, 0xfe, 0xdc, 0xe8,
|
||||
0xc1, 0x11, 0x07, 0x97, 0xff, 0xfd, 0x7f, 0xbf, 0x82, 0x07, 0x8f, 0xff, 0xf8, 0x82, 0x06, 0xef,
|
||||
0x7e, 0x04, 0x0e, 0x0f, 0xff, 0xe0, 0x9f, 0xfe, 0x04, 0x67, 0x01, 0x9f, 0x60, 0x21, 0xff, 0x0d,
|
||||
0xf8, 0x68, 0xa0, 0x11, 0xcc, 0x04, 0x1f, 0xc1, 0xbf, 0x0d, 0x0c, 0xfe, 0x01, 0x08, 0x80, 0x40,
|
||||
0xb8, 0x1f, 0xc0, 0x88, 0xc7, 0xe0, 0x00, 0x03, 0xe4, 0x5f, 0xff, 0xf0, 0xf0, 0x42, 0x70, 0x03,
|
||||
0x43, 0x03, 0x04, 0x28, 0x68, 0x60, 0x20, 0x87, 0x03, 0xa4, 0x03, 0xc1, 0x7f, 0x1a, 0x08, 0x45,
|
||||
0x86, 0x8b, 0x00, 0xc0, 0x5f, 0xe1, 0xc0, 0x85, 0x80, 0x5f, 0xe0, 0x80, 0x86, 0xfe, 0x01, 0xda,
|
||||
0x01, 0x78, 0x04, 0x3c, 0xc0,
|
||||
};
|
||||
const uint8_t* const _I_logo_inv[] = {_I_logo_inv_0};
|
||||
|
||||
const Icon I_fire_inv =
|
||||
{.width = 24, .height = 20, .frame_count = 1, .frame_rate = 0, .frames = _I_fire_inv};
|
||||
const Icon I_gun_inv =
|
||||
{.width = 32, .height = 32, .frame_count = 1, .frame_rate = 0, .frames = _I_gun_inv};
|
||||
const Icon I_gun_mask_inv =
|
||||
{.width = 32, .height = 32, .frame_count = 1, .frame_rate = 0, .frames = _I_gun_mask_inv};
|
||||
const Icon I_logo_inv =
|
||||
{.width = 72, .height = 47, .frame_count = 1, .frame_rate = 0, .frames = _I_logo_inv};
|
||||
|
||||
const uint8_t space[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
const uint8_t zero[] = {0x00, 0x60, 0x90, 0x90, 0x90, 0x60};
|
||||
const uint8_t one[] = {0x00, 0x20, 0x20, 0x20, 0x20, 0x70};
|
||||
const uint8_t two[] = {0x00, 0x60, 0x90, 0x20, 0x40, 0xf0};
|
||||
const uint8_t three[] = {0x00, 0x60, 0x90, 0x20, 0x90, 0x60};
|
||||
const uint8_t four[] = {0x00, 0x90, 0x90, 0xf0, 0x10, 0x10};
|
||||
const uint8_t five[] = {0x00, 0xf0, 0x80, 0xe0, 0x10, 0xe0};
|
||||
const uint8_t six[] = {0x00, 0x60, 0x80, 0xe0, 0x90, 0x60};
|
||||
const uint8_t seven[] = {0x00, 0xf0, 0x10, 0x10, 0x10, 0x10};
|
||||
const uint8_t eight[] = {0x00, 0x60, 0x90, 0x60, 0x90, 0x60};
|
||||
const uint8_t nine[] = {0x00, 0x60, 0x90, 0x70, 0x10, 0x60};
|
||||
const uint8_t A[] = {0x00, 0x60, 0x90, 0xf0, 0x90, 0x90};
|
||||
const uint8_t B[] = {0x00, 0xe0, 0x90, 0xe0, 0x90, 0xe0};
|
||||
const uint8_t C[] = {0x00, 0x60, 0x90, 0x80, 0x90, 0x60};
|
||||
const uint8_t D[] = {0x00, 0xe0, 0x90, 0x90, 0x90, 0xe0};
|
||||
const uint8_t E[] = {0x00, 0xf0, 0x80, 0xe0, 0x80, 0xf0};
|
||||
const uint8_t F[] = {0x00, 0xf0, 0x80, 0xe0, 0x80, 0x80};
|
||||
const uint8_t G[] = {0x00, 0x60, 0x80, 0x80, 0x90, 0x60};
|
||||
const uint8_t H[] = {0x00, 0x90, 0x90, 0xf0, 0x90, 0x90};
|
||||
const uint8_t I[] = {0x00, 0x20, 0x20, 0x20, 0x20, 0x20};
|
||||
const uint8_t J[] = {0x00, 0x10, 0x10, 0x10, 0x90, 0x60};
|
||||
const uint8_t K[] = {0x00, 0x90, 0xa0, 0xc0, 0xa0, 0x90};
|
||||
const uint8_t L[] = {0x00, 0x80, 0x80, 0x80, 0x80, 0xf0};
|
||||
const uint8_t M[] = {0x00, 0x90, 0xf0, 0x90, 0x90, 0x90};
|
||||
const uint8_t N[] = {0x00, 0x90, 0xd0, 0xb0, 0x90, 0x90};
|
||||
const uint8_t O[] = {0x00, 0x60, 0x90, 0x90, 0x90, 0x60};
|
||||
const uint8_t P[] = {0x00, 0xe0, 0x90, 0xe0, 0x80, 0x80};
|
||||
const uint8_t Q[] = {0x00, 0x60, 0x90, 0x90, 0xb0, 0x70};
|
||||
const uint8_t R[] = {0x00, 0xe0, 0x90, 0xe0, 0x90, 0x90};
|
||||
const uint8_t S[] = {0x00, 0x60, 0x80, 0x60, 0x10, 0xe0};
|
||||
const uint8_t T[] = {0x00, 0xe0, 0x40, 0x40, 0x40, 0x40};
|
||||
const uint8_t U[] = {0x00, 0x90, 0x90, 0x90, 0x90, 0x60};
|
||||
const uint8_t V[] = {0x00, 0x90, 0x90, 0x90, 0x60, 0x60};
|
||||
const uint8_t W[] = {0x00, 0x90, 0x90, 0x90, 0xf0, 0x90};
|
||||
const uint8_t X[] = {0x00, 0x90, 0x90, 0x60, 0x90, 0x90};
|
||||
const uint8_t Y[] = {0x00, 0x90, 0x90, 0x60, 0x60, 0x60};
|
||||
const uint8_t Z[] = {0x00, 0xf0, 0x10, 0x60, 0x80, 0xf0};
|
||||
const uint8_t dot[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x40};
|
||||
const uint8_t comma[] = {0x00, 0x00, 0x00, 0x00, 0x20, 0x40};
|
||||
const uint8_t dash[] = {0x00, 0x00, 0x00, 0x60, 0x00, 0x00};
|
||||
const uint8_t underscore[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
|
||||
const uint8_t bracket_open[] = {0x00, 0x20, 0x40, 0x40, 0x40, 0x20};
|
||||
const uint8_t bracket_close[] = {0x00, 0x40, 0x20, 0x20, 0x20, 0x40};
|
||||
const uint8_t cross_left[] = {0x10, 0x10, 0x70, 0x70, 0x10, 0x10};
|
||||
const uint8_t cross_right[] = {0x80, 0x80, 0xe0, 0xe0, 0x80, 0x80};
|
||||
const uint8_t pacman_left[] = {0x00, 0x30, 0x50, 0x70, 0x70, 0x00};
|
||||
const uint8_t pacman_right[] = {0x00, 0xc0, 0x60, 0xe0, 0xe0, 0xe0};
|
||||
const uint8_t box[] = {0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x00};
|
||||
const uint8_t* char_arr[48] = {
|
||||
space,
|
||||
zero,
|
||||
one,
|
||||
two,
|
||||
three,
|
||||
four,
|
||||
five,
|
||||
six,
|
||||
seven,
|
||||
eight,
|
||||
nine,
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
K,
|
||||
L,
|
||||
M,
|
||||
N,
|
||||
O,
|
||||
P,
|
||||
Q,
|
||||
R,
|
||||
S,
|
||||
T,
|
||||
U,
|
||||
V,
|
||||
W,
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
dot,
|
||||
comma,
|
||||
dash,
|
||||
underscore,
|
||||
bracket_open,
|
||||
bracket_close,
|
||||
cross_left,
|
||||
cross_right,
|
||||
pacman_left,
|
||||
pacman_right,
|
||||
box};
|
||||
const uint8_t gradient[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22,
|
||||
0x00, 0x00, 0x8a, 0x8a, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0xaa, 0xaa,
|
||||
0x10, 0x10, 0xaa, 0xaa, 0x00, 0x00, 0xaa, 0xaa, 0x01, 0x01, 0xaa, 0xaa,
|
||||
0x44, 0x44, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x44, 0x44, 0xaa, 0xaa,
|
||||
0x15, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xbb, 0xbb,
|
||||
0x55, 0x55, 0xaa, 0xea, 0x55, 0x55, 0xbb, 0xbb, 0x55, 0x55, 0xff, 0xff,
|
||||
0x55, 0x55, 0xfb, 0xfb, 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, 0xbb, 0xbf,
|
||||
0x57, 0x57, 0xff, 0xff, 0xdd, 0xdd, 0xff, 0xff, 0x77, 0x75, 0xff, 0xff,
|
||||
0xdd, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
//const uint8_t gun[] = {0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0x27, 0xff, 0xff, 0xfe, 0x3b, 0xff, 0xff, 0xfd, 0xfb, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xfd, 0x15, 0xff, 0xff, 0xfb, 0x2e, 0xff, 0xff, 0xf6, 0x77, 0x7f, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xf2, 0x3d, 0x7f, 0xff, 0xd6, 0x7e, 0x3f, 0xff, 0xf4, 0x5d, 0xdf, 0xff, 0xce, 0xbf, 0xbf, 0xff, 0xdc, 0xff, 0x3f, 0xff, 0xec, 0xff, 0xbf, 0xff, 0x8d, 0xfd, 0xff, 0xff, 0xb6, 0xff, 0xbf, 0xfe, 0x1f, 0x57, 0xdf, 0xf8, 0x0e, 0xff, 0xcf, 0xf4, 0x46, 0x1f, 0x17, 0xf8, 0xa3, 0xfc, 0x03, 0xf8, 0x10, 0x00, 0x11, 0xf8, 0x8a, 0x80, 0x2d, 0xe4, 0x44, 0x00, 0x4d, 0xee, 0xa8, 0x82, 0x9b, 0xcd, 0x50, 0x00, 0x17, 0xec, 0xa0, 0x8a, 0x2f, 0xcc, 0x00, 0x04, 0x67, 0xe8, 0x28, 0x1a, 0xff, 0xe4, 0x70, 0x4d, 0xcf, 0xfc, 0x82, 0xa7, 0xef, 0x90, 0x40, 0x13, 0xdf};
|
||||
// const uint8_t gun_mask[] = {0xff, 0xff, 0x8f, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xfc, 0x01, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0x80, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f};
|
||||
const uint8_t gun[] = {0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x01, 0xc4, 0x00,
|
||||
0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0xea, 0x00,
|
||||
0x00, 0x04, 0xd1, 0x00, 0x00, 0x09, 0x88, 0x80, 0x00, 0x19, 0x00, 0x00,
|
||||
0x00, 0x0d, 0xc2, 0x80, 0x00, 0x29, 0x81, 0xc0, 0x00, 0x0b, 0xa2, 0x20,
|
||||
0x00, 0x31, 0x40, 0x40, 0x00, 0x23, 0x00, 0xc0, 0x00, 0x13, 0x00, 0x40,
|
||||
0x00, 0x72, 0x02, 0x00, 0x00, 0x49, 0x00, 0x40, 0x01, 0xe0, 0xa8, 0x20,
|
||||
0x07, 0xf1, 0x00, 0x30, 0x0b, 0xb9, 0xe0, 0xe8, 0x07, 0x5c, 0x03, 0xfc,
|
||||
0x07, 0xef, 0xff, 0xee, 0x07, 0x75, 0x7f, 0xd2, 0x1b, 0xbb, 0xff, 0xb2,
|
||||
0x11, 0x57, 0x7d, 0x64, 0x32, 0xaf, 0xff, 0xe8, 0x13, 0x5f, 0x75, 0xd0,
|
||||
0x33, 0xff, 0xfb, 0x98, 0x17, 0xd7, 0xe5, 0x00, 0x1b, 0x8f, 0xb2, 0x30,
|
||||
0x03, 0x7d, 0x58, 0x10, 0x6f, 0xbf, 0xec, 0x20};
|
||||
const uint8_t gun_mask[] = {0x00, 0x00, 0x70, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x03, 0xfe, 0x00,
|
||||
0x00, 0x07, 0xfe, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, 0x00,
|
||||
0x00, 0x0f, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0x80,
|
||||
0x00, 0x3f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xf0,
|
||||
0x00, 0x7f, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xe0,
|
||||
0x00, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xf0,
|
||||
0x0f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xfe,
|
||||
0x1f, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff,
|
||||
0x3f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xf8,
|
||||
0x7f, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xf8,
|
||||
0x7f, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf0};
|
||||
|
||||
const uint8_t
|
||||
imp_inv[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
|
||||
0x02, 0x80, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x01, 0x0f, 0xb3, 0x00, 0x00, 0xd0, 0x4e, 0x00, 0x00, 0x79, 0x8c,
|
||||
0x00, 0x00, 0x1c, 0x19, 0x00, 0x01, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x40, 0x02, 0x08, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x8e,
|
||||
0x30, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x02, 0x20, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x03, 0xe0,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0xa1, 0x80, 0x01, 0x80, 0x13, 0x00,
|
||||
0x00, 0xf3, 0x8a, 0x00, 0x00, 0x09, 0x94, 0x00, 0x00, 0x88, 0x38, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x80,
|
||||
0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0xe2, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x02, 0x20, 0x00,
|
||||
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x02, 0x20, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00,
|
||||
0x00, 0x1f, 0x00, 0x00, 0x02, 0x2a, 0x80, 0x00, 0x01, 0x05, 0x00, 0x00, 0x01,
|
||||
0xae, 0x20, 0x00, 0x01, 0x24, 0x40, 0x00, 0x02, 0xac, 0x80, 0x00, 0x02, 0x86,
|
||||
0x00, 0x00, 0x03, 0x20, 0x20, 0x00, 0x04, 0x30, 0x40, 0x00, 0x0c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x00, 0x00,
|
||||
0x1c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x98,
|
||||
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00,
|
||||
0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0xd6, 0x80, 0x00,
|
||||
0x02, 0xbf, 0x80, 0x00, 0x06, 0x61, 0xa0, 0x00, 0x0c, 0xe8, 0x80, 0x00, 0x0c,
|
||||
0x10, 0x00, 0x00, 0x1a, 0x22, 0x00, 0x00, 0x12, 0x40, 0x00, 0x00, 0x06, 0x0c,
|
||||
0x00, 0x00, 0x04, 0x0d, 0x00, 0x00, 0x3a, 0x03, 0x00, 0x00, 0x10, 0x02, 0x00,
|
||||
0x00, 0x60, 0x0a, 0x00, 0x00, 0x50, 0x04, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00,
|
||||
0x00, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x01,
|
||||
0x18, 0x00, 0x00, 0x01, 0x41, 0x40, 0x02, 0x33, 0xb6, 0x80, 0x01, 0x9c, 0x04,
|
||||
0x00, 0x08, 0xfa, 0x02, 0x08, 0x05, 0x00, 0x01, 0x0c, 0x27, 0x83, 0xa2, 0x2a,
|
||||
0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00}; //{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x0f, 0xb3, 0x00, 0x00, 0xd0, 0x4e, 0x00, 0x00, 0x79, 0x8c, 0x00, 0x00, 0x1c, 0x19, 0x00, 0x01, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x08, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x8e, 0x30, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
const uint8_t imp_mask_inv[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00,
|
||||
0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x07, 0xf1, 0x80,
|
||||
0x00, 0xdf, 0xfe, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x01, 0xff, 0xff, 0x80,
|
||||
0x00, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x80, 0x03, 0xcf, 0xf1, 0xc0, 0x01, 0xc7, 0xf1, 0xc0,
|
||||
0x01, 0x87, 0xf1, 0xc0, 0x03, 0x0f, 0xf9, 0x80, 0x03, 0x0f, 0xfb, 0x80, 0x01, 0x8f, 0xff, 0x80,
|
||||
0x03, 0x9f, 0x79, 0x00, 0x00, 0x1f, 0x7c, 0x00, 0x00, 0x0f, 0x78, 0x00, 0x00, 0x0f, 0x78, 0x00,
|
||||
0x00, 0x07, 0x30, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x07, 0x30, 0x00,
|
||||
0x00, 0x03, 0x78, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x07, 0xe0, 0x00,
|
||||
0x00, 0x07, 0xc0, 0x00, 0x01, 0x07, 0xe1, 0x00, 0x00, 0x8f, 0xfa, 0x00, 0x00, 0xff, 0xfe, 0x00,
|
||||
0x00, 0x3f, 0xfe, 0x00, 0x01, 0x7f, 0xff, 0x80, 0x00, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0x80,
|
||||
0x03, 0xcf, 0xfb, 0xc0, 0x03, 0x87, 0xf1, 0xc0, 0x03, 0xcf, 0xf3, 0xc0, 0x01, 0xcf, 0xf1, 0x80,
|
||||
0x00, 0xcf, 0xf1, 0x00, 0x00, 0x0f, 0xfb, 0x80, 0x00, 0x1e, 0x78, 0x00, 0x00, 0x0e, 0x78, 0x00,
|
||||
0x00, 0x1e, 0x78, 0x00, 0x00, 0x0f, 0x70, 0x00, 0x00, 0x0f, 0x78, 0x00, 0x00, 0x07, 0x70, 0x00,
|
||||
0x00, 0x07, 0x70, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x03, 0x20, 0x00,
|
||||
0x00, 0x07, 0x30, 0x00, 0x00, 0x05, 0x70, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1f, 0x00,
|
||||
0x00, 0x00, 0x1f, 0x00, 0x00, 0x03, 0x3f, 0x80, 0x00, 0x01, 0x3f, 0x00, 0x00, 0x01, 0xff, 0x30,
|
||||
0x00, 0x03, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x03, 0xff, 0x80, 0x00, 0x07, 0xff, 0xe0,
|
||||
0x00, 0x07, 0xff, 0xc0, 0x00, 0x05, 0xff, 0xe0, 0x00, 0x00, 0xfc, 0xe0, 0x00, 0x01, 0xfc, 0xe0,
|
||||
0x00, 0x01, 0xfc, 0x70, 0x00, 0x03, 0xfc, 0x38, 0x00, 0x03, 0xfe, 0x70, 0x00, 0x07, 0xfc, 0x00,
|
||||
0x00, 0x07, 0x9e, 0x00, 0x00, 0x0f, 0xbc, 0x00, 0x00, 0x0f, 0x3e, 0x00, 0x00, 0x07, 0x9c, 0x00,
|
||||
0x00, 0x03, 0x9c, 0x00, 0x00, 0x03, 0xb8, 0x00, 0x00, 0x03, 0x98, 0x00, 0x00, 0x01, 0x98, 0x00,
|
||||
0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1f, 0x00,
|
||||
0x00, 0x00, 0x1f, 0x40, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x01, 0xff, 0x80, 0x00, 0x03, 0xff, 0x80,
|
||||
0x00, 0x07, 0xff, 0xe0, 0x00, 0x0e, 0xff, 0xc0, 0x00, 0x0c, 0xff, 0x80, 0x00, 0x1f, 0xfe, 0x00,
|
||||
0x00, 0x13, 0xfc, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x3f, 0x9f, 0x00,
|
||||
0x00, 0x3e, 0x0f, 0x00, 0x00, 0x7c, 0x0f, 0x00, 0x00, 0x78, 0x0f, 0x00, 0x00, 0x78, 0x07, 0x80,
|
||||
0x00, 0x78, 0x07, 0x40, 0x00, 0x38, 0x07, 0x80, 0x00, 0x30, 0x07, 0x00, 0x00, 0x30, 0x01, 0x00,
|
||||
0x01, 0xf0, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x00,
|
||||
0x00, 0x01, 0x3e, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0x01, 0x3f, 0xff, 0xc0,
|
||||
0x01, 0xff, 0xff, 0xc0, 0x19, 0xff, 0xff, 0xe8, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfe,
|
||||
0x1f, 0xc2, 0x07, 0xe0, 0x1f, 0x00, 0x01, 0xe0, 0x0e, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
}; //{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x07, 0xf1, 0x80, 0x00, 0xdf, 0xfe, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x80, 0x03, 0xcf, 0xf1, 0xc0, 0x01, 0xc7, 0xf1, 0xc0, 0x01, 0x87, 0xf1, 0xc0, 0x03, 0x0f, 0xf9, 0x80, 0x03, 0x0f, 0xfb, 0x80, 0x01, 0x8f, 0xff, 0x80, 0x03, 0x9f, 0x79, 0x00, 0x00, 0x1f, 0x7c, 0x00, 0x00, 0x0f, 0x78, 0x00, 0x00, 0x0f, 0x78, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x03, 0x78, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
const uint8_t fireball[] = {0x00, 0x00, 0x01, 0x40, 0x0a, 0xb0, 0x0e, 0xd0, 0x00, 0x68, 0x53,
|
||||
0xb4, 0x0f, 0x48, 0x27, 0x78, 0x17, 0xa8, 0x27, 0xf0, 0x21, 0xd6,
|
||||
0x02, 0xf8, 0x20, 0x48, 0x06, 0x20, 0x01, 0x00, 0x00, 0x00};
|
||||
const uint8_t fireball_mask[] = {0x1f, 0x40, 0x0f, 0xf0, 0x3f, 0xf8, 0x1f, 0xfc, 0x7f, 0xfd, 0x7f,
|
||||
0xfc, 0x7f, 0xfd, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
||||
0xff, 0xfe, 0x3f, 0xfe, 0x17, 0xf8, 0x07, 0xf4, 0x01, 0xe0};
|
||||
const uint8_t item[] = {0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfe, 0x77, 0xee, 0x3f,
|
||||
0xfc, 0x5f, 0xfa, 0x2f, 0xf6, 0x53, 0xcc, 0x3e, 0x7e, 0x5e, 0x7c,
|
||||
0x38, 0x1e, 0x58, 0x1c, 0x3e, 0x7e, 0x5e, 0x7e, 0x2e, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc,
|
||||
0x17, 0xfc, 0x22, 0x6c, 0x36, 0x44, 0x3f, 0xfc, 0x1f, 0xfc, 0x2b,
|
||||
0xfc, 0x05, 0x54, 0x02, 0xa8, 0x00, 0x00, 0x00, 0x00};
|
||||
const uint8_t item_mask[] = {0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f,
|
||||
0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe,
|
||||
0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x3f, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc,
|
||||
0x1f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f,
|
||||
0xfc, 0x07, 0xfc, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
//const uint8_t door[] = {0xff, 0xff, 0xff, 0xff,0xb2, 0xbd, 0xcd, 0x5b,0x9a, 0xf4, 0x6d, 0x71,0xff, 0xff, 0xff, 0xff,0x00, 0x00, 0x00, 0x00,0xbf, 0xff, 0xff, 0xfd,0x3f, 0x00, 0xfe, 0xfc,0x3e, 0x00, 0xc6, 0xfc,0xbc, 0xaa, 0xfe, 0xbd,0x39, 0x54, 0xc6, 0xbc,0x32, 0x8e, 0xfe, 0xac,0xb5, 0xfe, 0xc6, 0xad,0x3f, 0xe0, 0xfe, 0xac,0x31, 0xe0, 0xc6, 0xac,0xb3, 0xf4, 0xfe, 0xad,0x3f, 0xe8, 0xc6, 0xac,0x3c, 0xf4, 0xd6, 0xac,0xb8, 0xff, 0xfe, 0xad,0x34, 0xc7, 0xfe, 0xfc,0x38, 0xd6, 0x0e, 0x0c,0xb0, 0xd6, 0x4e, 0x0d,0x3f, 0xd6, 0xaf, 0x5c,0x30, 0x47, 0xff, 0xac,0xb7, 0x57, 0xff, 0xfd,0x3f, 0xc6, 0x0e, 0x0c,0x35, 0x56, 0x40, 0x4c,0xb5, 0x46, 0xaa, 0xad,0x35, 0x56, 0x55, 0x4c,0xff, 0xff, 0xff, 0xff,0xb0, 0x1f, 0xf8, 0x0d,0xd9, 0x30, 0x0c, 0x9b,0xff, 0xe0, 0x07, 0xff};
|
||||
const uint8_t door[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0xe1, 0x8c, 0x00, 0x04,
|
||||
0x00, 0x7c, 0x03, 0x18, 0x60, 0x08, 0x00, 0x3e, 0x0f, 0xf7, 0xdf, 0x00, 0x1f, 0x00, 0xfe, 0x0f,
|
||||
0xbe, 0xf8, 0x3e, 0x00, 0x3f, 0x1f, 0xff, 0xdf, 0x00, 0x1f, 0x81, 0xff, 0x0f, 0xff, 0xf8, 0x7e,
|
||||
0x00, 0x3f, 0x8f, 0xff, 0xdf, 0x00, 0xff, 0xf9, 0xff, 0x1f, 0xff, 0xf8, 0xff, 0x80, 0x3f, 0xc7,
|
||||
0xff, 0xcc, 0x07, 0xff, 0xfc, 0xff, 0x1f, 0xff, 0xe3, 0xff, 0x80, 0x3f, 0xc7, 0xff, 0xc0, 0x07,
|
||||
0xff, 0xfc, 0x7f, 0x0f, 0xfe, 0x03, 0xff, 0xc0, 0x3f, 0xc3, 0xf7, 0xc0, 0x07, 0xdf, 0xf8, 0x3e,
|
||||
0x0f, 0xbe, 0x01, 0xff, 0x80, 0x1f, 0x80, 0xe3, 0x80, 0x07, 0x8f, 0xf8, 0x1e, 0x07, 0x1c, 0x01,
|
||||
0xff, 0x80, 0x3f, 0xc1, 0xff, 0xc0, 0x0f, 0xff, 0xfc, 0x3f, 0x0f, 0xbe, 0x03, 0xff, 0xc0, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x80, 0x00,
|
||||
0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0xe0, 0x00, 0x1f, 0xf0, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff,
|
||||
0xc0, 0x00, 0x00, 0xe0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01,
|
||||
0xe0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0xf0, 0x00, 0x0f,
|
||||
0xf0, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0x81, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00,
|
||||
0x07, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xc1, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x0f, 0xff, 0xff,
|
||||
0xff, 0xe1, 0xff, 0xe1, 0xf0, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0xff,
|
||||
0xc1, 0xf3, 0x00, 0x0f, 0xf0, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xe0, 0xff, 0x81, 0xff, 0xc0,
|
||||
0x0f, 0xf0, 0xff, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0x01, 0xff, 0xc0, 0x0f, 0xf0, 0xff,
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xe0, 0x0f, 0xf0, 0xff, 0x01, 0xff, 0xff,
|
||||
0xff, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xe0, 0x0f, 0xf0, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xe1,
|
||||
0xff, 0xe1, 0xff, 0xe0, 0x0f, 0xf0, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xc1, 0xff,
|
||||
0xf0, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x8f, 0xe0, 0xff, 0x81, 0xff, 0xff, 0x0f, 0xf0,
|
||||
0xff, 0x1f, 0xff, 0xff, 0xfe, 0x07, 0xe0, 0x7f, 0x81, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff,
|
||||
0xff, 0xfc, 0x07, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff, 0x8f, 0xfc, 0x03,
|
||||
0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff, 0x07, 0xfc, 0x07, 0xe0, 0xff, 0xc1,
|
||||
0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xfe, 0x00, 0x7f, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f,
|
||||
0xf0, 0xff, 0x0f, 0x9c, 0x00, 0x3f, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x07,
|
||||
0xfc, 0x00, 0x7f, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x07, 0xfc, 0x00, 0x7f,
|
||||
0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x0f, 0xfc, 0x00, 0x7f, 0xff, 0xe0, 0xff,
|
||||
0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x0f, 0xfc, 0x00, 0x7f, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff,
|
||||
0x8f, 0xf0, 0xff, 0x1f, 0xfe, 0x00, 0x7f, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff,
|
||||
0x1f, 0xfc, 0x00, 0x3f, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xfc, 0x00,
|
||||
0x3f, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xf0, 0x00, 0x1f, 0xff, 0xe0,
|
||||
0x7f, 0x81, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x0f, 0xf0, 0x00, 0x1f, 0xff, 0xe0, 0xff, 0x81, 0xff,
|
||||
0xff, 0x8f, 0xf0, 0xff, 0x07, 0xe0, 0x00, 0x3f, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xff, 0x8f, 0xf0,
|
||||
0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x00, 0x1f,
|
||||
0x80, 0x3f, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x00, 0x3f, 0xc0, 0x1f, 0xff,
|
||||
0xe1, 0xff, 0xe1, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x00, 0x7f, 0xc0, 0x0f, 0xff, 0xe1, 0xff, 0xe1,
|
||||
0xff, 0xff, 0x8f, 0xf0, 0xff, 0x00, 0xff, 0xc0, 0x07, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xff, 0x8f,
|
||||
0xf0, 0xff, 0x01, 0xff, 0xc0, 0x03, 0x8f, 0xc0, 0xc1, 0x81, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x03,
|
||||
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x07, 0xff, 0xc0, 0xff,
|
||||
0x80, 0x00, 0x00, 0x01, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xc1, 0xff, 0x80, 0x00, 0x00,
|
||||
0x01, 0xf3, 0x8e, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xc3, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xff, 0x9c,
|
||||
0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xc3, 0xff, 0xc0, 0xff, 0xfc, 0x01, 0xff, 0xfe, 0x0f, 0xf0, 0xff,
|
||||
0x0f, 0xff, 0xc3, 0xff, 0xc1, 0xff, 0xfe, 0x01, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0x07, 0xff, 0xc3,
|
||||
0xff, 0xc3, 0xff, 0xff, 0x01, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x0f, 0xff, 0xc3, 0xff, 0xc3, 0xff,
|
||||
0xff, 0x01, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x0f, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xff, 0x01, 0xff,
|
||||
0xff, 0x8f, 0xf0, 0xff, 0x0f, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xff, 0x01, 0xff, 0xff, 0x8f, 0xf0,
|
||||
0xff, 0x0f, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xff, 0x01, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff,
|
||||
0xc3, 0xff, 0xc3, 0xff, 0xff, 0x00, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xc3, 0xff, 0xc3,
|
||||
0xff, 0xff, 0x00, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0x07, 0xff, 0xe3, 0xff, 0xc3, 0xff, 0xff, 0x00,
|
||||
0x3f, 0xfe, 0x0f, 0xf0, 0xff, 0x07, 0xff, 0xf3, 0xff, 0xc1, 0xef, 0xfe, 0x00, 0x3f, 0xfe, 0x0f,
|
||||
0xf0, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x82, 0x00, 0x00, 0x1f, 0xff, 0x0f, 0xf0, 0xff, 0x1f,
|
||||
0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x07, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff, 0xff, 0xff,
|
||||
0xc0, 0x00, 0x00, 0x00, 0x07, 0xff, 0x0f, 0xf0, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x03, 0x8e, 0x0f, 0xf0, 0xff, 0x1f, 0xc1, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x03, 0x88,
|
||||
0x0f, 0xf0, 0xff, 0x0f, 0x80, 0xff, 0xff, 0xc1, 0xff, 0xfc, 0x00, 0xff, 0xfe, 0x0f, 0xf0, 0xff,
|
||||
0x06, 0x00, 0x73, 0xff, 0xc3, 0xff, 0xfe, 0x01, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0x00, 0x00, 0x03,
|
||||
0xff, 0xc3, 0xff, 0xff, 0x83, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x07, 0x0c, 0x73, 0xff, 0xc3, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x0f, 0xfe, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xf0,
|
||||
0xff, 0x1f, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff,
|
||||
0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xc3,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x8f, 0xf0, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f,
|
||||
0xf0, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xf0, 0xfe, 0x1f,
|
||||
0xfe, 0xfb, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfc, 0x0f, 0x9e, 0x73, 0xff,
|
||||
0x81, 0xf9, 0xf7, 0xe7, 0x9c, 0xff, 0x03, 0xf0, 0xfc, 0x07, 0xfe, 0xfb, 0xc0, 0x00, 0xf0, 0x00,
|
||||
0x6f, 0xbe, 0xfe, 0x03, 0xf0, 0x3c, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe,
|
||||
0x03, 0xc0, 0x1c, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x03, 0x80, 0x1e,
|
||||
0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x07, 0x80, 0x3f, 0x0f, 0xff, 0xff,
|
||||
0xe0, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0x0f, 0xc0, 0x1f, 0x8f, 0xff, 0xff, 0xe7, 0xff, 0xff,
|
||||
0xfe, 0x7f, 0xff, 0xff, 0x1f, 0x80, 0x1f, 0xc7, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfe, 0x3f, 0x80, 0x07, 0xc3, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xfc, 0x3e, 0x00,
|
||||
0x07, 0xc1, 0xfe, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xcf, 0xf7, 0xf8, 0x3e, 0x00, 0x01, 0x00, 0xfc,
|
||||
0x7e, 0x7f, 0xff, 0xff, 0xff, 0xe7, 0xe3, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
|
||||
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0,
|
||||
0x00, 0x00, 0x00, 0x00};
|
||||
114
applications/plugins/doom/compiled/assets_icons.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
#include <gui/icon.h>
|
||||
|
||||
#ifndef _sprites_h
|
||||
#define _sprites_h
|
||||
|
||||
#define bmp_font_width 24 // in bytes
|
||||
#define bmp_font_height 6
|
||||
#define bmp_font_width_pxs 192
|
||||
#define bmp_font_height_pxs 48
|
||||
#define CHAR_MAP " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.,-_(){}[]#"
|
||||
#define CHAR_WIDTH 4
|
||||
#define CHAR_HEIGHT 6
|
||||
|
||||
#define BMP_GUN_WIDTH 32
|
||||
#define BMP_GUN_HEIGHT 32
|
||||
|
||||
#define BMP_FIRE_WIDTH 24
|
||||
#define BMP_FIRE_HEIGHT 20
|
||||
|
||||
#define BMP_IMP_WIDTH 32
|
||||
#define BMP_IMP_HEIGHT 32
|
||||
#define BMP_IMP_COUNT 5
|
||||
|
||||
#define BMP_FIREBALL_WIDTH 16
|
||||
#define BMP_FIREBALL_HEIGHT 16
|
||||
|
||||
#define BMP_DOOR_WIDTH 100
|
||||
#define BMP_DOOR_HEIGHT 100
|
||||
|
||||
#define BMP_ITEMS_WIDTH 16
|
||||
#define BMP_ITEMS_HEIGHT 16
|
||||
#define BMP_ITEMS_COUNT 2
|
||||
|
||||
#define BMP_LOGO_WIDTH 72
|
||||
#define BMP_LOGO_HEIGHT 47
|
||||
|
||||
#define GRADIENT_WIDTH 2
|
||||
#define GRADIENT_HEIGHT 8
|
||||
#define GRADIENT_COUNT 8
|
||||
#define GRADIENT_WHITE 7
|
||||
#define GRADIENT_BLACK 0
|
||||
|
||||
// Inverted icons
|
||||
extern const Icon I_fire_inv;
|
||||
extern const Icon I_gun_inv;
|
||||
extern const Icon I_gun_mask_inv;
|
||||
extern const Icon I_logo_inv;
|
||||
|
||||
// Fonts
|
||||
extern const uint8_t zero[];
|
||||
extern const uint8_t one[];
|
||||
extern const uint8_t two[];
|
||||
extern const uint8_t three[];
|
||||
extern const uint8_t four[];
|
||||
extern const uint8_t five[];
|
||||
extern const uint8_t six[];
|
||||
extern const uint8_t seven[];
|
||||
extern const uint8_t eight[];
|
||||
extern const uint8_t nine[];
|
||||
extern const uint8_t A[];
|
||||
extern const uint8_t B[];
|
||||
extern const uint8_t C[];
|
||||
extern const uint8_t D[];
|
||||
extern const uint8_t E[];
|
||||
extern const uint8_t F[];
|
||||
extern const uint8_t G[];
|
||||
extern const uint8_t H[];
|
||||
extern const uint8_t I[];
|
||||
extern const uint8_t J[];
|
||||
extern const uint8_t K[];
|
||||
extern const uint8_t L[];
|
||||
extern const uint8_t M[];
|
||||
extern const uint8_t N[];
|
||||
extern const uint8_t O[];
|
||||
extern const uint8_t P[];
|
||||
extern const uint8_t Q[];
|
||||
extern const uint8_t R[];
|
||||
extern const uint8_t S[];
|
||||
extern const uint8_t T[];
|
||||
extern const uint8_t U[];
|
||||
extern const uint8_t V[];
|
||||
extern const uint8_t W[];
|
||||
extern const uint8_t X[];
|
||||
extern const uint8_t Y[];
|
||||
extern const uint8_t Z[];
|
||||
extern const uint8_t dot[];
|
||||
extern const uint8_t comma[];
|
||||
extern const uint8_t dash[];
|
||||
extern const uint8_t underscore[];
|
||||
extern const uint8_t bracket_open[];
|
||||
extern const uint8_t bracket_close[];
|
||||
extern const uint8_t cross_left[];
|
||||
extern const uint8_t cross_right[];
|
||||
extern const uint8_t pacman_left[];
|
||||
extern const uint8_t pacman_right[];
|
||||
extern const uint8_t box[];
|
||||
extern const uint8_t* char_arr[48];
|
||||
extern const uint8_t gradient[];
|
||||
//extern const uint8_t gun[]
|
||||
//extern const uint8_t gun_mask[]
|
||||
extern const uint8_t gun[];
|
||||
extern const uint8_t gun_mask[];
|
||||
|
||||
extern const uint8_t imp_inv[];
|
||||
extern const uint8_t imp_mask_inv[];
|
||||
extern const uint8_t fireball[];
|
||||
extern const uint8_t fireball_mask[];
|
||||
extern const uint8_t item[];
|
||||
extern const uint8_t item_mask[];
|
||||
|
||||
extern const uint8_t door[];
|
||||
|
||||
#endif
|
||||
91
applications/plugins/doom/constants.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef _constants_h
|
||||
#define _constants_h
|
||||
#define PB_CONSTEXPR constexpr
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
// Key pinout
|
||||
#define USE_INPUT_PULLUP
|
||||
#define K_LEFT 6
|
||||
#define K_RIGHT 7
|
||||
#define K_UP 8
|
||||
#define K_DOWN 3
|
||||
#define K_FIRE 10
|
||||
|
||||
// SNES Controller
|
||||
// uncomment following line to enable snes controller support
|
||||
// #define SNES_CONTROLLER
|
||||
const uint8_t DATA_CLOCK = 11;
|
||||
const uint8_t DATA_LATCH = 12;
|
||||
const uint8_t DATA_SERIAL = 13;
|
||||
|
||||
// Sound
|
||||
const uint8_t SOUND_PIN = 9; // do not change, belongs to used timer
|
||||
|
||||
// GFX settings
|
||||
#define OPTIMIZE_SSD1306 // Optimizations for SSD1366 displays
|
||||
|
||||
#define FRAME_TIME 66.666666 // Desired time per frame in ms (66.666666 is ~15 fps)
|
||||
#define RES_DIVIDER 2
|
||||
|
||||
/* Higher values will result in lower horizontal resolution when rasterize and lower process and memory usage
|
||||
Lower will require more process and memory, but looks nicer
|
||||
*/
|
||||
#define Z_RES_DIVIDER 2 // Zbuffer resolution divider. We sacrifice resolution to save memory
|
||||
#define DISTANCE_MULTIPLIER 20
|
||||
|
||||
/* Distances are stored as uint8_t, multiplying the distance we can obtain more precision taking care
|
||||
of keep numbers inside the type range. Max is 256 / MAX_RENDER_DEPTH
|
||||
*/
|
||||
|
||||
#define MAX_RENDER_DEPTH 12
|
||||
#define MAX_SPRITE_DEPTH 8
|
||||
|
||||
#define ZBUFFER_SIZE SCREEN_WIDTH / Z_RES_DIVIDER
|
||||
|
||||
// Level
|
||||
#define LEVEL_WIDTH_BASE 6
|
||||
#define LEVEL_WIDTH (1 << LEVEL_WIDTH_BASE)
|
||||
#define LEVEL_HEIGHT 57
|
||||
#define LEVEL_SIZE LEVEL_WIDTH / 2 * LEVEL_HEIGHT
|
||||
|
||||
// scenes
|
||||
#define INTRO 0
|
||||
#define GAME_PLAY 1
|
||||
|
||||
// Game
|
||||
#define GUN_TARGET_POS 18
|
||||
#define GUN_SHOT_POS GUN_TARGET_POS + 4
|
||||
|
||||
#define ROT_SPEED .12
|
||||
#define MOV_SPEED .2
|
||||
#define MOV_SPEED_INV 5 // 1 / MOV_SPEED
|
||||
|
||||
#define JOGGING_SPEED .005
|
||||
#define ENEMY_SPEED .02
|
||||
#define FIREBALL_SPEED .2
|
||||
#define FIREBALL_ANGLES 45 // Num of angles per PI
|
||||
|
||||
#define MAX_ENTITIES 10 // Max num of active entities
|
||||
#define MAX_STATIC_ENTITIES 28 // Max num of entities in sleep mode
|
||||
|
||||
#define MAX_ENTITY_DISTANCE 200 // * DISTANCE_MULTIPLIER
|
||||
#define MAX_ENEMY_VIEW 80 // * DISTANCE_MULTIPLIER
|
||||
#define ITEM_COLLIDER_DIST 6 // * DISTANCE_MULTIPLIER
|
||||
#define ENEMY_COLLIDER_DIST 4 // * DISTANCE_MULTIPLIER
|
||||
#define FIREBALL_COLLIDER_DIST 2 // * DISTANCE_MULTIPLIER
|
||||
#define ENEMY_MELEE_DIST 6 // * DISTANCE_MULTIPLIER
|
||||
#define WALL_COLLIDER_DIST .2
|
||||
|
||||
#define ENEMY_MELEE_DAMAGE 8
|
||||
#define ENEMY_FIREBALL_DAMAGE 20
|
||||
#define GUN_MAX_DAMAGE 20
|
||||
|
||||
// display
|
||||
const uint8_t SCREEN_WIDTH = 128;
|
||||
const uint8_t SCREEN_HEIGHT = 64;
|
||||
const uint8_t HALF_WIDTH = SCREEN_WIDTH / 2;
|
||||
const uint8_t RENDER_HEIGHT = 56; // raycaster working height (the rest is for the hud)
|
||||
const uint8_t HALF_HEIGHT = SCREEN_HEIGHT / 2;
|
||||
|
||||
#endif
|
||||
282
applications/plugins/doom/display.h
Normal file
@@ -0,0 +1,282 @@
|
||||
#include <gui/gui.h>
|
||||
#include <gui/canvas_i.h>
|
||||
#include <furi_hal.h>
|
||||
#include <u8g2_glue.h>
|
||||
#include "constants.h"
|
||||
#include "compiled/assets_icons.h"
|
||||
|
||||
#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
|
||||
|
||||
static const uint8_t bit_mask[8] = {128, 64, 32, 16, 8, 4, 2, 1};
|
||||
|
||||
#define pgm_read_byte(addr) (*(const unsigned char*)(addr))
|
||||
#define read_bit(b, n) b& pgm_read_byte(bit_mask + n) ? 1 : 0
|
||||
//#define read_bit(byte, index) (((unsigned)(byte) >> (index)) & 1)
|
||||
|
||||
void drawVLine(uint8_t x, int8_t start_y, int8_t end_y, uint8_t intensity, Canvas* const canvas);
|
||||
void drawPixel(int8_t x, int8_t y, bool color, bool raycasterViewport, Canvas* const canvas);
|
||||
void drawSprite(
|
||||
int8_t x,
|
||||
int8_t y,
|
||||
const uint8_t* bitmap,
|
||||
const uint8_t* bitmap_mask,
|
||||
int16_t w,
|
||||
int16_t h,
|
||||
uint8_t sprite,
|
||||
double distance,
|
||||
Canvas* const canvas);
|
||||
void drawBitmap(
|
||||
int16_t x,
|
||||
int16_t y,
|
||||
const Icon* i,
|
||||
int16_t w,
|
||||
int16_t h,
|
||||
uint16_t color,
|
||||
Canvas* const canvas);
|
||||
void drawTextSpace(int8_t x, int8_t y, char* txt, uint8_t space, Canvas* const canvas);
|
||||
void drawChar(int8_t x, int8_t y, char ch, Canvas* const canvas);
|
||||
void clearRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, Canvas* const canvas);
|
||||
void drawGun(
|
||||
int16_t x,
|
||||
int16_t y,
|
||||
const uint8_t* bitmap,
|
||||
int16_t w,
|
||||
int16_t h,
|
||||
uint16_t color,
|
||||
Canvas* const canvas);
|
||||
void drawRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, Canvas* const canvas);
|
||||
void drawText(uint8_t x, uint8_t y, uint8_t num, Canvas* const canvas);
|
||||
void fadeScreen(uint8_t intensity, bool color, Canvas* const canvas);
|
||||
bool getGradientPixel(uint8_t x, uint8_t y, uint8_t i);
|
||||
double getActualFps();
|
||||
void fps();
|
||||
void setupDisplay(Canvas* canvas);
|
||||
uint8_t reverse_bits(uint8_t num);
|
||||
|
||||
// FPS control
|
||||
double delta = 1;
|
||||
uint32_t lastFrameTime = 0;
|
||||
uint8_t zbuffer[128]; /// 128 = screen width & REMOVE WHEN DISPLAY.H IMPLEMENTED
|
||||
uint8_t* display_buf = NULL;
|
||||
|
||||
void drawGun(
|
||||
int16_t x,
|
||||
int16_t y,
|
||||
const uint8_t* bitmap,
|
||||
int16_t w,
|
||||
int16_t h,
|
||||
uint16_t color,
|
||||
Canvas* const canvas) {
|
||||
int16_t byteWidth = (w + 7) / 8;
|
||||
uint8_t byte = 0;
|
||||
for(int16_t j = 0; j < h; j++, y++) {
|
||||
for(int16_t i = 0; i < w; i++) {
|
||||
if(i & 7)
|
||||
byte <<= 1;
|
||||
else
|
||||
byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]);
|
||||
if(byte & 0x80) drawPixel(x + i, y, color, false, canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawVLine(uint8_t x, int8_t start_y, int8_t end_y, uint8_t intensity, Canvas* const canvas) {
|
||||
UNUSED(intensity);
|
||||
uint8_t dots = end_y - start_y;
|
||||
for(int i = 0; i < dots; i++) {
|
||||
canvas_draw_dot(canvas, x, start_y + i);
|
||||
}
|
||||
}
|
||||
|
||||
void setupDisplay(Canvas* canvas) {
|
||||
memset(zbuffer, 0xff, 128);
|
||||
display_buf = (uint8_t*)canvas_get_buffer(canvas);
|
||||
//display_buf = u8g2_GetBufferPtr(&canvas->fb);
|
||||
}
|
||||
|
||||
void drawBitmap(
|
||||
int16_t x,
|
||||
int16_t y,
|
||||
const Icon* i,
|
||||
int16_t w,
|
||||
int16_t h,
|
||||
uint16_t color,
|
||||
Canvas* const canvas) {
|
||||
UNUSED(color);
|
||||
canvas_draw_icon_bitmap(canvas, x, y, w, h, i);
|
||||
}
|
||||
|
||||
void drawText(uint8_t x, uint8_t y, uint8_t num, Canvas* const canvas) {
|
||||
char buf[4];
|
||||
itoa(num, buf, 10);
|
||||
drawTextSpace(x, y, buf, 1, canvas);
|
||||
}
|
||||
|
||||
void drawTextSpace(int8_t x, int8_t y, char* txt, uint8_t space, Canvas* const canvas) {
|
||||
uint8_t pos = x;
|
||||
uint8_t i = 0;
|
||||
char ch;
|
||||
while((ch = txt[i]) != '\0') {
|
||||
drawChar(pos, y, ch, canvas);
|
||||
i++;
|
||||
pos += CHAR_WIDTH + space;
|
||||
|
||||
// shortcut on end of screen
|
||||
if(pos > SCREEN_WIDTH) return;
|
||||
}
|
||||
}
|
||||
|
||||
// Custom drawBitmap method with scale support, mask, zindex and pattern filling
|
||||
void drawSprite(
|
||||
int8_t x,
|
||||
int8_t y,
|
||||
const uint8_t* bitmap,
|
||||
const uint8_t* bitmap_mask,
|
||||
int16_t w,
|
||||
int16_t h,
|
||||
uint8_t sprite,
|
||||
double distance,
|
||||
Canvas* const canvas) {
|
||||
uint8_t tw = (double)w / distance;
|
||||
uint8_t th = (double)h / distance;
|
||||
uint8_t byte_width = w / 8;
|
||||
uint8_t pixel_size = fmax(1, (double)1.0 / (double)distance);
|
||||
uint16_t sprite_offset = byte_width * h * sprite;
|
||||
|
||||
bool pixel;
|
||||
bool maskPixel;
|
||||
|
||||
// Don't draw the whole sprite if the anchor is hidden by z buffer
|
||||
// Not checked per pixel for performance reasons
|
||||
if(zbuffer[(int)(fmin(fmax(x, 0), ZBUFFER_SIZE - 1) / Z_RES_DIVIDER)] <
|
||||
distance * DISTANCE_MULTIPLIER) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint8_t ty = 0; ty < th; ty += pixel_size) {
|
||||
// Don't draw out of screen
|
||||
if(y + ty < 0 || y + ty >= RENDER_HEIGHT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t sy = ty * distance; // The y from the sprite
|
||||
|
||||
for(uint8_t tx = 0; tx < tw; tx += pixel_size) {
|
||||
uint8_t sx = tx * distance; // The x from the sprite
|
||||
uint16_t byte_offset = sprite_offset + sy * byte_width + sx / 8;
|
||||
|
||||
// Don't draw out of screen
|
||||
if(x + tx < 0 || x + tx >= SCREEN_WIDTH) {
|
||||
continue;
|
||||
}
|
||||
|
||||
maskPixel = read_bit(pgm_read_byte(bitmap_mask + byte_offset), sx % 8);
|
||||
|
||||
if(maskPixel) {
|
||||
pixel = read_bit(pgm_read_byte(bitmap + byte_offset), sx % 8);
|
||||
for(uint8_t ox = 0; ox < pixel_size; ox++) {
|
||||
for(uint8_t oy = 0; oy < pixel_size; oy++) {
|
||||
if(bitmap == imp_inv)
|
||||
drawPixel(x + tx + ox, y + ty + oy, 1, true, canvas);
|
||||
else
|
||||
drawPixel(x + tx + ox, y + ty + oy, pixel, true, canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawPixel(int8_t x, int8_t y, bool color, bool raycasterViewport, Canvas* const canvas) {
|
||||
if(x < 0 || x >= SCREEN_WIDTH || y < 0 ||
|
||||
y >= (raycasterViewport ? RENDER_HEIGHT : SCREEN_HEIGHT)) {
|
||||
return;
|
||||
}
|
||||
if(color)
|
||||
canvas_draw_dot(canvas, x, y);
|
||||
else {
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_dot(canvas, x, y);
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
void drawChar(int8_t x, int8_t y, char ch, Canvas* const canvas) {
|
||||
uint8_t lsb;
|
||||
uint8_t c = 0;
|
||||
while(CHAR_MAP[c] != ch && CHAR_MAP[c] != '\0') c++;
|
||||
for(uint8_t i = 0; i < 6; i++) {
|
||||
//lsb = (char_arr[c][i] >> 4);
|
||||
lsb = reverse_bits(char_arr[c][i]);
|
||||
for(uint8_t n = 0; n < 4; n++) {
|
||||
if(CHECK_BIT(lsb, n)) {
|
||||
drawPixel(x + n, y + i, true, false, canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clearRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, Canvas* const canvas) {
|
||||
canvas_invert_color(canvas);
|
||||
|
||||
for(int i = 0; i < w; i++) {
|
||||
for(int j = 0; j < h; j++) {
|
||||
canvas_draw_dot(canvas, x + i, y + j);
|
||||
}
|
||||
}
|
||||
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
|
||||
void drawRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, Canvas* const canvas) {
|
||||
for(int i = 0; i < w; i++) {
|
||||
for(int j = 0; j < h; j++) {
|
||||
canvas_draw_dot(canvas, x + i, y + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool getGradientPixel(uint8_t x, uint8_t y, uint8_t i) {
|
||||
if(i == 0) return 0;
|
||||
if(i >= GRADIENT_COUNT - 1) return 1;
|
||||
|
||||
uint8_t index =
|
||||
fmax(0, fmin(GRADIENT_COUNT - 1, i)) * GRADIENT_WIDTH * GRADIENT_HEIGHT // gradient index
|
||||
+ y * GRADIENT_WIDTH % (GRADIENT_WIDTH * GRADIENT_HEIGHT) // y byte offset
|
||||
+ x / GRADIENT_HEIGHT % GRADIENT_WIDTH; // x byte offset
|
||||
//uint8_t *gradient_data = NULL;
|
||||
//furi_hal_compress_icon_decode(icon_get_data(&I_gradient_inv), &gradient_data);
|
||||
// return the bit based on x
|
||||
return read_bit(pgm_read_byte(gradient + index), x % 8);
|
||||
}
|
||||
|
||||
void fadeScreen(uint8_t intensity, bool color, Canvas* const canvas) {
|
||||
for(uint8_t x = 0; x < SCREEN_WIDTH; x++) {
|
||||
for(uint8_t y = 0; y < SCREEN_HEIGHT; y++) {
|
||||
if(getGradientPixel(x, y, intensity)) drawPixel(x, y, color, false, canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a delay to limit play to specified fps
|
||||
// Calculates also delta to keep movement consistent in lower framerates
|
||||
void fps() {
|
||||
while(furi_get_tick() - lastFrameTime < FRAME_TIME)
|
||||
;
|
||||
delta = (double)(furi_get_tick() - lastFrameTime) / (double)FRAME_TIME;
|
||||
lastFrameTime = furi_get_tick();
|
||||
}
|
||||
|
||||
double getActualFps() {
|
||||
return 1000 / ((double)FRAME_TIME * (double)delta);
|
||||
}
|
||||
|
||||
uint8_t reverse_bits(uint8_t num) {
|
||||
unsigned int NO_OF_BITS = sizeof(num) * 8;
|
||||
uint8_t reverse_num = 0;
|
||||
uint8_t i;
|
||||
for(i = 0; i < NO_OF_BITS; i++) {
|
||||
if((num & (1 << i))) reverse_num |= 1 << ((NO_OF_BITS - 1) - i);
|
||||
}
|
||||
return reverse_num;
|
||||
}
|
||||
1105
applications/plugins/doom/doom.c
Normal file
BIN
applications/plugins/doom/doom_10px.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
499
applications/plugins/doom/doom_music_player_worker.c
Normal file
@@ -0,0 +1,499 @@
|
||||
#include "doom_music_player_worker.h"
|
||||
|
||||
#include <furi_hal.h>
|
||||
#include <furi.h>
|
||||
|
||||
#include <storage/storage.h>
|
||||
#include <lib/flipper_format/flipper_format.h>
|
||||
|
||||
#include <m-array.h>
|
||||
|
||||
#define TAG "MusicPlayerWorker"
|
||||
|
||||
#define MUSIC_PLAYER_FILETYPE "Flipper Music Format"
|
||||
#define MUSIC_PLAYER_VERSION 0
|
||||
|
||||
#define SEMITONE_PAUSE 0xFF
|
||||
|
||||
#define NOTE_C4 261.63f
|
||||
#define NOTE_C4_SEMITONE (4.0f * 12.0f)
|
||||
#define TWO_POW_TWELTH_ROOT 1.059463094359f
|
||||
|
||||
typedef struct {
|
||||
uint8_t semitone;
|
||||
uint8_t duration;
|
||||
uint8_t dots;
|
||||
} NoteBlock;
|
||||
|
||||
ARRAY_DEF(NoteBlockArray, NoteBlock, M_POD_OPLIST);
|
||||
|
||||
struct MusicPlayerWorker {
|
||||
FuriThread* thread;
|
||||
bool should_work;
|
||||
|
||||
MusicPlayerWorkerCallback callback;
|
||||
void* callback_context;
|
||||
|
||||
float volume;
|
||||
uint32_t bpm;
|
||||
uint32_t duration;
|
||||
uint32_t octave;
|
||||
NoteBlockArray_t notes;
|
||||
};
|
||||
|
||||
static int32_t music_player_worker_thread_callback(void* context) {
|
||||
furi_assert(context);
|
||||
MusicPlayerWorker* instance = context;
|
||||
|
||||
NoteBlockArray_it_t it;
|
||||
NoteBlockArray_it(it, instance->notes);
|
||||
|
||||
while(instance->should_work) {
|
||||
if(NoteBlockArray_end_p(it)) {
|
||||
NoteBlockArray_it(it, instance->notes);
|
||||
furi_delay_ms(10);
|
||||
} else {
|
||||
NoteBlock* note_block = NoteBlockArray_ref(it);
|
||||
|
||||
float note_from_a4 = (float)note_block->semitone - NOTE_C4_SEMITONE;
|
||||
float frequency = NOTE_C4 * powf(TWO_POW_TWELTH_ROOT, note_from_a4);
|
||||
float duration =
|
||||
60.0 * furi_kernel_get_tick_frequency() * 4 / instance->bpm / note_block->duration;
|
||||
uint32_t dots = note_block->dots;
|
||||
while(dots > 0) {
|
||||
duration += duration / 2;
|
||||
dots--;
|
||||
}
|
||||
uint32_t next_tick = furi_get_tick() + duration;
|
||||
float volume = instance->volume;
|
||||
|
||||
if(instance->callback) {
|
||||
instance->callback(
|
||||
note_block->semitone,
|
||||
note_block->dots,
|
||||
note_block->duration,
|
||||
0.0,
|
||||
instance->callback_context);
|
||||
}
|
||||
|
||||
furi_hal_speaker_stop();
|
||||
furi_hal_speaker_start(frequency, volume);
|
||||
while(instance->should_work && furi_get_tick() < next_tick) {
|
||||
volume *= 0.9945679;
|
||||
furi_hal_speaker_set_volume(volume);
|
||||
furi_delay_ms(2);
|
||||
}
|
||||
NoteBlockArray_next(it);
|
||||
}
|
||||
}
|
||||
|
||||
furi_hal_speaker_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MusicPlayerWorker* music_player_worker_alloc() {
|
||||
MusicPlayerWorker* instance = malloc(sizeof(MusicPlayerWorker));
|
||||
|
||||
NoteBlockArray_init(instance->notes);
|
||||
|
||||
instance->thread = furi_thread_alloc();
|
||||
furi_thread_set_name(instance->thread, "MusicPlayerWorker");
|
||||
furi_thread_set_stack_size(instance->thread, 1024);
|
||||
furi_thread_set_context(instance->thread, instance);
|
||||
furi_thread_set_callback(instance->thread, music_player_worker_thread_callback);
|
||||
|
||||
instance->volume = 1.0f;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void music_player_worker_free(MusicPlayerWorker* instance) {
|
||||
furi_assert(instance);
|
||||
furi_thread_free(instance->thread);
|
||||
NoteBlockArray_clear(instance->notes);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
static bool is_digit(const char c) {
|
||||
return isdigit(c) != 0;
|
||||
}
|
||||
|
||||
static bool is_letter(const char c) {
|
||||
return islower(c) != 0 || isupper(c) != 0;
|
||||
}
|
||||
|
||||
static bool is_space(const char c) {
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
static size_t extract_number(const char* string, uint32_t* number) {
|
||||
size_t ret = 0;
|
||||
while(is_digit(*string)) {
|
||||
*number *= 10;
|
||||
*number += (*string - '0');
|
||||
string++;
|
||||
ret++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t extract_dots(const char* string, uint32_t* number) {
|
||||
size_t ret = 0;
|
||||
while(*string == '.') {
|
||||
*number += 1;
|
||||
string++;
|
||||
ret++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t extract_char(const char* string, char* symbol) {
|
||||
if(is_letter(*string)) {
|
||||
*symbol = *string;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t extract_sharp(const char* string, char* symbol) {
|
||||
if(*string == '#' || *string == '_') {
|
||||
*symbol = '#';
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t skip_till(const char* string, const char symbol) {
|
||||
size_t ret = 0;
|
||||
while(*string != '\0' && *string != symbol) {
|
||||
string++;
|
||||
ret++;
|
||||
}
|
||||
if(*string != symbol) {
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool music_player_worker_add_note(
|
||||
MusicPlayerWorker* instance,
|
||||
uint8_t semitone,
|
||||
uint8_t duration,
|
||||
uint8_t dots) {
|
||||
NoteBlock note_block;
|
||||
|
||||
note_block.semitone = semitone;
|
||||
note_block.duration = duration;
|
||||
note_block.dots = dots;
|
||||
|
||||
NoteBlockArray_push_back(instance->notes, note_block);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int8_t note_to_semitone(const char note) {
|
||||
switch(note) {
|
||||
case 'C':
|
||||
return 0;
|
||||
// C#
|
||||
case 'D':
|
||||
return 2;
|
||||
// D#
|
||||
case 'E':
|
||||
return 4;
|
||||
case 'F':
|
||||
return 5;
|
||||
// F#
|
||||
case 'G':
|
||||
return 7;
|
||||
// G#
|
||||
case 'A':
|
||||
return 9;
|
||||
// A#
|
||||
case 'B':
|
||||
return 11;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const char* string) {
|
||||
const char* cursor = string;
|
||||
bool result = true;
|
||||
|
||||
while(*cursor != '\0') {
|
||||
if(!is_space(*cursor)) {
|
||||
uint32_t duration = 0;
|
||||
char note_char = '\0';
|
||||
char sharp_char = '\0';
|
||||
uint32_t octave = 0;
|
||||
uint32_t dots = 0;
|
||||
|
||||
// Parsing
|
||||
cursor += extract_number(cursor, &duration);
|
||||
cursor += extract_char(cursor, ¬e_char);
|
||||
cursor += extract_sharp(cursor, &sharp_char);
|
||||
cursor += extract_number(cursor, &octave);
|
||||
cursor += extract_dots(cursor, &dots);
|
||||
|
||||
// Post processing
|
||||
note_char = toupper(note_char);
|
||||
if(!duration) {
|
||||
duration = instance->duration;
|
||||
}
|
||||
if(!octave) {
|
||||
octave = instance->octave;
|
||||
}
|
||||
|
||||
// Validation
|
||||
bool is_valid = true;
|
||||
is_valid &= (duration >= 1 && duration <= 128);
|
||||
is_valid &= ((note_char >= 'A' && note_char <= 'G') || note_char == 'P');
|
||||
is_valid &= (sharp_char == '#' || sharp_char == '\0');
|
||||
is_valid &= (octave <= 16);
|
||||
is_valid &= (dots <= 16);
|
||||
if(!is_valid) {
|
||||
FURI_LOG_E(
|
||||
TAG,
|
||||
"Invalid note: %u%c%c%u.%u",
|
||||
duration,
|
||||
note_char == '\0' ? '_' : note_char,
|
||||
sharp_char == '\0' ? '_' : sharp_char,
|
||||
octave,
|
||||
dots);
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Note to semitones
|
||||
uint8_t semitone = 0;
|
||||
if(note_char == 'P') {
|
||||
semitone = SEMITONE_PAUSE;
|
||||
} else {
|
||||
semitone += octave * 12;
|
||||
semitone += note_to_semitone(note_char);
|
||||
semitone += sharp_char == '#' ? 1 : 0;
|
||||
}
|
||||
|
||||
if(music_player_worker_add_note(instance, semitone, duration, dots)) {
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"Added note: %c%c%u.%u = %u %u",
|
||||
note_char == '\0' ? '_' : note_char,
|
||||
sharp_char == '\0' ? '_' : sharp_char,
|
||||
octave,
|
||||
dots,
|
||||
semitone,
|
||||
duration);
|
||||
} else {
|
||||
FURI_LOG_E(
|
||||
TAG,
|
||||
"Invalid note: %c%c%u.%u = %u %u",
|
||||
note_char == '\0' ? '_' : note_char,
|
||||
sharp_char == '\0' ? '_' : sharp_char,
|
||||
octave,
|
||||
dots,
|
||||
semitone,
|
||||
duration);
|
||||
}
|
||||
cursor += skip_till(cursor, ',');
|
||||
}
|
||||
|
||||
if(*cursor != '\0') cursor++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool music_player_worker_load(MusicPlayerWorker* instance, const char* file_path) {
|
||||
furi_assert(instance);
|
||||
furi_assert(file_path);
|
||||
|
||||
bool ret = false;
|
||||
if(strcasestr(file_path, ".fmf")) {
|
||||
ret = music_player_worker_load_fmf_from_file(instance, file_path);
|
||||
} else {
|
||||
ret = music_player_worker_load_rtttl_from_file(instance, file_path);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const char* file_path) {
|
||||
furi_assert(instance);
|
||||
furi_assert(file_path);
|
||||
|
||||
bool result = false;
|
||||
string_t temp_str;
|
||||
string_init(temp_str);
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
|
||||
do {
|
||||
if(!flipper_format_file_open_existing(file, file_path)) break;
|
||||
|
||||
uint32_t version = 0;
|
||||
if(!flipper_format_read_header(file, temp_str, &version)) break;
|
||||
if(string_cmp_str(temp_str, MUSIC_PLAYER_FILETYPE) || (version != MUSIC_PLAYER_VERSION)) {
|
||||
FURI_LOG_E(TAG, "Incorrect file format or version");
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_uint32(file, "BPM", &instance->bpm, 1)) {
|
||||
FURI_LOG_E(TAG, "BPM is missing");
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_read_uint32(file, "Duration", &instance->duration, 1)) {
|
||||
FURI_LOG_E(TAG, "Duration is missing");
|
||||
break;
|
||||
}
|
||||
if(!flipper_format_read_uint32(file, "Octave", &instance->octave, 1)) {
|
||||
FURI_LOG_E(TAG, "Octave is missing");
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_string(file, "Notes", temp_str)) {
|
||||
FURI_LOG_E(TAG, "Notes is missing");
|
||||
break;
|
||||
}
|
||||
|
||||
if(!music_player_worker_parse_notes(instance, string_get_cstr(temp_str))) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = true;
|
||||
} while(false);
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
flipper_format_free(file);
|
||||
string_clear(temp_str);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const char* file_path) {
|
||||
furi_assert(instance);
|
||||
furi_assert(file_path);
|
||||
|
||||
bool result = false;
|
||||
string_t content;
|
||||
string_init(content);
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
File* file = storage_file_alloc(storage);
|
||||
|
||||
do {
|
||||
if(!storage_file_open(file, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
FURI_LOG_E(TAG, "Unable to open file");
|
||||
break;
|
||||
};
|
||||
|
||||
uint16_t ret = 0;
|
||||
do {
|
||||
uint8_t buffer[65] = {0};
|
||||
ret = storage_file_read(file, buffer, sizeof(buffer) - 1);
|
||||
for(size_t i = 0; i < ret; i++) {
|
||||
string_push_back(content, buffer[i]);
|
||||
}
|
||||
} while(ret > 0);
|
||||
|
||||
string_strim(content);
|
||||
if(!string_size(content)) {
|
||||
FURI_LOG_E(TAG, "Empty file");
|
||||
break;
|
||||
}
|
||||
|
||||
if(!music_player_worker_load_rtttl_from_string(instance, string_get_cstr(content))) {
|
||||
FURI_LOG_E(TAG, "Invalid file content");
|
||||
break;
|
||||
}
|
||||
|
||||
result = true;
|
||||
} while(0);
|
||||
|
||||
storage_file_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
string_clear(content);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool music_player_worker_load_rtttl_from_string(MusicPlayerWorker* instance, const char* string) {
|
||||
furi_assert(instance);
|
||||
|
||||
const char* cursor = string;
|
||||
|
||||
// Skip name
|
||||
cursor += skip_till(cursor, ':');
|
||||
if(*cursor != ':') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Duration
|
||||
cursor += skip_till(cursor, '=');
|
||||
if(*cursor != '=') {
|
||||
return false;
|
||||
}
|
||||
cursor++;
|
||||
cursor += extract_number(cursor, &instance->duration);
|
||||
|
||||
// Octave
|
||||
cursor += skip_till(cursor, '=');
|
||||
if(*cursor != '=') {
|
||||
return false;
|
||||
}
|
||||
cursor++;
|
||||
cursor += extract_number(cursor, &instance->octave);
|
||||
|
||||
// BPM
|
||||
cursor += skip_till(cursor, '=');
|
||||
if(*cursor != '=') {
|
||||
return false;
|
||||
}
|
||||
cursor++;
|
||||
cursor += extract_number(cursor, &instance->bpm);
|
||||
|
||||
// Notes
|
||||
cursor += skip_till(cursor, ':');
|
||||
if(*cursor != ':') {
|
||||
return false;
|
||||
}
|
||||
cursor++;
|
||||
if(!music_player_worker_parse_notes(instance, cursor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void music_player_worker_set_callback(
|
||||
MusicPlayerWorker* instance,
|
||||
MusicPlayerWorkerCallback callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
instance->callback = callback;
|
||||
instance->callback_context = context;
|
||||
}
|
||||
|
||||
void music_player_worker_set_volume(MusicPlayerWorker* instance, float volume) {
|
||||
furi_assert(instance);
|
||||
instance->volume = volume;
|
||||
}
|
||||
|
||||
void music_player_worker_start(MusicPlayerWorker* instance) {
|
||||
furi_assert(instance);
|
||||
furi_assert(instance->should_work == false);
|
||||
|
||||
instance->should_work = true;
|
||||
furi_thread_start(instance->thread);
|
||||
}
|
||||
|
||||
void music_player_worker_stop(MusicPlayerWorker* instance) {
|
||||
furi_assert(instance);
|
||||
furi_assert(instance->should_work == true);
|
||||
|
||||
instance->should_work = false;
|
||||
furi_thread_join(instance->thread);
|
||||
}
|
||||
44
applications/plugins/doom/doom_music_player_worker.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*MusicPlayerWorkerCallback)(
|
||||
uint8_t semitone,
|
||||
uint8_t dots,
|
||||
uint8_t duration,
|
||||
float position,
|
||||
void* context);
|
||||
|
||||
typedef struct MusicPlayerWorker MusicPlayerWorker;
|
||||
|
||||
MusicPlayerWorker* music_player_worker_alloc();
|
||||
|
||||
void music_player_worker_free(MusicPlayerWorker* instance);
|
||||
|
||||
bool music_player_worker_load(MusicPlayerWorker* instance, const char* file_path);
|
||||
|
||||
bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const char* file_path);
|
||||
|
||||
bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const char* file_path);
|
||||
|
||||
bool music_player_worker_load_rtttl_from_string(MusicPlayerWorker* instance, const char* string);
|
||||
|
||||
void music_player_worker_set_callback(
|
||||
MusicPlayerWorker* instance,
|
||||
MusicPlayerWorkerCallback callback,
|
||||
void* context);
|
||||
|
||||
void music_player_worker_set_volume(MusicPlayerWorker* instance, float volume);
|
||||
|
||||
void music_player_worker_start(MusicPlayerWorker* instance);
|
||||
|
||||
void music_player_worker_stop(MusicPlayerWorker* instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
42
applications/plugins/doom/entities.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "entities.h"
|
||||
|
||||
//extern "C"
|
||||
/*Player create_player(double x, double y){
|
||||
return {create_coords((double) x + (double)0.5, (double) y + (double)0.5), create_coords(1, 0), create_coords(0, -0.66), 0, 100, 0};
|
||||
}*/
|
||||
|
||||
Player create_player(double x, double y) {
|
||||
Player p;
|
||||
p.pos = create_coords((double)x + (double)0.5, (double)y + (double)0.5);
|
||||
p.dir = create_coords(1, 0);
|
||||
p.plane = create_coords(0, -0.66);
|
||||
p.velocity = 0;
|
||||
p.health = 100;
|
||||
p.keys = 0;
|
||||
return p; //{create_coords((double) x + (double)0.5, (double) y + (double)0.5), create_coords(1, 0), create_coords(0, -0.66), 0, 100, 0};
|
||||
}
|
||||
|
||||
//extern "C"
|
||||
Entity
|
||||
create_entity(uint8_t type, uint8_t x, uint8_t y, uint8_t initialState, uint8_t initialHealth) {
|
||||
UID uid = create_uid(type, x, y);
|
||||
Coords pos = create_coords((double)x + (double).5, (double)y + (double).5);
|
||||
Entity new_entity; // = { uid, pos, initialState, initialHealth, 0, 0 };
|
||||
new_entity.uid = uid;
|
||||
new_entity.pos = pos;
|
||||
new_entity.state = initialState;
|
||||
new_entity.health = initialHealth;
|
||||
new_entity.distance = 0;
|
||||
new_entity.timer = 0;
|
||||
return new_entity;
|
||||
}
|
||||
|
||||
//extern "C"
|
||||
StaticEntity crate_static_entity(UID uid, uint8_t x, uint8_t y, bool active) {
|
||||
StaticEntity ent;
|
||||
ent.uid = uid;
|
||||
ent.x = x;
|
||||
ent.y = y;
|
||||
ent.active = active;
|
||||
return ent;
|
||||
}
|
||||
56
applications/plugins/doom/entities.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef _entities_h
|
||||
#define _entities_h
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "types.h"
|
||||
|
||||
// Shortcuts
|
||||
//#define create_player(x, y) {create_coords((double) x + (double)0.5, (double) y + (double)0.5), create_coords(1, 0), create_coords(0, -0.66), 0, 100}
|
||||
|
||||
#define create_enemy(x, y) create_entity(E_ENEMY, x, y, S_STAND, 50)
|
||||
#define create_medikit(x, y) create_entity(E_MEDIKIT, x, y, S_STAND, 0)
|
||||
#define create_key(x, y) create_entity(E_KEY, x, y, S_STAND, 0)
|
||||
#define create_fireball(x, y, dir) create_entity(E_FIREBALL, x, y, S_STAND, dir)
|
||||
#define create_door(x, y) create_entity(E_DOOR, x, y, S_STAND, 0)
|
||||
|
||||
// entity statuses
|
||||
#define S_STAND 0
|
||||
#define S_ALERT 1
|
||||
#define S_FIRING 2
|
||||
#define S_MELEE 3
|
||||
#define S_HIT 4
|
||||
#define S_DEAD 5
|
||||
#define S_HIDDEN 6
|
||||
#define S_OPEN 7
|
||||
#define S_CLOSE 8
|
||||
|
||||
typedef struct Player {
|
||||
Coords pos;
|
||||
Coords dir;
|
||||
Coords plane;
|
||||
double velocity;
|
||||
uint8_t health;
|
||||
uint8_t keys;
|
||||
} Player;
|
||||
|
||||
typedef struct Entity {
|
||||
UID uid;
|
||||
Coords pos;
|
||||
uint8_t state;
|
||||
uint8_t health; // angle for fireballs
|
||||
uint8_t distance;
|
||||
uint8_t timer;
|
||||
} Entity;
|
||||
|
||||
typedef struct StaticEntity {
|
||||
UID uid;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
bool active;
|
||||
} StaticEntity;
|
||||
|
||||
Entity
|
||||
create_entity(uint8_t type, uint8_t x, uint8_t y, uint8_t initialState, uint8_t initialHealth);
|
||||
StaticEntity create_static_entity(UID uid, uint8_t x, uint8_t y, bool active);
|
||||
Player create_player(double x, double y);
|
||||
#endif
|
||||
188
applications/plugins/doom/level.h
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef _level_h
|
||||
#define _level_h
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
/*
|
||||
Based on E1M1 from Wolfenstein 3D
|
||||
|
||||
################################################################
|
||||
#############################...........########################
|
||||
######....###################........E..########################
|
||||
######....########..........#...........#...####################
|
||||
######.....#######..........L.....E.......M.####################
|
||||
######.....#######..........#...........#...####################
|
||||
##################...########...........########################
|
||||
######.........###...########...........########################
|
||||
######.........###...#############D#############################
|
||||
######.........#......E##########...############################
|
||||
######....E....D...E...##########...############################
|
||||
######.........#.......##########...############################
|
||||
######....E....##################...############################
|
||||
#...##.........##################...############################
|
||||
#.K.######D######################...############################
|
||||
#...#####...###############...#E.....K##########################
|
||||
##D######...###############..####...############################
|
||||
#...#####...###############..####...############################
|
||||
#...#...#...###############..####...############################
|
||||
#...D...#...#####################...############################
|
||||
#...#...#...#####################...############################
|
||||
#...######D#######################L#############################
|
||||
#.E.##.........#################.....#################........##
|
||||
#...##.........############...............############........##
|
||||
#...##...E.....############...............############........##
|
||||
#....#.........############...E.......E....#.........#........##
|
||||
#....L....K....############................D....E....D....E...##
|
||||
#....#.........############................#.........#........##
|
||||
#...##.....E...############...............####....####........##
|
||||
#...##.........############...............#####..#####.....M..##
|
||||
#...##.........#################.....##########..#####........##
|
||||
#...######L#######################D############..###############
|
||||
#...#####...#####################...###########..###############
|
||||
#E.E#####...#####################...###########..###############
|
||||
#...#...#...#####################.E.###########..###############
|
||||
#...D.M.#...#####################...###########..###############
|
||||
#...#...#...#####################...###########..###.#.#.#.#####
|
||||
#...#####...#####################...###########...#.........####
|
||||
#...#####...#####################...###########...D....E..K.####
|
||||
#................##......########...###########...#.........####
|
||||
#....E........E...L...E...X######...################.#.#.#.#####
|
||||
#................##......########...############################
|
||||
#################################...############################
|
||||
#############..#..#..#############L#############################
|
||||
###########....#..#.########....#...#....#######################
|
||||
#############.....##########.P..D...D....#######################
|
||||
############################....#...#....#######################
|
||||
##############..#################...############################
|
||||
##############..############....#...#....#######################
|
||||
############################....D...D....#######################
|
||||
############################....#...#....#######################
|
||||
#################################...############################
|
||||
############################.............#######################
|
||||
############################..........EK.#######################
|
||||
############################.............#######################
|
||||
################################################################
|
||||
*/
|
||||
|
||||
/*
|
||||
Same map above built from some regexp replacements using the legend above.
|
||||
Using this way lets me use only 4 bit to store each block
|
||||
*/
|
||||
const uint8_t sto_level_1[LEVEL_SIZE] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00,
|
||||
0x00, 0x20, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x02, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x90, 0xFF, 0xFF, 0xFF, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xF2,
|
||||
0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x4F, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0x40, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x20, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0x00, 0x02, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00, 0x20, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0x05, 0x00, 0x00, 0x90, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0x00, 0x00, 0x02, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x08, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF2, 0x02, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0x40, 0x80, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x40, 0x00, 0x02, 0x00, 0x90, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x20, 0x00, 0x7F, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00,
|
||||
0x40, 0x00, 0x40, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x40, 0x00, 0x40, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x29, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
|
||||
#endif
|
||||
35
applications/plugins/doom/sound.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef sound_h
|
||||
#define sound_h
|
||||
#include <m-string.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <stdint.h>
|
||||
#include "doom_music_player_worker.h"
|
||||
|
||||
//static const char dspistol[] = "AnyConv:d=,o=,b=120:408,40p,40p,40p,40p,405,40p,40p,40p,405,30p.,30p.,30p.,13p";
|
||||
static const char dsintro[] =
|
||||
"Doom:d=32,o=4,b=56:f,f,f5,f,f,d#5,f,f,c#5,f,f,b,f,f,c5,c#5,f,f,f5,f,f,d#5,f,f,c#5,f,f,8b.,f,f,f5,f,f,d#5,f,f,c#5,f,f,b,f,f,c5,c#5,f,f,f5,f,f,d#5,f,f,c#5,f,f,8b.,a#,a#,a#5,a#,a#,g#5,a#,a#,f#5,a#,a#,e5,a#,a#,f5,f#5,a#,a#,a#5,a#,a#,g#5,a#,a#,f#5,a#,a#,8e5";
|
||||
//static const char dsgetpow[] = "dsgetpow:d=,o=,b=120:407,40p,30.6,407,40p,406,40p,407,40p,40p,407,30p.,407";
|
||||
//static const char dsnoway[] = "dsnoway:d=,o=,b=120:407,30.4";
|
||||
|
||||
#define MUSIC_PLAYER_SEMITONE_HISTORY_SIZE 4
|
||||
static const float MUSIC_PLAYER_VOLUMES[] = {0, .25, .5, .75, 1};
|
||||
|
||||
typedef struct {
|
||||
uint8_t semitone_history[MUSIC_PLAYER_SEMITONE_HISTORY_SIZE];
|
||||
uint8_t duration_history[MUSIC_PLAYER_SEMITONE_HISTORY_SIZE];
|
||||
|
||||
uint8_t volume;
|
||||
uint8_t semitone;
|
||||
uint8_t dots;
|
||||
uint8_t duration;
|
||||
float position;
|
||||
} MusicPlayerModel;
|
||||
|
||||
typedef struct {
|
||||
MusicPlayerModel* model;
|
||||
MusicPlayerWorker* worker;
|
||||
FuriMutex** model_mutex;
|
||||
} MusicPlayer;
|
||||
|
||||
#endif
|
||||
33
applications/plugins/doom/types.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "types.h"
|
||||
|
||||
/*template <class T>
|
||||
inline T sq(T value) {
|
||||
return value * value;
|
||||
}*/
|
||||
|
||||
double sq(double val) {
|
||||
return val * val;
|
||||
}
|
||||
|
||||
//extern "C"
|
||||
Coords create_coords(double x, double y) {
|
||||
Coords cord;
|
||||
cord.x = x;
|
||||
cord.y = y;
|
||||
return cord;
|
||||
}
|
||||
|
||||
//extern "C"
|
||||
uint8_t coords_distance(Coords* a, Coords* b) {
|
||||
return sqrt(sq(a->x - b->x) + sq(a->y - b->y)) * 20;
|
||||
}
|
||||
|
||||
//extern "C"
|
||||
UID create_uid(uint8_t type, uint8_t x, uint8_t y) {
|
||||
return ((y << 6) | x) << 4 | type;
|
||||
}
|
||||
|
||||
//extern "C"
|
||||
uint8_t uid_get_type(UID uid) {
|
||||
return uid & 0x0F;
|
||||
}
|
||||
36
applications/plugins/doom/types.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef _types_h
|
||||
#define _types_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
//#include "constants.h"
|
||||
|
||||
#define UID_null 0
|
||||
|
||||
// Entity types (legend applies to level.h)
|
||||
#define E_FLOOR 0x0 // . (also null)
|
||||
#define E_WALL 0xF // #
|
||||
#define E_PLAYER 0x1 // P
|
||||
#define E_ENEMY 0x2 // E
|
||||
#define E_DOOR 0x4 // D
|
||||
#define E_LOCKEDDOOR 0x5 // L
|
||||
#define E_EXIT 0x7 // X
|
||||
// collectable entities >= 0x8
|
||||
#define E_MEDIKIT 0x8 // M
|
||||
#define E_KEY 0x9 // K
|
||||
#define E_FIREBALL 0xA // not in map
|
||||
|
||||
typedef uint16_t UID;
|
||||
typedef uint8_t EType;
|
||||
|
||||
typedef struct Coords {
|
||||
double x;
|
||||
double y;
|
||||
} Coords;
|
||||
|
||||
UID create_uid(EType type, uint8_t x, uint8_t y);
|
||||
EType uid_get_type(UID uid);
|
||||
Coords create_coords(double x, double y);
|
||||
uint8_t coords_distance(Coords* a, Coords* b);
|
||||
|
||||
#endif
|
||||
12
applications/plugins/flappy_bird/application.fam
Normal file
@@ -0,0 +1,12 @@
|
||||
App(
|
||||
appid="game_flappybird",
|
||||
name="Flappy Bird",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="flappy_game_app",
|
||||
cdefines=["APP_FLAPPY_GAME"],
|
||||
requires=["gui"],
|
||||
stack_size=4 * 1024,
|
||||
order=100,
|
||||
fap_icon="flappy_10px.png",
|
||||
fap_category="Games",
|
||||
)
|
||||
54
applications/plugins/flappy_bird/bird.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <furi.h>
|
||||
|
||||
uint8_t bird_array[3][15][11] = {
|
||||
{
|
||||
{0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0},
|
||||
{0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0},
|
||||
{0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0},
|
||||
{0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0},
|
||||
{0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1},
|
||||
{1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1},
|
||||
{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1},
|
||||
{1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
|
||||
},
|
||||
{
|
||||
{0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},
|
||||
{0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0},
|
||||
{0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0},
|
||||
{0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0},
|
||||
{0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
|
||||
{1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1},
|
||||
{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1},
|
||||
{1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
|
||||
},
|
||||
{
|
||||
{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0},
|
||||
{0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0},
|
||||
{0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0},
|
||||
{0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0},
|
||||
{0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||
{1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1},
|
||||
{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1},
|
||||
{1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0},
|
||||
{0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
|
||||
}};
|
||||
BIN
applications/plugins/flappy_bird/flappy_10px.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
357
applications/plugins/flappy_bird/flappy_bird.c
Normal file
@@ -0,0 +1,357 @@
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bird.h"
|
||||
|
||||
#define TAG "Flappy"
|
||||
#define DEBUG false
|
||||
|
||||
#define FLAPPY_BIRD_HEIGHT 15
|
||||
#define FLAPPY_BIRD_WIDTH 10
|
||||
|
||||
#define FLAPPY_PILAR_MAX 6
|
||||
#define FLAPPY_PILAR_DIST 40
|
||||
|
||||
#define FLAPPY_GAB_HEIGHT 25
|
||||
#define FLAPPY_GAB_WIDTH 5
|
||||
|
||||
#define FLAPPY_GRAVITY_JUMP -1.1
|
||||
#define FLAPPY_GRAVITY_TICK 0.15
|
||||
|
||||
#define FLIPPER_LCD_WIDTH 128
|
||||
#define FLIPPER_LCD_HEIGHT 64
|
||||
|
||||
typedef enum {
|
||||
EventTypeTick,
|
||||
EventTypeKey,
|
||||
} EventType;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} POINT;
|
||||
|
||||
typedef struct {
|
||||
float gravity;
|
||||
POINT point;
|
||||
} BIRD;
|
||||
|
||||
typedef struct {
|
||||
POINT point;
|
||||
int height;
|
||||
int visible;
|
||||
bool passed;
|
||||
} PILAR;
|
||||
|
||||
typedef enum {
|
||||
GameStateLife,
|
||||
GameStateGameOver,
|
||||
} State;
|
||||
|
||||
typedef struct {
|
||||
BIRD bird;
|
||||
int points;
|
||||
int pilars_count;
|
||||
PILAR pilars[FLAPPY_PILAR_MAX];
|
||||
bool debug;
|
||||
State state;
|
||||
} GameState;
|
||||
|
||||
typedef struct {
|
||||
EventType type;
|
||||
InputEvent input;
|
||||
} GameEvent;
|
||||
|
||||
typedef enum {
|
||||
DirectionUp,
|
||||
DirectionRight,
|
||||
DirectionDown,
|
||||
DirectionLeft,
|
||||
} Direction;
|
||||
|
||||
static void flappy_game_random_pilar(GameState* const game_state) {
|
||||
PILAR pilar;
|
||||
|
||||
pilar.passed = false;
|
||||
pilar.visible = 1;
|
||||
pilar.height = random() % (FLIPPER_LCD_HEIGHT - FLAPPY_GAB_HEIGHT) + 1;
|
||||
pilar.point.y = 0;
|
||||
pilar.point.x = FLIPPER_LCD_WIDTH + FLAPPY_GAB_WIDTH + 1;
|
||||
|
||||
game_state->pilars_count++;
|
||||
game_state->pilars[game_state->pilars_count % FLAPPY_PILAR_MAX] = pilar;
|
||||
}
|
||||
|
||||
static void flappy_game_state_init(GameState* const game_state) {
|
||||
BIRD bird;
|
||||
bird.gravity = 0.0f;
|
||||
bird.point.x = 15;
|
||||
bird.point.y = 32;
|
||||
|
||||
game_state->debug = DEBUG;
|
||||
game_state->bird = bird;
|
||||
game_state->pilars_count = 0;
|
||||
game_state->points = 0;
|
||||
game_state->state = GameStateLife;
|
||||
memset(game_state->pilars, 0, sizeof(game_state->pilars));
|
||||
|
||||
flappy_game_random_pilar(game_state);
|
||||
}
|
||||
|
||||
// static void flappy_game_reset(GameState* const game_state) {
|
||||
// FURI_LOG_I(TAG, "Reset Game State\r\n"); // Resetting State
|
||||
// }
|
||||
|
||||
static void flappy_game_tick(GameState* const game_state) {
|
||||
if(game_state->state == GameStateLife) {
|
||||
if(!game_state->debug) {
|
||||
game_state->bird.gravity += FLAPPY_GRAVITY_TICK;
|
||||
game_state->bird.point.y += game_state->bird.gravity;
|
||||
}
|
||||
|
||||
// Checking the location of the last respawned pilar.
|
||||
PILAR* pilar = &game_state->pilars[game_state->pilars_count % FLAPPY_PILAR_MAX];
|
||||
if(pilar->point.x == (FLIPPER_LCD_WIDTH - FLAPPY_PILAR_DIST))
|
||||
flappy_game_random_pilar(game_state);
|
||||
|
||||
// Updating the position/status of the pilars (visiblity, posotion, game points)
|
||||
// | | | | |
|
||||
// | | | | |
|
||||
// |__| | |__|
|
||||
// _____X | X_____
|
||||
// | | | | | // [Pos + Width of pilar] >= [Bird Pos]
|
||||
// |_____| | |_____|
|
||||
// X <----> | X <->
|
||||
// Bird Pos + Lenght of the bird] >= [Pilar]
|
||||
for(int i = 0; i < FLAPPY_PILAR_MAX; i++) {
|
||||
PILAR* pilar = &game_state->pilars[i];
|
||||
if(pilar != NULL && pilar->visible && game_state->state == GameStateLife) {
|
||||
pilar->point.x--;
|
||||
if(game_state->bird.point.x >= pilar->point.x + FLAPPY_GAB_WIDTH &&
|
||||
pilar->passed == false) {
|
||||
pilar->passed = true;
|
||||
game_state->points++;
|
||||
}
|
||||
if(pilar->point.x < -FLAPPY_GAB_WIDTH) pilar->visible = 0;
|
||||
|
||||
// Checking out of bounds
|
||||
if(game_state->bird.point.y < 0 - FLAPPY_BIRD_WIDTH ||
|
||||
game_state->bird.point.y > FLIPPER_LCD_HEIGHT) {
|
||||
game_state->state = GameStateGameOver;
|
||||
break;
|
||||
}
|
||||
|
||||
// Bird inbetween pipes
|
||||
if((game_state->bird.point.x + FLAPPY_BIRD_HEIGHT >= pilar->point.x) &&
|
||||
(game_state->bird.point.x <= pilar->point.x + FLAPPY_GAB_WIDTH)) {
|
||||
// Bird below Bottom Pipe
|
||||
if(game_state->bird.point.y + FLAPPY_BIRD_WIDTH - 2 >=
|
||||
pilar->height + FLAPPY_GAB_HEIGHT) {
|
||||
game_state->state = GameStateGameOver;
|
||||
break;
|
||||
}
|
||||
|
||||
// Bird above Upper Pipe
|
||||
if(game_state->bird.point.y < pilar->height) {
|
||||
game_state->state = GameStateGameOver;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flappy_game_flap(GameState* const game_state) {
|
||||
game_state->bird.gravity = FLAPPY_GRAVITY_JUMP;
|
||||
}
|
||||
|
||||
static void flappy_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||
const GameState* game_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(game_state == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
if(game_state->state == GameStateLife) {
|
||||
// Pilars
|
||||
for(int i = 0; i < FLAPPY_PILAR_MAX; i++) {
|
||||
const PILAR* pilar = &game_state->pilars[i];
|
||||
if(pilar != NULL && pilar->visible == 1) {
|
||||
canvas_draw_frame(
|
||||
canvas, pilar->point.x, pilar->point.y, FLAPPY_GAB_WIDTH, pilar->height);
|
||||
|
||||
canvas_draw_frame(
|
||||
canvas,
|
||||
pilar->point.x,
|
||||
pilar->point.y + pilar->height + FLAPPY_GAB_HEIGHT,
|
||||
FLAPPY_GAB_WIDTH,
|
||||
FLIPPER_LCD_HEIGHT - pilar->height - FLAPPY_GAB_HEIGHT);
|
||||
}
|
||||
}
|
||||
// Flappy
|
||||
for(int h = 0; h < FLAPPY_BIRD_HEIGHT; h++) {
|
||||
for(int w = 0; w < FLAPPY_BIRD_WIDTH; w++) {
|
||||
// Switch animation
|
||||
int bird = 0;
|
||||
if(game_state->bird.gravity < -0.5)
|
||||
bird = 1;
|
||||
else
|
||||
bird = 2;
|
||||
|
||||
// Draw bird pixels
|
||||
if(bird_array[bird][h][w] == 1) {
|
||||
int x = game_state->bird.point.x + h;
|
||||
int y = game_state->bird.point.y + w;
|
||||
|
||||
canvas_draw_dot(canvas, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stats
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
char buffer[12];
|
||||
snprintf(buffer, sizeof(buffer), "Score: %u", game_state->points);
|
||||
canvas_draw_str_aligned(canvas, 100, 12, AlignCenter, AlignBottom, buffer);
|
||||
|
||||
if(game_state->debug) {
|
||||
char coordinates[20];
|
||||
snprintf(coordinates, sizeof(coordinates), "Y: %u", game_state->bird.point.y);
|
||||
canvas_draw_str_aligned(canvas, 1, 12, AlignCenter, AlignBottom, coordinates);
|
||||
}
|
||||
}
|
||||
|
||||
if(game_state->state == GameStateGameOver) {
|
||||
// Screen is 128x64 px
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_box(canvas, 34, 20, 62, 24);
|
||||
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_frame(canvas, 34, 20, 62, 24);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 37, 31, "Game Over");
|
||||
|
||||
/*if(game_state->points != 0 && game_state->points % 5 == 0) {
|
||||
DOLPHIN_DEED(getRandomDeed());
|
||||
}*/
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
char buffer[12];
|
||||
snprintf(buffer, sizeof(buffer), "Score: %u", game_state->points);
|
||||
canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, buffer);
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, game_state);
|
||||
}
|
||||
|
||||
static void flappy_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
furi_assert(event_queue);
|
||||
|
||||
GameEvent event = {.type = EventTypeKey, .input = *input_event};
|
||||
furi_message_queue_put(event_queue, &event, FuriWaitForever);
|
||||
}
|
||||
|
||||
static void flappy_game_update_timer_callback(FuriMessageQueue* event_queue) {
|
||||
furi_assert(event_queue);
|
||||
|
||||
GameEvent event = {.type = EventTypeTick};
|
||||
furi_message_queue_put(event_queue, &event, 0);
|
||||
}
|
||||
|
||||
int32_t flappy_game_app(void* p) {
|
||||
UNUSED(p);
|
||||
int32_t return_code = 0;
|
||||
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(GameEvent));
|
||||
|
||||
GameState* game_state = malloc(sizeof(GameState));
|
||||
flappy_game_state_init(game_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, game_state, sizeof(GameState))) {
|
||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
||||
return_code = 255;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, flappy_game_render_callback, &state_mutex);
|
||||
view_port_input_callback_set(view_port, flappy_game_input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer =
|
||||
furi_timer_alloc(flappy_game_update_timer_callback, FuriTimerTypePeriodic, event_queue);
|
||||
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 25);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
GameEvent event;
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
GameState* game_state = (GameState*)acquire_mutex_block(&state_mutex);
|
||||
|
||||
if(event_status == FuriStatusOk) {
|
||||
// press events
|
||||
if(event.type == EventTypeKey) {
|
||||
if(event.input.type == InputTypePress) {
|
||||
switch(event.input.key) {
|
||||
case InputKeyUp:
|
||||
game_state->bird.point.y--;
|
||||
break;
|
||||
case InputKeyDown:
|
||||
game_state->bird.point.y++;
|
||||
break;
|
||||
case InputKeyRight:
|
||||
game_state->bird.point.x++;
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
game_state->bird.point.x--;
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(game_state->state == GameStateGameOver) {
|
||||
flappy_game_state_init(game_state);
|
||||
}
|
||||
|
||||
if(game_state->state == GameStateLife) {
|
||||
flappy_game_flap(game_state);
|
||||
}
|
||||
|
||||
break;
|
||||
case InputKeyBack:
|
||||
processing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(event.type == EventTypeTick) {
|
||||
flappy_game_tick(game_state);
|
||||
}
|
||||
} else {
|
||||
//FURI_LOG_D(TAG, "osMessageQueue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, game_state);
|
||||
}
|
||||
|
||||
furi_timer_free(timer);
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
delete_mutex(&state_mutex);
|
||||
|
||||
free_and_exit:
|
||||
free(game_state);
|
||||
furi_message_queue_free(event_queue);
|
||||
|
||||
return return_code;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ App(
|
||||
],
|
||||
provides=["music_player_start"],
|
||||
stack_size=2 * 1024,
|
||||
order=20,
|
||||
order=45,
|
||||
fap_icon="../../../assets/icons/Archive/music_10px.png",
|
||||
fap_category="Games",
|
||||
)
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*MusicPlayerWorkerCallback)(
|
||||
uint8_t semitone,
|
||||
uint8_t dots,
|
||||
@@ -34,3 +38,7 @@ void music_player_worker_set_volume(MusicPlayerWorker* instance, float volume);
|
||||
void music_player_worker_start(MusicPlayerWorker* instance);
|
||||
|
||||
void music_player_worker_stop(MusicPlayerWorker* instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,11 +16,11 @@ void subbrute_scene_entrypoint_menu_callback(SubBruteState* context, uint32_t in
|
||||
case SubBruteAttackCAME12bit307:
|
||||
case SubBruteAttackCAME12bit433:
|
||||
case SubBruteAttackCAME12bit868:
|
||||
if (index == SubBruteAttackCAME12bit307) {
|
||||
if(index == SubBruteAttackCAME12bit307) {
|
||||
context->frequency = 307800000;
|
||||
} else if (index == SubBruteAttackCAME12bit433) {
|
||||
} else if(index == SubBruteAttackCAME12bit433) {
|
||||
context->frequency = 433920000;
|
||||
} else if (index == SubBruteAttackCAME12bit868) {
|
||||
} else if(index == SubBruteAttackCAME12bit868) {
|
||||
context->frequency = 868350000;
|
||||
}
|
||||
context->bit = 12;
|
||||
|
||||
12
applications/plugins/zombiez/application.fam
Normal file
@@ -0,0 +1,12 @@
|
||||
App(
|
||||
appid="game_zombiez",
|
||||
name="Zombiez",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="zombiez_game_app",
|
||||
cdefines=["APP_ZOMBIEZ_GAME"],
|
||||
requires=["gui"],
|
||||
stack_size=2 * 1024,
|
||||
order=280,
|
||||
fap_icon="zombie_10px.png",
|
||||
fap_category="Games",
|
||||
)
|
||||
BIN
applications/plugins/zombiez/zombie_10px.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
400
applications/plugins/zombiez/zombiez.c
Normal file
@@ -0,0 +1,400 @@
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//ORIGINAL REPO: https://github.com/Dooskington/flipperzero-zombiez
|
||||
//AUTHORS: https://github.com/Dooskington | https://github.com/DevMilanIan
|
||||
|
||||
#include "zombiez.h"
|
||||
|
||||
#define ZOMBIES_MAX 3
|
||||
#define ZOMBIES_WIDTH 5
|
||||
#define ZOMBIES_HEIGHT 8
|
||||
#define PROJECTILES_MAX 10
|
||||
|
||||
#define MIN_Y 5
|
||||
#define MAX_Y 58
|
||||
#define WALL_X 16
|
||||
#define PLAYER_START_X 8
|
||||
#define PLAYER_START_Y (MAX_Y - MIN_Y) / 2
|
||||
|
||||
typedef enum {
|
||||
EventTypeTick,
|
||||
EventTypeKey,
|
||||
} EventType;
|
||||
|
||||
typedef struct {
|
||||
EventType type;
|
||||
InputEvent input;
|
||||
} PluginEvent;
|
||||
|
||||
typedef enum { GameStatePlaying, GameStateGameOver } GameState;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} Point;
|
||||
|
||||
typedef struct {
|
||||
Point position;
|
||||
int hp;
|
||||
} Player;
|
||||
|
||||
typedef struct {
|
||||
Point position;
|
||||
int hp;
|
||||
} Zombie;
|
||||
|
||||
typedef struct {
|
||||
Point position;
|
||||
} Projectile;
|
||||
|
||||
typedef struct {
|
||||
GameState game_state;
|
||||
Player player;
|
||||
|
||||
size_t zombies_count;
|
||||
Zombie* zombies[ZOMBIES_MAX];
|
||||
|
||||
size_t projectiles_count;
|
||||
Projectile* projectiles[PROJECTILES_MAX];
|
||||
|
||||
uint16_t score;
|
||||
bool input_shoot;
|
||||
} PluginState;
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25);
|
||||
if(plugin_state == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas,
|
||||
plugin_state->player.position.x,
|
||||
plugin_state->player.position.y,
|
||||
AlignCenter,
|
||||
AlignCenter,
|
||||
"@");
|
||||
|
||||
canvas_draw_line(canvas, WALL_X, 0, WALL_X, 64);
|
||||
canvas_draw_line(canvas, WALL_X + 2, 4, WALL_X + 2, 59);
|
||||
|
||||
for(int i = 0; i < PROJECTILES_MAX; ++i) {
|
||||
Projectile* p = plugin_state->projectiles[i];
|
||||
if(p != NULL) {
|
||||
canvas_draw_circle(canvas, p->position.x, p->position.y, 3);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < ZOMBIES_MAX; ++i) {
|
||||
Zombie* z = plugin_state->zombies[i];
|
||||
if(z != NULL) {
|
||||
for(int h = 0; h < ZOMBIES_HEIGHT; h++) {
|
||||
for(int w = 0; w < ZOMBIES_WIDTH; w++) {
|
||||
// Switch animation
|
||||
int zIdx = 0;
|
||||
if(z->position.x % 2 == 0) {
|
||||
zIdx = 1;
|
||||
}
|
||||
|
||||
// Draw zombie pixels
|
||||
if(zombie_array[zIdx][h][w] == 1) {
|
||||
int x = z->position.x + w;
|
||||
int y = z->position.y + h;
|
||||
|
||||
canvas_draw_dot(canvas, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int heart;
|
||||
if((plugin_state->player.hp - 10) > 5) { // 16, 17, 18, 19, 20
|
||||
heart = 0;
|
||||
} else if((plugin_state->player.hp - 5) > 5) { // 11, 12, 13, 14, 15
|
||||
heart = 1;
|
||||
} else if((plugin_state->player.hp - 3) > 2) { // 6, 7, 8, 9, 10
|
||||
heart = 2;
|
||||
} else if(plugin_state->player.hp > 0) { // 1, 2, 3, 4, 5
|
||||
heart = 3;
|
||||
} else { // 0
|
||||
heart = 4;
|
||||
}
|
||||
// visual representation of health
|
||||
for(int h = 0; h < 5; h++) {
|
||||
for(int w = 0; w < 5; w++) {
|
||||
if(heart_array[heart][h][w] == 1) {
|
||||
int x = 124 - w;
|
||||
int y = 56 + h;
|
||||
|
||||
canvas_draw_dot(canvas, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// buffer hp + score
|
||||
char hpBuffer[8];
|
||||
char scoreBuffer[14];
|
||||
|
||||
if(plugin_state->game_state == GameStatePlaying) {
|
||||
// display ammo / reload
|
||||
if(plugin_state->projectiles_count >= PROJECTILES_MAX) {
|
||||
canvas_draw_str_aligned(canvas, 24, 10, AlignLeft, AlignCenter, "RELOAD");
|
||||
} else {
|
||||
for(uint8_t i = 0; i < (PROJECTILES_MAX - plugin_state->projectiles_count); i++) {
|
||||
canvas_draw_box(canvas, 24 + (4 * i), 6, 2, 4);
|
||||
}
|
||||
}
|
||||
// display hp + score
|
||||
snprintf(hpBuffer, sizeof(hpBuffer), "%u", plugin_state->player.hp);
|
||||
canvas_draw_str_aligned(canvas, 118, 62, AlignRight, AlignBottom, hpBuffer);
|
||||
|
||||
snprintf(scoreBuffer, sizeof(scoreBuffer), "%u", plugin_state->score);
|
||||
canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, scoreBuffer);
|
||||
}
|
||||
// Game Over banner
|
||||
if(plugin_state->game_state == GameStateGameOver) {
|
||||
// Screen is 128x64 px
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_box(canvas, 34, 20, 62, 24);
|
||||
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_frame(canvas, 34, 20, 62, 24);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 37, 31, "Game Over");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
snprintf(scoreBuffer, sizeof(scoreBuffer), "Score: %u", plugin_state->score);
|
||||
canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, scoreBuffer);
|
||||
}
|
||||
|
||||
//char* info = (char*)malloc(16 * sizeof(char));
|
||||
//asprintf(&info, "%d, %d", plugin_state->x, plugin_state->y);
|
||||
//canvas_draw_str_aligned(canvas, 32, 16, AlignLeft, AlignBottom, info);
|
||||
//free(info);
|
||||
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
}
|
||||
|
||||
static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||
furi_assert(event_queue);
|
||||
PluginEvent event = {.type = EventTypeKey, .input = *input_event};
|
||||
furi_message_queue_put(event_queue, &event, FuriWaitForever);
|
||||
}
|
||||
|
||||
static void tick(PluginState* const plugin_state) {
|
||||
if(plugin_state->input_shoot && (plugin_state->projectiles_count < PROJECTILES_MAX)) {
|
||||
Projectile* p = (Projectile*)malloc(sizeof(Projectile));
|
||||
p->position.x = plugin_state->player.position.x;
|
||||
p->position.y = plugin_state->player.position.y;
|
||||
|
||||
size_t idx = plugin_state->projectiles_count;
|
||||
plugin_state->projectiles[idx] = p;
|
||||
plugin_state->projectiles_count += 1;
|
||||
}
|
||||
|
||||
for(int i = 0; i < ZOMBIES_MAX; ++i) {
|
||||
if(!plugin_state->zombies[i]) {
|
||||
Zombie* z = (Zombie*)malloc(sizeof(Zombie));
|
||||
//z->hp = 20;
|
||||
z->position.x = 126;
|
||||
z->position.y = MIN_Y + (rand() % (MAX_Y - MIN_Y));
|
||||
|
||||
plugin_state->zombies[i] = z;
|
||||
plugin_state->zombies_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < PROJECTILES_MAX; ++i) {
|
||||
Projectile* p = plugin_state->projectiles[i];
|
||||
if(p != NULL) {
|
||||
p->position.x += 2;
|
||||
|
||||
for(int i = 0; i < ZOMBIES_MAX; ++i) {
|
||||
Zombie* z = plugin_state->zombies[i];
|
||||
if(z != NULL) {
|
||||
if( // projectile close enough to zombie
|
||||
(((z->position.x - p->position.x) <= 2) &&
|
||||
((z->position.y - p->position.y) <= 4)) &&
|
||||
(((p->position.x - z->position.x) <= 2) &&
|
||||
((p->position.y - z->position.y) <= 6))) {
|
||||
//z->hp -= 5;
|
||||
//if(z->hp <= 0) {
|
||||
plugin_state->zombies_count -= 1;
|
||||
free(z);
|
||||
plugin_state->zombies[i] = NULL;
|
||||
plugin_state->score++;
|
||||
//if(plugin_state->score % 15 == 0) DOLPHIN_DEED(getRandomDeed());
|
||||
//}
|
||||
} else if(z->position.x <= WALL_X && z->position.x > 0) { // zombie got to the wall
|
||||
plugin_state->zombies_count -= 1;
|
||||
free(z);
|
||||
plugin_state->zombies[i] = NULL;
|
||||
if(plugin_state->player.hp > 0) {
|
||||
plugin_state->player.hp--;
|
||||
} else {
|
||||
plugin_state->game_state = GameStateGameOver;
|
||||
}
|
||||
} else {
|
||||
if(furi_get_tick() % 2 == 0) z->position.x--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(p->position.x >= 128) {
|
||||
free(p);
|
||||
plugin_state->projectiles[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugin_state->input_shoot = false;
|
||||
}
|
||||
|
||||
static void timer_callback(void* ctx) {
|
||||
furi_assert(ctx);
|
||||
FuriMessageQueue* event_queue = ctx;
|
||||
PluginEvent event = {.type = EventTypeTick};
|
||||
furi_message_queue_put(event_queue, &event, 0);
|
||||
}
|
||||
|
||||
static void zombiez_state_init(PluginState* const plugin_state) {
|
||||
plugin_state->player.position.x = PLAYER_START_X;
|
||||
plugin_state->player.position.y = PLAYER_START_Y;
|
||||
plugin_state->player.hp = 20;
|
||||
|
||||
plugin_state->projectiles_count = 0;
|
||||
plugin_state->zombies_count = 0;
|
||||
plugin_state->score = 0;
|
||||
|
||||
for(int i = 0; i < PROJECTILES_MAX; i++) {
|
||||
plugin_state->projectiles[i] = NULL;
|
||||
}
|
||||
|
||||
for(int i = 0; i < ZOMBIES_MAX; i++) {
|
||||
plugin_state->zombies[i] = NULL;
|
||||
}
|
||||
|
||||
plugin_state->game_state = GameStatePlaying;
|
||||
plugin_state->input_shoot = false;
|
||||
}
|
||||
|
||||
int32_t zombiez_game_app(void* p) {
|
||||
UNUSED(p);
|
||||
uint32_t return_code = 0;
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
|
||||
|
||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
||||
zombiez_state_init(plugin_state);
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) {
|
||||
FURI_LOG_E("Zombiez", "cannot create mutex\r\n");
|
||||
return_code = 255;
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
FuriTimer* timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, event_queue);
|
||||
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 22);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
PluginEvent event;
|
||||
bool isRunning = true;
|
||||
while(isRunning) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex);
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == EventTypeKey) {
|
||||
if(event.input.type == InputTypePress) {
|
||||
switch(event.input.key) {
|
||||
case InputKeyUp:
|
||||
if(plugin_state->player.position.y > MIN_Y &&
|
||||
plugin_state->game_state == GameStatePlaying) {
|
||||
plugin_state->player.position.y--;
|
||||
}
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(plugin_state->player.position.y < MAX_Y &&
|
||||
plugin_state->game_state == GameStatePlaying) {
|
||||
plugin_state->player.position.y++;
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(plugin_state->projectiles_count < PROJECTILES_MAX &&
|
||||
plugin_state->game_state == GameStatePlaying) {
|
||||
plugin_state->input_shoot = true;
|
||||
}
|
||||
break;
|
||||
case InputKeyBack:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(
|
||||
event.input.type == InputTypeRepeat &&
|
||||
plugin_state->game_state == GameStatePlaying) {
|
||||
switch(event.input.key) {
|
||||
case InputKeyUp:
|
||||
if(plugin_state->player.position.y > (MIN_Y + 1)) {
|
||||
plugin_state->player.position.y -= 2;
|
||||
}
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(plugin_state->player.position.y < (MAX_Y - 1)) {
|
||||
plugin_state->player.position.y += 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(event.input.type == InputTypeLong) {
|
||||
if(event.input.key == InputKeyOk) {
|
||||
if(plugin_state->game_state == GameStateGameOver) {
|
||||
zombiez_state_init(plugin_state);
|
||||
} else if(plugin_state->projectiles_count >= PROJECTILES_MAX) {
|
||||
plugin_state->projectiles_count = 0;
|
||||
plugin_state->player.hp++;
|
||||
}
|
||||
} else if(event.input.key == InputKeyBack) {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
} else if(event.type == EventTypeTick) {
|
||||
tick(plugin_state);
|
||||
}
|
||||
} else {
|
||||
// event timeout
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
}
|
||||
|
||||
furi_timer_free(timer);
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
view_port_free(view_port);
|
||||
delete_mutex(&state_mutex);
|
||||
|
||||
free_and_exit:
|
||||
free(plugin_state);
|
||||
furi_message_queue_free(event_queue);
|
||||
|
||||
return return_code;
|
||||
}
|
||||
62
applications/plugins/zombiez/zombiez.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <furi.h>
|
||||
|
||||
uint8_t zombie_array[2][8][5] = {
|
||||
{
|
||||
{0, 0, 1, 1, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{1, 1, 1, 1, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{0, 0, 1, 0, 0},
|
||||
{0, 0, 1, 0, 0},
|
||||
},
|
||||
{
|
||||
{0, 0, 1, 1, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{1, 1, 1, 1, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{0, 0, 0, 0, 1},
|
||||
{0, 0, 0, 0, 1},
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t heart_array[5][5][5] = {
|
||||
{
|
||||
{0, 1, 0, 1, 0},
|
||||
{1, 1, 1, 1, 1},
|
||||
{1, 1, 1, 1, 1},
|
||||
{0, 1, 1, 1, 0},
|
||||
{0, 0, 1, 0, 0},
|
||||
},
|
||||
{
|
||||
{0, 0, 0, 0, 0},
|
||||
{1, 1, 1, 1, 1},
|
||||
{1, 1, 1, 1, 1},
|
||||
{0, 1, 1, 1, 0},
|
||||
{0, 0, 1, 0, 0},
|
||||
},
|
||||
{
|
||||
{0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0},
|
||||
{1, 1, 1, 1, 1},
|
||||
{0, 1, 1, 1, 0},
|
||||
{0, 0, 1, 0, 0},
|
||||
},
|
||||
{
|
||||
{0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0},
|
||||
{0, 1, 1, 1, 0},
|
||||
{0, 0, 1, 0, 0},
|
||||
},
|
||||
{
|
||||
{1, 0, 0, 0, 1},
|
||||
{0, 1, 0, 1, 0},
|
||||
{0, 0, 1, 0, 0},
|
||||
{0, 1, 0, 1, 0},
|
||||
{1, 0, 0, 0, 1},
|
||||
},
|
||||
};
|
||||
@@ -367,6 +367,23 @@ void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch) {
|
||||
u8g2_DrawGlyph(&canvas->fb, x, y, ch);
|
||||
}
|
||||
|
||||
void canvas_draw_icon_bitmap(
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
int16_t w,
|
||||
int16_t h,
|
||||
const Icon* icon) {
|
||||
furi_assert(canvas);
|
||||
furi_assert(icon);
|
||||
|
||||
x += canvas->offset_x;
|
||||
y += canvas->offset_y;
|
||||
uint8_t* icon_data = NULL;
|
||||
furi_hal_compress_icon_decode(icon_get_data(icon), &icon_data);
|
||||
u8g2_DrawXBM(&canvas->fb, x, y, w, h, icon_data);
|
||||
}
|
||||
|
||||
void canvas_set_bitmap_mode(Canvas* canvas, bool alpha) {
|
||||
u8g2_SetBitmapMode(&canvas->fb, alpha ? 1 : 0);
|
||||
}
|
||||
|
||||
@@ -358,6 +358,14 @@ void canvas_draw_rbox(
|
||||
uint8_t height,
|
||||
uint8_t radius);
|
||||
|
||||
void canvas_draw_icon_bitmap(
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
int16_t w,
|
||||
int16_t h,
|
||||
const Icon* icon);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,2.3,,
|
||||
Version,+,3.0,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@@ -540,6 +540,7 @@ Function,+,canvas_draw_frame,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t"
|
||||
Function,+,canvas_draw_glyph,void,"Canvas*, uint8_t, uint8_t, uint16_t"
|
||||
Function,+,canvas_draw_icon,void,"Canvas*, uint8_t, uint8_t, const Icon*"
|
||||
Function,+,canvas_draw_icon_animation,void,"Canvas*, uint8_t, uint8_t, IconAnimation*"
|
||||
Function,+,canvas_draw_icon_bitmap,void,"Canvas*, uint8_t, uint8_t, int16_t, int16_t, const Icon*"
|
||||
Function,+,canvas_draw_line,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t"
|
||||
Function,+,canvas_draw_rbox,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t"
|
||||
Function,+,canvas_draw_rframe,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t"
|
||||
@@ -1479,7 +1480,7 @@ Function,-,isupper,int,int
|
||||
Function,-,isupper_l,int,"int, locale_t"
|
||||
Function,-,isxdigit,int,int
|
||||
Function,-,isxdigit_l,int,"int, locale_t"
|
||||
Function,-,itoa,char*,"int, char*, int"
|
||||
Function,+,itoa,char*,"int, char*, int"
|
||||
Function,-,j0,double,double
|
||||
Function,-,j0f,float,float
|
||||
Function,-,j1,double,double
|
||||
|
||||
|
@@ -19,7 +19,6 @@ class FlipperAppType(Enum):
|
||||
STARTUP = "StartupHook"
|
||||
EXTERNAL = "External"
|
||||
METAPACKAGE = "Package"
|
||||
GAME = "Game"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||