ap80max: New hosted port

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 51d7d56803379aeefc3ac3a7f0e1a7d564912b1c
Author: Jerry Shen <[email protected]>
Date:   Tue Aug 11 22:45:40 2026 -0700

    ap80max: New hosted port
    
    HibyOS-based target: keymaps, LED, powermgmt, bootloader and sim support,
    plus cabbiev2 for the new 360x640x16 screen. Opus 5 helped w/ debugging
    and the initial scaffolding.
    
    Updated name to FB_STRIDE_MISMATCH, added simulator bmp and specs.
    
    Change-Id: If797ac6581cf75d9d1fcf36e615ee03cf6f905d6

diff --git a/apps/SOURCES b/apps/SOURCES
index 923e979af5..bf39273405 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -304,4 +304,6 @@ keymaps/keymap-rgnano.c
 keymaps/keymap-ctru.c
 #elif CONFIG_KEYPAD == HIBY_R3PROII_PAD
 keymaps/keymap-hibyr3proii.c
+#elif CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
+keymaps/keymap-hidizsap80max.c
 #endif
diff --git a/apps/bitmaps/native/SOURCES b/apps/bitmaps/native/SOURCES
index f0149175f3..9812851388 100644
--- a/apps/bitmaps/native/SOURCES
+++ b/apps/bitmaps/native/SOURCES
@@ -46,7 +46,7 @@ toolsicon.130x130x16.bmp
 hibyicon.70x70x16.bmp
 rockboxicon.70x70x16.bmp
 toolsicon.70x70x16.bmp
-#elif (defined(XDUOO_X3II) || defined(XDUOO_X20) || defined(EROS_Q) || defined(SURFANS_F28) || defined(HIBY_R3PROII) || defined(HIBY_R1))
+#elif (defined(XDUOO_X3II) || defined(XDUOO_X20) || defined(EROS_Q) || defined(SURFANS_F28) || defined(HIBY_R3PROII) || defined(HIBY_R1) || defined(HIDIZS_AP80MAX))
 hibyicon.130x130x16.bmp
 rockboxicon.130x130x16.bmp
 toolsicon.130x130x16.bmp
diff --git a/apps/keymaps/keymap-hidizsap80max.c b/apps/keymaps/keymap-hidizsap80max.c
new file mode 100644
index 0000000000..ca23b3b050
--- /dev/null
+++ b/apps/keymaps/keymap-hidizsap80max.c
@@ -0,0 +1,246 @@
+/***************************************************************************
+ *             __________               __   ___
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ *
+ * Copyright (C) 2025 Solomon Peachy
+ * Copyright (C) 2026 by Jerry Shen
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "action.h"
+#include "button.h"
+#include "settings.h"
+
+static const struct button_mapping button_context_standard[] =
+{
+    { ACTION_STD_KEYLOCK,        BUTTON_POWER|BUTTON_PLAY,           BUTTON_POWER },
+
+    { ACTION_STD_PREV,           BUTTON_SCROLL_BACK,                 BUTTON_NONE },
+    { ACTION_STD_NEXT,           BUTTON_SCROLL_FWD,                  BUTTON_NONE },
+
+    { ACTION_STD_OK,             BUTTON_POWER|BUTTON_REL,            BUTTON_POWER },
+    { ACTION_STD_OK,             BUTTON_NEXT|BUTTON_REL,             BUTTON_NEXT },
+    { ACTION_STD_CANCEL,         BUTTON_PREV|BUTTON_REL,             BUTTON_PREV },
+
+    { ACTION_STD_OK,             BUTTON_PLAY|BUTTON_REL,             BUTTON_PLAY },
+    { ACTION_STD_CONTEXT,        BUTTON_PLAY|BUTTON_REPEAT,          BUTTON_PLAY },
+
+    LAST_ITEM_IN_LIST
+};
+
+
+static const struct button_mapping button_context_wps[] =
+{
+    { ACTION_WPS_MENU,           BUTTON_POWER|BUTTON_REL,            BUTTON_POWER },
+    { ACTION_WPS_PLAY,           BUTTON_PLAY|BUTTON_REL,             BUTTON_PLAY },
+    { ACTION_WPS_STOP,           BUTTON_PLAY|BUTTON_REPEAT,          BUTTON_NONE },
+    { ACTION_WPS_VOLDOWN,        BUTTON_SCROLL_FWD,                  BUTTON_NONE },
+    { ACTION_WPS_VOLUP,          BUTTON_SCROLL_BACK,                 BUTTON_NONE },
+    { ACTION_WPS_SKIPNEXT,       BUTTON_NEXT|BUTTON_REL,             BUTTON_NEXT },
+    { ACTION_WPS_SKIPPREV,       BUTTON_PREV|BUTTON_REL,             BUTTON_PREV },
+    { ACTION_WPS_SEEKFWD,        BUTTON_NEXT|BUTTON_REPEAT,          BUTTON_NONE },
+    { ACTION_WPS_STOPSEEK,       BUTTON_NEXT|BUTTON_REL,             BUTTON_NEXT|BUTTON_REPEAT },
+    { ACTION_WPS_SEEKBACK,       BUTTON_PREV|BUTTON_REPEAT,          BUTTON_NONE },
+    { ACTION_WPS_STOPSEEK,       BUTTON_PREV|BUTTON_REL,             BUTTON_PREV|BUTTON_REPEAT },
+    { ACTION_STD_KEYLOCK,        BUTTON_POWER|BUTTON_PLAY,           BUTTON_POWER },
+
+    LAST_ITEM_IN_LIST
+};
+
+
+static const struct button_mapping button_context_list[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
+};
+
+
+static const struct button_mapping button_context_tree[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
+};
+
+
+static const struct button_mapping button_context_listtree_scroll_with_combo[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM | CONTEXT_TREE),
+};
+
+
+static const struct button_mapping button_context_listtree_scroll_without_combo[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM | CONTEXT_TREE),
+};
+
+
+static const struct button_mapping button_context_settings[] =
+{
+    { ACTION_SETTINGS_DEC,       BUTTON_SCROLL_FWD,   BUTTON_NONE },
+    { ACTION_SETTINGS_INC,       BUTTON_SCROLL_BACK,  BUTTON_NONE },
+    { ACTION_SETTINGS_INC,       BUTTON_NEXT,         BUTTON_NONE },
+    { ACTION_SETTINGS_DEC,       BUTTON_PREV,         BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
+};
+
+
+static const struct button_mapping button_context_settings_right_is_inc[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
+};
+
+
+static const struct button_mapping button_context_mainmenu[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_TREE),
+};
+
+
+static const struct button_mapping button_context_yesno[] =
+{
+    { ACTION_YESNO_ACCEPT,       BUTTON_PLAY|BUTTON_REL,             BUTTON_PLAY },
+    { ACTION_YESNO_ACCEPT,       BUTTON_POWER|BUTTON_REL,            BUTTON_POWER },
+    { ACTION_STD_CANCEL,         BUTTON_PREV|BUTTON_REL,             BUTTON_PREV },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
+};
+
+
+static const struct button_mapping button_context_colorchooser[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
+};
+
+
+static const struct button_mapping button_context_eq[] =
+{
+    { ACTION_SETTINGS_INCBIGSTEP, BUTTON_PLAY|BUTTON_SCROLL_BACK,    BUTTON_NONE },
+    { ACTION_SETTINGS_DECBIGSTEP, BUTTON_PLAY|BUTTON_SCROLL_FWD,     BUTTON_NONE },
+
+    { ACTION_SETTINGS_INC,       BUTTON_SCROLL_BACK,                 BUTTON_NONE },
+    { ACTION_SETTINGS_DEC,       BUTTON_SCROLL_FWD,                  BUTTON_NONE },
+
+    { ACTION_NONE,               BUTTON_PREV,                        BUTTON_NONE },
+    { ACTION_NONE,               BUTTON_NEXT,                        BUTTON_NONE },
+    { ACTION_STD_PREV,           BUTTON_PREV|BUTTON_REL,             BUTTON_PREV },
+    { ACTION_STD_PREVREPEAT,     BUTTON_PREV|BUTTON_REPEAT,          BUTTON_NONE },
+    { ACTION_STD_NEXT,           BUTTON_NEXT|BUTTON_REL,             BUTTON_NEXT },
+    { ACTION_STD_NEXTREPEAT,     BUTTON_NEXT|BUTTON_REPEAT,          BUTTON_NONE },
+
+    { ACTION_STD_OK,             BUTTON_PLAY|BUTTON_REL,             BUTTON_PLAY },
+    { ACTION_STD_CANCEL,         BUTTON_POWER|BUTTON_REL,            BUTTON_POWER },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
+};
+
+
+static const struct button_mapping button_context_keyboard[] =
+{
+    { ACTION_KBD_LEFT,         BUTTON_SCROLL_BACK,                       BUTTON_NONE },
+    { ACTION_KBD_RIGHT,        BUTTON_SCROLL_FWD,                        BUTTON_NONE },
+    { ACTION_KBD_CURSOR_LEFT,  BUTTON_PLAY | BUTTON_SCROLL_BACK,         BUTTON_NONE },
+    { ACTION_KBD_CURSOR_RIGHT, BUTTON_PLAY | BUTTON_SCROLL_FWD,          BUTTON_NONE },
+    { ACTION_KBD_DONE,         BUTTON_PLAY | BUTTON_REPEAT,              BUTTON_NONE },
+    { ACTION_KBD_SELECT,       BUTTON_PLAY | BUTTON_REL,                 BUTTON_NONE },
+    { ACTION_KBD_ABORT,        BUTTON_POWER,                             BUTTON_NONE },
+    { ACTION_KBD_UP,           BUTTON_NEXT,                              BUTTON_NONE },
+    { ACTION_KBD_UP,           BUTTON_NEXT | BUTTON_REPEAT,              BUTTON_NONE },
+    { ACTION_KBD_DOWN,         BUTTON_PREV,                              BUTTON_NONE },
+    { ACTION_KBD_DOWN,         BUTTON_PREV | BUTTON_REPEAT,              BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST
+};
+
+
+static const struct button_mapping button_context_bmark[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
+};
+
+
+static const struct button_mapping button_context_time[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
+};
+
+
+static const struct button_mapping button_context_quickscreen[] =
+{
+    { ACTION_QS_TOP,     BUTTON_SCROLL_BACK,                 BUTTON_NONE },
+    { ACTION_QS_DOWN,    BUTTON_SCROLL_FWD,                  BUTTON_NONE },
+    { ACTION_QS_LEFT,    BUTTON_PREV|BUTTON_REL,             BUTTON_NONE },
+    { ACTION_QS_LEFT,    BUTTON_PREV|BUTTON_REPEAT,          BUTTON_NONE },
+    { ACTION_QS_RIGHT,   BUTTON_NEXT|BUTTON_REL,             BUTTON_NONE },
+    { ACTION_QS_RIGHT,   BUTTON_NEXT|BUTTON_REPEAT,          BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+};
+
+
+static const struct button_mapping button_context_pitchscreen[] =
+{
+    { ACTION_PS_DEC_SMALL, BUTTON_SCROLL_FWD,   BUTTON_NONE },
+    { ACTION_PS_INC_SMALL, BUTTON_SCROLL_BACK,  BUTTON_NONE },
+    { ACTION_PS_NUDGE_RIGHT, BUTTON_NEXT,       BUTTON_NONE },
+    { ACTION_PS_NUDGE_LEFT,  BUTTON_PREV,       BUTTON_NONE },
+    { ACTION_PS_EXIT,      BUTTON_POWER,        BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+};
+
+
+static const struct button_mapping button_context_radio[] =
+{
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
+};
+
+
+const struct button_mapping* target_get_context_mapping(int context)
+{
+    switch (context & ~CONTEXT_LOCKED)
+    {
+        case CONTEXT_STD:                       { return button_context_standard; }
+        case CONTEXT_WPS:                       { return button_context_wps; }
+        case CONTEXT_LIST:                      { return button_context_list; }
+        case CONTEXT_MAINMENU:                  { return button_context_mainmenu; }
+        case CONTEXT_CUSTOM | CONTEXT_TREE:     { return button_context_tree; }
+        case CONTEXT_SETTINGS:                  { return button_context_settings; }
+        case CONTEXT_SETTINGS_COLOURCHOOSER:    { return button_context_colorchooser; }
+        case CONTEXT_SETTINGS_EQ:               { return button_context_eq; }
+        case CONTEXT_SETTINGS_TIME:             { return button_context_time; }
+        case CONTEXT_YESNOSCREEN:               { return button_context_yesno; }
+        case CONTEXT_KEYBOARD:                  { return button_context_keyboard; }
+        case CONTEXT_FM:                        { return button_context_radio; }
+        case CONTEXT_BOOKMARKSCREEN:            { return button_context_bmark; }
+        case CONTEXT_QUICKSCREEN:               { return button_context_quickscreen; }
+        case CONTEXT_PITCHSCREEN:               { return button_context_pitchscreen; }
+        case CONTEXT_CUSTOM | CONTEXT_SETTINGS:
+        case CONTEXT_SETTINGS_RECTRIGGER:       { return button_context_settings_right_is_inc; }
+        case CONTEXT_TREE:
+        {
+            if(global_settings.hold_lr_for_scroll_in_list)
+            {
+                return button_context_listtree_scroll_without_combo;
+            }
+            return button_context_listtree_scroll_with_combo;
+        }
+    }
+
+    return button_context_standard;
+}
diff --git a/apps/plugins/SOURCES.app_build b/apps/plugins/SOURCES.app_build
index cdd764dc27..439a6dd29c 100644
--- a/apps/plugins/SOURCES.app_build
+++ b/apps/plugins/SOURCES.app_build
@@ -1,4 +1,4 @@
-#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90) || defined(HIBY_R3PROII) || defined(HIBY_R1)
+#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90) || defined(HIBY_R3PROII) || defined(HIBY_R1) || defined(HIDIZS_AP80MAX)
 /* In devices running RockBox as an application, but having a keypad */
 #include "SOURCES"
 #else
