Signed-off-by: Vincent-FK <vincent.buso@funkey-project.com>
This commit is contained in:
Vincent-FK 2020-11-15 15:55:57 +01:00
parent d1809eb9c0
commit 6eb1a04901
4 changed files with 1017 additions and 2 deletions

View File

@ -153,6 +153,7 @@ set(RETROFE_HEADERS
"${RETROFE_DIR}/Source/Graphics/PageBuilder.h"
"${RETROFE_DIR}/Source/Graphics/Page.h"
"${RETROFE_DIR}/Source/Menu/Menu.h"
"${RETROFE_DIR}/Source/Menu/MenuMode.h"
"${RETROFE_DIR}/Source/Sound/Sound.h"
"${RETROFE_DIR}/Source/Utility/Log.h"
"${RETROFE_DIR}/Source/Utility/Utils.h"
@ -206,6 +207,7 @@ set(RETROFE_SOURCES
"${RETROFE_DIR}/Source/Graphics/Component/VideoComponent.cpp"
"${RETROFE_DIR}/Source/Graphics/Component/Video.cpp"
"${RETROFE_DIR}/Source/Menu/Menu.cpp"
"${RETROFE_DIR}/Source/Menu/MenuMode.cpp"
"${RETROFE_DIR}/Source/Sound/Sound.cpp"
"${RETROFE_DIR}/Source/Utility/Log.cpp"
"${RETROFE_DIR}/Source/Utility/Utils.cpp"

View File

@ -0,0 +1,861 @@
#include "MenuMode.h"
#include <iostream>
#include "../SDL.h"
/// -------------- DEFINES --------------
//#define MENU_DEBUG
#define MENU_ERROR
#ifdef MENU_DEBUG
#define MENU_DEBUG_PRINTF(...) printf(__VA_ARGS__);
#else
#define MENU_DEBUG_PRINTF(...)
#endif //MENU_DEBUG
#ifdef MENU_ERROR
#define MENU_ERROR_PRINTF(...) printf(__VA_ARGS__);
#else
#define MENU_ERROR_PRINTF(...)
#endif //MENU_ERROR
#define SCREEN_HORIZONTAL_SIZE 240 //RES_HW_SCREEN_HORIZONTAL
#define SCREEN_VERTICAL_SIZE 240 //RES_HW_SCREEN_VERTICAL
#define SCROLL_SPEED_PX 240 //This means no animations but also no tearing effect
#define FPS_MENU 30
#define MENU_ZONE_WIDTH SCREEN_HORIZONTAL_SIZE
#define MENU_ZONE_HEIGHT SCREEN_VERTICAL_SIZE
#define MENU_FONT_NAME_TITLE "/usr/games/menu_resources/OpenSans-Bold.ttf"
#define MENU_FONT_SIZE_TITLE 22
#define MENU_FONT_NAME_INFO "/usr/games/menu_resources/OpenSans-Bold.ttf"
#define MENU_FONT_SIZE_INFO 16
#define MENU_FONT_NAME_SMALL_INFO "/usr/games/menu_resources/OpenSans-Regular.ttf"
#define MENU_FONT_SIZE_SMALL_INFO 13
#define MENU_PNG_BG_PATH "/usr/games/menu_resources/zone_bg.png"
#define GRAY_MAIN_R 85
#define GRAY_MAIN_G 85
#define GRAY_MAIN_B 85
#define WHITE_MAIN_R 236
#define WHITE_MAIN_G 236
#define WHITE_MAIN_B 236
#define MAX_SAVE_SLOTS 9
#define MAXPATHLEN 512
/// -------------- STATIC VARIABLES --------------
SDL_Surface * MenuMode::backup_hw_screen = NULL;
int MenuMode::backup_key_repeat_delay=0;
int MenuMode::backup_key_repeat_interval=0;
TTF_Font *MenuMode::menu_title_font = NULL;
TTF_Font *MenuMode::menu_info_font = NULL;
TTF_Font *MenuMode::menu_small_info_font = NULL;
SDL_Surface ** MenuMode::menu_zone_surfaces = NULL;
int * MenuMode::idx_menus = NULL;
int MenuMode::nb_menu_zones = 0;
int MenuMode::stop_menu_loop = 0;
SDL_Color MenuMode::text_color = {GRAY_MAIN_R, GRAY_MAIN_G, GRAY_MAIN_B};
int MenuMode::padding_y_from_center_menu_zone = 18;
uint16_t MenuMode::width_progress_bar = 100;
uint16_t MenuMode::height_progress_bar = 20;
uint16_t MenuMode::x_volume_bar = 0;
uint16_t MenuMode::y_volume_bar = 0;
uint16_t MenuMode::x_brightness_bar = 0;
uint16_t MenuMode::y_brightness_bar = 0;
int MenuMode::volume_percentage = 0;
int MenuMode::brightness_percentage = 0;
#undef X
#define X(a, b) b,
const char *MenuMode::aspect_ratio_name[] = {ASPECT_RATIOS};
int MenuMode::aspect_ratio = ASPECT_RATIOS_TYPE_STRECHED;
int MenuMode::aspect_ratio_factor_percent = 50;
int MenuMode::aspect_ratio_factor_step = 10;
int MenuMode::savestate_slot = 0;
/// -------------- FUNCTIONS IMPLEMENTATION --------------
void MenuMode::init( )
{
MENU_DEBUG_PRINTF("Init MenuMode\n");
/// ----- Loading the fonts -----
menu_title_font = TTF_OpenFont(MENU_FONT_NAME_TITLE, MENU_FONT_SIZE_TITLE);
if(!menu_title_font){
MENU_ERROR_PRINTF("ERROR in init_menu_SDL: Could not open menu font %s, %s\n", MENU_FONT_NAME_TITLE, SDL_GetError());
}
menu_info_font = TTF_OpenFont(MENU_FONT_NAME_INFO, MENU_FONT_SIZE_INFO);
if(!menu_info_font){
MENU_ERROR_PRINTF("ERROR in init_menu_SDL: Could not open menu font %s, %s\n", MENU_FONT_NAME_INFO, SDL_GetError());
}
menu_small_info_font = TTF_OpenFont(MENU_FONT_NAME_SMALL_INFO, MENU_FONT_SIZE_SMALL_INFO);
if(!menu_small_info_font){
MENU_ERROR_PRINTF("ERROR in init_menu_SDL: Could not open menu font %s, %s\n", MENU_FONT_NAME_SMALL_INFO, SDL_GetError());
}
/// ----- Copy virtual_hw_screen at init ------
SDL_Surface * virtual_hw_screen = SDL::getWindow();
backup_hw_screen = SDL_CreateRGBSurface(SDL_SWSURFACE,
virtual_hw_screen->w, virtual_hw_screen->h, 32, 0, 0, 0, 0);
if(backup_hw_screen == NULL){
MENU_ERROR_PRINTF("ERROR in init_menu_SDL: Could not create backup_hw_screen: %s\n", SDL_GetError());
}
/// ------ Save prev key repeat params and set new Key repeat -------
SDL_GetKeyRepeat(&backup_key_repeat_delay, &backup_key_repeat_interval);
if(SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL)){
MENU_ERROR_PRINTF("ERROR with SDL_EnableKeyRepeat: %s\n", SDL_GetError());
}
/// ------ Init menu zones ------
init_menu_zones();
return;
}
void MenuMode::end( )
{
MENU_DEBUG_PRINTF("End MenuMode \n");
/// ------ Close font -------
TTF_CloseFont(menu_title_font);
TTF_CloseFont(menu_info_font);
TTF_CloseFont(menu_small_info_font);
/// ------ Free Surfaces -------
for(int i=0; i < nb_menu_zones; i++){
SDL_FreeSurface(menu_zone_surfaces[i]);
}
SDL_FreeSurface(backup_hw_screen);
/// ------ reset initial key repeat values ------
if(SDL_EnableKeyRepeat(backup_key_repeat_delay, backup_key_repeat_interval)){
MENU_ERROR_PRINTF("ERROR with SDL_EnableKeyRepeat: %s\n", SDL_GetError());
}
return;
}
void MenuMode::draw_progress_bar(SDL_Surface * surface, uint16_t x, uint16_t y, uint16_t width,
uint16_t height, uint8_t percentage, uint16_t nb_bars){
/// ------ Init Variables ------
uint16_t line_width = 1; //px
uint16_t padding_bars_ratio = 3;
uint16_t nb_full_bars = 0;
/// ------ Check values ------
percentage = (percentage > 100)?100:percentage;
x = (x > (surface->w-1))?(surface->w-1):x;
y = (y > surface->h-1)?(surface->h-1):y;
width = (width < line_width*2+1)?(line_width*2+1):width;
width = (width > surface->w-x-1)?(surface->w-x-1):width;
height = (height < line_width*2+1)?(line_width*2+1):height;
height = (height > surface->h-y-1)?(surface->h-y-1):height;
uint16_t nb_bars_max = ( width * padding_bars_ratio / (line_width*2+1) + 1 ) / (padding_bars_ratio+1);
nb_bars = (nb_bars > nb_bars_max)?nb_bars_max:nb_bars;
uint16_t bar_width = (width / nb_bars)*padding_bars_ratio/(padding_bars_ratio+1)+1;
uint16_t bar_padding_x = bar_width/padding_bars_ratio;
nb_full_bars = nb_bars*percentage/100;
/// ------ draw full bars ------
for (int i = 0; i < nb_full_bars; ++i)
{
/// ---- draw one bar ----
//MENU_DEBUG_PRINTF("Drawing filled bar %d\n", i);
SDL_Rect rect = {x+ i*(bar_width +bar_padding_x),
y, bar_width, height};
SDL_FillRect(surface, &rect, SDL_MapRGB(surface->format, GRAY_MAIN_R, GRAY_MAIN_G, GRAY_MAIN_B));
}
/// ------ draw full bars ------
for (int i = 0; i < (nb_bars-nb_full_bars); ++i)
{
/// ---- draw one bar ----
//MENU_DEBUG_PRINTF("Drawing empty bar %d\n", i);
SDL_Rect rect = {x+ i*(bar_width +bar_padding_x) + nb_full_bars*(bar_width +bar_padding_x),
y, bar_width, height};
SDL_FillRect(surface, &rect, SDL_MapRGB(surface->format, GRAY_MAIN_R, GRAY_MAIN_G, GRAY_MAIN_B));
SDL_Rect rect2 = {x+ i*(bar_width +bar_padding_x) + line_width + nb_full_bars*(bar_width +bar_padding_x),
y + line_width, bar_width - line_width*2, height - line_width*2};
SDL_FillRect(surface, &rect2, SDL_MapRGB(surface->format, WHITE_MAIN_R, WHITE_MAIN_R, WHITE_MAIN_R));
}
}
void MenuMode::add_menu_zone(ENUM_MENU_TYPE menu_type){
/// ------ Increase nb of menu zones -------
nb_menu_zones++;
/// ------ Realoc idx Menus array -------
if(!idx_menus){
idx_menus = (int*) malloc(nb_menu_zones*sizeof(int));
menu_zone_surfaces = (SDL_Surface**) malloc(nb_menu_zones*sizeof(SDL_Surface*));
}
else{
int *temp = (int*) realloc(idx_menus, nb_menu_zones*sizeof(int));
idx_menus = temp;
menu_zone_surfaces = (SDL_Surface**) realloc(menu_zone_surfaces, nb_menu_zones*sizeof(SDL_Surface*));
}
idx_menus[nb_menu_zones-1] = menu_type;
/// ------ Reinit menu surface with height increased -------
menu_zone_surfaces[nb_menu_zones-1] = IMG_Load(MENU_PNG_BG_PATH);
if(!menu_zone_surfaces[nb_menu_zones-1]) {
MENU_ERROR_PRINTF("ERROR IMG_Load: %s\n", IMG_GetError());
}
/// --------- Init Common Variables --------
SDL_Surface *text_surface = NULL;
SDL_Surface *surface = menu_zone_surfaces[nb_menu_zones-1];
SDL_Rect text_pos;
/// --------- Add new zone ---------
switch(menu_type){
case MENU_TYPE_VOLUME:
MENU_DEBUG_PRINTF("Init MENU_TYPE_VOLUME\n");
/// ------ Text ------
text_surface = TTF_RenderText_Blended(menu_title_font, "VOLUME", text_color);
text_pos.x = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = surface->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 - padding_y_from_center_menu_zone;
SDL_BlitSurface(text_surface, NULL, surface, &text_pos);
x_volume_bar = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - width_progress_bar)/2;
y_volume_bar = surface->h - MENU_ZONE_HEIGHT/2 - height_progress_bar/2 + padding_y_from_center_menu_zone;
draw_progress_bar(surface, x_volume_bar, y_volume_bar,
width_progress_bar, height_progress_bar, 0, 100/STEP_CHANGE_VOLUME);
break;
case MENU_TYPE_BRIGHTNESS:
MENU_DEBUG_PRINTF("Init MENU_TYPE_BRIGHTNESS\n");
/// ------ Text ------
text_surface = TTF_RenderText_Blended(menu_title_font, "BRIGHTNESS", text_color);
text_pos.x = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = surface->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 - padding_y_from_center_menu_zone;
SDL_BlitSurface(text_surface, NULL, surface, &text_pos);
x_brightness_bar = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - width_progress_bar)/2;
y_brightness_bar = surface->h - MENU_ZONE_HEIGHT/2 - height_progress_bar/2 + padding_y_from_center_menu_zone;
draw_progress_bar(surface, x_brightness_bar, y_brightness_bar,
width_progress_bar, height_progress_bar, 0, 100/STEP_CHANGE_BRIGHTNESS);
break;
case MENU_TYPE_SAVE:
MENU_DEBUG_PRINTF("Init MENU_TYPE_SAVE\n");
/// ------ Text ------
text_surface = TTF_RenderText_Blended(menu_title_font, "SAVE", text_color);
text_pos.x = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = surface->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 - padding_y_from_center_menu_zone*2;
SDL_BlitSurface(text_surface, NULL, surface, &text_pos);
break;
case MENU_TYPE_LOAD:
MENU_DEBUG_PRINTF("Init MENU_TYPE_LOAD\n");
/// ------ Text ------
text_surface = TTF_RenderText_Blended(menu_title_font, "LOAD", text_color);
text_pos.x = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = surface->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 - padding_y_from_center_menu_zone*2;
SDL_BlitSurface(text_surface, NULL, surface, &text_pos);
break;
case MENU_TYPE_ASPECT_RATIO:
MENU_DEBUG_PRINTF("Init MENU_TYPE_ASPECT_RATIO\n");
/// ------ Text ------
text_surface = TTF_RenderText_Blended(menu_title_font, "ASPECT RATIO", text_color);
text_pos.x = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = surface->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 - padding_y_from_center_menu_zone;
SDL_BlitSurface(text_surface, NULL, surface, &text_pos);
break;
case MENU_TYPE_EXIT:
MENU_DEBUG_PRINTF("Init MENU_TYPE_EXIT\n");
/// ------ Text ------
text_surface = TTF_RenderText_Blended(menu_title_font, "EXIT GAME", text_color);
text_pos.x = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = surface->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2;
SDL_BlitSurface(text_surface, NULL, surface, &text_pos);
break;
case MENU_TYPE_POWERDOWN:
MENU_DEBUG_PRINTF("Init MENU_TYPE_POWERDOWN\n");
/// ------ Text ------
text_surface = TTF_RenderText_Blended(menu_title_font, "POWERDOWN", text_color);
text_pos.x = (surface->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = surface->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2;
SDL_BlitSurface(text_surface, NULL, surface, &text_pos);
break;
default:
MENU_DEBUG_PRINTF("Warning - In add_menu_zone, unknown MENU_TYPE: %d\n", menu_type);
break;
}
/// ------ Free Surfaces -------
SDL_FreeSurface(text_surface);
}
void MenuMode::init_menu_zones(){
/// Init Volume Menu
add_menu_zone(MENU_TYPE_VOLUME);
/// Init Brightness Menu
add_menu_zone(MENU_TYPE_BRIGHTNESS);
/// Init Save Menu
//add_menu_zone(MENU_TYPE_SAVE);
/// Init Load Menu
//add_menu_zone(MENU_TYPE_LOAD);
/// Init Aspect Ratio Menu
//add_menu_zone(MENU_TYPE_ASPECT_RATIO);
/// Init Exit Menu
//add_menu_zone(MENU_TYPE_EXIT);
/// Init Powerdown Menu
add_menu_zone(MENU_TYPE_POWERDOWN);
}
void MenuMode::init_menu_system_values(){
FILE *fp;
char res[100];
/// ------- Get system volume percentage --------
fp = popen(SHELL_CMD_VOLUME_GET, "r");
if (fp == NULL) {
MENU_ERROR_PRINTF("Failed to run command %s\n", SHELL_CMD_VOLUME_GET );
volume_percentage = 50; ///wrong value: setting default to 50
}
else{
fgets(res, sizeof(res)-1, fp);
/// Check if Volume is a number (at least the first char)
if(res[0] < '0' || res[0] > '9'){
MENU_ERROR_PRINTF("Wrong return value: %s for volume cmd: %s\n",res, SHELL_CMD_VOLUME_GET);
volume_percentage = 50; ///wrong value: setting default to 50
}
else{
volume_percentage = atoi(res);
MENU_DEBUG_PRINTF("System volume = %d%%\n", volume_percentage);
}
}
/// ------- Get system brightness percentage -------
fp = popen(SHELL_CMD_BRIGHTNESS_GET, "r");
if (fp == NULL) {
MENU_ERROR_PRINTF("Failed to run command %s\n", SHELL_CMD_BRIGHTNESS_GET );
brightness_percentage = 50; ///wrong value: setting default to 50
}
else{
fgets(res, sizeof(res)-1, fp);
/// Check if brightness is a number (at least the first char)
if(res[0] < '0' || res[0] > '9'){
MENU_ERROR_PRINTF("Wrong return value: %s for volume cmd: %s\n",res, SHELL_CMD_BRIGHTNESS_GET);
brightness_percentage = 50; ///wrong value: setting default to 50
}
else{
brightness_percentage = atoi(res);
MENU_DEBUG_PRINTF("System brightness = %d%%\n", brightness_percentage);
}
}
/// Get save slot from game
savestate_slot = (savestate_slot%MAX_SAVE_SLOTS); // security
}
void MenuMode::menu_screen_refresh(int menuItem, int prevItem, int scroll, uint8_t menu_confirmation, uint8_t menu_action){
/// --------- Clear HW screen ----------
SDL_Surface * virtual_hw_screen = SDL::getWindow();
if(SDL_BlitSurface(backup_hw_screen, NULL, virtual_hw_screen, NULL)){
MENU_ERROR_PRINTF("ERROR Could not Clear virtual_hw_screen: %s\n", SDL_GetError());
}
/// --------- Setup Blit Window ----------
SDL_Rect menu_blit_window;
menu_blit_window.x = 0;
menu_blit_window.w = SCREEN_HORIZONTAL_SIZE;
/// --------- Blit prev menu Zone going away ----------
menu_blit_window.y = scroll;
menu_blit_window.h = SCREEN_VERTICAL_SIZE;
if(SDL_BlitSurface(menu_zone_surfaces[prevItem], &menu_blit_window, virtual_hw_screen, NULL)){
MENU_ERROR_PRINTF("ERROR Could not Blit surface on virtual_hw_screen: %s\n", SDL_GetError());
}
/// --------- Blit new menu Zone going in (only during animations) ----------
if(scroll>0){
menu_blit_window.y = SCREEN_VERTICAL_SIZE-scroll;
menu_blit_window.h = SCREEN_VERTICAL_SIZE;
if(SDL_BlitSurface(menu_zone_surfaces[menuItem], NULL, virtual_hw_screen, &menu_blit_window)){
MENU_ERROR_PRINTF("ERROR Could not Blit surface on virtual_hw_screen: %s\n", SDL_GetError());
}
}
else if(scroll<0){
menu_blit_window.y = SCREEN_VERTICAL_SIZE+scroll;
menu_blit_window.h = SCREEN_VERTICAL_SIZE;
if(SDL_BlitSurface(menu_zone_surfaces[menuItem], &menu_blit_window, virtual_hw_screen, NULL)){
MENU_ERROR_PRINTF("ERROR Could not Blit surface on virtual_hw_screen: %s\n", SDL_GetError());
}
}
/// --------- No Scroll ? Blitting menu-specific info
else{
SDL_Surface * text_surface = NULL;
char text_tmp[40];
SDL_Rect text_pos;
char fname[MAXPATHLEN];
memset(fname, 0, MAXPATHLEN);
switch(idx_menus[menuItem]){
case MENU_TYPE_VOLUME:
draw_progress_bar(virtual_hw_screen, x_volume_bar, y_volume_bar,
width_progress_bar, height_progress_bar, volume_percentage, 100/STEP_CHANGE_VOLUME);
break;
case MENU_TYPE_BRIGHTNESS:
draw_progress_bar(virtual_hw_screen, x_volume_bar, y_volume_bar,
width_progress_bar, height_progress_bar, brightness_percentage, 100/STEP_CHANGE_BRIGHTNESS);
break;
case MENU_TYPE_SAVE:
/// ---- Write slot -----
sprintf(text_tmp, "IN SLOT < %d >", savestate_slot+1);
text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color);
text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2;
SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos);
if(menu_action){
sprintf(text_tmp, "Saving...");
text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color);
}
else{
if(menu_confirmation){
sprintf(text_tmp, "Are you sure ?");
text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color);
}
else{
/*/// ---- Write current Save state ----
get_savestate_filename(savestate_slot, fname);
file_open(savestate_file, fname, read);
if(file_check_valid(savestate_file))
{
file_close(savestate_file);
printf("Found Save slot: %s\n", fname);
char *p = strrchr (fname, '/');
char *basename = p ? p + 1 : (char *) fname;
char file_name_short[24];
snprintf(file_name_short, 24, "%s", basename);
text_surface = TTF_RenderText_Blended(menu_small_info_font, file_name_short, text_color);
}
else{
text_surface = TTF_RenderText_Blended(menu_info_font, "Free", text_color);
}*/
}
}
text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 + 2*padding_y_from_center_menu_zone;
SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos);
break;
case MENU_TYPE_LOAD:
/// ---- Write slot -----
sprintf(text_tmp, "FROM SLOT < %d >", savestate_slot+1);
text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color);
text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2;
SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos);
if(menu_action){
sprintf(text_tmp, "Loading...");
text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color);
}
else{
if(menu_confirmation){
sprintf(text_tmp, "Are you sure ?");
text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color);
}
else{
/*/// ---- Write current Load state ----
get_savestate_filename(savestate_slot, fname);
file_open(savestate_file, fname, read);
if(file_check_valid(savestate_file))
{
file_close(savestate_file);
printf("Found Load slot: %s\n", fname);
char *p = strrchr (fname, '/');
char *basename = p ? p + 1 : (char *) fname;
char file_name_short[24];
snprintf(file_name_short, 24, "%s", basename);
text_surface = TTF_RenderText_Blended(menu_small_info_font, file_name_short, text_color);
}
else{
text_surface = TTF_RenderText_Blended(menu_info_font, "Free", text_color);
}*/
}
}
text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 + 2*padding_y_from_center_menu_zone;
SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos);
break;
case MENU_TYPE_ASPECT_RATIO:
sprintf(text_tmp, "< %s >", aspect_ratio_name[aspect_ratio]);
text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color);
text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 + padding_y_from_center_menu_zone;
SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos);
break;
case MENU_TYPE_EXIT:
case MENU_TYPE_POWERDOWN:
if(menu_confirmation){
sprintf(text_tmp, "Are you sure ?");
text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color);
text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2;
text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 + 2*padding_y_from_center_menu_zone;
SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos);
}
break;
default:
break;
}
/// ------ Free Surfaces -------
if(text_surface)
SDL_FreeSurface(text_surface);
}
/// --------- Screen Rotate --------
/*SDL_Copy_Rotate_270((uint16_t *)virtual_hw_screen->pixels, (uint16_t *)hw_screen->pixels,
RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL,
RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL);*/
/*SDL_BlitSurface(virtual_hw_screen, NULL, virtual_hw_screen, NULL);*/
/// --------- Flip Screen ----------
//SDL_Flip(hw_screen);
SDL::renderAndFlipWindow();
}
void MenuMode::launch( )
{
MENU_DEBUG_PRINTF("Launch MenuMode\n");
SDL_Event event;
uint32_t prev_ms = SDL_GetTicks();
uint32_t cur_ms = SDL_GetTicks();
static int menuItem=0;
int prevItem=menuItem;
int scroll=0;
uint8_t screen_refresh = 1;
char shell_cmd[100];
FILE *fp;
uint8_t menu_confirmation = 0;
stop_menu_loop = 0;
char fname[MAXPATHLEN];
/// ------ Get init values -------
init_menu_system_values();
/// ------ Copy currently displayed screen -------
SDL_Surface * virtual_hw_screen = SDL::getWindow();
if(SDL_BlitSurface(virtual_hw_screen, NULL, backup_hw_screen, NULL)){
MENU_ERROR_PRINTF("ERROR Could not copy virtual_hw_screen: %s\n", SDL_GetError());
}
/// -------- Main loop ---------
while (!stop_menu_loop)
{
/// -------- Handle Keyboard Events ---------
if(!scroll){
while (SDL_PollEvent(&event))
switch(event.type)
{
case SDL_QUIT:
stop_menu_loop = 1;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_b:
if(menu_confirmation){
/// ------ Reset menu confirmation ------
menu_confirmation = 0;
/// ------ Refresh screen ------
screen_refresh = 1;
}
/*else{
stop_menu_loop = 1;
}*/
break;
case SDLK_q:
case SDLK_ESCAPE:
stop_menu_loop = 1;
break;
case SDLK_d:
case SDLK_DOWN:
MENU_DEBUG_PRINTF("DOWN\n");
/// ------ Start scrolling to new menu -------
menuItem++;
if (menuItem>=nb_menu_zones) menuItem=0;
scroll=SCROLL_SPEED_PX;
/// ------ Reset menu confirmation ------
menu_confirmation = 0;
/// ------ Refresh screen ------
screen_refresh = 1;
break;
case SDLK_u:
case SDLK_UP:
MENU_DEBUG_PRINTF("UP\n");
/// ------ Start scrolling to new menu -------
menuItem--;
if (menuItem<0) menuItem=nb_menu_zones-1;
scroll=-SCROLL_SPEED_PX;
/// ------ Reset menu confirmation ------
menu_confirmation = 0;
/// ------ Refresh screen ------
screen_refresh = 1;
break;
case SDLK_l:
case SDLK_LEFT:
//MENU_DEBUG_PRINTF("LEFT\n");
if(idx_menus[menuItem] == MENU_TYPE_VOLUME){
MENU_DEBUG_PRINTF("Volume DOWN\n");
/// ----- Compute new value -----
volume_percentage = (volume_percentage < STEP_CHANGE_VOLUME)?
0:(volume_percentage-STEP_CHANGE_VOLUME);
/// ----- Shell cmd ----
sprintf(shell_cmd, "%s %d", SHELL_CMD_VOLUME_SET, volume_percentage);
fp = popen(shell_cmd, "r");
if (fp == NULL) {
MENU_ERROR_PRINTF("Failed to run command %s\n", shell_cmd);
}
/// ------ Refresh screen ------
screen_refresh = 1;
}
else if(idx_menus[menuItem] == MENU_TYPE_BRIGHTNESS){
MENU_DEBUG_PRINTF("Brightness DOWN\n");
/// ----- Compute new value -----
brightness_percentage = (brightness_percentage < STEP_CHANGE_BRIGHTNESS)?
0:(brightness_percentage-STEP_CHANGE_BRIGHTNESS);
/// ----- Shell cmd ----
sprintf(shell_cmd, "%s %d", SHELL_CMD_BRIGHTNESS_SET, brightness_percentage);
fp = popen(shell_cmd, "r");
if (fp == NULL) {
MENU_ERROR_PRINTF("Failed to run command %s\n", shell_cmd);
}
/// ------ Refresh screen ------
screen_refresh = 1;
}
else if(idx_menus[menuItem] == MENU_TYPE_SAVE){
MENU_DEBUG_PRINTF("Save Slot DOWN\n");
savestate_slot = (!savestate_slot)?(MAX_SAVE_SLOTS-1):(savestate_slot-1);
/// ------ Refresh screen ------
screen_refresh = 1;
}
else if(idx_menus[menuItem] == MENU_TYPE_LOAD){
MENU_DEBUG_PRINTF("Load Slot DOWN\n");
//idx_load_slot = (!idx_load_slot)?(MAX_SAVE_SLOTS-1):(idx_load_slot-1);
savestate_slot = (!savestate_slot)?(MAX_SAVE_SLOTS-1):(savestate_slot-1);
/// ------ Refresh screen ------
screen_refresh = 1;
}
else if(idx_menus[menuItem] == MENU_TYPE_ASPECT_RATIO){
MENU_DEBUG_PRINTF("Aspect Ratio DOWN\n");
aspect_ratio = (!aspect_ratio)?(NB_ASPECT_RATIOS_TYPES-1):(aspect_ratio-1);
/// ------ Refresh screen ------
screen_refresh = 1;
}
break;
case SDLK_r:
case SDLK_RIGHT:
//MENU_DEBUG_PRINTF("RIGHT\n");
if(idx_menus[menuItem] == MENU_TYPE_VOLUME){
MENU_DEBUG_PRINTF("Volume UP\n");
/// ----- Compute new value -----
volume_percentage = (volume_percentage > 100 - STEP_CHANGE_VOLUME)?
100:(volume_percentage+STEP_CHANGE_VOLUME);
/// ----- Shell cmd ----
sprintf(shell_cmd, "%s %d", SHELL_CMD_VOLUME_SET, volume_percentage);
fp = popen(shell_cmd, "r");
if (fp == NULL) {
MENU_ERROR_PRINTF("Failed to run command %s\n", shell_cmd);
}
/// ------ Refresh screen ------
screen_refresh = 1;
}
else if(idx_menus[menuItem] == MENU_TYPE_BRIGHTNESS){
MENU_DEBUG_PRINTF("Brightness UP\n");
/// ----- Compute new value -----
brightness_percentage = (brightness_percentage > 100 - STEP_CHANGE_BRIGHTNESS)?
100:(brightness_percentage+STEP_CHANGE_BRIGHTNESS);
/// ----- Shell cmd ----
sprintf(shell_cmd, "%s %d", SHELL_CMD_BRIGHTNESS_SET, brightness_percentage);
fp = popen(shell_cmd, "r");
if (fp == NULL) {
MENU_ERROR_PRINTF("Failed to run command %s\n", shell_cmd);
}
/// ------ Refresh screen ------
screen_refresh = 1;
}
else if(idx_menus[menuItem] == MENU_TYPE_SAVE){
MENU_DEBUG_PRINTF("Save Slot UP\n");
savestate_slot = (savestate_slot+1)%MAX_SAVE_SLOTS;
/// ------ Refresh screen ------
screen_refresh = 1;
}
else if(idx_menus[menuItem] == MENU_TYPE_LOAD){
MENU_DEBUG_PRINTF("Load Slot UP\n");
//idx_load_slot = (idx_load_slot+1)%MAX_SAVE_SLOTS;
savestate_slot = (savestate_slot+1)%MAX_SAVE_SLOTS;
/// ------ Refresh screen ------
screen_refresh = 1;
}
else if(idx_menus[menuItem] == MENU_TYPE_ASPECT_RATIO){
MENU_DEBUG_PRINTF("Aspect Ratio UP\n");
aspect_ratio = (aspect_ratio+1)%NB_ASPECT_RATIOS_TYPES;
/// ------ Refresh screen ------
screen_refresh = 1;
}
break;
case SDLK_a:
case SDLK_RETURN:
if(idx_menus[menuItem] == MENU_TYPE_SAVE){
if(menu_confirmation){
MENU_DEBUG_PRINTF("Saving in slot %d\n", savestate_slot);
/// ------ Refresh Screen -------
menu_screen_refresh(menuItem, prevItem, scroll, menu_confirmation, 1);
/// ------ Save game ------
/*u16 *current_screen = copy_screen();
get_savestate_filename_noshot(savestate_slot, fname);
save_state(fname, current_screen);
/// ----- Hud Msg -----
sprintf(hud_msg, "SAVED IN SLOT %d", savestate_slot);
set_hud_msg(hud_msg, 4);*/
stop_menu_loop = 1;
}
else{
MENU_DEBUG_PRINTF("Save game - asking confirmation\n");
menu_confirmation = 1;
/// ------ Refresh screen ------
screen_refresh = 1;
}
}
else if(idx_menus[menuItem] == MENU_TYPE_LOAD){
if(menu_confirmation){
MENU_DEBUG_PRINTF("Loading in slot %d\n", savestate_slot);
/// ------ Refresh Screen -------
menu_screen_refresh(menuItem, prevItem, scroll, menu_confirmation, 1);
/// ------ Load game ------
/*get_savestate_filename_noshot(savestate_slot, fname);
load_state(fname);
/// ----- Hud Msg -----
sprintf(hud_msg, "LOADED FROM SLOT %d", savestate_slot);
set_hud_msg(hud_msg, 4);*/
stop_menu_loop = 1;
}
else{
MENU_DEBUG_PRINTF("Save game - asking confirmation\n");
menu_confirmation = 1;
/// ------ Refresh screen ------
screen_refresh = 1;
}
}
else if(idx_menus[menuItem] == MENU_TYPE_EXIT){
MENU_DEBUG_PRINTF("Exit game\n");
if(menu_confirmation){
MENU_DEBUG_PRINTF("Exit game - confirmed\n");
/// ----- The game should be saved here ----
/// ----- Exit game and back to launcher ----
//quit();
stop_menu_loop = 1;
}
else{
MENU_DEBUG_PRINTF("Exit game - asking confirmation\n");
menu_confirmation = 1;
/// ------ Refresh screen ------
screen_refresh = 1;
}
}
else if(idx_menus[menuItem] == MENU_TYPE_POWERDOWN){
if(menu_confirmation){
MENU_DEBUG_PRINTF("Powerdown - confirmed\n");
/// ----- Shell cmd ----
sprintf(shell_cmd, "%s", SHELL_CMD_POWERDOWN);
fp = popen(shell_cmd, "r");
if (fp == NULL) {
MENU_ERROR_PRINTF("Failed to run command %s\n", shell_cmd);
}
}
else{
MENU_DEBUG_PRINTF("Powerdown - asking confirmation\n");
menu_confirmation = 1;
/// ------ Refresh screen ------
screen_refresh = 1;
}
}
break;
default:
//MENU_DEBUG_PRINTF("Keydown: %d\n", event.key.keysym.sym);
break;
}
break;
}
}
/// --------- Handle Scroll effect ---------
if (scroll>0){
scroll+=SCROLL_SPEED_PX;
screen_refresh = 1;
}
if (scroll<0){
scroll-=SCROLL_SPEED_PX;
screen_refresh = 1;
}
if (scroll>MENU_ZONE_HEIGHT || scroll<-MENU_ZONE_HEIGHT) {
prevItem=menuItem;
scroll=0;
screen_refresh = 1;
}
/// --------- Handle FPS ---------
cur_ms = SDL_GetTicks();
if(cur_ms-prev_ms < 1000/FPS_MENU){
SDL_Delay(1000/FPS_MENU - (cur_ms-prev_ms));
}
prev_ms = SDL_GetTicks();
/// --------- Refresh screen
if(screen_refresh){
menu_screen_refresh(menuItem, prevItem, scroll, menu_confirmation, 0);
}
/// --------- reset screen refresh ---------
screen_refresh = 0;
}
return;
}

