Tetris external app (#1842)

* Tetris external app
* 4 levels
This commit is contained in:
Mark Thompson
2024-02-03 19:33:36 +01:00
committed by GitHub
parent f0f279eec5
commit c30a61441b
10 changed files with 1138 additions and 12 deletions
+10 -6
View File
@@ -3,7 +3,11 @@ set(EXTCPPSRC
#pacman
external/pacman/main.cpp
external/pacman/ui_pacman.cpp
#tetris
external/tetris/main.cpp
external/tetris/ui_tetris.cpp
#afsk_rx
external/afsk_rx/main.cpp
external/afsk_rx/ui_afsk_rx.cpp
@@ -19,7 +23,7 @@ set(EXTCPPSRC
#blespam
external/blespam/main.cpp
external/blespam/ui_blespam.cpp
#analogtv
external/analogtv/main.cpp
external/analogtv/analog_tv_app.cpp
@@ -35,13 +39,12 @@ set(EXTCPPSRC
#lge
external/lge/main.cpp
external/lge/lge_app.cpp
#lcr
external/lcr/main.cpp
external/lcr/ui_lcr.cpp
#lcr
#jammer
external/jammer/main.cpp
external/jammer/ui_jammer.cpp
@@ -76,4 +79,5 @@ set(EXTAPPLIST
gpssim
spainter
keyfob
tetris
)
+13 -6
View File
@@ -31,6 +31,7 @@ MEMORY
ram_external_app_gpssim(rwx) : org = 0xEEF40000, len = 32k
ram_external_app_spainter(rwx) : org = 0xEEF50000, len = 32k
ram_external_app_keyfob(rwx) : org = 0xEEF60000, len = 32k
ram_external_app_tetris(rwx) : org = 0xEEF70000, len = 32k
}
SECTIONS
@@ -59,7 +60,7 @@ SECTIONS
*(*ui*external_app*font_viewer*);
} > ram_external_app_font_viewer
.external_app_blespam : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_blespam.application_information));
@@ -77,33 +78,33 @@ SECTIONS
KEEP(*(.external_app.app_nrf_rx.application_information));
*(*ui*external_app*nrf_rx*);
} > ram_external_app_nrf_rx
.external_app_coasterp : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_coasterp.application_information));
*(*ui*external_app*coasterp*);
} > ram_external_app_coasterp
.external_app_lge : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_lge.application_information));
*(*ui*external_app*lge*);
} > ram_external_app_lge
.external_app_lcr : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_lcr.application_information));
*(*ui*external_app*lcr*);
} > ram_external_app_lcr
.external_app_jammer : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_jammer.application_information));
*(*ui*external_app*jammer*);
} > ram_external_app_jammer
.external_app_gpssim : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_gpssim.application_information));
@@ -123,4 +124,10 @@ SECTIONS
*(*ui*external_app*keyfob*);
} > ram_external_app_keyfob
.external_app_tetris : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_tetris.application_information));
*(*ui*external_app*tetris*);
} > ram_external_app_tetris
}
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 Mark Thompson
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
// dummy include file to avoid changing original source
#ifndef __UI_Arial12x12_H__
#define __UI_Arial12x12_H__
#define Arial12x12 (0)
#endif /*__UI_Arial12x12_H__*/
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2024 Mark Thompson
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
// "HAL" display layer for Tetris code to run on PortaPack without its original ILI9341 functions
#ifndef __UI_SPI_TFT_ILI9341_H__
#define __UI_SPI_TFT_ILI9341_H__
ui::Painter painter;
static int x_pos{0};
static int y_pos{0};
static int fg_color;
static int bg_color;
enum {
White,
Blue,
Yellow,
Purple,
Green,
Red,
Maroon,
Orange,
Black,
};
// pp_colors must be in same order as enums above
static const Color pp_colors[] = {
Color::white(),
Color::blue(),
Color::yellow(),
Color::purple(),
Color::green(),
Color::red(),
Color::magenta(),
Color::orange(),
Color::black(),
};
class SPI_TFT_ILI9341 {
public:
SPI_TFT_ILI9341(int, int, int, int, int, int, std::string) { (void)0; };
void claim(__FILE* x) { (void)x; };
void cls() {
painter.fill_rectangle({0, 0, portapack::display.width(), portapack::display.height()}, Color::black());
};
void background(int color) { bg_color = color; };
void foreground(int color) { fg_color = color; };
void locate(int x, int y) {
x_pos = x;
y_pos = y;
};
void set_orientation(int x) { (void)x; };
void set_font(unsigned char* x) { (void)x; };
void fillrect(int x1, int y1, int x2, int y2, int color) {
painter.fill_rectangle({x1, y1, x2 - x1, y2 - y1}, pp_colors[color]);
};
void rect(int x1, int y1, int x2, int y2, int color) {
painter.draw_rectangle({x1, y1, x2 - x1, y2 - y1}, pp_colors[color]);
};
private:
};
static void printf(std::string str) {
auto style = (fg_color == White) ? ui::Styles::white : ui::Styles::bg_white;
painter.draw_string({x_pos, y_pos - 1}, style, str);
};
static void printf(std::string str, int v) {
if (str.find_first_of("%") != std::string::npos) {
str.resize(str.find_first_of("%")); // remove %d from end of string
}
printf(str + to_string_dec_uint(v));
};
#endif /*__UI_SPI_TFT_ILI9341_H__*/
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2024 Mark Thompson
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include "ui_tetris.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::tetris {
void initialize_app(ui::NavigationView& nav) {
nav.push<TetrisView>();
}
} // namespace ui::external_app::tetris
extern "C" {
__attribute__((section(".external_app.app_tetris.application_information"), used)) application_information_t _application_information_tetris = {
/*.memory_location = */ (uint8_t*)0x00000000, // will be filled at compile time
/*.externalAppEntry = */ ui::external_app::tetris::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "Tetris",
/*.bitmap_data = */ {
0xF8,
0xFF,
0x88,
0x88,
0x88,
0x88,
0x88,
0x88,
0xF8,
0xFF,
0x80,
0x08,
0x80,
0x08,
0x9F,
0x08,
0x91,
0x0F,
0x11,
0x00,
0x11,
0x00,
0xFF,
0xF1,
0x11,
0x91,
0x11,
0x91,
0x11,
0x91,
0xFF,
0xF1,
},
/*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::UTILITIES,
/*.m4_app_tag = portapack::spi_flash::image_tag_noop */ {'\0', '\0', '\0', '\0'}, // optional
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
}
+220
View File
@@ -0,0 +1,220 @@
/*
* Copyright (C) 2024 Mark Thompson
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
// "HAL" layer for Tetris code to run on PortaPack without its original mbed OS
// (the dream here was to avoid modifying the original code)
#ifndef __UI_mbed_H__
#define __UI_mbed_H__
using Callback = void (*)(void);
#define wait_us(x) (void)0
#define wait(x) chThdSleepMilliseconds(x * 1000)
#define PullUp 1
enum {
dp0,
dp1,
dp2,
dp3,
dp4,
dp5,
dp6,
dp7,
dp8,
dp9,
dp10,
dp11,
dp12,
dp13,
dp14,
dp15,
dp16,
dp17,
dp18,
dp19,
dp20,
dp21,
dp22,
dp23,
dp24,
dp25,
};
static bool but_RIGHT;
static bool but_LEFT;
static bool but_UP;
static bool but_DOWN;
static bool but_SELECT;
//
// AnalogIn Class -- DID NOT WORK BECAUSE INITIALIZER CODE WON'T EXECUTE -- hacked original code module instead
//
// dp9 = joystick rotate button --> select button
// dp10 = joystick y --> up & down buttons
// dp11 = joystick x --> left & right buttons
// dp13 = random number generator
//
//
// class AnalogIn {
// public:
// AnalogIn(uint32_t analog_input) {
// // FIXME - THIS CODE NEVER GETS EXECUTED!
// analog_input_ = analog_input;
// };
//
// // Tetris code only uses this function for dp13 - supposed to be a random number
// uint16_t read_u16() {
// return std::rand();
// };
//
// // Tetris code uses read() function for direction buttons only
// float read() {
// float retval = 0.5;
// switch (analog_input_) {
// case dp11:
// if (but_LEFT)
// retval = 0.0;
// else if (but_RIGHT)
// retval = 1.0;
// break;
//
// case dp10:
// if (but_UP)
// retval = 0.0;
// else if (but_DOWN)
// retval = 1.0;
// break;
// }
// return retval;
// };
//
// operator float() {
// return read();
// };
//
// private:
// uint32_t analog_input_{INT_MAX};
// };
//
// Timer Class
// (Timer object was used for unneeded button debouncing, so just returning 1000ms to indicate we've waited long enough)
//
class Timer {
public:
// NOTE: INITIALIZER CODE WON'T RUN
Timer() { (void)0; };
void reset() { (void)0; };
void start() { (void)0; }
uint32_t read_ms() { return 1000; };
private:
};
//
// Ticker Class
// (Ticker is timed callback, used for checking "joystick" directional switches and when time to move piece down a row)
//
// NB: Only one callback is supported per Ticker class instantiation
static Callback fall_timer_callback;
static uint32_t fall_timer_timeout;
static uint32_t fall_timer_counter;
static Callback dir_button_callback;
static void check_fall_timer() {
if (fall_timer_callback) {
if (++fall_timer_counter >= fall_timer_timeout) {
fall_timer_counter = 0;
fall_timer_callback();
}
}
}
class Ticker {
public:
// NOTE: INITIALIZER CODE WON'T RUN
Ticker() { (void)0; };
void attach(Callback func, double delay_sec) {
// 0.3 sec is requested only for button check -- kludge to use on_key callback for this one instead of timer
if (delay_sec == 0.3) {
dir_button_callback = func;
} else {
fall_timer_callback = func;
fall_timer_timeout = delay_sec * 60; // timer interrupts at 60 Hz
}
}
void detach() {
// shouldn't detach both, but don't know how to tell which object is which
dir_button_callback = nullptr;
fall_timer_callback = nullptr;
}
private:
};
//
// InterruptIn Class
// (just used for the Select button)
//
static Callback sel_button_callback;
static bool check_encoder(const EncoderEvent delta) {
(void)delta;
// TODO: consider adding ability to rotate Tetronimo via encoder too
return false;
}
static bool check_key(const KeyEvent key) {
auto switches_debounced = get_switches_state().to_ulong();
but_RIGHT = (switches_debounced & 0x01) != 0;
but_LEFT = (switches_debounced & 0x02) != 0;
but_DOWN = (switches_debounced & 0x04) != 0;
but_UP = (switches_debounced & 0x08) != 0;
but_SELECT = (switches_debounced & 0x10) != 0;
if (key == KeyEvent::Select) {
if (sel_button_callback)
sel_button_callback();
} else {
if (dir_button_callback)
dir_button_callback();
}
return true;
}
class InterruptIn {
public:
InterruptIn(int reg) {
// NOTE: INITIALIZER CODE WON'T RUN
(void)reg;
};
void fall(Callback func) { sel_button_callback = func; };
void mode(int v) { (void)v; };
private:
};
#endif /*__UI_mbed_H__*/
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
#include "ui_tetris.hpp"
namespace ui::external_app::tetris {
#pragma GCC diagnostic push
// external code, so ignore warnings
#pragma GCC diagnostic ignored "-Weffc++"
#include "tetris.cpp"
#pragma GCC diagnostic pop
TetrisView::TetrisView(NavigationView& nav)
: nav_(nav) {
add_children({&dummy});
}
void TetrisView::paint(Painter& painter) {
(void)painter;
if (!initialized) {
initialized = true;
std::srand(LPC_RTC->CTIME0);
main();
}
}
void TetrisView::frame_sync() {
check_fall_timer();
set_dirty();
}
bool TetrisView::on_encoder(const EncoderEvent delta) {
return check_encoder(delta);
}
bool TetrisView::on_key(const KeyEvent key) {
return check_key(key);
}
} // namespace ui::external_app::tetris
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2024 Mark Thompson
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __UI_TETRIS_H__
#define __UI_TETRIS_H__
#include "ui_navigation.hpp"
#include "event_m0.hpp"
#include "message.hpp"
#include "irq_controls.hpp"
#include "ui_styles.hpp"
#include "random.hpp"
#include "lpc43xx_cpp.hpp"
#include "limits.h"
namespace ui::external_app::tetris {
class TetrisView : public View {
public:
TetrisView(NavigationView& nav);
std::string title() const override { return "Tetris"; };
void focus() override { dummy.focus(); };
void paint(Painter& painter) override;
void frame_sync();
bool on_encoder(const EncoderEvent event) override;
bool on_key(KeyEvent key) override;
private:
bool initialized = false;
NavigationView& nav_;
Button dummy{
{240, 0, 0, 0},
""};
MessageHandlerRegistration message_handler_frame_sync{
Message::ID::DisplayFrameSync,
[this](const Message* const) {
this->frame_sync();
}};
};
} // namespace ui::external_app::tetris
#endif /*__UI_TETRIS_H__*/
Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B