diff --git a/apps/plugins/SUBDIRS.app_build b/apps/plugins/SUBDIRS.app_build
index 5618f41afe..d4c382050c 100644
--- a/apps/plugins/SUBDIRS.app_build
+++ b/apps/plugins/SUBDIRS.app_build
@@ -1,4 +1,4 @@
-#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90) || defined(HIBY_R3PROII) || defined(HIBY_R1)
+#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90) || defined(HIBY_R3PROII) || defined(HIBY_R1) || defined(HIDIZS_AP80MAX)
 /* This is for devices having a keypad, running RockBox as an application */
 #include "SUBDIRS"
 
diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c
index ec7ad45bb8..4b2d90588c 100644
--- a/apps/plugins/battery_bench.c
+++ b/apps/plugins/battery_bench.c
@@ -243,7 +243,7 @@ struct battery_tables_t {
 #define BATTERY_ON_TXT  "Play"
 #define BATTERY_OFF_TXT "Power"
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/bitmaps/mono/SOURCES b/apps/plugins/bitmaps/mono/SOURCES
index 067942a70e..d864ef5ea7 100644
--- a/apps/plugins/bitmaps/mono/SOURCES
+++ b/apps/plugins/bitmaps/mono/SOURCES
@@ -21,7 +21,8 @@ bubbles_bubble.220x176x1.bmp
 #elif ((LCD_WIDTH == 240) && (LCD_HEIGHT == 240)) || \
       ((LCD_WIDTH == 320) && (LCD_HEIGHT == 240)) || \
       ((LCD_WIDTH == 240) && (LCD_HEIGHT >= 320)) || \
-      ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400))
+      ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400)) || \
+      ((LCD_WIDTH == 360) && (LCD_HEIGHT == 640))
 bubbles_bubble.320x240x1.bmp
 #elif   ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \
         ((LCD_WIDTH == 480) && (LCD_HEIGHT >= 640))
diff --git a/apps/plugins/bitmaps/native/SOURCES b/apps/plugins/bitmaps/native/SOURCES
index b2286bcc33..e9c852e1b2 100644
--- a/apps/plugins/bitmaps/native/SOURCES
+++ b/apps/plugins/bitmaps/native/SOURCES
@@ -438,7 +438,7 @@ invadrox_ufo_explode.21x8x16.bmp
 invadrox_numbers.50x7x16.bmp
 #if LCD_WIDTH == 480
 invadrox_background.480x640x16.bmp
-#elif LCD_WIDTH == 360 && LCD_HEIGHT == 400
+#elif LCD_WIDTH == 360 && (LCD_HEIGHT == 400 || LCD_HEIGHT == 640)
 invadrox_background.360x400x16.bmp
 #elif LCD_WIDTH == 320
 invadrox_background.320x240x16.bmp
@@ -513,7 +513,7 @@ jewels.240x240x16.bmp
 jewels.320x240x16.bmp
 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
 jewels.320x240x16.bmp
-#elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400)
+#elif (LCD_WIDTH == 360) && ((LCD_HEIGHT == 400) || (LCD_HEIGHT == 640))
 jewels.360x400x16.bmp
 #elif   ((LCD_WIDTH >= 480) && (LCD_HEIGHT >= 640)) || \
         ((LCD_WIDTH >= 640) && (LCD_HEIGHT >= 480))
@@ -947,7 +947,8 @@ superdom_boarditems.176x132x16.bmp
 superdom_boarditems.320x240x16.bmp
 #elif ((LCD_WIDTH == 240) && (LCD_HEIGHT == 320)) || \
       ((LCD_WIDTH == 240) && (LCD_HEIGHT == 400)) || \
-      ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400))
+      ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400)) || \
+      ((LCD_WIDTH == 360) && (LCD_HEIGHT == 640))
 superdom_boarditems.240x320x16.bmp
 #elif (LCD_WIDTH >= 480 && LCD_HEIGHT >= 640)
 superdom_boarditems.480x640x16.bmp
