mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-06 22:04:10 +08:00
157 lines
4.7 KiB
C
157 lines
4.7 KiB
C
#include "arm11/atp.h"
|
|
#include "arm11/acf.h"
|
|
#include "arm11/console.h"
|
|
#include "arm11/drivers/hid.h"
|
|
#include "drivers/gfx.h"
|
|
|
|
#define TIPS_MAX 64
|
|
static char ta[TIPS_MAX] = {'\0'};
|
|
static char tb[TIPS_MAX] = {'\0'};
|
|
|
|
//---------------------------------------------------
|
|
// basic print helper
|
|
|
|
static void set_screen_color( acf_callerdata_t data, acf_position_t tx, acf_position_t ty, acf_color_t b )
|
|
{
|
|
if( b == 0 ) return;
|
|
|
|
int *draw_data = data;
|
|
u16 *frame = consoleGet()->frameBuffer;
|
|
|
|
int x = tx + draw_data[0];
|
|
int y = ty + draw_data[1];
|
|
if( 0 <= x && x < draw_data[2] && 0 <= y && y < draw_data[3] ){
|
|
frame[ x*draw_data[3] + (draw_data[3]-1-y) ] = (u16)draw_data[4];
|
|
}
|
|
}
|
|
|
|
const char *acf_put_text(int x, int y, int width, int height, int maxwidth, u8 color, u8 placement, const char* text)
|
|
{
|
|
uint8_t draw_data[sizeof(int)*5];
|
|
|
|
int *draw_data_int = (int*)&draw_data;
|
|
draw_data_int[0] = x;
|
|
draw_data_int[1] = y;
|
|
draw_data_int[2] = width;
|
|
draw_data_int[3] = height;
|
|
draw_data_int[4] = (int)consoleGetRGB565Color(color);
|
|
|
|
const char *retval = text;
|
|
acf_rectedge_t realwid;
|
|
acf_canvas_t canvas = acf_get_canvas(maxwidth, text, &realwid, NULL, &retval);
|
|
if( !canvas ) return retval;
|
|
if( placement == ATP_PLACEMENT_RIGHT ) draw_data_int[0] += maxwidth - realwid;
|
|
else if( placement == ATP_PLACEMENT_CENTER ) draw_data_int[0] += (maxwidth-realwid) >> 1;
|
|
acf_recycle( acf_use_canvas(canvas, set_screen_color, draw_data) );
|
|
return retval;
|
|
}
|
|
|
|
//---------------------------------------------------
|
|
|
|
#define CONTAINER_LEFTTOP_X 20u
|
|
#define CONTAINER_LEFTTOP_Y 15u
|
|
#define CONTAINER_RECT_WIDTH 282u
|
|
#define CONTAINER_MAX_LINES 13u
|
|
#define WINDOW_WIDTH 320u
|
|
#define WINDOW_HEIGHT 240u
|
|
|
|
#define FONT_HEIGHT 15u
|
|
|
|
static void screen_clean()
|
|
{
|
|
memset(consoleGet()->frameBuffer, 0, WINDOW_WIDTH*WINDOW_HEIGHT*sizeof(uint16_t));
|
|
acf_put_text( 5, 215, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH-10, ATP_COLOR_BLUE, ATP_PLACEMENT_LEFT, ta );
|
|
acf_put_text( 5, 215, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH-10, ATP_COLOR_BLUE, ATP_PLACEMENT_RIGHT, tb );
|
|
}
|
|
|
|
// wait key pressed, if power key is pressed, return 0
|
|
static uint32_t waitKey()
|
|
{
|
|
uint32_t ek, down;
|
|
do{
|
|
GFX_waitForVBlank0();
|
|
hidScanInput();
|
|
ek = hidGetExtraKeys(0);
|
|
if( ek & (KEY_POWER_HELD | KEY_POWER) )
|
|
return 0;
|
|
|
|
down = hidKeysDown();
|
|
}while ( down == 0 );
|
|
|
|
return down;
|
|
}
|
|
|
|
static void paint_one_line( atp_lineinfo_t provider, acf_callerdata_t data, int idx, int row )
|
|
{
|
|
atp_text_t text;
|
|
atp_color_t color = ATP_COLOR_WHITE;
|
|
atp_placement_t align = ATP_PLACEMENT_LEFT;
|
|
atp_error_t err = provider( data, idx, &text, NULL, &color, &align );
|
|
if( !err ){
|
|
acf_put_text(
|
|
CONTAINER_LEFTTOP_X,
|
|
CONTAINER_LEFTTOP_Y + row*FONT_HEIGHT,
|
|
WINDOW_WIDTH,
|
|
WINDOW_HEIGHT,
|
|
CONTAINER_RECT_WIDTH,
|
|
color > ATP_COLOR_WHITE ? ATP_COLOR_WHITE : color,
|
|
align,
|
|
text
|
|
);
|
|
}
|
|
}
|
|
|
|
static void container_paint( atp_lineinfo_t provider, atp_callerdata_t data, atp_counter_t nlines, int top )
|
|
{
|
|
int end = top + CONTAINER_MAX_LINES;
|
|
if( end > (int)nlines ) end = nlines;
|
|
for( int n = top; n < end; ++n ){
|
|
paint_one_line( provider, data, n, n-top );
|
|
}
|
|
}
|
|
|
|
atp_error_t atp_show( atp_counter_t cnt, atp_lineinfo_t provider, atp_callerdata_t data )
|
|
{
|
|
int idx_top = 0;
|
|
screen_clean();
|
|
container_paint( provider, data, cnt, idx_top );
|
|
|
|
while( 1 ){
|
|
int top = idx_top;
|
|
u32 kDown = waitKey();
|
|
|
|
if( kDown == KEY_B || kDown == KEY_A ) return ATP_SUCCESS;
|
|
else if( cnt > CONTAINER_MAX_LINES ){ // may scroll
|
|
if( kDown == KEY_UP || kDown == KEY_DUP ){
|
|
top = idx_top - 1;
|
|
}
|
|
else if( kDown == KEY_DOWN || kDown == KEY_DDOWN ){
|
|
top = idx_top + 1;
|
|
}
|
|
|
|
if( top+CONTAINER_MAX_LINES > cnt ) top = cnt - CONTAINER_MAX_LINES;
|
|
else if( top < 0 ) top = 0;
|
|
}
|
|
else if( kDown == 0 ) return ATP_POWER_OFF;
|
|
|
|
if( top != idx_top ){
|
|
idx_top = top;
|
|
screen_clean();
|
|
container_paint(provider, data, cnt, idx_top);
|
|
}
|
|
}
|
|
}
|
|
|
|
atp_error_t atp_tips( atp_text_t tipsA, atp_text_t tipsB )
|
|
{
|
|
if( tipsA != NULL ){
|
|
strncpy( ta, tipsA, TIPS_MAX-1 );
|
|
ta[TIPS_MAX-1] = 0;
|
|
}
|
|
if( tipsB != NULL ){
|
|
strncpy( tb, tipsB, TIPS_MAX-1 );
|
|
tb[TIPS_MAX-1] = 0;
|
|
}
|
|
return ATP_SUCCESS;
|
|
}
|