#include "arm11/atp.h" #include "arm11/acf.h" #include "arm11/console.h" #include "arm11/drivers/hid.h" #include "drivers/gfx.h" #define TITLE_MAX 8 #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)); if( ta[0] ) acf_put_text( 5, 215, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH-10, ATP_COLOR_BLUE, ATP_PLACEMENT_LEFT, ta ); if( tb[0] ) 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_lineprovider_t provider, acf_callerdata_t data, int idx, int row ) { atp_linecfg_t config; config.text_color = ATP_COLOR_WHITE; config.text_align = ATP_PLACEMENT_LEFT; atp_error_t err = provider( data, idx, &config ); if( !err ) { acf_put_text( CONTAINER_LEFTTOP_X, CONTAINER_LEFTTOP_Y + row*FONT_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, CONTAINER_RECT_WIDTH, config.text_color > ATP_COLOR_WHITE ? ATP_COLOR_WHITE : config.text_color, config.text_align, config.text ); } } static void container_paint( atp_lineprovider_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_lineprovider_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 == 0 ) return ATP_POWER_OFF; 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; } if( top != idx_top ) { idx_top = top; screen_clean(); container_paint(provider, data, cnt, idx_top); } } } atp_itemval_t atp_select( atp_text_t title, atp_counter_t cnt, atp_itemprovider_t provider, atp_keyhandler_t handler, atp_callerdata_t data ) { uint8_t title_offset[TITLE_MAX]; int idx_top = 0, title_len = 1; atp_itemcfg_t config; } 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; }