sdl: code cleanup; pre-release code review (in progress)

This commit is contained in:
punkrockguy318 2012-03-06 11:12:28 +00:00
parent 118b82544c
commit b0c2758324
22 changed files with 8298 additions and 8302 deletions

View File

@ -1,417 +1,417 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <signal.h> #include <signal.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "main.h" #include "main.h"
#include "throttle.h" #include "throttle.h"
#include "config.h" #include "config.h"
#include "../common/cheat.h" #include "../common/cheat.h"
#include "input.h" #include "input.h"
#include "dface.h" #include "dface.h"
#include "sdl.h" #include "sdl.h"
#include "sdl-video.h" #include "sdl-video.h"
#include "unix-netplay.h" #include "unix-netplay.h"
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
#endif #endif
/** /**
* Read a custom pallete from a file and load it into the core. * Read a custom pallete from a file and load it into the core.
*/ */
int int
LoadCPalette(const std::string &file) LoadCPalette(const std::string &file)
{ {
uint8 tmpp[192]; uint8 tmpp[192];
FILE *fp; FILE *fp;
if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) { if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) {
printf(" Error loading custom palette from file: %s\n", file.c_str()); printf(" Error loading custom palette from file: %s\n", file.c_str());
return 0; return 0;
} }
size_t result = fread(tmpp, 1, 192, fp); size_t result = fread(tmpp, 1, 192, fp);
if(result != 192) { if(result != 192) {
printf(" Error reading custom palette from file: %s\n", file.c_str()); printf(" Error reading custom palette from file: %s\n", file.c_str());
return 0; return 0;
} }
FCEUI_SetPaletteArray(tmpp); FCEUI_SetPaletteArray(tmpp);
fclose(fp); fclose(fp);
return 1; return 1;
} }
/** /**
* Creates the subdirectories used for saving snapshots, movies, game * Creates the subdirectories used for saving snapshots, movies, game
* saves, etc. Hopefully obsolete with new configuration system. * saves, etc. Hopefully obsolete with new configuration system.
*/ */
static void static void
CreateDirs(const std::string &dir) CreateDirs(const std::string &dir)
{ {
char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"}; char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
std::string subdir; std::string subdir;
int x; int x;
#if defined(WIN32) || defined(NEED_MINGW_HACKS) #if defined(WIN32) || defined(NEED_MINGW_HACKS)
mkdir(dir.c_str()); mkdir(dir.c_str());
chmod(dir.c_str(), 755); chmod(dir.c_str(), 755);
for(x = 0; x < 6; x++) { for(x = 0; x < 6; x++) {
subdir = dir + PSS + subs[x]; subdir = dir + PSS + subs[x];
mkdir(subdir.c_str()); mkdir(subdir.c_str());
} }
#else #else
mkdir(dir.c_str(), S_IRWXU); mkdir(dir.c_str(), S_IRWXU);
for(x = 0; x < 6; x++) { for(x = 0; x < 6; x++) {
subdir = dir + PSS + subs[x]; subdir = dir + PSS + subs[x];
mkdir(subdir.c_str(), S_IRWXU); mkdir(subdir.c_str(), S_IRWXU);
} }
#endif #endif
} }
/** /**
* Attempts to locate FCEU's application directory. This will * Attempts to locate FCEU's application directory. This will
* hopefully become obsolete once the new configuration system is in * hopefully become obsolete once the new configuration system is in
* place. * place.
*/ */
static void static void
GetBaseDirectory(std::string &dir) GetBaseDirectory(std::string &dir)
{ {
char *home = getenv("HOME"); char *home = getenv("HOME");
if(home) { if(home) {
dir = std::string(home) + "/.fceux"; dir = std::string(home) + "/.fceux";
} else { } else {
#ifdef WIN32 #ifdef WIN32
home = new char[MAX_PATH + 1]; home = new char[MAX_PATH + 1];
GetModuleFileName(NULL, home, MAX_PATH + 1); GetModuleFileName(NULL, home, MAX_PATH + 1);
char *lastBS = strrchr(home,'\\'); char *lastBS = strrchr(home,'\\');
if(lastBS) { if(lastBS) {
*lastBS = 0; *lastBS = 0;
} }
dir = std::string(home); dir = std::string(home);
delete[] home; delete[] home;
#else #else
dir = ""; dir = "";
#endif #endif
} }
} }
// returns a config structure with default options // returns a config structure with default options
// also creates config base directory (ie: /home/user/.fceux as well as subdirs // also creates config base directory (ie: /home/user/.fceux as well as subdirs
Config * Config *
InitConfig() InitConfig()
{ {
std::string dir, prefix; std::string dir, prefix;
Config *config; Config *config;
GetBaseDirectory(dir); GetBaseDirectory(dir);
FCEUI_SetBaseDirectory(dir.c_str()); FCEUI_SetBaseDirectory(dir.c_str());
CreateDirs(dir); CreateDirs(dir);
config = new Config(dir); config = new Config(dir);
// sound options // sound options
config->addOption('s', "sound", "SDL.Sound", 1); config->addOption('s', "sound", "SDL.Sound", 1);
config->addOption("volume", "SDL.Sound.Volume", 150); config->addOption("volume", "SDL.Sound.Volume", 150);
config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 256); config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 256);
config->addOption("square1vol", "SDL.Sound.Square1Volume", 256); config->addOption("square1vol", "SDL.Sound.Square1Volume", 256);
config->addOption("square2vol", "SDL.Sound.Square2Volume", 256); config->addOption("square2vol", "SDL.Sound.Square2Volume", 256);
config->addOption("noisevol", "SDL.Sound.NoiseVolume", 256); config->addOption("noisevol", "SDL.Sound.NoiseVolume", 256);
config->addOption("pcmvol", "SDL.Sound.PCMVolume", 256); config->addOption("pcmvol", "SDL.Sound.PCMVolume", 256);
config->addOption("soundrate", "SDL.Sound.Rate", 44100); config->addOption("soundrate", "SDL.Sound.Rate", 44100);
config->addOption("soundq", "SDL.Sound.Quality", 1); config->addOption("soundq", "SDL.Sound.Quality", 1);
config->addOption("soundrecord", "SDL.Sound.RecordFile", ""); config->addOption("soundrecord", "SDL.Sound.RecordFile", "");
config->addOption("soundbufsize", "SDL.Sound.BufSize", 128); config->addOption("soundbufsize", "SDL.Sound.BufSize", 128);
config->addOption("lowpass", "SDL.Sound.LowPass", 0); config->addOption("lowpass", "SDL.Sound.LowPass", 0);
config->addOption('g', "gamegenie", "SDL.GameGenie", 0); config->addOption('g', "gamegenie", "SDL.GameGenie", 0);
config->addOption("pal", "SDL.PAL", 0); config->addOption("pal", "SDL.PAL", 0);
config->addOption("frameskip", "SDL.Frameskip", 0); config->addOption("frameskip", "SDL.Frameskip", 0);
config->addOption("clipsides", "SDL.ClipSides", 0); config->addOption("clipsides", "SDL.ClipSides", 0);
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1); config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);
// color control // color control
config->addOption('p', "palette", "SDL.Palette", ""); config->addOption('p', "palette", "SDL.Palette", "");
config->addOption("tint", "SDL.Tint", 56); config->addOption("tint", "SDL.Tint", 56);
config->addOption("hue", "SDL.Hue", 72); config->addOption("hue", "SDL.Hue", 72);
config->addOption("ntsccolor", "SDL.NTSCpalette", 0); config->addOption("ntsccolor", "SDL.NTSCpalette", 0);
// scanline settings // scanline settings
config->addOption("slstart", "SDL.ScanLineStart", 0); config->addOption("slstart", "SDL.ScanLineStart", 0);
config->addOption("slend", "SDL.ScanLineEnd", 239); config->addOption("slend", "SDL.ScanLineEnd", 239);
// video controls // video controls
config->addOption('x', "xres", "SDL.XResolution", 512); config->addOption('x', "xres", "SDL.XResolution", 512);
config->addOption('y', "yres", "SDL.YResolution", 448); config->addOption('y', "yres", "SDL.YResolution", 448);
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0); config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
config->addOption('b', "bpp", "SDL.BitsPerPixel", 32); config->addOption('b', "bpp", "SDL.BitsPerPixel", 32);
config->addOption("doublebuf", "SDL.DoubleBuffering", 0); config->addOption("doublebuf", "SDL.DoubleBuffering", 0);
config->addOption("autoscale", "SDL.AutoScale", 1); config->addOption("autoscale", "SDL.AutoScale", 1);
config->addOption("keepratio", "SDL.KeepRatio", 1); config->addOption("keepratio", "SDL.KeepRatio", 1);
config->addOption("xscale", "SDL.XScale", 1.0); config->addOption("xscale", "SDL.XScale", 1.0);
config->addOption("yscale", "SDL.YScale", 1.0); config->addOption("yscale", "SDL.YScale", 1.0);
config->addOption("xstretch", "SDL.XStretch", 0); config->addOption("xstretch", "SDL.XStretch", 0);
config->addOption("ystretch", "SDL.YStretch", 0); config->addOption("ystretch", "SDL.YStretch", 0);
config->addOption("noframe", "SDL.NoFrame", 0); config->addOption("noframe", "SDL.NoFrame", 0);
config->addOption("special", "SDL.SpecialFilter", 0); config->addOption("special", "SDL.SpecialFilter", 0);
// OpenGL options // OpenGL options
config->addOption("opengl", "SDL.OpenGL", 0); config->addOption("opengl", "SDL.OpenGL", 0);
config->addOption("openglip", "SDL.OpenGLip", 0); config->addOption("openglip", "SDL.OpenGLip", 0);
config->addOption("SDL.SpecialFilter", 0); config->addOption("SDL.SpecialFilter", 0);
config->addOption("SDL.SpecialFX", 0); config->addOption("SDL.SpecialFX", 0);
config->addOption("SDL.Vsync", 1); config->addOption("SDL.Vsync", 1);
// network play options - netplay is broken // network play options - netplay is broken
config->addOption("server", "SDL.NetworkIsServer", 0); config->addOption("server", "SDL.NetworkIsServer", 0);
config->addOption('n', "net", "SDL.NetworkIP", ""); config->addOption('n', "net", "SDL.NetworkIP", "");
config->addOption('u', "user", "SDL.NetworkUsername", ""); config->addOption('u', "user", "SDL.NetworkUsername", "");
config->addOption('w', "pass", "SDL.NetworkPassword", ""); config->addOption('w', "pass", "SDL.NetworkPassword", "");
config->addOption('k', "netkey", "SDL.NetworkGameKey", ""); config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
config->addOption("port", "SDL.NetworkPort", 4046); config->addOption("port", "SDL.NetworkPort", 4046);
config->addOption("players", "SDL.NetworkPlayers", 1); config->addOption("players", "SDL.NetworkPlayers", 1);
// input configuration options // input configuration options
config->addOption("input1", "SDL.Input.0", "GamePad.0"); config->addOption("input1", "SDL.Input.0", "GamePad.0");
config->addOption("input2", "SDL.Input.1", "GamePad.1"); config->addOption("input2", "SDL.Input.1", "GamePad.1");
config->addOption("input3", "SDL.Input.2", "Gamepad.2"); config->addOption("input3", "SDL.Input.2", "Gamepad.2");
config->addOption("input4", "SDL.Input.3", "Gamepad.3"); config->addOption("input4", "SDL.Input.3", "Gamepad.3");
// allow for input configuration // allow for input configuration
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg); config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
// display input // display input
config->addOption("inputdisplay", "SDL.InputDisplay", 0); config->addOption("inputdisplay", "SDL.InputDisplay", 0);
// pause movie playback at frame x // pause movie playback at frame x
config->addOption("pauseframe", "SDL.PauseFrame", 0); config->addOption("pauseframe", "SDL.PauseFrame", 0);
config->addOption("recordhud", "SDL.RecordHUD", 1); config->addOption("recordhud", "SDL.RecordHUD", 1);
config->addOption("moviemsg", "SDL.MovieMsg", 1); config->addOption("moviemsg", "SDL.MovieMsg", 1);
// overwrite the config file? // overwrite the config file?
config->addOption("no-config", "SDL.NoConfig", 0); config->addOption("no-config", "SDL.NoConfig", 0);
// video playback // video playback
config->addOption("playmov", "SDL.Movie", ""); config->addOption("playmov", "SDL.Movie", "");
config->addOption("subtitles", "SDL.SubtitleDisplay", 1); config->addOption("subtitles", "SDL.SubtitleDisplay", 1);
config->addOption("fourscore", "SDL.FourScore", 0); config->addOption("fourscore", "SDL.FourScore", 0);
config->addOption("nofscursor", "SDL.NoFullscreenCursor", 1); config->addOption("nofscursor", "SDL.NoFullscreenCursor", 1);
#ifdef _S9XLUA_H #ifdef _S9XLUA_H
// load lua script // load lua script
config->addOption("loadlua", "SDL.LuaScript", ""); config->addOption("loadlua", "SDL.LuaScript", "");
#endif #endif
#ifdef CREATE_AVI #ifdef CREATE_AVI
config->addOption("videolog", "SDL.VideoLog", ""); config->addOption("videolog", "SDL.VideoLog", "");
config->addOption("mute", "SDL.MuteCapture", 0); config->addOption("mute", "SDL.MuteCapture", 0);
#endif #endif
#ifdef _GTK #ifdef _GTK
char* home_dir = getenv("HOME"); char* home_dir = getenv("HOME");
// prefixed with _ because they are internal (not cli options) // prefixed with _ because they are internal (not cli options)
config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir); config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir);
config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir); config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir);
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir); config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir); config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
config->addOption("_lastloadlua", "SDL.LastLoadLua", home_dir); config->addOption("_lastloadlua", "SDL.LastLoadLua", home_dir);
#endif #endif
// fcm -> fm2 conversion // fcm -> fm2 conversion
config->addOption("fcmconvert", "SDL.FCMConvert", ""); config->addOption("fcmconvert", "SDL.FCMConvert", "");
// fm2 -> srt conversion // fm2 -> srt conversion
config->addOption("ripsubs", "SDL.RipSubs", ""); config->addOption("ripsubs", "SDL.RipSubs", "");
// enable new PPU core // enable new PPU core
config->addOption("newppu", "SDL.NewPPU", 0); config->addOption("newppu", "SDL.NewPPU", 0);
// GamePad 0 - 3 // GamePad 0 - 3
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) { for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) {
char buf[64]; char buf[64];
snprintf(buf, 20, "SDL.Input.GamePad.%d.", i); snprintf(buf, 20, "SDL.Input.GamePad.%d.", i);
prefix = buf; prefix = buf;
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]); config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
config->addOption(prefix + "DeviceNum", 0); config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) { for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]); config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
} }
} }
// PowerPad 0 - 1 // PowerPad 0 - 1
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) { for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
char buf[64]; char buf[64];
snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i); snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i);
prefix = buf; prefix = buf;
config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]); config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]);
config->addOption(prefix + "DeviceNum", 0); config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) { for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) {
config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]); config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]);
} }
} }
// QuizKing // QuizKing
prefix = "SDL.Input.QuizKing."; prefix = "SDL.Input.QuizKing.";
config->addOption(prefix + "DeviceType", DefaultQuizKingDevice); config->addOption(prefix + "DeviceType", DefaultQuizKingDevice);
config->addOption(prefix + "DeviceNum", 0); config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) { for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) {
config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]); config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]);
} }
// HyperShot // HyperShot
prefix = "SDL.Input.HyperShot."; prefix = "SDL.Input.HyperShot.";
config->addOption(prefix + "DeviceType", DefaultHyperShotDevice); config->addOption(prefix + "DeviceType", DefaultHyperShotDevice);
config->addOption(prefix + "DeviceNum", 0); config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) { for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) {
config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]); config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]);
} }
// Mahjong // Mahjong
prefix = "SDL.Input.Mahjong."; prefix = "SDL.Input.Mahjong.";
config->addOption(prefix + "DeviceType", DefaultMahjongDevice); config->addOption(prefix + "DeviceType", DefaultMahjongDevice);
config->addOption(prefix + "DeviceNum", 0); config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) { for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) {
config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]); config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]);
} }
// TopRider // TopRider
prefix = "SDL.Input.TopRider."; prefix = "SDL.Input.TopRider.";
config->addOption(prefix + "DeviceType", DefaultTopRiderDevice); config->addOption(prefix + "DeviceType", DefaultTopRiderDevice);
config->addOption(prefix + "DeviceNum", 0); config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) { for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) {
config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]); config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]);
} }
// FTrainer // FTrainer
prefix = "SDL.Input.FTrainer."; prefix = "SDL.Input.FTrainer.";
config->addOption(prefix + "DeviceType", DefaultFTrainerDevice); config->addOption(prefix + "DeviceType", DefaultFTrainerDevice);
config->addOption(prefix + "DeviceNum", 0); config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) { for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) {
config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]); config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]);
} }
// FamilyKeyBoard // FamilyKeyBoard
prefix = "SDL.Input.FamilyKeyBoard."; prefix = "SDL.Input.FamilyKeyBoard.";
config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice); config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice);
config->addOption(prefix + "DeviceNum", 0); config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) { for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) {
config->addOption(prefix + FamilyKeyBoardNames[j], config->addOption(prefix + FamilyKeyBoardNames[j],
DefaultFamilyKeyBoard[j]); DefaultFamilyKeyBoard[j]);
} }
// for FAMICOM microphone in pad 2 pad 1 didn't have it // for FAMICOM microphone in pad 2 pad 1 didn't have it
// Takeshi no Chousenjou uses it for example. // Takeshi no Chousenjou uses it for example.
prefix = "SDL.Input.FamicomPad2."; prefix = "SDL.Input.FamicomPad2.";
config->addOption("rp2mic", prefix + "EnableMic", 0); config->addOption("rp2mic", prefix + "EnableMic", 0);
// TODO: use a better data structure to store the hotkeys or something // TODO: use a better data structure to store the hotkeys or something
// improve this code overall in the future to make it // improve this code overall in the future to make it
// easier to maintain // easier to maintain
const int Hotkeys[HK_MAX] = { const int Hotkeys[HK_MAX] = {
SDLK_F1, // cheat menu SDLK_F1, // cheat menu
SDLK_F2, // bind state SDLK_F2, // bind state
SDLK_F3, // load lua SDLK_F3, // load lua
SDLK_F4, // toggleBG SDLK_F4, // toggleBG
SDLK_F5, // save state SDLK_F5, // save state
SDLK_F6, // fds select SDLK_F6, // fds select
SDLK_F7, // load state SDLK_F7, // load state
SDLK_F8, // fds eject SDLK_F8, // fds eject
SDLK_F6, // VS insert coin SDLK_F6, // VS insert coin
SDLK_F8, // VS toggle dipswitch SDLK_F8, // VS toggle dipswitch
SDLK_PERIOD, // toggle frame display SDLK_PERIOD, // toggle frame display
SDLK_F10, // toggle subtitle SDLK_F10, // toggle subtitle
SDLK_F11, // reset SDLK_F11, // reset
SDLK_F12, // screenshot SDLK_F12, // screenshot
SDLK_PAUSE, // pause SDLK_PAUSE, // pause
SDLK_MINUS, // speed++ SDLK_MINUS, // speed++
SDLK_EQUALS, // speed-- SDLK_EQUALS, // speed--
SDLK_BACKQUOTE, //frame advnace SDLK_BACKQUOTE, //frame advnace
SDLK_TAB, // turbo SDLK_TAB, // turbo
SDLK_COMMA, // toggle input display SDLK_COMMA, // toggle input display
SDLK_q, // toggle movie RW SDLK_q, // toggle movie RW
SDLK_QUOTE, // toggle mute capture SDLK_QUOTE, // toggle mute capture
0, // quit // edit 10/11/11 - don't map to escape, it causes ugly things to happen to sdl. can be manually appended to config 0, // quit // edit 10/11/11 - don't map to escape, it causes ugly things to happen to sdl. can be manually appended to config
SDLK_DELETE, // frame advance lag skip SDLK_DELETE, // frame advance lag skip
SDLK_SLASH, // lag counter display SDLK_SLASH, // lag counter display
SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5,
SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDLK_6, SDLK_7, SDLK_8, SDLK_9,
SDLK_PAGEUP, // select state next SDLK_PAGEUP, // select state next
SDLK_PAGEDOWN}; // select state prev SDLK_PAGEDOWN}; // select state prev
prefix = "SDL.Hotkeys."; prefix = "SDL.Hotkeys.";
for(int i=0; i < HK_MAX; i++) for(int i=0; i < HK_MAX; i++)
config->addOption(prefix + HotkeyStrings[i], Hotkeys[i]); config->addOption(prefix + HotkeyStrings[i], Hotkeys[i]);
// All mouse devices // All mouse devices
config->addOption("SDL.OekaKids.0.DeviceType", "Mouse"); config->addOption("SDL.OekaKids.0.DeviceType", "Mouse");
config->addOption("SDL.OekaKids.0.DeviceNum", 0); config->addOption("SDL.OekaKids.0.DeviceNum", 0);
config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse"); config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse");
config->addOption("SDL.Arkanoid.0.DeviceNum", 0); config->addOption("SDL.Arkanoid.0.DeviceNum", 0);
config->addOption("SDL.Shadow.0.DeviceType", "Mouse"); config->addOption("SDL.Shadow.0.DeviceType", "Mouse");
config->addOption("SDL.Shadow.0.DeviceNum", 0); config->addOption("SDL.Shadow.0.DeviceNum", 0);
config->addOption("SDL.Zapper.0.DeviceType", "Mouse"); config->addOption("SDL.Zapper.0.DeviceType", "Mouse");
config->addOption("SDL.Zapper.0.DeviceNum", 0); config->addOption("SDL.Zapper.0.DeviceNum", 0);
return config; return config;
} }
void void
UpdateEMUCore(Config *config) UpdateEMUCore(Config *config)
{ {
int ntsccol, ntsctint, ntschue, flag, start, end; int ntsccol, ntsctint, ntschue, flag, start, end;
std::string cpalette; std::string cpalette;
config->getOption("SDL.NTSCpalette", &ntsccol); config->getOption("SDL.NTSCpalette", &ntsccol);
config->getOption("SDL.Tint", &ntsctint); config->getOption("SDL.Tint", &ntsctint);
config->getOption("SDL.Hue", &ntschue); config->getOption("SDL.Hue", &ntschue);
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue); FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
config->getOption("SDL.Palette", &cpalette); config->getOption("SDL.Palette", &cpalette);
if(cpalette.size()) { if(cpalette.size()) {
LoadCPalette(cpalette); LoadCPalette(cpalette);
} }
config->getOption("SDL.PAL", &flag); config->getOption("SDL.PAL", &flag);
FCEUI_SetVidSystem(flag ? 1 : 0); FCEUI_SetVidSystem(flag ? 1 : 0);
config->getOption("SDL.GameGenie", &flag); config->getOption("SDL.GameGenie", &flag);
FCEUI_SetGameGenie(flag ? 1 : 0); FCEUI_SetGameGenie(flag ? 1 : 0);
config->getOption("SDL.Sound.LowPass", &flag); config->getOption("SDL.Sound.LowPass", &flag);
FCEUI_SetLowPass(flag ? 1 : 0); FCEUI_SetLowPass(flag ? 1 : 0);
config->getOption("SDL.DisableSpriteLimit", &flag); config->getOption("SDL.DisableSpriteLimit", &flag);
FCEUI_DisableSpriteLimitation(flag ? 1 : 0); FCEUI_DisableSpriteLimitation(flag ? 1 : 0);
config->getOption("SDL.ScanLineStart", &start); config->getOption("SDL.ScanLineStart", &start);
config->getOption("SDL.ScanLineEnd", &end); config->getOption("SDL.ScanLineEnd", &end);
#if DOING_SCANLINE_CHECKS #if DOING_SCANLINE_CHECKS
for(int i = 0; i < 2; x++) { for(int i = 0; i < 2; x++) {
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0; if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239; if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
} }
#endif #endif
FCEUI_SetRenderedLines(start + 8, end - 8, start, end); FCEUI_SetRenderedLines(start + 8, end - 8, start, end);
} }