View File

@ -0,0 +1,128 @@
#pragma once
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <SDL/SDL_image.h>
typedef enum{
MENU_TYPE_VOLUME,
MENU_TYPE_BRIGHTNESS,
MENU_TYPE_SAVE,
MENU_TYPE_LOAD,
MENU_TYPE_ASPECT_RATIO,
MENU_TYPE_EXIT,
MENU_TYPE_POWERDOWN,
NB_MENU_TYPES,
} ENUM_MENU_TYPE;
///------ Definition of the different aspect ratios
#define ASPECT_RATIOS \
X(ASPECT_RATIOS_TYPE_MANUAL, "MANUAL ZOOM") \
X(ASPECT_RATIOS_TYPE_STRECHED, "STRECHED") \
X(ASPECT_RATIOS_TYPE_CROPPED, "CROPPED") \
X(ASPECT_RATIOS_TYPE_SCALED, "SCALED") \
X(NB_ASPECT_RATIOS_TYPES, "")
////------ Enumeration of the different aspect ratios ------
#undef X
#define X(a, b) a,
typedef enum {ASPECT_RATIOS} ENUM_ASPECT_RATIOS_TYPES;
////------ Defines to be shared -------
#define STEP_CHANGE_VOLUME 10
#define STEP_CHANGE_BRIGHTNESS 10
////------ Menu commands -------
#define SHELL_CMD_VOLUME_GET "/root/shell_cmds/volume_get.sh"
#define SHELL_CMD_VOLUME_SET "/root/shell_cmds/volume_set.sh"
#define SHELL_CMD_BRIGHTNESS_GET "/root/shell_cmds/brightness_get.sh"
#define SHELL_CMD_BRIGHTNESS_SET "/root/shell_cmds/brightness_set.sh"
#define SHELL_CMD_POWERDOWN "shutdown -h now"
class MenuMode
{
public:
//MenuMode();
static void init();
static void end();
static void launch( );
/*static SDL_Surface * draw_screen;
static int backup_key_repeat_delay, backup_key_repeat_interval;
static SDL_Surface * backup_hw_screen;
static TTF_Font *menu_title_font;
static TTF_Font *menu_info_font;
static TTF_Font *menu_small_info_font;
static SDL_Surface ** menu_zone_surfaces;
static int * idx_menus;
static int nb_menu_zones;
static int stop_menu_loop;
static SDL_Color text_color;
static int padding_y_from_center_menu_zone;
static uint16_t width_progress_bar;
static uint16_t height_progress_bar;
static uint16_t x_volume_bar;
static uint16_t y_volume_bar;
static uint16_t x_brightness_bar;
static uint16_t y_brightness_bar;
static int volume_percentage;
static int brightness_percentage;
static const char *aspect_ratio_name[];
static int aspect_ratio;
static int aspect_ratio_factor_percent;
static int aspect_ratio_factor_step;
static int savestate_slot;*/
private:
static void draw_progress_bar(SDL_Surface * surface, uint16_t x, uint16_t y, uint16_t width,
uint16_t height, uint8_t percentage, uint16_t nb_bars);
static void add_menu_zone(ENUM_MENU_TYPE menu_type);
static void init_menu_zones();
static void init_menu_system_values();
static void menu_screen_refresh(int menuItem, int prevItem, int scroll, uint8_t menu_confirmation, uint8_t menu_action);
//static SDL_Surface * hw_screen;
//static SDL_Surface * virtual_hw_screen; // this one is not rotated
static SDL_Surface * draw_screen;
static int backup_key_repeat_delay;
static int backup_key_repeat_interval;
static SDL_Surface * backup_hw_screen;
static TTF_Font *menu_title_font;
static TTF_Font *menu_info_font;
static TTF_Font *menu_small_info_font;
static SDL_Surface ** menu_zone_surfaces;
static int * idx_menus;
static int nb_menu_zones;
static int stop_menu_loop;
static SDL_Color text_color;
static int padding_y_from_center_menu_zone;
static uint16_t width_progress_bar;
static uint16_t height_progress_bar;
static uint16_t x_volume_bar;
static uint16_t y_volume_bar;
static uint16_t x_brightness_bar;
static uint16_t y_brightness_bar;
static int volume_percentage;
static int brightness_percentage;
static const char *aspect_ratio_name[];
static int aspect_ratio;
static int aspect_ratio_factor_percent;
static int aspect_ratio_factor_step;
static int savestate_slot;
};

