window-size sdl surfaces instead of snes
authorJavier S. Pedro <maemo@javispedro.com>
Fri, 28 Aug 2009 01:06:11 +0000 (03:06 +0200)
committerJavier S. Pedro <maemo@javispedro.com>
Fri, 28 Aug 2009 01:06:11 +0000 (03:06 +0200)
Makefile
platform/config.cpp
platform/hgw.cpp
platform/platform.h
platform/sdl.cpp
platform/sdli.cpp
platform/sdlv.cpp

index 6b09edf..e2838c3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ CPPFLAGS := -I. $(shell sdl-config --cflags) $(shell pkg-config --cflags x11 xsp
 LDLIBS := -lz $(shell sdl-config --libs) $(shell pkg-config --libs x11 xsp) -lpopt -lhgw
 
 # Default CFLAGS for building in N8x0
-CFLAGS ?= -march=armv6j -mtune=arm1136jf-s -mfpu=vfp -mfloat-abi=softfp -O2 -g -Wall -static-libgcc
+CFLAGS ?= -DMAEMO -DMAEMO_VERSION=4 -march=armv6j -mtune=arm1136jf-s -mfpu=vfp -mfloat-abi=softfp -O2 -g -Wall -static-libgcc
 ASFLAGS ?= -march=armv6j -mfpu=vfp -mfloat-abi=softfp -g
 CXXFLAGS ?= $(CFLAGS)
 
index 41fac3e..f25a259 100644 (file)
@@ -28,45 +28,47 @@ static struct poptOption commonOptionsTable[] = {
        { "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
 };
 
@@ -166,6 +168,7 @@ static void loadDefaults()
        Config.fullscreen = false;
        Config.xsp = false;
        Config.hacksFile = 0;
+       Config.touchscreenInput = false;
 
        Settings.JoystickEnabled = FALSE;
        Settings.SoundPlaybackRate = 22050;
@@ -348,6 +351,9 @@ static void parseArgs(poptContext optCon)
                        case 15:
                                Settings.SoundBufferSize = atoi(poptGetOptArg(optCon));
                                break;
+                       case 16:
+                               Config.touchscreenInput = true;
+                               break;
                        case 100:
                                scancode = atoi(poptGetOptArg(optCon));
                                break;
index d4273ee..dee9427 100644 (file)
@@ -12,7 +12,6 @@
        } while (0);
 
 
-
 bool hgwLaunched;
 static HgwContext *hgw;
 
@@ -210,12 +209,12 @@ static void parseGConfKeyMappings()
                        if (scancode <= 0 || scancode > 255) continue;
 
                        if (buttons[i].is_action) {
-                               Config.action[scancode] = buttons[i].mask;
+                               Config.action[scancode] |= buttons[i].mask;
                                if (buttons[i].mask & (kActionQuit | kActionToggleFullscreen)) {
                                        quit_mapped = true;
                                }
                        } else {
-                               Config.joypad1Mapping[scancode] = buttons[i].mask;
+                               Config.joypad1Mapping[scancode] |= buttons[i].mask;
                        }
                }
        }
index b0d2803..75ef7d2 100644 (file)
@@ -20,6 +20,8 @@ extern struct config {
        bool enableAudio;
        /** Speedhacks file to use */
        char * hacksFile;
+       /** Enable touchscreen controls */
+       bool touchscreenInput;
        /** Current scancode->joypad mapping */
        unsigned short joypad1Mapping[256];
        unsigned char action[256];
@@ -36,6 +38,11 @@ void S9xInitAudioOutput();
 void S9xDeinitAudioOutput();
 void S9xAudioOutputEnable(bool enable);
 
+// Input devices
+EXTERN_C void S9xInitInputDevices();
+void S9xDeinitInputDevices();
+void S9xInputFullscreenChanged();
+
 // Input actions
 #define kActionNone                                            0
 #define kActionQuit                                    (1U << 0)
index 862d352..7da4fa7 100644 (file)
@@ -239,6 +239,7 @@ int main(int argc, const char ** argv) {
        
        // Deinitialization
        S9xAudioOutputEnable(false);
+       S9xDeinitInputDevices();
        S9xDeinitAudioOutput();
        S9xDeinitDisplay();
 
@@ -262,7 +263,9 @@ void S9xDoAction(unsigned char action)
        if (action & kActionQuit) 
                Config.quitting = true;
 
-       if (action & kActionToggleFullscreen)
+       if (action & kActionToggleFullscreen) {
                S9xVideoToggleFullscreen();
+               S9xInputFullscreenChanged();
+       }
 }
 
index 1d20b18..3fb883f 100644 (file)
@@ -120,3 +120,13 @@ void S9xInitInputDevices()
        }
 }
 
+void S9xDeinitInputDevices()
+{
+
+}
+
+void S9xInputFullscreenChanged()
+{
+
+}
+
index e61a861..03c7c06 100644 (file)
 
 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;
        }
 }
 
@@ -57,44 +104,84 @@ static void freeVideoSurface()
 
 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" : "");
 }
@@ -103,7 +190,7 @@ void S9xInitDisplay(int argc, const char ** argv)
 {      
        if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) 
                DIE("SDL_InitSubSystem(VIDEO): %s", SDL_GetError());
-       
+
        setupVideoSurface();
 }
 
@@ -165,7 +252,7 @@ bool8_32 S9xDeinitUpdate (int width, int height, bool8_32 sixteenBit)
                height *= 2;
        }
 
-       SDL_UpdateRect(screen, 0, 0, width, height);
+       SDL_UpdateRects(screen, 1, &renderArea);
        
        return TRUE;
 }