mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
New & improved touchscreen playground
This commit is contained in:
parent
77f857ab64
commit
df21331218
@ -10,6 +10,7 @@
|
||||
#define HID_TOUCH_MAXPOINT (0x1000)
|
||||
#define HID_TOUCH_MIDPOINT (HID_TOUCH_MAXPOINT / 2)
|
||||
|
||||
|
||||
// there's some weird thing going on when reading this
|
||||
// with an LDRD instruction so for now they'll be two
|
||||
// separate things - hopefully LTO won't get in the way
|
||||
|
20
arm9/source/common/touchui.c
Normal file
20
arm9/source/common/touchui.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "touchui.h"
|
||||
#include "hid.h"
|
||||
|
||||
|
||||
bool TouchBoxGet(u16* x, u16* y, u32* id, const TouchBox* tbs, const u32 tbn) {
|
||||
*id = 0;
|
||||
|
||||
// read coordinates, check if inside touchbox
|
||||
if (!HID_ReadTouchState(x, y)) return false;
|
||||
for (u32 i = 0; i < tbn; i++) {
|
||||
const TouchBox* tb = tbs + i;
|
||||
if ((*x >= tb->x) && (*y >= tb->y) &&
|
||||
(*x < tb->x + tb->w) && (*y < tb->y + tb->h)) {
|
||||
*id = tb->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
15
arm9/source/common/touchui.h
Normal file
15
arm9/source/common/touchui.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
u16 x;
|
||||
u16 y;
|
||||
u16 w;
|
||||
u16 h;
|
||||
u32 id; // shouldn't be zero
|
||||
} __attribute__((packed)) TouchBox;
|
||||
|
||||
// this assumes the touchscreen is actually in use
|
||||
bool TouchBoxGet(u16* x, u16* y, u32* id, const TouchBox* tbs, const u32 tbn);
|
@ -149,6 +149,18 @@ void ClearScreenF(bool clear_main, bool clear_alt, int color)
|
||||
if (clear_alt) ClearScreen(ALT_SCREEN, color);
|
||||
}
|
||||
|
||||
u32 GetColor(u8* screen, int x, int y)
|
||||
{
|
||||
u32 color = 0;
|
||||
int xDisplacement = (x * BYTES_PER_PIXEL * SCREEN_HEIGHT);
|
||||
int yDisplacement = ((SCREEN_HEIGHT - y - 1) * BYTES_PER_PIXEL);
|
||||
u8* screenPos = screen + xDisplacement + yDisplacement;
|
||||
color |= (*(screenPos + 0) << 16 ); // B
|
||||
color |= (*(screenPos + 1) << 8 ); // G
|
||||
color |= (*(screenPos + 2) << 0 ); // R
|
||||
return color;
|
||||
}
|
||||
|
||||
void DrawPixel(u8* screen, int x, int y, int color)
|
||||
{
|
||||
int xDisplacement = (x * BYTES_PER_PIXEL * SCREEN_HEIGHT);
|
||||
|
@ -48,6 +48,8 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...);
|
||||
u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h);
|
||||
bool SetFontFromPbm(const void* pbm, const u32 pbm_size);
|
||||
|
||||
u32 GetColor(u8* screen, int x, int y);
|
||||
|
||||
void ClearScreen(unsigned char *screen, int color);
|
||||
void ClearScreenF(bool clear_main, bool clear_alt, int color);
|
||||
void DrawPixel(u8* screen, int x, int y, int color);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "godmode.h"
|
||||
#include "paint9.h"
|
||||
#include "memmap.h"
|
||||
#include "support.h"
|
||||
#include "ui.h"
|
||||
@ -2001,7 +2002,8 @@ u32 HomeMoreMenu(char* current_path) {
|
||||
ShowPrompt(false, "Touchscreen calibration %s!", (ShowTouchCalibrationDialog()) ? "success" : "failed");
|
||||
}
|
||||
else if (user_select == playground) {
|
||||
ShowTouchPlayground();
|
||||
// ShowTouchPlayground();
|
||||
Paint9();
|
||||
} else return 1;
|
||||
|
||||
return HomeMoreMenu(current_path);
|
||||
|
192
arm9/source/utils/paint9.c
Normal file
192
arm9/source/utils/paint9.c
Normal file
@ -0,0 +1,192 @@
|
||||
#include "paint9.h"
|
||||
#include "touchui.h"
|
||||
#include "hid.h"
|
||||
#include "ui.h"
|
||||
|
||||
|
||||
#define PAINT9_BRUSH_SIZE 15 // don't change!
|
||||
#define PAINT9_N_BRUSHES 6 // don't change!
|
||||
#define PAINT9_COLSEL_WIDTH 16
|
||||
#define PAINT9_COLSEL_HEIGHT 220 // don't change!
|
||||
|
||||
enum P9BOXES {
|
||||
P9BOX_CANVAS = 1,
|
||||
P9BOX_PICKER = 2,
|
||||
P9BOX_BRUSH_N = 3
|
||||
};
|
||||
|
||||
static const TouchBox paint9_boxes[] = {
|
||||
{ 30, 0, SCREEN_WIDTH_BOT - (2*30), SCREEN_HEIGHT, P9BOX_CANVAS },
|
||||
{ SCREEN_WIDTH_BOT - PAINT9_COLSEL_WIDTH - 7, 10, PAINT9_COLSEL_WIDTH, PAINT9_COLSEL_HEIGHT, P9BOX_PICKER },
|
||||
{ 7, 10 + ((PAINT9_BRUSH_SIZE+3)*0), PAINT9_BRUSH_SIZE, PAINT9_BRUSH_SIZE, P9BOX_BRUSH_N+0 },
|
||||
{ 7, 10 + ((PAINT9_BRUSH_SIZE+3)*1), PAINT9_BRUSH_SIZE, PAINT9_BRUSH_SIZE, P9BOX_BRUSH_N+1 },
|
||||
{ 7, 10 + ((PAINT9_BRUSH_SIZE+3)*2), PAINT9_BRUSH_SIZE, PAINT9_BRUSH_SIZE, P9BOX_BRUSH_N+2 },
|
||||
{ 7, 10 + ((PAINT9_BRUSH_SIZE+3)*3), PAINT9_BRUSH_SIZE, PAINT9_BRUSH_SIZE, P9BOX_BRUSH_N+3 },
|
||||
{ 7, 10 + ((PAINT9_BRUSH_SIZE+3)*4), PAINT9_BRUSH_SIZE, PAINT9_BRUSH_SIZE, P9BOX_BRUSH_N+4 },
|
||||
{ 7, 10 + ((PAINT9_BRUSH_SIZE+3)*5), PAINT9_BRUSH_SIZE, PAINT9_BRUSH_SIZE, P9BOX_BRUSH_N+5 }
|
||||
};
|
||||
|
||||
static const u8 color_picker_tmp[PAINT9_COLSEL_HEIGHT * BYTES_PER_PIXEL] = {
|
||||
0xFD, 0x01, 0x00, 0xFD, 0x01, 0x00, 0xFC, 0x00, 0x01, 0xFD, 0x00, 0x04,
|
||||
0xFE, 0x00, 0x0A, 0xFF, 0x00, 0x0E, 0xFE, 0x00, 0x10, 0xFF, 0x00, 0x15,
|
||||
0xFE, 0x00, 0x1E, 0xFE, 0x00, 0x27, 0xFC, 0x00, 0x2F, 0xFD, 0x00, 0x36,
|
||||
0xFE, 0x00, 0x3F, 0xFF, 0x00, 0x49, 0xFE, 0x00, 0x52, 0xFD, 0x00, 0x5E,
|
||||
0xFC, 0x00, 0x67, 0xFD, 0x00, 0x74, 0xFE, 0x00, 0x7F, 0xFF, 0x00, 0x89,
|
||||
0xFE, 0x00, 0x94, 0xFF, 0x00, 0xA1, 0xFD, 0x00, 0xAD, 0xFD, 0x00, 0xB5,
|
||||
0xFE, 0x00, 0xBC, 0xFE, 0x00, 0xC6, 0xFE, 0x00, 0xCF, 0xFE, 0x00, 0xD9,
|
||||
0xFF, 0x00, 0xDE, 0xFE, 0x01, 0xE7, 0xFD, 0x01, 0xEE, 0xFE, 0x00, 0xEF,
|
||||
0xFD, 0x00, 0xF1, 0xFE, 0x00, 0xF7, 0xFF, 0x00, 0xFB, 0xFF, 0x00, 0xFE,
|
||||
0xFE, 0x00, 0xFE, 0xFE, 0x00, 0xFE, 0xFF, 0x00, 0xFF, 0xFE, 0x00, 0xFF,
|
||||
0xFA, 0x00, 0xFE, 0xF4, 0x00, 0xFE, 0xEF, 0x00, 0xFE, 0xEA, 0x00, 0xFE,
|
||||
0xE2, 0x00, 0xFF, 0xDD, 0x00, 0xFE, 0xD6, 0x00, 0xFF, 0xCC, 0x00, 0xFE,
|
||||
0xC2, 0x00, 0xFE, 0xB9, 0x00, 0xFF, 0xB2, 0x00, 0xFD, 0xA8, 0x00, 0xFE,
|
||||
0x9B, 0x00, 0xFF, 0x92, 0x00, 0xFE, 0x86, 0x00, 0xFD, 0x79, 0x00, 0xFE,
|
||||
0x6E, 0x00, 0xFF, 0x64, 0x00, 0xFD, 0x5A, 0x00, 0xFE, 0x4B, 0x00, 0xFF,
|
||||
0x46, 0x00, 0xFE, 0x3E, 0x00, 0xFE, 0x34, 0x00, 0xFE, 0x2B, 0x00, 0xFE,
|
||||
0x22, 0x00, 0xFE, 0x1C, 0x00, 0xFD, 0x13, 0x00, 0xFD, 0x0F, 0x00, 0xFF,
|
||||
0x0B, 0x00, 0xFE, 0x07, 0x00, 0xFD, 0x02, 0x00, 0xFD, 0x01, 0x00, 0xFF,
|
||||
0x00, 0x01, 0xFF, 0x00, 0x00, 0xFD, 0x00, 0x00, 0xFE, 0x00, 0x02, 0xFF,
|
||||
0x00, 0x04, 0xFE, 0x00, 0x09, 0xFE, 0x00, 0x0C, 0xFE, 0x02, 0x10, 0xFF,
|
||||
0x00, 0x14, 0xFF, 0x00, 0x1C, 0xFE, 0x01, 0x23, 0xFE, 0x01, 0x2C, 0xFF,
|
||||
0x00, 0x36, 0xFE, 0x00, 0x40, 0xFD, 0x00, 0x48, 0xFE, 0x01, 0x50, 0xFE,
|
||||
0x00, 0x5D, 0xFE, 0x00, 0x67, 0xFD, 0x01, 0x72, 0xFC, 0x00, 0x7D, 0xFD,
|
||||
0x00, 0x88, 0xFF, 0x00, 0x93, 0xFF, 0x02, 0x9C, 0xFE, 0x00, 0xA8, 0xFD,
|
||||
0x00, 0xB2, 0xFD, 0x02, 0xBB, 0xFF, 0x01, 0xC5, 0xFF, 0x00, 0xCE, 0xFE,
|
||||
0x00, 0xD7, 0xFD, 0x01, 0xDF, 0xFE, 0x00, 0xE6, 0xFE, 0x00, 0xED, 0xFC,
|
||||
0x00, 0xF0, 0xFE, 0x00, 0xF4, 0xFE, 0x00, 0xF8, 0xFD, 0x00, 0xFC, 0xFD,
|
||||
0x00, 0xFE, 0xFC, 0x01, 0xFF, 0xFD, 0x01, 0xFE, 0xFF, 0x00, 0xFE, 0xFE,
|
||||
0x01, 0xFF, 0xFC, 0x00, 0xFE, 0xF7, 0x00, 0xFE, 0xF2, 0x00, 0xFF, 0xF0,
|
||||
0x00, 0xFF, 0xED, 0x00, 0xFE, 0xE7, 0x00, 0xFD, 0xDE, 0x00, 0xFE, 0xD3,
|
||||
0x00, 0xFE, 0xCA, 0x00, 0xFE, 0xC5, 0x00, 0xFF, 0xBD, 0x00, 0xFF, 0xB2,
|
||||
0x00, 0xFE, 0xAA, 0x01, 0xFD, 0xA0, 0x02, 0xFE, 0x93, 0x01, 0xFF, 0x89,
|
||||
0x00, 0xFE, 0x7E, 0x00, 0xFE, 0x73, 0x00, 0xFE, 0x68, 0x00, 0xFF, 0x5D,
|
||||
0x00, 0xFE, 0x4E, 0x01, 0xFE, 0x47, 0x00, 0xFF, 0x40, 0x00, 0xFE, 0x35,
|
||||
0x00, 0xFE, 0x2B, 0x00, 0xFF, 0x23, 0x00, 0xFF, 0x1E, 0x01, 0xFE, 0x16,
|
||||
0x01, 0xFE, 0x10, 0x00, 0xFD, 0x0D, 0x00, 0xFC, 0x08, 0x00, 0xFE, 0x04,
|
||||
0x00, 0xFF, 0x02, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFE, 0x00, 0x02, 0xFD, 0x00, 0x07, 0xFD, 0x00, 0x0C, 0xFE, 0x00,
|
||||
0x0F, 0xFF, 0x00, 0x13, 0xFE, 0x00, 0x1B, 0xFE, 0x00, 0x23, 0xFF, 0x00,
|
||||
0x2D, 0xFE, 0x01, 0x34, 0xFD, 0x00, 0x3C, 0xFF, 0x01, 0x46, 0xFF, 0x02,
|
||||
0x4F, 0xFE, 0x03, 0x59, 0xFE, 0x00, 0x64, 0xFF, 0x00, 0x71, 0xFE, 0x00,
|
||||
0x7C, 0xFF, 0x00, 0x85, 0xFE, 0x00, 0x90, 0xFF, 0x00, 0x9D, 0xFE, 0x01,
|
||||
0xAA, 0xFE, 0x00, 0xB2, 0xFE, 0x00, 0xB9, 0xFE, 0x00, 0xC2, 0xFE, 0x00,
|
||||
0xCC, 0xFE, 0x00, 0xD5, 0xFD, 0x00, 0xDC, 0xFD, 0x01, 0xE2, 0xFD, 0x02,
|
||||
0xED, 0xFE, 0x00, 0xF0, 0xFF, 0x00, 0xF3, 0xFE, 0x00, 0xF7, 0xFF, 0x01,
|
||||
0xFB, 0xFE, 0x00, 0xFD, 0xFD, 0x00, 0xFE, 0xFD, 0x00, 0xFE, 0xFD, 0x00,
|
||||
0xFE, 0xFD, 0x00, 0xFE, 0xFD, 0x00, 0xFF, 0xFA, 0x01, 0xFE, 0xF5, 0x00,
|
||||
0xFF, 0xF1, 0x01, 0xFD, 0xEE, 0x00, 0xFD, 0xE8, 0x00, 0xFE, 0xE0, 0x00,
|
||||
0xFD, 0xD8, 0x00, 0xFE, 0xCF, 0x00, 0xFF, 0xC6, 0x03, 0xFF, 0xBD, 0x03,
|
||||
0xFD, 0xB3, 0x00, 0xFC, 0xAA, 0x00, 0xFF, 0x9D, 0x01, 0xFE, 0x95, 0x00,
|
||||
0xFE, 0x8A, 0x00, 0xFE, 0x7E, 0x00, 0xFE, 0x72, 0x01, 0xFD, 0x67, 0x01,
|
||||
0xFB, 0x5F, 0x00, 0xFE, 0x54, 0x00, 0xFE, 0x4B, 0x00, 0xFD, 0x41, 0x00,
|
||||
0xFE, 0x37, 0x00, 0xFE, 0x2E, 0x00, 0xFF, 0x25, 0x00, 0xFD, 0x1D, 0x00,
|
||||
0xFD, 0x16, 0x01, 0xFE, 0x12, 0x02, 0xFF, 0x0D, 0x00, 0xFF, 0x08, 0x00,
|
||||
0xFE, 0x04, 0x00, 0xFF, 0x02, 0x02, 0xFE, 0x01, 0x03, 0xFD, 0x00, 0x02
|
||||
};
|
||||
|
||||
static const u16 brushes_tmp[PAINT9_N_BRUSHES][PAINT9_BRUSH_SIZE] = {
|
||||
{ 0x0FE0, 0x1FF0, 0x3FF8, 0x7FFC, 0xFFFE, 0xFFFE, 0xFFFE,0xFFFE,
|
||||
0xFFFE, 0xFFFE, 0xFFFE, 0x7FFC, 0x3FF8, 0x1FF0, 0x0FE0 },
|
||||
{ 0x0000, 0x0000, 0x07C0, 0x0FE0, 0x1FF0, 0x3FF8, 0x3FF8, 0x3FF8,
|
||||
0x3FF8, 0x3FF8, 0x1FF0, 0x0FE0, 0x07C0, 0x0000, 0x0000 },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0380, 0x07C0, 0x0FE0, 0x0FE0,
|
||||
0x0FE0, 0x07C0, 0x0380, 0x0000, 0x0000, 0x0000, 0x0000 },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0380, 0x07C0, 0x07C0,
|
||||
0x07C0, 0x0380, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0380,
|
||||
0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0100,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }
|
||||
};
|
||||
|
||||
|
||||
void Paint9_DrawBrush(u16 px, u16 py, u32 color_fg, u32 color_bg, u32 id) {
|
||||
const u16* brush = brushes_tmp[id];
|
||||
|
||||
// fix px / py
|
||||
s16 pxf = px - (PAINT9_BRUSH_SIZE/2);
|
||||
s16 pyf = py - (PAINT9_BRUSH_SIZE/2);
|
||||
|
||||
// draw brush, pixel by pixel
|
||||
for (s16 y = 0; y < PAINT9_BRUSH_SIZE; y++) {
|
||||
s16 pyc = pyf + y;
|
||||
if ((pyc < 0) || (pyc >= SCREEN_HEIGHT)) continue;
|
||||
|
||||
for (s16 x = 0; x < PAINT9_BRUSH_SIZE; x++) {
|
||||
s16 pxc = pxf + x;
|
||||
if ((pxc < 0) || (pxc >= SCREEN_WIDTH_BOT)) continue;
|
||||
|
||||
if ((brush[y]>>(PAINT9_BRUSH_SIZE-x))&0x1) {
|
||||
DrawPixel(BOT_SCREEN, pxc, pyc, color_fg);
|
||||
} else if (color_bg != COLOR_TRANSPARENT) {
|
||||
DrawPixel(BOT_SCREEN, pxc, pyc, color_bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 Paint9(void) {
|
||||
static u32 brush_bg = RGB(0x20, 0x20, 0x20);
|
||||
static u32 outline_bg = RGB(0x18, 0x18, 0x18);
|
||||
u16 x_cb = paint9_boxes[2].x + (PAINT9_BRUSH_SIZE/2) + 1;
|
||||
u16 y_cb = SCREEN_HEIGHT - 10 - (PAINT9_BRUSH_SIZE/2) - 1;
|
||||
|
||||
u32 color = COLOR_RED;
|
||||
u32 brush_id = 0;
|
||||
|
||||
// clear screens, draw title
|
||||
ClearScreenF(true, true, COLOR_STD_BG);
|
||||
DrawStringCenter(TOP_SCREEN, COLOR_STD_FONT, COLOR_TRANSPARENT,
|
||||
"Paint9\n \nYou may save your creation at\nany time via the screenshot\nfunction (L+R).\n \nHave fun!");
|
||||
|
||||
// outline canvas
|
||||
DrawRectangle(BOT_SCREEN, 0, 0, 30, SCREEN_HEIGHT, outline_bg);
|
||||
DrawRectangle(BOT_SCREEN, SCREEN_WIDTH_BOT - 30, 0, 30, SCREEN_HEIGHT, outline_bg);
|
||||
|
||||
// draw color picker
|
||||
u32 pick_x = paint9_boxes[1].x;
|
||||
u32 pick_y = paint9_boxes[1].y;
|
||||
for (u32 y = 0; y < PAINT9_COLSEL_HEIGHT; y++) {
|
||||
const u8* rgb = color_picker_tmp + (y * BYTES_PER_PIXEL);
|
||||
color = RGB(rgb[0], rgb[1], rgb[2]);
|
||||
for (u32 x = 0; x < PAINT9_COLSEL_WIDTH; x++)
|
||||
DrawPixel(BOT_SCREEN, pick_x + x, pick_y + y, color);
|
||||
}
|
||||
|
||||
// draw brushes
|
||||
for (u32 i = 0; i < PAINT9_N_BRUSHES; i++) {
|
||||
u32 color_fg = COLOR_STD_FONT;
|
||||
u16 x = paint9_boxes[2+i].x + (PAINT9_BRUSH_SIZE/2) + 1;
|
||||
u16 y = paint9_boxes[2+i].y + (PAINT9_BRUSH_SIZE/2) + 1;
|
||||
Paint9_DrawBrush(x, y, color_fg, brush_bg, i);
|
||||
}
|
||||
|
||||
// Paint9 main loop
|
||||
while (1) {
|
||||
DrawStringF(TOP_SCREEN, 16, 16, COLOR_STD_FONT, COLOR_STD_BG,
|
||||
"Touchscreen coordinates (0/0) ");
|
||||
Paint9_DrawBrush(x_cb, y_cb, color, brush_bg, brush_id);
|
||||
if (InputWait(0) & BUTTON_B) break;
|
||||
|
||||
u16 tx, ty;
|
||||
u32 tb_id;
|
||||
while (TouchBoxGet(&tx, &ty, &tb_id, paint9_boxes, 8)) {
|
||||
DrawStringF(TOP_SCREEN, 16, 16, COLOR_STD_FONT, COLOR_STD_BG,
|
||||
"Touchscreen coordinates (%d/%d) ", tx, ty);
|
||||
if (tb_id == P9BOX_CANVAS) {
|
||||
Paint9_DrawBrush(tx, ty, color, COLOR_TRANSPARENT, brush_id);
|
||||
continue;
|
||||
} else if (tb_id == P9BOX_PICKER) {
|
||||
color = GetColor(BOT_SCREEN, tx, ty);
|
||||
} else if (tb_id >= P9BOX_BRUSH_N) {
|
||||
brush_id = tb_id - P9BOX_BRUSH_N;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
Paint9_DrawBrush(x_cb, y_cb, color, brush_bg, brush_id);
|
||||
}
|
||||
}
|
||||
|
||||
ClearScreenF(true, true, COLOR_STD_BG);
|
||||
return 0;
|
||||
}
|
5
arm9/source/utils/paint9.h
Normal file
5
arm9/source/utils/paint9.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
u32 Paint9(void);
|
Loading…
x
Reference in New Issue
Block a user