View File

@ -1,38 +1,38 @@
#include "../common/args.h" #include "../common/args.h"
#include "../common/config.h" #include "../common/config.h"
#include "input.h" #include "input.h"
extern CFGSTRUCT DriverConfig[]; extern CFGSTRUCT DriverConfig[];
extern ARGPSTRUCT DriverArgs[]; extern ARGPSTRUCT DriverArgs[];
extern char *DriverUsage; extern char *DriverUsage;
void DoDriverArgs(void); void DoDriverArgs(void);
int InitSound(); int InitSound();
void WriteSound(int32 *Buffer, int Count); void WriteSound(int32 *Buffer, int Count);
int KillSound(void); int KillSound(void);
uint32 GetMaxSound(void); uint32 GetMaxSound(void);
uint32 GetWriteSound(void); uint32 GetWriteSound(void);
void SilenceSound(int s); /* DOS and SDL */ void SilenceSound(int s); /* DOS and SDL */
int InitJoysticks(void); int InitJoysticks(void);
int KillJoysticks(void); int KillJoysticks(void);
uint32 *GetJSOr(void); uint32 *GetJSOr(void);
int InitVideo(FCEUGI *gi); int InitVideo(FCEUGI *gi);
int KillVideo(void); int KillVideo(void);
void BlitScreen(uint8 *XBuf); void BlitScreen(uint8 *XBuf);
void LockConsole(void); void LockConsole(void);
void UnlockConsole(void); void UnlockConsole(void);
void ToggleFS(); /* SDL */ void ToggleFS(); /* SDL */
int LoadGame(const char *path); int LoadGame(const char *path);
//int CloseGame(void); //int CloseGame(void);
void Giggles(int); void Giggles(int);
void DoFun(void); void DoFun(void);
int FCEUD_NetworkConnect(void); int FCEUD_NetworkConnect(void);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,58 +1,58 @@
#ifndef _aosdfjk02fmasf #ifndef _aosdfjk02fmasf
#define _aosdfjk02fmasf #define _aosdfjk02fmasf
#include "../common/configSys.h" #include "../common/configSys.h"
#define MAXBUTTCONFIG 4 #define MAXBUTTCONFIG 4
typedef struct { typedef struct {
uint8 ButtType[MAXBUTTCONFIG]; uint8 ButtType[MAXBUTTCONFIG];
uint8 DeviceNum[MAXBUTTCONFIG]; uint8 DeviceNum[MAXBUTTCONFIG];
uint16 ButtonNum[MAXBUTTCONFIG]; uint16 ButtonNum[MAXBUTTCONFIG];
uint32 NumC; uint32 NumC;
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
} ButtConfig; } ButtConfig;
extern CFGSTRUCT InputConfig[]; extern CFGSTRUCT InputConfig[];
extern ARGPSTRUCT InputArgs[]; extern ARGPSTRUCT InputArgs[];
extern int Hotkeys[]; extern int Hotkeys[];
void ParseGIInput(FCEUGI *GI); void ParseGIInput(FCEUGI *GI);
void setHotKeys(); void setHotKeys();
int ButtonConfigBegin(); int ButtonConfigBegin();
void ButtonConfigEnd(); void ButtonConfigEnd();
void ConfigButton(char *text, ButtConfig *bc); void ConfigButton(char *text, ButtConfig *bc);
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb); int DWaitButton(const uint8 *text, ButtConfig *bc, int wb);
#define BUTTC_KEYBOARD 0x00 #define BUTTC_KEYBOARD 0x00
#define BUTTC_JOYSTICK 0x01 #define BUTTC_JOYSTICK 0x01
#define BUTTC_MOUSE 0x02 #define BUTTC_MOUSE 0x02
#define FCFGD_GAMEPAD 1 #define FCFGD_GAMEPAD 1
#define FCFGD_POWERPAD 2 #define FCFGD_POWERPAD 2
#define FCFGD_HYPERSHOT 3 #define FCFGD_HYPERSHOT 3
#define FCFGD_QUIZKING 4 #define FCFGD_QUIZKING 4
#define SDL_FCEU_HOTKEY_EVENT SDL_USEREVENT #define SDL_FCEU_HOTKEY_EVENT SDL_USEREVENT
void InitInputInterface(void); void InitInputInterface(void);
void InputUserActiveFix(void); void InputUserActiveFix(void);
extern bool replaceP2StartWithMicrophone; extern bool replaceP2StartWithMicrophone;
extern ButtConfig GamePadConfig[4][10]; extern ButtConfig GamePadConfig[4][10];
//extern ButtConfig powerpadsc[2][12]; //extern ButtConfig powerpadsc[2][12];
//extern ButtConfig QuizKingButtons[6]; //extern ButtConfig QuizKingButtons[6];
//extern ButtConfig FTrainerButtons[12]; //extern ButtConfig FTrainerButtons[12];
void IncreaseEmulationSpeed(void); void IncreaseEmulationSpeed(void);
void DecreaseEmulationSpeed(void); void DecreaseEmulationSpeed(void);
int DTestButtonJoy(ButtConfig *bc); int DTestButtonJoy(ButtConfig *bc);
void FCEUD_UpdateInput(void); void FCEUD_UpdateInput(void);
void UpdateInput(Config *config); void UpdateInput(Config *config);
void InputCfg(const std::string &); void InputCfg(const std::string &);
std::string GetUserText(const char* title); std::string GetUserText(const char* title);
const char* ButtonName(const ButtConfig* bc, int which); const char* ButtonName(const ButtConfig* bc, int which);
#endif
#endif

View File