diff --git a/apps/plugins/blackjack.c b/apps/plugins/blackjack.c
index cca73029b2..233c3e760d 100644
--- a/apps/plugins/blackjack.c
+++ b/apps/plugins/blackjack.c
@@ -591,7 +591,7 @@ enum {
 #define BJACK_LEFT          BUTTON_LEFT
 
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define BJACK_QUIT          BUTTON_POWER
 #define BJACK_QUIT_NAME     "QUIT"
 
diff --git a/apps/plugins/brickmania.c b/apps/plugins/brickmania.c
index 4ec3a40f3a..b588000cdb 100644
--- a/apps/plugins/brickmania.c
+++ b/apps/plugins/brickmania.c
@@ -353,7 +353,7 @@ CONFIG_KEYPAD == SANSA_M200_PAD
 #define UP          BUTTON_UP
 #define DOWN        BUTTON_DOWN
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define QUIT        BUTTON_POWER
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/bubbles.c b/apps/plugins/bubbles.c
index a647d98fad..374b4cad38 100644
--- a/apps/plugins/bubbles.c
+++ b/apps/plugins/bubbles.c
@@ -138,6 +138,17 @@ enum {
 #define XOFS          128
 #define MAX_FPS       40
 
+#elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 640)
+#define XOFS            86
+#define YOFS            220
+#define SCORE_TXT_X     28
+#define SCORE_TXT_WIDTH 32
+#define SCORE_TXT_Y     48
+#define LEVEL_TXT_X     27
+#define LEVEL_TXT_WIDTH 32
+#define LEVEL_TXT_Y     5
+#define MAX_FPS         40
+
 #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400)
 #define XOFS            86
 #define YOFS            100
diff --git a/apps/plugins/calculator.c b/apps/plugins/calculator.c
index 0b06609573..252618865c 100644
--- a/apps/plugins/calculator.c
+++ b/apps/plugins/calculator.c
@@ -522,7 +522,7 @@ F3: equal to "="
 #define CALCULATOR_CALC     BUTTON_MENU
 #define CALCULATOR_CLEAR    BUTTON_BACK
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define CALCULATOR_QUIT     BUTTON_POWER
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/calendar.c b/apps/plugins/calendar.c
index b1c2662038..2b6813c3f4 100644
--- a/apps/plugins/calendar.c
+++ b/apps/plugins/calendar.c
@@ -408,7 +408,7 @@
 #define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
 #define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/chessbox/chessbox_pgn.h b/apps/plugins/chessbox/chessbox_pgn.h
index eecb70d1c0..d046b1ed8b 100644
--- a/apps/plugins/chessbox/chessbox_pgn.h
+++ b/apps/plugins/chessbox/chessbox_pgn.h
@@ -566,7 +566,7 @@
 #define CB_SCROLL_LEFT  (BUTTON_LEFT|BUTTON_REPEAT)
 #define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT)
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/chessclock.c b/apps/plugins/chessclock.c
index 5d4ca183ae..fd9bc92708 100644
--- a/apps/plugins/chessclock.c
+++ b/apps/plugins/chessclock.c
@@ -384,7 +384,7 @@
 #define CHC_SETTINGS_OK     BUTTON_SELECT
 #define CHC_SETTINGS_CANCEL BUTTON_POWER
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define CHC_QUIT            BUTTON_POWER
 
 #elif (CONFIG_KEYPAD == MA_PAD)
diff --git a/apps/plugins/chip8.c b/apps/plugins/chip8.c
index 0df928eb77..df583bb04c 100644
--- a/apps/plugins/chip8.c
+++ b/apps/plugins/chip8.c
@@ -1326,7 +1326,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define CHIP8_KEY9 BUTTON_START
 #define CHIP8_KEYA BUTTON_X
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #else
diff --git a/apps/plugins/clix.c b/apps/plugins/clix.c
index 721f2b85fa..356021f826 100644
--- a/apps/plugins/clix.c
+++ b/apps/plugins/clix.c
@@ -305,7 +305,7 @@
 #define CLIX_BUTTON_RIGHT       BUTTON_RIGHT
 #define CLIX_BUTTON_CLICK       BUTTON_SELECT
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define CLIX_BUTTON_QUIT        BUTTON_POWER
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/cube.c b/apps/plugins/cube.c
index fec40eb274..9a48b37a37 100644
--- a/apps/plugins/cube.c
+++ b/apps/plugins/cube.c
@@ -391,7 +391,7 @@
 #define CUBE_PAUSE          BUTTON_PLAY
 #define CUBE_HIGHSPEED      BUTTON_BACK
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c
index 1e64c2f40d..5f3eb68cbe 100644
--- a/apps/plugins/doom/i_video.c
+++ b/apps/plugins/doom/i_video.c
@@ -616,7 +616,7 @@ void I_ShutdownGraphics(void)
 #define DOOMBUTTON_WEAPON  BUTTON_BACK
 #define DOOMBUTTON_MAP     (BUTTON_BACK|BUTTON_REPEAT)
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define DOOMBUTTON_ESC     BUTTON_POWER
 #define DOOMBUTTON_MAP     BUTTON_PREV
 
diff --git a/apps/plugins/flipit.c b/apps/plugins/flipit.c
index 66bf87cc94..673dadbb3e 100644
--- a/apps/plugins/flipit.c
+++ b/apps/plugins/flipit.c
@@ -481,7 +481,7 @@
 #define FLIPIT_STEP_BY_STEP BUTTON_VOL_UP
 #define FLIPIT_TOGGLE       BUTTON_SELECT
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/fractals/fractal.h b/apps/plugins/fractals/fractal.h
index 96a41736e7..84a932d713 100644
--- a/apps/plugins/fractals/fractal.h
+++ b/apps/plugins/fractals/fractal.h
@@ -491,7 +491,7 @@
 #define FRACTAL_PRECISION_DEC   BUTTON_BACK
 #define FRACTAL_RESET           BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define FRACTAL_QUIT            BUTTON_POWER
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/imageviewer/imageviewer_button.h b/apps/plugins/imageviewer/imageviewer_button.h
index 2396c647b3..cbfce5bc9a 100644
--- a/apps/plugins/imageviewer/imageviewer_button.h
+++ b/apps/plugins/imageviewer/imageviewer_button.h
@@ -544,7 +544,7 @@
 #define IMGVIEW_MENU        (BUTTON_PLAY|BUTTON_REPEAT)
 #define IMGVIEW_SLIDE_SHOW  BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/invadrox.c b/apps/plugins/invadrox.c
index 8500e2b558..294b4b3c3f 100644
--- a/apps/plugins/invadrox.c
+++ b/apps/plugins/invadrox.c
@@ -280,7 +280,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define RIGHT BUTTON_RIGHT
 #define FIRE  BUTTON_SELECT
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
@@ -687,6 +687,24 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define LIVES_X 8
 #define MAX_Y 15
 
+#elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 640)
+
+/* Hidizs AP80 Pro Max
+ */
+#define ARCADISH_GRAPHICS
+#define PLAYFIELD_X 32
+#define SHIP_Y (PLAYFIELD_Y - 3 * SHIP_HEIGHT)
+#define ALIEN_START_Y (UFO_Y + 3 * ALIEN_HEIGHT)
+/* Redefine SCORE_Y */
+#undef SCORE_Y
+#define SCORE_Y 80
+#define SCORENUM_X (PLAYFIELD_X + NUMBERS_WIDTH)
+#define SCORENUM_Y SCORE_Y + (2 * (FONT_HEIGHT + 1) + 1)
+#define HISCORENUM_X (LCD_WIDTH - PLAYFIELD_X - 1 - 6 * NUMBERS_WIDTH - 5 * NUM_SPACING)
+#define SHIELD_Y (PLAYFIELD_Y - 6 * SHIP_HEIGHT)
+#define LIVES_X 10
+#define MAX_Y 30
+
 #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400)
 
 /* Shanling Q1
diff --git a/apps/plugins/jewels.c b/apps/plugins/jewels.c
index 779febed22..ce2de05330 100644
--- a/apps/plugins/jewels.c
+++ b/apps/plugins/jewels.c
@@ -366,7 +366,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define HK_SELECT "SELECT"
 #define HK_CANCEL "BACK"
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/lib/keymaps.h b/apps/plugins/lib/keymaps.h
index 71d5b6ad5f..51e9f65395 100644
--- a/apps/plugins/lib/keymaps.h
+++ b/apps/plugins/lib/keymaps.h
@@ -249,7 +249,7 @@
 #define BTN_FIRE        BUTTON_SELECT
 #define BTN_PAUSE       BUTTON_POWER
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define BTN_FIRE        BUTTON_CENTER
 #define BTN_PAUSE       BUTTON_POWER
 #define BTN_HAVE_DIAGONAL
@@ -318,6 +318,7 @@
       (CONFIG_KEYPAD != CREATIVE_ZENXFI2_PAD) && \
       (CONFIG_KEYPAD != SHANLING_Q1_PAD) && \
       (CONFIG_KEYPAD != HIBY_R3PROII_PAD) && \
+      (CONFIG_KEYPAD != HIDIZS_AP80MAX_PAD) && \
       (CONFIG_KEYPAD != CTRU_PAD)
 #define BTN_FIRE       BUTTON_BOTTOMLEFT
 #define BTN_PAUSE      BUTTON_TOPLEFT
diff --git a/apps/plugins/lib/pluginlib_actions.c b/apps/plugins/lib/pluginlib_actions.c
index 5b175a66a4..a45a0a0399 100644
--- a/apps/plugins/lib/pluginlib_actions.c
+++ b/apps/plugins/lib/pluginlib_actions.c
@@ -529,7 +529,7 @@ const struct button_mapping pla_main_ctx[] =
     {PLA_SELECT,            BUTTON_SELECT,                      BUTTON_NONE},
     {PLA_SELECT_REL,        BUTTON_SELECT|BUTTON_REL,           BUTTON_SELECT},
     {PLA_SELECT_REPEAT,     BUTTON_SELECT|BUTTON_REPEAT,        BUTTON_NONE},
-#elif (CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD)
+#elif (CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD)
     {PLA_EXIT,              BUTTON_POWER,                       BUTTON_NONE},
 #elif (CONFIG_KEYPAD == MA_PAD)
     {PLA_CANCEL,            BUTTON_BACK|BUTTON_REL,            BUTTON_BACK},
diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c
index 5ec6e7ede4..647273bf4a 100644
--- a/apps/plugins/midi/midiplay.c
+++ b/apps/plugins/midi/midiplay.c
@@ -316,7 +316,7 @@
 #define MIDI_VOL_DOWN     BUTTON_VOL_DOWN
 #define MIDI_PLAYPAUSE    BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/minesweeper.c b/apps/plugins/minesweeper.c
index 41145c90b8..704c659a40 100644
--- a/apps/plugins/minesweeper.c
+++ b/apps/plugins/minesweeper.c
@@ -441,7 +441,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #   define MINESWP_DISCOVER     (BUTTON_MENU|BUTTON_REPEAT)
 #   define MINESWP_INFO         BUTTON_MENU
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/mp3_encoder.c b/apps/plugins/mp3_encoder.c
index af998487e9..f6423a4329 100644
--- a/apps/plugins/mp3_encoder.c
+++ b/apps/plugins/mp3_encoder.c
@@ -2578,7 +2578,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define MP3ENC_DONE     BUTTON_POWER
 #define MP3ENC_SELECT   BUTTON_SELECT
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
index 3c6ec54a0e..8475f26b7f 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ b/apps/plugins/mpegplayer/mpeg_settings.c
@@ -352,7 +352,7 @@ struct mpeg_settings settings;
 #define MPEG_START_TIME_DOWN        BUTTON_DOWN
 #define MPEG_START_TIME_EXIT        BUTTON_BACK
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define MPEG_START_TIME_EXIT        BUTTON_POWER
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
index 60522cd56c..761c95cde0 100644
--- a/apps/plugins/mpegplayer/mpegplayer.c
+++ b/apps/plugins/mpegplayer/mpegplayer.c
@@ -485,7 +485,7 @@ CONFIG_KEYPAD == SANSA_M200_PAD
 #define MPEG_RW         BUTTON_LEFT
 #define MPEG_FF         BUTTON_RIGHT
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c
index 4754416ab7..c0bef75cd4 100644
--- a/apps/plugins/oscilloscope.c
+++ b/apps/plugins/oscilloscope.c
@@ -549,7 +549,7 @@
 #define OSCILLOSCOPE_VOL_UP         BUTTON_UP
 #define OSCILLOSCOPE_VOL_DOWN       BUTTON_DOWN
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/pacbox/pacbox.h b/apps/plugins/pacbox/pacbox.h
index 4292e47f18..855e3c536c 100644
--- a/apps/plugins/pacbox/pacbox.h
+++ b/apps/plugins/pacbox/pacbox.h
@@ -386,7 +386,7 @@
 #define PACMAN_1UP      BUTTON_VOL_UP
 #define PACMAN_COIN     BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define PACMAN_UP       BUTTON_TOPMIDDLE
 #define PACMAN_DOWN     BUTTON_BOTTOMMIDDLE
 #define PACMAN_LEFT     BUTTON_MIDLEFT
diff --git a/apps/plugins/pegbox.c b/apps/plugins/pegbox.c
index 7fbac41335..bd17965ef6 100644
--- a/apps/plugins/pegbox.c
+++ b/apps/plugins/pegbox.c
@@ -710,7 +710,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define LVL_UP_TEXT "UP+MENU"
 #define LVL_DOWN_TEXT "DOWN+MENU"
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/pong.c b/apps/plugins/pong.c
index a7aa93724f..5cc79de1d1 100644
--- a/apps/plugins/pong.c
+++ b/apps/plugins/pong.c
@@ -317,7 +317,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define PONG_RIGHT_UP   BUTTON_BACK
 #define PONG_RIGHT_DOWN BUTTON_RIGHT
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/reversi/reversi-gui.h b/apps/plugins/reversi/reversi-gui.h
index c73acb2797..79755f620a 100644
--- a/apps/plugins/reversi/reversi-gui.h
+++ b/apps/plugins/reversi/reversi-gui.h
@@ -351,7 +351,7 @@
 #define REVERSI_BUTTON_MAKE_MOVE   BUTTON_SELECT
 #define REVERSI_BUTTON_MENU        BUTTON_MENU
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif (CONFIG_KEYPAD == MA_PAD)
diff --git a/apps/plugins/rockblox.c b/apps/plugins/rockblox.c
index bdc3795301..b310cf65bd 100644
--- a/apps/plugins/rockblox.c
+++ b/apps/plugins/rockblox.c
@@ -457,7 +457,7 @@
 #define ROCKBLOX_RESTART        BUTTON_BACK
 #define ROCKBLOX_SCROLL_ENABLED 1
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
@@ -576,6 +576,23 @@
 #define LEVEL_Y 142
 #define LINES_Y 218
 
+#elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 640)
+
+/* 10x20 board of 24px blocks = 240x480, leaving a 100px label column */
+#define BLOCK_WIDTH 24
+#define BLOCK_HEIGHT 24
+#define BOARD_X 8
+#define BOARD_Y 40
+#define LABEL_X 258
+#define SCORE_Y 60
+#define LEVEL_Y 140
+#define LINES_Y 220
+#define HIGH_LABEL_X   258
+#define HIGH_SCORE_Y   320
+#define HIGH_LEVEL_Y   400
+#define PREVIEW_X 258
+#define PREVIEW_Y 480
+
 #elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400)
 
 #define BLOCK_WIDTH 19
diff --git a/apps/plugins/rockboy/rockboy.c b/apps/plugins/rockboy/rockboy.c
index 96fb2c68ba..7d7c9f1b01 100644
--- a/apps/plugins/rockboy/rockboy.c
+++ b/apps/plugins/rockboy/rockboy.c
@@ -457,7 +457,7 @@ static void setoptions (void)
         options.SELECT  = BUTTON_VOL_UP;
         options.MENU    = BUTTON_POWER;
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
         /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c
index bfde6c53f0..7ed5b4104a 100644
--- a/apps/plugins/rockpaint.c
+++ b/apps/plugins/rockpaint.c
@@ -392,7 +392,7 @@
 #define ROCKPAINT_LEFT      BUTTON_LEFT
 #define ROCKPAINT_RIGHT     BUTTON_RIGHT
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == EROSQ_PAD
diff --git a/apps/plugins/sliding_puzzle.c b/apps/plugins/sliding_puzzle.c
index d3189945ee..562384ac6a 100644
--- a/apps/plugins/sliding_puzzle.c
+++ b/apps/plugins/sliding_puzzle.c
@@ -347,7 +347,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define PUZZLE_SHUFFLE  BUTTON_BACK
 #define PUZZLE_PICTURE  BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/snake.c b/apps/plugins/snake.c
index 49c4ca81e8..2ae29ee6c0 100644
--- a/apps/plugins/snake.c
+++ b/apps/plugins/snake.c
@@ -304,7 +304,7 @@ dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left;
 #define SNAKE_DOWN      BUTTON_DOWN
 #define SNAKE_PLAYPAUSE BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/snake2.c b/apps/plugins/snake2.c
index b5f15b80c2..6b225713e4 100644
--- a/apps/plugins/snake2.c
+++ b/apps/plugins/snake2.c
@@ -448,7 +448,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define SNAKE2_PLAYPAUSE    BUTTON_PLAY
 #define SNAKE2_PLAYPAUSE_TEXT "PLAY"
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c
index 027ad99c7e..625a2679fd 100644
--- a/apps/plugins/sokoban.c
+++ b/apps/plugins/sokoban.c
@@ -680,7 +680,7 @@
 #define BUTTON_SAVE        BUTTON_BACK
 #define BUTTON_SAVE_NAME   "BACK"
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c
index aa5f876c80..abe2143ef8 100644
--- a/apps/plugins/solitaire.c
+++ b/apps/plugins/solitaire.c
@@ -722,7 +722,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #   define HK_CUR2STACK     "HOLD SELECT"
 #   define HK_REM2STACK     "VOL+"
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #   define SOL_QUIT         BUTTON_POWER
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/spacerocks.c b/apps/plugins/spacerocks.c
index 611a373418..95338d0ef9 100644
--- a/apps/plugins/spacerocks.c
+++ b/apps/plugins/spacerocks.c
@@ -362,7 +362,7 @@
 #define AST_RIGHT       BUTTON_RIGHT
 #define AST_FIRE        BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/star.c b/apps/plugins/star.c
index 735fb3bc60..86e95fc2ce 100644
--- a/apps/plugins/star.c
+++ b/apps/plugins/star.c
@@ -650,7 +650,7 @@
 #define STAR_LEVEL_DOWN_NAME "VOL-"
 #define STAR_LEVEL_REPEAT_NAME "BACK"
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define STAR_QUIT           BUTTON_POWER
 #define STAR_QUIT_NAME      "POWER"
 
diff --git a/apps/plugins/sudoku/sudoku.h b/apps/plugins/sudoku/sudoku.h
index c43a6b0d96..8926bd68af 100644
--- a/apps/plugins/sudoku/sudoku.h
+++ b/apps/plugins/sudoku/sudoku.h
@@ -458,7 +458,7 @@
 #define SUDOKU_BUTTON_TOGGLE     BUTTON_PLAY
 #define SUDOKU_BUTTON_POSSIBLE   BUTTON_BACK
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/test_touchscreen.c b/apps/plugins/test_touchscreen.c
index 3c9e559a45..b5999b672a 100644
--- a/apps/plugins/test_touchscreen.c
+++ b/apps/plugins/test_touchscreen.c
@@ -36,7 +36,7 @@
 #elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
 #define TOUCHSCREEN_QUIT   BUTTON_POWER
 #define TOUCHSCREEN_TOGGLE BUTTON_MENU
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define TOUCHSCREEN_QUIT   BUTTON_POWER
 #define TOUCHSCREEN_TOGGLE BUTTON_PLAY
 #elif (CONFIG_KEYPAD == ANDROID_PAD)
diff --git a/apps/plugins/text_viewer/tv_button.h b/apps/plugins/text_viewer/tv_button.h
index d1bacb1f10..e64ba00e58 100644
--- a/apps/plugins/text_viewer/tv_button.h
+++ b/apps/plugins/text_viewer/tv_button.h
@@ -560,7 +560,7 @@
 #define TV_LINE_DOWN    BUTTON_SCROLL_FWD
 #define TV_BOOKMARK     BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 #define TV_BOOKMARK     BUTTON_PLAY
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/vu_meter.c b/apps/plugins/vu_meter.c
index e1178fc691..22f5fe4b31 100644
--- a/apps/plugins/vu_meter.c
+++ b/apps/plugins/vu_meter.c
@@ -443,7 +443,7 @@
 #define LABEL_MENU      "MENU"
 #define LABEL_VOLUME    "VOL+/VOL-"
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/apps/plugins/wormlet.c b/apps/plugins/wormlet.c
index fec98315af..af1e0c9662 100644
--- a/apps/plugins/wormlet.c
+++ b/apps/plugins/wormlet.c
@@ -396,7 +396,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define BTN_QUIT        BUTTON_POWER
 #define BTN_STOPRESET   BUTTON_BACK
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
@@ -525,7 +525,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #elif ((LCD_WIDTH == 240) && (LCD_HEIGHT == 240)) || \
     ((LCD_WIDTH == 320) && (LCD_HEIGHT == 240)) || \
     ((LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))) || \
-    ((LCD_WIDTH == 360) && (LCD_HEIGHT == 400))
+    ((LCD_WIDTH == 360) && ((LCD_HEIGHT == 400) || (LCD_HEIGHT == 640)))
 #define FOOD_SIZE 7
 #define ARGH_SIZE 8
 #define SPEED 4
diff --git a/apps/plugins/xobox.c b/apps/plugins/xobox.c
index 445ca77b18..12c9c4fd2b 100644
--- a/apps/plugins/xobox.c
+++ b/apps/plugins/xobox.c
@@ -350,7 +350,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define DOWN    BUTTON_DOWN
 #define PAUSE   BUTTON_PLAY
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == RG_NANO_PAD
diff --git a/apps/plugins/zxbox/keymaps.h b/apps/plugins/zxbox/keymaps.h
index fa7394abfa..e87c6afff3 100644
--- a/apps/plugins/zxbox/keymaps.h
+++ b/apps/plugins/zxbox/keymaps.h
@@ -282,7 +282,7 @@
 #define ZX_UP           BUTTON_UP
 #define ZX_DOWN         BUTTON_DOWN
 
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
+#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
 /* use touchscreen */
 
 #elif CONFIG_KEYPAD == MA_PAD
diff --git a/backdrops/cabbiev2.360x640x16.bmp b/backdrops/cabbiev2.360x640x16.bmp
new file mode 100644
index 0000000000..4b527dbf88
Binary files /dev/null and b/backdrops/cabbiev2.360x640x16.bmp differ
diff --git a/bootloader/hibyos_linux.c b/bootloader/hibyos_linux.c
index edda204796..449ff6bd76 100644
--- a/bootloader/hibyos_linux.c
+++ b/bootloader/hibyos_linux.c
@@ -126,6 +126,18 @@
 #define BUTTON_LEFT   BUTTON_VOL_DOWN
 #define BUTTON_RIGHT  BUTTON_VOL_UP
 #include "bitmaps/hibyicon.h"
+#elif defined(HIDIZS_AP80MAX)
+#define ICON_WIDTH  130
+#define ICON_HEIGHT 130
+#define ICON_NAME bm_hibyicon
+#define OF_NAME "HIBY PLAYER"
+#define BUTTON_UP     BUTTON_PREV
+#define BUTTON_DOWN   BUTTON_NEXT
+#define BUTTON_SELECT BUTTON_PLAY
+/* No volume keys, so the scroll wheel takes left/right */
+#define BUTTON_LEFT   BUTTON_SCROLL_BACK
+#define BUTTON_RIGHT  BUTTON_SCROLL_FWD
+#include "bitmaps/hibyicon.h"
 #else
 #error "must define ICON_WIDTH/HEIGHT"
 #endif
@@ -279,7 +291,7 @@ static enum boot_mode get_boot_mode(void)
     while(true)
     {
         /* on usb detect, immediately boot with last choice */
-#if !defined(HIBY_R3PROII) && !defined(HIBY_R1)
+#if !defined(HIBY_R3PROII) && !defined(HIBY_R1) && !defined(HIDIZS_AP80MAX)
         if(!adb_running && power_input_status() & POWER_INPUT_USB_CHARGER)
         {
             /* save last choice */
@@ -526,7 +538,7 @@ static void adb(int start)
     pid_t pid = fork();
     if(pid == 0)
     {
-#if defined(HIBY_R3PROII) || defined(HIBY_R1)
+#if defined(HIBY_R3PROII) || defined(HIBY_R1) || defined(HIDIZS_AP80MAX)
         execlp("/etc/init.d/T90adb", "T90adb", start ? "start" : "stop", NULL);
 #else
         execlp("/etc/init.d/K90adb", "K90adb", start ? "start" : "stop", NULL);
@@ -694,9 +706,13 @@ int main(int argc, char **argv)
         }
         else if(mode == BOOT_ROCKBOX)
         {
-#if defined(HIBY_R3PROII) || defined(HIBY_R1)
+#if defined(HIBY_R3PROII) || defined(HIBY_R1) || defined(HIDIZS_AP80MAX)
             /* Suspend bluetooth as it's not currently supported */
             system("/usr/bin/bt_suspend");
+#endif
+#if defined(HIDIZS_AP80MAX)
+            /* Hidizs bt_suspend has these commented out */
+            system("killall bluealsa bt-agent bluetoothd dbus-daemon 2>/dev/null");
 #endif
             fflush(stdout);
             mount_storage(true);
diff --git a/docs/CREDITS b/docs/CREDITS
index b7acbb46d6..9b64d7dfbc 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -765,6 +765,7 @@ Adam N. Burke
 Lê Khánh Bình
 Michael McAllister
 Hemant Kumar
+Jerry Shen
 
 The libmad team
 The wavpack team
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 3b3a62765d..7ae34427e9 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -187,7 +187,18 @@ target/hosted/hiby/hibylinux_codec.c
 #endif
 #endif
 
-#if (defined(HIBY_R1) || defined(HIBY_R3PROII)) && !defined(SIMULATOR)
+#if defined(HIDIZS_AP80MAX) && !defined(SIMULATOR)
+target/hosted/hiby/usb-hiby-gadget.c
+target/hosted/hiby/ap80max/button-ap80max.c
+target/hosted/hiby/ap80max/powermgmt-ap80max.c
+target/hosted/hiby/debug-hiby.c
+#ifndef BOOTLOADER
+target/hosted/hiby/ap80max/led-ap80max.c
+target/hosted/hiby/hibylinux_codec.c
+#endif
+#endif
+
+#if (defined(HIBY_R1) || defined(HIBY_R3PROII) || defined(HIDIZS_AP80MAX)) && !defined(SIMULATOR)
 target/hosted/hiby/usb-dac-hiby.c
 #endif
 
@@ -222,7 +233,7 @@ target/hosted/xduoo/xduoolinux_codec.c
 target/hosted/button-devinput.c
 #endif
 
-#if defined(HIBY_LINUX) && !defined(HIBY_R3PROII) && !defined(HIBY_R1) && !defined(SIMULATOR)
+#if defined(HIBY_LINUX) && !defined(HIBY_R3PROII) && !defined(HIBY_R1) && !defined(HIDIZS_AP80MAX) && !defined(SIMULATOR)
 target/hosted/usb-hiby.c
 #endif
 
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 997d14e010..afa0b274f8 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -157,6 +157,7 @@
 #define RG_NANO_PAD        77
 #define CTRU_PAD           78
 #define HIBY_R3PROII_PAD   79
+#define HIDIZS_AP80MAX_PAD 80
 
 /* CONFIG_REMOTE_KEYPAD */
 #define H100_REMOTE   1
@@ -580,6 +581,8 @@ Lyre prototype 1 */
 #include "config/hibyr3proii.h"
 #elif defined(HIBY_R1)
 #include "config/hibyr1.h"
+#elif defined(HIDIZS_AP80MAX)
+#include "config/hidizsap80max.h"
 #else
 #error "unknown hardware platform!"
 #endif
diff --git a/firmware/export/config/hidizsap80max.h b/firmware/export/config/hidizsap80max.h
new file mode 100644
index 0000000000..38d8b49d31
--- /dev/null
+++ b/firmware/export/config/hidizsap80max.h
@@ -0,0 +1,105 @@
+/*
+ * This config file is for the Hidizs AP80 Pro Max based on the x1600E soc
+ */
+
+/* For Rolo and boot loader */
+#define MODEL_NUMBER 125
+#define MODEL_NAME   "HIDIZS AP80 PRO MAX"
+
+#define PIVOT_ROOT "/data/mnt/sd_0"
+#define MULTIDRIVE_DIR "/data/mnt/usb"
+
+/* LCD dimensions. The framebuffer is not the panel: /dev/fb0 is 480x640 but
+   only the center 360 columns are scanned out - see hiby/lcd-target.h.
+   sqrt(360^2 + 640^2) / 2.95" = 249 */
+#define LCD_WIDTH 360
+#define LCD_HEIGHT 640
+#define LCD_DPI 249
+
+#define HAVE_LCD_SLEEP
+#define LCD_SLEEP_TIMEOUT (2*HZ)
+
+#define LCD_DEPTH  16   /* 65536 colours */
+#define LCD_PIXELFORMAT RGB565 /* rgb565 */
+
+/* /dev/fb0 is 480 columns wide but only the center 360 display */
+#define FB_STRIDE_MISMATCH   480
+#define FB_STRIDE_XOFFSET ((FB_STRIDE_MISMATCH - LCD_WIDTH) / 2)
+
+#define CPU_FREQ           1008000000
+
+#ifndef SIMULATOR
+#define HAVE_GENERAL_PURPOSE_LED
+#endif
+
+/* define this if you have access to the quickscreen */
+#define HAVE_QUICKSCREEN
+#define HAVE_HOTKEY
+
+#define HAVE_HEADPHONE_DETECTION
+
+#ifndef BOOTLOADER
+#define HAVE_BUTTON_DATA
+#define HAVE_TOUCHSCREEN
+#endif
+
+/* Identity, as the digitiser already reports in panel coordinates. EVIOCGABS
+   declares twice that range but the hardware does not use it */
+#define DEFAULT_TOUCHSCREEN_CALIBRATION { .A=1, .B=0, .C=0, \
+                                          .D=0, .E=1, .F=0, \
+                                          .divider=1 }
+
+#define HAVE_SCROLLWHEEL
+
+#ifndef CONFIG_BACKLIGHT_FADING
+#undef CONFIG_BACKLIGHT_FADING
+#endif
+
+/* KeyPad configuration for plugins */
+#define CONFIG_KEYPAD HIDIZS_AP80MAX_PAD
+
+/* There are no volume buttons, so HAVE_VOLUME_IN_LIST is not defined - the
+   scroll wheel handles volume instead */
+
+/* Battery */
+#define BATTERY_TYPES_COUNT  1
+
+/* Audio codec */
+#define HAVE_HIBY_LINUX_CODEC
+
+/* We don't have hardware controls */
+#define HAVE_SW_TONE_CONTROLS
+
+/* HW codec is flexible */
+#define HW_SAMPR_CAPS SAMPR_CAP_ALL_192
+
+/* Battery */
+#define CONFIG_BATTERY_MEASURE (VOLTAGE_MEASURE|PERCENTAGE_MEASURE|TIME_MEASURE)
+
+#define BATTERY_CAPACITY_DEFAULT 100 /* default battery capacity */
+#define BATTERY_CAPACITY_MIN 100  /* min. capacity selectable */
+#define BATTERY_CAPACITY_MAX 100 /* max. capacity selectable */
+#define BATTERY_CAPACITY_INC 0   /* capacity increment */
+
+/* Special backlight paths */
+#define BACKLIGHT_HIBY
+
+#define MIN_BRIGHTNESS_SETTING      1
+#define MAX_BRIGHTNESS_SETTING      100
+#define BRIGHTNESS_STEP             5
+#define DEFAULT_BRIGHTNESS_SETTING  100
+
+/* ROLO */
+#define BOOTFILE_EXT "ap80max"
+#define BOOTFILE     "rockbox." BOOTFILE_EXT
+#define BOOTDIR      "/.rockbox"
+
+/* USB */
+#define HAVE_USB_ADB
+#define HAVE_HOST_USB_AUDIO
+#define HAVE_USB_POWER
+#define USB_VID_STR "C502"
+#define USB_PID_STR "008C"
+
+/* Generic HiBy stuff */
+#include "hibylinux.h"
diff --git a/firmware/target/hosted/hiby/ap80max/button-ap80max.c b/firmware/target/hosted/hiby/ap80max/button-ap80max.c
new file mode 100644
index 0000000000..1d61d4371d
--- /dev/null
+++ b/firmware/target/hosted/hiby/ap80max/button-ap80max.c
@@ -0,0 +1,83 @@
+/***************************************************************************
+ *             __________               __   ___
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ *
+ * Copyright (C) 2017 Marcin Bukat
+ * Copyright (C) 2025 by Melissa Autumn
+ * Copyright (C) 2026 by Jerry Shen
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <linux/input.h>
+
+#include "sysfs.h"
+#include "button.h"
+#include "button-target.h"
+#include "hibylinux_codec.h"
+#include "touchscreen.h"
+#ifdef HAVE_BACKLIGHT
+#include "backlight.h"
+#endif /* HAVE_BACKLIGHT */
+
+/*
+ *   /dev/input: gpio keys, adc keys, ring encoder, touchscreen
+ */
+
+int button_map(int keycode)
+{
+    switch(keycode)
+    {
+        case KEY_PLAYPAUSE:
+            return BUTTON_PLAY;
+        /* Keys are reversed as per glyphs */
+        case KEY_PREVIOUSSONG:
+            return BUTTON_NEXT;
+        case KEY_NEXTSONG:
+            return BUTTON_PREV;
+        case KEY_POWER:
+            return BUTTON_POWER;
+        /* Scroll wheel */
+        case KEY_LEFT:
+            return BUTTON_SCROLL_FWD;
+        case KEY_RIGHT:
+            return BUTTON_SCROLL_BACK;
+
+        case BTN_TOUCH:
+        {
+#ifdef HAVE_BACKLIGHT
+            if (is_backlight_on(true)) {
+                return BUTTON_TOUCH;
+            }
+            // Ignore
+            return 0;
+#else
+            return BUTTON_TOUCH;
+#endif
+        }
+        default:
+            return 0;
+    }
+}
+
+bool headphones_inserted(void)
+{
+    #ifdef BOOTLOADER
+    int ps = 0;
+    #else
+    int ps = hiby_get_outputs();
+    #endif
+
+    return (ps == 2 || ps == 3);
+}
diff --git a/firmware/target/hosted/hiby/ap80max/button-target.h b/firmware/target/hosted/hiby/ap80max/button-target.h
new file mode 100644
index 0000000000..3ee0aec152
--- /dev/null
+++ b/firmware/target/hosted/hiby/ap80max/button-target.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ *
+ * Copyright (C) 2026 by Jerry Shen
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _BUTTON_TARGET_H_
+#define _BUTTON_TARGET_H_
+
+#include <stdbool.h>
+#include "config.h"
+
+/* Main unit's buttons - four keys and a scroll wheel, no volume keys. */
+
+#define BUTTON_POWER                0x00000001
+#define BUTTON_PREV                 0x00000002
+#define BUTTON_NEXT                 0x00000004
+#define BUTTON_PLAY                 0x00000008
+
+/* Scroll wheel */
+#define BUTTON_SCROLL_BACK          0x00000010
+#define BUTTON_SCROLL_FWD           0x00000020
+
+#define BUTTON_MAIN                 0x0000003f
+
+#define BUTTON_TOUCH                0x00000040
+
+/* Touchscreen virtual buttons */
+#define BUTTON_TOPLEFT      0x00001000
+#define BUTTON_TOPMIDDLE    0x00002000
+#define BUTTON_TOPRIGHT     0x00004000
+#define BUTTON_MIDLEFT      0x00008000
+#define BUTTON_CENTER       0x00010000
+#define BUTTON_MIDRIGHT     0x00020000
+#define BUTTON_BOTTOMLEFT   0x00040000
+#define BUTTON_BOTTOMMIDDLE 0x00080000
+#define BUTTON_BOTTOMRIGHT  0x00100000
+
+/* Software power-off */
+#define POWEROFF_BUTTON BUTTON_POWER
+#define POWEROFF_COUNT 25
+
+/* For the simulator/sdl plugins/xworld */
+#ifndef BOOTLOADER
+#define BUTTON_LEFT        BUTTON_PREV
+#define BUTTON_RIGHT       BUTTON_NEXT
+#endif
+
+/* The left/right aliases above don't exist in BOOTLOADER builds */
+#define NO_BUTTON_LR
+
+int button_map(int keycode);
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/hosted/hiby/ap80max/led-ap80max.c b/firmware/target/hosted/hiby/ap80max/led-ap80max.c
new file mode 100644
index 0000000000..a272557a3d
--- /dev/null
+++ b/firmware/target/hosted/hiby/ap80max/led-ap80max.c
@@ -0,0 +1,117 @@
+/***************************************************************************
+ *             __________               __   ___
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ *
+ * Copyright (C) 2025 Melissa Autumn
+ * Copyright (C) 2026 by Jerry Shen
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include "config.h"
+#include "backlight-target.h"
+#include "sysfs.h"
+#include "panic.h"
+#include "lcd.h"
+#include "settings.h"
+#include "power.h"
+
+/* Same sgm31324 controller as the R3 Pro II, so the same sysfs node */
+static const char * const sysfs_led_type =
+"/sys/class/leds/sgm31324-leds/led_pattern";
+
+/* FIXME: taken from the R3 Pro II's leds_sgm31324_add.sh; this player ships
+   its own copy and the ordering has not been checked against it */
+enum AP80MAX_LED_PATTERNS {
+    LED_PATTERN_INVALID = -1,
+    LED_PATTERN_OFF = 0,
+    LED_PATTERN_LIGHT_BLUE,
+    LED_PATTERN_YELLOW,
+    LED_PATTERN_CYAN,
+    LED_PATTERN_ORANGE,
+    LED_PATTERN_UNK_1, /* This might do something, but it seems to just be off */
+    LED_PATTERN_NORMAL_RED_BLINK,
+    LED_PATTERN_FAST_RED_BLINK,
+    LED_PATTERN_GREEN,
+    LED_PATTERN_BLUE, /* A slightly more blue blue */
+    LED_PATTERN_PINK,
+    LED_PATTERN_WHITE,
+};
+
+int _last_buttonlight = LED_PATTERN_INVALID;
+
+void _set_pattern(enum AP80MAX_LED_PATTERNS pattern) {
+    if (_last_buttonlight != pattern) {
+        _last_buttonlight = pattern;
+        sysfs_set_int(sysfs_led_type, _last_buttonlight);
+    }
+}
+
+#ifdef HAVE_GENERAL_PURPOSE_LED
+void led_hw_brightness(int brightness)
+{
+    (void)brightness;
+}
+
+void led_hw_charged(void)
+{
+    if (global_settings.use_led_indicators) {
+        _set_pattern(LED_PATTERN_GREEN);
+    }
+}
+
+void led_hw_charging(void)
+{
+    _set_pattern(LED_PATTERN_NORMAL_RED_BLINK);
+}
+
+void led_hw_off(void)
+{
+    // Don't turn the led off if charging.
+    if (charging_state())
+        return;
+
+    _set_pattern(LED_PATTERN_OFF);
+}
+
+void led_hw_on(void)
+{
+    if (charging_state()) {
+        led_hw_charging();
+    } else {
+        if (global_settings.use_led_indicators) {
+            _set_pattern(LED_PATTERN_LIGHT_BLUE);
+        }
+        else {
+            led_hw_off();
+        }
+    }
+}
+
+void led_hw_set_mode(bool mode)
+{
+    if (mode) {
+        led_hw_on();
+    }
+    else {
+        led_hw_off();
+    }
+}
+#endif
diff --git a/firmware/target/hosted/hiby/ap80max/powermgmt-ap80max.c b/firmware/target/hosted/hiby/ap80max/powermgmt-ap80max.c
new file mode 100644
index 0000000000..63e4255338
--- /dev/null
+++ b/firmware/target/hosted/hiby/ap80max/powermgmt-ap80max.c
@@ -0,0 +1,39 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ *
+ * Copyright (C) 2017 Marcin Bukat
+ * Copyright (C) 2025 by Melissa Autumn
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "powermgmt.h"
+#include "power.h"
+
+unsigned short battery_level_disksafe = 3470;
+
+/* the OF shuts down at this voltage */
+unsigned short battery_level_shutoff = 3400;
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+unsigned short percent_to_volt_discharge[11] =
+{
+    3400, 3675, 3715, 3750, 3775, 3810, 3850, 4025, 4120, 4230, 4350
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+unsigned short percent_to_volt_charge[11] =
+{
+    3485, 3780, 3836, 3857, 3890, 3930, 3986, 4025, 4120, 4230, 4350
+};
diff --git a/firmware/target/hosted/hiby/lcd-target.h b/firmware/target/hosted/hiby/lcd-target.h
index 4882fab60a..0dab04cc69 100644
--- a/firmware/target/hosted/hiby/lcd-target.h
+++ b/firmware/target/hosted/hiby/lcd-target.h
@@ -26,7 +26,13 @@
 #define LCD_OPTIMIZED_UPDATE_RECT
 
 extern fb_data *framebuffer;
+
+#ifdef FB_STRIDE_MISMATCH
+#define LCD_FRAMEBUF_ADDR(col, row) \
+    (framebuffer + (row)*FB_STRIDE_MISMATCH + (col) + FB_STRIDE_XOFFSET)
+#else
 #define LCD_FRAMEBUF_ADDR(col, row) (framebuffer + (row)*LCD_WIDTH + (col))
+#endif
 
 extern void lcd_set_active(bool active);
 #endif /* __LCD_TARGET_H__ */
diff --git a/firmware/target/hosted/lcd-linuxfb.c b/firmware/target/hosted/lcd-linuxfb.c
index e25dd37b21..63661a1254 100644
--- a/firmware/target/hosted/lcd-linuxfb.c
+++ b/firmware/target/hosted/lcd-linuxfb.c
@@ -106,6 +106,10 @@ void lcd_init_device(void)
             vinfo.yres, vinfo.bits_per_pixel);
     }
 #endif
+#elif defined(FB_STRIDE_MISMATCH)
+    /* For framebuffers wider than the panel and cannot be resized */
+    if (vinfo.bits_per_pixel != LCD_DEPTH)
+        panicf("Unexpected framebuffer depth: %d", vinfo.bits_per_pixel);
 #else
     /* Make sure we match our desired bitdepth */
     if (vinfo.bits_per_pixel != LCD_DEPTH || vinfo.xres != LCD_WIDTH || vinfo.yres != LCD_HEIGHT) {
@@ -167,6 +171,20 @@ void lcd_enable(bool on)
 extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src,
                                  int width, int height);
 
+#ifdef FB_STRIDE_MISMATCH
+/* lcd_copy_buffer_rect() for framebuffers wider than the panel */
+static void fb_copy_rect(fb_data *dst, const fb_data *src,
+                         int width, int height)
+{
+    while (height--)
+    {
+        memcpy(dst, src, width * sizeof(fb_data));
+        dst += FB_STRIDE_MISMATCH;
+        src += LCD_WIDTH;
+    }
+}
+#endif
+
 void lcd_update(void)
 {
     if (fd < 0) return;
@@ -176,9 +194,15 @@ void lcd_update(void)
 #endif
     {
         /* Copy the Rockbox framebuffer to the second framebuffer */
+#ifdef FB_STRIDE_MISMATCH
+        /* Strides differ - not one contiguous run */
+        fb_copy_rect(LCD_FRAMEBUF_ADDR(0, 0), FBADDR(0, 0),
+                     LCD_WIDTH, LCD_HEIGHT);
+#else
         fb_data *dst = LCD_FRAMEBUF_ADDR(0, 0) + (fb_plane * FRAMEBUFFER_SIZE);
         lcd_copy_buffer_rect(dst, FBADDR(0,0),
                              LCD_WIDTH*LCD_HEIGHT, 1);
+#endif
         redraw();
     }
 }
@@ -191,6 +215,10 @@ void lcd_update_rect(int x, int y, int width, int height)
     if (lcd_active())
 #endif
     {
+#ifdef FB_STRIDE_MISMATCH
+        /* Strides differ - do line-by-line */
+        fb_copy_rect(LCD_FRAMEBUF_ADDR(x, y), FBADDR(x, y), width, height);
+#else
         fb_data *dst = LCD_FRAMEBUF_ADDR(x, y) + (fb_plane * FRAMEBUFFER_SIZE);
         fb_data *src = FBADDR(x,y);
 
@@ -205,6 +233,7 @@ void lcd_update_rect(int x, int y, int width, int height)
             /* Full width - copy as one line */
             lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1);
         }
+#endif
         redraw();
     }
 }
