implemented in-game menu
This commit is contained in:
parent
baf2c0da7f
commit
c486cf61d9
1 changed files with 427 additions and 25 deletions
|
|
@ -29,6 +29,7 @@ static int show_menu;
|
||||||
static struct Game {
|
static struct Game {
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
char name[MAX_PATH]; // TODO: rename to basename?
|
char name[MAX_PATH]; // TODO: rename to basename?
|
||||||
|
char m3u_path[MAX_PATH];
|
||||||
void* data;
|
void* data;
|
||||||
size_t size;
|
size_t size;
|
||||||
} game;
|
} game;
|
||||||
|
|
@ -50,11 +51,60 @@ static void Game_open(char* path) {
|
||||||
fread(game.data, sizeof(uint8_t), game.size, file);
|
fread(game.data, sizeof(uint8_t), game.size, file);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
// m3u-based?
|
||||||
|
char* tmp;
|
||||||
|
char m3u_path[256];
|
||||||
|
char base_path[256];
|
||||||
|
char dir_name[256];
|
||||||
|
|
||||||
|
strcpy(m3u_path, game.path);
|
||||||
|
tmp = strrchr(m3u_path, '/') + 1;
|
||||||
|
tmp[0] = '\0';
|
||||||
|
|
||||||
|
strcpy(base_path, m3u_path);
|
||||||
|
|
||||||
|
tmp = strrchr(m3u_path, '/');
|
||||||
|
tmp[0] = '\0';
|
||||||
|
|
||||||
|
tmp = strrchr(m3u_path, '/');
|
||||||
|
strcpy(dir_name, tmp);
|
||||||
|
|
||||||
|
tmp = m3u_path + strlen(m3u_path);
|
||||||
|
strcpy(tmp, dir_name);
|
||||||
|
|
||||||
|
tmp = m3u_path + strlen(m3u_path);
|
||||||
|
strcpy(tmp, ".m3u");
|
||||||
|
|
||||||
|
if (exists(m3u_path)) {
|
||||||
|
strcpy(game.m3u_path, m3u_path);
|
||||||
|
strcpy((char*)game.name, strrchr(m3u_path, '/')+1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
game.m3u_path[0] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static void Game_close(void) {
|
static void Game_close(void) {
|
||||||
free(game.data);
|
free(game.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct retro_disk_control_ext_callback disk_control_ext;
|
||||||
|
static void Game_changeDisc(char* path) {
|
||||||
|
|
||||||
|
if (exactMatch(game.path, path) || !exists(path)) return;
|
||||||
|
|
||||||
|
Game_close();
|
||||||
|
Game_open(path);
|
||||||
|
|
||||||
|
struct retro_game_info game_info = {};
|
||||||
|
game_info.path = game.path;
|
||||||
|
game_info.data = game.data;
|
||||||
|
game_info.size = game.size;
|
||||||
|
|
||||||
|
disk_control_ext.replace_image_index(0, &game_info);
|
||||||
|
putFile(CHANGE_DISC_PATH, path); // MinUI still needs to know this to update recents.txt
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
static struct Core {
|
static struct Core {
|
||||||
|
|
@ -235,7 +285,6 @@ static void State_resume(void) {
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
// callbacks
|
// callbacks
|
||||||
static struct retro_disk_control_ext_callback disk_control_ext;
|
|
||||||
|
|
||||||
// TODO: tmp, naive options
|
// TODO: tmp, naive options
|
||||||
static struct {
|
static struct {
|
||||||
|
|
@ -930,6 +979,9 @@ void Core_load(void) {
|
||||||
printf("%f\n%f\n", core.fps, core.sample_rate);
|
printf("%f\n%f\n", core.fps, core.sample_rate);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
void Core_reset(void) {
|
||||||
|
core.reset();
|
||||||
|
}
|
||||||
void Core_unload(void) {
|
void Core_unload(void) {
|
||||||
SND_quit();
|
SND_quit();
|
||||||
}
|
}
|
||||||
|
|
@ -947,10 +999,76 @@ void Core_close(void) {
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
#define MENU_ITEM_COUNT 5
|
||||||
|
#define MENU_SLOT_COUNT 8
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ITEM_CONT,
|
||||||
|
ITEM_SAVE,
|
||||||
|
ITEM_LOAD,
|
||||||
|
ITEM_OPTS,
|
||||||
|
ITEM_QUIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STATUS_CONT = 0,
|
||||||
|
STATUS_SAVE = 1,
|
||||||
|
STATUS_LOAD = 11,
|
||||||
|
STATUS_OPTS = 23,
|
||||||
|
STATUS_DISC = 24,
|
||||||
|
STATUS_QUIT = 30
|
||||||
|
};
|
||||||
|
|
||||||
static struct Menu {
|
static struct Menu {
|
||||||
int initialized;
|
int initialized;
|
||||||
SDL_Surface* overlay;
|
SDL_Surface* overlay;
|
||||||
} menu;
|
char* items[MENU_ITEM_COUNT];
|
||||||
|
int slot;
|
||||||
|
} menu = {
|
||||||
|
.items = {
|
||||||
|
[ITEM_CONT] = "Continue",
|
||||||
|
[ITEM_SAVE] = "Save",
|
||||||
|
[ITEM_LOAD] = "Load",
|
||||||
|
[ITEM_OPTS] = "Reset",
|
||||||
|
[ITEM_QUIT] = "Quit",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct __attribute__((__packed__)) uint24_t {
|
||||||
|
uint8_t a,b,c;
|
||||||
|
} uint24_t;
|
||||||
|
static SDL_Surface* Menu_thumbnail(SDL_Surface* src_img) {
|
||||||
|
SDL_Surface* dst_img = SDL_CreateRGBSurface(0,SCREEN_WIDTH/2, SCREEN_HEIGHT/2,src_img->format->BitsPerPixel,src_img->format->Rmask,src_img->format->Gmask,src_img->format->Bmask,src_img->format->Amask);
|
||||||
|
|
||||||
|
uint8_t* src_px = src_img->pixels;
|
||||||
|
uint8_t* dst_px = dst_img->pixels;
|
||||||
|
int step = dst_img->format->BytesPerPixel;
|
||||||
|
int step2 = step * 2;
|
||||||
|
int stride = src_img->pitch;
|
||||||
|
for (int y=0; y<dst_img->h; y++) {
|
||||||
|
for (int x=0; x<dst_img->w; x++) {
|
||||||
|
switch(step) {
|
||||||
|
case 1:
|
||||||
|
*dst_px = *src_px;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*(uint16_t*)dst_px = *(uint16_t*)src_px;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
*(uint24_t*)dst_px = *(uint24_t*)src_px;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*(uint32_t*)dst_px = *(uint32_t*)src_px;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dst_px += step;
|
||||||
|
src_px += step2;
|
||||||
|
}
|
||||||
|
src_px += stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst_img;
|
||||||
|
}
|
||||||
|
|
||||||
void Menu_init(void) {
|
void Menu_init(void) {
|
||||||
menu.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, 0, 0, 0, 0);
|
menu.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, 0, 0, 0, 0);
|
||||||
|
|
@ -974,42 +1092,222 @@ void Menu_loop(void) {
|
||||||
// current screen is on the previous buffer
|
// current screen is on the previous buffer
|
||||||
SDL_Surface* backing = GFX_getBufferCopy();
|
SDL_Surface* backing = GFX_getBufferCopy();
|
||||||
|
|
||||||
// displau name
|
// path and string things
|
||||||
char rom_name[MAX_PATH];
|
char* tmp;
|
||||||
getDisplayName(game.path, rom_name);
|
char rom_name[256]; // without extension or cruft
|
||||||
|
char slot_path[256];
|
||||||
|
char emu_name[256];
|
||||||
|
char minui_dir[256];
|
||||||
|
|
||||||
|
getEmuName(game.path, emu_name);
|
||||||
|
sprintf(minui_dir, USERDATA_PATH "/.minui/%s", emu_name);
|
||||||
|
mkdir(minui_dir, 0755);
|
||||||
|
|
||||||
|
int rom_disc = -1;
|
||||||
|
int disc = rom_disc;
|
||||||
|
int total_discs = 0;
|
||||||
|
char disc_name[16];
|
||||||
|
char* disc_paths[9]; // up to 9 paths, Arc the Lad Collection is 7 discs
|
||||||
|
char base_path[256]; // used below too when status==kItemSave
|
||||||
|
|
||||||
|
if (game.m3u_path[0]) {
|
||||||
|
strcpy(base_path, game.m3u_path);
|
||||||
|
tmp = strrchr(base_path, '/') + 1;
|
||||||
|
tmp[0] = '\0';
|
||||||
|
|
||||||
|
//read m3u file
|
||||||
|
FILE* file = fopen(game.m3u_path, "r");
|
||||||
|
if (file) {
|
||||||
|
char line[256];
|
||||||
|
while (fgets(line,256,file)!=NULL) {
|
||||||
|
normalizeNewline(line);
|
||||||
|
trimTrailingNewlines(line);
|
||||||
|
if (strlen(line)==0) continue; // skip empty lines
|
||||||
|
|
||||||
|
char disc_path[256];
|
||||||
|
strcpy(disc_path, base_path);
|
||||||
|
tmp = disc_path + strlen(disc_path);
|
||||||
|
strcpy(tmp, line);
|
||||||
|
|
||||||
|
// found a valid disc path
|
||||||
|
if (exists(disc_path)) {
|
||||||
|
disc_paths[total_discs] = strdup(disc_path);
|
||||||
|
// matched our current disc
|
||||||
|
if (exactMatch(disc_path, game.path)) {
|
||||||
|
rom_disc = total_discs;
|
||||||
|
disc = rom_disc;
|
||||||
|
sprintf(disc_name, "Disc %i", disc+1);
|
||||||
|
}
|
||||||
|
total_discs += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// shares saves across multi-disc games too
|
||||||
|
sprintf(slot_path, "%s/%s.txt", minui_dir, game.name);
|
||||||
|
getDisplayName(game.name, rom_name);
|
||||||
|
|
||||||
|
puts("slot_path");
|
||||||
|
puts(slot_path);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
//
|
||||||
|
int selected = 0; // resets every launch
|
||||||
|
if (exists(slot_path)) menu.slot = getInt(slot_path);
|
||||||
|
if (menu.slot==8) menu.slot = 0;
|
||||||
|
|
||||||
|
char save_path[256];
|
||||||
|
char bmp_path[256];
|
||||||
|
char txt_path[256];
|
||||||
|
int save_exists = 0;
|
||||||
|
int preview_exists = 0;
|
||||||
|
|
||||||
|
int status = STATUS_CONT; // TODO: tmp
|
||||||
int show_setting = 0;
|
int show_setting = 0;
|
||||||
int menu_dirty = 1;
|
int dirty = 1;
|
||||||
int menu_start = SDL_GetTicks();
|
|
||||||
while (show_menu) {
|
while (show_menu) {
|
||||||
|
GFX_startFrame();
|
||||||
|
int frame_start = SDL_GetTicks();
|
||||||
|
|
||||||
PAD_poll();
|
PAD_poll();
|
||||||
|
|
||||||
// TODO: tmp (L)oad and w(R)ite state
|
if (PAD_justPressed(BTN_UP)) {
|
||||||
if (PAD_justPressed(BTN_L1)) {
|
selected -= 1;
|
||||||
State_read();
|
if (selected<0) selected += MENU_ITEM_COUNT;
|
||||||
|
dirty = 1;
|
||||||
|
}
|
||||||
|
else if (PAD_justPressed(BTN_DOWN)) {
|
||||||
|
selected += 1;
|
||||||
|
if (selected>=MENU_ITEM_COUNT) selected -= MENU_ITEM_COUNT;
|
||||||
|
dirty = 1;
|
||||||
|
}
|
||||||
|
else if (PAD_justPressed(BTN_LEFT)) {
|
||||||
|
if (total_discs>1 && selected==ITEM_CONT) {
|
||||||
|
disc -= 1;
|
||||||
|
if (disc<0) disc += total_discs;
|
||||||
|
dirty = 1;
|
||||||
|
sprintf(disc_name, "Disc %i", disc+1);
|
||||||
|
}
|
||||||
|
else if (selected==ITEM_SAVE || selected==ITEM_LOAD) {
|
||||||
|
menu.slot -= 1;
|
||||||
|
if (menu.slot<0) menu.slot += MENU_SLOT_COUNT;
|
||||||
|
dirty = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PAD_justPressed(BTN_RIGHT)) {
|
||||||
|
if (total_discs>1 && selected==ITEM_CONT) {
|
||||||
|
disc += 1;
|
||||||
|
if (disc==total_discs) disc -= total_discs;
|
||||||
|
dirty = 1;
|
||||||
|
sprintf(disc_name, "Disc %i", disc+1);
|
||||||
|
}
|
||||||
|
else if (selected==ITEM_SAVE || selected==ITEM_LOAD) {
|
||||||
|
menu.slot += 1;
|
||||||
|
if (menu.slot>=MENU_SLOT_COUNT) menu.slot -= MENU_SLOT_COUNT;
|
||||||
|
dirty = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirty && (selected==ITEM_SAVE || selected==ITEM_LOAD)) {
|
||||||
|
int last_slot = state_slot;
|
||||||
|
state_slot = menu.slot;
|
||||||
|
State_getPath(save_path);
|
||||||
|
state_slot = last_slot;
|
||||||
|
sprintf(bmp_path, "%s/%s.%d.bmp", minui_dir, game.name, menu.slot);
|
||||||
|
sprintf(txt_path, "%s/%s.%d.txt", minui_dir, game.name, menu.slot);
|
||||||
|
|
||||||
|
save_exists = exists(save_path);
|
||||||
|
preview_exists = save_exists && exists(bmp_path);
|
||||||
|
// printf("save_path: %s (%i)\n", save_path, save_exists);
|
||||||
|
// printf("bmp_path: %s (%i)\n", bmp_path, preview_exists);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PAD_justPressed(BTN_B)) { // TODO: ignore BTN_MENU release if VOL_* buttons were pressed while it was pressed?
|
||||||
|
status = STATUS_CONT;
|
||||||
show_menu = 0;
|
show_menu = 0;
|
||||||
}
|
}
|
||||||
else if (PAD_justPressed(BTN_R1)) {
|
else if (PAD_justPressed(BTN_A)) {
|
||||||
|
switch(selected) {
|
||||||
|
case ITEM_CONT:
|
||||||
|
if (total_discs && rom_disc!=disc) {
|
||||||
|
status = STATUS_DISC;
|
||||||
|
char* disc_path = disc_paths[disc];
|
||||||
|
Game_changeDisc(disc_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
status = STATUS_CONT;
|
||||||
|
}
|
||||||
|
show_menu = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ITEM_SAVE: {
|
||||||
|
state_slot = menu.slot;
|
||||||
State_write();
|
State_write();
|
||||||
|
status = STATUS_SAVE;
|
||||||
|
SDL_Surface* preview = Menu_thumbnail(backing);
|
||||||
|
SDL_RWops* out = SDL_RWFromFile(bmp_path, "wb");
|
||||||
|
if (total_discs) {
|
||||||
|
char* disc_path = disc_paths[disc];
|
||||||
|
putFile(txt_path, disc_path + strlen(base_path));
|
||||||
|
sprintf(bmp_path, "%s/%s.%d.bmp", minui_dir, game.name, menu.slot);
|
||||||
|
}
|
||||||
|
SDL_SaveBMP_RW(preview, out, 1);
|
||||||
|
SDL_FreeSurface(preview);
|
||||||
|
putInt(slot_path, menu.slot);
|
||||||
show_menu = 0;
|
show_menu = 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
if (PAD_justPressed(BTN_B)) show_menu = 0;
|
case ITEM_LOAD: {
|
||||||
if (PAD_justPressed(BTN_X)) {
|
if (save_exists && total_discs) {
|
||||||
|
char slot_disc_name[256];
|
||||||
|
getFile(txt_path, slot_disc_name, 256);
|
||||||
|
char slot_disc_path[256];
|
||||||
|
if (slot_disc_name[0]=='/') strcpy(slot_disc_path, slot_disc_name);
|
||||||
|
else sprintf(slot_disc_path, "%s%s", base_path, slot_disc_name);
|
||||||
|
char* disc_path = disc_paths[disc];
|
||||||
|
if (!exactMatch(slot_disc_path, disc_path)) {
|
||||||
|
Game_changeDisc(slot_disc_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state_slot = menu.slot;
|
||||||
|
State_read();
|
||||||
|
status = STATUS_LOAD;
|
||||||
|
putInt(slot_path, menu.slot);
|
||||||
show_menu = 0;
|
show_menu = 0;
|
||||||
quit = 1; // TODO: tmp
|
}
|
||||||
|
break;
|
||||||
|
case ITEM_OPTS:
|
||||||
|
Core_reset(); // TODO: tmp?
|
||||||
|
status = STATUS_OPTS;
|
||||||
|
show_menu = 0;
|
||||||
|
break;
|
||||||
|
case ITEM_QUIT:
|
||||||
|
status = STATUS_QUIT;
|
||||||
|
show_menu = 0;
|
||||||
|
quit = 1; // TODO: tmp?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!show_menu) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
POW_update(&menu_dirty, &show_setting, Menu_beforeSleep, Menu_afterSleep);
|
POW_update(&dirty, &show_setting, Menu_beforeSleep, Menu_afterSleep);
|
||||||
|
|
||||||
if (menu_dirty) {
|
if (dirty) {
|
||||||
SDL_BlitSurface(backing, NULL, screen, NULL);
|
SDL_BlitSurface(backing, NULL, screen, NULL);
|
||||||
SDL_BlitSurface(menu.overlay, NULL, screen, NULL);
|
SDL_BlitSurface(menu.overlay, NULL, screen, NULL);
|
||||||
|
|
||||||
|
int ox, oy;
|
||||||
int ow = GFX_blitHardwareGroup(screen, show_setting);
|
int ow = GFX_blitHardwareGroup(screen, show_setting);
|
||||||
|
int max_width = SCREEN_WIDTH - SCALE1(PADDING * 2) - ow;
|
||||||
|
|
||||||
SDL_Surface* text = TTF_RenderUTF8_Blended(font.large, rom_name, COLOR_WHITE);
|
char display_name[256];
|
||||||
int max_width = MIN(SCREEN_WIDTH - SCALE1(PADDING * 2) - ow, text->w+SCALE1(12*2));
|
int text_width = GFX_truncateDisplayName(rom_name, display_name, max_width);
|
||||||
|
max_width = MIN(max_width, text_width);
|
||||||
|
|
||||||
|
SDL_Surface* text;
|
||||||
|
text = TTF_RenderUTF8_Blended(font.large, display_name, COLOR_WHITE);
|
||||||
GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){
|
GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){
|
||||||
SCALE1(PADDING),
|
SCALE1(PADDING),
|
||||||
SCALE1(PADDING),
|
SCALE1(PADDING),
|
||||||
|
|
@ -1030,12 +1328,116 @@ void Menu_loop(void) {
|
||||||
GFX_blitButtonGroup((char*[]){ "POWER","SLEEP", NULL }, screen, 0);
|
GFX_blitButtonGroup((char*[]){ "POWER","SLEEP", NULL }, screen, 0);
|
||||||
GFX_blitButtonGroup((char*[]){ "B","BACK", "A","OKAY", NULL }, screen, 1);
|
GFX_blitButtonGroup((char*[]){ "B","BACK", "A","OKAY", NULL }, screen, 1);
|
||||||
|
|
||||||
|
// list
|
||||||
|
TTF_SizeUTF8(font.large, menu.items[ITEM_CONT], &ow, NULL);
|
||||||
|
ow += SCALE1(12*2);
|
||||||
|
oy = 35;
|
||||||
|
for (int i=0; i<MENU_ITEM_COUNT; i++) {
|
||||||
|
char* item = menu.items[i];
|
||||||
|
SDL_Color text_color = COLOR_WHITE;
|
||||||
|
|
||||||
|
if (i==selected) {
|
||||||
|
// disc change
|
||||||
|
if (total_discs>1 && i==ITEM_CONT) {
|
||||||
|
GFX_blitPill(ASSET_DARK_GRAY_PILL, screen, &(SDL_Rect){
|
||||||
|
SCALE1(PADDING),
|
||||||
|
SCALE1(oy + PADDING),
|
||||||
|
SCREEN_WIDTH - SCALE1(PADDING * 2),
|
||||||
|
SCALE1(PILL_SIZE)
|
||||||
|
});
|
||||||
|
text = TTF_RenderUTF8_Blended(font.large, disc_name, COLOR_WHITE);
|
||||||
|
SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){
|
||||||
|
SCREEN_WIDTH - SCALE1(PADDING + 12) - text->w,
|
||||||
|
SCALE1(oy + PADDING + 4)
|
||||||
|
});
|
||||||
|
SDL_FreeSurface(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pill
|
||||||
|
GFX_blitPill(ASSET_WHITE_PILL, screen, &(SDL_Rect){
|
||||||
|
SCALE1(PADDING),
|
||||||
|
SCALE1(oy + PADDING + (i * PILL_SIZE)),
|
||||||
|
ow,
|
||||||
|
SCALE1(PILL_SIZE)
|
||||||
|
});
|
||||||
|
text_color = COLOR_BLACK;
|
||||||
|
|
||||||
|
// TODO: draw arrow?
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// shadow
|
||||||
|
text = TTF_RenderUTF8_Blended(font.large, item, COLOR_BLACK);
|
||||||
|
SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){
|
||||||
|
SCALE1(2 + PADDING + 12),
|
||||||
|
SCALE1(1 + PADDING + oy + (i * PILL_SIZE) + 4)
|
||||||
|
});
|
||||||
|
SDL_FreeSurface(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// text
|
||||||
|
text = TTF_RenderUTF8_Blended(font.large, item, text_color);
|
||||||
|
SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){
|
||||||
|
SCALE1(PADDING + 12),
|
||||||
|
SCALE1(oy + PADDING + (i * PILL_SIZE) + 4)
|
||||||
|
});
|
||||||
|
SDL_FreeSurface(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// slot preview
|
||||||
|
if (selected==ITEM_SAVE || selected==ITEM_LOAD) {
|
||||||
|
#define WINDOW_RADIUS 4 // TODO: this logic belongs in blitRect?
|
||||||
|
// unscaled
|
||||||
|
ox = 146;
|
||||||
|
oy = 54;
|
||||||
|
int hw = SCREEN_WIDTH / 2;
|
||||||
|
int hh = SCREEN_HEIGHT / 2;
|
||||||
|
|
||||||
|
// preview window
|
||||||
|
// GFX_blitWindow(screen, Screen.menu.preview.x, Screen.menu.preview.y, Screen.menu.preview.width, Screen.menu.preview.height, 1);
|
||||||
|
|
||||||
|
// window
|
||||||
|
GFX_blitRect(ASSET_STATE_BG, screen, &(SDL_Rect){SCALE2(ox-WINDOW_RADIUS,oy-WINDOW_RADIUS),hw+SCALE1(WINDOW_RADIUS*2),hh+SCALE1(WINDOW_RADIUS*3+6)});
|
||||||
|
|
||||||
|
if (preview_exists) { // has save, has preview
|
||||||
|
SDL_Surface* preview = IMG_Load(bmp_path);
|
||||||
|
if (!preview) printf("IMG_Load: %s\n", IMG_GetError());
|
||||||
|
SDL_BlitSurface(preview, NULL, screen, &(SDL_Rect){SCALE2(ox,oy)});
|
||||||
|
SDL_FreeSurface(preview);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Rect preview_rect = {SCALE2(ox,oy),hw,hh};
|
||||||
|
SDL_FillRect(screen, &preview_rect, 0);
|
||||||
|
if (save_exists) { // has save but no preview
|
||||||
|
GFX_blitMessage("No Preview", screen, &preview_rect);
|
||||||
|
}
|
||||||
|
else { // no save
|
||||||
|
GFX_blitMessage("Empty Slot", screen, &preview_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pagination
|
||||||
|
ox += 24;
|
||||||
|
oy += 124;
|
||||||
|
for (int i=0; i<MENU_SLOT_COUNT; i++) {
|
||||||
|
if (i==menu.slot) {
|
||||||
|
GFX_blitAsset(ASSET_PAGE, NULL, screen, &(SDL_Rect){SCALE2(ox+(i*15),oy)});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GFX_blitAsset(ASSET_DOT, NULL, screen, &(SDL_Rect){SCALE2(ox+(i*15)+4,oy+2)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SDL_BlitSurface(slot_overlay, NULL, screen, &preview_rect);
|
||||||
|
// SDL_BlitSurface(slot_dots, NULL, screen, &(SDL_Rect){Screen.menu.slots.x,Screen.menu.slots.y});
|
||||||
|
// SDL_BlitSurface(slot_dot_selected, NULL, screen, &(SDL_Rect){Screen.menu.slots.x+(Screen.menu.slots.ox*slot),Screen.menu.slots.y});
|
||||||
|
}
|
||||||
|
|
||||||
GFX_flip(screen);
|
GFX_flip(screen);
|
||||||
menu_dirty = 0;
|
dirty = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// slow down to 60fps
|
// slow down to 60fps
|
||||||
unsigned long frame_duration = SDL_GetTicks() - menu_start;
|
unsigned long frame_duration = SDL_GetTicks() - frame_start;
|
||||||
#define kTargetFrameDuration 17
|
#define kTargetFrameDuration 17
|
||||||
if (frame_duration<kTargetFrameDuration) SDL_Delay(kTargetFrameDuration-frame_duration);
|
if (frame_duration<kTargetFrameDuration) SDL_Delay(kTargetFrameDuration-frame_duration);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue