DEADSOFTWARE

added optional framebuffer and resolution scaling
[d2df-sdl.git] / src / game / sdl / g_system.pas
index 21501c6705baacbfc11a2711f7789163b9c9556e..e5f62750ea6b0ca2c993025d4f7ab23125eb1d35 100644 (file)
@@ -24,8 +24,8 @@ interface
   procedure sys_Delay (ms: Integer);
 
   (* --- Graphics --- *)
-  function sys_GetDispalyModes (bpp: Integer): SSArray;
-  function sys_SetDisplayMode (w, h, bpp: Integer; fullscreen: Boolean): Boolean;
+  function sys_GetDisplayModes (bpp: Integer): SSArray;
+  function sys_SetDisplayMode (w, h, bpp: Integer; fullscreen, maximized: Boolean): Boolean;
   procedure sys_EnableVSync (yes: Boolean);
   procedure sys_Repaint;
 
@@ -40,12 +40,13 @@ interface
 implementation
 
   uses
-    SysUtils, SDL, GL, Math,
-    e_log, e_graphics, e_input,
-    g_options, g_window, g_console, g_game, g_menu, g_gui, g_main;
+    SysUtils, SDL, Math,
+    {$INCLUDE ../nogl/noGLuses.inc}
+    e_log, e_graphics, e_input, e_sound,
+    g_options, g_window, g_console, g_game, g_menu, g_gui, g_main, g_basic;
 
   const
-    GameTitle = 'Doom 2D: Forever (SDL 1.2)';
+    GameTitle = 'Doom 2D: Forever (SDL 1.2, %s)';
 
   var
     userResize: Boolean;
@@ -73,8 +74,15 @@ implementation
   begin
     gWinSizeX := w;
     gWinSizeY := h;
-    gWinRealPosX := 0;
-    gWinRealPosY := 0;
+    gRC_Width := w;
+    gRC_Height := h;
+    if glRenderToFBO then
+    begin
+      // store real window size in gWinSize, downscale resolution now
+      w := round(w / r_pixel_scale);
+      h := round(h / r_pixel_scale);
+      e_ResizeFramebuffer(w, h);
+    end;
     gScreenWidth := w;
     gScreenHeight := h;
     {$IFDEF ENABLE_HOLMES}
@@ -88,11 +96,20 @@ implementation
     g_Game_ClearLoading;
   end;
 
+  function GetTitle (): PChar;
+    var info: AnsiString;
+  begin
+    info := g_GetBuildHash(false);
+    if info = 'custom build' then
+      info := info + ' by ' + g_GetBuilderName() + ' ' + GAME_BUILDDATE + ' ' + GAME_BUILDTIME;
+    result := PChar(Format(GameTitle, [info]))
+  end;
+
   function InitWindow (w, h, bpp: Integer; fullScreen: Boolean): Boolean;
     var flags: Uint32;
   begin
     e_LogWritefln('InitWindow %s %s %s %s', [w, h, bpp, fullScreen]);
-    result := False;
+    result := false;
     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
@@ -108,7 +125,21 @@ implementation
       screen := SDL_SetVideoMode(w, h, bpp, flags);
       if screen <> nil then
       begin
-        SDL_WM_SetCaption(GameTitle, nil);
+        {$IFDEF NOGL_INIT}
+          nogl_Init;
+          glRenderToFBO := False; // TODO: check for GL_OES_framebuffer_object
+        {$ELSE}
+          if glRenderToFBO then
+            if not Load_GL_ARB_framebuffer_object() then
+              if not Load_GL_EXT_framebuffer_object() then
+              begin
+                e_LogWriteln('SDL: no framebuffer support detected');
+                glRenderToFBO := False
+              end;
+        {$ENDIF}
+        SDL_WM_SetCaption(GetTitle(), nil);
+        gFullScreen := fullscreen;
+        gRC_FullScreen := fullscreen;
         UpdateSize(w, h);
         result := True
       end
@@ -121,6 +152,8 @@ implementation
 
   procedure sys_Repaint;
   begin
+    if glRenderToFBO then
+      e_BlitFramebuffer(gWinSizeX, gWinSizeY);
     SDL_GL_SwapBuffers
   end;
 
@@ -129,7 +162,7 @@ implementation
     (* ??? *)
   end;
 
-  function sys_GetDispalyModes (bpp: Integer): SSArray;
+  function sys_GetDisplayModes (bpp: Integer): SSArray;
     var m: PPSDL_Rect; f: TSDL_PixelFormat; i, count: Integer;
   begin
     SetLength(result, 0);
@@ -138,7 +171,7 @@ implementation
     f.BitsPerPixel := bpp;
     f.BytesPerPixel := (bpp + 7) div 8;
     m := SDL_ListModes(@f, SDL_OPENGL or SDL_FULLSCREEN);
-    if (m <> NIL) and (IntPtr(m) <> -1) then
+    if (m <> NIL) and (UIntPtr(m) <> UIntPtr(-1)) then
     begin
       count := 0;
       while m[count] <> nil do inc(count);
@@ -148,7 +181,7 @@ implementation
     end
   end;
 
-  function sys_SetDisplayMode (w, h, bpp: Integer; fullscreen: Boolean): Boolean;
+  function sys_SetDisplayMode (w, h, bpp: Integer; fullscreen, maximized: Boolean): Boolean;
   begin
     result := InitWindow(w, h, bpp, fullscreen)
   end;
@@ -429,6 +462,7 @@ implementation
         SDL_JOYAXISMOTION: HandleJoyAxis(ev.jaxis);
         SDL_JOYHATMOTION: HandleJoyHat(ev.jhat);
         SDL_VIDEOEXPOSE: sys_Repaint;
+        SDL_ACTIVEEVENT: e_MuteChannels((ev.active.gain = 0) and gMuteWhenInactive);
       end
     end
   end;
@@ -443,7 +477,7 @@ implementation
   (* --------- Init --------- *)
 
   procedure sys_Init;
-    var flags: Uint32; ok: Boolean; i: Integer;
+    var flags: Uint32; i: Integer;
   begin
     e_WriteLog('Init SDL', TMsgType.Notify);
     flags := SDL_INIT_VIDEO or SDL_INIT_AUDIO or
@@ -451,9 +485,6 @@ implementation
              (*or SDL_INIT_NOPARACHUTE*);
     if SDL_Init(flags) <> 0 then
       raise Exception.Create('SDL: Init failed: ' + SDL_GetError);
-    ok := InitWindow(gScreenWidth, gScreenHeight, gBPP, gFullScreen);
-    if not ok then
-      raise Exception.Create('SDL: Failed to set videomode: ' + SDL_GetError);
     SDL_EnableUNICODE(1);
     SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
     for i := 0 to e_MaxJoys - 1 do
@@ -466,7 +497,13 @@ implementation
     e_WriteLog('Releasing SDL', TMsgType.Notify);
     for i := 0 to e_MaxJoys - 1 do
       RemoveJoystick(i);
-    SDL_FreeSurface(screen);
+    if screen <> nil then
+    begin
+      {$IFDEF NOGL_INIT}
+        nogl_Quit;
+      {$ENDIF}
+      SDL_FreeSurface(screen)
+    end;
     SDL_Quit
   end;