@ -1,49 +1,49 @@
#include <SDL.h> #include <SDL.h>
#define SDLK_A SDLK_a #define SDLK_A SDLK_a
#define SDLK_B SDLK_b #define SDLK_B SDLK_b
#define SDLK_C SDLK_c #define SDLK_C SDLK_c
#define SDLK_D SDLK_d #define SDLK_D SDLK_d
#define SDLK_E SDLK_e #define SDLK_E SDLK_e
#define SDLK_F SDLK_f #define SDLK_F SDLK_f
#define SDLK_G SDLK_g #define SDLK_G SDLK_g
#define SDLK_H SDLK_h #define SDLK_H SDLK_h
#define SDLK_I SDLK_i #define SDLK_I SDLK_i
#define SDLK_J SDLK_j #define SDLK_J SDLK_j
#define SDLK_K SDLK_k #define SDLK_K SDLK_k
#define SDLK_L SDLK_l #define SDLK_L SDLK_l
#define SDLK_M SDLK_m #define SDLK_M SDLK_m
#define SDLK_N SDLK_n #define SDLK_N SDLK_n
#define SDLK_O SDLK_o #define SDLK_O SDLK_o
#define SDLK_P SDLK_p #define SDLK_P SDLK_p
#define SDLK_Q SDLK_q #define SDLK_Q SDLK_q
#define SDLK_R SDLK_r #define SDLK_R SDLK_r
#define SDLK_S SDLK_s #define SDLK_S SDLK_s
#define SDLK_T SDLK_t #define SDLK_T SDLK_t
#define SDLK_U SDLK_u #define SDLK_U SDLK_u
#define SDLK_V SDLK_v #define SDLK_V SDLK_v
#define SDLK_W SDLK_w #define SDLK_W SDLK_w
#define SDLK_X SDLK_x #define SDLK_X SDLK_x
#define SDLK_Y SDLK_y #define SDLK_Y SDLK_y
#define SDLK_Z SDLK_z #define SDLK_Z SDLK_z
#define SDLK_LEFTCONTROL SDLK_LCTRL #define SDLK_LEFTCONTROL SDLK_LCTRL
#define SDLK_RIGHTCONTROL SDLK_RCTRL #define SDLK_RIGHTCONTROL SDLK_RCTRL
#define SDLK_LEFTALT SDLK_LALT #define SDLK_LEFTALT SDLK_LALT
#define SDLK_RIGHTALT SDLK_RALT #define SDLK_RIGHTALT SDLK_RALT
#define SDLK_LEFTSHIFT SDLK_LSHIFT #define SDLK_LEFTSHIFT SDLK_LSHIFT
#define SDLK_RIGHTSHIFT SDLK_RSHIFT #define SDLK_RIGHTSHIFT SDLK_RSHIFT
#define SDLK_CURSORDOWN SDLK_DOWN #define SDLK_CURSORDOWN SDLK_DOWN
#define SDLK_CURSORUP SDLK_UP #define SDLK_CURSORUP SDLK_UP
#define SDLK_CURSORLEFT SDLK_LEFT #define SDLK_CURSORLEFT SDLK_LEFT
#define SDLK_CURSORRIGHT SDLK_RIGHT #define SDLK_CURSORRIGHT SDLK_RIGHT
#define SDLK_ENTER SDLK_RETURN #define SDLK_ENTER SDLK_RETURN
#define SDLK_EQUAL SDLK_EQUALS #define SDLK_EQUAL SDLK_EQUALS
#define SDLK_APOSTROPHE SDLK_QUOTE #define SDLK_APOSTROPHE SDLK_QUOTE
#define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET #define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET
#define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET #define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET
#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */ #define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */
#define SDLK_GRAVE SDLK_BACKQUOTE #define SDLK_GRAVE SDLK_BACKQUOTE
#define MKK(k) SDLK_##k #define MKK(k) SDLK_##k
#if SDL_VERSION_ATLEAST(1, 3, 0) #if SDL_VERSION_ATLEAST(1, 3, 0)
#define SDLK_LAST SDL_NUM_SCANCODES #define SDLK_LAST SDL_NUM_SCANCODES
#endif #endif
#define MKK_COUNT (SDLK_LAST+1) #define MKK_COUNT (SDLK_LAST+1)

View File

@ -1,102 +1,102 @@
/* FCE Ultra - NES/Famicom Emulator /* FCE Ultra - NES/Famicom Emulator
* *
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2002 Xodnizel * Copyright (C) 2002 Xodnizel
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef __FCEU_SDL_MAIN_H #ifndef __FCEU_SDL_MAIN_H
#define __FCEU_SDL_MAIN_H #define __FCEU_SDL_MAIN_H
#include <SDL.h> #include <SDL.h>
#include "../../driver.h" #include "../../driver.h"
#include "../common/config.h" #include "../common/config.h"
#include "../common/args.h" #include "../common/args.h"
extern int eoptions; extern int eoptions;
#define EO_NO8LIM 1 #define EO_NO8LIM 1
#define EO_SUBASE 2 #define EO_SUBASE 2
#define EO_CLIPSIDES 8 #define EO_CLIPSIDES 8
#define EO_SNAPNAME 16 #define EO_SNAPNAME 16
#define EO_FOURSCORE 32 #define EO_FOURSCORE 32
#define EO_NOTHROTTLE 64 #define EO_NOTHROTTLE 64
#define EO_GAMEGENIE 128 #define EO_GAMEGENIE 128
#define EO_PAL 256 #define EO_PAL 256
#define EO_LOWPASS 512 #define EO_LOWPASS 512
#define EO_AUTOHIDE 1024 #define EO_AUTOHIDE 1024
extern int NoWaiting; extern int NoWaiting;
extern int _sound; extern int _sound;
extern long soundrate; extern long soundrate;
extern long soundbufsize; extern long soundbufsize;
int CLImain(int argc, char *argv[]); int CLImain(int argc, char *argv[]);
// Device management defaults // Device management defaults
#define NUM_INPUT_DEVICES 3 #define NUM_INPUT_DEVICES 3
// GamePad defaults // GamePad defaults
#define GAMEPAD_NUM_DEVICES 4 #define GAMEPAD_NUM_DEVICES 4
#define GAMEPAD_NUM_BUTTONS 10 #define GAMEPAD_NUM_BUTTONS 10
extern const char *GamePadNames[GAMEPAD_NUM_BUTTONS]; extern const char *GamePadNames[GAMEPAD_NUM_BUTTONS];
extern const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES]; extern const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES];
extern const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS]; extern const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS];
// PowerPad defaults // PowerPad defaults
#define POWERPAD_NUM_DEVICES 2 #define POWERPAD_NUM_DEVICES 2
#define POWERPAD_NUM_BUTTONS 12 #define POWERPAD_NUM_BUTTONS 12
extern const char *PowerPadNames[POWERPAD_NUM_BUTTONS]; extern const char *PowerPadNames[POWERPAD_NUM_BUTTONS];
extern const char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES]; extern const char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES];
extern const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS]; extern const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS];
// QuizKing defaults // QuizKing defaults
#define QUIZKING_NUM_BUTTONS 6 #define QUIZKING_NUM_BUTTONS 6
extern const char *QuizKingNames[QUIZKING_NUM_BUTTONS]; extern const char *QuizKingNames[QUIZKING_NUM_BUTTONS];
extern const char *DefaultQuizKingDevice; extern const char *DefaultQuizKingDevice;
extern const int DefaultQuizKing[QUIZKING_NUM_BUTTONS]; extern const int DefaultQuizKing[QUIZKING_NUM_BUTTONS];
// HyperShot defaults // HyperShot defaults
#define HYPERSHOT_NUM_BUTTONS 4 #define HYPERSHOT_NUM_BUTTONS 4
extern const char *HyperShotNames[HYPERSHOT_NUM_BUTTONS]; extern const char *HyperShotNames[HYPERSHOT_NUM_BUTTONS];
extern const char *DefaultHyperShotDevice; extern const char *DefaultHyperShotDevice;
extern const int DefaultHyperShot[HYPERSHOT_NUM_BUTTONS]; extern const int DefaultHyperShot[HYPERSHOT_NUM_BUTTONS];
// Mahjong defaults // Mahjong defaults
#define MAHJONG_NUM_BUTTONS 21 #define MAHJONG_NUM_BUTTONS 21
extern const char *MahjongNames[MAHJONG_NUM_BUTTONS]; extern const char *MahjongNames[MAHJONG_NUM_BUTTONS];
extern const char *DefaultMahjongDevice; extern const char *DefaultMahjongDevice;
extern const int DefaultMahjong[MAHJONG_NUM_BUTTONS]; extern const int DefaultMahjong[MAHJONG_NUM_BUTTONS];
// TopRider defaults // TopRider defaults
#define TOPRIDER_NUM_BUTTONS 8 #define TOPRIDER_NUM_BUTTONS 8
extern const char *TopRiderNames[TOPRIDER_NUM_BUTTONS]; extern const char *TopRiderNames[TOPRIDER_NUM_BUTTONS];
extern const char *DefaultTopRiderDevice; extern const char *DefaultTopRiderDevice;
extern const int DefaultTopRider[TOPRIDER_NUM_BUTTONS]; extern const int DefaultTopRider[TOPRIDER_NUM_BUTTONS];
// FTrainer defaults // FTrainer defaults
#define FTRAINER_NUM_BUTTONS 12 #define FTRAINER_NUM_BUTTONS 12
extern const char *FTrainerNames[FTRAINER_NUM_BUTTONS]; extern const char *FTrainerNames[FTRAINER_NUM_BUTTONS];
extern const char *DefaultFTrainerDevice; extern const char *DefaultFTrainerDevice;
extern const int DefaultFTrainer[FTRAINER_NUM_BUTTONS]; extern const int DefaultFTrainer[FTRAINER_NUM_BUTTONS];
// FamilyKeyBoard defaults // FamilyKeyBoard defaults
#define FAMILYKEYBOARD_NUM_BUTTONS 0x48 #define FAMILYKEYBOARD_NUM_BUTTONS 0x48
extern const char *FamilyKeyBoardNames[FAMILYKEYBOARD_NUM_BUTTONS]; extern const char *FamilyKeyBoardNames[FAMILYKEYBOARD_NUM_BUTTONS];
extern const char *DefaultFamilyKeyBoardDevice; extern const char *DefaultFamilyKeyBoardDevice;
extern const int DefaultFamilyKeyBoard[FAMILYKEYBOARD_NUM_BUTTONS]; extern const int DefaultFamilyKeyBoard[FAMILYKEYBOARD_NUM_BUTTONS];
#endif #endif

View File

@ -1,134 +1,134 @@
static const struct { static const struct {
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
uint8 pixel_data[32 * 32 * 3 + 1]; uint8 pixel_data[32 * 32 * 3 + 1];
} fceu_playicon = { } fceu_playicon = {
32, 32, 3, 32, 32, 3,
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223" "\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\0\0\0\0\0\0\0\0\0\\\223\373\\\223\373\267\317\373" "\373\\\223\373\\\223\373\0\0\0\0\0\0\0\0\0\\\223\373\\\223\373\267\317\373"
"\246\304\373\260\312\373\222\267\373\246\304\373\\\223\373\\\223\373\\\223" "\246\304\373\260\312\373\222\267\373\246\304\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\267\317\373\246\304\373\260\312\373\210\261\373\246\304\373\\\223\373\\" "\267\317\373\246\304\373\260\312\373\210\261\373\246\304\373\\\223\373\\"
"\223\373\210\261\373\222\267\373\267\317\373\241\301\373\\\223\373\\\223" "\223\373\210\261\373\222\267\373\267\317\373\241\301\373\\\223\373\\\223"
"\373\0\0\0\0\0\0\\\223\373\\\223\373\227\272\373\227\272\373\227\272\373" "\373\0\0\0\0\0\0\\\223\373\\\223\373\227\272\373\227\272\373\227\272\373"
"\227\272\373\227\272\373\227\272\373\\\223\373\\\223\373z`sr\242\373\227" "\227\272\373\227\272\373\227\272\373\\\223\373\\\223\373z`sr\242\373\227"
"\272\373\227\272\373\\\223\373\\\223\373\\\223\373\\\223\373\213\261\373" "\272\373\227\272\373\\\223\373\\\223\373\\\223\373\\\223\373\213\261\373"
"z\247\373\213\261\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "z\247\373\213\261\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\" "\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\"
"\223\373\\\223\373\313i=\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40" "\223\373\\\223\373\313i=\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40"
"\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40" "\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40"
"\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\257T*\\\223\373\\\223\373\\\223" "\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\257T*\\\223\373\\\223\373\\\223"
"\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40" "\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40"
"\355\235\203\355\235\203\341\232\205\341\232\205\365\255\233\355\235\203" "\355\235\203\355\235\203\341\232\205\341\232\205\365\255\233\355\235\203"
"\355\235\203\350\250\232\365\255\233\355\235\203\307L\14\307L\14\307L\14" "\355\235\203\350\250\232\365\255\233\355\235\203\307L\14\307L\14\307L\14"
"\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256B\12\\\223\373" "\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256B\12\\\223\373"
"\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373" "\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373"
"\\\223\373\315Z\40\273zc\233l_\325\225\205\325\225\205\325\225\205\273\212" "\\\223\373\315Z\40\273zc\233l_\325\225\205\325\225\205\325\225\205\273\212"
"\201\325\225\205\237qd\325\225\205\317\231\216\307L\14\307L\14\307L\14\307" "\201\325\225\205\237qd\325\225\205\317\231\216\307L\14\307L\14\307L\14\307"
"L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256B\12\\\223\373\\" "L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256B\12\\\223\373\\"
"\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\" "\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\"
"\223\373\315Z\40\344\232\203\301\215\201\344\232\203\273\212\201\325\225" "\223\373\315Z\40\344\232\203\301\215\201\344\232\203\273\212\201\325\225"
"\205\2114\10\344\232\203\350\250\232\325\225\205\333\230\205\307L\14\307" "\205\2114\10\344\232\203\350\250\232\325\225\205\333\230\205\307L\14\307"
"L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256" "L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256"
"B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223" "B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223"
"\373\\\223\373\\\223\373\315Z\40\2259\11}0\10\2259\11}0\10}0\10\307L\14\225" "\373\\\223\373\\\223\373\315Z\40\2259\11}0\10\2259\11}0\10}0\10\307L\14\225"
"9\11d&\6}0\10}0\10\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14" "9\11d&\6}0\10}0\10\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14"
"\307L\14\307L\14\307L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373" "\307L\14\307L\14\307L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373"
"\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40\355\235\203" "\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40\355\235\203"
"\355\233\201\355\235\203\355\235\203\355\235\203\365\255\233\355\235\203" "\355\233\201\355\235\203\355\235\203\355\235\203\365\255\233\355\235\203"
"\341\232\205\355\235\203\355\235\203\307L\14\365\255\233\355\235\203\365" "\341\232\205\355\235\203\355\235\203\307L\14\365\255\233\355\235\203\365"
"\255\233\355\235\203\355\235\203\355\235\203\355\235\203\355\235\203\307" "\255\233\355\235\203\355\235\203\355\235\203\355\235\203\355\235\203\307"
"L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373" "L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
"\\\223\373\\\223\373\\\223\373\315Z\40\325\225\205\311\221\204\311\221\204" "\\\223\373\\\223\373\\\223\373\315Z\40\325\225\205\311\221\204\311\221\204"
"\325\225\205\311\221\204\325\225\205\311\221\204\325\225\205\325\225\205" "\325\225\205\311\221\204\325\225\205\311\221\204\325\225\205\325\225\205"
"\311\221\204\307L\14\325\225\205\311\221\204\325\225\205\311\221\204\325" "\311\221\204\307L\14\325\225\205\311\221\204\325\225\205\311\221\204\325"
"\225\205\311\221\204\325\225\205\311\221\204\307L\14\256B\12\\\223\373\\" "\225\205\311\221\204\325\225\205\311\221\204\307L\14\256B\12\\\223\373\\"
"\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\" "\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\"
"\223\373\315Z\40\325\225\205\325\225\205\325\225\205\325\225\205\325\225" "\223\373\315Z\40\325\225\205\325\225\205\325\225\205\325\225\205\325\225"
"\205\325\225\205\317\231\216\325\225\205\325\225\205\325\225\205\307L\14" "\205\325\225\205\317\231\216\325\225\205\325\225\205\325\225\205\307L\14"
"\325\225\205\317\231\216\325\225\205\317\231\216\325\225\205\325\225\205" "\325\225\205\317\231\216\325\225\205\317\231\216\325\225\205\325\225\205"
"\273zc\241n_\307L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0" "\273zc\241n_\307L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0"
"\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40\325\225\205\325" "\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40\325\225\205\325"
"\225\205\325\225\205\365\255\233\333\243\231\325\225\205\333\230\205\325" "\225\205\325\225\205\365\255\233\333\243\231\325\225\205\333\230\205\325"
"\225\205\325\225\205\325\225\205\307L\14\325\225\205\317\223\204\325\225" "\225\205\325\225\205\325\225\205\307L\14\325\225\205\317\223\204\325\225"
"\205\333\230\205\325\225\205\325\225\205\333\230\205\317\223\204\307L\14" "\205\333\230\205\325\225\205\325\225\205\333\230\205\317\223\204\307L\14"
"\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\" "\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\"
"\223\373\\\223\373\\\223\373\315Z\40\325\225\205\325\225\205\325\225\205" "\223\373\\\223\373\\\223\373\315Z\40\325\225\205\325\225\205\325\225\205"
"\325\225\205\311\221\204\325\225\205\325\225\205\325\225\205\344\232\203" "\325\225\205\311\221\204\325\225\205\325\225\205\325\225\205\344\232\203"
"\273\212\201\307L\14\325\225\205\273\212\201\325\225\205\325\225\205\344" "\273\212\201\307L\14\325\225\205\273\212\201\325\225\205\325\225\205\344"
"\232\203\273\212\201\344\232\203\273\212\201\341\232\205\256B\12\\\223\373" "\232\203\273\212\201\344\232\203\273\212\201\341\232\205\256B\12\\\223\373"
"\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373" "\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373"
"\\\223\373\257T*d&\6d&\6d&\6d&\6d&\6d&\6d&\6d&\6}0\10d&\6\256B\12d&\6p+\7" "\\\223\373\257T*d&\6d&\6d&\6d&\6d&\6d&\6d&\6d&\6}0\10d&\6\256B\12d&\6p+\7"
"d&\6d&\6}0\10d&\6}0\10d&\6d&\6\223@\26\\\223\373\\\223\373\\\223\373\\\223" "d&\6d&\6}0\10d&\6}0\10d&\6d&\6\223@\26\\\223\373\\\223\373\\\223\373\\\223"
"\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223" "\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\234\243" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\234\243"
"\335\213\237\344\237\244\333\251\247\326\237\244\333\\\223\373\267\252\317" "\335\213\237\344\237\244\333\251\247\326\237\244\333\\\223\373\267\252\317"
"\222\241\341\267\252\317\210\237\346\241\245\332\267\252\317\246\246\327" "\222\241\341\267\252\317\210\237\346\241\245\332\267\252\317\246\246\327"
"\246\246\327\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373" "\246\246\327\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223" "\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0"
"\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223" "\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\" "\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\257hT\\\223\373\213\261\373\\\223" "\223\373\\\223\373\\\223\373\\\223\373\257hT\\\223\373\213\261\373\\\223"
"\373\241\301\373\210\261\373\246\304\373\222\267\373\241\301\373\260\312" "\373\241\301\373\210\261\373\246\304\373\222\267\373\241\301\373\260\312"
"\373\\\223\373\237\277\373\246\304\373\267\317\373\241\301\373\\\223\373" "\373\\\223\373\237\277\373\246\304\373\267\317\373\241\301\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223" "\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\246\304\373\\\223\373\241" "\223\373\\\223\373\\\223\373\\\223\373\\\223\373\246\304\373\\\223\373\241"
"\301\373\210\261\373\246\304\373\222\267\373\241\301\373\260\312\373\\\223" "\301\373\210\261\373\246\304\373\222\267\373\241\301\373\260\312\373\\\223"
"\373\237\277\373\246\304\373\267\317\373\241\301\373\\\223\373\\\223\373" "\373\237\277\373\246\304\373\267\317\373\241\301\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
"\\\223\373\\\223\373D\203\270D\203\270\\\223\373\\\223\373\\\223\373\\\223" "\\\223\373\\\223\373D\203\270D\203\270\\\223\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0" "\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0"
"\0\0\0\0\\\223\373\\\223\373(\211n\0\247\0\0n\0(\211n\\\223\373\\\223\373" "\0\0\0\0\\\223\373\\\223\373(\211n\0\247\0\0n\0(\211n\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223" "\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\0\0\0\0\0\0\\\223\373(\211n\0\247\0\0\247\0\0\247\0\0\247\0(\211n\\\223" "\0\0\0\0\0\0\\\223\373(\211n\0\247\0\0\247\0\0\247\0\0\247\0(\211n\\\223"
"\373\\\223\373\\\223\373\\\223\373\210\261\373\246\304\373\241\301\373z\247" "\373\\\223\373\\\223\373\\\223\373\210\261\373\246\304\373\241\301\373z\247"
"\373\\\223\373\227\272\373\227\272\373\227\272\373\227\272\373\227\272\373" "\373\\\223\373\227\272\373\227\272\373\227\272\373\227\272\373\227\272\373"
"\227\272\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\227\272\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\0\0\0\0\0\0(\211n\0\247\0\0n\0\0\247\0\\\215\12fs\16" "\\\223\373\\\223\373\0\0\0\0\0\0(\211n\0\247\0\0n\0\0\247\0\\\215\12fs\16"
"\0\247\0(\211n\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\0\247\0(\211n\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
"\223\373\\\223\373Z\231Z[\230SZ\231Z[\230SZ\231Z[\230S\\\223\373\0\0\0\0" "\223\373\\\223\373Z\231Z[\230SZ\231Z[\230SZ\231Z[\230S\\\223\373\0\0\0\0"
"\0\0\0\247\0\0\247\0\0\247\0\0\247\0vy\7p|\7\0\247\0\0\247\0(\211n\\\223" "\0\0\0\247\0\0\247\0\0\247\0\0\247\0vy\7p|\7\0\247\0\0\247\0(\211n\\\223"
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373" "\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373b\237L\200\317\20\200\317" "\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373b\237L\200\317\20\200\317"
"\20\200\317\20\200\317\20\200\317\20\200\317\20[\223H\0\0\0\0\0\0\230P.\323" "\20\200\317\20\200\317\20\200\317\20\200\317\20[\223H\0\0\0\0\0\0\230P.\323"
"d0\230P.\323d0\221M&\313`%\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323" "d0\230P.\323d0\221M&\313`%\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323"
"d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323" "d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323"
"d0\230P.\323d0\230P.\323d0\0\0\0\0\0\0\0\0\0\237N(\225E\35\237N(\225E\35" "d0\230P.\323d0\230P.\323d0\0\0\0\0\0\0\0\0\0\237N(\225E\35\237N(\225E\35"
"\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237" "\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237"
"N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(" "N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N("
"\225E\35\237N(\225E\35\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\225E\35\237N(\225E\35\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
}; };

View File

@ -1,124 +1,123 @@
/* FCE Ultra - NES/Famicom Emulator /* FCE Ultra - NES/Famicom Emulator
* *
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2002 Xodnizel * Copyright (C) 2002 Xodnizel
* Copyright (C) 2002 Paul Kuliniewicz * Copyright (C) 2002 Paul Kuliniewicz
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/// \file /// \file
/// \brief Handles joystick input using the SDL. /// \brief Handles joystick input using the SDL.
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include "sdl.h" #include "sdl.h"
#define MAX_JOYSTICKS 32 #define MAX_JOYSTICKS 32
static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL}; static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL};
static int s_jinited = 0; static int s_jinited = 0;
/** /**
* Tests if the given button is active on the joystick. * Tests if the given button is active on the joystick.
*/ */
int int
DTestButtonJoy(ButtConfig *bc) DTestButtonJoy(ButtConfig *bc)
{ {
int x; int x;
for(x = 0; x < bc->NumC; x++) for(x = 0; x < bc->NumC; x++)
{ {
if(bc->ButtonNum[x] & 0x2000) if(bc->ButtonNum[x] & 0x2000)
{ {
/* Hat "button" */ /* Hat "button" */
if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]], if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]],
((bc->ButtonNum[x] >> 8) & 0x1F)) & ((bc->ButtonNum[x] >> 8) & 0x1F)) &
(bc->ButtonNum[x]&0xFF)) (bc->ButtonNum[x]&0xFF))
return(1); return 1;
}
} else if(bc->ButtonNum[x] & 0x8000)
else if(bc->ButtonNum[x] & 0x8000) {
{ /* Axis "button" */
/* Axis "button" */ int pos;
int pos; pos = SDL_JoystickGetAxis(s_Joysticks[bc->DeviceNum[x]],
pos = SDL_JoystickGetAxis(s_Joysticks[bc->DeviceNum[x]], bc->ButtonNum[x] & 16383);
bc->ButtonNum[x] & 16383); if ((bc->ButtonNum[x] & 0x4000) && pos <= -16383) {
if ((bc->ButtonNum[x] & 0x4000) && pos <= -16383) { return 1;
return(1); } else if (!(bc->ButtonNum[x] & 0x4000) && pos >= 16363) {
} else if (!(bc->ButtonNum[x] & 0x4000) && pos >= 16363) { return 1;
return(1); }
} }
} else if(SDL_JoystickGetButton(s_Joysticks[bc->DeviceNum[x]],
else if(SDL_JoystickGetButton(s_Joysticks[bc->DeviceNum[x]], bc->ButtonNum[x]))
bc->ButtonNum[x])) return 1;
return(1); }
} return 0;
return(0); }
}
/**
/** * Shutdown the SDL joystick subsystem.
* Shutdown the SDL joystick subsystem. */
*/ int
int KillJoysticks()
KillJoysticks() {
{ int n; /* joystick index */
int n; /* joystick index */
if(!s_jinited) {
if(!s_jinited) { return -1;
return(-1); }
}
for(n = 0; n < MAX_JOYSTICKS; n++) {
for(n = 0; n < MAX_JOYSTICKS; n++) { if (s_Joysticks[n] != 0) {
if (s_Joysticks[n] != 0) { SDL_JoystickClose(s_Joysticks[n]);
SDL_JoystickClose(s_Joysticks[n]); }
} s_Joysticks[n]=0;
s_Joysticks[n]=0; }
} SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
SDL_QuitSubSystem(SDL_INIT_JOYSTICK); return 0;
return(0); }
}
/**
/** * Initialize the SDL joystick subsystem.
* Initialize the SDL joystick subsystem. */
*/ int
int InitJoysticks()
InitJoysticks() {
{ int n; /* joystick index */
int n; /* joystick index */ int total;
int total;
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
total = SDL_NumJoysticks();
total = SDL_NumJoysticks(); if(total>MAX_JOYSTICKS) {
if(total>MAX_JOYSTICKS) { total = MAX_JOYSTICKS;
total = MAX_JOYSTICKS; }
}
for(n = 0; n < total; n++) {
for(n = 0; n < total; n++) { /* Open the joystick under SDL. */
/* Open the joystick under SDL. */ s_Joysticks[n] = SDL_JoystickOpen(n);
s_Joysticks[n] = SDL_JoystickOpen(n); //printf("Could not open joystick %d: %s.\n",
//printf("Could not open joystick %d: %s.\n", //joy[n] - 1, SDL_GetError());
//joy[n] - 1, SDL_GetError()); continue;
continue; }
}
s_jinited = 1;
s_jinited = 1; return 1;
return(1); }
}

