sdl: code cleanup; pre-release code review (in progress)
This commit is contained in:
parent
118b82544c
commit
b0c2758324
|
@ -1,417 +1,417 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "throttle.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "../common/cheat.h"
|
||||
|
||||
#include "input.h"
|
||||
#include "dface.h"
|
||||
|
||||
#include "sdl.h"
|
||||
#include "sdl-video.h"
|
||||
#include "unix-netplay.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Read a custom pallete from a file and load it into the core.
|
||||
*/
|
||||
int
|
||||
LoadCPalette(const std::string &file)
|
||||
{
|
||||
uint8 tmpp[192];
|
||||
FILE *fp;
|
||||
|
||||
if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) {
|
||||
printf(" Error loading custom palette from file: %s\n", file.c_str());
|
||||
return 0;
|
||||
}
|
||||
size_t result = fread(tmpp, 1, 192, fp);
|
||||
if(result != 192) {
|
||||
printf(" Error reading custom palette from file: %s\n", file.c_str());
|
||||
return 0;
|
||||
}
|
||||
FCEUI_SetPaletteArray(tmpp);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the subdirectories used for saving snapshots, movies, game
|
||||
* saves, etc. Hopefully obsolete with new configuration system.
|
||||
*/
|
||||
static void
|
||||
CreateDirs(const std::string &dir)
|
||||
{
|
||||
char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
|
||||
std::string subdir;
|
||||
int x;
|
||||
|
||||
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
|
||||
mkdir(dir.c_str());
|
||||
chmod(dir.c_str(), 755);
|
||||
for(x = 0; x < 6; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str());
|
||||
}
|
||||
#else
|
||||
mkdir(dir.c_str(), S_IRWXU);
|
||||
for(x = 0; x < 6; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str(), S_IRWXU);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to locate FCEU's application directory. This will
|
||||
* hopefully become obsolete once the new configuration system is in
|
||||
* place.
|
||||
*/
|
||||
static void
|
||||
GetBaseDirectory(std::string &dir)
|
||||
{
|
||||
char *home = getenv("HOME");
|
||||
if(home) {
|
||||
dir = std::string(home) + "/.fceux";
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
home = new char[MAX_PATH + 1];
|
||||
GetModuleFileName(NULL, home, MAX_PATH + 1);
|
||||
|
||||
char *lastBS = strrchr(home,'\\');
|
||||
if(lastBS) {
|
||||
*lastBS = 0;
|
||||
}
|
||||
|
||||
dir = std::string(home);
|
||||
delete[] home;
|
||||
#else
|
||||
dir = "";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// returns a config structure with default options
|
||||
// also creates config base directory (ie: /home/user/.fceux as well as subdirs
|
||||
Config *
|
||||
InitConfig()
|
||||
{
|
||||
std::string dir, prefix;
|
||||
Config *config;
|
||||
|
||||
GetBaseDirectory(dir);
|
||||
|
||||
FCEUI_SetBaseDirectory(dir.c_str());
|
||||
CreateDirs(dir);
|
||||
|
||||
config = new Config(dir);
|
||||
|
||||
// sound options
|
||||
config->addOption('s', "sound", "SDL.Sound", 1);
|
||||
config->addOption("volume", "SDL.Sound.Volume", 150);
|
||||
config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 256);
|
||||
config->addOption("square1vol", "SDL.Sound.Square1Volume", 256);
|
||||
config->addOption("square2vol", "SDL.Sound.Square2Volume", 256);
|
||||
config->addOption("noisevol", "SDL.Sound.NoiseVolume", 256);
|
||||
config->addOption("pcmvol", "SDL.Sound.PCMVolume", 256);
|
||||
config->addOption("soundrate", "SDL.Sound.Rate", 44100);
|
||||
config->addOption("soundq", "SDL.Sound.Quality", 1);
|
||||
config->addOption("soundrecord", "SDL.Sound.RecordFile", "");
|
||||
config->addOption("soundbufsize", "SDL.Sound.BufSize", 128);
|
||||
config->addOption("lowpass", "SDL.Sound.LowPass", 0);
|
||||
|
||||
config->addOption('g', "gamegenie", "SDL.GameGenie", 0);
|
||||
config->addOption("pal", "SDL.PAL", 0);
|
||||
config->addOption("frameskip", "SDL.Frameskip", 0);
|
||||
config->addOption("clipsides", "SDL.ClipSides", 0);
|
||||
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);
|
||||
|
||||
// color control
|
||||
config->addOption('p', "palette", "SDL.Palette", "");
|
||||
config->addOption("tint", "SDL.Tint", 56);
|
||||
config->addOption("hue", "SDL.Hue", 72);
|
||||
config->addOption("ntsccolor", "SDL.NTSCpalette", 0);
|
||||
|
||||
// scanline settings
|
||||
config->addOption("slstart", "SDL.ScanLineStart", 0);
|
||||
config->addOption("slend", "SDL.ScanLineEnd", 239);
|
||||
|
||||
// video controls
|
||||
config->addOption('x', "xres", "SDL.XResolution", 512);
|
||||
config->addOption('y', "yres", "SDL.YResolution", 448);
|
||||
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
|
||||
config->addOption('b', "bpp", "SDL.BitsPerPixel", 32);
|
||||
config->addOption("doublebuf", "SDL.DoubleBuffering", 0);
|
||||
config->addOption("autoscale", "SDL.AutoScale", 1);
|
||||
config->addOption("keepratio", "SDL.KeepRatio", 1);
|
||||
config->addOption("xscale", "SDL.XScale", 1.0);
|
||||
config->addOption("yscale", "SDL.YScale", 1.0);
|
||||
config->addOption("xstretch", "SDL.XStretch", 0);
|
||||
config->addOption("ystretch", "SDL.YStretch", 0);
|
||||
config->addOption("noframe", "SDL.NoFrame", 0);
|
||||
config->addOption("special", "SDL.SpecialFilter", 0);
|
||||
|
||||
// OpenGL options
|
||||
config->addOption("opengl", "SDL.OpenGL", 0);
|
||||
config->addOption("openglip", "SDL.OpenGLip", 0);
|
||||
config->addOption("SDL.SpecialFilter", 0);
|
||||
config->addOption("SDL.SpecialFX", 0);
|
||||
config->addOption("SDL.Vsync", 1);
|
||||
|
||||
// network play options - netplay is broken
|
||||
config->addOption("server", "SDL.NetworkIsServer", 0);
|
||||
config->addOption('n', "net", "SDL.NetworkIP", "");
|
||||
config->addOption('u', "user", "SDL.NetworkUsername", "");
|
||||
config->addOption('w', "pass", "SDL.NetworkPassword", "");
|
||||
config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
|
||||
config->addOption("port", "SDL.NetworkPort", 4046);
|
||||
config->addOption("players", "SDL.NetworkPlayers", 1);
|
||||
|
||||
// input configuration options
|
||||
config->addOption("input1", "SDL.Input.0", "GamePad.0");
|
||||
config->addOption("input2", "SDL.Input.1", "GamePad.1");
|
||||
config->addOption("input3", "SDL.Input.2", "Gamepad.2");
|
||||
config->addOption("input4", "SDL.Input.3", "Gamepad.3");
|
||||
|
||||
// allow for input configuration
|
||||
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
|
||||
|
||||
// display input
|
||||
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
|
||||
|
||||
// pause movie playback at frame x
|
||||
config->addOption("pauseframe", "SDL.PauseFrame", 0);
|
||||
config->addOption("recordhud", "SDL.RecordHUD", 1);
|
||||
config->addOption("moviemsg", "SDL.MovieMsg", 1);
|
||||
|
||||
// overwrite the config file?
|
||||
config->addOption("no-config", "SDL.NoConfig", 0);
|
||||
|
||||
// video playback
|
||||
config->addOption("playmov", "SDL.Movie", "");
|
||||
config->addOption("subtitles", "SDL.SubtitleDisplay", 1);
|
||||
|
||||
config->addOption("fourscore", "SDL.FourScore", 0);
|
||||
|
||||
config->addOption("nofscursor", "SDL.NoFullscreenCursor", 1);
|
||||
|
||||
#ifdef _S9XLUA_H
|
||||
// load lua script
|
||||
config->addOption("loadlua", "SDL.LuaScript", "");
|
||||
#endif
|
||||
|
||||
#ifdef CREATE_AVI
|
||||
config->addOption("videolog", "SDL.VideoLog", "");
|
||||
config->addOption("mute", "SDL.MuteCapture", 0);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _GTK
|
||||
char* home_dir = getenv("HOME");
|
||||
// prefixed with _ because they are internal (not cli options)
|
||||
config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir);
|
||||
config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir);
|
||||
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
|
||||
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
|
||||
config->addOption("_lastloadlua", "SDL.LastLoadLua", home_dir);
|
||||
#endif
|
||||
|
||||
// fcm -> fm2 conversion
|
||||
config->addOption("fcmconvert", "SDL.FCMConvert", "");
|
||||
|
||||
// fm2 -> srt conversion
|
||||
config->addOption("ripsubs", "SDL.RipSubs", "");
|
||||
|
||||
// enable new PPU core
|
||||
config->addOption("newppu", "SDL.NewPPU", 0);
|
||||
|
||||
|
||||
// GamePad 0 - 3
|
||||
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.GamePad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// PowerPad 0 - 1
|
||||
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// QuizKing
|
||||
prefix = "SDL.Input.QuizKing.";
|
||||
config->addOption(prefix + "DeviceType", DefaultQuizKingDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]);
|
||||
}
|
||||
|
||||
// HyperShot
|
||||
prefix = "SDL.Input.HyperShot.";
|
||||
config->addOption(prefix + "DeviceType", DefaultHyperShotDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]);
|
||||
}
|
||||
|
||||
// Mahjong
|
||||
prefix = "SDL.Input.Mahjong.";
|
||||
config->addOption(prefix + "DeviceType", DefaultMahjongDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]);
|
||||
}
|
||||
|
||||
// TopRider
|
||||
prefix = "SDL.Input.TopRider.";
|
||||
config->addOption(prefix + "DeviceType", DefaultTopRiderDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]);
|
||||
}
|
||||
|
||||
// FTrainer
|
||||
prefix = "SDL.Input.FTrainer.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFTrainerDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]);
|
||||
}
|
||||
|
||||
// FamilyKeyBoard
|
||||
prefix = "SDL.Input.FamilyKeyBoard.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FamilyKeyBoardNames[j],
|
||||
DefaultFamilyKeyBoard[j]);
|
||||
}
|
||||
|
||||
// for FAMICOM microphone in pad 2 pad 1 didn't have it
|
||||
// Takeshi no Chousenjou uses it for example.
|
||||
prefix = "SDL.Input.FamicomPad2.";
|
||||
config->addOption("rp2mic", prefix + "EnableMic", 0);
|
||||
|
||||
// TODO: use a better data structure to store the hotkeys or something
|
||||
// improve this code overall in the future to make it
|
||||
// easier to maintain
|
||||
const int Hotkeys[HK_MAX] = {
|
||||
SDLK_F1, // cheat menu
|
||||
SDLK_F2, // bind state
|
||||
SDLK_F3, // load lua
|
||||
SDLK_F4, // toggleBG
|
||||
SDLK_F5, // save state
|
||||
SDLK_F6, // fds select
|
||||
SDLK_F7, // load state
|
||||
SDLK_F8, // fds eject
|
||||
SDLK_F6, // VS insert coin
|
||||
SDLK_F8, // VS toggle dipswitch
|
||||
SDLK_PERIOD, // toggle frame display
|
||||
SDLK_F10, // toggle subtitle
|
||||
SDLK_F11, // reset
|
||||
SDLK_F12, // screenshot
|
||||
SDLK_PAUSE, // pause
|
||||
SDLK_MINUS, // speed++
|
||||
SDLK_EQUALS, // speed--
|
||||
SDLK_BACKQUOTE, //frame advnace
|
||||
SDLK_TAB, // turbo
|
||||
SDLK_COMMA, // toggle input display
|
||||
SDLK_q, // toggle movie RW
|
||||
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
|
||||
SDLK_DELETE, // frame advance lag skip
|
||||
SDLK_SLASH, // lag counter display
|
||||
SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5,
|
||||
SDLK_6, SDLK_7, SDLK_8, SDLK_9,
|
||||
SDLK_PAGEUP, // select state next
|
||||
SDLK_PAGEDOWN}; // select state prev
|
||||
|
||||
prefix = "SDL.Hotkeys.";
|
||||
for(int i=0; i < HK_MAX; i++)
|
||||
config->addOption(prefix + HotkeyStrings[i], Hotkeys[i]);
|
||||
// All mouse devices
|
||||
config->addOption("SDL.OekaKids.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.OekaKids.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Arkanoid.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Shadow.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Shadow.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Zapper.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Zapper.0.DeviceNum", 0);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateEMUCore(Config *config)
|
||||
{
|
||||
int ntsccol, ntsctint, ntschue, flag, start, end;
|
||||
std::string cpalette;
|
||||
|
||||
config->getOption("SDL.NTSCpalette", &ntsccol);
|
||||
config->getOption("SDL.Tint", &ntsctint);
|
||||
config->getOption("SDL.Hue", &ntschue);
|
||||
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||
|
||||
config->getOption("SDL.Palette", &cpalette);
|
||||
if(cpalette.size()) {
|
||||
LoadCPalette(cpalette);
|
||||
}
|
||||
|
||||
config->getOption("SDL.PAL", &flag);
|
||||
FCEUI_SetVidSystem(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.GameGenie", &flag);
|
||||
FCEUI_SetGameGenie(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.Sound.LowPass", &flag);
|
||||
FCEUI_SetLowPass(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.DisableSpriteLimit", &flag);
|
||||
FCEUI_DisableSpriteLimitation(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.ScanLineStart", &start);
|
||||
config->getOption("SDL.ScanLineEnd", &end);
|
||||
|
||||
#if DOING_SCANLINE_CHECKS
|
||||
for(int i = 0; i < 2; x++) {
|
||||
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
||||
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
||||
}
|
||||
#endif
|
||||
|
||||
FCEUI_SetRenderedLines(start + 8, end - 8, start, end);
|
||||
}
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "throttle.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "../common/cheat.h"
|
||||
|
||||
#include "input.h"
|
||||
#include "dface.h"
|
||||
|
||||
#include "sdl.h"
|
||||
#include "sdl-video.h"
|
||||
#include "unix-netplay.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Read a custom pallete from a file and load it into the core.
|
||||
*/
|
||||
int
|
||||
LoadCPalette(const std::string &file)
|
||||
{
|
||||
uint8 tmpp[192];
|
||||
FILE *fp;
|
||||
|
||||
if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) {
|
||||
printf(" Error loading custom palette from file: %s\n", file.c_str());
|
||||
return 0;
|
||||
}
|
||||
size_t result = fread(tmpp, 1, 192, fp);
|
||||
if(result != 192) {
|
||||
printf(" Error reading custom palette from file: %s\n", file.c_str());
|
||||
return 0;
|
||||
}
|
||||
FCEUI_SetPaletteArray(tmpp);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the subdirectories used for saving snapshots, movies, game
|
||||
* saves, etc. Hopefully obsolete with new configuration system.
|
||||
*/
|
||||
static void
|
||||
CreateDirs(const std::string &dir)
|
||||
{
|
||||
char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
|
||||
std::string subdir;
|
||||
int x;
|
||||
|
||||
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
|
||||
mkdir(dir.c_str());
|
||||
chmod(dir.c_str(), 755);
|
||||
for(x = 0; x < 6; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str());
|
||||
}
|
||||
#else
|
||||
mkdir(dir.c_str(), S_IRWXU);
|
||||
for(x = 0; x < 6; x++) {
|
||||
subdir = dir + PSS + subs[x];
|
||||
mkdir(subdir.c_str(), S_IRWXU);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to locate FCEU's application directory. This will
|
||||
* hopefully become obsolete once the new configuration system is in
|
||||
* place.
|
||||
*/
|
||||
static void
|
||||
GetBaseDirectory(std::string &dir)
|
||||
{
|
||||
char *home = getenv("HOME");
|
||||
if(home) {
|
||||
dir = std::string(home) + "/.fceux";
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
home = new char[MAX_PATH + 1];
|
||||
GetModuleFileName(NULL, home, MAX_PATH + 1);
|
||||
|
||||
char *lastBS = strrchr(home,'\\');
|
||||
if(lastBS) {
|
||||
*lastBS = 0;
|
||||
}
|
||||
|
||||
dir = std::string(home);
|
||||
delete[] home;
|
||||
#else
|
||||
dir = "";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// returns a config structure with default options
|
||||
// also creates config base directory (ie: /home/user/.fceux as well as subdirs
|
||||
Config *
|
||||
InitConfig()
|
||||
{
|
||||
std::string dir, prefix;
|
||||
Config *config;
|
||||
|
||||
GetBaseDirectory(dir);
|
||||
|
||||
FCEUI_SetBaseDirectory(dir.c_str());
|
||||
CreateDirs(dir);
|
||||
|
||||
config = new Config(dir);
|
||||
|
||||
// sound options
|
||||
config->addOption('s', "sound", "SDL.Sound", 1);
|
||||
config->addOption("volume", "SDL.Sound.Volume", 150);
|
||||
config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 256);
|
||||
config->addOption("square1vol", "SDL.Sound.Square1Volume", 256);
|
||||
config->addOption("square2vol", "SDL.Sound.Square2Volume", 256);
|
||||
config->addOption("noisevol", "SDL.Sound.NoiseVolume", 256);
|
||||
config->addOption("pcmvol", "SDL.Sound.PCMVolume", 256);
|
||||
config->addOption("soundrate", "SDL.Sound.Rate", 44100);
|
||||
config->addOption("soundq", "SDL.Sound.Quality", 1);
|
||||
config->addOption("soundrecord", "SDL.Sound.RecordFile", "");
|
||||
config->addOption("soundbufsize", "SDL.Sound.BufSize", 128);
|
||||
config->addOption("lowpass", "SDL.Sound.LowPass", 0);
|
||||
|
||||
config->addOption('g', "gamegenie", "SDL.GameGenie", 0);
|
||||
config->addOption("pal", "SDL.PAL", 0);
|
||||
config->addOption("frameskip", "SDL.Frameskip", 0);
|
||||
config->addOption("clipsides", "SDL.ClipSides", 0);
|
||||
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);
|
||||
|
||||
// color control
|
||||
config->addOption('p', "palette", "SDL.Palette", "");
|
||||
config->addOption("tint", "SDL.Tint", 56);
|
||||
config->addOption("hue", "SDL.Hue", 72);
|
||||
config->addOption("ntsccolor", "SDL.NTSCpalette", 0);
|
||||
|
||||
// scanline settings
|
||||
config->addOption("slstart", "SDL.ScanLineStart", 0);
|
||||
config->addOption("slend", "SDL.ScanLineEnd", 239);
|
||||
|
||||
// video controls
|
||||
config->addOption('x', "xres", "SDL.XResolution", 512);
|
||||
config->addOption('y', "yres", "SDL.YResolution", 448);
|
||||
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
|
||||
config->addOption('b', "bpp", "SDL.BitsPerPixel", 32);
|
||||
config->addOption("doublebuf", "SDL.DoubleBuffering", 0);
|
||||
config->addOption("autoscale", "SDL.AutoScale", 1);
|
||||
config->addOption("keepratio", "SDL.KeepRatio", 1);
|
||||
config->addOption("xscale", "SDL.XScale", 1.0);
|
||||
config->addOption("yscale", "SDL.YScale", 1.0);
|
||||
config->addOption("xstretch", "SDL.XStretch", 0);
|
||||
config->addOption("ystretch", "SDL.YStretch", 0);
|
||||
config->addOption("noframe", "SDL.NoFrame", 0);
|
||||
config->addOption("special", "SDL.SpecialFilter", 0);
|
||||
|
||||
// OpenGL options
|
||||
config->addOption("opengl", "SDL.OpenGL", 0);
|
||||
config->addOption("openglip", "SDL.OpenGLip", 0);
|
||||
config->addOption("SDL.SpecialFilter", 0);
|
||||
config->addOption("SDL.SpecialFX", 0);
|
||||
config->addOption("SDL.Vsync", 1);
|
||||
|
||||
// network play options - netplay is broken
|
||||
config->addOption("server", "SDL.NetworkIsServer", 0);
|
||||
config->addOption('n', "net", "SDL.NetworkIP", "");
|
||||
config->addOption('u', "user", "SDL.NetworkUsername", "");
|
||||
config->addOption('w', "pass", "SDL.NetworkPassword", "");
|
||||
config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
|
||||
config->addOption("port", "SDL.NetworkPort", 4046);
|
||||
config->addOption("players", "SDL.NetworkPlayers", 1);
|
||||
|
||||
// input configuration options
|
||||
config->addOption("input1", "SDL.Input.0", "GamePad.0");
|
||||
config->addOption("input2", "SDL.Input.1", "GamePad.1");
|
||||
config->addOption("input3", "SDL.Input.2", "Gamepad.2");
|
||||
config->addOption("input4", "SDL.Input.3", "Gamepad.3");
|
||||
|
||||
// allow for input configuration
|
||||
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
|
||||
|
||||
// display input
|
||||
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
|
||||
|
||||
// pause movie playback at frame x
|
||||
config->addOption("pauseframe", "SDL.PauseFrame", 0);
|
||||
config->addOption("recordhud", "SDL.RecordHUD", 1);
|
||||
config->addOption("moviemsg", "SDL.MovieMsg", 1);
|
||||
|
||||
// overwrite the config file?
|
||||
config->addOption("no-config", "SDL.NoConfig", 0);
|
||||
|
||||
// video playback
|
||||
config->addOption("playmov", "SDL.Movie", "");
|
||||
config->addOption("subtitles", "SDL.SubtitleDisplay", 1);
|
||||
|
||||
config->addOption("fourscore", "SDL.FourScore", 0);
|
||||
|
||||
config->addOption("nofscursor", "SDL.NoFullscreenCursor", 1);
|
||||
|
||||
#ifdef _S9XLUA_H
|
||||
// load lua script
|
||||
config->addOption("loadlua", "SDL.LuaScript", "");
|
||||
#endif
|
||||
|
||||
#ifdef CREATE_AVI
|
||||
config->addOption("videolog", "SDL.VideoLog", "");
|
||||
config->addOption("mute", "SDL.MuteCapture", 0);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _GTK
|
||||
char* home_dir = getenv("HOME");
|
||||
// prefixed with _ because they are internal (not cli options)
|
||||
config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir);
|
||||
config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir);
|
||||
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
|
||||
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
|
||||
config->addOption("_lastloadlua", "SDL.LastLoadLua", home_dir);
|
||||
#endif
|
||||
|
||||
// fcm -> fm2 conversion
|
||||
config->addOption("fcmconvert", "SDL.FCMConvert", "");
|
||||
|
||||
// fm2 -> srt conversion
|
||||
config->addOption("ripsubs", "SDL.RipSubs", "");
|
||||
|
||||
// enable new PPU core
|
||||
config->addOption("newppu", "SDL.NewPPU", 0);
|
||||
|
||||
|
||||
// GamePad 0 - 3
|
||||
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.GamePad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// PowerPad 0 - 1
|
||||
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
|
||||
char buf[64];
|
||||
snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i);
|
||||
prefix = buf;
|
||||
|
||||
config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// QuizKing
|
||||
prefix = "SDL.Input.QuizKing.";
|
||||
config->addOption(prefix + "DeviceType", DefaultQuizKingDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]);
|
||||
}
|
||||
|
||||
// HyperShot
|
||||
prefix = "SDL.Input.HyperShot.";
|
||||
config->addOption(prefix + "DeviceType", DefaultHyperShotDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]);
|
||||
}
|
||||
|
||||
// Mahjong
|
||||
prefix = "SDL.Input.Mahjong.";
|
||||
config->addOption(prefix + "DeviceType", DefaultMahjongDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]);
|
||||
}
|
||||
|
||||
// TopRider
|
||||
prefix = "SDL.Input.TopRider.";
|
||||
config->addOption(prefix + "DeviceType", DefaultTopRiderDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]);
|
||||
}
|
||||
|
||||
// FTrainer
|
||||
prefix = "SDL.Input.FTrainer.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFTrainerDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]);
|
||||
}
|
||||
|
||||
// FamilyKeyBoard
|
||||
prefix = "SDL.Input.FamilyKeyBoard.";
|
||||
config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice);
|
||||
config->addOption(prefix + "DeviceNum", 0);
|
||||
for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) {
|
||||
config->addOption(prefix + FamilyKeyBoardNames[j],
|
||||
DefaultFamilyKeyBoard[j]);
|
||||
}
|
||||
|
||||
// for FAMICOM microphone in pad 2 pad 1 didn't have it
|
||||
// Takeshi no Chousenjou uses it for example.
|
||||
prefix = "SDL.Input.FamicomPad2.";
|
||||
config->addOption("rp2mic", prefix + "EnableMic", 0);
|
||||
|
||||
// TODO: use a better data structure to store the hotkeys or something
|
||||
// improve this code overall in the future to make it
|
||||
// easier to maintain
|
||||
const int Hotkeys[HK_MAX] = {
|
||||
SDLK_F1, // cheat menu
|
||||
SDLK_F2, // bind state
|
||||
SDLK_F3, // load lua
|
||||
SDLK_F4, // toggleBG
|
||||
SDLK_F5, // save state
|
||||
SDLK_F6, // fds select
|
||||
SDLK_F7, // load state
|
||||
SDLK_F8, // fds eject
|
||||
SDLK_F6, // VS insert coin
|
||||
SDLK_F8, // VS toggle dipswitch
|
||||
SDLK_PERIOD, // toggle frame display
|
||||
SDLK_F10, // toggle subtitle
|
||||
SDLK_F11, // reset
|
||||
SDLK_F12, // screenshot
|
||||
SDLK_PAUSE, // pause
|
||||
SDLK_MINUS, // speed++
|
||||
SDLK_EQUALS, // speed--
|
||||
SDLK_BACKQUOTE, //frame advnace
|
||||
SDLK_TAB, // turbo
|
||||
SDLK_COMMA, // toggle input display
|
||||
SDLK_q, // toggle movie RW
|
||||
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
|
||||
SDLK_DELETE, // frame advance lag skip
|
||||
SDLK_SLASH, // lag counter display
|
||||
SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5,
|
||||
SDLK_6, SDLK_7, SDLK_8, SDLK_9,
|
||||
SDLK_PAGEUP, // select state next
|
||||
SDLK_PAGEDOWN}; // select state prev
|
||||
|
||||
prefix = "SDL.Hotkeys.";
|
||||
for(int i=0; i < HK_MAX; i++)
|
||||
config->addOption(prefix + HotkeyStrings[i], Hotkeys[i]);
|
||||
// All mouse devices
|
||||
config->addOption("SDL.OekaKids.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.OekaKids.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Arkanoid.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Shadow.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Shadow.0.DeviceNum", 0);
|
||||
|
||||
config->addOption("SDL.Zapper.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.Zapper.0.DeviceNum", 0);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateEMUCore(Config *config)
|
||||
{
|
||||
int ntsccol, ntsctint, ntschue, flag, start, end;
|
||||
std::string cpalette;
|
||||
|
||||
config->getOption("SDL.NTSCpalette", &ntsccol);
|
||||
config->getOption("SDL.Tint", &ntsctint);
|
||||
config->getOption("SDL.Hue", &ntschue);
|
||||
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||
|
||||
config->getOption("SDL.Palette", &cpalette);
|
||||
if(cpalette.size()) {
|
||||
LoadCPalette(cpalette);
|
||||
}
|
||||
|
||||
config->getOption("SDL.PAL", &flag);
|
||||
FCEUI_SetVidSystem(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.GameGenie", &flag);
|
||||
FCEUI_SetGameGenie(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.Sound.LowPass", &flag);
|
||||
FCEUI_SetLowPass(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.DisableSpriteLimit", &flag);
|
||||
FCEUI_DisableSpriteLimitation(flag ? 1 : 0);
|
||||
|
||||
config->getOption("SDL.ScanLineStart", &start);
|
||||
config->getOption("SDL.ScanLineEnd", &end);
|
||||
|
||||
#if DOING_SCANLINE_CHECKS
|
||||
for(int i = 0; i < 2; x++) {
|
||||
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
||||
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
||||
}
|
||||
#endif
|
||||
|
||||
FCEUI_SetRenderedLines(start + 8, end - 8, start, end);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
#include "../common/args.h"
|
||||
#include "../common/config.h"
|
||||
|
||||
#include "input.h"
|
||||
|
||||
extern CFGSTRUCT DriverConfig[];
|
||||
extern ARGPSTRUCT DriverArgs[];
|
||||
extern char *DriverUsage;
|
||||
|
||||
void DoDriverArgs(void);
|
||||
|
||||
int InitSound();
|
||||
void WriteSound(int32 *Buffer, int Count);
|
||||
int KillSound(void);
|
||||
uint32 GetMaxSound(void);
|
||||
uint32 GetWriteSound(void);
|
||||
|
||||
void SilenceSound(int s); /* DOS and SDL */
|
||||
|
||||
int InitJoysticks(void);
|
||||
int KillJoysticks(void);
|
||||
uint32 *GetJSOr(void);
|
||||
|
||||
int InitVideo(FCEUGI *gi);
|
||||
int KillVideo(void);
|
||||
void BlitScreen(uint8 *XBuf);
|
||||
void LockConsole(void);
|
||||
void UnlockConsole(void);
|
||||
void ToggleFS(); /* SDL */
|
||||
|
||||
int LoadGame(const char *path);
|
||||
//int CloseGame(void);
|
||||
|
||||
void Giggles(int);
|
||||
void DoFun(void);
|
||||
|
||||
int FCEUD_NetworkConnect(void);
|
||||
|
||||
#include "../common/args.h"
|
||||
#include "../common/config.h"
|
||||
|
||||
#include "input.h"
|
||||
|
||||
extern CFGSTRUCT DriverConfig[];
|
||||
extern ARGPSTRUCT DriverArgs[];
|
||||
extern char *DriverUsage;
|
||||
|
||||
void DoDriverArgs(void);
|
||||
|
||||
int InitSound();
|
||||
void WriteSound(int32 *Buffer, int Count);
|
||||
int KillSound(void);
|
||||
uint32 GetMaxSound(void);
|
||||
uint32 GetWriteSound(void);
|
||||
|
||||
void SilenceSound(int s); /* DOS and SDL */
|
||||
|
||||
int InitJoysticks(void);
|
||||
int KillJoysticks(void);
|
||||
uint32 *GetJSOr(void);
|
||||
|
||||
int InitVideo(FCEUGI *gi);
|
||||
int KillVideo(void);
|
||||
void BlitScreen(uint8 *XBuf);
|
||||
void LockConsole(void);
|
||||
void UnlockConsole(void);
|
||||
void ToggleFS(); /* SDL */
|
||||
|
||||
int LoadGame(const char *path);
|
||||
//int CloseGame(void);
|
||||
|
||||
void Giggles(int);
|
||||
void DoFun(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
|
@ -1,58 +1,58 @@
|
|||
#ifndef _aosdfjk02fmasf
|
||||
#define _aosdfjk02fmasf
|
||||
|
||||
#include "../common/configSys.h"
|
||||
|
||||
#define MAXBUTTCONFIG 4
|
||||
typedef struct {
|
||||
uint8 ButtType[MAXBUTTCONFIG];
|
||||
uint8 DeviceNum[MAXBUTTCONFIG];
|
||||
uint16 ButtonNum[MAXBUTTCONFIG];
|
||||
uint32 NumC;
|
||||
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
|
||||
} ButtConfig;
|
||||
|
||||
extern CFGSTRUCT InputConfig[];
|
||||
extern ARGPSTRUCT InputArgs[];
|
||||
extern int Hotkeys[];
|
||||
void ParseGIInput(FCEUGI *GI);
|
||||
void setHotKeys();
|
||||
int ButtonConfigBegin();
|
||||
void ButtonConfigEnd();
|
||||
void ConfigButton(char *text, ButtConfig *bc);
|
||||
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb);
|
||||
|
||||
#define BUTTC_KEYBOARD 0x00
|
||||
#define BUTTC_JOYSTICK 0x01
|
||||
#define BUTTC_MOUSE 0x02
|
||||
|
||||
#define FCFGD_GAMEPAD 1
|
||||
#define FCFGD_POWERPAD 2
|
||||
#define FCFGD_HYPERSHOT 3
|
||||
#define FCFGD_QUIZKING 4
|
||||
|
||||
#define SDL_FCEU_HOTKEY_EVENT SDL_USEREVENT
|
||||
|
||||
void InitInputInterface(void);
|
||||
void InputUserActiveFix(void);
|
||||
|
||||
extern bool replaceP2StartWithMicrophone;
|
||||
extern ButtConfig GamePadConfig[4][10];
|
||||
//extern ButtConfig powerpadsc[2][12];
|
||||
//extern ButtConfig QuizKingButtons[6];
|
||||
//extern ButtConfig FTrainerButtons[12];
|
||||
|
||||
void IncreaseEmulationSpeed(void);
|
||||
void DecreaseEmulationSpeed(void);
|
||||
|
||||
int DTestButtonJoy(ButtConfig *bc);
|
||||
|
||||
void FCEUD_UpdateInput(void);
|
||||
|
||||
void UpdateInput(Config *config);
|
||||
void InputCfg(const std::string &);
|
||||
|
||||
std::string GetUserText(const char* title);
|
||||
const char* ButtonName(const ButtConfig* bc, int which);
|
||||
|
||||
#endif
|
||||
#ifndef _aosdfjk02fmasf
|
||||
#define _aosdfjk02fmasf
|
||||
|
||||
#include "../common/configSys.h"
|
||||
|
||||
#define MAXBUTTCONFIG 4
|
||||
typedef struct {
|
||||
uint8 ButtType[MAXBUTTCONFIG];
|
||||
uint8 DeviceNum[MAXBUTTCONFIG];
|
||||
uint16 ButtonNum[MAXBUTTCONFIG];
|
||||
uint32 NumC;
|
||||
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
|
||||
} ButtConfig;
|
||||
|
||||
extern CFGSTRUCT InputConfig[];
|
||||
extern ARGPSTRUCT InputArgs[];
|
||||
extern int Hotkeys[];
|
||||
void ParseGIInput(FCEUGI *GI);
|
||||
void setHotKeys();
|
||||
int ButtonConfigBegin();
|
||||
void ButtonConfigEnd();
|
||||
void ConfigButton(char *text, ButtConfig *bc);
|
||||
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb);
|
||||
|
||||
#define BUTTC_KEYBOARD 0x00
|
||||
#define BUTTC_JOYSTICK 0x01
|
||||
#define BUTTC_MOUSE 0x02
|
||||
|
||||
#define FCFGD_GAMEPAD 1
|
||||
#define FCFGD_POWERPAD 2
|
||||
#define FCFGD_HYPERSHOT 3
|
||||
#define FCFGD_QUIZKING 4
|
||||
|
||||
#define SDL_FCEU_HOTKEY_EVENT SDL_USEREVENT
|
||||
|
||||
void InitInputInterface(void);
|
||||
void InputUserActiveFix(void);
|
||||
|
||||
extern bool replaceP2StartWithMicrophone;
|
||||
extern ButtConfig GamePadConfig[4][10];
|
||||
//extern ButtConfig powerpadsc[2][12];
|
||||
//extern ButtConfig QuizKingButtons[6];
|
||||
//extern ButtConfig FTrainerButtons[12];
|
||||
|
||||
void IncreaseEmulationSpeed(void);
|
||||
void DecreaseEmulationSpeed(void);
|
||||
|
||||
int DTestButtonJoy(ButtConfig *bc);
|
||||
|
||||
void FCEUD_UpdateInput(void);
|
||||
|
||||
void UpdateInput(Config *config);
|
||||
void InputCfg(const std::string &);
|
||||
|
||||
std::string GetUserText(const char* title);
|
||||
const char* ButtonName(const ButtConfig* bc, int which);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
#include <SDL.h>
|
||||
#define SDLK_A SDLK_a
|
||||
#define SDLK_B SDLK_b
|
||||
#define SDLK_C SDLK_c
|
||||
#define SDLK_D SDLK_d
|
||||
#define SDLK_E SDLK_e
|
||||
#define SDLK_F SDLK_f
|
||||
#define SDLK_G SDLK_g
|
||||
#define SDLK_H SDLK_h
|
||||
#define SDLK_I SDLK_i
|
||||
#define SDLK_J SDLK_j
|
||||
#define SDLK_K SDLK_k
|
||||
#define SDLK_L SDLK_l
|
||||
#define SDLK_M SDLK_m
|
||||
#define SDLK_N SDLK_n
|
||||
#define SDLK_O SDLK_o
|
||||
#define SDLK_P SDLK_p
|
||||
#define SDLK_Q SDLK_q
|
||||
#define SDLK_R SDLK_r
|
||||
#define SDLK_S SDLK_s
|
||||
#define SDLK_T SDLK_t
|
||||
#define SDLK_U SDLK_u
|
||||
#define SDLK_V SDLK_v
|
||||
#define SDLK_W SDLK_w
|
||||
#define SDLK_X SDLK_x
|
||||
#define SDLK_Y SDLK_y
|
||||
#define SDLK_Z SDLK_z
|
||||
#define SDLK_LEFTCONTROL SDLK_LCTRL
|
||||
#define SDLK_RIGHTCONTROL SDLK_RCTRL
|
||||
#define SDLK_LEFTALT SDLK_LALT
|
||||
#define SDLK_RIGHTALT SDLK_RALT
|
||||
#define SDLK_LEFTSHIFT SDLK_LSHIFT
|
||||
#define SDLK_RIGHTSHIFT SDLK_RSHIFT
|
||||
#define SDLK_CURSORDOWN SDLK_DOWN
|
||||
#define SDLK_CURSORUP SDLK_UP
|
||||
#define SDLK_CURSORLEFT SDLK_LEFT
|
||||
#define SDLK_CURSORRIGHT SDLK_RIGHT
|
||||
#define SDLK_ENTER SDLK_RETURN
|
||||
#define SDLK_EQUAL SDLK_EQUALS
|
||||
#define SDLK_APOSTROPHE SDLK_QUOTE
|
||||
#define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET
|
||||
#define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET
|
||||
#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */
|
||||
#define SDLK_GRAVE SDLK_BACKQUOTE
|
||||
#define MKK(k) SDLK_##k
|
||||
#if SDL_VERSION_ATLEAST(1, 3, 0)
|
||||
#define SDLK_LAST SDL_NUM_SCANCODES
|
||||
#endif
|
||||
#define MKK_COUNT (SDLK_LAST+1)
|
||||
#include <SDL.h>
|
||||
#define SDLK_A SDLK_a
|
||||
#define SDLK_B SDLK_b
|
||||
#define SDLK_C SDLK_c
|
||||
#define SDLK_D SDLK_d
|
||||
#define SDLK_E SDLK_e
|
||||
#define SDLK_F SDLK_f
|
||||
#define SDLK_G SDLK_g
|
||||
#define SDLK_H SDLK_h
|
||||
#define SDLK_I SDLK_i
|
||||
#define SDLK_J SDLK_j
|
||||
#define SDLK_K SDLK_k
|
||||
#define SDLK_L SDLK_l
|
||||
#define SDLK_M SDLK_m
|
||||
#define SDLK_N SDLK_n
|
||||
#define SDLK_O SDLK_o
|
||||
#define SDLK_P SDLK_p
|
||||
#define SDLK_Q SDLK_q
|
||||
#define SDLK_R SDLK_r
|
||||
#define SDLK_S SDLK_s
|
||||
#define SDLK_T SDLK_t
|
||||
#define SDLK_U SDLK_u
|
||||
#define SDLK_V SDLK_v
|
||||
#define SDLK_W SDLK_w
|
||||
#define SDLK_X SDLK_x
|
||||
#define SDLK_Y SDLK_y
|
||||
#define SDLK_Z SDLK_z
|
||||
#define SDLK_LEFTCONTROL SDLK_LCTRL
|
||||
#define SDLK_RIGHTCONTROL SDLK_RCTRL
|
||||
#define SDLK_LEFTALT SDLK_LALT
|
||||
#define SDLK_RIGHTALT SDLK_RALT
|
||||
#define SDLK_LEFTSHIFT SDLK_LSHIFT
|
||||
#define SDLK_RIGHTSHIFT SDLK_RSHIFT
|
||||
#define SDLK_CURSORDOWN SDLK_DOWN
|
||||
#define SDLK_CURSORUP SDLK_UP
|
||||
#define SDLK_CURSORLEFT SDLK_LEFT
|
||||
#define SDLK_CURSORRIGHT SDLK_RIGHT
|
||||
#define SDLK_ENTER SDLK_RETURN
|
||||
#define SDLK_EQUAL SDLK_EQUALS
|
||||
#define SDLK_APOSTROPHE SDLK_QUOTE
|
||||
#define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET
|
||||
#define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET
|
||||
#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */
|
||||
#define SDLK_GRAVE SDLK_BACKQUOTE
|
||||
#define MKK(k) SDLK_##k
|
||||
#if SDL_VERSION_ATLEAST(1, 3, 0)
|
||||
#define SDLK_LAST SDL_NUM_SCANCODES
|
||||
#endif
|
||||
#define MKK_COUNT (SDLK_LAST+1)
|
||||
|
|
|
@ -1,102 +1,102 @@
|
|||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __FCEU_SDL_MAIN_H
|
||||
#define __FCEU_SDL_MAIN_H
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../common/config.h"
|
||||
#include "../common/args.h"
|
||||
|
||||
extern int eoptions;
|
||||
#define EO_NO8LIM 1
|
||||
#define EO_SUBASE 2
|
||||
#define EO_CLIPSIDES 8
|
||||
#define EO_SNAPNAME 16
|
||||
#define EO_FOURSCORE 32
|
||||
#define EO_NOTHROTTLE 64
|
||||
#define EO_GAMEGENIE 128
|
||||
#define EO_PAL 256
|
||||
#define EO_LOWPASS 512
|
||||
#define EO_AUTOHIDE 1024
|
||||
|
||||
extern int NoWaiting;
|
||||
|
||||
extern int _sound;
|
||||
extern long soundrate;
|
||||
extern long soundbufsize;
|
||||
|
||||
int CLImain(int argc, char *argv[]);
|
||||
|
||||
// Device management defaults
|
||||
#define NUM_INPUT_DEVICES 3
|
||||
|
||||
// GamePad defaults
|
||||
#define GAMEPAD_NUM_DEVICES 4
|
||||
#define GAMEPAD_NUM_BUTTONS 10
|
||||
extern const char *GamePadNames[GAMEPAD_NUM_BUTTONS];
|
||||
extern const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES];
|
||||
extern const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS];
|
||||
|
||||
// PowerPad defaults
|
||||
#define POWERPAD_NUM_DEVICES 2
|
||||
#define POWERPAD_NUM_BUTTONS 12
|
||||
extern const char *PowerPadNames[POWERPAD_NUM_BUTTONS];
|
||||
extern const char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES];
|
||||
extern const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS];
|
||||
|
||||
// QuizKing defaults
|
||||
#define QUIZKING_NUM_BUTTONS 6
|
||||
extern const char *QuizKingNames[QUIZKING_NUM_BUTTONS];
|
||||
extern const char *DefaultQuizKingDevice;
|
||||
extern const int DefaultQuizKing[QUIZKING_NUM_BUTTONS];
|
||||
|
||||
// HyperShot defaults
|
||||
#define HYPERSHOT_NUM_BUTTONS 4
|
||||
extern const char *HyperShotNames[HYPERSHOT_NUM_BUTTONS];
|
||||
extern const char *DefaultHyperShotDevice;
|
||||
extern const int DefaultHyperShot[HYPERSHOT_NUM_BUTTONS];
|
||||
|
||||
// Mahjong defaults
|
||||
#define MAHJONG_NUM_BUTTONS 21
|
||||
extern const char *MahjongNames[MAHJONG_NUM_BUTTONS];
|
||||
extern const char *DefaultMahjongDevice;
|
||||
extern const int DefaultMahjong[MAHJONG_NUM_BUTTONS];
|
||||
|
||||
// TopRider defaults
|
||||
#define TOPRIDER_NUM_BUTTONS 8
|
||||
extern const char *TopRiderNames[TOPRIDER_NUM_BUTTONS];
|
||||
extern const char *DefaultTopRiderDevice;
|
||||
extern const int DefaultTopRider[TOPRIDER_NUM_BUTTONS];
|
||||
|
||||
// FTrainer defaults
|
||||
#define FTRAINER_NUM_BUTTONS 12
|
||||
extern const char *FTrainerNames[FTRAINER_NUM_BUTTONS];
|
||||
extern const char *DefaultFTrainerDevice;
|
||||
extern const int DefaultFTrainer[FTRAINER_NUM_BUTTONS];
|
||||
|
||||
// FamilyKeyBoard defaults
|
||||
#define FAMILYKEYBOARD_NUM_BUTTONS 0x48
|
||||
extern const char *FamilyKeyBoardNames[FAMILYKEYBOARD_NUM_BUTTONS];
|
||||
extern const char *DefaultFamilyKeyBoardDevice;
|
||||
extern const int DefaultFamilyKeyBoard[FAMILYKEYBOARD_NUM_BUTTONS];
|
||||
|
||||
#endif
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __FCEU_SDL_MAIN_H
|
||||
#define __FCEU_SDL_MAIN_H
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../common/config.h"
|
||||
#include "../common/args.h"
|
||||
|
||||
extern int eoptions;
|
||||
#define EO_NO8LIM 1
|
||||
#define EO_SUBASE 2
|
||||
#define EO_CLIPSIDES 8
|
||||
#define EO_SNAPNAME 16
|
||||
#define EO_FOURSCORE 32
|
||||
#define EO_NOTHROTTLE 64
|
||||
#define EO_GAMEGENIE 128
|
||||
#define EO_PAL 256
|
||||
#define EO_LOWPASS 512
|
||||
#define EO_AUTOHIDE 1024
|
||||
|
||||
extern int NoWaiting;
|
||||
|
||||
extern int _sound;
|
||||
extern long soundrate;
|
||||
extern long soundbufsize;
|
||||
|
||||
int CLImain(int argc, char *argv[]);
|
||||
|
||||
// Device management defaults
|
||||
#define NUM_INPUT_DEVICES 3
|
||||
|
||||
// GamePad defaults
|
||||
#define GAMEPAD_NUM_DEVICES 4
|
||||
#define GAMEPAD_NUM_BUTTONS 10
|
||||
extern const char *GamePadNames[GAMEPAD_NUM_BUTTONS];
|
||||
extern const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES];
|
||||
extern const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS];
|
||||
|
||||
// PowerPad defaults
|
||||
#define POWERPAD_NUM_DEVICES 2
|
||||
#define POWERPAD_NUM_BUTTONS 12
|
||||
extern const char *PowerPadNames[POWERPAD_NUM_BUTTONS];
|
||||
extern const char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES];
|
||||
extern const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS];
|
||||
|
||||
// QuizKing defaults
|
||||
#define QUIZKING_NUM_BUTTONS 6
|
||||
extern const char *QuizKingNames[QUIZKING_NUM_BUTTONS];
|
||||
extern const char *DefaultQuizKingDevice;
|
||||
extern const int DefaultQuizKing[QUIZKING_NUM_BUTTONS];
|
||||
|
||||
// HyperShot defaults
|
||||
#define HYPERSHOT_NUM_BUTTONS 4
|
||||
extern const char *HyperShotNames[HYPERSHOT_NUM_BUTTONS];
|
||||
extern const char *DefaultHyperShotDevice;
|
||||
extern const int DefaultHyperShot[HYPERSHOT_NUM_BUTTONS];
|
||||
|
||||
// Mahjong defaults
|
||||
#define MAHJONG_NUM_BUTTONS 21
|
||||
extern const char *MahjongNames[MAHJONG_NUM_BUTTONS];
|
||||
extern const char *DefaultMahjongDevice;
|
||||
extern const int DefaultMahjong[MAHJONG_NUM_BUTTONS];
|
||||
|
||||
// TopRider defaults
|
||||
#define TOPRIDER_NUM_BUTTONS 8
|
||||
extern const char *TopRiderNames[TOPRIDER_NUM_BUTTONS];
|
||||
extern const char *DefaultTopRiderDevice;
|
||||
extern const int DefaultTopRider[TOPRIDER_NUM_BUTTONS];
|
||||
|
||||
// FTrainer defaults
|
||||
#define FTRAINER_NUM_BUTTONS 12
|
||||
extern const char *FTrainerNames[FTRAINER_NUM_BUTTONS];
|
||||
extern const char *DefaultFTrainerDevice;
|
||||
extern const int DefaultFTrainer[FTRAINER_NUM_BUTTONS];
|
||||
|
||||
// FamilyKeyBoard defaults
|
||||
#define FAMILYKEYBOARD_NUM_BUTTONS 0x48
|
||||
extern const char *FamilyKeyBoardNames[FAMILYKEYBOARD_NUM_BUTTONS];
|
||||
extern const char *DefaultFamilyKeyBoardDevice;
|
||||
extern const int DefaultFamilyKeyBoard[FAMILYKEYBOARD_NUM_BUTTONS];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,134 +1,134 @@
|
|||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
|
||||
uint8 pixel_data[32 * 32 * 3 + 1];
|
||||
} fceu_playicon = {
|
||||
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\\\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\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"
|
||||
"\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\\"
|
||||
"\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"
|
||||
"\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"
|
||||
"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\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\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"
|
||||
"\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"
|
||||
"\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\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"
|
||||
"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\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"
|
||||
"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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\\\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"
|
||||
"\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\\"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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\\"
|
||||
"\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"
|
||||
"\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"
|
||||
"\\\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"
|
||||
"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\\\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"
|
||||
"\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"
|
||||
"\\\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\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\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\\\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\\\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\\\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\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"
|
||||
"\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"
|
||||
"\\\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"
|
||||
"\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(\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\373"
|
||||
"\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\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"
|
||||
"\\\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"
|
||||
"\\\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"
|
||||
"\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"
|
||||
"\\\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"
|
||||
"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\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"
|
||||
"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"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
||||
};
|
||||
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
|
||||
uint8 pixel_data[32 * 32 * 3 + 1];
|
||||
} fceu_playicon = {
|
||||
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\\\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\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"
|
||||
"\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\\"
|
||||
"\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"
|
||||
"\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"
|
||||
"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\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\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"
|
||||
"\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"
|
||||
"\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\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"
|
||||
"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\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"
|
||||
"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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\\\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"
|
||||
"\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\\"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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"
|
||||
"\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\\"
|
||||
"\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"
|
||||
"\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"
|
||||
"\\\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"
|
||||
"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\\\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"
|
||||
"\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"
|
||||
"\\\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\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\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\\\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\\\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\\\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\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"
|
||||
"\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"
|
||||
"\\\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"
|
||||
"\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(\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\373"
|
||||
"\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\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"
|
||||
"\\\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"
|
||||
"\\\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"
|
||||
"\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"
|
||||
"\\\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"
|
||||
"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\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"
|
||||
"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"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
||||
};
|
||||
|
||||
|
|
|
@ -1,124 +1,123 @@
|
|||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
* Copyright (C) 2002 Paul Kuliniewicz
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/// \file
|
||||
/// \brief Handles joystick input using the SDL.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "sdl.h"
|
||||
|
||||
#define MAX_JOYSTICKS 32
|
||||
static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL};
|
||||
|
||||
static int s_jinited = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Tests if the given button is active on the joystick.
|
||||
*/
|
||||
int
|
||||
DTestButtonJoy(ButtConfig *bc)
|
||||
{
|
||||
int x;
|
||||
|
||||
for(x = 0; x < bc->NumC; x++)
|
||||
{
|
||||
if(bc->ButtonNum[x] & 0x2000)
|
||||
{
|
||||
/* Hat "button" */
|
||||
if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]],
|
||||
((bc->ButtonNum[x] >> 8) & 0x1F)) &
|
||||
(bc->ButtonNum[x]&0xFF))
|
||||
return(1);
|
||||
|
||||
}
|
||||
else if(bc->ButtonNum[x] & 0x8000)
|
||||
{
|
||||
/* Axis "button" */
|
||||
int pos;
|
||||
pos = SDL_JoystickGetAxis(s_Joysticks[bc->DeviceNum[x]],
|
||||
bc->ButtonNum[x] & 16383);
|
||||
if ((bc->ButtonNum[x] & 0x4000) && pos <= -16383) {
|
||||
return(1);
|
||||
} else if (!(bc->ButtonNum[x] & 0x4000) && pos >= 16363) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
else if(SDL_JoystickGetButton(s_Joysticks[bc->DeviceNum[x]],
|
||||
bc->ButtonNum[x]))
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the SDL joystick subsystem.
|
||||
*/
|
||||
int
|
||||
KillJoysticks()
|
||||
{
|
||||
int n; /* joystick index */
|
||||
|
||||
if(!s_jinited) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
for(n = 0; n < MAX_JOYSTICKS; n++) {
|
||||
if (s_Joysticks[n] != 0) {
|
||||
SDL_JoystickClose(s_Joysticks[n]);
|
||||
}
|
||||
s_Joysticks[n]=0;
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the SDL joystick subsystem.
|
||||
*/
|
||||
int
|
||||
InitJoysticks()
|
||||
{
|
||||
int n; /* joystick index */
|
||||
int total;
|
||||
|
||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||
|
||||
total = SDL_NumJoysticks();
|
||||
if(total>MAX_JOYSTICKS) {
|
||||
total = MAX_JOYSTICKS;
|
||||
}
|
||||
|
||||
for(n = 0; n < total; n++) {
|
||||
/* Open the joystick under SDL. */
|
||||
s_Joysticks[n] = SDL_JoystickOpen(n);
|
||||
//printf("Could not open joystick %d: %s.\n",
|
||||
//joy[n] - 1, SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
|
||||
s_jinited = 1;
|
||||
return(1);
|
||||
}
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
* Copyright (C) 2002 Paul Kuliniewicz
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/// \file
|
||||
/// \brief Handles joystick input using the SDL.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "sdl.h"
|
||||
|
||||
#define MAX_JOYSTICKS 32
|
||||
static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL};
|
||||
|
||||
static int s_jinited = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Tests if the given button is active on the joystick.
|
||||
*/
|
||||
int
|
||||
DTestButtonJoy(ButtConfig *bc)
|
||||
{
|
||||
int x;
|
||||
|
||||
for(x = 0; x < bc->NumC; x++)
|
||||
{
|
||||
if(bc->ButtonNum[x] & 0x2000)
|
||||
{
|
||||
/* Hat "button" */
|
||||
if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]],
|
||||
((bc->ButtonNum[x] >> 8) & 0x1F)) &
|
||||
(bc->ButtonNum[x]&0xFF))
|
||||
return 1;
|
||||
}
|
||||
else if(bc->ButtonNum[x] & 0x8000)
|
||||
{
|
||||
/* Axis "button" */
|
||||
int pos;
|
||||
pos = SDL_JoystickGetAxis(s_Joysticks[bc->DeviceNum[x]],
|
||||
bc->ButtonNum[x] & 16383);
|
||||
if ((bc->ButtonNum[x] & 0x4000) && pos <= -16383) {
|
||||
return 1;
|
||||
} else if (!(bc->ButtonNum[x] & 0x4000) && pos >= 16363) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if(SDL_JoystickGetButton(s_Joysticks[bc->DeviceNum[x]],
|
||||
bc->ButtonNum[x]))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the SDL joystick subsystem.
|
||||
*/
|
||||
int
|
||||
KillJoysticks()
|
||||
{
|
||||
int n; /* joystick index */
|
||||
|
||||
if(!s_jinited) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(n = 0; n < MAX_JOYSTICKS; n++) {
|
||||
if (s_Joysticks[n] != 0) {
|
||||
SDL_JoystickClose(s_Joysticks[n]);
|
||||
}
|
||||
s_Joysticks[n]=0;
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the SDL joystick subsystem.
|
||||
*/
|
||||
int
|
||||
InitJoysticks()
|
||||
{
|
||||
int n; /* joystick index */
|
||||
int total;
|
||||
|
||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||
|
||||
total = SDL_NumJoysticks();
|
||||
if(total>MAX_JOYSTICKS) {
|
||||
total = MAX_JOYSTICKS;
|
||||
}
|
||||
|
||||
for(n = 0; n < total; n++) {
|
||||
/* Open the joystick under SDL. */
|
||||
s_Joysticks[n] = SDL_JoystickOpen(n);
|
||||
//printf("Could not open joystick %d: %s.\n",
|
||||
//joy[n] - 1, SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
|
||||
s_jinited = 1;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,223 +1,223 @@
|
|||
#include "sdl.h"
|
||||
#include <SDL_net.h>
|
||||
#include "sdl-netplay.h"
|
||||
|
||||
char *ServerHost;
|
||||
int magic;
|
||||
|
||||
static int LocalPortTCP=0xFCE;
|
||||
static int LocalPortUDP=0xFCE;
|
||||
static int RemotePortTCP=0xFCE;
|
||||
|
||||
static int RemotePortUDP; /* Not configurable, figured out during handshake. */
|
||||
|
||||
static TCPsocket Socket;
|
||||
static UDPsocket UDPSocket;
|
||||
static SDLNet_SocketSet set;
|
||||
|
||||
|
||||
static void en32(uint8 *buf, uint32 morp)
|
||||
{
|
||||
buf[0]=morp;
|
||||
buf[1]=morp>>8;
|
||||
buf[2]=morp>>16;
|
||||
buf[3]=morp>>24;
|
||||
}
|
||||
|
||||
static uint32 de32(uint8 *morp)
|
||||
{
|
||||
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int FCEUD_NetworkConnect(void)
|
||||
{
|
||||
IPaddress rip;
|
||||
|
||||
SDLNet_Init();
|
||||
int netplay =1;
|
||||
if(netplay==1) /* Be a server. */
|
||||
{
|
||||
TCPsocket tmp;
|
||||
Uint16 p=LocalPortUDP;
|
||||
|
||||
SDLNet_ResolveHost(&rip,NULL,LocalPortTCP);
|
||||
|
||||
UDPSocket=SDLNet_UDP_Open(p);
|
||||
|
||||
tmp=SDLNet_TCP_Open(&rip);
|
||||
Socket=SDLNet_TCP_Accept(tmp);
|
||||
|
||||
memcpy(&rip,SDLNet_TCP_GetPeerAddress(Socket),sizeof(IPaddress));
|
||||
{
|
||||
Uint32 buf[12];
|
||||
uint32 player=1;
|
||||
|
||||
magic=SDL_GetTicks();
|
||||
|
||||
SDLNet_Write32(buf,uport);
|
||||
SDLNet_Write32(buf+4,1);
|
||||
SDLNet_Write32(buf+8,magic);
|
||||
|
||||
SDLNet_TCP_Send(Socket, buf, 12);
|
||||
|
||||
/* Get the UDP port the client is waiting for data on. */
|
||||
SDLNet_TCP_Recv(Socket, buf, 2);
|
||||
RemotePortUDP=de32(buf);
|
||||
}
|
||||
}
|
||||
else /* Be a client */
|
||||
{
|
||||
SDLNet_ResolveHost(&rip,ServerHost,RemotePortTCP);
|
||||
Socket=SDLNet_TCP_Open(&rip);
|
||||
|
||||
{
|
||||
Uint16 p=LocalPortUDP;
|
||||
uint8 buf[12];
|
||||
|
||||
UDPSocket=SDLNet_UDP_Open(p);
|
||||
|
||||
/* Now, tell the server what local UDP port it should send to. */
|
||||
en32(buf,p);
|
||||
SDLNet_TCP_Send(Socket, buf, 4);
|
||||
|
||||
/* Get the UDP port from the server we should send data to. */
|
||||
SDLNet_TCP_Recv(Socket, buf, 12);
|
||||
RemotePortUDP=de32(buf);
|
||||
magic=de32(buf+8);
|
||||
}
|
||||
set=SDLNet_AllocSocketSet(1);
|
||||
SDLNet_TCP_AddSocket(set,Socket);
|
||||
SDLNet_UDP_AddSocket(set,UDPSocket);
|
||||
} // End client connect code.
|
||||
|
||||
rip.port=RemotePortUDP;
|
||||
SDLNet_UDP_Bind(UDPSocket, 0, &rip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int CheckUDP(uint8 *packet, int32 len, int32 alt)
|
||||
{
|
||||
uint32 crc;
|
||||
uint32 repcrc;
|
||||
|
||||
crc=FCEUI_CRC32(0,packet+4,len+8);
|
||||
repcrc=de32(packet);
|
||||
|
||||
if(crc!=repcrc) return(0); /* CRC32 mismatch, bad packet. */
|
||||
packet+=4;
|
||||
|
||||
if(de32(packet)!=magic) /* Magic number mismatch, bad or spoofed packet. */
|
||||
return(0);
|
||||
|
||||
packet+=4;
|
||||
if(alt)
|
||||
{
|
||||
if(de32(packet)<incounter) /* Time warped packet. */
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
if(de32(packet)!=incounter) /* Time warped packet. */
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Be careful where these MakeXXX() functions are used. */
|
||||
static uint8 *MakeUDP(uint8 *data, int32 len)
|
||||
{
|
||||
/* UDP packet data header is 12 bytes in length. */
|
||||
static uint8 buf[12+32]; // arbitrary 32.
|
||||
|
||||
en32(buf+4,magic);
|
||||
en32(buf+8,outcounter);
|
||||
memcpy(buf+12,data,len);
|
||||
en32(buf,FCEUI_CRC32(0,buf+4,8+len));
|
||||
return(buf);
|
||||
}
|
||||
|
||||
static uint8 *MakeTCP(uint8 *data, int32 len)
|
||||
{
|
||||
/* TCP packet data header is 4 bytes in length. */
|
||||
static uint8 buf[4+32]; // arbitrary 32.
|
||||
|
||||
en32(buf,outcounter);
|
||||
memcpy(buf+4,data,len);
|
||||
return(buf);
|
||||
}
|
||||
|
||||
#define UDPHEADSIZE 12
|
||||
#define TCPHEADSIZE 4
|
||||
|
||||
void FCEUD_NetworkClose(void)
|
||||
{
|
||||
SDLNet_Quit();
|
||||
}
|
||||
|
||||
/* 1 byte to server */
|
||||
int FCEUD_SendDataToServer(uint8 v,uint8 cmd)
|
||||
{
|
||||
UDPpacket upack;
|
||||
|
||||
upack.channel=0;
|
||||
upack.data=MakeUDP(data,1);
|
||||
upack.len=upack.maxlen=UDPHEADSIZE+1;
|
||||
upack.status=0;
|
||||
|
||||
SDLNet_UDP_Send(UDPSocket,0,&upack);
|
||||
|
||||
outcounter++;
|
||||
return(1);
|
||||
}
|
||||
|
||||
void FCEUD_SendDataToClients(uint8 *data)
|
||||
{
|
||||
UDPpacket upack;
|
||||
|
||||
SDLNet_TCP_Send(Socket,MakeTCP(data,5),TCPHEADSIZE+5);
|
||||
|
||||
upack.channel=0;
|
||||
upack.data=MakeUDP(data,5);
|
||||
upack.len=upack.maxlen=UDPHEADSIZE+5;
|
||||
upack.status=0;
|
||||
|
||||
SDLNet_UDP_Send(UDPSocket,0,&upack);
|
||||
|
||||
outcounter++;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int FCEUD_GetDataFromServer(uint8 *data)
|
||||
{
|
||||
uint8 buf[128];
|
||||
NoWaiting&=~2;
|
||||
|
||||
while(SDLNet_CheckSockets(set,1)==0)
|
||||
{
|
||||
// do something here.
|
||||
}
|
||||
if(SDLNet_SocketReady(Socket))
|
||||
{
|
||||
if(de32(buf)==incounter) /* New packet, keep. */
|
||||
{
|
||||
unsigned long beefie;
|
||||
memcpy(data,buf+TCPHEADSIZE,5);
|
||||
incounter++;
|
||||
|
||||
if(!ioctl(Socket,FIONREAD,&beefie))
|
||||
if(beefie)
|
||||
NoWaiting|=2;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
}
|
||||
if(SDLNet_SocketReady(UDPSocket)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#include "sdl.h"
|
||||
#include <SDL_net.h>
|
||||
#include "sdl-netplay.h"
|
||||
|
||||
char *ServerHost;
|
||||
int magic;
|
||||
|
||||
static int LocalPortTCP=0xFCE;
|
||||
static int LocalPortUDP=0xFCE;
|
||||
static int RemotePortTCP=0xFCE;
|
||||
|
||||
static int RemotePortUDP; /* Not configurable, figured out during handshake. */
|
||||
|
||||
static TCPsocket Socket;
|
||||
static UDPsocket UDPSocket;
|
||||
static SDLNet_SocketSet set;
|
||||
|
||||
|
||||
static void en32(uint8 *buf, uint32 morp)
|
||||
{
|
||||
buf[0]=morp;
|
||||
buf[1]=morp>>8;
|
||||
buf[2]=morp>>16;
|
||||
buf[3]=morp>>24;
|
||||
}
|
||||
|
||||
static uint32 de32(uint8 *morp)
|
||||
{
|
||||
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int FCEUD_NetworkConnect(void)
|
||||
{
|
||||
IPaddress rip;
|
||||
|
||||
SDLNet_Init();
|
||||
int netplay =1;
|
||||
if(netplay==1) /* Be a server. */
|
||||
{
|
||||
TCPsocket tmp;
|
||||
Uint16 p=LocalPortUDP;
|
||||
|
||||
SDLNet_ResolveHost(&rip,NULL,LocalPortTCP);
|
||||
|
||||
UDPSocket=SDLNet_UDP_Open(p);
|
||||
|
||||
tmp=SDLNet_TCP_Open(&rip);
|
||||
Socket=SDLNet_TCP_Accept(tmp);
|
||||
|
||||
memcpy(&rip,SDLNet_TCP_GetPeerAddress(Socket),sizeof(IPaddress));
|
||||
{
|
||||
Uint32 buf[12];
|
||||
uint32 player=1;
|
||||
|
||||
magic=SDL_GetTicks();
|
||||
|
||||
SDLNet_Write32(buf,uport);
|
||||
SDLNet_Write32(buf+4,1);
|
||||
SDLNet_Write32(buf+8,magic);
|
||||
|
||||
SDLNet_TCP_Send(Socket, buf, 12);
|
||||
|
||||
/* Get the UDP port the client is waiting for data on. */
|
||||
SDLNet_TCP_Recv(Socket, buf, 2);
|
||||
RemotePortUDP=de32(buf);
|
||||
}
|
||||
}
|
||||
else /* Be a client */
|
||||
{
|
||||
SDLNet_ResolveHost(&rip,ServerHost,RemotePortTCP);
|
||||
Socket=SDLNet_TCP_Open(&rip);
|
||||
|
||||
{
|
||||
Uint16 p=LocalPortUDP;
|
||||
uint8 buf[12];
|
||||
|
||||
UDPSocket=SDLNet_UDP_Open(p);
|
||||
|
||||
/* Now, tell the server what local UDP port it should send to. */
|
||||
en32(buf,p);
|
||||
SDLNet_TCP_Send(Socket, buf, 4);
|
||||
|
||||
/* Get the UDP port from the server we should send data to. */
|
||||
SDLNet_TCP_Recv(Socket, buf, 12);
|
||||
RemotePortUDP=de32(buf);
|
||||
magic=de32(buf+8);
|
||||
}
|
||||
set=SDLNet_AllocSocketSet(1);
|
||||
SDLNet_TCP_AddSocket(set,Socket);
|
||||
SDLNet_UDP_AddSocket(set,UDPSocket);
|
||||
} // End client connect code.
|
||||
|
||||
rip.port=RemotePortUDP;
|
||||
SDLNet_UDP_Bind(UDPSocket, 0, &rip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int CheckUDP(uint8 *packet, int32 len, int32 alt)
|
||||
{
|
||||
uint32 crc;
|
||||
uint32 repcrc;
|
||||
|
||||
crc=FCEUI_CRC32(0,packet+4,len+8);
|
||||
repcrc=de32(packet);
|
||||
|
||||
if(crc!=repcrc) return(0); /* CRC32 mismatch, bad packet. */
|
||||
packet+=4;
|
||||
|
||||
if(de32(packet)!=magic) /* Magic number mismatch, bad or spoofed packet. */
|
||||
return(0);
|
||||
|
||||
packet+=4;
|
||||
if(alt)
|
||||
{
|
||||
if(de32(packet)<incounter) /* Time warped packet. */
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
if(de32(packet)!=incounter) /* Time warped packet. */
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Be careful where these MakeXXX() functions are used. */
|
||||
static uint8 *MakeUDP(uint8 *data, int32 len)
|
||||
{
|
||||
/* UDP packet data header is 12 bytes in length. */
|
||||
static uint8 buf[12+32]; // arbitrary 32.
|
||||
|
||||
en32(buf+4,magic);
|
||||
en32(buf+8,outcounter);
|
||||
memcpy(buf+12,data,len);
|
||||
en32(buf,FCEUI_CRC32(0,buf+4,8+len));
|
||||
return(buf);
|
||||
}
|
||||
|
||||
static uint8 *MakeTCP(uint8 *data, int32 len)
|
||||
{
|
||||
/* TCP packet data header is 4 bytes in length. */
|
||||
static uint8 buf[4+32]; // arbitrary 32.
|
||||
|
||||
en32(buf,outcounter);
|
||||
memcpy(buf+4,data,len);
|
||||
return(buf);
|
||||
}
|
||||
|
||||
#define UDPHEADSIZE 12
|
||||
#define TCPHEADSIZE 4
|
||||
|
||||
void FCEUD_NetworkClose(void)
|
||||
{
|
||||
SDLNet_Quit();
|
||||
}
|
||||
|
||||
/* 1 byte to server */
|
||||
int FCEUD_SendDataToServer(uint8 v,uint8 cmd)
|
||||
{
|
||||
UDPpacket upack;
|
||||
|
||||
upack.channel=0;
|
||||
upack.data=MakeUDP(data,1);
|
||||
upack.len=upack.maxlen=UDPHEADSIZE+1;
|
||||
upack.status=0;
|
||||
|
||||
SDLNet_UDP_Send(UDPSocket,0,&upack);
|
||||
|
||||
outcounter++;
|
||||
return(1);
|
||||
}
|
||||
|
||||
void FCEUD_SendDataToClients(uint8 *data)
|
||||
{
|
||||
UDPpacket upack;
|
||||
|
||||
SDLNet_TCP_Send(Socket,MakeTCP(data,5),TCPHEADSIZE+5);
|
||||
|
||||
upack.channel=0;
|
||||
upack.data=MakeUDP(data,5);
|
||||
upack.len=upack.maxlen=UDPHEADSIZE+5;
|
||||
upack.status=0;
|
||||
|
||||
SDLNet_UDP_Send(UDPSocket,0,&upack);
|
||||
|
||||
outcounter++;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int FCEUD_GetDataFromServer(uint8 *data)
|
||||
{
|
||||
uint8 buf[128];
|
||||
NoWaiting&=~2;
|
||||
|
||||
while(SDLNet_CheckSockets(set,1)==0)
|
||||
{
|
||||
// do something here.
|
||||
}
|
||||
if(SDLNet_SocketReady(Socket))
|
||||
{
|
||||
if(de32(buf)==incounter) /* New packet, keep. */
|
||||
{
|
||||
unsigned long beefie;
|
||||
memcpy(data,buf+TCPHEADSIZE,5);
|
||||
incounter++;
|
||||
|
||||
if(!ioctl(Socket,FIONREAD,&beefie))
|
||||
if(beefie)
|
||||
NoWaiting|=2;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
}
|
||||
if(SDLNet_SocketReady(UDPSocket)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,293 +1,293 @@
|
|||
#define GL_GLEXT_LEGACY
|
||||
#ifdef APPLEOPENGL
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#include <OpenGL/glext.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sdl.h"
|
||||
#include "sdl-opengl.h"
|
||||
#include "../common/vidblit.h"
|
||||
#include "../../utils/memory.h"
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
|
||||
static GLuint textures[2]={0,0}; // Normal image, scanline overlay.
|
||||
|
||||
static int left,right,top,bottom; // right and bottom are not inclusive.
|
||||
static int scanlines;
|
||||
static void *HiBuffer;
|
||||
|
||||
typedef void APIENTRY (*glBindTexture_Func)(GLenum target,GLuint texture);
|
||||
typedef void APIENTRY (*glColorTableEXT_Func)(GLenum target,
|
||||
GLenum internalformat, GLsizei width, GLenum format, GLenum type,
|
||||
const GLvoid *table);
|
||||
typedef void APIENTRY (*glTexImage2D_Func)(GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid *pixels);
|
||||
typedef void APIENTRY (*glBegin_Func)(GLenum mode);
|
||||
typedef void APIENTRY (*glVertex2f_Func)(GLfloat x, GLfloat y);
|
||||
typedef void APIENTRY (*glTexCoord2f_Func)(GLfloat s, GLfloat t);
|
||||
typedef void APIENTRY (*glEnd_Func)(void);
|
||||
typedef void APIENTRY (*glEnable_Func)(GLenum cap);
|
||||
typedef void APIENTRY (*glBlendFunc_Func)(GLenum sfactor, GLenum dfactor);
|
||||
typedef const GLubyte* APIENTRY (*glGetString_Func)(GLenum name);
|
||||
typedef void APIENTRY (*glViewport_Func)(GLint x, GLint y,GLsizei width,
|
||||
GLsizei height);
|
||||
typedef void APIENTRY (*glGenTextures_Func)(GLsizei n, GLuint *textures);
|
||||
typedef void APIENTRY (*glDeleteTextures_Func)(GLsizei n,
|
||||
const GLuint *textures);
|
||||
typedef void APIENTRY (*glTexParameteri_Func)(GLenum target, GLenum pname,
|
||||
GLint param);
|
||||
typedef void APIENTRY (*glClearColor_Func)(GLclampf red, GLclampf green,
|
||||
GLclampf blue, GLclampf alpha);
|
||||
typedef void APIENTRY (*glLoadIdentity_Func)(void);
|
||||
typedef void APIENTRY (*glClear_Func)(GLbitfield mask);
|
||||
typedef void APIENTRY (*glMatrixMode_Func)(GLenum mode);
|
||||
typedef void APIENTRY (*glDisable_Func)(GLenum cap);
|
||||
glBindTexture_Func p_glBindTexture;
|
||||
glColorTableEXT_Func p_glColorTableEXT;
|
||||
glTexImage2D_Func p_glTexImage2D;
|
||||
glBegin_Func p_glBegin;
|
||||
glVertex2f_Func p_glVertex2f;
|
||||
glTexCoord2f_Func p_glTexCoord2f;
|
||||
glEnd_Func p_glEnd;
|
||||
glEnable_Func p_glEnable;
|
||||
glBlendFunc_Func p_glBlendFunc;
|
||||
glGetString_Func p_glGetString;
|
||||
glViewport_Func p_glViewport;
|
||||
glGenTextures_Func p_glGenTextures;
|
||||
glDeleteTextures_Func p_glDeleteTextures;
|
||||
glTexParameteri_Func p_glTexParameteri;
|
||||
glClearColor_Func p_glClearColor;
|
||||
glLoadIdentity_Func p_glLoadIdentity;
|
||||
glClear_Func p_glClear;
|
||||
glMatrixMode_Func p_glMatrixMode;
|
||||
glDisable_Func p_glDisable;
|
||||
|
||||
void
|
||||
SetOpenGLPalette(uint8 *data)
|
||||
{
|
||||
if(!HiBuffer) {
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
p_glColorTableEXT(GL_TEXTURE_2D, GL_RGB, 256,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
SetPaletteBlitToHigh((uint8*)data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BlitOpenGL(uint8 *buf)
|
||||
{
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
if(HiBuffer) {
|
||||
Blit8ToHigh(buf, (uint8*)HiBuffer, 256, 240, 256*4, 1, 1);
|
||||
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, HiBuffer);
|
||||
}
|
||||
else {
|
||||
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0,
|
||||
GL_COLOR_INDEX,GL_UNSIGNED_BYTE,buf);
|
||||
}
|
||||
|
||||
p_glBegin(GL_QUADS);
|
||||
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_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256);// Bottom right of picture.
|
||||
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_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_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
p_glEnd();
|
||||
|
||||
//glDisable(GL_BLEND);
|
||||
if(scanlines) {
|
||||
p_glEnable(GL_BLEND);
|
||||
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[1]);
|
||||
p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
|
||||
|
||||
p_glBegin(GL_QUADS);
|
||||
|
||||
p_glTexCoord2f(1.0f*left/256,
|
||||
1.0f*bottom/256); // Bottom left of our picture.
|
||||
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
|
||||
p_glTexCoord2f(1.0f*right/256,
|
||||
1.0f*bottom/256); // Bottom right of our picture.
|
||||
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_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_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
|
||||
p_glEnd();
|
||||
p_glDisable(GL_BLEND);
|
||||
}
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
void
|
||||
KillOpenGL(void)
|
||||
{
|
||||
if(textures[0]) {
|
||||
p_glDeleteTextures(2, &textures[0]);
|
||||
}
|
||||
textures[0]=0;
|
||||
if(HiBuffer) {
|
||||
free(HiBuffer);
|
||||
HiBuffer=0;
|
||||
}
|
||||
}
|
||||
/* Rectangle, left, right(not inclusive), top, bottom(not inclusive). */
|
||||
|
||||
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)
|
||||
{
|
||||
const char *extensions;
|
||||
|
||||
#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)
|
||||
|
||||
LFG(glBindTexture);
|
||||
LFGN(glColorTableEXT);
|
||||
LFG(glTexImage2D);
|
||||
LFG(glBegin);
|
||||
LFG(glVertex2f);
|
||||
LFG(glTexCoord2f);
|
||||
LFG(glEnd);
|
||||
LFG(glEnable);
|
||||
LFG(glBlendFunc);
|
||||
LFG(glGetString);
|
||||
LFG(glViewport);
|
||||
LFG(glGenTextures);
|
||||
LFG(glDeleteTextures);
|
||||
LFG(glTexParameteri);
|
||||
LFG(glClearColor);
|
||||
LFG(glLoadIdentity);
|
||||
LFG(glClear);
|
||||
LFG(glMatrixMode);
|
||||
LFG(glDisable);
|
||||
|
||||
left=l;
|
||||
right=r;
|
||||
top=t;
|
||||
bottom=b;
|
||||
|
||||
HiBuffer=0;
|
||||
|
||||
extensions=(const char*)p_glGetString(GL_EXTENSIONS);
|
||||
|
||||
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...
|
||||
FCEU_printf("Paletted texture extension not found. Using slower texture format...\n");
|
||||
HiBuffer=FCEU_malloc(4*256*256);
|
||||
memset(HiBuffer,0x00,4*256*256);
|
||||
#ifndef LSB_FIRST
|
||||
InitBlitToHigh(4,0xFF000000,0xFF0000,0xFF00,efx&2,0,0);
|
||||
#else
|
||||
InitBlitToHigh(4,0xFF,0xFF00,0xFF0000,efx&2,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(screen->flags & SDL_FULLSCREEN)
|
||||
{
|
||||
xscale=(double)screen->w / (double)(r-l);
|
||||
yscale=(double)screen->h / (double)(b-t);
|
||||
if(xscale<yscale) yscale = xscale;
|
||||
if(yscale<xscale) xscale = yscale;
|
||||
}
|
||||
|
||||
{
|
||||
int rw=(int)((r-l)*xscale);
|
||||
int rh=(int)((b-t)*yscale);
|
||||
int sx=(screen->w-rw)/2; // Start x
|
||||
int sy=(screen->h-rh)/2; // Start y
|
||||
|
||||
if(stretchx) { sx=0; rw=screen->w; }
|
||||
if(stretchy) { sy=0; rh=screen->h; }
|
||||
p_glViewport(sx, sy, rw, rh);
|
||||
}
|
||||
p_glGenTextures(2, &textures[0]);
|
||||
scanlines=0;
|
||||
|
||||
if(efx&1)
|
||||
{
|
||||
uint8 *buf;
|
||||
int x,y;
|
||||
|
||||
scanlines=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_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||
|
||||
buf=(uint8*)FCEU_dmalloc(256*(256*2)*4);
|
||||
|
||||
for(y=0;y<(256*2);y++)
|
||||
for(x=0;x<256;x++)
|
||||
{
|
||||
buf[y*256*4+x*4]=0;
|
||||
buf[y*256*4+x*4+1]=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+x]=(y&1)?0x00:0xFF;
|
||||
}
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, (scanlines==2)?256*4:512, 0,
|
||||
GL_RGBA,GL_UNSIGNED_BYTE,buf);
|
||||
FCEU_dfree(buf);
|
||||
}
|
||||
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_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_T,GL_CLAMP);
|
||||
p_glEnable(GL_TEXTURE_2D);
|
||||
p_glDisable(GL_DEPTH_TEST);
|
||||
p_glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
|
||||
p_glMatrixMode(GL_MODELVIEW);
|
||||
p_glLoadIdentity();
|
||||
|
||||
// In a double buffered setup with page flipping, be sure to clear both buffers.
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
SDL_GL_SwapBuffers();
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
return(1);
|
||||
}
|
||||
#define GL_GLEXT_LEGACY
|
||||
#ifdef APPLEOPENGL
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#include <OpenGL/glext.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sdl.h"
|
||||
#include "sdl-opengl.h"
|
||||
#include "../common/vidblit.h"
|
||||
#include "../../utils/memory.h"
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
|
||||
static GLuint textures[2]={0,0}; // Normal image, scanline overlay.
|
||||
|
||||
static int left,right,top,bottom; // right and bottom are not inclusive.
|
||||
static int scanlines;
|
||||
static void *HiBuffer;
|
||||
|
||||
typedef void APIENTRY (*glBindTexture_Func)(GLenum target,GLuint texture);
|
||||
typedef void APIENTRY (*glColorTableEXT_Func)(GLenum target,
|
||||
GLenum internalformat, GLsizei width, GLenum format, GLenum type,
|
||||
const GLvoid *table);
|
||||
typedef void APIENTRY (*glTexImage2D_Func)(GLenum target, GLint level,
|
||||
GLint internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
GLenum format, GLenum type,
|
||||
const GLvoid *pixels);
|
||||
typedef void APIENTRY (*glBegin_Func)(GLenum mode);
|
||||
typedef void APIENTRY (*glVertex2f_Func)(GLfloat x, GLfloat y);
|
||||
typedef void APIENTRY (*glTexCoord2f_Func)(GLfloat s, GLfloat t);
|
||||
typedef void APIENTRY (*glEnd_Func)(void);
|
||||
typedef void APIENTRY (*glEnable_Func)(GLenum cap);
|
||||
typedef void APIENTRY (*glBlendFunc_Func)(GLenum sfactor, GLenum dfactor);
|
||||
typedef const GLubyte* APIENTRY (*glGetString_Func)(GLenum name);
|
||||
typedef void APIENTRY (*glViewport_Func)(GLint x, GLint y,GLsizei width,
|
||||
GLsizei height);
|
||||
typedef void APIENTRY (*glGenTextures_Func)(GLsizei n, GLuint *textures);
|
||||
typedef void APIENTRY (*glDeleteTextures_Func)(GLsizei n,
|
||||
const GLuint *textures);
|
||||
typedef void APIENTRY (*glTexParameteri_Func)(GLenum target, GLenum pname,
|
||||
GLint param);
|
||||
typedef void APIENTRY (*glClearColor_Func)(GLclampf red, GLclampf green,
|
||||
GLclampf blue, GLclampf alpha);
|
||||
typedef void APIENTRY (*glLoadIdentity_Func)(void);
|
||||
typedef void APIENTRY (*glClear_Func)(GLbitfield mask);
|
||||
typedef void APIENTRY (*glMatrixMode_Func)(GLenum mode);
|
||||
typedef void APIENTRY (*glDisable_Func)(GLenum cap);
|
||||
glBindTexture_Func p_glBindTexture;
|
||||
glColorTableEXT_Func p_glColorTableEXT;
|
||||
glTexImage2D_Func p_glTexImage2D;
|
||||
glBegin_Func p_glBegin;
|
||||
glVertex2f_Func p_glVertex2f;
|
||||
glTexCoord2f_Func p_glTexCoord2f;
|
||||
glEnd_Func p_glEnd;
|
||||
glEnable_Func p_glEnable;
|
||||
glBlendFunc_Func p_glBlendFunc;
|
||||
glGetString_Func p_glGetString;
|
||||
glViewport_Func p_glViewport;
|
||||
glGenTextures_Func p_glGenTextures;
|
||||
glDeleteTextures_Func p_glDeleteTextures;
|
||||
glTexParameteri_Func p_glTexParameteri;
|
||||
glClearColor_Func p_glClearColor;
|
||||
glLoadIdentity_Func p_glLoadIdentity;
|
||||
glClear_Func p_glClear;
|
||||
glMatrixMode_Func p_glMatrixMode;
|
||||
glDisable_Func p_glDisable;
|
||||
|
||||
void
|
||||
SetOpenGLPalette(uint8 *data)
|
||||
{
|
||||
if(!HiBuffer) {
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
p_glColorTableEXT(GL_TEXTURE_2D, GL_RGB, 256,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
SetPaletteBlitToHigh((uint8*)data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BlitOpenGL(uint8 *buf)
|
||||
{
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
if(HiBuffer) {
|
||||
Blit8ToHigh(buf, (uint8*)HiBuffer, 256, 240, 256*4, 1, 1);
|
||||
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, HiBuffer);
|
||||
}
|
||||
else {
|
||||
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0,
|
||||
GL_COLOR_INDEX,GL_UNSIGNED_BYTE,buf);
|
||||
}
|
||||
|
||||
p_glBegin(GL_QUADS);
|
||||
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_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256);// Bottom right of picture.
|
||||
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_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_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
p_glEnd();
|
||||
|
||||
//glDisable(GL_BLEND);
|
||||
if(scanlines) {
|
||||
p_glEnable(GL_BLEND);
|
||||
|
||||
p_glBindTexture(GL_TEXTURE_2D, textures[1]);
|
||||
p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
|
||||
|
||||
p_glBegin(GL_QUADS);
|
||||
|
||||
p_glTexCoord2f(1.0f*left/256,
|
||||
1.0f*bottom/256); // Bottom left of our picture.
|
||||
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
|
||||
p_glTexCoord2f(1.0f*right/256,
|
||||
1.0f*bottom/256); // Bottom right of our picture.
|
||||
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_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_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
|
||||
p_glEnd();
|
||||
p_glDisable(GL_BLEND);
|
||||
}
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
void
|
||||
KillOpenGL(void)
|
||||
{
|
||||
if(textures[0]) {
|
||||
p_glDeleteTextures(2, &textures[0]);
|
||||
}
|
||||
textures[0]=0;
|
||||
if(HiBuffer) {
|
||||
free(HiBuffer);
|
||||
HiBuffer=0;
|
||||
}
|
||||
}
|
||||
/* Rectangle, left, right(not inclusive), top, bottom(not inclusive). */
|
||||
|
||||
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)
|
||||
{
|
||||
const char *extensions;
|
||||
|
||||
#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)
|
||||
|
||||
LFG(glBindTexture);
|
||||
LFGN(glColorTableEXT);
|
||||
LFG(glTexImage2D);
|
||||
LFG(glBegin);
|
||||
LFG(glVertex2f);
|
||||
LFG(glTexCoord2f);
|
||||
LFG(glEnd);
|
||||
LFG(glEnable);
|
||||
LFG(glBlendFunc);
|
||||
LFG(glGetString);
|
||||
LFG(glViewport);
|
||||
LFG(glGenTextures);
|
||||
LFG(glDeleteTextures);
|
||||
LFG(glTexParameteri);
|
||||
LFG(glClearColor);
|
||||
LFG(glLoadIdentity);
|
||||
LFG(glClear);
|
||||
LFG(glMatrixMode);
|
||||
LFG(glDisable);
|
||||
|
||||
left=l;
|
||||
right=r;
|
||||
top=t;
|
||||
bottom=b;
|
||||
|
||||
HiBuffer=0;
|
||||
|
||||
extensions=(const char*)p_glGetString(GL_EXTENSIONS);
|
||||
|
||||
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...
|
||||
FCEU_printf("Paletted texture extension not found. Using slower texture format...\n");
|
||||
HiBuffer=FCEU_malloc(4*256*256);
|
||||
memset(HiBuffer,0x00,4*256*256);
|
||||
#ifndef LSB_FIRST
|
||||
InitBlitToHigh(4,0xFF000000,0xFF0000,0xFF00,efx&2,0,0);
|
||||
#else
|
||||
InitBlitToHigh(4,0xFF,0xFF00,0xFF0000,efx&2,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(screen->flags & SDL_FULLSCREEN)
|
||||
{
|
||||
xscale=(double)screen->w / (double)(r-l);
|
||||
yscale=(double)screen->h / (double)(b-t);
|
||||
if(xscale<yscale) yscale = xscale;
|
||||
if(yscale<xscale) xscale = yscale;
|
||||
}
|
||||
|
||||
{
|
||||
int rw=(int)((r-l)*xscale);
|
||||
int rh=(int)((b-t)*yscale);
|
||||
int sx=(screen->w-rw)/2; // Start x
|
||||
int sy=(screen->h-rh)/2; // Start y
|
||||
|
||||
if(stretchx) { sx=0; rw=screen->w; }
|
||||
if(stretchy) { sy=0; rh=screen->h; }
|
||||
p_glViewport(sx, sy, rw, rh);
|
||||
}
|
||||
p_glGenTextures(2, &textures[0]);
|
||||
scanlines=0;
|
||||
|
||||
if(efx&1)
|
||||
{
|
||||
uint8 *buf;
|
||||
int x,y;
|
||||
|
||||
scanlines=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_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||
|
||||
buf=(uint8*)FCEU_dmalloc(256*(256*2)*4);
|
||||
|
||||
for(y=0;y<(256*2);y++)
|
||||
for(x=0;x<256;x++)
|
||||
{
|
||||
buf[y*256*4+x*4]=0;
|
||||
buf[y*256*4+x*4+1]=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+x]=(y&1)?0x00:0xFF;
|
||||
}
|
||||
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, (scanlines==2)?256*4:512, 0,
|
||||
GL_RGBA,GL_UNSIGNED_BYTE,buf);
|
||||
FCEU_dfree(buf);
|
||||
}
|
||||
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_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_T,GL_CLAMP);
|
||||
p_glEnable(GL_TEXTURE_2D);
|
||||
p_glDisable(GL_DEPTH_TEST);
|
||||
p_glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
|
||||
p_glMatrixMode(GL_MODELVIEW);
|
||||
p_glLoadIdentity();
|
||||
|
||||
// In a double buffered setup with page flipping, be sure to clear both buffers.
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
SDL_GL_SwapBuffers();
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
void SetOpenGLPalette(uint8 *data);
|
||||
void BlitOpenGL(uint8 *buf);
|
||||
void KillOpenGL(void);
|
||||
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);
|
||||
|
||||
void SetOpenGLPalette(uint8 *data);
|
||||
void BlitOpenGL(uint8 *buf);
|
||||
void KillOpenGL(void);
|
||||
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);
|
||||
|
||||
|
|
|
@ -1,274 +1,269 @@
|
|||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/// \file
|
||||
/// \brief Handles sound emulation using the SDL.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sdl.h"
|
||||
|
||||
#include "../common/configSys.h"
|
||||
#include "../../utils/memory.h"
|
||||
|
||||
extern Config *g_config;
|
||||
|
||||
static volatile int *s_Buffer = 0;
|
||||
static unsigned int s_BufferSize;
|
||||
static unsigned int s_BufferRead;
|
||||
static unsigned int s_BufferWrite;
|
||||
static volatile unsigned int s_BufferIn;
|
||||
|
||||
static int s_mute = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Callback from the SDL to get and play audio data.
|
||||
*/
|
||||
static void
|
||||
fillaudio(void *udata,
|
||||
uint8 *stream,
|
||||
int len)
|
||||
{
|
||||
int16 *tmps = (int16*)stream;
|
||||
len >>= 1;
|
||||
// debug code
|
||||
//printf("s_BufferIn: %i s_BufferWrite = %i s_BufferRead = %i s_BufferSize = %i\n",
|
||||
// s_BufferIn, s_BufferWrite, s_BufferRead, s_BufferSize);
|
||||
|
||||
while(len) {
|
||||
int16 sample = 0;
|
||||
if(s_BufferIn) {
|
||||
sample = s_Buffer[s_BufferRead];
|
||||
s_BufferRead = (s_BufferRead + 1) % s_BufferSize;
|
||||
s_BufferIn--;
|
||||
} else {
|
||||
sample = 0;
|
||||
}
|
||||
|
||||
*tmps = sample;
|
||||
tmps++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the audio subsystem.
|
||||
*/
|
||||
int
|
||||
InitSound()
|
||||
{
|
||||
int sound, soundrate, soundbufsize, soundvolume, soundtrianglevolume, soundsquare1volume, soundsquare2volume, soundnoisevolume, soundpcmvolume, soundq;
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
g_config->getOption("SDL.Sound", &sound);
|
||||
if(!sound) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&spec, 0, sizeof(spec));
|
||||
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
puts(SDL_GetError());
|
||||
KillSound();
|
||||
return(0);
|
||||
}
|
||||
char driverName[8];
|
||||
SDL_AudioDriverName(driverName, 8);
|
||||
|
||||
fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName);
|
||||
|
||||
// load configuration variables
|
||||
g_config->getOption("SDL.Sound.Rate", &soundrate);
|
||||
g_config->getOption("SDL.Sound.BufSize", &soundbufsize);
|
||||
g_config->getOption("SDL.Sound.Volume", &soundvolume);
|
||||
g_config->getOption("SDL.Sound.Quality", &soundq);
|
||||
g_config->getOption("SDL.Sound.TriangleVolume", &soundtrianglevolume);
|
||||
g_config->getOption("SDL.Sound.Square1Volume", &soundsquare1volume);
|
||||
g_config->getOption("SDL.Sound.Square2Volume", &soundsquare2volume);
|
||||
g_config->getOption("SDL.Sound.NoiseVolume", &soundnoisevolume);
|
||||
g_config->getOption("SDL.Sound.PCMVolume", &soundpcmvolume);
|
||||
|
||||
spec.freq = soundrate;
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.channels = 1;
|
||||
spec.samples = 512;
|
||||
spec.callback = fillaudio;
|
||||
spec.userdata = 0;
|
||||
|
||||
s_BufferSize = soundbufsize * soundrate / 1000;
|
||||
|
||||
// For safety, set a bare minimum:
|
||||
if (s_BufferSize < spec.samples * 2)
|
||||
s_BufferSize = spec.samples * 2;
|
||||
|
||||
s_Buffer = (int *)FCEU_dmalloc(sizeof(int) * s_BufferSize);
|
||||
if (!s_Buffer)
|
||||
return 0;
|
||||
s_BufferRead = s_BufferWrite = s_BufferIn = 0;
|
||||
|
||||
//printf("SDL Size: %d, Internal size: %d\n",spec.samples,s_BufferSize);
|
||||
|
||||
if(SDL_OpenAudio(&spec, 0) < 0) {
|
||||
puts(SDL_GetError());
|
||||
KillSound();
|
||||
return(0);
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
FCEUI_SetSoundQuality(soundq);
|
||||
FCEUI_Sound(soundrate);
|
||||
FCEUI_SetTriangleVolume(soundtrianglevolume);
|
||||
FCEUI_SetSquare1Volume(soundsquare1volume);
|
||||
FCEUI_SetSquare2Volume(soundsquare2volume);
|
||||
FCEUI_SetNoiseVolume(soundnoisevolume);
|
||||
FCEUI_SetPCMVolume(soundpcmvolume);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the size of the audio buffer.
|
||||
*/
|
||||
uint32
|
||||
GetMaxSound(void)
|
||||
{
|
||||
return(s_BufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of free space in the audio buffer.
|
||||
*/
|
||||
uint32
|
||||
GetWriteSound(void)
|
||||
{
|
||||
return(s_BufferSize - s_BufferIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a sound clip to the audio subsystem.
|
||||
*/
|
||||
void
|
||||
WriteSound(int32 *buf,
|
||||
int Count)
|
||||
{
|
||||
extern int EmulationPaused;
|
||||
if (EmulationPaused == 0)
|
||||
while(Count)
|
||||
{
|
||||
while(s_BufferIn == s_BufferSize)
|
||||
{
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
s_Buffer[s_BufferWrite] = *buf;
|
||||
Count--;
|
||||
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
|
||||
|
||||
SDL_LockAudio();
|
||||
s_BufferIn++;
|
||||
SDL_UnlockAudio();
|
||||
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause (1) or unpause (0) the audio output.
|
||||
*/
|
||||
void
|
||||
SilenceSound(int n)
|
||||
{
|
||||
SDL_PauseAudio(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down the audio subsystem.
|
||||
*/
|
||||
int
|
||||
KillSound(void)
|
||||
{
|
||||
FCEUI_Sound(0);
|
||||
SDL_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
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)
|
||||
{
|
||||
int soundvolume;
|
||||
g_config->getOption("SDL.SoundVolume", &soundvolume);
|
||||
|
||||
switch(n) {
|
||||
case -1:
|
||||
soundvolume -= 10;
|
||||
if(soundvolume < 0) {
|
||||
soundvolume = 0;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
soundvolume = 100;
|
||||
break;
|
||||
case 1:
|
||||
soundvolume += 10;
|
||||
if(soundvolume > 150) {
|
||||
soundvolume = 150;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
s_mute = 0;
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
g_config->setOption("SDL.SoundVolume", soundvolume);
|
||||
|
||||
FCEU_DispMessage("Sound volume %d.",0, soundvolume);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the sound on or off.
|
||||
*/
|
||||
void
|
||||
FCEUD_SoundToggle(void)
|
||||
{
|
||||
if(s_mute) {
|
||||
int soundvolume;
|
||||
g_config->getOption("SDL.SoundVolume", &soundvolume);
|
||||
|
||||
s_mute = 0;
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
FCEU_DispMessage("Sound mute off.",0);
|
||||
} else {
|
||||
s_mute = 1;
|
||||
FCEUI_SetSoundVolume(0);
|
||||
FCEU_DispMessage("Sound mute on.",0);
|
||||
}
|
||||
}
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/// \file
|
||||
/// \brief Handles sound emulation using the SDL.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sdl.h"
|
||||
|
||||
#include "../common/configSys.h"
|
||||
#include "../../utils/memory.h"
|
||||
|
||||
extern Config *g_config;
|
||||
|
||||
static volatile int *s_Buffer = 0;
|
||||
static unsigned int s_BufferSize;
|
||||
static unsigned int s_BufferRead;
|
||||
static unsigned int s_BufferWrite;
|
||||
static volatile unsigned int s_BufferIn;
|
||||
|
||||
static int s_mute = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Callback from the SDL to get and play audio data.
|
||||
*/
|
||||
static void
|
||||
fillaudio(void *udata,
|
||||
uint8 *stream,
|
||||
int len)
|
||||
{
|
||||
int16 *tmps = (int16*)stream;
|
||||
len >>= 1;
|
||||
while(len) {
|
||||
int16 sample = 0;
|
||||
if(s_BufferIn) {
|
||||
sample = s_Buffer[s_BufferRead];
|
||||
s_BufferRead = (s_BufferRead + 1) % s_BufferSize;
|
||||
s_BufferIn--;
|
||||
} else {
|
||||
sample = 0;
|
||||
}
|
||||
|
||||
*tmps = sample;
|
||||
tmps++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the audio subsystem.
|
||||
*/
|
||||
int
|
||||
InitSound()
|
||||
{
|
||||
int sound, soundrate, soundbufsize, soundvolume, soundtrianglevolume, soundsquare1volume, soundsquare2volume, soundnoisevolume, soundpcmvolume, soundq;
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
g_config->getOption("SDL.Sound", &sound);
|
||||
if(!sound) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&spec, 0, sizeof(spec));
|
||||
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
puts(SDL_GetError());
|
||||
KillSound();
|
||||
return 0;
|
||||
}
|
||||
char driverName[8];
|
||||
SDL_AudioDriverName(driverName, 8);
|
||||
|
||||
fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName);
|
||||
|
||||
// load configuration variables
|
||||
g_config->getOption("SDL.Sound.Rate", &soundrate);
|
||||
g_config->getOption("SDL.Sound.BufSize", &soundbufsize);
|
||||
g_config->getOption("SDL.Sound.Volume", &soundvolume);
|
||||
g_config->getOption("SDL.Sound.Quality", &soundq);
|
||||
g_config->getOption("SDL.Sound.TriangleVolume", &soundtrianglevolume);
|
||||
g_config->getOption("SDL.Sound.Square1Volume", &soundsquare1volume);
|
||||
g_config->getOption("SDL.Sound.Square2Volume", &soundsquare2volume);
|
||||
g_config->getOption("SDL.Sound.NoiseVolume", &soundnoisevolume);
|
||||
g_config->getOption("SDL.Sound.PCMVolume", &soundpcmvolume);
|
||||
|
||||
spec.freq = soundrate;
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.channels = 1;
|
||||
spec.samples = 512;
|
||||
spec.callback = fillaudio;
|
||||
spec.userdata = 0;
|
||||
|
||||
s_BufferSize = soundbufsize * soundrate / 1000;
|
||||
|
||||
// For safety, set a bare minimum:
|
||||
if (s_BufferSize < spec.samples * 2)
|
||||
s_BufferSize = spec.samples * 2;
|
||||
|
||||
s_Buffer = (int *)FCEU_dmalloc(sizeof(int) * s_BufferSize);
|
||||
if (!s_Buffer)
|
||||
return 0;
|
||||
s_BufferRead = s_BufferWrite = s_BufferIn = 0;
|
||||
|
||||
if(SDL_OpenAudio(&spec, 0) < 0)
|
||||
{
|
||||
puts(SDL_GetError());
|
||||
KillSound();
|
||||
return 0;
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
FCEUI_SetSoundQuality(soundq);
|
||||
FCEUI_Sound(soundrate);
|
||||
FCEUI_SetTriangleVolume(soundtrianglevolume);
|
||||
FCEUI_SetSquare1Volume(soundsquare1volume);
|
||||
FCEUI_SetSquare2Volume(soundsquare2volume);
|
||||
FCEUI_SetNoiseVolume(soundnoisevolume);
|
||||
FCEUI_SetPCMVolume(soundpcmvolume);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the size of the audio buffer.
|
||||
*/
|
||||
uint32
|
||||
GetMaxSound(void)
|
||||
{
|
||||
return(s_BufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of free space in the audio buffer.
|
||||
*/
|
||||
uint32
|
||||
GetWriteSound(void)
|
||||
{
|
||||
return(s_BufferSize - s_BufferIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a sound clip to the audio subsystem.
|
||||
*/
|
||||
void
|
||||
WriteSound(int32 *buf,
|
||||
int Count)
|
||||
{
|
||||
extern int EmulationPaused;
|
||||
if (EmulationPaused == 0)
|
||||
while(Count)
|
||||
{
|
||||
while(s_BufferIn == s_BufferSize)
|
||||
{
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
s_Buffer[s_BufferWrite] = *buf;
|
||||
Count--;
|
||||
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
|
||||
|
||||
SDL_LockAudio();
|
||||
s_BufferIn++;
|
||||
SDL_UnlockAudio();
|
||||
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause (1) or unpause (0) the audio output.
|
||||
*/
|
||||
void
|
||||
SilenceSound(int n)
|
||||
{
|
||||
SDL_PauseAudio(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down the audio subsystem.
|
||||
*/
|
||||
int
|
||||
KillSound(void)
|
||||
{
|
||||
FCEUI_Sound(0);
|
||||
SDL_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
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)
|
||||
{
|
||||
int soundvolume;
|
||||
g_config->getOption("SDL.SoundVolume", &soundvolume);
|
||||
|
||||
switch(n) {
|
||||
case -1:
|
||||
soundvolume -= 10;
|
||||
if(soundvolume < 0) {
|
||||
soundvolume = 0;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
soundvolume = 100;
|
||||
break;
|
||||
case 1:
|
||||
soundvolume += 10;
|
||||
if(soundvolume > 150) {
|
||||
soundvolume = 150;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
s_mute = 0;
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
g_config->setOption("SDL.SoundVolume", soundvolume);
|
||||
|
||||
FCEU_DispMessage("Sound volume %d.",0, soundvolume);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the sound on or off.
|
||||
*/
|
||||
void
|
||||
FCEUD_SoundToggle(void)
|
||||
{
|
||||
if(s_mute) {
|
||||
int soundvolume;
|
||||
g_config->getOption("SDL.SoundVolume", &soundvolume);
|
||||
|
||||
s_mute = 0;
|
||||
FCEUI_SetSoundVolume(soundvolume);
|
||||
FCEU_DispMessage("Sound mute off.",0);
|
||||
} else {
|
||||
s_mute = 1;
|
||||
FCEUI_SetSoundVolume(0);
|
||||
FCEU_DispMessage("Sound mute on.",0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,150 +1,150 @@
|
|||
/// \file
|
||||
/// \brief Handles emulation speed throttling using the SDL timing functions.
|
||||
|
||||
#include "sdl.h"
|
||||
#include "throttle.h"
|
||||
|
||||
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 Normal = 1.0; // 1x speed (around 60 fps on NTSC)
|
||||
|
||||
static uint64 Lasttime, Nexttime;
|
||||
static long double desired_frametime;
|
||||
static int InFrame;
|
||||
double g_fpsScale = Normal; // used by sdl.cpp
|
||||
bool MaxSpeed = false;
|
||||
|
||||
/* LOGMUL = exp(log(2) / 3)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This gives us three speed steps per order of magnitude.
|
||||
*
|
||||
*/
|
||||
#define LOGMUL 1.259921049894873
|
||||
|
||||
/**
|
||||
* Refreshes the FPS throttling variables.
|
||||
*/
|
||||
void
|
||||
RefreshThrottleFPS()
|
||||
{
|
||||
uint64 fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz
|
||||
desired_frametime = 16777216.0l / (fps * g_fpsScale);
|
||||
|
||||
Lasttime=0;
|
||||
Nexttime=0;
|
||||
InFrame=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform FPS speed throttling by delaying until the next time slot.
|
||||
*/
|
||||
int
|
||||
SpeedThrottle()
|
||||
{
|
||||
if(g_fpsScale >= 32)
|
||||
{
|
||||
return 0; /* Done waiting */
|
||||
}
|
||||
uint64 time_left;
|
||||
uint64 cur_time;
|
||||
|
||||
if(!Lasttime)
|
||||
Lasttime = SDL_GetTicks();
|
||||
|
||||
if(!InFrame)
|
||||
{
|
||||
InFrame = 1;
|
||||
Nexttime = Lasttime + desired_frametime * 1000;
|
||||
}
|
||||
|
||||
cur_time = SDL_GetTicks();
|
||||
if(cur_time >= Nexttime)
|
||||
time_left = 0;
|
||||
else
|
||||
time_left = Nexttime - cur_time;
|
||||
|
||||
if(time_left > 50)
|
||||
{
|
||||
time_left = 50;
|
||||
/* 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. */
|
||||
}
|
||||
else
|
||||
InFrame = 0;
|
||||
|
||||
/*fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n",
|
||||
time_left, InFrame?"no":"yes");*/
|
||||
SDL_Delay(time_left);
|
||||
|
||||
if(!InFrame)
|
||||
{
|
||||
Lasttime = SDL_GetTicks();
|
||||
return 0; /* Done waiting */
|
||||
}
|
||||
return 1; /* Must still wait some more */
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the emulation speed throttling to the next entry in the speed table.
|
||||
*/
|
||||
void IncreaseEmulationSpeed(void)
|
||||
{
|
||||
g_fpsScale *= LOGMUL;
|
||||
|
||||
if(g_fpsScale > Fastest) g_fpsScale = Fastest;
|
||||
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the emulation speed throttling to the previous entry in the speed table.
|
||||
*/
|
||||
void DecreaseEmulationSpeed(void)
|
||||
{
|
||||
g_fpsScale /= LOGMUL;
|
||||
if(g_fpsScale < Slowest)
|
||||
g_fpsScale = Slowest;
|
||||
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the emulation speed throttling to a specific value.
|
||||
*/
|
||||
void
|
||||
FCEUD_SetEmulationSpeed(int cmd)
|
||||
{
|
||||
MaxSpeed = false;
|
||||
|
||||
switch(cmd) {
|
||||
case EMUSPEED_SLOWEST:
|
||||
g_fpsScale = Slowest;
|
||||
break;
|
||||
case EMUSPEED_SLOWER:
|
||||
DecreaseEmulationSpeed();
|
||||
break;
|
||||
case EMUSPEED_NORMAL:
|
||||
g_fpsScale = Normal;
|
||||
break;
|
||||
case EMUSPEED_FASTER:
|
||||
IncreaseEmulationSpeed();
|
||||
break;
|
||||
case EMUSPEED_FASTEST:
|
||||
g_fpsScale = Fastest;
|
||||
MaxSpeed = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
|
||||
}
|
||||
/// \file
|
||||
/// \brief Handles emulation speed throttling using the SDL timing functions.
|
||||
|
||||
#include "sdl.h"
|
||||
#include "throttle.h"
|
||||
|
||||
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 Normal = 1.0; // 1x speed (around 60 fps on NTSC)
|
||||
|
||||
static uint64 Lasttime, Nexttime;
|
||||
static long double desired_frametime;
|
||||
static int InFrame;
|
||||
double g_fpsScale = Normal; // used by sdl.cpp
|
||||
bool MaxSpeed = false;
|
||||
|
||||
/* LOGMUL = exp(log(2) / 3)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This gives us three speed steps per order of magnitude.
|
||||
*
|
||||
*/
|
||||
#define LOGMUL 1.259921049894873
|
||||
|
||||
/**
|
||||
* Refreshes the FPS throttling variables.
|
||||
*/
|
||||
void
|
||||
RefreshThrottleFPS()
|
||||
{
|
||||
uint64 fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz
|
||||
desired_frametime = 16777216.0l / (fps * g_fpsScale);
|
||||
|
||||
Lasttime=0;
|
||||
Nexttime=0;
|
||||
InFrame=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform FPS speed throttling by delaying until the next time slot.
|
||||
*/
|
||||
int
|
||||
SpeedThrottle()
|
||||
{
|
||||
if(g_fpsScale >= 32)
|
||||
{
|
||||
return 0; /* Done waiting */
|
||||
}
|
||||
uint64 time_left;
|
||||
uint64 cur_time;
|
||||
|
||||
if(!Lasttime)
|
||||
Lasttime = SDL_GetTicks();
|
||||
|
||||
if(!InFrame)
|
||||
{
|
||||
InFrame = 1;
|
||||
Nexttime = Lasttime + desired_frametime * 1000;
|
||||
}
|
||||
|
||||
cur_time = SDL_GetTicks();
|
||||
if(cur_time >= Nexttime)
|
||||
time_left = 0;
|
||||
else
|
||||
time_left = Nexttime - cur_time;
|
||||
|
||||
if(time_left > 50)
|
||||
{
|
||||
time_left = 50;
|
||||
/* 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. */
|
||||
}
|
||||
else
|
||||
InFrame = 0;
|
||||
|
||||
/*fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n",
|
||||
time_left, InFrame?"no":"yes");*/
|
||||
SDL_Delay(time_left);
|
||||
|
||||
if(!InFrame)
|
||||
{
|
||||
Lasttime = SDL_GetTicks();
|
||||
return 0; /* Done waiting */
|
||||
}
|
||||
return 1; /* Must still wait some more */
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the emulation speed throttling to the next entry in the speed table.
|
||||
*/
|
||||
void IncreaseEmulationSpeed(void)
|
||||
{
|
||||
g_fpsScale *= LOGMUL;
|
||||
|
||||
if(g_fpsScale > Fastest) g_fpsScale = Fastest;
|
||||
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the emulation speed throttling to the previous entry in the speed table.
|
||||
*/
|
||||
void DecreaseEmulationSpeed(void)
|
||||
{
|
||||
g_fpsScale /= LOGMUL;
|
||||
if(g_fpsScale < Slowest)
|
||||
g_fpsScale = Slowest;
|
||||
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the emulation speed throttling to a specific value.
|
||||
*/
|
||||
void
|
||||
FCEUD_SetEmulationSpeed(int cmd)
|
||||
{
|
||||
MaxSpeed = false;
|
||||
|
||||
switch(cmd) {
|
||||
case EMUSPEED_SLOWEST:
|
||||
g_fpsScale = Slowest;
|
||||
break;
|
||||
case EMUSPEED_SLOWER:
|
||||
DecreaseEmulationSpeed();
|
||||
break;
|
||||
case EMUSPEED_NORMAL:
|
||||
g_fpsScale = Normal;
|
||||
break;
|
||||
case EMUSPEED_FASTER:
|
||||
IncreaseEmulationSpeed();
|
||||
break;
|
||||
case EMUSPEED_FASTEST:
|
||||
g_fpsScale = Fastest;
|
||||
MaxSpeed = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshThrottleFPS();
|
||||
|
||||
FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
#ifndef __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 FCEUI_AviDisableMovieMessages();
|
||||
static SDL_Surface *s_screen;
|
||||
|
@ -8,5 +8,5 @@ bool FCEUI_AviEnableHUDrecording();
|
|||
void FCEUI_SetAviEnableHUDrecording(bool enable);
|
||||
bool FCEUI_AviDisableMovieMessages();
|
||||
void FCEUI_SetAviDisableMovieMessages(bool disable);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,16 @@
|
|||
#ifndef __FCEU_SDL_H
|
||||
#define __FCEU_SDL_H
|
||||
|
||||
#include <SDL.h>
|
||||
#include "main.h"
|
||||
#include "dface.h"
|
||||
#include "input.h"
|
||||
|
||||
static void DoFun(int frameskip);
|
||||
static int isloaded = 0;
|
||||
extern int noGui;
|
||||
|
||||
int LoadGame(const char *path);
|
||||
int CloseGame(void);
|
||||
|
||||
#endif
|
||||
#ifndef __FCEU_SDL_H
|
||||
#define __FCEU_SDL_H
|
||||
|
||||
#include <SDL.h>
|
||||
#include "main.h"
|
||||
#include "dface.h"
|
||||
#include "input.h"
|
||||
|
||||
static void DoFun(int frameskip);
|
||||
static int isloaded = 0;
|
||||
extern int noGui;
|
||||
|
||||
int LoadGame(const char *path);
|
||||
int CloseGame(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
void RefreshThrottleFPS(void);
|
||||
int SpeedThrottle(void);
|
||||
void RefreshThrottleFPS(void);
|
||||
int SpeedThrottle(void);
|
||||
|
|
|
@ -1,357 +1,359 @@
|
|||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//todo - ensure that #ifdef WIN32 makes sense
|
||||
//consider changing this to use sdl net stuff?
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "main.h"
|
||||
#include "dface.h"
|
||||
#include "unix-netplay.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "../../fceu.h"
|
||||
#include "../../utils/md5.h"
|
||||
#include "../../utils/memory.h"
|
||||
|
||||
#include <string>
|
||||
#include "../common/configSys.h"
|
||||
|
||||
extern Config *g_config;
|
||||
|
||||
#ifndef socklen_t
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
#ifndef SOL_TCP
|
||||
#define SOL_TCP IPPROTO_TCP
|
||||
#endif
|
||||
|
||||
int FCEUDnetplay=0;
|
||||
|
||||
static int s_Socket = -1;
|
||||
|
||||
static void
|
||||
en32(uint8 *buf,
|
||||
uint32 morp)
|
||||
{
|
||||
buf[0] = morp;
|
||||
buf[1] = morp >> 8;
|
||||
buf[2] = morp >> 16;
|
||||
buf[3] = morp >> 24;
|
||||
}
|
||||
|
||||
/*
|
||||
static uint32 de32(uint8 *morp)
|
||||
{
|
||||
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
|
||||
}
|
||||
*/
|
||||
|
||||
int
|
||||
FCEUD_NetworkConnect(void)
|
||||
{
|
||||
struct sockaddr_in sockin;
|
||||
struct hostent *phostentb;
|
||||
unsigned long hadr;
|
||||
int TSocket, tcpopt, error;
|
||||
int netdivisor;
|
||||
|
||||
// get any required configuration variables
|
||||
int port, localPlayers;
|
||||
std::string server, username, password, key;
|
||||
g_config->getOption("SDL.NetworkIP", &server);
|
||||
g_config->getOption("SDL.NetworkUsername", &username);
|
||||
g_config->getOption("SDL.NetworkPassword", &password);
|
||||
g_config->getOption("SDL.NetworkGameKey", &key);
|
||||
g_config->getOption("SDL.NetworkPort", &port);
|
||||
g_config->getOption("SDL.NetworkPlayers", &localPlayers);
|
||||
|
||||
|
||||
g_config->setOption("SDL.NetworkIP", "");
|
||||
g_config->setOption("SDL.NetworkPassword", "");
|
||||
g_config->setOption("SDL.NetworkGameKey", "");
|
||||
|
||||
|
||||
|
||||
// only initialize if remote server is specified
|
||||
if(!server.size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(TSocket < 0) {
|
||||
char* s = "Error creating stream socket.";
|
||||
puts(s);
|
||||
FCEU_DispMessage(s,0);
|
||||
FCEUD_NetworkClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// try to setup TCP_NODELAY to avoid network jitters
|
||||
tcpopt = 1;
|
||||
#ifdef BEOS
|
||||
error = setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int));
|
||||
#elif WIN32
|
||||
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY,
|
||||
(char*)&tcpopt, sizeof(int));
|
||||
#else
|
||||
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int));
|
||||
#endif
|
||||
if(error) {
|
||||
puts("Nodelay fail");
|
||||
}
|
||||
|
||||
memset(&sockin, 0, sizeof(sockin));
|
||||
sockin.sin_family = AF_INET;
|
||||
hadr = inet_addr(server.c_str());
|
||||
if(hadr != INADDR_NONE) {
|
||||
sockin.sin_addr.s_addr = hadr;
|
||||
} else {
|
||||
puts("*** Looking up host name...");
|
||||
phostentb = gethostbyname(server.c_str());
|
||||
if(!phostentb) {
|
||||
puts("Error getting host network information.");
|
||||
FCEU_DispMessage("Error getting host info",0);
|
||||
close(TSocket);
|
||||
FCEUD_NetworkClose();
|
||||
return(0);
|
||||
}
|
||||
memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length);
|
||||
}
|
||||
|
||||
sockin.sin_port = htons(port);
|
||||
puts("*** Connecting to remote host...");
|
||||
error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin));
|
||||
if(error < 0) {
|
||||
puts("Error connecting to remote host.");
|
||||
FCEU_DispMessage("Error connecting to server",0);
|
||||
close(TSocket);
|
||||
FCEUD_NetworkClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
s_Socket = TSocket;
|
||||
|
||||
puts("*** Sending initialization data to server...");
|
||||
uint8 *sendbuf;
|
||||
uint8 buf[5];
|
||||
uint32 sblen;
|
||||
|
||||
sblen = 4 + 16 + 16 + 64 + 1 + username.size();
|
||||
sendbuf = (uint8 *)FCEU_dmalloc(sblen);
|
||||
memset(sendbuf, 0, sblen);
|
||||
|
||||
// XXX soules - should use htons instead of en32() from above!
|
||||
//uint32 data = htons(sblen - 4);
|
||||
//memcpy(sendbuf, &data, sizeof(data));
|
||||
en32(sendbuf, sblen - 4);
|
||||
|
||||
if(key.size()) {
|
||||
struct md5_context md5;
|
||||
uint8 md5out[16];
|
||||
|
||||
md5_starts(&md5);
|
||||
md5_update(&md5, (uint8*)&GameInfo->MD5.data, 16);
|
||||
md5_update(&md5, (uint8 *)key.c_str(), key.size());
|
||||
md5_finish(&md5, md5out);
|
||||
memcpy(sendbuf + 4, md5out, 16);
|
||||
} else {
|
||||
memcpy(sendbuf + 4, (uint8*)&GameInfo->MD5.data, 16);
|
||||
}
|
||||
|
||||
if(password.size()) {
|
||||
struct md5_context md5;
|
||||
uint8 md5out[16];
|
||||
|
||||
md5_starts(&md5);
|
||||
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;
|
||||
|
||||
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
|
||||
send(s_Socket, sendbuf, sblen, 0);
|
||||
#endif
|
||||
FCEU_dfree(sendbuf);
|
||||
|
||||
#ifdef WIN32
|
||||
recv(s_Socket, (char*)buf, 1, 0);
|
||||
#else
|
||||
recv(s_Socket, buf, 1, MSG_WAITALL);
|
||||
#endif
|
||||
netdivisor = buf[0];
|
||||
|
||||
puts("*** Connection established.");
|
||||
FCEU_DispMessage("Connection established.",0);
|
||||
|
||||
FCEUDnetplay = 1;
|
||||
FCEUI_NetplayStart(localPlayers, netdivisor);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FCEUD_SendData(void *data,
|
||||
uint32 len)
|
||||
{
|
||||
int check = 0, error = 0;
|
||||
#ifndef WIN32
|
||||
error = ioctl(fileno(stdin), FIONREAD, &check);
|
||||
#endif
|
||||
if(!error && check) {
|
||||
char buf[1024];
|
||||
char *f;
|
||||
fgets(buf, 1024, stdin);
|
||||
if((f=strrchr(buf,'\n'))) {
|
||||
*f = 0;
|
||||
}
|
||||
FCEUI_NetplayText((uint8 *)buf);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
send(s_Socket, (char*)data, len ,0);
|
||||
#else
|
||||
send(s_Socket, data, len ,0);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
FCEUD_RecvData(void *data,
|
||||
uint32 len)
|
||||
{
|
||||
int size;
|
||||
NoWaiting &= ~2;
|
||||
|
||||
for(;;) {
|
||||
fd_set funfun;
|
||||
struct timeval popeye;
|
||||
|
||||
popeye.tv_sec=0;
|
||||
popeye.tv_usec=100000;
|
||||
|
||||
FD_ZERO(&funfun);
|
||||
FD_SET(s_Socket, &funfun);
|
||||
|
||||
switch(select(s_Socket + 1,&funfun,0,0,&popeye)) {
|
||||
case 0: continue;
|
||||
case -1:return(0);
|
||||
}
|
||||
|
||||
if(FD_ISSET(s_Socket,&funfun)) {
|
||||
#ifdef WIN32
|
||||
size = recv(s_Socket, (char*)data, len, 0);
|
||||
#else
|
||||
size = recv(s_Socket, data, len, MSG_WAITALL);
|
||||
#endif
|
||||
|
||||
if(size == len) {
|
||||
//unsigned long beefie;
|
||||
|
||||
FD_ZERO(&funfun);
|
||||
FD_SET(s_Socket, &funfun);
|
||||
|
||||
popeye.tv_sec = popeye.tv_usec = 0;
|
||||
if(select(s_Socket + 1, &funfun, 0, 0, &popeye) == 1)
|
||||
//if(!ioctl(s_Socket,FIONREAD,&beefie))
|
||||
// if(beefie)
|
||||
{
|
||||
NoWaiting|=2;
|
||||
//puts("Yaya");
|
||||
}
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
FCEUD_NetworkClose(void)
|
||||
{
|
||||
if(s_Socket > 0) {
|
||||
#ifdef BEOS
|
||||
closesocket(s_Socket);
|
||||
#else
|
||||
close(s_Socket);
|
||||
#endif
|
||||
}
|
||||
s_Socket = -1;
|
||||
|
||||
if(FCEUDnetplay) {
|
||||
FCEUI_NetplayStop();
|
||||
}
|
||||
FCEUDnetplay = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FCEUD_NetplayText(uint8 *text)
|
||||
{
|
||||
char *tot = (char *)FCEU_dmalloc(strlen((const char *)text) + 1);
|
||||
char *tmp;
|
||||
if (!tot)
|
||||
return;
|
||||
strcpy(tot, (const char *)text);
|
||||
tmp = tot;
|
||||
|
||||
while(*tmp) {
|
||||
if(*tmp < 0x20) {
|
||||
*tmp = ' ';
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
puts(tot);
|
||||
FCEU_dfree(tot);
|
||||
}
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//todo - ensure that #ifdef WIN32 makes sense
|
||||
//consider changing this to use sdl net stuff?
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "main.h"
|
||||
#include "dface.h"
|
||||
#include "unix-netplay.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "../../fceu.h"
|
||||
#include "../../utils/md5.h"
|
||||
#include "../../utils/memory.h"
|
||||
|
||||
#include <string>
|
||||
#include "../common/configSys.h"
|
||||
|
||||
extern Config *g_config;
|
||||
|
||||
#ifndef socklen_t
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
#ifndef SOL_TCP
|
||||
#define SOL_TCP IPPROTO_TCP
|
||||
#endif
|
||||
|
||||
int FCEUDnetplay=0;
|
||||
|
||||
static int s_Socket = -1;
|
||||
|
||||
static void
|
||||
en32(uint8 *buf,
|
||||
uint32 morp)
|
||||
{
|
||||
buf[0] = morp;
|
||||
buf[1] = morp >> 8;
|
||||
buf[2] = morp >> 16;
|
||||
buf[3] = morp >> 24;
|
||||
}
|
||||
|
||||
/*
|
||||
static uint32 de32(uint8 *morp)
|
||||
{
|
||||
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
|
||||
}
|
||||
*/
|
||||
|
||||
int
|
||||
FCEUD_NetworkConnect(void)
|
||||
{
|
||||
struct sockaddr_in sockin;
|
||||
struct hostent *phostentb;
|
||||
unsigned long hadr;
|
||||
int TSocket, tcpopt, error;
|
||||
int netdivisor;
|
||||
|
||||
// get any required configuration variables
|
||||
int port, localPlayers;
|
||||
std::string server, username, password, key;
|
||||
g_config->getOption("SDL.NetworkIP", &server);
|
||||
g_config->getOption("SDL.NetworkUsername", &username);
|
||||
g_config->getOption("SDL.NetworkPassword", &password);
|
||||
g_config->getOption("SDL.NetworkGameKey", &key);
|
||||
g_config->getOption("SDL.NetworkPort", &port);
|
||||
g_config->getOption("SDL.NetworkPlayers", &localPlayers);
|
||||
|
||||
|
||||
g_config->setOption("SDL.NetworkIP", "");
|
||||
g_config->setOption("SDL.NetworkPassword", "");
|
||||
g_config->setOption("SDL.NetworkGameKey", "");
|
||||
|
||||
|
||||
|
||||
// only initialize if remote server is specified
|
||||
if(!server.size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(TSocket < 0) {
|
||||
char* s = "Error creating stream socket.";
|
||||
puts(s);
|
||||
FCEU_DispMessage(s,0);
|
||||
FCEUD_NetworkClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// try to setup TCP_NODELAY to avoid network jitters
|
||||
tcpopt = 1;
|
||||
#ifdef BEOS
|
||||
error = setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int));
|
||||
#elif WIN32
|
||||
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY,
|
||||
(char*)&tcpopt, sizeof(int));
|
||||
#else
|
||||
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int));
|
||||
#endif
|
||||
if(error) {
|
||||
puts("Nodelay fail");
|
||||
}
|
||||
|
||||
memset(&sockin, 0, sizeof(sockin));
|
||||
sockin.sin_family = AF_INET;
|
||||
hadr = inet_addr(server.c_str());
|
||||
if(hadr != INADDR_NONE) {
|
||||
sockin.sin_addr.s_addr = hadr;
|
||||
} else {
|
||||
puts("*** Looking up host name...");
|
||||
phostentb = gethostbyname(server.c_str());
|
||||
if(!phostentb) {
|
||||
puts("Error getting host network information.");
|
||||
FCEU_DispMessage("Error getting host info",0);
|
||||
close(TSocket);
|
||||
FCEUD_NetworkClose();
|
||||
return(0);
|
||||
}
|
||||
memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length);
|
||||
}
|
||||
|
||||
sockin.sin_port = htons(port);
|
||||
puts("*** Connecting to remote host...");
|
||||
error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin));
|
||||
if(error < 0) {
|
||||
puts("Error connecting to remote host.");
|
||||
FCEU_DispMessage("Error connecting to server",0);
|
||||
close(TSocket);
|
||||
FCEUD_NetworkClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
s_Socket = TSocket;
|
||||
|
||||
puts("*** Sending initialization data to server...");
|
||||
uint8 *sendbuf;
|
||||
uint8 buf[5];
|
||||
uint32 sblen;
|
||||
|
||||
sblen = 4 + 16 + 16 + 64 + 1 + username.size();
|
||||
sendbuf = (uint8 *)FCEU_dmalloc(sblen);
|
||||
memset(sendbuf, 0, sblen);
|
||||
|
||||
// XXX soules - should use htons instead of en32() from above!
|
||||
//uint32 data = htons(sblen - 4);
|
||||
//memcpy(sendbuf, &data, sizeof(data));
|
||||
en32(sendbuf, sblen - 4);
|
||||
|
||||
if(key.size())
|
||||
{
|
||||
struct md5_context md5;
|
||||
uint8 md5out[16];
|
||||
|
||||
md5_starts(&md5);
|
||||
md5_update(&md5, (uint8*)&GameInfo->MD5.data, 16);
|
||||
md5_update(&md5, (uint8 *)key.c_str(), key.size());
|
||||
md5_finish(&md5, md5out);
|
||||
memcpy(sendbuf + 4, md5out, 16);
|
||||
} else
|
||||
{
|
||||
memcpy(sendbuf + 4, (uint8*)&GameInfo->MD5.data, 16);
|
||||
}
|
||||
|
||||
if(password.size()) {
|
||||
struct md5_context md5;
|
||||
uint8 md5out[16];
|
||||
|
||||
md5_starts(&md5);
|
||||
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;
|
||||
|
||||
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
|
||||
send(s_Socket, sendbuf, sblen, 0);
|
||||
#endif
|
||||
FCEU_dfree(sendbuf);
|
||||
|
||||
#ifdef WIN32
|
||||
recv(s_Socket, (char*)buf, 1, 0);
|
||||
#else
|
||||
recv(s_Socket, buf, 1, MSG_WAITALL);
|
||||
#endif
|
||||
netdivisor = buf[0];
|
||||
|
||||
puts("*** Connection established.");
|
||||
FCEU_DispMessage("Connection established.",0);
|
||||
|
||||
FCEUDnetplay = 1;
|
||||
FCEUI_NetplayStart(localPlayers, netdivisor);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FCEUD_SendData(void *data,
|
||||
uint32 len)
|
||||
{
|
||||
int check = 0, error = 0;
|
||||
#ifndef WIN32
|
||||
error = ioctl(fileno(stdin), FIONREAD, &check);
|
||||
#endif
|
||||
if(!error && check) {
|
||||
char buf[1024];
|
||||
char *f;
|
||||
fgets(buf, 1024, stdin);
|
||||
if((f=strrchr(buf,'\n'))) {
|
||||
*f = 0;
|
||||
}
|
||||
FCEUI_NetplayText((uint8 *)buf);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
send(s_Socket, (char*)data, len ,0);
|
||||
#else
|
||||
send(s_Socket, data, len ,0);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
FCEUD_RecvData(void *data,
|
||||
uint32 len)
|
||||
{
|
||||
int size;
|
||||
NoWaiting &= ~2;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
fd_set funfun;
|
||||
struct timeval popeye;
|
||||
|
||||
popeye.tv_sec=0;
|
||||
popeye.tv_usec=100000;
|
||||
|
||||
FD_ZERO(&funfun);
|
||||
FD_SET(s_Socket, &funfun);
|
||||
|
||||
switch(select(s_Socket + 1,&funfun,0,0,&popeye)) {
|
||||
case 0: continue;
|
||||
case -1:return 0;
|
||||
}
|
||||
|
||||
if(FD_ISSET(s_Socket,&funfun)) {
|
||||
#ifdef WIN32
|
||||
size = recv(s_Socket, (char*)data, len, 0);
|
||||
#else
|
||||
size = recv(s_Socket, data, len, MSG_WAITALL);
|
||||
#endif
|
||||
|
||||
if(size == len) {
|
||||
//unsigned long beefie;
|
||||
|
||||
FD_ZERO(&funfun);
|
||||
FD_SET(s_Socket, &funfun);
|
||||
|
||||
popeye.tv_sec = popeye.tv_usec = 0;
|
||||
if(select(s_Socket + 1, &funfun, 0, 0, &popeye) == 1)
|
||||
//if(!ioctl(s_Socket,FIONREAD,&beefie))
|
||||
// if(beefie)
|
||||
{
|
||||
NoWaiting|=2;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
FCEUD_NetworkClose(void)
|
||||
{
|
||||
if(s_Socket > 0) {
|
||||
#ifdef BEOS
|
||||
closesocket(s_Socket);
|
||||
#else
|
||||
close(s_Socket);
|
||||
#endif
|
||||
}
|
||||
s_Socket = -1;
|
||||
|
||||
if(FCEUDnetplay) {
|
||||
FCEUI_NetplayStop();
|
||||
}
|
||||
FCEUDnetplay = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FCEUD_NetplayText(uint8 *text)
|
||||
{
|
||||
char *tot = (char *)FCEU_dmalloc(strlen((const char *)text) + 1);
|
||||
char *tmp;
|
||||
if (!tot)
|
||||
return;
|
||||
strcpy(tot, (const char *)text);
|
||||
tmp = tot;
|
||||
|
||||
while(*tmp) {
|
||||
if(*tmp < 0x20) {
|
||||
*tmp = ' ';
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
puts(tot);
|
||||
FCEU_dfree(tot);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
extern char *netplaynick;
|
||||
extern char *netplayhost;
|
||||
extern char *netpassword;
|
||||
extern char *netgamekey;
|
||||
extern int tport;
|
||||
extern int netlocalplayers;
|
||||
extern char *netplaynick;
|
||||
extern char *netplayhost;
|
||||
extern char *netpassword;
|
||||
extern char *netgamekey;
|
||||
extern int tport;
|
||||
extern int netlocalplayers;
|
||||
|
|
Loading…
Reference in New Issue