sdl: fixed formatting issues; overall code cleanup
This commit is contained in:
parent
750b7f75e0
commit
646847ddc8
|
@ -32,21 +32,21 @@
|
|||
int
|
||||
LoadCPalette(const std::string &file)
|
||||
{
|
||||
uint8 tmpp[192];
|
||||
FILE *fp;
|
||||
uint8 tmpp[192];
|
||||
FILE *fp;
|
||||
|
||||
if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) {
|
||||
printf(" Error loading custom palette from file: %s\n", file.c_str());
|
||||
return 0;
|
||||
}
|
||||
size_t result = fread(tmpp, 1, 192, fp);
|
||||
if(result != 192) {
|
||||
if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) {
|
||||
printf(" Error loading custom palette from file: %s\n", file.c_str());
|
||||
return 0;
|
||||
}
|
||||
size_t result = fread(tmpp, 1, 192, fp);
|
||||
if(result != 192) {
|
||||
printf(" Error reading custom palette from file: %s\n", file.c_str());
|
||||
return 0;
|
||||
}
|
||||
FCEUI_SetPaletteArray(tmpp);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
FCEUI_SetPaletteArray(tmpp);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,23 +56,23 @@ LoadCPalette(const std::string &file)
|
|||
static void
|
||||
CreateDirs(const std::string &dir)
|
||||
{
|
||||
char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
|
||||
std::string subdir;
|
||||
int x;
|
||||
char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
|
||||
std::string subdir;
|
||||
int x;
|
||||
|
||||
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
|
||||
mkdir(dir.c_str());
|
||||
chmod(dir.c_str(), 755);
|
||||
for(x = 0; x < 6; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str());
|
||||
}
|
||||
mkdir(dir.c_str());
|
||||
chmod(dir.c_str(), 755);
|
||||
for(x = 0; x < 6; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str());
|
||||
}
|
||||
#else
|
||||
mkdir(dir.c_str(), S_IRWXU);
|
||||
for(x = 0; x < 6; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str(), S_IRWXU);
|
||||
}
|
||||
mkdir(dir.c_str(), S_IRWXU);
|
||||
for(x = 0; x < 6; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str(), S_IRWXU);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -84,25 +84,25 @@ CreateDirs(const std::string &dir)
|
|||
static void
|
||||
GetBaseDirectory(std::string &dir)
|
||||
{
|
||||
char *home = getenv("HOME");
|
||||
if(home) {
|
||||
dir = std::string(home) + "/.fceux";
|
||||
} else {
|
||||
char *home = getenv("HOME");
|
||||
if(home) {
|
||||
dir = std::string(home) + "/.fceux";
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
home = new char[MAX_PATH + 1];
|
||||
GetModuleFileName(NULL, home, MAX_PATH + 1);
|
||||
home = new char[MAX_PATH + 1];
|
||||
GetModuleFileName(NULL, home, MAX_PATH + 1);
|
||||
|
||||
char *lastBS = strrchr(home,'\\');
|
||||
if(lastBS) {
|
||||
*lastBS = 0;
|
||||
}
|
||||
char *lastBS = strrchr(home,'\\');
|
||||
if(lastBS) {
|
||||
*lastBS = 0;
|
||||
}
|
||||
|
||||
dir = std::string(home);
|
||||
delete[] home;
|
||||
dir = std::string(home);
|
||||
delete[] home;
|
||||
#else
|
||||
dir = "";
|
||||
dir = "";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns a config structure with default options
|
||||
|
@ -110,221 +110,221 @@ GetBaseDirectory(std::string &dir)
|
|||
Config *
|
||||
InitConfig()
|
||||
{
|
||||
std::string dir, prefix;
|
||||
Config *config;
|
||||
std::string dir, prefix;
|
||||
Config *config;
|
||||
|
||||
GetBaseDirectory(dir);
|
||||
GetBaseDirectory(dir);
|
||||
|
||||
FCEUI_SetBaseDirectory(dir.c_str());
|
||||
CreateDirs(dir);
|
||||
FCEUI_SetBaseDirectory(dir.c_str());
|
||||
CreateDirs(dir);
|
||||
|
||||
config = new Config(dir);
|
||||
config = new Config(dir);
|
||||
|
||||
// sound options
|
||||
config->addOption('s', "sound", "SDL.Sound", 1);
|
||||
config->addOption("volume", "SDL.Sound.Volume", 150);
|
||||
config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 256);
|
||||
config->addOption("square1vol", "SDL.Sound.Square1Volume", 256);
|
||||
config->addOption("square2vol", "SDL.Sound.Square2Volume", 256);
|
||||
config->addOption("noisevol", "SDL.Sound.NoiseVolume", 256);
|
||||
config->addOption("pcmvol", "SDL.Sound.PCMVolume", 256);
|
||||
config->addOption("soundrate", "SDL.Sound.Rate", 44100);
|
||||
config->addOption("soundq", "SDL.Sound.Quality", 1);
|
||||
config->addOption("soundrecord", "SDL.Sound.RecordFile", "");
|
||||
config->addOption("soundbufsize", "SDL.Sound.BufSize", 128);
|
||||
// sound options
|
||||
config->addOption('s', "sound", "SDL.Sound", 1);
|
||||
config->addOption("volume", "SDL.Sound.Volume", 150);
|
||||
config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 256);
|
||||
config->addOption("square1vol", "SDL.Sound.Square1Volume", 256);
|
||||
config->addOption("square2vol", "SDL.Sound.Square2Volume", 256);
|
||||
config->addOption("noisevol", "SDL.Sound.NoiseVolume", 256);
|
||||
config->addOption("pcmvol", "SDL.Sound.PCMVolume", 256);
|
||||
config->addOption("soundrate", "SDL.Sound.Rate", 44100);
|
||||
config->addOption("soundq", "SDL.Sound.Quality", 1);
|
||||
config->addOption("soundrecord", "SDL.Sound.RecordFile", "");
|
||||
config->addOption("soundbufsize", "SDL.Sound.BufSize", 128);
|
||||
config->addOption("lowpass", "SDL.Sound.LowPass", 0);
|
||||
|
||||
config->addOption('g', "gamegenie", "SDL.GameGenie", 0);
|
||||
config->addOption("pal", "SDL.PAL", 0);
|
||||
config->addOption("frameskip", "SDL.Frameskip", 0);
|
||||
config->addOption("clipsides", "SDL.ClipSides", 0);
|
||||
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);
|
||||
config->addOption('g', "gamegenie", "SDL.GameGenie", 0);
|
||||
config->addOption("pal", "SDL.PAL", 0);
|
||||
config->addOption("frameskip", "SDL.Frameskip", 0);
|
||||
config->addOption("clipsides", "SDL.ClipSides", 0);
|
||||
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);
|
||||
|
||||
// color control
|
||||
config->addOption('p', "palette", "SDL.Palette", "");
|
||||
config->addOption("tint", "SDL.Tint", 56);
|
||||
config->addOption("hue", "SDL.Hue", 72);
|
||||
config->addOption("ntsccolor", "SDL.NTSCpalette", 0);
|
||||
// color control
|
||||
config->addOption('p', "palette", "SDL.Palette", "");
|
||||
config->addOption("tint", "SDL.Tint", 56);
|
||||
config->addOption("hue", "SDL.Hue", 72);
|
||||
config->addOption("ntsccolor", "SDL.NTSCpalette", 0);
|
||||
|
||||
// scanline settings
|
||||
config->addOption("slstart", "SDL.ScanLineStart", 0);
|
||||
config->addOption("slend", "SDL.ScanLineEnd", 239);
|
||||
// scanline settings
|
||||
config->addOption("slstart", "SDL.ScanLineStart", 0);
|
||||
config->addOption("slend", "SDL.ScanLineEnd", 239);
|
||||
|
||||
// video controls
|
||||
config->addOption('x', "xres", "SDL.XResolution", 512);
|
||||
config->addOption('y', "yres", "SDL.YResolution", 448);
|
||||
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
|
||||
config->addOption('b', "bpp", "SDL.BitsPerPixel", 32);
|
||||
config->addOption("doublebuf", "SDL.DoubleBuffering", 0);
|
||||
config->addOption("autoscale", "SDL.AutoScale", 1);
|
||||
config->addOption("keepratio", "SDL.KeepRatio", 1);
|
||||
config->addOption("xscale", "SDL.XScale", 1.0);
|
||||
config->addOption("yscale", "SDL.YScale", 1.0);
|
||||
config->addOption("xstretch", "SDL.XStretch", 0);
|
||||
config->addOption("ystretch", "SDL.YStretch", 0);
|
||||
config->addOption("noframe", "SDL.NoFrame", 0);
|
||||
config->addOption("special", "SDL.SpecialFilter", 0);
|
||||
// video controls
|
||||
config->addOption('x', "xres", "SDL.XResolution", 512);
|
||||
config->addOption('y', "yres", "SDL.YResolution", 448);
|
||||
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
|
||||
config->addOption('b', "bpp", "SDL.BitsPerPixel", 32);
|
||||
config->addOption("doublebuf", "SDL.DoubleBuffering", 0);
|
||||
config->addOption("autoscale", "SDL.AutoScale", 1);
|
||||
config->addOption("keepratio", "SDL.KeepRatio", 1);
|
||||
config->addOption("xscale", "SDL.XScale", 1.0);
|
||||
config->addOption("yscale", "SDL.YScale", 1.0);
|
||||
config->addOption("xstretch", "SDL.XStretch", 0);
|
||||
config->addOption("ystretch", "SDL.YStretch", 0);
|
||||
config->addOption("noframe", "SDL.NoFrame", 0);
|
||||
config->addOption("special", "SDL.SpecialFilter", 0);
|
||||
|
||||
// OpenGL options
|
||||
config->addOption("opengl", "SDL.OpenGL", 0);
|
||||
config->addOption("openglip", "SDL.OpenGLip", 0);
|
||||
config->addOption("SDL.SpecialFilter", 0);
|
||||
config->addOption("SDL.SpecialFX", 0);
|
||||
config->addOption("SDL.Vsync", 1);
|
||||
// OpenGL options
|
||||
config->addOption("opengl", "SDL.OpenGL", 0);
|
||||
config->addOption("openglip", "SDL.OpenGLip", 0);
|
||||
config->addOption("SDL.SpecialFilter", 0);
|
||||
config->addOption("SDL.SpecialFX", 0);
|
||||
config->addOption("SDL.Vsync", 1);
|
||||
|
||||
// network play options - netplay is broken
|
||||
config->addOption("server", "SDL.NetworkIsServer", 0);
|
||||
config->addOption('n', "net", "SDL.NetworkIP", "");
|
||||
config->addOption('u', "user", "SDL.NetworkUsername", "");
|
||||
config->addOption('w', "pass", "SDL.NetworkPassword", "");
|
||||
config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
|
||||
config->addOption("port", "SDL.NetworkPort", 4046);
|
||||
config->addOption("players", "SDL.NetworkPlayers", 1);
|
||||
// network play options - netplay is broken
|
||||
config->addOption("server", "SDL.NetworkIsServer", 0);
|
||||
config->addOption('n', "net", "SDL.NetworkIP", "");
|
||||
config->addOption('u', "user", "SDL.NetworkUsername", "");
|
||||
config->addOption('w', "pass", "SDL.NetworkPassword", "");
|
||||
config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
|
||||
config->addOption("port", "SDL.NetworkPort", 4046);
|
||||
config->addOption("players", "SDL.NetworkPlayers", 1);
|
||||
|
||||
// input configuration options
|
||||
config->addOption("input1", "SDL.Input.0", "GamePad.0");
|
||||
config->addOption("input2", "SDL.Input.1", "GamePad.1");
|
||||
config->addOption("input3", "SDL.Input.2", "Gamepad.2");
|
||||
config->addOption("input4", "SDL.Input.3", "Gamepad.3");
|
||||
// input configuration options
|
||||
config->addOption("input1", "SDL.Input.0", "GamePad.0");
|
||||
config->addOption("input2", "SDL.Input.1", "GamePad.1");
|
||||
config->addOption("input3", "SDL.Input.2", "Gamepad.2");
|
||||
config->addOption("input4", "SDL.Input.3", "Gamepad.3");
|
||||
|
||||
// allow for input configuration
|
||||
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
|
||||
// allow for input configuration
|
||||
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
|
||||
|
||||
// display input
|
||||
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
|
||||
// display input
|
||||
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
|
||||
|
||||
// pause movie playback at frame x
|
||||
config->addOption("pauseframe", "SDL.PauseFrame", 0);
|
||||
config->addOption("recordhud", "SDL.RecordHUD", 1);
|
||||
config->addOption("moviemsg", "SDL.MovieMsg", 1);
|
||||
// pause movie playback at frame x
|
||||
config->addOption("pauseframe", "SDL.PauseFrame", 0);
|
||||
config->addOption("recordhud", "SDL.RecordHUD", 1);
|
||||
config->addOption("moviemsg", "SDL.MovieMsg", 1);
|
||||
|
||||
// overwrite the config file?
|
||||
config->addOption("no-config", "SDL.NoConfig", 0);
|
||||
// overwrite the config file?
|
||||
config->addOption("no-config", "SDL.NoConfig", 0);
|
||||
|
||||
// video playback
|
||||
config->addOption("playmov", "SDL.Movie", "");
|
||||
config->addOption("subtitles", "SDL.SubtitleDisplay", 1);
|
||||
// video playback
|
||||
config->addOption("playmov", "SDL.Movie", "");
|
||||
config->addOption("subtitles", "SDL.SubtitleDisplay", 1);
|
||||
|
||||
config->addOption("fourscore", "SDL.FourScore", 0);
|
||||
|
||||
config->addOption("nofscursor", "SDL.NoFullscreenCursor", 1);
|
||||
|
||||
#ifdef _S9XLUA_H
|
||||
// load lua script
|
||||
config->addOption("loadlua", "SDL.LuaScript", "");
|
||||
// load lua script
|
||||
config->addOption("loadlua", "SDL.LuaScript", "");
|
||||
#endif
|
||||
|
||||
#ifdef CREATE_AVI
|
||||
config->addOption("videolog", "SDL.VideoLog", "");
|
||||
config->addOption("mute", "SDL.MuteCapture", 0);
|
||||
config->addOption("videolog", "SDL.VideoLog", "");
|
||||
config->addOption("mute", "SDL.MuteCapture", 0);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _GTK
|
||||
char* home_dir = getenv("HOME");
|
||||
// prefixed with _ because they are internal (not cli options)
|
||||
config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir);
|
||||
config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir);
|
||||
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
|
||||
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
|
||||
config->addOption("_lastloadlua", "SDL.LastLoadLua", home_dir);
|
||||
char* home_dir = getenv("HOME");
|
||||
// prefixed with _ because they are internal (not cli options)
|
||||
config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir);
|
||||
config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir);
|
||||
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
|
||||
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
|
||||
config->addOption("_lastloadlua", "SDL.LastLoadLua", home_dir);
|
||||
#endif
|
||||
|
||||
// fcm -> fm2 conversion
|
||||
config->addOption("fcmconvert", "SDL.FCMConvert", "");
|
||||
// fcm -> fm2 conversion
|
||||
config->addOption("fcmconvert", "SDL.FCMConvert", "");
|
||||
|
||||
// fm2 -> srt conversion
|
||||
config->addOption("ripsubs", "SDL.RipSubs", "");
|
||||
// fm2 -> srt conversion
|
||||
config->addOption("ripsubs", "SDL.RipSubs", "");
|
||||
|
||||
// enable new PPU core
|
||||
config->addOption("newppu", "SDL.NewPPU", 0);
|
||||
|
||||
|
||||
// GamePad 0 - 3
|
||||
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.GamePad.%d.", i);
|
||||
prefix = buf;
|
||||
// GamePad 0 - 3
|
||||
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.GamePad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
|
||||
}
|
||||
}
|
||||
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// PowerPad 0 - 1
|
||||
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i);
|
||||
prefix = buf;
|
||||
// PowerPad 0 - 1
|
||||
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]);
|
||||
}
|
||||
}
|
||||
config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// QuizKing
|
||||
prefix = "SDL.Input.QuizKing.";
|
||||
config->addOption(prefix + "DeviceType", DefaultQuizKingDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]);
|
||||
}
|
||||
// QuizKing
|
||||
prefix = "SDL.Input.QuizKing.";
|
||||
config->addOption(prefix + "DeviceType", DefaultQuizKingDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]);
|
||||
}
|
||||
|
||||
// HyperShot
|
||||
prefix = "SDL.Input.HyperShot.";
|
||||
config->addOption(prefix + "DeviceType", DefaultHyperShotDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]);
|
||||
}
|
||||
// HyperShot
|
||||
prefix = "SDL.Input.HyperShot.";
|
||||
config->addOption(prefix + "DeviceType", DefaultHyperShotDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]);
|
||||
}
|
||||
|
||||
// Mahjong
|
||||
prefix = "SDL.Input.Mahjong.";
|
||||
config->addOption(prefix + "DeviceType", DefaultMahjongDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]);
|
||||
}
|
||||
// Mahjong
|
||||
prefix = "SDL.Input.Mahjong.";
|
||||
config->addOption(prefix + "DeviceType", DefaultMahjongDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]);
|
||||
}
|
||||
|
||||
// TopRider
|
||||
prefix = "SDL.Input.TopRider.";
|
||||
config->addOption(prefix + "DeviceType", DefaultTopRiderDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]);
|
||||
}
|
||||
// TopRider
|
||||
prefix = "SDL.Input.TopRider.";
|
||||
config->addOption(prefix + "DeviceType", DefaultTopRiderDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]);
|
||||
}
|
||||
|
||||
// FTrainer
|
||||
prefix = "SDL.Input.FTrainer.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFTrainerDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]);
|
||||
}
|
||||
// FTrainer
|
||||
prefix = "SDL.Input.FTrainer.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFTrainerDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]);
|
||||
}
|
||||
|
||||
// FamilyKeyBoard
|
||||
prefix = "SDL.Input.FamilyKeyBoard.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FamilyKeyBoardNames[j],
|
||||
DefaultFamilyKeyBoard[j]);
|
||||
}
|
||||
// FamilyKeyBoard
|
||||
prefix = "SDL.Input.FamilyKeyBoard.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FamilyKeyBoardNames[j],
|
||||
DefaultFamilyKeyBoard[j]);
|
||||
}
|
||||
|
||||
// for FAMICOM microphone in pad 2 pad 1 didn't have it
|
||||
// Takeshi no Chousenjou uses it for example.
|
||||
prefix = "SDL.Input.FamicomPad2.";
|
||||
config->addOption("rp2mic", prefix + "EnableMic", 0);
|
||||
|
||||
// for FAMICOM microphone in pad 2 pad 1 didn't have it
|
||||
// Takeshi no Chousenjou uses it for example.
|
||||
prefix = "SDL.Input.FamicomPad2.";
|
||||
config->addOption("rp2mic", prefix + "EnableMic", 0);
|
||||
|
||||
// this is really hacky
|
||||
// TODO clean this up; clean config.h as well
|
||||
const int Hotkeys[HK_MAX] = {
|
||||
// TODO: use a better data structure to store the hotkeys or something
|
||||
// improve this code overall in the future to make it
|
||||
// easier to maintain
|
||||
const int Hotkeys[HK_MAX] = {
|
||||
SDLK_F1, // cheat menu
|
||||
SDLK_F2, // bind state
|
||||
SDLK_F3, // load lua
|
||||
|
@ -352,100 +352,66 @@ InitConfig()
|
|||
SDLK_SLASH, // lag counter display
|
||||
SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5,
|
||||
SDLK_6, SDLK_7, SDLK_8, SDLK_9,
|
||||
SDLK_PAGEUP, // select state next
|
||||
SDLK_PAGEDOWN}; // select state prev
|
||||
|
||||
prefix = "SDL.Hotkeys.";
|
||||
for(int i=0; i < HK_MAX; i++)
|
||||
SDLK_PAGEUP, // select state next
|
||||
SDLK_PAGEDOWN}; // select state prev
|
||||
|
||||
prefix = "SDL.Hotkeys.";
|
||||
for(int i=0; i < HK_MAX; i++)
|
||||
config->addOption(prefix + HotkeyStrings[i], Hotkeys[i]);
|
||||
|
||||
/*
|
||||
config->addOption(prefix + "Pause", SDLK_PAUSE);
|
||||
config->addOption(prefix + "DecreaseSpeed", SDLK_MINUS);
|
||||
config->addOption(prefix + "IncreaseSpeed", SDLK_EQUALS);
|
||||
config->addOption(prefix + "FrameAdvance", SDLK_BACKSLASH);
|
||||
config->addOption(prefix + "FastForward", SDLK_TAB);
|
||||
config->addOption(prefix + "InputDisplay", SDLK_i);
|
||||
config->addOption(prefix + "MovieToggleReadWrite", SDLK_q);
|
||||
#ifdef CREATE_AVI
|
||||
config->addOption(prefix + "MuteCapture", SDLK_DELETE);
|
||||
#endif
|
||||
config->addOption(prefix + "Quit", SDLK_ESCAPE);
|
||||
//config->addOption(prefix + "Power", 0);
|
||||
|
||||
|
||||
|
||||
|
||||
config->addOption(prefix + "SelectState0", SDLK_0);
|
||||
config->addOption(prefix + "SelectState1", SDLK_1);
|
||||
config->addOption(prefix + "SelectState2", SDLK_2);
|
||||
config->addOption(prefix + "SelectState3", SDLK_3);
|
||||
config->addOption(prefix + "SelectState4", SDLK_4);
|
||||
config->addOption(prefix + "SelectState5", SDLK_5);
|
||||
config->addOption(prefix + "SelectState6", SDLK_6);
|
||||
config->addOption(prefix + "SelectState7", SDLK_7);
|
||||
config->addOption(prefix + "SelectState8", SDLK_8);
|
||||
config->addOption(prefix + "SelectState9", SDLK_9);
|
||||
|
||||
*/
|
||||
// All mouse devices
|
||||
config->addOption("SDL.OekaKids.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.OekaKids.0.DeviceNum", 0);
|
||||
|
||||
// All mouse devices
|
||||
config->addOption("SDL.OekaKids.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.OekaKids.0.DeviceNum", 0);
|
||||
config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Arkanoid.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Arkanoid.0.DeviceNum", 0);
|
||||
config->addOption("SDL.Shadow.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Shadow.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Shadow.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Shadow.0.DeviceNum", 0);
|
||||
config->addOption("SDL.Zapper.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Zapper.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Zapper.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Zapper.0.DeviceNum", 0);
|
||||
|
||||
return config;
|
||||
return config;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateEMUCore(Config *config)
|
||||
{
|
||||
int ntsccol, ntsctint, ntschue, flag, start, end;
|
||||
std::string cpalette;
|
||||
int ntsccol, ntsctint, ntschue, flag, start, end;
|
||||
std::string cpalette;
|
||||
|
||||
config->getOption("SDL.NTSCpalette", &ntsccol);
|
||||
config->getOption("SDL.Tint", &ntsctint);
|
||||
config->getOption("SDL.Hue", &ntschue);
|
||||
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||
config->getOption("SDL.NTSCpalette", &ntsccol);
|
||||
config->getOption("SDL.Tint", &ntsctint);
|
||||
config->getOption("SDL.Hue", &ntschue);
|
||||
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||
|
||||
config->getOption("SDL.Palette", &cpalette);
|
||||
if(cpalette.size()) {
|
||||
LoadCPalette(cpalette);
|
||||
}
|
||||
config->getOption("SDL.Palette", &cpalette);
|
||||
if(cpalette.size()) {
|
||||
LoadCPalette(cpalette);
|
||||
}
|
||||
|
||||
config->getOption("SDL.PAL", &flag);
|
||||
FCEUI_SetVidSystem(flag ? 1 : 0);
|
||||
config->getOption("SDL.PAL", &flag);
|
||||
FCEUI_SetVidSystem(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.GameGenie", &flag);
|
||||
FCEUI_SetGameGenie(flag ? 1 : 0);
|
||||
config->getOption("SDL.GameGenie", &flag);
|
||||
FCEUI_SetGameGenie(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.Sound.LowPass", &flag);
|
||||
FCEUI_SetLowPass(flag ? 1 : 0);
|
||||
config->getOption("SDL.Sound.LowPass", &flag);
|
||||
FCEUI_SetLowPass(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.DisableSpriteLimit", &flag);
|
||||
FCEUI_DisableSpriteLimitation(flag ? 1 : 0);
|
||||
config->getOption("SDL.DisableSpriteLimit", &flag);
|
||||
FCEUI_DisableSpriteLimitation(flag ? 1 : 0);
|
||||
|
||||
//Not used anymore.
|
||||
//config->getOption("SDL.SnapName", &flag);
|
||||
//FCEUI_SetSnapName(flag ? true : false);
|
||||
|
||||
config->getOption("SDL.ScanLineStart", &start);
|
||||
config->getOption("SDL.ScanLineEnd", &end);
|
||||
config->getOption("SDL.ScanLineStart", &start);
|
||||
config->getOption("SDL.ScanLineEnd", &end);
|
||||
|
||||
#if DOING_SCANLINE_CHECKS
|
||||
for(int i = 0; i < 2; x++) {
|
||||
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
||||
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
||||
}
|
||||
for(int i = 0; i < 2; x++) {
|
||||
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
||||
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
||||
}
|
||||
#endif
|
||||
|
||||
FCEUI_SetRenderedLines(start + 8, end - 8, start, end);
|
||||
FCEUI_SetRenderedLines(start + 8, end - 8, start, end);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,8 @@ Config *InitConfig(void);
|
|||
void UpdateEMUCore(Config *);
|
||||
int LoadCPalette(const std::string &file);
|
||||
|
||||
|
||||
// hotkey definitions
|
||||
|
||||
|
||||
// TODO: encapsulate this in an improved data structure
|
||||
enum HOTKEY { HK_CHEAT_MENU, HK_BIND_STATE, HK_LOAD_LUA, HK_TOGGLE_BG,
|
||||
HK_SAVE_STATE, HK_FDS_SELECT, HK_LOAD_STATE, HK_FDS_EJECT ,
|
||||
HK_VS_INSERT_COIN, HK_VS_TOGGLE_DIPSWITCH,
|
||||
|
@ -20,7 +18,7 @@ enum HOTKEY { HK_CHEAT_MENU, HK_BIND_STATE, HK_LOAD_LUA, HK_TOGGLE_BG,
|
|||
HK_SELECT_STATE_0, HK_SELECT_STATE_1, HK_SELECT_STATE_2, HK_SELECT_STATE_3,
|
||||
HK_SELECT_STATE_4, HK_SELECT_STATE_5, HK_SELECT_STATE_6, HK_SELECT_STATE_7,
|
||||
HK_SELECT_STATE_8, HK_SELECT_STATE_9,
|
||||
HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV};
|
||||
HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV};
|
||||
|
||||
const int HK_MAX = 37;
|
||||
|
||||
|
@ -53,5 +51,5 @@ static const char* HotkeyStrings[HK_MAX] = {
|
|||
"SelectState0", "SelectState1", "SelectState2", "SelectState3",
|
||||
"SelectState4", "SelectState5", "SelectState6", "SelectState7",
|
||||
"SelectState8", "SelectState9", "SelectStateNext", "SelectStatePrev" };
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ uint32 GetWriteSound(void);
|
|||
|
||||
void SilenceSound(int s); /* DOS and SDL */
|
||||
|
||||
|
||||
int InitJoysticks(void);
|
||||
int KillJoysticks(void);
|
||||
uint32 *GetJSOr(void);
|
||||
|
@ -37,4 +36,3 @@ void DoFun(void);
|
|||
|
||||
int FCEUD_NetworkConnect(void);
|
||||
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#ifdef _GTK3
|
||||
#include <gdk/gdkkeysyms-compat.h>
|
||||
#endif
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "../../types.h"
|
||||
#include "../../fceu.h"
|
||||
#include "../../driver.h"
|
||||
|
@ -18,9 +19,8 @@
|
|||
#include "../../movie.h"
|
||||
#include "../../palette.h"
|
||||
#include "../../fds.h"
|
||||
|
||||
|
||||
#include "../common/configSys.h"
|
||||
|
||||
#include "sdl.h"
|
||||
#include "gui.h"
|
||||
#include "dface.h"
|
||||
|
@ -65,7 +65,7 @@ int configGamepadButton(GtkButton* button, gpointer p)
|
|||
|
||||
// only configure when the "Change" button is pressed in, not when it is unpressed
|
||||
if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
ButtonConfigBegin();
|
||||
|
||||
|
@ -113,7 +113,6 @@ void toggleLowPass(GtkWidget* w, gpointer p)
|
|||
FCEUI_SetLowPass(0);
|
||||
}
|
||||
g_config->save();
|
||||
|
||||
}
|
||||
|
||||
// Wrapper for pushing GTK options into the config file
|
||||
|
@ -160,8 +159,8 @@ void loadPalette (GtkWidget* w, gpointer p)
|
|||
fileChooser = gtk_file_chooser_dialog_new ("Open NES Palette", GTK_WINDOW(MainWindow),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
|
||||
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), getcwd(NULL, 0));
|
||||
|
||||
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), getcwd(NULL, 0));
|
||||
|
||||
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
char* filename;
|
||||
|
@ -178,7 +177,7 @@ void loadPalette (GtkWidget* w, gpointer p)
|
|||
gtk_dialog_run(GTK_DIALOG(msgbox));
|
||||
gtk_widget_hide(msgbox);
|
||||
}
|
||||
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(p), filename);
|
||||
|
||||
}
|
||||
|
@ -235,15 +234,12 @@ void openPaletteConfig()
|
|||
g_signal_connect(paletteButton, "clicked", G_CALLBACK(loadPalette), paletteEntry);
|
||||
g_signal_connect(clearButton, "clicked", G_CALLBACK(clearPalette), paletteEntry);
|
||||
|
||||
|
||||
|
||||
// sync with config
|
||||
std::string fn;
|
||||
g_config->getOption("SDL.Palette", &fn);
|
||||
gtk_entry_set_text(GTK_ENTRY(paletteEntry), fn.c_str());
|
||||
|
||||
// ntsc color check
|
||||
|
||||
ntscColorChk = gtk_check_button_new_with_label("Use NTSC palette");
|
||||
|
||||
g_signal_connect(ntscColorChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.NTSCpalette");
|
||||
|
@ -255,8 +251,7 @@ void openPaletteConfig()
|
|||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ntscColorChk), 1);
|
||||
else
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ntscColorChk), 0);
|
||||
|
||||
|
||||
|
||||
// color / tint / hue sliders
|
||||
slidersFrame = gtk_frame_new("NTSC palette controls");
|
||||
slidersVbox = gtk_vbox_new(FALSE, 2);
|
||||
|
@ -360,7 +355,6 @@ void openNetworkConfig()
|
|||
|
||||
g_signal_connect(userEntry, "changed", G_CALLBACK(setUsername), NULL);
|
||||
|
||||
|
||||
frame = gtk_frame_new("Network options");
|
||||
vbox = gtk_vbox_new(FALSE, 5);
|
||||
ipBox = gtk_hbox_new(FALSE, 5);
|
||||
|
@ -970,7 +964,6 @@ int mixerChanged(GtkWidget* w, gpointer p)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void openSoundConfig()
|
||||
{
|
||||
|
@ -992,20 +985,17 @@ void openSoundConfig()
|
|||
GtkWidget* mixerHbox;
|
||||
GtkWidget* mixers[6];
|
||||
GtkWidget* mixerFrames[6];
|
||||
|
||||
|
||||
|
||||
win = gtk_dialog_new_with_buttons("Sound Preferences",
|
||||
GTK_WINDOW(MainWindow),
|
||||
(GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
|
||||
GTK_STOCK_CLOSE,
|
||||
GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
GTK_WINDOW(MainWindow),
|
||||
(GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
|
||||
GTK_STOCK_CLOSE,
|
||||
GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
gtk_window_set_icon_name(GTK_WINDOW(win), "audio-x-generic");
|
||||
main_hbox = gtk_hbox_new(FALSE, 15);
|
||||
vbox = gtk_vbox_new(False, 5);
|
||||
//gtk_widget_set_size_request(win, 300, 200);
|
||||
|
||||
|
||||
|
||||
// sound enable check
|
||||
soundChk = gtk_check_button_new_with_label("Enable sound");
|
||||
|
||||
|
@ -1017,9 +1007,7 @@ void openSoundConfig()
|
|||
else
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(soundChk), FALSE);
|
||||
|
||||
g_signal_connect(soundChk, "clicked",
|
||||
G_CALLBACK(toggleSound), NULL);
|
||||
|
||||
g_signal_connect(soundChk, "clicked", G_CALLBACK(toggleSound), NULL);
|
||||
|
||||
// low pass filter check
|
||||
lowpassChk = gtk_check_button_new_with_label("Enable low pass filter");
|
||||
|
@ -1076,8 +1064,7 @@ void openSoundConfig()
|
|||
gtk_combo_box_set_active(GTK_COMBO_BOX(rateCombo), i);
|
||||
|
||||
g_signal_connect(rateCombo, "changed", G_CALLBACK(setRate), NULL);
|
||||
|
||||
|
||||
|
||||
// sound rate widgets
|
||||
rateLbl = gtk_label_new("Rate (Hz): ");
|
||||
|
||||
|
@ -1087,15 +1074,13 @@ void openSoundConfig()
|
|||
hbox3 = gtk_hbox_new(FALSE, 2);
|
||||
bufferHscale = gtk_hscale_new_with_range(15, 200, 2);
|
||||
bufferLbl = gtk_label_new("Buffer size (in ms)");
|
||||
|
||||
|
||||
// sync widget with cfg
|
||||
g_config->getOption("SDL.Sound.BufSize", &cfgBuf);
|
||||
gtk_range_set_value(GTK_RANGE(bufferHscale), cfgBuf);
|
||||
|
||||
g_signal_connect(bufferHscale, "button-release-event", G_CALLBACK(setBufSize), NULL);
|
||||
|
||||
|
||||
|
||||
// mixer
|
||||
mixerFrame = gtk_frame_new("Mixer:");
|
||||
mixerHbox = gtk_hbox_new(TRUE, 5);
|
||||
|
@ -1156,10 +1141,10 @@ void quit ()
|
|||
// it raises a GTK-Critical when its called
|
||||
//gtk_main_quit();
|
||||
FCEUI_Kill();
|
||||
// LoadGame() checks for an IP and if it finds one begins a network session
|
||||
// clear the NetworkIP field so this doesn't happen unintentionally
|
||||
g_config->setOption("SDL.NetworkIP", "");
|
||||
g_config->save();
|
||||
// LoadGame() checks for an IP and if it finds one begins a network session
|
||||
// clear the NetworkIP field so this doesn't happen unintentionally
|
||||
g_config->setOption("SDL.NetworkIP", "");
|
||||
g_config->save();
|
||||
SDL_Quit();
|
||||
exit(0);
|
||||
}
|
||||
|
@ -1229,7 +1214,6 @@ void hardReset ()
|
|||
resizeGtkWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void enableFullscreen ()
|
||||
{
|
||||
|
@ -1369,7 +1353,7 @@ void loadLua ()
|
|||
char* filename;
|
||||
|
||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
|
||||
g_config->setOption("SDL.LastLoadLua", filename);
|
||||
g_config->setOption("SDL.LastLoadLua", filename);
|
||||
gtk_widget_destroy(fileChooser);
|
||||
if(FCEU_LoadLuaCode(filename) == 0)
|
||||
{
|
||||
|
@ -1523,7 +1507,7 @@ void loadGameGenie ()
|
|||
"Game Genie ROM copied to ~/.fceux/gg.rom.");
|
||||
gtk_dialog_run(GTK_DIALOG(d));
|
||||
gtk_widget_destroy(d);
|
||||
|
||||
|
||||
f2<<f1.rdbuf();
|
||||
g_free(filename);
|
||||
}
|
||||
|
@ -1722,7 +1706,7 @@ void saveStateAs()
|
|||
void loadStateFrom()
|
||||
{
|
||||
GtkWidget* fileChooser;
|
||||
GtkFileFilter* filterFcs;
|
||||
GtkFileFilter* filterFcs;
|
||||
GtkFileFilter* filterSav;
|
||||
GtkFileFilter* filterAll;
|
||||
|
||||
|
@ -1731,7 +1715,7 @@ void loadStateFrom()
|
|||
gtk_file_filter_add_pattern(filterSav, "*.SAV");
|
||||
gtk_file_filter_set_name(filterSav, "SAV files");
|
||||
|
||||
filterFcs = gtk_file_filter_new();
|
||||
filterFcs = gtk_file_filter_new();
|
||||
gtk_file_filter_add_pattern(filterFcs, "*.fc?");
|
||||
gtk_file_filter_add_pattern(filterFcs, "*.FC?");
|
||||
gtk_file_filter_set_name(filterFcs, "FCS files");
|
||||
|
|
Loading…
Reference in New Issue