View File

@ -1,223 +1,223 @@
#include "sdl.h" #include "sdl.h"
#include <SDL_net.h> #include <SDL_net.h>
#include "sdl-netplay.h" #include "sdl-netplay.h"
char *ServerHost; char *ServerHost;
int magic; int magic;
static int LocalPortTCP=0xFCE; static int LocalPortTCP=0xFCE;
static int LocalPortUDP=0xFCE; static int LocalPortUDP=0xFCE;
static int RemotePortTCP=0xFCE; static int RemotePortTCP=0xFCE;
static int RemotePortUDP; /* Not configurable, figured out during handshake. */ static int RemotePortUDP; /* Not configurable, figured out during handshake. */
static TCPsocket Socket; static TCPsocket Socket;
static UDPsocket UDPSocket; static UDPsocket UDPSocket;
static SDLNet_SocketSet set; static SDLNet_SocketSet set;
static void en32(uint8 *buf, uint32 morp) static void en32(uint8 *buf, uint32 morp)
{ {
buf[0]=morp; buf[0]=morp;
buf[1]=morp>>8; buf[1]=morp>>8;
buf[2]=morp>>16; buf[2]=morp>>16;
buf[3]=morp>>24; buf[3]=morp>>24;
} }
static uint32 de32(uint8 *morp) static uint32 de32(uint8 *morp)
{ {
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24)); return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
} }
int FCEUD_NetworkConnect(void) int FCEUD_NetworkConnect(void)
{ {
IPaddress rip; IPaddress rip;
SDLNet_Init(); SDLNet_Init();
int netplay =1; int netplay =1;
if(netplay==1) /* Be a server. */ if(netplay==1) /* Be a server. */
{ {
TCPsocket tmp; TCPsocket tmp;
Uint16 p=LocalPortUDP; Uint16 p=LocalPortUDP;
SDLNet_ResolveHost(&rip,NULL,LocalPortTCP); SDLNet_ResolveHost(&rip,NULL,LocalPortTCP);
UDPSocket=SDLNet_UDP_Open(p); UDPSocket=SDLNet_UDP_Open(p);
tmp=SDLNet_TCP_Open(&rip); tmp=SDLNet_TCP_Open(&rip);
Socket=SDLNet_TCP_Accept(tmp); Socket=SDLNet_TCP_Accept(tmp);
memcpy(&rip,SDLNet_TCP_GetPeerAddress(Socket),sizeof(IPaddress)); memcpy(&rip,SDLNet_TCP_GetPeerAddress(Socket),sizeof(IPaddress));
{ {
Uint32 buf[12]; Uint32 buf[12];
uint32 player=1; uint32 player=1;
magic=SDL_GetTicks(); magic=SDL_GetTicks();
SDLNet_Write32(buf,uport); SDLNet_Write32(buf,uport);
SDLNet_Write32(buf+4,1); SDLNet_Write32(buf+4,1);
SDLNet_Write32(buf+8,magic); SDLNet_Write32(buf+8,magic);
SDLNet_TCP_Send(Socket, buf, 12); SDLNet_TCP_Send(Socket, buf, 12);
/* Get the UDP port the client is waiting for data on. */ /* Get the UDP port the client is waiting for data on. */
SDLNet_TCP_Recv(Socket, buf, 2); SDLNet_TCP_Recv(Socket, buf, 2);
RemotePortUDP=de32(buf); RemotePortUDP=de32(buf);
} }
} }
else /* Be a client */ else /* Be a client */
{ {
SDLNet_ResolveHost(&rip,ServerHost,RemotePortTCP); SDLNet_ResolveHost(&rip,ServerHost,RemotePortTCP);
Socket=SDLNet_TCP_Open(&rip); Socket=SDLNet_TCP_Open(&rip);
{ {
Uint16 p=LocalPortUDP; Uint16 p=LocalPortUDP;
uint8 buf[12]; uint8 buf[12];
UDPSocket=SDLNet_UDP_Open(p); UDPSocket=SDLNet_UDP_Open(p);
/* Now, tell the server what local UDP port it should send to. */ /* Now, tell the server what local UDP port it should send to. */
en32(buf,p); en32(buf,p);
SDLNet_TCP_Send(Socket, buf, 4); SDLNet_TCP_Send(Socket, buf, 4);
/* Get the UDP port from the server we should send data to. */ /* Get the UDP port from the server we should send data to. */
SDLNet_TCP_Recv(Socket, buf, 12); SDLNet_TCP_Recv(Socket, buf, 12);
RemotePortUDP=de32(buf); RemotePortUDP=de32(buf);
magic=de32(buf+8); magic=de32(buf+8);
} }
set=SDLNet_AllocSocketSet(1); set=SDLNet_AllocSocketSet(1);
SDLNet_TCP_AddSocket(set,Socket); SDLNet_TCP_AddSocket(set,Socket);
SDLNet_UDP_AddSocket(set,UDPSocket); SDLNet_UDP_AddSocket(set,UDPSocket);
} // End client connect code. } // End client connect code.
rip.port=RemotePortUDP; rip.port=RemotePortUDP;
SDLNet_UDP_Bind(UDPSocket, 0, &rip); SDLNet_UDP_Bind(UDPSocket, 0, &rip);
} }
static int CheckUDP(uint8 *packet, int32 len, int32 alt) static int CheckUDP(uint8 *packet, int32 len, int32 alt)
{ {
uint32 crc; uint32 crc;
uint32 repcrc; uint32 repcrc;
crc=FCEUI_CRC32(0,packet+4,len+8); crc=FCEUI_CRC32(0,packet+4,len+8);
repcrc=de32(packet); repcrc=de32(packet);
if(crc!=repcrc) return(0); /* CRC32 mismatch, bad packet. */ if(crc!=repcrc) return(0); /* CRC32 mismatch, bad packet. */
packet+=4; packet+=4;
if(de32(packet)!=magic) /* Magic number mismatch, bad or spoofed packet. */ if(de32(packet)!=magic) /* Magic number mismatch, bad or spoofed packet. */
return(0); return(0);
packet+=4; packet+=4;
if(alt) if(alt)
{ {
if(de32(packet)<incounter) /* Time warped packet. */ if(de32(packet)<incounter) /* Time warped packet. */
return(0); return(0);
} }
else else
if(de32(packet)!=incounter) /* Time warped packet. */ if(de32(packet)!=incounter) /* Time warped packet. */
return(0); return(0);
return(1); return(1);
} }
/* Be careful where these MakeXXX() functions are used. */ /* Be careful where these MakeXXX() functions are used. */
static uint8 *MakeUDP(uint8 *data, int32 len) static uint8 *MakeUDP(uint8 *data, int32 len)
{ {
/* UDP packet data header is 12 bytes in length. */ /* UDP packet data header is 12 bytes in length. */
static uint8 buf[12+32]; // arbitrary 32. static uint8 buf[12+32]; // arbitrary 32.
en32(buf+4,magic); en32(buf+4,magic);
en32(buf+8,outcounter); en32(buf+8,outcounter);
memcpy(buf+12,data,len); memcpy(buf+12,data,len);
en32(buf,FCEUI_CRC32(0,buf+4,8+len)); en32(buf,FCEUI_CRC32(0,buf+4,8+len));
return(buf); return(buf);
} }
static uint8 *MakeTCP(uint8 *data, int32 len) static uint8 *MakeTCP(uint8 *data, int32 len)
{ {
/* TCP packet data header is 4 bytes in length. */ /* TCP packet data header is 4 bytes in length. */
static uint8 buf[4+32]; // arbitrary 32. static uint8 buf[4+32]; // arbitrary 32.
en32(buf,outcounter); en32(buf,outcounter);
memcpy(buf+4,data,len); memcpy(buf+4,data,len);
return(buf); return(buf);
} }
#define UDPHEADSIZE 12 #define UDPHEADSIZE 12
#define TCPHEADSIZE 4 #define TCPHEADSIZE 4
void FCEUD_NetworkClose(void) void FCEUD_NetworkClose(void)
{ {
SDLNet_Quit(); SDLNet_Quit();
} }
/* 1 byte to server */ /* 1 byte to server */
int FCEUD_SendDataToServer(uint8 v,uint8 cmd) int FCEUD_SendDataToServer(uint8 v,uint8 cmd)
{ {
UDPpacket upack; UDPpacket upack;
upack.channel=0; upack.channel=0;
upack.data=MakeUDP(data,1); upack.data=MakeUDP(data,1);
upack.len=upack.maxlen=UDPHEADSIZE+1; upack.len=upack.maxlen=UDPHEADSIZE+1;
upack.status=0; upack.status=0;
SDLNet_UDP_Send(UDPSocket,0,&upack); SDLNet_UDP_Send(UDPSocket,0,&upack);
outcounter++; outcounter++;
return(1); return(1);
} }
void FCEUD_SendDataToClients(uint8 *data) void FCEUD_SendDataToClients(uint8 *data)
{ {
UDPpacket upack; UDPpacket upack;
SDLNet_TCP_Send(Socket,MakeTCP(data,5),TCPHEADSIZE+5); SDLNet_TCP_Send(Socket,MakeTCP(data,5),TCPHEADSIZE+5);
upack.channel=0; upack.channel=0;
upack.data=MakeUDP(data,5); upack.data=MakeUDP(data,5);
upack.len=upack.maxlen=UDPHEADSIZE+5; upack.len=upack.maxlen=UDPHEADSIZE+5;
upack.status=0; upack.status=0;
SDLNet_UDP_Send(UDPSocket,0,&upack); SDLNet_UDP_Send(UDPSocket,0,&upack);
outcounter++; outcounter++;
return(1); return(1);
} }
int FCEUD_GetDataFromServer(uint8 *data) int FCEUD_GetDataFromServer(uint8 *data)
{ {
uint8 buf[128]; uint8 buf[128];
NoWaiting&=~2; NoWaiting&=~2;
while(SDLNet_CheckSockets(set,1)==0) while(SDLNet_CheckSockets(set,1)==0)
{ {
// do something here. // do something here.
} }
if(SDLNet_SocketReady(Socket)) if(SDLNet_SocketReady(Socket))
{ {
if(de32(buf)==incounter) /* New packet, keep. */ if(de32(buf)==incounter) /* New packet, keep. */
{ {
unsigned long beefie; unsigned long beefie;
memcpy(data,buf+TCPHEADSIZE,5); memcpy(data,buf+TCPHEADSIZE,5);
incounter++; incounter++;
if(!ioctl(Socket,FIONREAD,&beefie)) if(!ioctl(Socket,FIONREAD,&beefie))
if(beefie) if(beefie)
NoWaiting|=2; NoWaiting|=2;
return(1); return(1);
} }
} }
if(SDLNet_SocketReady(UDPSocket) if(SDLNet_SocketReady(UDPSocket)
{ {
} }
} }

View File

@ -1,293 +1,293 @@
#define GL_GLEXT_LEGACY #define GL_GLEXT_LEGACY
#ifdef APPLEOPENGL #ifdef APPLEOPENGL
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#include <OpenGL/glu.h> #include <OpenGL/glu.h>
#include <OpenGL/glext.h> #include <OpenGL/glext.h>
#else #else
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glu.h> #include <GL/glu.h>
#include <GL/glext.h> #include <GL/glext.h>
#endif #endif
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "sdl.h" #include "sdl.h"
#include "sdl-opengl.h" #include "sdl-opengl.h"
#include "../common/vidblit.h" #include "../common/vidblit.h"
#include "../../utils/memory.h" #include "../../utils/memory.h"
#ifndef APIENTRY #ifndef APIENTRY
#define APIENTRY #define APIENTRY
#endif #endif
static GLuint textures[2]={0,0}; // Normal image, scanline overlay. static GLuint textures[2]={0,0}; // Normal image, scanline overlay.
static int left,right,top,bottom; // right and bottom are not inclusive. static int left,right,top,bottom; // right and bottom are not inclusive.
static int scanlines; static int scanlines;
static void *HiBuffer; static void *HiBuffer;
typedef void APIENTRY (*glBindTexture_Func)(GLenum target,GLuint texture); typedef void APIENTRY (*glBindTexture_Func)(GLenum target,GLuint texture);
typedef void APIENTRY (*glColorTableEXT_Func)(GLenum target, typedef void APIENTRY (*glColorTableEXT_Func)(GLenum target,
GLenum internalformat, GLsizei width, GLenum format, GLenum type, GLenum internalformat, GLsizei width, GLenum format, GLenum type,
const GLvoid *table); const GLvoid *table);
typedef void APIENTRY (*glTexImage2D_Func)(GLenum target, GLint level, typedef void APIENTRY (*glTexImage2D_Func)(GLenum target, GLint level,
GLint internalFormat, GLint internalFormat,
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, GLenum format, GLenum type,
const GLvoid *pixels); const GLvoid *pixels);
typedef void APIENTRY (*glBegin_Func)(GLenum mode); typedef void APIENTRY (*glBegin_Func)(GLenum mode);
typedef void APIENTRY (*glVertex2f_Func)(GLfloat x, GLfloat y); typedef void APIENTRY (*glVertex2f_Func)(GLfloat x, GLfloat y);
typedef void APIENTRY (*glTexCoord2f_Func)(GLfloat s, GLfloat t); typedef void APIENTRY (*glTexCoord2f_Func)(GLfloat s, GLfloat t);
typedef void APIENTRY (*glEnd_Func)(void); typedef void APIENTRY (*glEnd_Func)(void);
typedef void APIENTRY (*glEnable_Func)(GLenum cap); typedef void APIENTRY (*glEnable_Func)(GLenum cap);
typedef void APIENTRY (*glBlendFunc_Func)(GLenum sfactor, GLenum dfactor); typedef void APIENTRY (*glBlendFunc_Func)(GLenum sfactor, GLenum dfactor);
typedef const GLubyte* APIENTRY (*glGetString_Func)(GLenum name); typedef const GLubyte* APIENTRY (*glGetString_Func)(GLenum name);
typedef void APIENTRY (*glViewport_Func)(GLint x, GLint y,GLsizei width, typedef void APIENTRY (*glViewport_Func)(GLint x, GLint y,GLsizei width,
GLsizei height); GLsizei height);
typedef void APIENTRY (*glGenTextures_Func)(GLsizei n, GLuint *textures); typedef void APIENTRY (*glGenTextures_Func)(GLsizei n, GLuint *textures);
typedef void APIENTRY (*glDeleteTextures_Func)(GLsizei n, typedef void APIENTRY (*glDeleteTextures_Func)(GLsizei n,
const GLuint *textures); const GLuint *textures);
typedef void APIENTRY (*glTexParameteri_Func)(GLenum target, GLenum pname, typedef void APIENTRY (*glTexParameteri_Func)(GLenum target, GLenum pname,
GLint param); GLint param);
typedef void APIENTRY (*glClearColor_Func)(GLclampf red, GLclampf green, typedef void APIENTRY (*glClearColor_Func)(GLclampf red, GLclampf green,
GLclampf blue, GLclampf alpha); GLclampf blue, GLclampf alpha);
typedef void APIENTRY (*glLoadIdentity_Func)(void); typedef void APIENTRY (*glLoadIdentity_Func)(void);
typedef void APIENTRY (*glClear_Func)(GLbitfield mask); typedef void APIENTRY (*glClear_Func)(GLbitfield mask);
typedef void APIENTRY (*glMatrixMode_Func)(GLenum mode); typedef void APIENTRY (*glMatrixMode_Func)(GLenum mode);
typedef void APIENTRY (*glDisable_Func)(GLenum cap); typedef void APIENTRY (*glDisable_Func)(GLenum cap);
glBindTexture_Func p_glBindTexture; glBindTexture_Func p_glBindTexture;
glColorTableEXT_Func p_glColorTableEXT; glColorTableEXT_Func p_glColorTableEXT;
glTexImage2D_Func p_glTexImage2D; glTexImage2D_Func p_glTexImage2D;
glBegin_Func p_glBegin; glBegin_Func p_glBegin;
glVertex2f_Func p_glVertex2f; glVertex2f_Func p_glVertex2f;
glTexCoord2f_Func p_glTexCoord2f; glTexCoord2f_Func p_glTexCoord2f;
glEnd_Func p_glEnd; glEnd_Func p_glEnd;
glEnable_Func p_glEnable; glEnable_Func p_glEnable;
glBlendFunc_Func p_glBlendFunc; glBlendFunc_Func p_glBlendFunc;
glGetString_Func p_glGetString; glGetString_Func p_glGetString;
glViewport_Func p_glViewport; glViewport_Func p_glViewport;
glGenTextures_Func p_glGenTextures; glGenTextures_Func p_glGenTextures;
glDeleteTextures_Func p_glDeleteTextures; glDeleteTextures_Func p_glDeleteTextures;
glTexParameteri_Func p_glTexParameteri; glTexParameteri_Func p_glTexParameteri;
glClearColor_Func p_glClearColor; glClearColor_Func p_glClearColor;
glLoadIdentity_Func p_glLoadIdentity; glLoadIdentity_Func p_glLoadIdentity;
glClear_Func p_glClear; glClear_Func p_glClear;
glMatrixMode_Func p_glMatrixMode; glMatrixMode_Func p_glMatrixMode;
glDisable_Func p_glDisable; glDisable_Func p_glDisable;
void void
SetOpenGLPalette(uint8 *data) SetOpenGLPalette(uint8 *data)
{ {
if(!HiBuffer) { if(!HiBuffer) {
p_glBindTexture(GL_TEXTURE_2D, textures[0]); p_glBindTexture(GL_TEXTURE_2D, textures[0]);
p_glColorTableEXT(GL_TEXTURE_2D, GL_RGB, 256, p_glColorTableEXT(GL_TEXTURE_2D, GL_RGB, 256,
GL_RGBA, GL_UNSIGNED_BYTE, data); GL_RGBA, GL_UNSIGNED_BYTE, data);
} else { } else {
SetPaletteBlitToHigh((uint8*)data); SetPaletteBlitToHigh((uint8*)data);
} }
} }
void void
BlitOpenGL(uint8 *buf) BlitOpenGL(uint8 *buf)
{ {
p_glClear(GL_COLOR_BUFFER_BIT); p_glClear(GL_COLOR_BUFFER_BIT);
p_glBindTexture(GL_TEXTURE_2D, textures[0]); p_glBindTexture(GL_TEXTURE_2D, textures[0]);
if(HiBuffer) { if(HiBuffer) {
Blit8ToHigh(buf, (uint8*)HiBuffer, 256, 240, 256*4, 1, 1); Blit8ToHigh(buf, (uint8*)HiBuffer, 256, 240, 256*4, 1, 1);
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
GL_RGBA, GL_UNSIGNED_BYTE, HiBuffer); GL_RGBA, GL_UNSIGNED_BYTE, HiBuffer);
} }
else { else {
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 256); //glPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0, p_glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0,
GL_COLOR_INDEX,GL_UNSIGNED_BYTE,buf); GL_COLOR_INDEX,GL_UNSIGNED_BYTE,buf);
} }
p_glBegin(GL_QUADS); p_glBegin(GL_QUADS);
p_glTexCoord2f(1.0f*left/256, 1.0f*bottom/256); // Bottom left of picture. p_glTexCoord2f(1.0f*left/256, 1.0f*bottom/256); // Bottom left of picture.
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target. p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
p_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256);// Bottom right of picture. p_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256);// Bottom right of picture.
p_glVertex2f( 1.0f, -1.0f); // Bottom right of target. p_glVertex2f( 1.0f, -1.0f); // Bottom right of target.
p_glTexCoord2f(1.0f*right/256, 1.0f*top/256); // Top right of our picture. p_glTexCoord2f(1.0f*right/256, 1.0f*top/256); // Top right of our picture.
p_glVertex2f( 1.0f, 1.0f); // Top right of target. p_glVertex2f( 1.0f, 1.0f); // Top right of target.
p_glTexCoord2f(1.0f*left/256, 1.0f*top/256); // Top left of our picture. p_glTexCoord2f(1.0f*left/256, 1.0f*top/256); // Top left of our picture.
p_glVertex2f(-1.0f, 1.0f); // Top left of target. p_glVertex2f(-1.0f, 1.0f); // Top left of target.
p_glEnd(); p_glEnd();
//glDisable(GL_BLEND); //glDisable(GL_BLEND);
if(scanlines) { if(scanlines) {
p_glEnable(GL_BLEND); p_glEnable(GL_BLEND);
p_glBindTexture(GL_TEXTURE_2D, textures[1]); p_glBindTexture(GL_TEXTURE_2D, textures[1]);
p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA); p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
p_glBegin(GL_QUADS); p_glBegin(GL_QUADS);
p_glTexCoord2f(1.0f*left/256, p_glTexCoord2f(1.0f*left/256,
1.0f*bottom/256); // Bottom left of our picture. 1.0f*bottom/256); // Bottom left of our picture.
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target. p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
p_glTexCoord2f(1.0f*right/256, p_glTexCoord2f(1.0f*right/256,
1.0f*bottom/256); // Bottom right of our picture. 1.0f*bottom/256); // Bottom right of our picture.
p_glVertex2f( 1.0f, -1.0f); // Bottom right of target. p_glVertex2f( 1.0f, -1.0f); // Bottom right of target.
p_glTexCoord2f(1.0f*right/256, p_glTexCoord2f(1.0f*right/256,
1.0f*top/256); // Top right of our picture. 1.0f*top/256); // Top right of our picture.
p_glVertex2f( 1.0f, 1.0f); // Top right of target. p_glVertex2f( 1.0f, 1.0f); // Top right of target.
p_glTexCoord2f(1.0f*left/256, p_glTexCoord2f(1.0f*left/256,
1.0f*top/256); // Top left of our picture. 1.0f*top/256); // Top left of our picture.
p_glVertex2f(-1.0f, 1.0f); // Top left of target. p_glVertex2f(-1.0f, 1.0f); // Top left of target.
p_glEnd(); p_glEnd();
p_glDisable(GL_BLEND); p_glDisable(GL_BLEND);
} }
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
} }
void void
KillOpenGL(void) KillOpenGL(void)
{ {
if(textures[0]) { if(textures[0]) {
p_glDeleteTextures(2, &textures[0]); p_glDeleteTextures(2, &textures[0]);
} }
textures[0]=0; textures[0]=0;
if(HiBuffer) { if(HiBuffer) {
free(HiBuffer); free(HiBuffer);
HiBuffer=0; HiBuffer=0;
} }
} }
/* Rectangle, left, right(not inclusive), top, bottom(not inclusive). */ /* Rectangle, left, right(not inclusive), top, bottom(not inclusive). */
int int
InitOpenGL(int l, InitOpenGL(int l,
int r, int r,
int t, int t,
int b, int b,
double xscale, double xscale,
double yscale, double yscale,
int efx, int efx,
int ipolate, int ipolate,
int stretchx, int stretchx,
int stretchy, int stretchy,
SDL_Surface *screen) SDL_Surface *screen)
{ {
const char *extensions; const char *extensions;
#define LFG(x) if(!(p_##x = (x##_Func) SDL_GL_GetProcAddress(#x))) return(0); #define LFG(x) if(!(p_##x = (x##_Func) SDL_GL_GetProcAddress(#x))) return(0);
#define LFGN(x) p_##x = (x##_Func) SDL_GL_GetProcAddress(#x) #define LFGN(x) p_##x = (x##_Func) SDL_GL_GetProcAddress(#x)
LFG(glBindTexture); LFG(glBindTexture);
LFGN(glColorTableEXT); LFGN(glColorTableEXT);
LFG(glTexImage2D); LFG(glTexImage2D);
LFG(glBegin); LFG(glBegin);
LFG(glVertex2f); LFG(glVertex2f);
LFG(glTexCoord2f); LFG(glTexCoord2f);
LFG(glEnd); LFG(glEnd);
LFG(glEnable); LFG(glEnable);
LFG(glBlendFunc); LFG(glBlendFunc);
LFG(glGetString); LFG(glGetString);
LFG(glViewport); LFG(glViewport);
LFG(glGenTextures); LFG(glGenTextures);
LFG(glDeleteTextures); LFG(glDeleteTextures);
LFG(glTexParameteri); LFG(glTexParameteri);
LFG(glClearColor); LFG(glClearColor);
LFG(glLoadIdentity); LFG(glLoadIdentity);
LFG(glClear); LFG(glClear);
LFG(glMatrixMode); LFG(glMatrixMode);
LFG(glDisable); LFG(glDisable);
left=l; left=l;
right=r; right=r;
top=t; top=t;
bottom=b; bottom=b;
HiBuffer=0; HiBuffer=0;
extensions=(const char*)p_glGetString(GL_EXTENSIONS); extensions=(const char*)p_glGetString(GL_EXTENSIONS);
if((efx&2) || !extensions || !p_glColorTableEXT || !strstr(extensions,"GL_EXT_paletted_texture")) if((efx&2) || !extensions || !p_glColorTableEXT || !strstr(extensions,"GL_EXT_paletted_texture"))
{ {
if(!(efx&2)) // Don't want to print out a warning message in this case... if(!(efx&2)) // Don't want to print out a warning message in this case...
FCEU_printf("Paletted texture extension not found. Using slower texture format...\n"); FCEU_printf("Paletted texture extension not found. Using slower texture format...\n");
HiBuffer=FCEU_malloc(4*256*256); HiBuffer=FCEU_malloc(4*256*256);
memset(HiBuffer,0x00,4*256*256); memset(HiBuffer,0x00,4*256*256);
#ifndef LSB_FIRST #ifndef LSB_FIRST
InitBlitToHigh(4,0xFF000000,0xFF0000,0xFF00,efx&2,0,0); InitBlitToHigh(4,0xFF000000,0xFF0000,0xFF00,efx&2,0,0);
#else #else
InitBlitToHigh(4,0xFF,0xFF00,0xFF0000,efx&2,0,0); InitBlitToHigh(4,0xFF,0xFF00,0xFF0000,efx&2,0,0);
#endif #endif
} }
if(screen->flags & SDL_FULLSCREEN) if(screen->flags & SDL_FULLSCREEN)
{ {
xscale=(double)screen->w / (double)(r-l); xscale=(double)screen->w / (double)(r-l);
yscale=(double)screen->h / (double)(b-t); yscale=(double)screen->h / (double)(b-t);
if(xscale<yscale) yscale = xscale; if(xscale<yscale) yscale = xscale;
if(yscale<xscale) xscale = yscale; if(yscale<xscale) xscale = yscale;
} }
{ {
int rw=(int)((r-l)*xscale); int rw=(int)((r-l)*xscale);
int rh=(int)((b-t)*yscale); int rh=(int)((b-t)*yscale);
int sx=(screen->w-rw)/2; // Start x int sx=(screen->w-rw)/2; // Start x
int sy=(screen->h-rh)/2; // Start y int sy=(screen->h-rh)/2; // Start y
if(stretchx) { sx=0; rw=screen->w; } if(stretchx) { sx=0; rw=screen->w; }
if(stretchy) { sy=0; rh=screen->h; } if(stretchy) { sy=0; rh=screen->h; }
p_glViewport(sx, sy, rw, rh); p_glViewport(sx, sy, rw, rh);
} }
p_glGenTextures(2, &textures[0]); p_glGenTextures(2, &textures[0]);
scanlines=0; scanlines=0;
if(efx&1) if(efx&1)
{ {
uint8 *buf; uint8 *buf;
int x,y; int x,y;
scanlines=1; scanlines=1;
p_glBindTexture(GL_TEXTURE_2D, textures[1]); p_glBindTexture(GL_TEXTURE_2D, textures[1]);
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
buf=(uint8*)FCEU_dmalloc(256*(256*2)*4); buf=(uint8*)FCEU_dmalloc(256*(256*2)*4);
for(y=0;y<(256*2);y++) for(y=0;y<(256*2);y++)
for(x=0;x<256;x++) for(x=0;x<256;x++)
{ {
buf[y*256*4+x*4]=0; buf[y*256*4+x*4]=0;
buf[y*256*4+x*4+1]=0; buf[y*256*4+x*4+1]=0;
buf[y*256*4+x*4+2]=0; buf[y*256*4+x*4+2]=0;
buf[y*256*4+x*4+3]=(y&1)?0x00:0xFF; //?0xa0:0xFF; // <-- Pretty buf[y*256*4+x*4+3]=(y&1)?0x00:0xFF; //?0xa0:0xFF; // <-- Pretty
//buf[y*256+x]=(y&1)?0x00:0xFF; //buf[y*256+x]=(y&1)?0x00:0xFF;
} }
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, (scanlines==2)?256*4:512, 0, p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, (scanlines==2)?256*4:512, 0,
GL_RGBA,GL_UNSIGNED_BYTE,buf); GL_RGBA,GL_UNSIGNED_BYTE,buf);
FCEU_dfree(buf); FCEU_dfree(buf);
} }
p_glBindTexture(GL_TEXTURE_2D, textures[0]); p_glBindTexture(GL_TEXTURE_2D, textures[0]);
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
p_glEnable(GL_TEXTURE_2D); p_glEnable(GL_TEXTURE_2D);
p_glDisable(GL_DEPTH_TEST); p_glDisable(GL_DEPTH_TEST);
p_glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black. p_glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
p_glMatrixMode(GL_MODELVIEW); p_glMatrixMode(GL_MODELVIEW);
p_glLoadIdentity(); p_glLoadIdentity();
// In a double buffered setup with page flipping, be sure to clear both buffers. // In a double buffered setup with page flipping, be sure to clear both buffers.
p_glClear(GL_COLOR_BUFFER_BIT); p_glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
p_glClear(GL_COLOR_BUFFER_BIT); p_glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
return(1); return 1;
} }