View File

@ -22,6 +22,7 @@
#include "Collection/Item.h"
#include "Execute/Launcher.h"
#include "Menu/Menu.h"
#include "Menu/MenuMode.h"
#include "Utility/Log.h"
#include "Utility/Utils.h"
#include "Collection/MenuParser.h"
@ -225,6 +226,8 @@ void RetroFE::allocateGraphicsMemory( )
{
SDL::initialize( config_ );
currentPage_->initializeFonts( );
// Init MenuMode
MenuMode::init( );
}
// Allocate textures
@ -243,6 +246,9 @@ bool RetroFE::deInitialize( )
bool retVal = true;
// Deinit menuMode
MenuMode::end( );
// Free textures
freeGraphicsMemory( );
@ -395,6 +401,9 @@ void RetroFE::run( )
if(! SDL::initialize( config_ ) ) return;
fontcache_.initialize( );
// Initialize MenuMode
MenuMode::init();
// Define control configuration
std::string controlsConfPath = Utils::combinePath( Configuration::absolutePath, "controls.conf" );
if ( !config_.import( "controls", controlsConfPath ) )
@ -824,9 +833,17 @@ void RetroFE::run( )
nextPageItem_ = currentPage_->getSelectedItem( );
launchEnter( );
l.run(nextPageItem_->collectionInfo->name, nextPageItem_);
/********************************/
#warning to remove
//bypass
state = RETROFE_QUIT_REQUEST;
break;
/********************************/
launchExit( );
currentPage_->exitGame( );
state = RETROFE_LAUNCH_EXIT;
state = RETROFE_QUIT_REQUEST;
}
break;
@ -952,6 +969,12 @@ void RetroFE::run( )
state = RETROFE_MENUMODE_START_LOAD_ART;
}*/
/// Launch menu
menuMode_ = true;
printf("Menu launched here\n");
MenuMode::launch();
menuMode_ = false;
/// Clear events
SDL_Event ev;
while ( SDL_PollEvent( &ev ) );
@ -1000,6 +1023,7 @@ void RetroFE::run( )
// Handle screen updates and attract mode
if ( running )
{
// Handle FPS
lastTime = currentTime_;
currentTime_ = static_cast<float>( SDL_GetTicks( ) ) / 1000;
@ -1009,7 +1033,7 @@ void RetroFE::run( )
}
deltaTime = currentTime_ - lastTime;
double sleepTime = 1000.0/60.0 - deltaTime*1000;
double sleepTime = 1000.0/FPS - deltaTime*1000;
if ( sleepTime > 0 )
{
SDL_Delay( static_cast<unsigned int>( sleepTime ) );