diff --git a/firmware/target/hosted/sdl/sim-ui-defines.h b/firmware/target/hosted/sdl/sim-ui-defines.h
index 3a10589da6..5a08b27adf 100644
--- a/firmware/target/hosted/sdl/sim-ui-defines.h
+++ b/firmware/target/hosted/sdl/sim-ui-defines.h
@@ -525,6 +525,13 @@
 #define UI_LCD_POSX                 77
 #define UI_LCD_POSY                 74
 
+#elif defined(HIDIZS_AP80MAX)
+#define UI_TITLE                    "Hidizs AP80 Pro Max"
+#define UI_WIDTH                    580
+#define UI_HEIGHT                   880
+#define UI_LCD_POSX                 100
+#define UI_LCD_POSY                 100
+
 #elif defined(SIMULATOR)
 #error no UI defines
 #endif
diff --git a/firmware/usb.c b/firmware/usb.c
index c44a7df7fc..b41facb39d 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -50,7 +50,7 @@
 #include "gui/skin_engine/skin_engine.h"
 #endif
 
-#if defined(HIBY_R3PROII) || defined(HIBY_R1)
+#if defined(HIBY_R3PROII) || defined(HIBY_R1) || defined(HIDIZS_AP80MAX)
 #include "usb-hiby-gadget.h"
 #endif
 #if defined(DX50) || defined(DX90)