View File

@ -1,6 +1,6 @@
void SetOpenGLPalette(uint8 *data); void SetOpenGLPalette(uint8 *data);
void BlitOpenGL(uint8 *buf); void BlitOpenGL(uint8 *buf);
void KillOpenGL(void); void KillOpenGL(void);
int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx, int ipolate, int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx, int ipolate,
int stretchx, int stretchy, SDL_Surface *screen); int stretchx, int stretchy, SDL_Surface *screen);

View File

@ -1,274 +1,269 @@
/* FCE Ultra - NES/Famicom Emulator /* FCE Ultra - NES/Famicom Emulator
* *
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2002 Xodnizel * Copyright (C) 2002 Xodnizel
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/// \file /// \file
/// \brief Handles sound emulation using the SDL. /// \brief Handles sound emulation using the SDL.
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "sdl.h" #include "sdl.h"
#include "../common/configSys.h" #include "../common/configSys.h"
#include "../../utils/memory.h" #include "../../utils/memory.h"
extern Config *g_config; extern Config *g_config;
static volatile int *s_Buffer = 0; static volatile int *s_Buffer = 0;
static unsigned int s_BufferSize; static unsigned int s_BufferSize;
static unsigned int s_BufferRead; static unsigned int s_BufferRead;
static unsigned int s_BufferWrite; static unsigned int s_BufferWrite;
static volatile unsigned int s_BufferIn; static volatile unsigned int s_BufferIn;
static int s_mute = 0; static int s_mute = 0;
/** /**
* Callback from the SDL to get and play audio data. * Callback from the SDL to get and play audio data.
*/ */
static void static void
fillaudio(void *udata, fillaudio(void *udata,
uint8 *stream, uint8 *stream,
int len) int len)
{ {
int16 *tmps = (int16*)stream; int16 *tmps = (int16*)stream;
len >>= 1; len >>= 1;
// debug code while(len) {
//printf("s_BufferIn: %i s_BufferWrite = %i s_BufferRead = %i s_BufferSize = %i\n", int16 sample = 0;
// s_BufferIn, s_BufferWrite, s_BufferRead, s_BufferSize); if(s_BufferIn) {
sample = s_Buffer[s_BufferRead];
while(len) { s_BufferRead = (s_BufferRead + 1) % s_BufferSize;
int16 sample = 0; s_BufferIn--;
if(s_BufferIn) { } else {
sample = s_Buffer[s_BufferRead]; sample = 0;
s_BufferRead = (s_BufferRead + 1) % s_BufferSize; }
s_BufferIn--;
} else { *tmps = sample;
sample = 0; tmps++;
} len--;
}
*tmps = sample; }
tmps++;
len--; /**
} * Initialize the audio subsystem.
} */
int
/** InitSound()
* Initialize the audio subsystem. {
*/ int sound, soundrate, soundbufsize, soundvolume, soundtrianglevolume, soundsquare1volume, soundsquare2volume, soundnoisevolume, soundpcmvolume, soundq;
int SDL_AudioSpec spec;
InitSound()
{ g_config->getOption("SDL.Sound", &sound);
int sound, soundrate, soundbufsize, soundvolume, soundtrianglevolume, soundsquare1volume, soundsquare2volume, soundnoisevolume, soundpcmvolume, soundq; if(!sound) {
SDL_AudioSpec spec; return 0;
}
g_config->getOption("SDL.Sound", &sound);
if(!sound) { memset(&spec, 0, sizeof(spec));
return 0; if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
} puts(SDL_GetError());
KillSound();
memset(&spec, 0, sizeof(spec)); return 0;
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { }
puts(SDL_GetError()); char driverName[8];
KillSound(); SDL_AudioDriverName(driverName, 8);
return(0);
} fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName);
char driverName[8];
SDL_AudioDriverName(driverName, 8); // load configuration variables
g_config->getOption("SDL.Sound.Rate", &soundrate);
fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName); g_config->getOption("SDL.Sound.BufSize", &soundbufsize);
g_config->getOption("SDL.Sound.Volume", &soundvolume);
// load configuration variables g_config->getOption("SDL.Sound.Quality", &soundq);
g_config->getOption("SDL.Sound.Rate", &soundrate); g_config->getOption("SDL.Sound.TriangleVolume", &soundtrianglevolume);
g_config->getOption("SDL.Sound.BufSize", &soundbufsize); g_config->getOption("SDL.Sound.Square1Volume", &soundsquare1volume);
g_config->getOption("SDL.Sound.Volume", &soundvolume); g_config->getOption("SDL.Sound.Square2Volume", &soundsquare2volume);
g_config->getOption("SDL.Sound.Quality", &soundq); g_config->getOption("SDL.Sound.NoiseVolume", &soundnoisevolume);
g_config->getOption("SDL.Sound.TriangleVolume", &soundtrianglevolume); g_config->getOption("SDL.Sound.PCMVolume", &soundpcmvolume);
g_config->getOption("SDL.Sound.Square1Volume", &soundsquare1volume);
g_config->getOption("SDL.Sound.Square2Volume", &soundsquare2volume); spec.freq = soundrate;
g_config->getOption("SDL.Sound.NoiseVolume", &soundnoisevolume); spec.format = AUDIO_S16SYS;
g_config->getOption("SDL.Sound.PCMVolume", &soundpcmvolume); spec.channels = 1;
spec.samples = 512;
spec.freq = soundrate; spec.callback = fillaudio;
spec.format = AUDIO_S16SYS; spec.userdata = 0;
spec.channels = 1;
spec.samples = 512; s_BufferSize = soundbufsize * soundrate / 1000;
spec.callback = fillaudio;
spec.userdata = 0; // For safety, set a bare minimum:
if (s_BufferSize < spec.samples * 2)
s_BufferSize = soundbufsize * soundrate / 1000; s_BufferSize = spec.samples * 2;
// For safety, set a bare minimum: s_Buffer = (int *)FCEU_dmalloc(sizeof(int) * s_BufferSize);
if (s_BufferSize < spec.samples * 2) if (!s_Buffer)
s_BufferSize = spec.samples * 2; return 0;
s_BufferRead = s_BufferWrite = s_BufferIn = 0;
s_Buffer = (int *)FCEU_dmalloc(sizeof(int) * s_BufferSize);
if (!s_Buffer) if(SDL_OpenAudio(&spec, 0) < 0)
return 0; {
s_BufferRead = s_BufferWrite = s_BufferIn = 0; puts(SDL_GetError());
KillSound();
//printf("SDL Size: %d, Internal size: %d\n",spec.samples,s_BufferSize); return 0;
}
if(SDL_OpenAudio(&spec, 0) < 0) { SDL_PauseAudio(0);
puts(SDL_GetError());
KillSound(); FCEUI_SetSoundVolume(soundvolume);
return(0); FCEUI_SetSoundQuality(soundq);
} FCEUI_Sound(soundrate);
SDL_PauseAudio(0); FCEUI_SetTriangleVolume(soundtrianglevolume);
FCEUI_SetSquare1Volume(soundsquare1volume);
FCEUI_SetSoundVolume(soundvolume); FCEUI_SetSquare2Volume(soundsquare2volume);
FCEUI_SetSoundQuality(soundq); FCEUI_SetNoiseVolume(soundnoisevolume);
FCEUI_Sound(soundrate); FCEUI_SetPCMVolume(soundpcmvolume);
FCEUI_SetTriangleVolume(soundtrianglevolume); return 1;
FCEUI_SetSquare1Volume(soundsquare1volume); }
FCEUI_SetSquare2Volume(soundsquare2volume);
FCEUI_SetNoiseVolume(soundnoisevolume);
FCEUI_SetPCMVolume(soundpcmvolume); /**
return(1); * Returns the size of the audio buffer.
} */
uint32
GetMaxSound(void)
/** {
* Returns the size of the audio buffer. return(s_BufferSize);
*/ }
uint32
GetMaxSound(void) /**
{ * Returns the amount of free space in the audio buffer.
return(s_BufferSize); */
} uint32
GetWriteSound(void)
/** {
* Returns the amount of free space in the audio buffer. return(s_BufferSize - s_BufferIn);
*/ }
uint32
GetWriteSound(void) /**
{ * Send a sound clip to the audio subsystem.
return(s_BufferSize - s_BufferIn); */
} void
WriteSound(int32 *buf,
/** int Count)
* Send a sound clip to the audio subsystem. {
*/ extern int EmulationPaused;
void if (EmulationPaused == 0)
WriteSound(int32 *buf, while(Count)
int Count) {
{ while(s_BufferIn == s_BufferSize)
extern int EmulationPaused; {
if (EmulationPaused == 0) SDL_Delay(1);
while(Count) }
{
while(s_BufferIn == s_BufferSize) s_Buffer[s_BufferWrite] = *buf;
{ Count--;
SDL_Delay(1); s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
}
SDL_LockAudio();
s_Buffer[s_BufferWrite] = *buf; s_BufferIn++;
Count--; SDL_UnlockAudio();
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
buf++;
SDL_LockAudio(); }
s_BufferIn++; }
SDL_UnlockAudio();
/**
buf++; * Pause (1) or unpause (0) the audio output.
} */
} void
SilenceSound(int n)
/** {
* Pause (1) or unpause (0) the audio output. SDL_PauseAudio(n);
*/ }
void
SilenceSound(int n) /**
{ * Shut down the audio subsystem.
SDL_PauseAudio(n); */
} int
KillSound(void)
/** {
* Shut down the audio subsystem. FCEUI_Sound(0);
*/ SDL_CloseAudio();
int SDL_QuitSubSystem(SDL_INIT_AUDIO);
KillSound(void) if(s_Buffer) {
{ free((void *)s_Buffer);
FCEUI_Sound(0); s_Buffer = 0;
SDL_CloseAudio(); }
SDL_QuitSubSystem(SDL_INIT_AUDIO); return 0;
if(s_Buffer) { }
free((void *)s_Buffer);
s_Buffer = 0;
} /**
return(0); * Adjust the volume either down (-1), up (1), or to the default (0).
} * Unmutes if mute was active before.
*/
void
/** FCEUD_SoundVolumeAdjust(int n)
* Adjust the volume either down (-1), up (1), or to the default (0). {
* Unmutes if mute was active before. int soundvolume;
*/ g_config->getOption("SDL.SoundVolume", &soundvolume);
void
FCEUD_SoundVolumeAdjust(int n) switch(n) {
{ case -1:
int soundvolume; soundvolume -= 10;
g_config->getOption("SDL.SoundVolume", &soundvolume); if(soundvolume < 0) {
soundvolume = 0;
switch(n) { }
case -1: break;
soundvolume -= 10; case 0:
if(soundvolume < 0) { soundvolume = 100;
soundvolume = 0; break;
} case 1:
break; soundvolume += 10;
case 0: if(soundvolume > 150) {
soundvolume = 100; soundvolume = 150;
break; }
case 1: break;
soundvolume += 10; }
if(soundvolume > 150) {
soundvolume = 150; s_mute = 0;
} FCEUI_SetSoundVolume(soundvolume);
break; g_config->setOption("SDL.SoundVolume", soundvolume);
}
FCEU_DispMessage("Sound volume %d.",0, soundvolume);
s_mute = 0; }
FCEUI_SetSoundVolume(soundvolume);
g_config->setOption("SDL.SoundVolume", soundvolume); /**
* Toggles the sound on or off.
FCEU_DispMessage("Sound volume %d.",0, soundvolume); */
} void
FCEUD_SoundToggle(void)
/** {
* Toggles the sound on or off. if(s_mute) {
*/ int soundvolume;
void g_config->getOption("SDL.SoundVolume", &soundvolume);
FCEUD_SoundToggle(void)
{ s_mute = 0;
if(s_mute) { FCEUI_SetSoundVolume(soundvolume);
int soundvolume; FCEU_DispMessage("Sound mute off.",0);
g_config->getOption("SDL.SoundVolume", &soundvolume); } else {
s_mute = 1;
s_mute = 0; FCEUI_SetSoundVolume(0);
FCEUI_SetSoundVolume(soundvolume); FCEU_DispMessage("Sound mute on.",0);
FCEU_DispMessage("Sound mute off.",0); }
} else { }
s_mute = 1;
FCEUI_SetSoundVolume(0);
FCEU_DispMessage("Sound mute on.",0);
}
}

