{ "disable-audio", 'a', POPT_ARG_NONE, 0, 1,
"disable emulation and output of audio", 0 },
{ "display-framerate", 'r', POPT_ARG_NONE, 0, 2,
- "Show frames per second counter in lower left corner", 0 },
+ "show frames per second counter in lower left corner", 0 },
{ "skip-frames", 's', POPT_ARG_INT, 0, 3,
- "Render only 1 in every N frames", "NUM" },
+ "render only 1 in every N frames", "NUM" },
{ "fullscreen", 'f', POPT_ARG_NONE, 0, 4,
- "Start in fullscreen mode", 0 },
+ "start in fullscreen mode", 0 },
{ "transparency", 'y', POPT_ARG_NONE, 0, 5,
- "Enable transparency effects (slower)", 0 },
+ "enable transparency effects (slower)", 0 },
{ "hacks", 'h', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, 0, 6,
- "Enable hacks (yes, speed-only, no)", "option" },
+ "enable hacks (yes, speed-only, no)", "option" },
{ "pal", 'p', POPT_ARG_NONE, 0, 7,
- "Run in PAL mode", 0 },
+ "run in PAL mode", 0 },
{ "ntsc", 'n', POPT_ARG_NONE, 0, 8,
- "Run in NTSC mode", 0 },
+ "run in NTSC mode", 0 },
{ "turbo", 't', POPT_ARG_NONE, 0, 9,
- "Turbo mode (do not try to sleep between frames)", 0 },
+ "turbo mode (do not try to sleep between frames)", 0 },
{ "conf", 'c', POPT_ARG_STRING, 0, 10,
- "Extra configuration file to load", "FILE" },
+ "extra configuration file to load", "FILE" },
{ "mouse", 'm', POPT_ARG_INT | POPT_ARGFLAG_OPTIONAL, 0, 11,
- "Enable mouse on controller NUM", "NUM"},
+ "enable mouse on controller NUM", "NUM"},
{ "superscope", 'e', POPT_ARG_NONE, 0, 12,
- "Enable SuperScope", 0},
+ "enable SuperScope", 0},
{ "snapshot", 'o', POPT_ARG_NONE, 0, 13,
- "Unfreeze previous game on start and freeze game on exit", 0 },
+ "unfreeze previous game on start and freeze game on exit", 0 },
{ "audio-rate", 'u', POPT_ARG_INT, 0, 14,
- "Audio output rate", "HZ" },
+ "audio output rate", "HZ" },
{ "audio-buffer-size", 'b', POPT_ARG_INT, 0, 15,
- "Audio output buffer size", "SAMPLES" },
+ "audio output buffer size", "SAMPLES" },
+ { "touchscreen", 'd', POPT_ARG_NONE, 0, 16,
+ "enable touchscreen controls", 0 },
POPT_TABLEEND
};
static struct poptOption configOptionsTable[] = {
{ "scancode", '\0', POPT_ARG_INT, 0, 100,
- "Scancode to map", "CODE" },
+ "scancode to map", "CODE" },
{ "button", '\0', POPT_ARG_STRING, 0, 101,
"SNES Button to press (A, B, X, Y, L, R, Up, Down, Left, Right)", "name" },
{ "action", '\0', POPT_ARG_STRING, 0, 102,
- "Emulator action to do (fullscreen, quit, ...)", "action" },
+ "emulator action to do (fullscreen, quit, ...)", "action" },
{ "hacks-file", '\0', POPT_ARG_STRING, 0, 200,
- "Path to snesadvance.dat file", "FILE" },
+ "path to snesadvance.dat file", "FILE" },
POPT_TABLEEND
};
Config.fullscreen = false;
Config.xsp = false;
Config.hacksFile = 0;
+ Config.touchscreenInput = false;
Settings.JoystickEnabled = FALSE;
Settings.SoundPlaybackRate = 22050;
case 15:
Settings.SoundBufferSize = atoi(poptGetOptArg(optCon));
break;
+ case 16:
+ Config.touchscreenInput = true;
+ break;
case 100:
scancode = atoi(poptGetOptArg(optCon));
break;
static SDL_Surface *screen;
+static SDL_Rect windowSize, screenSize;
+static bool gotWindowSize, gotScreenSize;
+
+/** Inside the surface, where are we drawing */
+static SDL_Rect renderArea;
+
+#ifdef MAEMO
static void setDoubling(bool enable)
{
SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version);
if ( SDL_GetWMInfo(&wminfo) ) {
- XSPSetPixelDoubling(wminfo.info.x11.display, 0, enable ? 1 : 0);
+ Display *dpy = wminfo.info.x11.display;
+ XSPSetPixelDoubling(dpy, 0, enable ? 1 : 0);
+ XFlush(dpy);
+ }
+}
+#endif
+
+static void centerRectangle(SDL_Rect& result, int areaW, int areaH, int w, int h)
+{
+ result.x = areaW / 2 - w / 2;
+ result.w = w;
+ result.y = areaH / 2 - h / 2;
+ result.h = h;
+}
+
+static void calculateScreenSize()
+{
+ SDL_SysWMinfo wminfo;
+ SDL_VERSION(&wminfo.version);
+
+ if ( SDL_GetWMInfo(&wminfo) ) {
+ Display *dpy = wminfo.info.x11.display;
+ Window w;
+ SDL_Rect* size;
+ XWindowAttributes xwa;
+
+ if (Config.fullscreen) {
+ w = wminfo.info.x11.fswindow;
+ size = &screenSize;
+ gotScreenSize = true;
+ } else {
+ w = wminfo.info.x11.wmwindow;
+ size = &windowSize;
+ gotWindowSize = true;
+ }
+
+ XGetWindowAttributes(dpy, w, &xwa);
+ size->x = xwa.x;
+ size->y = xwa.y;
+ size->w = xwa.width;
+ size->h = xwa.height;
}
}
static void setupVideoSurface()
{
- int w = IMAGE_WIDTH;
- int h = IMAGE_HEIGHT;
+ // Real surface area.
+ unsigned realWidth = IMAGE_WIDTH;
+ unsigned realHeight = IMAGE_HEIGHT;
+ // SDL Window/Surface size (bigger, so we can get mouse events there).
+ unsigned srfWidth, srfHeight;
+
+#ifdef MAEMO
+ if ((Config.fullscreen && !gotScreenSize) ||
+ (!Config.fullscreen && !gotWindowSize)) {
+ // Do a first try, in order to get window/screen size
+ screen = SDL_SetVideoMode(realWidth, realHeight, 16,
+ SDL_SWSURFACE | SDL_RESIZABLE |
+ (Config.fullscreen ? SDL_FULLSCREEN : 0));
+ if (!screen) DIE("SDL_SetVideoMode: %s", SDL_GetError());
+ calculateScreenSize();
+ }
+ if (Config.fullscreen) {
+ srfWidth = screenSize.w;
+ srfHeight = screenSize.h;
+ } else {
+ srfWidth = windowSize.w;
+ srfHeight = windowSize.h;
+ }
// By now, just assume xsp == fullscreen. This has to change.
Config.xsp = Config.fullscreen;
- if (Config.xsp) {
- w *= 2;
- h *= 2;
- } else {
- setDoubling(false); // Before switching video modes
+ if (!Config.xsp) {
+ setDoubling(false); // Before switching video modes; avoids flicker.
}
+#else
+ srfWidth = realWidth;
+ srfHeight = realHeight;
+#endif
- screen = SDL_SetVideoMode(w, h,
+ screen = SDL_SetVideoMode(srfWidth, srfHeight,
Settings.SixteenBit ? 16 : 8,
SDL_SWSURFACE |
(Config.fullscreen ? SDL_FULLSCREEN : 0));
-
if (!screen)
DIE("SDL_SetVideoMode: %s", SDL_GetError());
SDL_ShowCursor(SDL_DISABLE);
- if (Config.xsp) setDoubling(true);
-
+ // We get pitch surface values from SDL
GFX.RealPitch = GFX.Pitch = screen->pitch;
+ GFX.ZPitch = realWidth; // The ZBuffer is independent of SDL surface size.
+ GFX.PixSize = screen->format->BitsPerPixel / 8;
+
+ // Ok, calculate renderArea
+#ifdef MAEMO
+ if (Config.xsp) {
+ setDoubling(true);
+ centerRectangle(renderArea, srfWidth, srfHeight,
+ realWidth * 2, realHeight * 2);
+ renderArea.w /= 2;
+ renderArea.h /= 2;
+ } else {
+ centerRectangle(renderArea, srfWidth, srfHeight, realWidth, realHeight);
+ }
+#else
+ centerRectangle(renderArea, srfWidth, srfHeight, realWidth, realHeight);
+#endif
- GFX.Screen = (uint8*) screen->pixels;
- GFX.SubScreen = (uint8 *) malloc(GFX.RealPitch * IMAGE_HEIGHT);
- GFX.ZBuffer = (uint8 *) malloc(GFX.RealPitch * IMAGE_HEIGHT);
- GFX.SubZBuffer = (uint8 *) malloc(GFX.RealPitch * IMAGE_HEIGHT);
+ GFX.Screen = ((uint8*) screen->pixels)
+ + (renderArea.x * GFX.PixSize)
+ + (renderArea.y * GFX.Pitch);
+ GFX.SubScreen = (uint8 *) malloc(GFX.Pitch * IMAGE_HEIGHT);
+ GFX.ZBuffer = (uint8 *) malloc(GFX.Pitch * IMAGE_HEIGHT);
+ GFX.SubZBuffer = (uint8 *) malloc(GFX.Pitch * IMAGE_HEIGHT);
GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;
GFX.PPL = GFX.Pitch >> 1;
GFX.PPLx2 = GFX.Pitch;
- GFX.ZPitch = GFX.Pitch >> 1;
-
- printf("Video: %dx%d, %hu bits per pixel, %s %s\n", screen->w, screen->h,
- screen->format->BitsPerPixel,
+ GFX.ZPitch = GFX.Pitch >> 1; // TODO
+
+ printf("Video: %dx%d (%dx%d output), %hu bits per pixel, %s %s\n",
+ realWidth, realHeight,
+ screen->w, screen->h, screen->format->BitsPerPixel,
Config.fullscreen ? "fullscreen" : "windowed",
Config.xsp ? "with pixel doubling" : "");
}
{
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
DIE("SDL_InitSubSystem(VIDEO): %s", SDL_GetError());
-
+
setupVideoSurface();
}
height *= 2;
}
- SDL_UpdateRect(screen, 0, 0, width, height);
+ SDL_UpdateRects(screen, 1, &renderArea);
return TRUE;
}