@@ -91,7 +91,7 @@ void usb_set_mode(int mode)
     usb_mode = mode;
 #if defined(DX50) || defined(DX90)
     ibasso_set_usb_mode(mode);
-#elif defined(HIBY_R3PROII) || defined(HIBY_R1)
+#elif defined(HIBY_R3PROII) || defined(HIBY_R1) || defined(HIDIZS_AP80MAX)
     hiby_set_usb_mode(mode);
 #endif
 }
diff --git a/tools/builds.pm b/tools/builds.pm
index 0aafee756f..08dd865593 100644
--- a/tools/builds.pm
+++ b/tools/builds.pm
@@ -471,6 +471,10 @@ $releasenotes="/wiki/ReleaseNotes400";
         name => 'Hiby R3Pro II',
         status => 2,
     },
+    'hidizsap80max' => {
+        name => 'Hidizs AP80 Pro Max',
+        status => 1,
+    },
 );
 
 sub manualname {
diff --git a/tools/configure b/tools/configure
index 608f783763..bc43bf184b 100755
--- a/tools/configure
+++ b/tools/configure
@@ -1737,8 +1737,8 @@ cat <<EOF
                                                  300) R3 Pro II
  ==Echo project==          ==Surfans==           301) R1
  270) Echo R1 (WIP)        280) F28 (WIP)