View File

@ -1,150 +1,150 @@
/// \file /// \file
/// \brief Handles emulation speed throttling using the SDL timing functions. /// \brief Handles emulation speed throttling using the SDL timing functions.
#include "sdl.h" #include "sdl.h"
#include "throttle.h" #include "throttle.h"
static const double Slowest = 0.015625; // 1/64x speed (around 1 fps on NTSC) static const double Slowest = 0.015625; // 1/64x speed (around 1 fps on NTSC)
static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC) static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC)
static const double Normal = 1.0; // 1x speed (around 60 fps on NTSC) static const double Normal = 1.0; // 1x speed (around 60 fps on NTSC)
static uint64 Lasttime, Nexttime; static uint64 Lasttime, Nexttime;
static long double desired_frametime; static long double desired_frametime;
static int InFrame; static int InFrame;
double g_fpsScale = Normal; // used by sdl.cpp double g_fpsScale = Normal; // used by sdl.cpp
bool MaxSpeed = false; bool MaxSpeed = false;
/* LOGMUL = exp(log(2) / 3) /* LOGMUL = exp(log(2) / 3)
* *
* This gives us a value such that if we do x*=LOGMUL three times, * This gives us a value such that if we do x*=LOGMUL three times,
* then after that, x is twice the value it was before. * then after that, x is twice the value it was before.
* *
* This gives us three speed steps per order of magnitude. * This gives us three speed steps per order of magnitude.
* *
*/ */
#define LOGMUL 1.259921049894873 #define LOGMUL 1.259921049894873
/** /**
* Refreshes the FPS throttling variables. * Refreshes the FPS throttling variables.
*/ */
void void
RefreshThrottleFPS() RefreshThrottleFPS()
{ {
uint64 fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz uint64 fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz
desired_frametime = 16777216.0l / (fps * g_fpsScale); desired_frametime = 16777216.0l / (fps * g_fpsScale);
Lasttime=0; Lasttime=0;
Nexttime=0; Nexttime=0;
InFrame=0; InFrame=0;
} }
/** /**
* Perform FPS speed throttling by delaying until the next time slot. * Perform FPS speed throttling by delaying until the next time slot.
*/ */
int int
SpeedThrottle() SpeedThrottle()
{ {
if(g_fpsScale >= 32) if(g_fpsScale >= 32)
{ {
return 0; /* Done waiting */ return 0; /* Done waiting */
} }
uint64 time_left; uint64 time_left;
uint64 cur_time; uint64 cur_time;
if(!Lasttime) if(!Lasttime)
Lasttime = SDL_GetTicks(); Lasttime = SDL_GetTicks();
if(!InFrame) if(!InFrame)
{ {
InFrame = 1; InFrame = 1;
Nexttime = Lasttime + desired_frametime * 1000; Nexttime = Lasttime + desired_frametime * 1000;
} }
cur_time = SDL_GetTicks(); cur_time = SDL_GetTicks();
if(cur_time >= Nexttime) if(cur_time >= Nexttime)
time_left = 0; time_left = 0;
else else
time_left = Nexttime - cur_time; time_left = Nexttime - cur_time;
if(time_left > 50) if(time_left > 50)
{ {
time_left = 50; time_left = 50;
/* In order to keep input responsive, don't wait too long at once */ /* In order to keep input responsive, don't wait too long at once */
/* 50 ms wait gives us a 20 Hz responsetime which is nice. */ /* 50 ms wait gives us a 20 Hz responsetime which is nice. */
} }
else else
InFrame = 0; InFrame = 0;
/*fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n", /*fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n",
time_left, InFrame?"no":"yes");*/ time_left, InFrame?"no":"yes");*/
SDL_Delay(time_left); SDL_Delay(time_left);
if(!InFrame) if(!InFrame)
{ {
Lasttime = SDL_GetTicks(); Lasttime = SDL_GetTicks();
return 0; /* Done waiting */ return 0; /* Done waiting */
} }
return 1; /* Must still wait some more */ return 1; /* Must still wait some more */
} }
/** /**
* Set the emulation speed throttling to the next entry in the speed table. * Set the emulation speed throttling to the next entry in the speed table.
*/ */
void IncreaseEmulationSpeed(void) void IncreaseEmulationSpeed(void)
{ {
g_fpsScale *= LOGMUL; g_fpsScale *= LOGMUL;
if(g_fpsScale > Fastest) g_fpsScale = Fastest; if(g_fpsScale > Fastest) g_fpsScale = Fastest;
RefreshThrottleFPS(); RefreshThrottleFPS();
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0); FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
} }
/** /**
* Set the emulation speed throttling to the previous entry in the speed table. * Set the emulation speed throttling to the previous entry in the speed table.
*/ */
void DecreaseEmulationSpeed(void) void DecreaseEmulationSpeed(void)
{ {
g_fpsScale /= LOGMUL; g_fpsScale /= LOGMUL;
if(g_fpsScale < Slowest) if(g_fpsScale < Slowest)
g_fpsScale = Slowest; g_fpsScale = Slowest;
RefreshThrottleFPS(); RefreshThrottleFPS();
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0); FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
} }
/** /**
* Set the emulation speed throttling to a specific value. * Set the emulation speed throttling to a specific value.
*/ */
void void
FCEUD_SetEmulationSpeed(int cmd) FCEUD_SetEmulationSpeed(int cmd)
{ {
MaxSpeed = false; MaxSpeed = false;
switch(cmd) { switch(cmd) {
case EMUSPEED_SLOWEST: case EMUSPEED_SLOWEST:
g_fpsScale = Slowest; g_fpsScale = Slowest;
break; break;
case EMUSPEED_SLOWER: case EMUSPEED_SLOWER:
DecreaseEmulationSpeed(); DecreaseEmulationSpeed();
break; break;
case EMUSPEED_NORMAL: case EMUSPEED_NORMAL:
g_fpsScale = Normal; g_fpsScale = Normal;
break; break;
case EMUSPEED_FASTER: case EMUSPEED_FASTER:
IncreaseEmulationSpeed(); IncreaseEmulationSpeed();
break; break;
case EMUSPEED_FASTEST: case EMUSPEED_FASTEST:
g_fpsScale = Fastest; g_fpsScale = Fastest;
MaxSpeed = true; MaxSpeed = true;
break; break;
default: default:
return; return;
} }
RefreshThrottleFPS(); RefreshThrottleFPS();
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0); FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
#ifndef __FCEU_SDL_VIDEO_H #ifndef __FCEU_SDL_VIDEO_H
#define __FCEU_SDL_VIDEO_H #define __FCEU_SDL_VIDEO_H
uint32 PtoV(uint16 x, uint16 y); uint32 PtoV(uint16 x, uint16 y);
bool FCEUD_ShouldDrawInputAids(); bool FCEUD_ShouldDrawInputAids();
bool FCEUI_AviDisableMovieMessages(); bool FCEUI_AviDisableMovieMessages();
static SDL_Surface *s_screen; static SDL_Surface *s_screen;
@ -8,5 +8,5 @@ bool FCEUI_AviEnableHUDrecording();
void FCEUI_SetAviEnableHUDrecording(bool enable); void FCEUI_SetAviEnableHUDrecording(bool enable);
bool FCEUI_AviDisableMovieMessages(); bool FCEUI_AviDisableMovieMessages();
void FCEUI_SetAviDisableMovieMessages(bool disable); void FCEUI_SetAviDisableMovieMessages(bool disable);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
#ifndef __FCEU_SDL_H #ifndef __FCEU_SDL_H
#define __FCEU_SDL_H #define __FCEU_SDL_H
#include <SDL.h> #include <SDL.h>
#include "main.h" #include "main.h"
#include "dface.h" #include "dface.h"
#include "input.h" #include "input.h"
static void DoFun(int frameskip); static void DoFun(int frameskip);
static int isloaded = 0; static int isloaded = 0;
extern int noGui; extern int noGui;
int LoadGame(const char *path); int LoadGame(const char *path);
int CloseGame(void); int CloseGame(void);
#endif #endif

View File

@ -1,2 +1,2 @@
void RefreshThrottleFPS(void); void RefreshThrottleFPS(void);
int SpeedThrottle(void); int SpeedThrottle(void);

View File

@ -1,357 +1,359 @@
/* FCE Ultra - NES/Famicom Emulator /* FCE Ultra - NES/Famicom Emulator
* *
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2002 Xodnizel * Copyright (C) 2002 Xodnizel
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
//todo - ensure that #ifdef WIN32 makes sense //todo - ensure that #ifdef WIN32 makes sense
//consider changing this to use sdl net stuff? //consider changing this to use sdl net stuff?
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include "main.h" #include "main.h"
#include "dface.h" #include "dface.h"
#include "unix-netplay.h" #include "unix-netplay.h"
#ifdef WIN32 #ifdef WIN32
#include <winsock.h> #include <winsock.h>
#else #else
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#endif #endif
#include "../../fceu.h" #include "../../fceu.h"
#include "../../utils/md5.h" #include "../../utils/md5.h"
#include "../../utils/memory.h" #include "../../utils/memory.h"
#include <string> #include <string>
#include "../common/configSys.h" #include "../common/configSys.h"
extern Config *g_config; extern Config *g_config;
#ifndef socklen_t #ifndef socklen_t
#define socklen_t int #define socklen_t int
#endif #endif
#ifndef SOL_TCP #ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP #define SOL_TCP IPPROTO_TCP
#endif #endif
int FCEUDnetplay=0; int FCEUDnetplay=0;
static int s_Socket = -1; static int s_Socket = -1;
static void static void
en32(uint8 *buf, en32(uint8 *buf,
uint32 morp) uint32 morp)
{ {
buf[0] = morp; buf[0] = morp;
buf[1] = morp >> 8; buf[1] = morp >> 8;
buf[2] = morp >> 16; buf[2] = morp >> 16;
buf[3] = morp >> 24; buf[3] = morp >> 24;
} }
/* /*
static uint32 de32(uint8 *morp) static uint32 de32(uint8 *morp)
{ {
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24)); return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
} }
*/ */
int int
FCEUD_NetworkConnect(void) FCEUD_NetworkConnect(void)
{ {
struct sockaddr_in sockin; struct sockaddr_in sockin;
struct hostent *phostentb; struct hostent *phostentb;
unsigned long hadr; unsigned long hadr;
int TSocket, tcpopt, error; int TSocket, tcpopt, error;
int netdivisor; int netdivisor;
// get any required configuration variables // get any required configuration variables
int port, localPlayers; int port, localPlayers;
std::string server, username, password, key; std::string server, username, password, key;
g_config->getOption("SDL.NetworkIP", &server); g_config->getOption("SDL.NetworkIP", &server);
g_config->getOption("SDL.NetworkUsername", &username); g_config->getOption("SDL.NetworkUsername", &username);
g_config->getOption("SDL.NetworkPassword", &password); g_config->getOption("SDL.NetworkPassword", &password);
g_config->getOption("SDL.NetworkGameKey", &key); g_config->getOption("SDL.NetworkGameKey", &key);
g_config->getOption("SDL.NetworkPort", &port); g_config->getOption("SDL.NetworkPort", &port);
g_config->getOption("SDL.NetworkPlayers", &localPlayers); g_config->getOption("SDL.NetworkPlayers", &localPlayers);
g_config->setOption("SDL.NetworkIP", ""); g_config->setOption("SDL.NetworkIP", "");
g_config->setOption("SDL.NetworkPassword", ""); g_config->setOption("SDL.NetworkPassword", "");
g_config->setOption("SDL.NetworkGameKey", ""); g_config->setOption("SDL.NetworkGameKey", "");
// only initialize if remote server is specified // only initialize if remote server is specified
if(!server.size()) { if(!server.size()) {
return 0; return 0;
} }
TSocket = socket(AF_INET, SOCK_STREAM, 0); TSocket = socket(AF_INET, SOCK_STREAM, 0);
if(TSocket < 0) { if(TSocket < 0) {
char* s = "Error creating stream socket."; char* s = "Error creating stream socket.";
puts(s); puts(s);
FCEU_DispMessage(s,0); FCEU_DispMessage(s,0);
FCEUD_NetworkClose(); FCEUD_NetworkClose();
return 0; return 0;
} }
// try to setup TCP_NODELAY to avoid network jitters // try to setup TCP_NODELAY to avoid network jitters
tcpopt = 1; tcpopt = 1;
#ifdef BEOS #ifdef BEOS
error = setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int)); error = setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int));
#elif WIN32 #elif WIN32
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY,
(char*)&tcpopt, sizeof(int)); (char*)&tcpopt, sizeof(int));
#else #else
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int)); error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int));
#endif #endif
if(error) { if(error) {
puts("Nodelay fail"); puts("Nodelay fail");
} }
memset(&sockin, 0, sizeof(sockin)); memset(&sockin, 0, sizeof(sockin));
sockin.sin_family = AF_INET; sockin.sin_family = AF_INET;
hadr = inet_addr(server.c_str()); hadr = inet_addr(server.c_str());
if(hadr != INADDR_NONE) { if(hadr != INADDR_NONE) {
sockin.sin_addr.s_addr = hadr; sockin.sin_addr.s_addr = hadr;
} else { } else {
puts("*** Looking up host name..."); puts("*** Looking up host name...");
phostentb = gethostbyname(server.c_str()); phostentb = gethostbyname(server.c_str());
if(!phostentb) { if(!phostentb) {
puts("Error getting host network information."); puts("Error getting host network information.");
FCEU_DispMessage("Error getting host info",0); FCEU_DispMessage("Error getting host info",0);
close(TSocket); close(TSocket);
FCEUD_NetworkClose(); FCEUD_NetworkClose();
return(0); return(0);
} }
memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length); memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length);
} }
sockin.sin_port = htons(port); sockin.sin_port = htons(port);
puts("*** Connecting to remote host..."); puts("*** Connecting to remote host...");
error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin)); error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin));
if(error < 0) { if(error < 0) {
puts("Error connecting to remote host."); puts("Error connecting to remote host.");
FCEU_DispMessage("Error connecting to server",0); FCEU_DispMessage("Error connecting to server",0);
close(TSocket); close(TSocket);
FCEUD_NetworkClose(); FCEUD_NetworkClose();
return 0; return 0;
} }
s_Socket = TSocket; s_Socket = TSocket;
puts("*** Sending initialization data to server..."); puts("*** Sending initialization data to server...");
uint8 *sendbuf; uint8 *sendbuf;
uint8 buf[5]; uint8 buf[5];
uint32 sblen; uint32 sblen;
sblen = 4 + 16 + 16 + 64 + 1 + username.size(); sblen = 4 + 16 + 16 + 64 + 1 + username.size();
sendbuf = (uint8 *)FCEU_dmalloc(sblen); sendbuf = (uint8 *)FCEU_dmalloc(sblen);
memset(sendbuf, 0, sblen); memset(sendbuf, 0, sblen);
// XXX soules - should use htons instead of en32() from above! // XXX soules - should use htons instead of en32() from above!
//uint32 data = htons(sblen - 4); //uint32 data = htons(sblen - 4);
//memcpy(sendbuf, &data, sizeof(data)); //memcpy(sendbuf, &data, sizeof(data));
en32(sendbuf, sblen - 4); en32(sendbuf, sblen - 4);
if(key.size()) { if(key.size())
struct md5_context md5; {
uint8 md5out[16]; struct md5_context md5;
uint8 md5out[16];
md5_starts(&md5);
md5_update(&md5, (uint8*)&GameInfo->MD5.data, 16); md5_starts(&md5);
md5_update(&md5, (uint8 *)key.c_str(), key.size()); md5_update(&md5, (uint8*)&GameInfo->MD5.data, 16);
md5_finish(&md5, md5out); md5_update(&md5, (uint8 *)key.c_str(), key.size());
memcpy(sendbuf + 4, md5out, 16); md5_finish(&md5, md5out);
} else { memcpy(sendbuf + 4, md5out, 16);
memcpy(sendbuf + 4, (uint8*)&GameInfo->MD5.data, 16); } else
} {
memcpy(sendbuf + 4, (uint8*)&GameInfo->MD5.data, 16);
if(password.size()) { }
struct md5_context md5;
uint8 md5out[16]; if(password.size()) {
struct md5_context md5;
md5_starts(&md5); uint8 md5out[16];
md5_update(&md5, (uint8 *)password.c_str(), password.size());
md5_finish(&md5, md5out); md5_starts(&md5);
memcpy(sendbuf + 4 + 16, md5out, 16); md5_update(&md5, (uint8 *)password.c_str(), password.size());
} md5_finish(&md5, md5out);
memcpy(sendbuf + 4 + 16, md5out, 16);
memset(sendbuf + 4 + 16 + 16, 0, 64); }
sendbuf[4 + 16 + 16 + 64] = (uint8)localPlayers; memset(sendbuf + 4 + 16 + 16, 0, 64);
if(username.size()) { sendbuf[4 + 16 + 16 + 64] = (uint8)localPlayers;
memcpy(sendbuf + 4 + 16 + 16 + 64 + 1,
username.c_str(), username.size()); if(username.size()) {
} memcpy(sendbuf + 4 + 16 + 16 + 64 + 1,
username.c_str(), username.size());
#ifdef WIN32 }
send(s_Socket, (char*)sendbuf, sblen, 0);
#else #ifdef WIN32
send(s_Socket, sendbuf, sblen, 0); send(s_Socket, (char*)sendbuf, sblen, 0);
#endif #else
FCEU_dfree(sendbuf); send(s_Socket, sendbuf, sblen, 0);
#endif
#ifdef WIN32 FCEU_dfree(sendbuf);
recv(s_Socket, (char*)buf, 1, 0);
#else #ifdef WIN32
recv(s_Socket, buf, 1, MSG_WAITALL); recv(s_Socket, (char*)buf, 1, 0);
#endif #else
netdivisor = buf[0]; recv(s_Socket, buf, 1, MSG_WAITALL);
#endif
puts("*** Connection established."); netdivisor = buf[0];
FCEU_DispMessage("Connection established.",0);
puts("*** Connection established.");
FCEUDnetplay = 1; FCEU_DispMessage("Connection established.",0);
FCEUI_NetplayStart(localPlayers, netdivisor);
FCEUDnetplay = 1;
return 1; FCEUI_NetplayStart(localPlayers, netdivisor);
}
return 1;
}
int
FCEUD_SendData(void *data,
uint32 len) int
{ FCEUD_SendData(void *data,
int check = 0, error = 0; uint32 len)
#ifndef WIN32 {
error = ioctl(fileno(stdin), FIONREAD, &check); int check = 0, error = 0;
#endif #ifndef WIN32
if(!error && check) { error = ioctl(fileno(stdin), FIONREAD, &check);
char buf[1024]; #endif
char *f; if(!error && check) {
fgets(buf, 1024, stdin); char buf[1024];
if((f=strrchr(buf,'\n'))) { char *f;
*f = 0; fgets(buf, 1024, stdin);
} if((f=strrchr(buf,'\n'))) {
FCEUI_NetplayText((uint8 *)buf); *f = 0;
} }
FCEUI_NetplayText((uint8 *)buf);
#ifdef WIN32 }
send(s_Socket, (char*)data, len ,0);
#else #ifdef WIN32
send(s_Socket, data, len ,0); send(s_Socket, (char*)data, len ,0);
#endif #else
return 1; send(s_Socket, data, len ,0);
} #endif
return 1;
int }
FCEUD_RecvData(void *data,
uint32 len) int
{ FCEUD_RecvData(void *data,
int size; uint32 len)
NoWaiting &= ~2; {
int size;
for(;;) { NoWaiting &= ~2;
fd_set funfun;
struct timeval popeye; for(;;)
{
popeye.tv_sec=0; fd_set funfun;
popeye.tv_usec=100000; struct timeval popeye;
FD_ZERO(&funfun); popeye.tv_sec=0;
FD_SET(s_Socket, &funfun); popeye.tv_usec=100000;
switch(select(s_Socket + 1,&funfun,0,0,&popeye)) { FD_ZERO(&funfun);
case 0: continue; FD_SET(s_Socket, &funfun);
case -1:return(0);
} switch(select(s_Socket + 1,&funfun,0,0,&popeye)) {
case 0: continue;
if(FD_ISSET(s_Socket,&funfun)) { case -1:return 0;
#ifdef WIN32 }
size = recv(s_Socket, (char*)data, len, 0);
#else if(FD_ISSET(s_Socket,&funfun)) {
size = recv(s_Socket, data, len, MSG_WAITALL); #ifdef WIN32
#endif size = recv(s_Socket, (char*)data, len, 0);
#else
if(size == len) { size = recv(s_Socket, data, len, MSG_WAITALL);
//unsigned long beefie; #endif
FD_ZERO(&funfun); if(size == len) {
FD_SET(s_Socket, &funfun); //unsigned long beefie;
popeye.tv_sec = popeye.tv_usec = 0; FD_ZERO(&funfun);
if(select(s_Socket + 1, &funfun, 0, 0, &popeye) == 1) FD_SET(s_Socket, &funfun);
//if(!ioctl(s_Socket,FIONREAD,&beefie))
// if(beefie) popeye.tv_sec = popeye.tv_usec = 0;
{ if(select(s_Socket + 1, &funfun, 0, 0, &popeye) == 1)
NoWaiting|=2; //if(!ioctl(s_Socket,FIONREAD,&beefie))
//puts("Yaya"); // if(beefie)
} {
return(1); NoWaiting|=2;
} else { }
return(0); return 1;
} } else {
} return 0;
} }
}
return 0; }
}
return 0;
void }
FCEUD_NetworkClose(void)
{ void
if(s_Socket > 0) { FCEUD_NetworkClose(void)
#ifdef BEOS {
closesocket(s_Socket); if(s_Socket > 0) {
#else #ifdef BEOS
close(s_Socket); closesocket(s_Socket);
#endif #else
} close(s_Socket);
s_Socket = -1; #endif
}
if(FCEUDnetplay) { s_Socket = -1;
FCEUI_NetplayStop();
} if(FCEUDnetplay) {
FCEUDnetplay = 0; FCEUI_NetplayStop();
} }
FCEUDnetplay = 0;
}
void
FCEUD_NetplayText(uint8 *text)
{ void
char *tot = (char *)FCEU_dmalloc(strlen((const char *)text) + 1); FCEUD_NetplayText(uint8 *text)
char *tmp; {
if (!tot) char *tot = (char *)FCEU_dmalloc(strlen((const char *)text) + 1);
return; char *tmp;
strcpy(tot, (const char *)text); if (!tot)
tmp = tot; return;
strcpy(tot, (const char *)text);
while(*tmp) { tmp = tot;
if(*tmp < 0x20) {
*tmp = ' '; while(*tmp) {
} if(*tmp < 0x20) {
tmp++; *tmp = ' ';
} }
puts(tot); tmp++;
FCEU_dfree(tot); }
} puts(tot);
FCEU_dfree(tot);
}

View File

@ -1,6 +1,6 @@
extern char *netplaynick; extern char *netplaynick;
extern char *netplayhost; extern char *netplayhost;
extern char *netpassword; extern char *netpassword;
extern char *netgamekey; extern char *netgamekey;
extern int tport; extern int tport;
extern int netlocalplayers; extern int netlocalplayers;