2012-07-29 10:39:21 +02:00
|
|
|
/*********************************************************************
|
|
|
|
* Copyright (C) 2012, Fabio Olimpieri
|
|
|
|
* Copyright (C) 2009, Simon Kagstrom
|
|
|
|
*
|
|
|
|
* Filename: menu_sdl.c
|
|
|
|
*
|
|
|
|
* Description: Code for menus (originally for Mophun)
|
|
|
|
*
|
|
|
|
* This file is part of FBZX Wii
|
|
|
|
*
|
|
|
|
* FBZX Wii 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 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* FBZX Wii is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <SDL/SDL.h>
|
|
|
|
#include <SDL/SDL_ttf.h>
|
2014-04-25 14:08:36 +02:00
|
|
|
#include<SDL/SDL_image.h>
|
2012-07-29 10:39:21 +02:00
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "menu_sdl.h"
|
|
|
|
#include "emulator.h"
|
|
|
|
#include "VirtualKeyboard.h"
|
|
|
|
|
2012-08-05 23:56:13 +02:00
|
|
|
#include "characters.h"
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2012-08-26 18:04:12 +02:00
|
|
|
#include "minizip/unzip.h"
|
2013-03-16 08:58:25 +01:00
|
|
|
#include "tape_browser.h"
|
2014-04-25 14:08:36 +02:00
|
|
|
#include "sound.h"
|
|
|
|
|
2012-08-26 18:04:12 +02:00
|
|
|
|
2013-01-05 07:43:46 +01:00
|
|
|
#if defined(GEKKO)
|
|
|
|
# include <wiiuse/wpad.h>
|
|
|
|
#endif
|
|
|
|
|
2012-08-26 18:04:12 +02:00
|
|
|
#ifdef DEBUG
|
|
|
|
extern FILE *fdebug;
|
|
|
|
#define printf(...) fprintf(fdebug,__VA_ARGS__)
|
|
|
|
#else
|
|
|
|
#ifdef GEKKO
|
|
|
|
#define printf(...)
|
|
|
|
#endif
|
|
|
|
#endif
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int n_entries;
|
|
|
|
int index;
|
|
|
|
int sel;
|
|
|
|
} submenu_t;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2013-02-10 14:08:05 +01:00
|
|
|
char title[MAX_PATH_LENGTH];
|
2012-07-29 10:39:21 +02:00
|
|
|
const char **pp_msgs;
|
|
|
|
TTF_Font *p_font;
|
|
|
|
int x1,y1;
|
|
|
|
int x2,y2;
|
|
|
|
int text_w;
|
|
|
|
int text_h;
|
|
|
|
|
|
|
|
int n_submenus;
|
|
|
|
submenu_t *p_submenus;
|
|
|
|
|
|
|
|
int cur_sel; /* Main selection */
|
|
|
|
int start_entry_visible;
|
|
|
|
int n_entries;
|
|
|
|
} menu_t;
|
|
|
|
|
|
|
|
static SDL_Surface *real_screen;
|
|
|
|
|
|
|
|
#define IS_SUBMENU(p_msg) ( (p_msg)[0] == '^' )
|
|
|
|
#define IS_TEXT(p_msg) ( (p_msg)[0] == '#' || (p_msg)[0] == ' ' )
|
|
|
|
#define IS_MARKER(p_msg) ( (p_msg)[0] == '@' )
|
|
|
|
|
|
|
|
static int is_inited = 0;
|
2014-04-19 19:02:16 +02:00
|
|
|
static TTF_Font *menu_font_alt_large, *menu_font_large, *menu_font_alt_small, *menu_font_small;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
int fh, fw;
|
|
|
|
|
2014-04-25 14:08:36 +02:00
|
|
|
static int *click_buffer_pointer[3];
|
|
|
|
static int len_click_buffer[3];
|
|
|
|
static SDL_Surface *image_stripes, *image_stripes_small,*tmp_surface;
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
int msgInfo(char *text, int duration, SDL_Rect *irc)
|
|
|
|
{
|
|
|
|
int len = strlen(text);
|
2014-04-19 19:02:16 +02:00
|
|
|
int X, Y, w, h;
|
2012-07-29 10:39:21 +02:00
|
|
|
SDL_Rect src;
|
|
|
|
SDL_Rect rc;
|
|
|
|
SDL_Rect brc;
|
2014-04-19 19:02:16 +02:00
|
|
|
|
|
|
|
if (RATIO==1) TTF_SizeText(menu_font_large, "Z", &w, &h); else TTF_SizeText(menu_font_small, "Z", &w, &h);
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*w;
|
|
|
|
Y = (FULL_DISPLAY_Y /2) - h;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
brc.x = FULL_DISPLAY_X/2-2*w-2/RATIO;
|
|
|
|
brc.y=Y+h*2-4/RATIO;
|
|
|
|
brc.w=w*4;
|
|
|
|
brc.h=h*3/2;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
rc.x = X;
|
|
|
|
rc.y=Y;
|
2014-04-19 19:02:16 +02:00
|
|
|
rc.w=w*(len + 2);
|
|
|
|
rc.h=duration >= 0 ? h*2 : h*4;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
src.x=rc.x+2/RATIO;
|
|
|
|
src.y=rc.y+2/RATIO;
|
|
|
|
src.w=rc.w-4/RATIO;
|
|
|
|
src.h=rc.h-4/RATIO;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
|
|
|
|
if (irc)
|
|
|
|
{
|
|
|
|
irc->x=rc.x;
|
|
|
|
irc->y=rc.y;
|
|
|
|
irc->w=src.w;
|
|
|
|
irc->h=src.h;
|
2014-04-19 19:02:16 +02:00
|
|
|
}
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 255, 255, 0));
|
2014-04-19 19:02:16 +02:00
|
|
|
SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 255, 255, 255));
|
|
|
|
menu_print_font(real_screen, 0,0,0, X+w, Y+h/2, text,20,64);
|
2012-07-29 10:39:21 +02:00
|
|
|
SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h);
|
|
|
|
SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h);
|
|
|
|
if (duration > 0)
|
|
|
|
SDL_Delay(duration);
|
|
|
|
else if (duration < 0)
|
|
|
|
{
|
|
|
|
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00));
|
2014-04-19 19:02:16 +02:00
|
|
|
menu_print_font(real_screen, 0,0,0, FULL_DISPLAY_X/2-w, Y+h*2, "OK",20,64);
|
2012-07-29 10:39:21 +02:00
|
|
|
SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w, brc.h);
|
2013-01-16 21:07:44 +01:00
|
|
|
while (!(KEY_SELECT & menu_wait_key_press())) {}
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
void msgKill(SDL_Rect *rc)
|
|
|
|
{
|
|
|
|
SDL_UpdateRect(real_screen, rc->x, rc->y, rc->w,rc->h);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
int msgYesNo(char *text, int default_opt, int x, int y)
|
|
|
|
{
|
|
|
|
int len = strlen(text);
|
2014-04-19 19:02:16 +02:00
|
|
|
int X, Y, w, h;
|
2012-07-29 10:39:21 +02:00
|
|
|
SDL_Rect src;
|
|
|
|
SDL_Rect rc;
|
|
|
|
SDL_Rect brc;
|
|
|
|
uint32_t key;
|
2014-04-19 19:02:16 +02:00
|
|
|
|
|
|
|
if (RATIO==1) TTF_SizeText(menu_font_large, "Z", &w, &h); else TTF_SizeText(menu_font_small, "Z", &w, &h);
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
if (x < 0)
|
2014-04-19 19:02:16 +02:00
|
|
|
X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*w;
|
2012-07-29 10:39:21 +02:00
|
|
|
else
|
|
|
|
X = x;
|
|
|
|
|
|
|
|
if (y < 0)
|
2014-04-19 19:02:16 +02:00
|
|
|
Y = (FULL_DISPLAY_Y /2) - h*2;
|
2012-07-29 10:39:21 +02:00
|
|
|
else
|
|
|
|
Y = y;
|
|
|
|
|
|
|
|
rc.x=X;
|
|
|
|
rc.y=Y;
|
2014-04-19 19:02:16 +02:00
|
|
|
rc.w=w*(len + 2);
|
|
|
|
rc.h=h*4;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
src.x=rc.x+2/RATIO;
|
|
|
|
src.y=rc.y+2/RATIO;
|
|
|
|
src.w=rc.w-4/RATIO;
|
|
|
|
src.h=rc.h-4/RATIO;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
while (1)
|
2014-04-19 19:02:16 +02:00
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 255, 255, 0));
|
2014-04-19 19:02:16 +02:00
|
|
|
SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 255, 255, 255));
|
|
|
|
menu_print_font(real_screen, 0,0,0, X+w, Y+h/2, text,20,64);
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
if (default_opt) //"YES"
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
brc.x=rc.x + rc.w/2-5*w-2/RATIO;
|
|
|
|
brc.y=rc.y+h*2-4/RATIO;
|
|
|
|
brc.w=w*3;
|
|
|
|
brc.h=h*3/2;
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 255, 0x00));
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
2014-04-19 19:02:16 +02:00
|
|
|
else //"NO"
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
brc.x=rc.x + rc.w/2+5*w-2*w-2/RATIO;
|
|
|
|
brc.y=rc.y+h*2-4/RATIO;
|
|
|
|
brc.w=w*2;
|
|
|
|
brc.h=h*3/2;
|
|
|
|
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 255, 0x00, 0x00));
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
menu_print_font(real_screen, 0,0,0, rc.x + rc.w/2-5*w, Y+h*2, "YES",20,64);
|
|
|
|
menu_print_font(real_screen, 0,0,0, rc.x + rc.w/2+5*w-2*w, Y+h*2, "NO",20,64);
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h);
|
|
|
|
SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h);
|
|
|
|
SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w,brc.h);
|
|
|
|
|
|
|
|
//SDL_Flip(real_screen);
|
2013-01-16 21:07:44 +01:00
|
|
|
key = menu_wait_key_press();
|
2012-07-29 10:39:21 +02:00
|
|
|
if (key & KEY_SELECT)
|
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
play_click(1);
|
2012-07-29 10:39:21 +02:00
|
|
|
return default_opt;
|
|
|
|
}
|
|
|
|
else if (key & KEY_ESCAPE)
|
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
play_click(2);
|
2012-07-29 10:39:21 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (key & KEY_LEFT)
|
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
play_click(0);
|
2012-07-29 10:39:21 +02:00
|
|
|
default_opt = !default_opt;
|
|
|
|
}
|
|
|
|
else if (key & KEY_RIGHT)
|
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
play_click(0);
|
2012-07-29 10:39:21 +02:00
|
|
|
default_opt = !default_opt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int cmpstringp(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
const char *p1_s = *(const char**)p1;
|
|
|
|
const char *p2_s = *(const char**)p2;
|
|
|
|
|
|
|
|
/* Put directories first */
|
|
|
|
if (*p1_s == '[' && *p2_s != '[')
|
|
|
|
return -1;
|
|
|
|
if (*p1_s != '[' && *p2_s == '[')
|
|
|
|
return 1;
|
2013-01-16 21:07:44 +01:00
|
|
|
return strcasecmp(* (char * const *) p1, * (char * const *) p2);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return true if name ends with ext (for filenames) */
|
|
|
|
int ext_matches(const char *name, const char *ext)
|
|
|
|
{
|
|
|
|
int len = strlen(name);
|
|
|
|
int ext_len = strlen(ext);
|
|
|
|
|
|
|
|
if (len <= ext_len)
|
|
|
|
return 0;
|
|
|
|
return (strcmp(name + len - ext_len, ext) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ext_matches_list(const char *name, const char **exts)
|
|
|
|
{
|
|
|
|
const char **p;
|
|
|
|
|
|
|
|
for (p = exts; *p; p++)
|
|
|
|
{
|
|
|
|
if (ext_matches(name, *p))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-08-26 18:04:12 +02:00
|
|
|
static const char **get_file_list_zip(const char *path)
|
|
|
|
{
|
|
|
|
unzFile uf = unzOpen(path);
|
|
|
|
unz_global_info gi;
|
|
|
|
const char **file_list;
|
|
|
|
int err, cur=0;
|
|
|
|
|
|
|
|
if (!uf) return NULL;
|
|
|
|
|
|
|
|
err = unzGetGlobalInfo (uf,&gi);
|
|
|
|
if (err!=UNZ_OK) printf("error %d with zipfile in unzGetGlobalInfo \n",err);
|
|
|
|
|
|
|
|
file_list = (const char**)malloc((gi.number_entry +3) * sizeof(char*));
|
|
|
|
file_list[cur++] = strdup("None");
|
|
|
|
file_list[cur++] = strdup("[..]");
|
|
|
|
file_list[cur] = NULL;
|
|
|
|
|
|
|
|
for (cur=2;cur<gi.number_entry+2;cur++)
|
|
|
|
{
|
2013-02-10 14:08:05 +01:00
|
|
|
char filename_inzip[MAX_PATH_LENGTH];
|
2012-08-26 18:04:12 +02:00
|
|
|
unz_file_info file_info;
|
|
|
|
|
|
|
|
err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
|
|
|
|
if (err!=UNZ_OK)
|
|
|
|
{
|
|
|
|
printf("Error %d with zipfile in unzGetCurrentFileInfo\n",err);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA",
|
|
|
|
".mdr", ".MDR", ".scr", ".SCR", ".conf", ".CONF",".pok", ".POK" ,NULL};
|
|
|
|
|
|
|
|
if (ext_matches_list(filename_inzip, exts))
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
p = strdup(filename_inzip);
|
|
|
|
file_list[cur] = p;
|
|
|
|
file_list[cur+1] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cur<gi.number_entry+1)
|
|
|
|
{
|
|
|
|
err = unzGoToNextFile(uf);
|
|
|
|
if (err!=UNZ_OK)
|
|
|
|
{
|
|
|
|
printf("error %d with zipfile in unzGoToNextFile\n",err);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
unzClose(uf);
|
|
|
|
|
|
|
|
//qsort(&file_list[2], gi.number_entry, sizeof(const char *), cmpstringp);
|
|
|
|
|
|
|
|
return file_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
static const char **get_file_list(const char *base_dir)
|
|
|
|
{
|
|
|
|
DIR *d = opendir(base_dir);
|
2012-12-30 18:52:21 +01:00
|
|
|
const char **file_list, **realloc_file_list;
|
2012-07-29 10:39:21 +02:00
|
|
|
int cur = 0;
|
|
|
|
struct dirent *de;
|
|
|
|
int cnt = 16;
|
|
|
|
|
|
|
|
if (!d)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
file_list = (const char**)malloc(cnt * sizeof(char*));
|
|
|
|
file_list[cur++] = strdup("None");
|
|
|
|
file_list[cur] = NULL;
|
|
|
|
|
|
|
|
for (de = readdir(d);
|
|
|
|
de;
|
|
|
|
de = readdir(d))
|
|
|
|
{
|
|
|
|
char buf[255];
|
|
|
|
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA",
|
2012-08-26 18:04:12 +02:00
|
|
|
".mdr", ".MDR", ".scr", ".SCR", ".conf", ".CONF",".pok", ".POK", ".zip", ".ZIP",NULL};
|
2012-07-29 10:39:21 +02:00
|
|
|
struct stat st;
|
|
|
|
|
|
|
|
snprintf(buf, 255, "%s/%s", base_dir, de->d_name);
|
|
|
|
if (stat(buf, &st) < 0)
|
|
|
|
continue;
|
|
|
|
if (S_ISDIR(st.st_mode)&&strcmp(".", de->d_name))
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
size_t len = strlen(de->d_name) + 4;
|
|
|
|
|
|
|
|
p = (char*)malloc( len );
|
2013-03-22 21:20:29 +01:00
|
|
|
if (p==NULL) break; //Terminate the list
|
2012-07-29 10:39:21 +02:00
|
|
|
snprintf(p, len, "[%s]", de->d_name);
|
|
|
|
file_list[cur++] = p;
|
|
|
|
file_list[cur] = NULL;
|
|
|
|
}
|
|
|
|
else if (ext_matches_list(de->d_name, exts))
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
p = strdup(de->d_name);
|
2013-03-22 21:20:29 +01:00
|
|
|
if (p==NULL) break; //Terminate the list
|
2012-07-29 10:39:21 +02:00
|
|
|
file_list[cur++] = p;
|
|
|
|
file_list[cur] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cur > cnt - 2)
|
|
|
|
{
|
|
|
|
cnt = cnt + 32;
|
2012-12-30 18:52:21 +01:00
|
|
|
realloc_file_list = (const char**)realloc(file_list, cnt * sizeof(char*));
|
2013-03-22 21:20:29 +01:00
|
|
|
if (realloc_file_list) file_list = realloc_file_list; else break;
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(d);
|
|
|
|
qsort(&file_list[1], cur-1, sizeof(const char *), cmpstringp);
|
|
|
|
|
|
|
|
return file_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static submenu_t *find_submenu(menu_t *p_menu, int index)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0; i<p_menu->n_submenus; i++)
|
|
|
|
{
|
|
|
|
if (p_menu->p_submenus[i].index == index)
|
|
|
|
return &p_menu->p_submenus[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void menu_print_font(SDL_Surface *screen, int r, int g, int b,
|
2013-01-19 13:36:36 +01:00
|
|
|
int x, int y, const char *msg, int font_size, int max_string)
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
|
|
|
SDL_Surface *font_surf;
|
|
|
|
SDL_Rect dst = {x, y, 0, 0};
|
2014-03-22 19:56:52 +01:00
|
|
|
SDL_Color color = {r, g, b, 0};
|
2012-07-29 10:39:21 +02:00
|
|
|
char buf[255];
|
2014-04-19 19:02:16 +02:00
|
|
|
unsigned int i, length;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
strncpy(buf, msg, 254);
|
|
|
|
if (buf[0] != '|' && buf[0] != '^' && buf[0] != '.'
|
|
|
|
&& buf[0] != '-' && buf[0] != ' ' && !strstr(buf, " \""))
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
length = strlen(buf);
|
|
|
|
if (length>max_string)
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
if (buf[length-8]== '.') strcpy (buf + max_string-8, buf + length-8);
|
2014-04-25 14:08:36 +02:00
|
|
|
else if (buf[length-4] == '.') strcpy (buf + max_string-4, buf + length-4);
|
|
|
|
else buf[length]=0;
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Fixup multi-menu option look */
|
|
|
|
for (i = 0; i < strlen(buf) ; i++)
|
|
|
|
{
|
|
|
|
if (buf[i] == '^' || buf[i] == '|')
|
|
|
|
buf[i] = ' ';
|
|
|
|
}
|
|
|
|
|
2012-08-11 10:31:00 +02:00
|
|
|
if (FULL_DISPLAY_X == 640)
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font_alt_large, buf, color);
|
|
|
|
else font_surf = TTF_RenderUTF8_Blended(menu_font_large, buf, color);
|
2012-08-11 10:31:00 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font_alt_small, buf, color);
|
|
|
|
else font_surf = TTF_RenderUTF8_Blended(menu_font_small, buf, color);
|
2012-08-11 10:31:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!font_surf)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", TTF_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_BlitSurface(font_surf, NULL, screen, &dst);
|
|
|
|
SDL_FreeSurface(font_surf);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_font(SDL_Surface *screen, int r, int g, int b,
|
|
|
|
int x, int y, const char *msg, int font_size)
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
#define _MAX_STRING 52
|
2012-08-11 10:31:00 +02:00
|
|
|
SDL_Surface *font_surf;
|
|
|
|
SDL_Rect dst = {x, y, 0, 0};
|
2014-03-22 19:56:52 +01:00
|
|
|
SDL_Color color = {r, g, b, 0};
|
2012-08-11 10:31:00 +02:00
|
|
|
char buf[255];
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
strncpy(buf, msg, 254);
|
|
|
|
|
|
|
|
|
|
|
|
if (strlen(buf)>_MAX_STRING)
|
|
|
|
{
|
|
|
|
buf[_MAX_STRING] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
if (FULL_DISPLAY_X == 640)
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font_alt_large, buf, color);
|
|
|
|
else font_surf = TTF_RenderUTF8_Blended(menu_font_large, buf, color);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font_alt_small, buf, color);
|
|
|
|
else font_surf = TTF_RenderUTF8_Blended(menu_font_small, buf, color);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!font_surf)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", TTF_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_BlitSurface(font_surf, NULL, screen, &dst);
|
|
|
|
SDL_FreeSurface(font_surf);
|
|
|
|
}
|
|
|
|
|
2013-01-03 08:34:16 +01:00
|
|
|
void draw_scr_file(int x,int y, char *filename)
|
|
|
|
{
|
|
|
|
FILE *fichero;
|
|
|
|
char screen [6912];
|
|
|
|
unsigned int *p_translt, *p_translt2;
|
|
|
|
unsigned char attribute, ink, paper, mask, octect;
|
|
|
|
int loop_x, loop_y,bucle,valor,*p ;
|
|
|
|
unsigned char *address;
|
|
|
|
|
|
|
|
|
|
|
|
if (filename==NULL) // Aborted
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!(ext_matches(filename, ".scr")||ext_matches(filename, ".SCR"))) return;
|
|
|
|
|
|
|
|
fichero=fopen(filename,"rb");
|
|
|
|
|
|
|
|
if (!fichero) return;
|
|
|
|
|
|
|
|
if (fread(screen,1,6912,fichero)!=6912) {fclose(fichero);return;}
|
|
|
|
fclose(fichero);
|
|
|
|
|
|
|
|
p_translt = ordenador.translate;
|
|
|
|
p_translt2 = ordenador.translate2;
|
|
|
|
|
|
|
|
for (loop_y=0; loop_y<192;loop_y++)
|
|
|
|
for(loop_x=0; loop_x<32; loop_x++)
|
|
|
|
{
|
|
|
|
|
|
|
|
attribute = screen[(*p_translt2)-147456]; // attribute
|
|
|
|
|
|
|
|
ink = attribute & 0x07; // ink colour
|
|
|
|
paper = (attribute >> 3) & 0x07; // paper colour
|
|
|
|
|
|
|
|
octect = screen[(*p_translt)-147456]; // bitmap
|
|
|
|
mask = 0x80;
|
|
|
|
|
|
|
|
for (bucle = 0; bucle < 8; bucle++)
|
|
|
|
{
|
|
|
|
valor = (octect & mask) ? (int) ink : (int) paper;
|
|
|
|
p=(colors+valor);
|
|
|
|
|
|
|
|
address = (unsigned char *)(ordenador.screen->pixels + (x + loop_x*8 + bucle + (y + loop_y)*640)*ordenador.bpp);
|
|
|
|
|
2014-03-23 18:49:03 +01:00
|
|
|
paint_one_pixel((unsigned char *)p, address);
|
2013-01-03 08:34:16 +01:00
|
|
|
|
|
|
|
mask = ((mask >> 1) & 0x7F);
|
|
|
|
}
|
|
|
|
|
|
|
|
p_translt++;
|
|
|
|
p_translt2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void menu_draw(SDL_Surface *screen, menu_t *p_menu, int sel, int font_size, int draw_scr)
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
//int font_height = TTF_FontHeight(p_menu->p_font);
|
|
|
|
//int line_height = (font_height + font_height / 2);
|
|
|
|
int line_height = 22/ RATIO;
|
|
|
|
int x_start = p_menu->x1+4/RATIO;
|
2014-04-25 14:08:36 +02:00
|
|
|
int y_start;
|
2012-07-29 10:39:21 +02:00
|
|
|
SDL_Rect r;
|
2014-04-19 19:02:16 +02:00
|
|
|
int entries_visible = (p_menu->y2 - p_menu->y1-10/RATIO) / line_height - 1;
|
2013-01-03 08:34:16 +01:00
|
|
|
const char *selected_file = NULL;
|
2013-02-10 14:08:05 +01:00
|
|
|
char filename[MAX_PATH_LENGTH];
|
|
|
|
char name[MAX_PATH_LENGTH];
|
2013-01-03 08:34:16 +01:00
|
|
|
char *ptr;
|
2013-01-19 13:36:36 +01:00
|
|
|
int i, y, length, max_string;
|
|
|
|
|
2014-04-25 14:08:36 +02:00
|
|
|
if (font_size==16) y_start = p_menu->y1 + line_height+2/RATIO;
|
|
|
|
else y_start = p_menu->y1 + line_height+4/RATIO;
|
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
if ((draw_scr)&&(RATIO==1)) max_string = 30; else max_string = 46;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
//if ( p_menu->n_entries * line_height > p_menu->y2 )
|
|
|
|
//y_start = p_menu->y1 + line_height;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
if (p_menu->cur_sel - p_menu->start_entry_visible > entries_visible)
|
|
|
|
{
|
|
|
|
while (p_menu->cur_sel - p_menu->start_entry_visible > entries_visible)
|
|
|
|
{
|
|
|
|
p_menu->start_entry_visible ++;
|
|
|
|
if (p_menu->start_entry_visible > p_menu->n_entries)
|
|
|
|
{
|
|
|
|
p_menu->start_entry_visible = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( p_menu->cur_sel < p_menu->start_entry_visible )
|
|
|
|
p_menu->start_entry_visible = p_menu->cur_sel;
|
|
|
|
|
|
|
|
if (strlen(p_menu->title))
|
|
|
|
{
|
|
|
|
r.x = p_menu->x1;
|
|
|
|
r.y = p_menu->y1;
|
|
|
|
r.w = p_menu->x2 - p_menu->x1;
|
2014-04-19 19:02:16 +02:00
|
|
|
r.h = line_height;
|
2012-07-29 10:39:21 +02:00
|
|
|
if (sel < 0)
|
|
|
|
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0x40, 0x00, 0x00));
|
|
|
|
else
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 255, 0)); //Title
|
|
|
|
if (font_size==16) menu_print_font(screen, 0,0,0, p_menu->x1+4/RATIO, p_menu->y1+2/RATIO, p_menu->title, font_size, 50);
|
|
|
|
else menu_print_font(screen, 0,0,0, p_menu->x1+4/RATIO, p_menu->y1+4/RATIO, p_menu->title, font_size, 50);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = p_menu->start_entry_visible; i <= p_menu->start_entry_visible + entries_visible; i++)
|
|
|
|
{
|
|
|
|
const char *msg = p_menu->pp_msgs[i];
|
|
|
|
|
|
|
|
if (i >= p_menu->n_entries)
|
|
|
|
break;
|
|
|
|
if (IS_MARKER(msg))
|
|
|
|
p_menu->cur_sel = atoi(&msg[1]);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
y = (i - p_menu->start_entry_visible) * line_height;
|
2014-04-19 19:02:16 +02:00
|
|
|
r.x = p_menu->x1+2/RATIO;
|
|
|
|
r.y = p_menu->y1 + line_height +y;
|
|
|
|
if ((draw_scr)&&(RATIO==1)) r.w = 365; //Only in 640 mode
|
|
|
|
else r.w = p_menu->x2 - p_menu->x1-4/RATIO;
|
|
|
|
r.h = line_height;
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
if (sel < 0)
|
2014-04-11 14:26:02 +02:00
|
|
|
menu_print_font(screen, 0x40,0x40,0x40, //Not used
|
2013-01-19 13:36:36 +01:00
|
|
|
x_start, y_start + y, msg, font_size, max_string);
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (p_menu->cur_sel == i) /* Selected - color */
|
2013-03-16 08:58:25 +01:00
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 255, 255));
|
2013-03-16 08:58:25 +01:00
|
|
|
if (msg[0] == ']')
|
2014-04-25 14:08:36 +02:00
|
|
|
menu_print_font(screen, 255,0,0, //Selected menu entry begining with ']' (tape browser)
|
2013-03-16 08:58:25 +01:00
|
|
|
x_start, y_start + y, msg+1, font_size,max_string ); //do not show ']'
|
2014-04-19 19:02:16 +02:00
|
|
|
else
|
|
|
|
menu_print_font(screen, 0,0,0, //Selected menu entry
|
2013-01-19 13:36:36 +01:00
|
|
|
x_start, y_start + y, msg, font_size,max_string );
|
2014-04-19 19:02:16 +02:00
|
|
|
|
2013-01-03 08:34:16 +01:00
|
|
|
selected_file = msg;
|
|
|
|
}
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (IS_SUBMENU(msg))
|
|
|
|
{
|
|
|
|
if (p_menu->cur_sel == i-1)
|
2014-04-19 19:02:16 +02:00
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 255, 255));
|
2014-04-19 19:02:16 +02:00
|
|
|
menu_print_font(screen, 0,0,0, //Selected sub menu entry
|
2013-01-19 13:36:36 +01:00
|
|
|
x_start, y_start + y, msg, font_size, max_string);
|
2014-04-19 19:02:16 +02:00
|
|
|
}
|
2012-07-29 10:39:21 +02:00
|
|
|
else
|
2014-04-19 19:02:16 +02:00
|
|
|
menu_print_font(screen, 255,255,255, //Non selected sub menu entry
|
2013-01-19 13:36:36 +01:00
|
|
|
x_start, y_start + y, msg, font_size, max_string);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
else if (msg[0] == '#')
|
|
|
|
{
|
|
|
|
switch (msg[1])
|
|
|
|
{
|
|
|
|
case '1':
|
2014-04-25 14:08:36 +02:00
|
|
|
menu_print_font(screen, 255,255,0, //Text 1
|
2013-01-19 13:36:36 +01:00
|
|
|
x_start, y_start + y, msg+2, font_size, max_string);
|
2012-07-29 10:39:21 +02:00
|
|
|
break;
|
|
|
|
case '2':
|
2014-04-19 19:02:16 +02:00
|
|
|
menu_print_font(screen, 255,255,255, //Text 2
|
2013-01-19 13:36:36 +01:00
|
|
|
x_start, y_start + y, msg+2, font_size, max_string);
|
2012-07-29 10:39:21 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
menu_print_font(screen, 0x40,0x40,0x40,
|
2013-01-19 13:36:36 +01:00
|
|
|
x_start, y_start + y, msg, font_size, max_string);
|
2012-07-29 10:39:21 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-03-16 08:58:25 +01:00
|
|
|
else if (msg[0] == ']')
|
2014-04-25 14:08:36 +02:00
|
|
|
menu_print_font(screen, 255,0,0, //Non selected menu entry starting with ']' (tape browser)
|
2013-03-16 08:58:25 +01:00
|
|
|
x_start, y_start + y, msg+1, font_size, max_string);
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
else /* Otherwise white */
|
2014-04-19 19:02:16 +02:00
|
|
|
menu_print_font(screen, 255,255,255, //Non selected menu entry
|
2013-01-19 13:36:36 +01:00
|
|
|
x_start, y_start + y, msg, font_size, max_string);
|
2012-07-29 10:39:21 +02:00
|
|
|
if (IS_SUBMENU(msg))
|
|
|
|
{
|
|
|
|
submenu_t *p_submenu = find_submenu(p_menu, i);
|
|
|
|
int n_pipe = 0;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
for (n=0; msg[n] != '\0'; n++)
|
|
|
|
{
|
|
|
|
/* Underline the selected entry */
|
|
|
|
if (msg[n] == '|')
|
|
|
|
{
|
|
|
|
int16_t n_chars;
|
|
|
|
|
|
|
|
for (n_chars = 1; msg[n+n_chars] && msg[n+n_chars] != '|'; n_chars++);
|
|
|
|
|
|
|
|
n_pipe++;
|
|
|
|
if (p_submenu->sel == n_pipe-1)
|
|
|
|
{
|
|
|
|
int w;
|
|
|
|
int h;
|
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
if (TTF_SizeText(p_menu->p_font, "Z", &w, &h) < 0)
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", TTF_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
r = (SDL_Rect){ x_start + (n+1) * w-2/RATIO, y_start + (i+ 1 - p_menu->start_entry_visible) *line_height -8/RATIO, (n_chars - 1) * w, 2/RATIO};
|
2012-07-29 10:39:21 +02:00
|
|
|
if (p_menu->cur_sel == i-1)
|
|
|
|
SDL_FillRect(screen, &r,
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_MapRGB(screen->format, 255,0,0)); //Underline selected text
|
2012-07-29 10:39:21 +02:00
|
|
|
else
|
|
|
|
SDL_FillRect(screen, &r,
|
2014-04-19 19:02:16 +02:00
|
|
|
SDL_MapRGB(screen->format, 255,255,255));//Underline non selected text
|
2012-07-29 10:39:21 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-01-03 08:34:16 +01:00
|
|
|
|
|
|
|
if ((draw_scr)&&(RATIO==1)) //Only in 640 mode
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
r.x = 367;
|
|
|
|
r.y = 39;
|
|
|
|
r.w = 2;
|
|
|
|
r.h = 423;
|
|
|
|
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 255, 0)); //Frame for scr preview
|
2014-04-19 19:02:16 +02:00
|
|
|
r.x = 369;
|
|
|
|
r.y = 249;
|
|
|
|
r.w = 270;
|
|
|
|
r.h = 2;
|
|
|
|
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 255, 0)); //Frame for scr preview
|
2013-01-19 13:36:36 +01:00
|
|
|
|
2013-01-03 08:34:16 +01:00
|
|
|
if ((!selected_file)||(selected_file[0] == '[')) return; //No dir
|
|
|
|
|
|
|
|
|
|
|
|
// Select after "/"
|
|
|
|
if (strrchr(selected_file, '/'))
|
|
|
|
strcpy(name, strrchr(selected_file, '/') + 1);
|
|
|
|
else strcpy(name,selected_file);
|
|
|
|
|
|
|
|
if ((ext_matches(name, ".zip")||ext_matches(name, ".ZIP")))
|
|
|
|
{
|
|
|
|
//remove the zip extension
|
|
|
|
ptr = strrchr (name, '.');
|
|
|
|
if (ptr) *ptr = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//remove the other extensions
|
|
|
|
ptr = strrchr (name, '.');
|
|
|
|
if (ptr) *ptr = 0;
|
|
|
|
|
2013-01-20 13:42:14 +01:00
|
|
|
//Always load from Default device
|
2013-01-03 08:34:16 +01:00
|
|
|
strcpy(filename,getenv("HOME"));
|
|
|
|
length=strlen(filename);
|
|
|
|
if ((length>0)&&(filename[length-1]!='/'))
|
|
|
|
strcat(filename,"/");
|
|
|
|
strcat(filename, "scr/");
|
|
|
|
strcat(filename, name);
|
|
|
|
strcat(filename, ".scr");
|
2013-01-19 13:36:36 +01:00
|
|
|
draw_scr_file(375,48, filename);
|
2013-01-03 08:34:16 +01:00
|
|
|
|
|
|
|
strcpy(filename,getenv("HOME"));
|
|
|
|
length=strlen(filename);
|
|
|
|
if ((length>0)&&(filename[length-1]!='/'))
|
|
|
|
strcat(filename,"/");
|
|
|
|
strcat(filename, "scr2/");
|
|
|
|
strcat(filename, name);
|
|
|
|
strcat(filename, ".scr");
|
2014-04-19 19:02:16 +02:00
|
|
|
draw_scr_file(375,260, filename);
|
2013-01-03 08:34:16 +01:00
|
|
|
}
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int get_next_seq_y(menu_t *p_menu, int v, int dy, int cicle)
|
|
|
|
{
|
|
|
|
if (v + dy < 0)
|
|
|
|
{if (cicle) return (p_menu->n_entries - 1); else return 0;}
|
|
|
|
|
|
|
|
if (v + dy > p_menu->n_entries - 1)
|
|
|
|
{if (cicle) return 0; else return (p_menu->n_entries - 1);}
|
|
|
|
return v + dy;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void select_next(menu_t *p_menu, int dx, int dy, int cicle)
|
|
|
|
{
|
|
|
|
int next;
|
|
|
|
|
|
|
|
|
|
|
|
p_menu->cur_sel = get_next_seq_y(p_menu, p_menu->cur_sel, dy, cicle);
|
|
|
|
next = get_next_seq_y(p_menu, p_menu->cur_sel, dy + 1, cicle);
|
2014-01-19 22:05:51 +01:00
|
|
|
if (IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel])&&(dy!=1)&&(dy!=-1)) p_menu->cur_sel--;
|
2012-07-29 10:39:21 +02:00
|
|
|
if (p_menu->pp_msgs[p_menu->cur_sel][0] == ' ' ||
|
|
|
|
p_menu->pp_msgs[p_menu->cur_sel][0] == '#' ||
|
|
|
|
IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel]) )
|
|
|
|
select_next(p_menu, dx, dy, cicle);
|
|
|
|
|
|
|
|
/* If the next is a submenu */
|
|
|
|
if (dx != 0 && IS_SUBMENU(p_menu->pp_msgs[next]))
|
|
|
|
{
|
|
|
|
submenu_t *p_submenu = find_submenu(p_menu, next);
|
|
|
|
|
|
|
|
p_submenu->sel = (p_submenu->sel + dx) < 0 ? p_submenu->n_entries - 1 :
|
|
|
|
(p_submenu->sel + dx) % p_submenu->n_entries;
|
|
|
|
}
|
|
|
|
else if (dx == -1 && !strcmp(p_menu->pp_msgs[0], "[..]"))
|
|
|
|
p_menu->cur_sel = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void select_one(menu_t *p_menu, int sel)
|
|
|
|
{
|
|
|
|
if (sel >= p_menu->n_entries)
|
|
|
|
sel = 0;
|
|
|
|
p_menu->cur_sel = sel;
|
|
|
|
if (p_menu->pp_msgs[p_menu->cur_sel][0] == ' ' ||
|
|
|
|
p_menu->pp_msgs[p_menu->cur_sel][0] == '#' ||
|
|
|
|
IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel]))
|
|
|
|
select_next(p_menu, 0, 1 , 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
static int is_submenu_title(menu_t *p_menu, int n)
|
|
|
|
{
|
|
|
|
if (n+1 >= p_menu->n_entries)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return IS_SUBMENU(p_menu->pp_msgs[n+1]);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void menu_init_internal(menu_t *p_menu, const char *title,
|
|
|
|
TTF_Font *p_font, const char **pp_msgs,
|
|
|
|
int16_t x1, int16_t y1, int16_t x2, int16_t y2)
|
|
|
|
{
|
|
|
|
int submenu;
|
|
|
|
int j;
|
|
|
|
|
|
|
|
memset(p_menu, 0, sizeof(menu_t));
|
|
|
|
|
|
|
|
p_menu->pp_msgs = pp_msgs;
|
|
|
|
p_menu->p_font = p_font;
|
|
|
|
p_menu->x1 = x1;
|
|
|
|
p_menu->y1 = y1;
|
|
|
|
p_menu->x2 = x2;
|
|
|
|
p_menu->y2 = y2;
|
|
|
|
|
|
|
|
p_menu->text_w = 0;
|
|
|
|
p_menu->n_submenus = 0;
|
|
|
|
strcpy(p_menu->title, title);
|
|
|
|
|
|
|
|
for (p_menu->n_entries = 0; p_menu->pp_msgs[p_menu->n_entries]; p_menu->n_entries++)
|
|
|
|
{
|
|
|
|
int text_w_font;
|
|
|
|
|
|
|
|
/* Is this a submenu? */
|
|
|
|
if (IS_SUBMENU(p_menu->pp_msgs[p_menu->n_entries]))
|
|
|
|
{
|
|
|
|
p_menu->n_submenus++;
|
|
|
|
continue; /* Length of submenus is unimportant */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TTF_SizeText(p_font, p_menu->pp_msgs[p_menu->n_entries], &text_w_font, NULL) != 0)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", TTF_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (text_w_font > p_menu->text_w)
|
|
|
|
p_menu->text_w = text_w_font;
|
|
|
|
}
|
|
|
|
if (p_menu->text_w > p_menu->x2 - p_menu->x1)
|
|
|
|
p_menu->text_w = p_menu->x2 - p_menu->x1;
|
|
|
|
|
|
|
|
if ( !(p_menu->p_submenus = (submenu_t *)malloc(sizeof(submenu_t) * p_menu->n_submenus)) )
|
|
|
|
{
|
|
|
|
perror("malloc failed!\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
j=0;
|
|
|
|
submenu = 0;
|
|
|
|
for (; j < p_menu->n_entries; j++)
|
|
|
|
{
|
|
|
|
if (IS_SUBMENU(p_menu->pp_msgs[j]))
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
|
|
|
|
p_menu->p_submenus[submenu].index = j;
|
|
|
|
p_menu->p_submenus[submenu].sel = 0;
|
|
|
|
p_menu->p_submenus[submenu].n_entries = 0;
|
|
|
|
for (n=0; p_menu->pp_msgs[j][n] != '\0'; n++)
|
|
|
|
{
|
|
|
|
if (p_menu->pp_msgs[j][n] == '|')
|
|
|
|
p_menu->p_submenus[submenu].n_entries++;
|
|
|
|
}
|
|
|
|
submenu++;
|
|
|
|
}
|
|
|
|
}
|
2014-04-19 19:02:16 +02:00
|
|
|
p_menu->text_h = p_menu->n_entries * (TTF_FontHeight(p_font) + TTF_FontHeight(p_font) / 2);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void menu_fini(menu_t *p_menu)
|
|
|
|
{
|
|
|
|
free(p_menu->p_submenus);
|
|
|
|
}
|
|
|
|
|
2013-01-16 21:07:44 +01:00
|
|
|
uint32_t menu_wait_key_press()
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
|
|
|
SDL_Event ev;
|
|
|
|
uint32_t keys = 0;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
int i, hats, nr;
|
|
|
|
SDL_Joystick *joy;
|
|
|
|
static int joy_keys_changed;
|
|
|
|
static int joy_keys_last;
|
2012-12-27 16:39:35 +01:00
|
|
|
static int joy_bottons_last[2][8];
|
2012-07-29 10:39:21 +02:00
|
|
|
SDL_JoystickUpdate();
|
2013-01-05 07:43:46 +01:00
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
/* Wii-specific, sorry */
|
|
|
|
for (nr = 0; nr < ordenador.joystick_number; nr++) {
|
|
|
|
joy = ordenador.joystick_sdl[nr];
|
|
|
|
if (!joy)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
hats = SDL_JoystickNumHats (joy);
|
|
|
|
for (i = 0; i < hats; i++) {
|
|
|
|
Uint8 v = SDL_JoystickGetHat (joy, i);
|
|
|
|
|
|
|
|
if (v & SDL_HAT_UP)
|
|
|
|
keys |= KEY_UP;
|
|
|
|
if (v & SDL_HAT_DOWN)
|
|
|
|
keys |= KEY_DOWN;
|
|
|
|
if (v & SDL_HAT_LEFT)
|
|
|
|
keys |= KEY_LEFT;
|
|
|
|
if (v & SDL_HAT_RIGHT)
|
|
|
|
keys |= KEY_RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sint16 axis0 = SDL_JoystickGetAxis(joy, 0);
|
|
|
|
Sint16 axis1 = SDL_JoystickGetAxis(joy, 1);
|
|
|
|
|
|
|
|
if ( axis0 < -15000 ) keys |= KEY_LEFT;
|
|
|
|
else if (axis0 > 15000 ) keys |= KEY_RIGHT;
|
|
|
|
|
|
|
|
if (axis1 < -15000 ) keys |= KEY_UP;
|
|
|
|
else if( axis1 > 15000 ) keys |= KEY_DOWN;
|
|
|
|
|
|
|
|
|
2012-12-30 18:52:21 +01:00
|
|
|
if ((!SDL_JoystickGetButton(joy, 0) && joy_bottons_last[nr][0]) || /* A */
|
|
|
|
(!SDL_JoystickGetButton(joy, 3) && joy_bottons_last[nr][1]) || /* 2 */
|
2012-07-29 10:39:21 +02:00
|
|
|
(!SDL_JoystickGetButton(joy, 9) && joy_bottons_last[nr][2]) || /* CA */
|
|
|
|
(!SDL_JoystickGetButton(joy, 10) && joy_bottons_last[nr][3])) /* CB */
|
|
|
|
keys |= KEY_SELECT;
|
|
|
|
if ((!SDL_JoystickGetButton(joy, 2) && joy_bottons_last[nr][4]) || /* 1 */
|
|
|
|
(!SDL_JoystickGetButton(joy, 11) && joy_bottons_last[nr][5]) || /* CX */
|
2012-12-27 16:39:35 +01:00
|
|
|
(!SDL_JoystickGetButton(joy, 12) && joy_bottons_last[nr][6])|| /* CY */
|
|
|
|
(!SDL_JoystickGetButton(joy, 1) && joy_bottons_last[nr][7])) /* B */
|
2012-07-29 10:39:21 +02:00
|
|
|
keys |= KEY_ESCAPE;
|
|
|
|
if (SDL_JoystickGetButton(joy, 5) != 0 || /* + */
|
|
|
|
SDL_JoystickGetButton(joy, 18) != 0) /* C+ */
|
|
|
|
keys |= KEY_PAGEUP;
|
|
|
|
if (SDL_JoystickGetButton(joy, 4) != 0 || /* - */
|
|
|
|
SDL_JoystickGetButton(joy, 17) != 0) /* C- */
|
|
|
|
keys |= KEY_PAGEDOWN;
|
|
|
|
|
|
|
|
joy_bottons_last[nr][0]=SDL_JoystickGetButton(joy, 0) ; /* A */
|
|
|
|
joy_bottons_last[nr][1] =SDL_JoystickGetButton(joy, 3) ; /* 2 */
|
|
|
|
joy_bottons_last[nr][2] =SDL_JoystickGetButton(joy, 9) ; /* CA */
|
|
|
|
joy_bottons_last[nr][3] =SDL_JoystickGetButton(joy, 10) ; /* CB */
|
|
|
|
joy_bottons_last[nr][4] =SDL_JoystickGetButton(joy, 2) ; /* 1 */
|
|
|
|
joy_bottons_last[nr][5] =SDL_JoystickGetButton(joy, 11) ; /* CX */
|
|
|
|
joy_bottons_last[nr][6] =SDL_JoystickGetButton(joy, 12) ; /* CY */
|
2012-12-27 16:39:35 +01:00
|
|
|
joy_bottons_last[nr][7] =SDL_JoystickGetButton(joy, 1) ; /* B */
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
joy_keys_changed = keys != joy_keys_last;
|
|
|
|
joy_keys_last = keys;
|
|
|
|
if (!joy_keys_changed)
|
|
|
|
keys = 0;
|
|
|
|
|
|
|
|
if (SDL_PollEvent(&ev))
|
|
|
|
{
|
|
|
|
switch(ev.type)
|
|
|
|
{
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
switch (ev.key.keysym.sym)
|
|
|
|
{
|
|
|
|
case SDLK_UP:
|
|
|
|
keys |= KEY_UP;
|
|
|
|
break;
|
|
|
|
case SDLK_DOWN:
|
|
|
|
keys |= KEY_DOWN;
|
|
|
|
break;
|
|
|
|
case SDLK_LEFT:
|
|
|
|
keys |= KEY_LEFT;
|
|
|
|
break;
|
|
|
|
case SDLK_RIGHT:
|
|
|
|
keys |= KEY_RIGHT;
|
|
|
|
break;
|
|
|
|
case SDLK_PAGEDOWN:
|
|
|
|
keys |= KEY_PAGEDOWN;
|
|
|
|
break;
|
|
|
|
case SDLK_PAGEUP:
|
|
|
|
keys |= KEY_PAGEUP;
|
|
|
|
break;
|
|
|
|
case SDLK_HOME:
|
|
|
|
case SDLK_ESCAPE:
|
|
|
|
keys |= KEY_ESCAPE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
SDL sound, compile against MINGW (VK, fopen binary files, menu key calls FBZX Wii menu, return key active on KEYUP), 2 bugs in 128k snap format, turbo N in line command, separated code for normal and precise emulation, toggle full screen in FBZX menu, removed snow effect in normal emulation, changed save tape routine, fixed 2 bugs in z80, changed SP call in z80
2013-04-06 16:45:45 +02:00
|
|
|
case SDL_KEYUP:
|
|
|
|
switch (ev.key.keysym.sym)
|
|
|
|
{
|
|
|
|
case SDLK_RETURN:
|
|
|
|
case SDLK_SPACE:
|
|
|
|
keys |= KEY_SELECT;
|
2012-07-29 10:39:21 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
SDL sound, compile against MINGW (VK, fopen binary files, menu key calls FBZX Wii menu, return key active on KEYUP), 2 bugs in 128k snap format, turbo N in line command, separated code for normal and precise emulation, toggle full screen in FBZX menu, removed snow effect in normal emulation, changed save tape routine, fixed 2 bugs in z80, changed SP call in z80
2013-04-06 16:45:45 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_QUIT:
|
|
|
|
exit(0);
|
|
|
|
break;
|
|
|
|
#ifndef GEKKO
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
if (ev.button.button==SDL_BUTTON_LEFT) keys |= KEY_SELECT;
|
2012-07-29 10:39:21 +02:00
|
|
|
break;
|
SDL sound, compile against MINGW (VK, fopen binary files, menu key calls FBZX Wii menu, return key active on KEYUP), 2 bugs in 128k snap format, turbo N in line command, separated code for normal and precise emulation, toggle full screen in FBZX menu, removed snow effect in normal emulation, changed save tape routine, fixed 2 bugs in z80, changed SP call in z80
2013-04-06 16:45:45 +02:00
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (keys != 0)
|
|
|
|
break;
|
2012-12-27 16:39:35 +01:00
|
|
|
SDL_Delay(50);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
return keys;
|
|
|
|
}
|
|
|
|
|
2013-02-10 14:08:05 +01:00
|
|
|
extern char curdir[MAX_PATH_LENGTH];
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
static int menu_select_internal(SDL_Surface *screen,
|
|
|
|
menu_t *p_menu, int *p_submenus, int sel,
|
|
|
|
void (*select_next_cb)(menu_t *p, void *data),
|
2013-01-03 08:34:16 +01:00
|
|
|
void *select_next_cb_data, int font_size, int draw_scr)
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < p_menu->n_submenus; i++)
|
|
|
|
p_menu->p_submenus[i].sel = p_submenus[i];
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
SDL_Rect r = {p_menu->x1, p_menu->y1,
|
|
|
|
p_menu->x2 - p_menu->x1, p_menu->y2 - p_menu->y1};
|
2014-04-19 19:02:16 +02:00
|
|
|
SDL_Rect r_int = {p_menu->x1+2/RATIO, p_menu->y1+2/RATIO,
|
|
|
|
p_menu->x2 - p_menu->x1-4/RATIO, p_menu->y2 - p_menu->y1-4/RATIO};
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
uint32_t keys;
|
|
|
|
int sel_last = p_menu->cur_sel;
|
|
|
|
|
2014-04-25 14:08:36 +02:00
|
|
|
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 255, 0));
|
2014-04-19 19:02:16 +02:00
|
|
|
SDL_FillRect(screen, &r_int, SDL_MapRGB(screen->format, 0, 0, 0));
|
2014-04-25 14:08:36 +02:00
|
|
|
|
|
|
|
if (strcmp(p_menu->title, "Select block")&&strcmp(p_menu->title, "Select program")
|
|
|
|
&&strncmp(p_menu->title, "Selected file:",14)&&strcmp(p_menu->title, "Select file"))
|
|
|
|
{
|
|
|
|
SDL_Rect dst_rect = {410/RATIO, 70/RATIO, 0, 0};
|
|
|
|
if (RATIO == 1) SDL_BlitSurface(image_stripes, NULL, screen, &dst_rect);
|
|
|
|
else SDL_BlitSurface(image_stripes_small, NULL, screen, &dst_rect);
|
|
|
|
}
|
|
|
|
|
2013-01-03 08:34:16 +01:00
|
|
|
menu_draw(screen, p_menu, 0, font_size, draw_scr);
|
2012-07-29 10:39:21 +02:00
|
|
|
SDL_Flip(screen);
|
|
|
|
|
2013-01-16 21:07:44 +01:00
|
|
|
keys = menu_wait_key_press();
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
if (keys & KEY_UP)
|
2014-04-25 14:08:36 +02:00
|
|
|
{select_next(p_menu, 0, -1, 1);play_click(0);}
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (keys & KEY_DOWN)
|
2014-04-25 14:08:36 +02:00
|
|
|
{select_next(p_menu, 0, 1, 1);play_click(0);}
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (keys & KEY_PAGEUP)
|
2014-04-25 14:08:36 +02:00
|
|
|
{select_next(p_menu, 0, -19, 0);play_click(0);}
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (keys & KEY_PAGEDOWN)
|
2014-04-25 14:08:36 +02:00
|
|
|
{select_next(p_menu, 0, 19, 0);play_click(0);}
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (keys & KEY_LEFT)
|
2014-04-25 14:08:36 +02:00
|
|
|
{select_next(p_menu, -1, 0 ,1);play_click(0);}
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (keys & KEY_RIGHT)
|
2014-04-25 14:08:36 +02:00
|
|
|
{select_next(p_menu, 1, 0 ,1);play_click(0);}
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (keys & KEY_ESCAPE)
|
2014-04-25 14:08:36 +02:00
|
|
|
{play_click(2);break;}
|
2012-07-29 10:39:21 +02:00
|
|
|
else if (keys & KEY_SELECT)
|
|
|
|
{
|
|
|
|
ret = p_menu->cur_sel;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0; i<p_menu->n_submenus; i++)
|
|
|
|
p_submenus[i] = p_menu->p_submenus[i].sel;
|
2014-04-25 14:08:36 +02:00
|
|
|
play_click(1);
|
2012-07-29 10:39:21 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Invoke the callback when an entry is selected */
|
|
|
|
if (sel_last != p_menu->cur_sel &&
|
|
|
|
select_next_cb != NULL)
|
|
|
|
select_next_cb(p_menu, select_next_cb_data);
|
|
|
|
}
|
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
//SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
|
2012-07-29 10:39:21 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int menu_select_sized(const char *title, const char **msgs, int *submenus, int sel,
|
|
|
|
int x, int y, int x2, int y2,
|
|
|
|
void (*select_next_cb)(menu_t *p, void *data),
|
2013-01-03 08:34:16 +01:00
|
|
|
void *select_next_cb_data, int font_size, int draw_scr)
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
menu_t menu;
|
|
|
|
int out;
|
|
|
|
|
|
|
|
if (FULL_DISPLAY_X == 640)
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
if (font_size == 16) menu_init_internal(&menu, title, menu_font_alt_large, msgs, x, y, x2, y2);
|
|
|
|
else menu_init_internal(&menu, title, menu_font_large, msgs, x, y, x2, y2);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
if (font_size == 16) menu_init_internal(&menu, title, menu_font_alt_small, msgs, x, y, x2, y2);
|
|
|
|
else menu_init_internal(&menu, title, menu_font_small, msgs, x, y, x2, y2);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sel >= 0)
|
|
|
|
select_one(&menu, sel);
|
|
|
|
out = menu_select_internal(real_screen, &menu, submenus, sel,
|
2013-01-03 08:34:16 +01:00
|
|
|
select_next_cb, select_next_cb_data, font_size, draw_scr);
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
menu_fini(&menu);
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
int menu_select_title(const char *title, const char **msgs, int *submenus)
|
|
|
|
{
|
|
|
|
SDL_FillRect(real_screen, 0, SDL_MapRGB(real_screen->format, 0, 0, 0));
|
|
|
|
return menu_select_sized(title, msgs, submenus, 0,
|
2014-04-19 19:02:16 +02:00
|
|
|
0, 48/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y-48/RATIO,
|
2013-01-03 08:34:16 +01:00
|
|
|
NULL, NULL, 20, 0);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int menu_select(const char **msgs, int *submenus)
|
|
|
|
{
|
|
|
|
return menu_select_title("", msgs, submenus);
|
|
|
|
}
|
|
|
|
|
2012-08-26 18:04:12 +02:00
|
|
|
static const char *menu_select_file_internal_zip(char *path,
|
2013-01-03 08:34:16 +01:00
|
|
|
int x, int y, int x2, int y2, const char *selected_file, int draw_scr)
|
2012-08-26 18:04:12 +02:00
|
|
|
{
|
|
|
|
const char **file_list = get_file_list_zip(path);
|
|
|
|
char *sel;
|
|
|
|
const char *ptr_selected_file;
|
|
|
|
int opt;
|
|
|
|
int i;
|
|
|
|
int err;
|
2014-04-25 14:08:36 +02:00
|
|
|
char buf[80];
|
2012-08-26 18:04:12 +02:00
|
|
|
|
|
|
|
if (file_list == NULL) {free(path); return NULL;}
|
|
|
|
|
|
|
|
if (selected_file)
|
|
|
|
{
|
|
|
|
ptr_selected_file= strrchr(selected_file,'/');
|
|
|
|
if (ptr_selected_file) ptr_selected_file++;
|
|
|
|
else ptr_selected_file = selected_file;
|
2014-04-25 14:08:36 +02:00
|
|
|
snprintf(buf,80,"Selected file:%s",ptr_selected_file);
|
2013-01-03 08:34:16 +01:00
|
|
|
opt = menu_select_sized(buf, file_list, NULL, 0, x, y, x2, y2, NULL, NULL, 16, draw_scr);
|
2012-08-26 18:04:12 +02:00
|
|
|
}
|
2013-01-03 08:34:16 +01:00
|
|
|
else opt = menu_select_sized("Select file", file_list, NULL, 0, x, y, x2, y2, NULL, NULL ,16, draw_scr);
|
2012-08-26 18:04:12 +02:00
|
|
|
|
2014-03-22 19:56:52 +01:00
|
|
|
sel = NULL;
|
2012-08-26 18:04:12 +02:00
|
|
|
|
2014-03-22 19:56:52 +01:00
|
|
|
if (opt >= 0) sel = strdup(file_list[opt]);
|
2012-08-26 18:04:12 +02:00
|
|
|
|
|
|
|
/* Cleanup everything - file_list is NULL-terminated */
|
|
|
|
for ( i = 0; file_list[i]; i++ )
|
|
|
|
free((void*)file_list[i]);
|
|
|
|
free(file_list);
|
2014-03-22 19:56:52 +01:00
|
|
|
|
|
|
|
if (opt < 0) {free(path); return NULL;}
|
2012-08-26 18:04:12 +02:00
|
|
|
|
|
|
|
if (!sel) {free(path); return NULL;}
|
|
|
|
|
|
|
|
if (opt==0||opt==1) {free(path); return sel;} //"None" or "[..]"
|
|
|
|
|
|
|
|
unzFile uf = unzOpen(path);
|
|
|
|
|
|
|
|
if (unzLocateFile (uf, sel, 1)!= UNZ_OK) {printf ("File not found in zip/n"); unzClose(path); free(path);free (sel);return NULL;}
|
|
|
|
|
|
|
|
free(path); //It does need anymore
|
|
|
|
|
|
|
|
char* filename_withoutpath;
|
|
|
|
char* write_filename;
|
|
|
|
char* p;
|
|
|
|
|
|
|
|
p = filename_withoutpath = sel;
|
|
|
|
while ((*p) != '\0')
|
|
|
|
{
|
|
|
|
if (((*p)=='/') || ((*p)=='\\'))
|
|
|
|
filename_withoutpath = p+1;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*filename_withoutpath)=='\0') filename_withoutpath = sel;
|
|
|
|
|
|
|
|
write_filename = (char*)malloc(strlen(path_tmp) + strlen(filename_withoutpath) + 4);
|
|
|
|
|
|
|
|
snprintf(write_filename, strlen(path_tmp) + strlen(filename_withoutpath) + 4, "%s/%s", path_tmp, filename_withoutpath);
|
|
|
|
|
|
|
|
err = unzOpenCurrentFile(uf);
|
|
|
|
if (err!=UNZ_OK)
|
|
|
|
{
|
|
|
|
printf("error %d with zipfile in unzOpenCurrentFile\n",err);
|
|
|
|
}
|
|
|
|
|
|
|
|
void* buf2;
|
|
|
|
unsigned int size_buf = 8192;
|
|
|
|
FILE *fout=NULL;
|
|
|
|
|
|
|
|
buf2 = (void*)malloc(size_buf);
|
|
|
|
if (buf2==NULL)
|
|
|
|
{
|
|
|
|
printf("Error allocating memory\n");
|
|
|
|
free(sel);
|
|
|
|
free(write_filename);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//unlink(write_filename);
|
|
|
|
|
|
|
|
fout=fopen(write_filename,"wb");
|
|
|
|
|
|
|
|
if (fout!=NULL)
|
|
|
|
{
|
|
|
|
printf("Extracting: %s in %s\n",sel, write_filename);
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
err = unzReadCurrentFile(uf,buf2,size_buf);
|
|
|
|
if (err<0)
|
|
|
|
{
|
|
|
|
printf("Error %d with zipfile in unzReadCurrentFile\n",err);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (err>0)
|
|
|
|
if (fwrite(buf2,err,1,fout)!=1)
|
|
|
|
{
|
|
|
|
printf("Error in writing extracted file\n");
|
|
|
|
err=UNZ_ERRNO;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (err>0);
|
|
|
|
|
|
|
|
if (fout) fclose(fout);
|
|
|
|
}
|
|
|
|
|
2014-03-22 19:56:52 +01:00
|
|
|
unzCloseCurrentFile(uf);
|
|
|
|
unzClose (uf);
|
2012-08-26 18:04:12 +02:00
|
|
|
free(buf2);
|
|
|
|
free(sel);
|
|
|
|
|
|
|
|
return write_filename;
|
|
|
|
}
|
|
|
|
|
2013-03-16 08:58:25 +01:00
|
|
|
const char **get_file_list_browser(unsigned int tape_pos, unsigned int *block_pos)
|
|
|
|
{
|
|
|
|
unsigned int loop;
|
|
|
|
char **browser_list_menu;
|
|
|
|
|
2013-03-19 08:26:39 +01:00
|
|
|
*block_pos=0;
|
|
|
|
|
2013-03-16 08:58:25 +01:00
|
|
|
browser_list_menu = (char**)malloc((MAX_BROWSER_ITEM+1) * sizeof(char*));
|
|
|
|
browser_list_menu[0] = NULL;
|
|
|
|
|
|
|
|
for(loop=0;browser_list[loop]!=NULL;loop++)
|
|
|
|
{
|
2013-03-19 08:26:39 +01:00
|
|
|
browser_list_menu[loop]=malloc(24+36+9);
|
2013-03-16 08:58:25 +01:00
|
|
|
if (browser_list[loop]->position==tape_pos)
|
|
|
|
{
|
2013-03-19 08:26:39 +01:00
|
|
|
sprintf(browser_list_menu[loop],"]%04d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info);
|
2013-03-16 08:58:25 +01:00
|
|
|
*block_pos=loop;
|
|
|
|
}
|
|
|
|
else
|
2013-03-19 08:26:39 +01:00
|
|
|
sprintf(browser_list_menu[loop],"%04d %s %s",loop,browser_list[loop]->block_type, browser_list[loop]->info);
|
2013-03-16 08:58:25 +01:00
|
|
|
}
|
|
|
|
browser_list_menu[loop]=NULL;
|
|
|
|
return (const char **) browser_list_menu;
|
|
|
|
}
|
|
|
|
|
2013-03-19 08:26:39 +01:00
|
|
|
const char **get_file_list_select_block()
|
|
|
|
{
|
|
|
|
unsigned int loop;
|
|
|
|
char **block_list_menu;
|
|
|
|
|
|
|
|
block_list_menu = (char**)malloc((MAX_SELECT_ITEM+1) * sizeof(char*));
|
|
|
|
block_list_menu[0] = NULL;
|
|
|
|
|
|
|
|
for(loop=0;block_select_list[loop]!=NULL;loop++)
|
|
|
|
{
|
|
|
|
block_list_menu[loop]=malloc(32);
|
|
|
|
sprintf(block_list_menu[loop],"%02d %s",loop, block_select_list[loop]->info);
|
|
|
|
}
|
|
|
|
block_list_menu[loop]=NULL;
|
|
|
|
return (const char **) block_list_menu;
|
|
|
|
}
|
|
|
|
|
2013-01-18 17:23:46 +01:00
|
|
|
static const char *menu_select_file_internal(char *dir_path,
|
2013-03-16 08:58:25 +01:00
|
|
|
int x, int y, int x2, int y2, const char *selected_file, int draw_scr, unsigned int tape_pos)
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
2013-03-16 08:58:25 +01:00
|
|
|
const char **file_list;
|
2012-07-29 10:39:21 +02:00
|
|
|
char *sel;
|
|
|
|
char *out;
|
2012-08-26 18:04:12 +02:00
|
|
|
char *out_zip;
|
2012-07-29 10:39:21 +02:00
|
|
|
const char *ptr_selected_file;
|
2013-01-18 17:23:46 +01:00
|
|
|
char *updir;
|
2012-07-29 10:39:21 +02:00
|
|
|
int opt;
|
|
|
|
int i;
|
2014-04-19 19:02:16 +02:00
|
|
|
char buf[80];
|
2013-03-16 08:58:25 +01:00
|
|
|
unsigned int block_pos;
|
|
|
|
|
2013-03-19 08:26:39 +01:00
|
|
|
if (!strcmp(dir_path,"browser")) file_list = get_file_list_browser(tape_pos, &block_pos);
|
|
|
|
else if (!strcmp(dir_path,"select_block")) file_list = get_file_list_select_block();
|
|
|
|
else file_list = get_file_list(dir_path);
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
if (file_list == NULL)
|
|
|
|
return NULL;
|
2013-03-16 08:58:25 +01:00
|
|
|
|
2013-03-19 08:26:39 +01:00
|
|
|
if (!strcmp(dir_path,"browser")) opt = menu_select_sized("Select block", file_list, NULL, block_pos, x, y, x2, y2, NULL, NULL ,16, 0);
|
|
|
|
else if (!strcmp(dir_path,"select_block")) opt = menu_select_sized("Select program", file_list, NULL, 0, x, y, x2, y2, NULL, NULL ,16, 0);
|
2013-03-16 08:58:25 +01:00
|
|
|
else if (selected_file)
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
|
|
|
ptr_selected_file= strrchr(selected_file,'/');
|
|
|
|
if (ptr_selected_file) ptr_selected_file++;
|
|
|
|
else ptr_selected_file = selected_file;
|
2014-04-19 19:02:16 +02:00
|
|
|
snprintf(buf,80,"Selected file:%s",ptr_selected_file);
|
2013-01-03 08:34:16 +01:00
|
|
|
opt = menu_select_sized(buf, file_list, NULL, 0, x, y, x2, y2, NULL, NULL, 16, draw_scr);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
2013-01-03 08:34:16 +01:00
|
|
|
else opt = menu_select_sized("Select file", file_list, NULL, 0, x, y, x2, y2, NULL, NULL ,16, draw_scr);
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2014-03-22 19:56:52 +01:00
|
|
|
sel = NULL;
|
|
|
|
|
|
|
|
if (opt >= 0 ) sel = strdup(file_list[opt]);
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
/* Cleanup everything - file_list is NULL-terminated */
|
|
|
|
for ( i = 0; file_list[i]; i++ )
|
|
|
|
free((void*)file_list[i]);
|
|
|
|
free(file_list);
|
2014-03-22 19:56:52 +01:00
|
|
|
|
|
|
|
if (opt < 0)
|
|
|
|
return NULL;
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
if (!sel)
|
|
|
|
return NULL;
|
2013-01-18 17:23:46 +01:00
|
|
|
|
2013-03-19 08:26:39 +01:00
|
|
|
if (!strcmp(dir_path,"browser")||!strcmp(dir_path,"select_block")) return sel;
|
2013-03-16 08:58:25 +01:00
|
|
|
|
2013-01-18 17:23:46 +01:00
|
|
|
if (!strcmp(sel,"[..]")) //selected "[..]"
|
|
|
|
{
|
|
|
|
free((void*)sel);
|
|
|
|
updir=strrchr(dir_path,'/');
|
2013-01-18 20:18:28 +01:00
|
|
|
if (updir!=NULL) // found "/"
|
|
|
|
{
|
|
|
|
*updir=0; //trunk dir_path at last /
|
|
|
|
if (strrchr(dir_path,'/')==NULL) {*updir='/'; *(updir+1)=0;} //check if it was root
|
|
|
|
}
|
2013-01-18 17:23:46 +01:00
|
|
|
|
|
|
|
return menu_select_file(dir_path, selected_file, draw_scr);
|
|
|
|
}
|
2012-07-29 10:39:21 +02:00
|
|
|
/* If this is a folder, enter it recursively */
|
|
|
|
if (sel[0] == '[')
|
|
|
|
{
|
|
|
|
int len = strlen(sel);
|
|
|
|
|
|
|
|
/* Remove trailing ] */
|
|
|
|
sel[len-1] = '\0';
|
2013-03-16 08:58:25 +01:00
|
|
|
if ((strlen(dir_path) + len) < MAX_PATH_LENGTH)
|
2013-01-18 17:23:46 +01:00
|
|
|
{
|
|
|
|
strcat(dir_path, "/");
|
|
|
|
strcat(dir_path, sel+1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free((void*)sel);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
/* We don't need this anymore */
|
|
|
|
free((void*)sel);
|
2013-01-18 17:23:46 +01:00
|
|
|
|
|
|
|
return menu_select_file(dir_path, selected_file, draw_scr);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
2012-08-26 18:04:12 +02:00
|
|
|
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
out = (char*)malloc(strlen(dir_path) + strlen(sel) + 4);
|
|
|
|
snprintf(out, strlen(dir_path) + strlen(sel) + 4,
|
|
|
|
"%s/%s", dir_path, sel);
|
|
|
|
|
|
|
|
free(sel);
|
2012-08-26 18:04:12 +02:00
|
|
|
|
|
|
|
if ((ext_matches(out, ".zip")||ext_matches(out, ".ZIP"))&&(tmpismade))
|
2013-01-03 08:34:16 +01:00
|
|
|
{out_zip = (char *) menu_select_file_internal_zip (out, x, y, x2, y2, selected_file, draw_scr);
|
2012-08-26 18:04:12 +02:00
|
|
|
if (!out_zip) return NULL;
|
|
|
|
if(!strcmp(out_zip,"[..]"))
|
|
|
|
{
|
|
|
|
free(out_zip);
|
2013-03-16 08:58:25 +01:00
|
|
|
return menu_select_file_internal (dir_path, x, y, x2, y2, selected_file, draw_scr, 0);
|
2012-08-26 18:04:12 +02:00
|
|
|
}
|
|
|
|
else return out_zip;
|
|
|
|
}
|
|
|
|
else return out;
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
2013-01-18 17:23:46 +01:00
|
|
|
const char *menu_select_file(char *dir_path,const char *selected_file, int draw_scr)
|
2012-07-29 10:39:21 +02:00
|
|
|
{
|
|
|
|
if (dir_path == NULL)
|
|
|
|
dir_path = "";
|
|
|
|
return menu_select_file_internal(dir_path,
|
2014-04-19 19:02:16 +02:00
|
|
|
0, 18/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 18/RATIO, selected_file, draw_scr, 0);
|
2013-03-16 08:58:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *menu_select_browser(unsigned int tape_pos)
|
|
|
|
{
|
|
|
|
return menu_select_file_internal("browser",
|
2014-04-19 19:02:16 +02:00
|
|
|
0, 18/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 18/RATIO, NULL, 0, tape_pos);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
2013-03-19 08:26:39 +01:00
|
|
|
const char *menu_select_tape_block()
|
|
|
|
{
|
|
|
|
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
|
|
|
|
return menu_select_file_internal("select_block",
|
2014-04-19 19:02:16 +02:00
|
|
|
0, 18/RATIO, FULL_DISPLAY_X, FULL_DISPLAY_Y - 18/RATIO, NULL, 0, 0);
|
2013-03-19 08:26:39 +01:00
|
|
|
}
|
|
|
|
|
2014-04-25 14:08:36 +02:00
|
|
|
/*
|
2012-07-29 10:39:21 +02:00
|
|
|
static TTF_Font *read_font(const char *path, int font_size)
|
|
|
|
{
|
|
|
|
TTF_Font *out;
|
|
|
|
SDL_RWops *rw;
|
|
|
|
Uint8 *data = (Uint8*)malloc(1 * 1024*1024);
|
SDL sound, compile against MINGW (VK, fopen binary files, menu key calls FBZX Wii menu, return key active on KEYUP), 2 bugs in 128k snap format, turbo N in line command, separated code for normal and precise emulation, toggle full screen in FBZX menu, removed snow effect in normal emulation, changed save tape routine, fixed 2 bugs in z80, changed SP call in z80
2013-04-06 16:45:45 +02:00
|
|
|
FILE *fp = fopen(path, "rb");
|
2012-07-29 10:39:21 +02:00
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
fprintf(stderr, "Malloc failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (!fp) {
|
|
|
|
fprintf(stderr, "Could not open font\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
fread(data, 1, 1 * 1024 * 1024, fp);
|
|
|
|
rw = SDL_RWFromMem(data, 1 * 1024 * 1024);
|
|
|
|
if (!rw)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Could not create RW: %s\n", SDL_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
out = TTF_OpenFontRW(rw, 1, font_size);
|
|
|
|
if (!out)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Unable to open font %s\n", path);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
2014-04-25 14:08:36 +02:00
|
|
|
*/
|
2012-07-29 10:39:21 +02:00
|
|
|
void font_init()
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
char *font_path,*font_path2;
|
2013-04-07 09:12:12 +02:00
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
TTF_Init();
|
2013-04-07 09:12:12 +02:00
|
|
|
|
2014-04-19 19:02:16 +02:00
|
|
|
font_path=myfile("fbzx/ZX_Spectrum.ttf");
|
2014-04-25 14:08:36 +02:00
|
|
|
font_path2=myfile("fbzx/FreeMono.ttf");
|
2012-07-29 10:39:21 +02:00
|
|
|
|
2014-04-25 14:08:36 +02:00
|
|
|
menu_font_large = TTF_OpenFont(font_path, 16);//Used for menu
|
|
|
|
menu_font_alt_large = TTF_OpenFont(font_path2, 20); //Used for file selection
|
|
|
|
menu_font_small = TTF_OpenFont(font_path, 8);
|
|
|
|
menu_font_alt_small = TTF_OpenFont(font_path2, 10);
|
2013-04-07 09:12:12 +02:00
|
|
|
|
|
|
|
free(font_path);
|
2014-04-25 14:08:36 +02:00
|
|
|
free(font_path2);
|
2012-07-29 10:39:21 +02:00
|
|
|
}
|
|
|
|
|
2014-04-09 09:51:06 +02:00
|
|
|
void font_fini()
|
|
|
|
{
|
2014-04-19 19:02:16 +02:00
|
|
|
TTF_CloseFont(menu_font_alt_large);
|
|
|
|
TTF_CloseFont(menu_font_large);
|
|
|
|
TTF_CloseFont(menu_font_alt_small);
|
|
|
|
TTF_CloseFont(menu_font_small);
|
2014-04-09 09:51:06 +02:00
|
|
|
|
|
|
|
TTF_Quit();
|
|
|
|
}
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
void menu_init(SDL_Surface *screen)
|
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
FILE *fichero;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i=0; i<3; i++)
|
|
|
|
{
|
|
|
|
switch (i)
|
|
|
|
{
|
|
|
|
#ifdef GEKKO
|
|
|
|
case 0:
|
|
|
|
fichero=myfopen("fbzx/menu_navigation_BE.raw","rb"); //Menu up, down, left, right
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
fichero=myfopen("fbzx/select_BE.raw","rb"); //Menu select
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
fichero=myfopen("fbzx/unselect_BE.raw","rb"); //Menu unselect
|
|
|
|
break;
|
|
|
|
#else
|
|
|
|
case 0:
|
|
|
|
fichero=myfopen("fbzx/menu_navigation_LE.raw","rb"); //Menu up, down, left, right
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
fichero=myfopen("fbzx/select_LE.raw","rb"); //Menu select
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
fichero=myfopen("fbzx/unselect_LE.raw","rb"); //Menu unselect
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(fichero==NULL) {
|
|
|
|
printf("Can't open button click wav file: %d\n", i);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fseek (fichero, 0, SEEK_END);
|
|
|
|
len_click_buffer[i]=ftell (fichero);
|
|
|
|
fseek (fichero, 0, SEEK_SET);
|
|
|
|
|
|
|
|
click_buffer_pointer[i]= (int *) malloc(len_click_buffer[i]);
|
|
|
|
|
|
|
|
if(click_buffer_pointer[i]==NULL) {
|
|
|
|
printf("Can't allocate click wav buffer: %d\n",i);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fread(click_buffer_pointer[i], 1, len_click_buffer[i], fichero);
|
|
|
|
|
|
|
|
fclose(fichero);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *image_path;
|
|
|
|
|
|
|
|
image_path=myfile("fbzx/stripes.png");
|
|
|
|
tmp_surface=IMG_Load(image_path);
|
|
|
|
free(image_path);
|
|
|
|
if (tmp_surface == NULL) {printf("Impossible to load stripes image\n"); exit(1);}
|
|
|
|
image_stripes=SDL_DisplayFormat(tmp_surface);
|
|
|
|
SDL_FreeSurface (tmp_surface);
|
|
|
|
|
|
|
|
image_path=myfile("fbzx/stripes_small.png");
|
|
|
|
tmp_surface=IMG_Load(image_path);
|
|
|
|
free(image_path);
|
|
|
|
if (tmp_surface == NULL) {printf("Impossible to load stripes small image\n"); exit(1);}
|
|
|
|
image_stripes_small=SDL_DisplayFormat(tmp_surface);
|
|
|
|
SDL_FreeSurface (tmp_surface);
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
real_screen = screen;
|
|
|
|
is_inited = 1;
|
|
|
|
}
|
|
|
|
|
2014-04-09 09:51:06 +02:00
|
|
|
void menu_deinit()
|
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
free(click_buffer_pointer[0]);
|
|
|
|
free(click_buffer_pointer[1]);
|
|
|
|
free(click_buffer_pointer[2]);
|
|
|
|
SDL_FreeSurface (image_stripes);
|
|
|
|
SDL_FreeSurface (image_stripes_small);
|
2014-04-09 09:51:06 +02:00
|
|
|
real_screen = 0;
|
|
|
|
is_inited = 0;
|
|
|
|
}
|
|
|
|
|
2012-07-29 10:39:21 +02:00
|
|
|
int menu_is_inited(void)
|
|
|
|
{
|
|
|
|
return is_inited;
|
|
|
|
}
|
2012-08-05 23:56:13 +02:00
|
|
|
|
2014-04-25 14:08:36 +02:00
|
|
|
//Sound must be reseted before calling this function
|
|
|
|
void play_click(sound)
|
2014-04-19 19:02:16 +02:00
|
|
|
{
|
2014-04-25 14:08:36 +02:00
|
|
|
int inc;
|
|
|
|
int len_click_buffer_norm = len_click_buffer[sound]/ordenador.increment;
|
|
|
|
|
|
|
|
for(inc=0; inc< len_click_buffer_norm-ordenador.buffer_len; inc+=ordenador.buffer_len)
|
|
|
|
{
|
|
|
|
memcpy(ordenador.current_buffer, click_buffer_pointer[sound]+inc, ordenador.buffer_len*ordenador.increment);
|
|
|
|
sound_play();
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(ordenador.current_buffer, click_buffer_pointer[sound] + inc, (len_click_buffer_norm - inc)*ordenador.increment);
|
|
|
|
//memset(ordenador.current_buffer + len_click_buffer_norm - inc,0, (inc-len_click_buffer_norm + ordenador.buffer_len)*ordenador.increment);
|
|
|
|
sound_play();
|
2014-04-19 19:02:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-05 23:56:13 +02:00
|
|
|
int ask_value_sdl(int *final_value,int y_coord,int max_value) {
|
|
|
|
|
|
|
|
unsigned char nombre2[50];
|
|
|
|
unsigned char *videomem;
|
|
|
|
int ancho,value,tmp,retorno;
|
|
|
|
struct virtkey *virtualkey;
|
|
|
|
unsigned int sdl_key;
|
|
|
|
|
|
|
|
videomem=screen->pixels;
|
|
|
|
ancho=screen->w;
|
|
|
|
|
2013-01-04 16:13:28 +01:00
|
|
|
|
2012-08-05 23:56:13 +02:00
|
|
|
value=0;
|
|
|
|
do {
|
2013-01-04 16:13:28 +01:00
|
|
|
retorno=-1;
|
2012-08-05 23:56:13 +02:00
|
|
|
sprintf (nombre2, " %d\177 ", value);
|
|
|
|
print_string (videomem, nombre2, -1, y_coord, 15, 0, ancho);
|
|
|
|
|
2012-12-30 18:52:21 +01:00
|
|
|
VirtualKeyboard.sel_x = 64;
|
|
|
|
VirtualKeyboard.sel_y = 155;
|
|
|
|
|
2013-01-16 21:07:44 +01:00
|
|
|
virtualkey = get_key();
|
2013-01-04 16:13:28 +01:00
|
|
|
if (virtualkey == NULL) return(0);
|
2014-04-25 14:08:36 +02:00
|
|
|
if (virtualkey->sdl_code==1) {play_click(2); break; }//done, retorno -1
|
|
|
|
|
|
|
|
play_click(1);
|
2012-08-05 23:56:13 +02:00
|
|
|
sdl_key = virtualkey->sdl_code;
|
|
|
|
|
|
|
|
switch (sdl_key) {
|
|
|
|
case SDLK_BACKSPACE:
|
|
|
|
value/=10;
|
|
|
|
break;
|
|
|
|
case SDLK_ESCAPE:
|
2013-01-04 16:13:28 +01:00
|
|
|
retorno=0;
|
2012-08-05 23:56:13 +02:00
|
|
|
break;
|
|
|
|
case SDLK_RETURN:
|
|
|
|
retorno=1;
|
|
|
|
break;
|
|
|
|
case SDLK_0:
|
|
|
|
tmp=value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_1:
|
|
|
|
tmp=1+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_2:
|
|
|
|
tmp=2+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_3:
|
|
|
|
tmp=3+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_4:
|
|
|
|
tmp=4+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_5:
|
|
|
|
tmp=5+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_6:
|
|
|
|
tmp=6+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_7:
|
|
|
|
tmp=7+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_8:
|
|
|
|
tmp=8+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_9:
|
|
|
|
tmp=9+value * 10;
|
|
|
|
if (tmp <= max_value) {
|
|
|
|
value=tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2013-01-04 16:13:28 +01:00
|
|
|
} while (retorno==-1);
|
2012-08-05 23:56:13 +02:00
|
|
|
|
|
|
|
*final_value=value;
|
|
|
|
|
|
|
|
return (retorno);
|
|
|
|
}
|
|
|
|
|
|
|
|
int ask_filename_sdl(char *nombre_final,int y_coord,char *extension, char *path, char *name) {
|
|
|
|
|
|
|
|
int longitud,retorno;
|
|
|
|
unsigned char nombre[37],nombre2[38];
|
|
|
|
char *ptr;
|
|
|
|
|
|
|
|
unsigned char *videomem;
|
|
|
|
int ancho;
|
|
|
|
|
|
|
|
struct virtkey *virtualkey;
|
|
|
|
unsigned int sdl_key;
|
|
|
|
|
|
|
|
videomem=screen->pixels;
|
|
|
|
ancho=screen->w;
|
|
|
|
|
|
|
|
retorno=0;
|
|
|
|
|
|
|
|
if (!name||(strlen(name)>36))
|
|
|
|
{
|
|
|
|
nombre[0]=127;
|
|
|
|
nombre[1]=0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strcpy(nombre,name);
|
|
|
|
ptr = strrchr (nombre, '.');
|
|
|
|
if (ptr) //remove the extension
|
|
|
|
{
|
|
|
|
*ptr = 127;
|
|
|
|
*(ptr+1) = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nombre[strlen(nombre)-1]=127;
|
|
|
|
nombre[strlen(nombre)]=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
longitud=strlen(nombre)-1;
|
|
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
sprintf (nombre2, " %s.%s ", nombre,extension);
|
|
|
|
print_string (videomem, nombre2, -1, y_coord, 15, 0, ancho);
|
|
|
|
|
2012-12-30 18:52:21 +01:00
|
|
|
VirtualKeyboard.sel_x = 64;
|
|
|
|
VirtualKeyboard.sel_y = 155;
|
|
|
|
|
2013-01-16 21:07:44 +01:00
|
|
|
virtualkey = get_key();
|
2012-08-05 23:56:13 +02:00
|
|
|
if (virtualkey == NULL) return(2);
|
2014-04-25 14:08:36 +02:00
|
|
|
|
|
|
|
play_click(1);
|
|
|
|
|
2012-08-05 23:56:13 +02:00
|
|
|
sdl_key = virtualkey->sdl_code;
|
|
|
|
|
|
|
|
switch (sdl_key) {
|
|
|
|
case SDLK_BACKSPACE:
|
|
|
|
if (longitud > 0) {
|
|
|
|
nombre[longitud]=0;
|
|
|
|
longitud--;
|
|
|
|
nombre[longitud]=127;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_ESCAPE:
|
|
|
|
retorno=2;
|
|
|
|
break;
|
|
|
|
case SDLK_RETURN:
|
|
|
|
retorno=1;
|
|
|
|
break;
|
|
|
|
case SDLK_a:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='a';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_b:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='b';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_c:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='c';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_d:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='d';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_e:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='e';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_f:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='f';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_g:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='g';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_h:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='h';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_i:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='i';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_j:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='j';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_k:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='k';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_l:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='l';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_m:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='m';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_n:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='n';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_o:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='o';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_p:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='p';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_q:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='q';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_r:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='r';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_s:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='s';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_t:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='t';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_u:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='u';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_v:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='v';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_w:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='w';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_x:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='x';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_y:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='y';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_z:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='z';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_0:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='0';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_1:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='1';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_2:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='2';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_3:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='3';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_4:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='4';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_5:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='5';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_6:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='6';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_7:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='7';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_8:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='8';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_9:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='9';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDLK_MINUS:
|
|
|
|
if (longitud < 30) {
|
|
|
|
nombre[longitud++]='-';
|
|
|
|
nombre[longitud]=127;
|
|
|
|
nombre[longitud + 1]=0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (!retorno);
|
|
|
|
|
|
|
|
nombre[longitud]=0; // erase cursor
|
|
|
|
|
|
|
|
longitud=strlen(path);
|
|
|
|
if((path[longitud-1]!='/')&&(longitud>1))
|
|
|
|
sprintf(nombre_final,"%s/%s.%s",path,nombre,extension); // name
|
|
|
|
else
|
|
|
|
sprintf(nombre_final,"%s%s.%s",path,nombre,extension);
|
|
|
|
|
|
|
|
return (retorno);
|
|
|
|
}
|