-
- ==Nintendo==
+                                                 ==Hidizs==
+ ==Nintendo==                                    302) AP80 Pro Max (WIP)
  290) Nintendo 3DS (WIP)
 
 EOF
@@ -4226,6 +4226,31 @@ fi
     sysfont="20-Terminus"
     ;;
 
+    302|hidizsap80max)
+    target_id=125
+    application=yes
+    app_type="hibyos"
+    modelname="hidizsap80max"
+    target="HIDIZS_AP80MAX"
+    memory=16 # The device has 64mb but let's make sure it still boots with things in the background
+    mipsellinuxcc
+    tool="cp "
+    boottool="cp "
+    bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
+    bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
+    output="rockbox.ap80max"
+    bootoutput="bootloader.ap80max"
+    appextra="recorder:gui:hosted"
+    plugins="yes"
+    # architecture, manufacturer and model for the target-tree build
+    # These align with
+    t_cpu="hosted"
+    t_manufacturer="hiby"
+    t_model="ap80max"
+    sysfontbl="24-Terminus"
+    sysfont="20-Terminus"
+    ;;
+
 
    *)
     echo "Please select a supported target platform!"
diff --git a/uisimulator/bitmaps/UI-hidizsap80max.bmp b/uisimulator/bitmaps/UI-hidizsap80max.bmp
new file mode 100644
index 0000000000..0ecd8362c6
Binary files /dev/null and b/uisimulator/bitmaps/UI-hidizsap80max.bmp differ
diff --git a/uisimulator/buttonmap/SOURCES b/uisimulator/buttonmap/SOURCES
index 4efbdee874..b9fa3b64ac 100644
--- a/uisimulator/buttonmap/SOURCES
+++ b/uisimulator/buttonmap/SOURCES
@@ -87,5 +87,7 @@ shanling-q1.c
 rg-nano.c
 #elif CONFIG_KEYPAD == HIBY_R3PROII_PAD
 hiby-r3proii.c
