RetroArch/360/frontend-xenon/main.c
2012-06-22 18:58:19 +02:00

245 lines
5.3 KiB
C

/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
* Copyright (C) 2011-2012 - Daniel De Matteis
*
* RetroArch 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 Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch 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 RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <debug.h>
#include <xenos/xenos.h>
#include <diskio/dvd.h>
#include <diskio/ata.h>
#include <input/input.h>
#include <console/console.h>
#include <diskio/diskio.h>
#include <usb/usbmain.h>
#include <time/time.h>
#include <ppc/timebase.h>
#include <xenon_soc/xenon_power.h>
#include <elf/elf.h>
#include <dirent.h>
#include "../../compat/strl.h"
#undef main
int rarch_main(int argc, char **argv);
static void start_rarch(const char *path)
{
char arg0[] = "retroarch";
char arg1[256];
strlcpy(arg1, path, sizeof(arg1));
char *argv[3] = { arg0, arg1, NULL };
rarch_main(sizeof(argv) / sizeof(argv[0]) - 1, argv);
}
#define FG_COL -1
#define BG_COL 0
#define MAX_FILES 1000
#define STICK_THRESHOLD 25000
#define MAX_DISPLAYED_ENTRIES 20
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
static struct dirent entries[MAX_FILES];
static int entrycount;
static void load_dir(const char *path)
{
DIR *d = opendir(path);
entrycount = 0;
if (!d)
return;
for (struct dirent *de = readdir(d); de; de = readdir(d))
{
if (strcmp(de->d_name, "."))
{
memcpy(&entries[entrycount], de, sizeof(struct dirent));
entrycount++;
}
}
closedir(d);
}
static void append_dir_to_path(char *path, const char *dir)
{
if (!strcmp(dir, ".."))
{
int i = strlen(path);
int delimcount = 0;
while (i >= 0 && delimcount < 2)
{
if (path[i] == '/')
{
delimcount++;
if (delimcount > 1)
path[i + 1]= '\0';
}
i--;
}
}
else if (!strcmp(dir, "."))
return;
else
{
strlcat(path, dir, sizeof(path));
strlcat(path, "/", sizeof(path));
}
}
int main(void)
{
const char *s = NULL;
char path[256];
int handle;
struct controller_data_s pad;
int pos = 0, ppos = -1;
xenos_init(VIDEO_MODE_AUTO);
console_init();
xenon_make_it_faster(XENON_SPEED_FULL);
usb_init();
usb_do_poll();
xenon_ata_init();
dvd_init();
handle = -1;
handle = bdev_enum(handle, &s);
if (handle < 0)
return 0;
strlcpy(path, s, sizeof(path));
strlcat(path, ":/", sizeof(path));
load_dir(path);
for (;;)
{
usb_do_poll();
get_controller_data(&pad, 0);
if (pad.s1_y > STICK_THRESHOLD || pad.up)
pos--;
if (pad.s1_y < -STICK_THRESHOLD || pad.down)
pos++;
if (entrycount && (pos < 0 || pos >= entrycount))
{
pos = ppos;
continue;
}
if (pad.logo)
return 0;
if (pad.a)
{
if (entries[pos].d_type & DT_DIR)
{
append_dir_to_path(path,entries[pos].d_name);
load_dir(path);
ppos = -1;
pos = 0;
}
else
{
char fn[256];
strlcpy(fn, path, sizeof(fn));
strlcat(fn, entries[pos].d_name, sizeof(fn));
printf("%s\n", fn);
start_rarch(fn);
}
}
if (pad.select)
{
append_dir_to_path(path, "..");
load_dir(path);
ppos = -1;
pos = 0;
}
if (pad.b)
{
do
{
handle = bdev_enum(handle, &s);
} while (handle < 0);
strlcpy(path, s, sizeof(path));
strlcat(path, ":/", sizeof(path));
load_dir(path);
ppos = -1;
pos = 0;
}
if (ppos == pos)
continue;
memset(&pad, 0, sizeof(pad));
console_set_colors(BG_COL, FG_COL);
console_clrscr();
printf("A: select, B: change disk, Back: parent dir, Logo: reload Xell\n\n%s\n\n", path);
int start = MAX(0, pos - MAX_DISPLAYED_ENTRIES / 2);
int count = MIN(MAX_DISPLAYED_ENTRIES, entrycount - start);
for (int i = start; i < start + count; i++)
{
struct dirent *de = &entries[i];
if (i == pos)
console_set_colors(FG_COL, BG_COL);
else
console_set_colors(BG_COL, FG_COL);
if (de->d_type & DT_DIR)
console_putch('[');
s = de->d_name;
while (*s)
console_putch(*s++);
if (de->d_type & DT_DIR)
console_putch(']');
console_putch('\r');
console_putch('\n');
}
ppos = pos;
do
{
usb_do_poll();
get_controller_data(&pad, 0);
} while (pad.a || pad.b || pad.select || pad.s1_y > STICK_THRESHOLD || pad.s1_y < -STICK_THRESHOLD);
}
return 0;
}