+#elif CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD
+hidizs-ap80max.c
 #endif
 #endif /* SIMULATOR */
diff --git a/uisimulator/buttonmap/hidizs-ap80max.c b/uisimulator/buttonmap/hidizs-ap80max.c
new file mode 100644
index 0000000000..295267bdb0
--- /dev/null
+++ b/uisimulator/buttonmap/hidizs-ap80max.c
@@ -0,0 +1,57 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ *
+ * Copyright (C) 2021 by Solomon Peachy
+ * Copyright (C) 2026 by Jerry Shen
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+
+#include <SDL.h>
+#include "button.h"
+#include "buttonmap.h"
+
+int key_to_button(int keyboard_button)
+{
+    switch (keyboard_button)
+    {
+        case SDLK_UP:
+            return BUTTON_SCROLL_BACK;
+        case SDLK_DOWN:
+            return BUTTON_SCROLL_FWD;
+        case SDLK_LEFT:
+            return BUTTON_PREV;
+        case SDLK_RIGHT:
+            return BUTTON_NEXT;
+        case SDLK_RETURN:
+        case SDLK_SPACE:
+            return BUTTON_PLAY;
+        case SDLK_ESCAPE:
+            return BUTTON_POWER;
+        default:
+            return BUTTON_NONE;
+    }
+}
+
+struct button_map bm[] = {
+    { SDLK_ESCAPE, 525, 270, 35, "Power" },
+    { SDLK_LEFT,   526, 432, 25, "Previous" },
+    { SDLK_SPACE,  526, 515, 25, "Play" },
+    { SDLK_RIGHT,  526, 598, 25, "Next" },
+    { SDLK_UP,  525, 230, 35, "Scroll Fwd" },
+    { SDLK_DOWN,  525, 310, 35, "Scroll Back" },
+    { 0, 0, 0, 0, "None" }
+};
diff --git a/wps/WPSLIST b/wps/WPSLIST
index 3e0ba230e0..d9438bb77b 100644
--- a/wps/WPSLIST
+++ b/wps/WPSLIST
@@ -85,6 +85,7 @@ wps.480x720x(16|24|32):  cabbiev2.480x720x16.touch.wps
 wps.800x480x(16|24|32):  cabbiev2.800x480x16.wps
 wps.480x800x(16|24|32):  cabbiev2.480x800x16.wps
 wps.400x240x(16|24|32):  cabbiev2.400x240x16.wps
+wps.360x640x(16|24|32):  cabbiev2.360x640x16.wps
 wps.360x400x(16|24|32):  cabbiev2.360x400x16.wps
 wps.320x480x(16|24|32):  cabbiev2.320x480x16.wps
 wps.320x240x(16|24|32):  cabbiev2.320x240x16.wps
@@ -118,6 +119,7 @@ Font.480x720x(16|24|32): 35-Adobe-Helvetica.fnt
 Font.800x480x(16|24|32): 35-Adobe-Helvetica.fnt
 Font.480x800x(16|24|32): 35-Adobe-Helvetica.fnt
 Font.400x240x(16|24|32): 15-Adobe-Helvetica.fnt
+Font.360x640x(16|24|32): 35-Adobe-Helvetica.fnt
 Font.360x400x(16|24|32): 18-Adobe-Helvetica.fnt
 Font.320x480x(16|24|32): 27-Adobe-Helvetica.fnt
 Font.320x240x(16|24|32): 15-Adobe-Helvetica.fnt
@@ -155,6 +157,7 @@ backdrop.480x720x(16|24|32): backdrops/cabbiev2.480x720x16.bmp
 backdrop.800x480x(16|24|32): backdrops/cabbiev2.800x480x16.bmp
 backdrop.480x800x(16|24|32): backdrops/cabbiev2.480x800x16.bmp
 backdrop.400x240x(16|24|32): backdrops/cabbiev2.400x240x16.bmp
+backdrop.360x640x(16|24|32):      backdrops/cabbiev2.360x640x16.bmp
 backdrop.360x400x(16|24|32):      backdrops/cabbiev2.360x400x16.bmp
 backdrop.320x480x(16|24|32): backdrops/cabbiev2.320x480x16.bmp
 backdrop.320x240x(16|24|32): backdrops/cabbiev2.320x240x16.bmp
@@ -185,6 +188,7 @@ iconset.480x720x(16|24|32):  icons/tango_icons.32x32.bmp
 iconset.800x480x(16|24|32):  icons/tango_icons.32x32.bmp
 iconset.480x800x(16|24|32):  icons/tango_icons.32x32.bmp
 iconset.400x240x(16|24|32):  icons/tango_icons.16x16.bmp
+iconset.360x640x(16|24|32):  icons/tango_icons.32x32.bmp
 iconset.360x400x(16|24|32):  icons/tango_icons.32x32.bmp
 iconset.320x480x(16|24|32):  icons/tango_icons.24x24.bmp
 iconset.320x240x(16|24|32):  icons/tango_icons.16x16.bmp
@@ -208,6 +212,7 @@ viewers iconset.480x720x(16|24|32):  icons/tango_icons_viewers.32x32.bmp
 viewers iconset.800x480x(16|24|32):  icons/tango_icons_viewers.32x32.bmp
 viewers iconset.480x800x(16|24|32):  icons/tango_icons_viewers.32x32.bmp
 viewers iconset.400x240x(16|24|32):  icons/tango_icons_viewers.16x16.bmp
+viewers iconset.360x640x(16|24|32):  icons/tango_icons_viewers.32x32.bmp
 viewers iconset.360x400x(16|24|32):  icons/tango_icons_viewers.32x32.bmp
 viewers iconset.320x480x(16|24|32):  icons/tango_icons_viewers.24x24.bmp
 viewers iconset.320x240x(16|24|32):  icons/tango_icons_viewers.16x16.bmp
diff --git a/wps/cabbiev2.360x640x16.wps b/wps/cabbiev2.360x640x16.wps
new file mode 100644
index 0000000000..b44ec434a3
--- /dev/null
+++ b/wps/cabbiev2.360x640x16.wps
@@ -0,0 +1,87 @@
+# Cabbie v2.0
+# (C) 2007-2012 The Authors (see /rockbox/wps/AUTHORS)
+# Derived from "cabbie" (C) Yohann Misquitta
+#
+# Laid out against wpsbackdrop-360x640x16.bmp, whose fixed landmarks are:
+#   title bar       x=30..329 y=6..27
+#   progress trough x=30..329 y=516..537
+#   status row      y=605..633, with shuffle baked at x=209 and repeat at x=273
+# Everything below is anchored to those; the content area is y=28..515.
+#
+# Disable Status Bar
+%wd
+#
+# Load Backdrop
+%X(wpsbackdrop-360x640x16.bmp)
+#
+# Preload Images
+%xl(A,lock-360x640x16.bmp,0,0,2)
+%xl(B,battery-360x640x16.bmp,0,0,10)
+%xl(C,volume-360x640x16.bmp,0,0,10)
+%xl(D,shuffle-360x640x16.bmp,0,0)
+%xl(E,repeat-360x640x16.bmp,0,0,4)
+%xl(F,playmode-360x640x16.bmp,0,0,5)
+#
+# Album Art/Info Viewport Conditional
+%?C<%Vd(a)|%Vd(b)>
+#
+# Progress Bar
+# Backdrop trough occupies x=30..329, y=516..537.
+%V(30,516,300,20,-)
+%pb(0,0,-,20,pb-360x640x16.bmp)
+#
+# Hold
+%V(16,605,38,29,-)
+%?mh<%xd(Aa)|%xd(Ab)>
+#
+# Battery
+%V(69,605,66,29,-)
+%?bp<%?bc<%xd(Ba)|%xd(Bb)>|%?bl<|%xd(Bc)|%xd(Bd)|%xd(Be)|%xd(Bf)|%xd(Bg)|%xd(Bh)|%xd(Bi)|%xd(Bj)>>
+#
+# Volume
+%V(147,605,50,29,-)
+%?pv<%xd(Ca)|%xd(Cb)|%xd(Cc)|%xd(Cd)|%xd(Ce)|%xd(Cf)|%xd(Cg)|%xd(Ch)|%xd(Ci)|%xd(Cj)>
+#
+# Shuffle
+%V(208,605,55,29,-)
+%?ps<%xd(D)>
+#
+# Repeat
+%V(273,605,27,29,-)
+%?mm<|%xd(Ea)|%xd(Eb)|%xd(Ec)|%xd(Ed)>
+#
+# Playmode
+%V(309,605,36,29,-)
+%?mp<%xd(Fa)|%xd(Fb)|%xd(Fc)|%xd(Fd)|%xd(Fe)>
+#
+# Time Elapsed/Remaining
+%V(30,542,300,36,-)
+%al%pc%ac%?Sr<%pe %Sx(of) %pp|%pp %Sx(of) %pe>%ar%pr
+#
+# Album Art
+%ax%Vl(a,40,45,280,280,-)
+%Cl(0,0,280,280,c,c)
+%Cd
+#
+# Track Info - Album Art
+%ax%Vl(a,0,329,-,187,1)
+%s%ac%?id<%id|%?d(1)<%d(1)|%(root%)>>
+%s%ac%?it<%it|%fn>
+%s%ac%?ia<%ia|%?iA<%iA|%?d(2)<%d(2)|%(root%)>>>
+
+%s%ac%Sx(Next:) %?Ia<%Ia|%?IA<%IA|%?D(2)<%D(2)|%(root%)>>> - %?It<%It|%Fn>
+#
+# Track Info - No Album Art
+%Vl(b,0,96,-,420,1)
+%s%ac%?id<%id|%?d(1)<%d(1)|%(root%)>>
+%s%ac%?it<%it|%fn>
+%s%ac%?ia<%ia|%?iA<%iA|%?d(2)<%d(2)|%(root%)>>>
+%ac%?iy<%iy|>
+
+%ac%?ig<%ig|>
+%ac%?fv<%(vbr%) |>%fb kbit/s %fc
+
+%ac%Sx(Next:)
+%s%ac%?Id<%Id|%?D(1)<%D(1)|%(root%)>>
+%ac%s%?It<%It|%Fn>
+%s%ac%?Ia<%Ia|%?IA<%IA|%?D(2)<%D(2)|%(root%)>>>
diff --git a/wps/cabbiev2/battery-360x640x16.bmp b/wps/cabbiev2/battery-360x640x16.bmp
new file mode 100644
index 0000000000..d00b4c1c5d
Binary files /dev/null and b/wps/cabbiev2/battery-360x640x16.bmp differ
diff --git a/wps/cabbiev2/lock-360x640x16.bmp b/wps/cabbiev2/lock-360x640x16.bmp
new file mode 100644
index 0000000000..70c419e875
Binary files /dev/null and b/wps/cabbiev2/lock-360x640x16.bmp differ
diff --git a/wps/cabbiev2/pb-360x640x16.bmp b/wps/cabbiev2/pb-360x640x16.bmp
new file mode 100644
index 0000000000..6b5884d059
Binary files /dev/null and b/wps/cabbiev2/pb-360x640x16.bmp differ
diff --git a/wps/cabbiev2/playmode-360x640x16.bmp b/wps/cabbiev2/playmode-360x640x16.bmp
new file mode 100644
index 0000000000..148376b127
Binary files /dev/null and b/wps/cabbiev2/playmode-360x640x16.bmp differ
diff --git a/wps/cabbiev2/repeat-360x640x16.bmp b/wps/cabbiev2/repeat-360x640x16.bmp
new file mode 100644
index 0000000000..f6fb08d909
Binary files /dev/null and b/wps/cabbiev2/repeat-360x640x16.bmp differ
diff --git a/wps/cabbiev2/shuffle-360x640x16.bmp b/wps/cabbiev2/shuffle-360x640x16.bmp
new file mode 100644
index 0000000000..1b16153176
Binary files /dev/null and b/wps/cabbiev2/shuffle-360x640x16.bmp differ
diff --git a/wps/cabbiev2/volume-360x640x16.bmp b/wps/cabbiev2/volume-360x640x16.bmp
new file mode 100644
index 0000000000..7d8b8e40e8
Binary files /dev/null and b/wps/cabbiev2/volume-360x640x16.bmp differ
diff --git a/wps/cabbiev2/wpsbackdrop-360x640x16.bmp b/wps/cabbiev2/wpsbackdrop-360x640x16.bmp
new file mode 100644
index 0000000000..a7ad1c6447
Binary files /dev/null and b/wps/cabbiev2/wpsbackdrop-360x640x16.bmp differ
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.