DEADSOFTWARE

Added support for win9x using allegro
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 31 Jan 2019 16:19:32 +0000 (19:19 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Sun, 10 Feb 2019 10:05:11 +0000 (13:05 +0300)
src/lib/allegro4/allegro.pas
src/nogl/noGLALSW.inc
src/shared/a_modes.inc
src/shared/envvars.pas
src/wrappers/sdl2/sdl2allegro.inc

index 0a1affef875346d773a0cdf9d01b6ad273800576..6f4456f765baee8527637e933cbbe9eac3cd8741 100644 (file)
@@ -8,13 +8,14 @@
   {$DEFINE LibraryLibAllegroDecl := cdecl}
   {$DEFINE LibraryLibAllegroImp := cdecl; external}
   {$DEFINE LibraryLibAllegroVar := cvar; external}
-{$ELSEIF DEFINED(UNIX)}
-  {$LINKLIB liballeg.so}
+{$ELSEIF DEFINED(WINDOWS)}
+  {$DEFINE LibraryLibAllegroDecl := cdecl}
+  {$DEFINE LibraryLibAllegroImp := cdecl; external 'alleg42.dll'}
+  {$DEFINE LibraryLibAllegroVar := external 'alleg42.dll'}
+{$ELSE}
   {$DEFINE LibraryLibAllegroDecl := cdecl}
   {$DEFINE LibraryLibAllegroImp := cdecl; external 'alleg'}
   {$DEFINE LibraryLibAllegroVar := cvar; external 'alleg'}
-{$ELSE}
-  {$ERROR unsupported platform!}
 {$ENDIF}
 
 unit allegro;
@@ -24,18 +25,16 @@ interface
   uses ctypes;
 
   const
-{$IF DEFINED(GO32V2)}
+{$IF DEFINED(GO32V2) OR DEFINED(WINDOWS)}
     ALLEGRO_VERSION = 4;
     ALEGRO_SUB_VERSION = 2;
     ALLEGRO_WIP_VERSION = 3;
     ALLEGRO_VERSION_STR = '4.2.3';
-{$ELSEIF DEFINED(UNIX)}
+{$ELSE}
     ALLEGRO_VERSION = 4;
     ALEGRO_SUB_VERSION = 4;
     ALLEGRO_WIP_VERSION = 2;
     ALLEGRO_VERSION_STR = '4.4.2';
-{$ELSE}
-  {$ERROR unsupported platform!}
 {$ENDIF}
 
     SYSTEM_AUTODETECT = 0;
@@ -242,13 +241,13 @@ interface
    AtExitCallback = procedure; LibraryLibAllegroDecl;
    AtExitFunction = function (func: AtExitCallback): cint; LibraryLibAllegroDecl;
    TimerIntCallback = procedure; LibraryLibAllegroDecl;
+   QuitCallback = procedure; LibraryLibAllegroDecl;
 
   var
     allegro_id: array [0..ALLEGRO_ERROR_SIZE] of char; LibraryLibAllegroVar;
     allegro_error: array [0..ALLEGRO_ERROR_SIZE] of char; LibraryLibAllegroVar;
     keyboard_lowlevel_callback: KeyboardCallback; LibraryLibAllegroVar;
     screen: PBITMAP; LibraryLibAllegroVar;
-
     black_palette: PALETTE; LibraryLibAllegroVar;
     desktop_palette: PALETTE; LibraryLibAllegroVar;
     default_palette: PALETTE; LibraryLibAllegroVar;
@@ -267,9 +266,6 @@ interface
   procedure remove_keyboard; LibraryLibAllegroImp;
   function _install_allegro_version_check (system_id: cint; errno_ptr: Pcint; atexit_ptr: AtExitFunction; version: cint): cint; LibraryLibAllegroImp;
 
-  function install_allegro (system_id: cint; errno_ptr: Pcint; atexit_ptr: AtExitFunction): cint; inline; (* macros *)
-  function allegro_init: cint; inline; (* macros *)
-
   function install_timer: cint; LibraryLibAllegroImp;
   procedure remove_timer; LibraryLibAllegroImp;
   procedure set_keyboard_rate (delay, _repeat: cint); LibraryLibAllegroImp;
@@ -298,18 +294,42 @@ interface
 
   procedure set_palette (const p: PALETTE); LibraryLibAllegroImp;
   procedure set_color_depth (depth: cint); LibraryLibAllegroImp;
+  function set_close_button_callback (proc: QuitCallback): cint; LibraryLibAllegroImp;
 
 //  function _install_allegro (system_id: cint; errno_prt: Pcint; AtExitFunction): cint; LibraryLibAllegroImp;
 
   (* MACRO *)
+  function install_allegro (system_id: cint; errno_ptr: Pcint; atexit_ptr: AtExitFunction): cint; inline;
+  function allegro_init: cint; inline;
+
   function TIMERS_PER_SECOND: clong; inline;
   function SECS_TO_TIMER (x: clong): clong; inline;
   function MSEC_TO_TIMER (x: clong): clong; inline;
   function BPS_TO_TIMER (x: clong): clong; inline;
   function BPM_TO_TIMER (x: clong): clong; inline;
 
+(*
+  function acquire_bitmap (bmp: PBITMAP); inline;
+  function release_bitmap (bmp: PBITMAP); inline;
+  function acquire_screen; inline;
+  function release_screen; inline;
+*)
+
+  procedure acquire_bitmap (bmp: PBITMAP); LibraryLibAllegroImp;
+  procedure release_bitmap (bmp: PBITMAP); LibraryLibAllegroImp;
+  procedure acquire_screen; LibraryLibAllegroImp;
+  procedure release_screen; LibraryLibAllegroImp;
+
 implementation
 
+  {$IF DEFINED(GO32V2)}
+    function atexit (func: AtexitCallback): cint; cdecl; external;
+  {$ELSEIF DEFINED(WINDOWS)}
+    function atexit (func: AtexitCallback): cint; cdecl; external 'msvcrt.dll';
+  {$ELSE}
+    function atexit (func: AtexitCallback): cint; cdecl; external 'c';
+  {$ENDIF}
+
   function install_allegro (system_id: cint; errno_ptr: Pcint; atexit_ptr: AtExitFunction): cint; inline;
   begin
     install_allegro := _install_allegro_version_check(system_id, errno_ptr, atexit_ptr, (ALLEGRO_VERSION shl 16) OR (ALEGRO_SUB_VERSION shl 8) OR ALLEGRO_WIP_VERSION)
@@ -317,13 +337,10 @@ implementation
 
   function allegro_init: cint; inline;
   begin
-    (* original macros sets atexit_ptr *)
     (* original macros sets libc errno? *)
-    allegro_init := _install_allegro_version_check(SYSTEM_AUTODETECT, nil, nil, (ALLEGRO_VERSION shl 16) OR (ALEGRO_SUB_VERSION shl 8) OR ALLEGRO_WIP_VERSION)
+    allegro_init := _install_allegro_version_check(SYSTEM_AUTODETECT, nil, @atexit, (ALLEGRO_VERSION shl 16) OR (ALEGRO_SUB_VERSION shl 8) OR ALLEGRO_WIP_VERSION)
   end;
 
-
-
   function TIMERS_PER_SECOND: clong; inline;
   begin
     TIMERS_PER_SECOND := 1193181
@@ -349,4 +366,13 @@ implementation
     BPM_TO_TIMER := 60 * TIMERS_PER_SECOND div x
   end;
 
+(*
+  function acquire_bitmap (bmp: PBITMAP); inline;
+  begin
+    ASSERT(bmp <> nil);
+    if bmp.vtable.acquire <> nil then
+      bmp.vtable.acquire(bmp)
+  end;
+*)
+
 end.
index 55ee112fe1bfbd05dfcd820cefca48fd799b9f34..853c22495095f6c1f2ce94b996490eb92b48f72e 100644 (file)
@@ -60,7 +60,7 @@ implementation
   begin
     assert(i >= 0);
     assert(i <= High(tex));
-    assert(tex[i].used);
+    //assert(tex[i].used); (* free unallocated texture *)
     tex[i].used := false;
     if tex[i].bmp <> nil then
       destroy_bitmap(tex[i].bmp);
index 26f2fd218b1f075ab8df0cfe0d94b916e9a588ba..57c97a82dc5f0c780f3c2b9fdc44c0b6944877d3 100644 (file)
 {$BOOLEVAL OFF}
 {$COPERATORS ON}
 {$EXTENDEDSYNTAX ON}
-{$IF DEFINED(CPU386) AND NOT DEFINED(GO32V2)}
-  {$FPUTYPE SSE}
+{$IF DEFINED(CPU386)}
+  {$IFDEF USE_X87}
+    {$FPUTYPE x87}
+    {$MMX-}
+  {$ELSE}
+    {$FPUTYPE SSE}
+    {$MMX-}
+  {$ENDIF}
+{$ELSE}
+  {$MMX-} // get lost, mmx
 {$ENDIF}
 {$GOTO ON}
 {$IEEEERRORS OFF}
@@ -52,9 +60,6 @@
 {$VARSTRINGCHECKS OFF}
 
 {$S-} // disable stack checking
-{$IF NOT DEFINED(GO32V2)}
-  {$MMX-} // get lost, mmx
-{$ENDIF}
 
 {$IF DEFINED(D2F_DEBUG)}
   {$STACKFRAMES ON}
index 55d58702b4487b0cf2d85de10921d0b42b877dab..32d3273c3714dc7c7d0b2d9c52c4726e03f8d3e8 100644 (file)
@@ -33,7 +33,7 @@ implementation
     utils;
 
 
-{$IFDEF WINDOWS}
+{$IF DEFINED(WINDOWS)}
 function setenv(const VarStr: PChar; const VarVal: PChar; Repl: cint): cint;
 begin
   if (SetEnvironmentVariable(VarStr, VarVal)) then
@@ -41,18 +41,12 @@ begin
   else
     Result := -1;
 end;
+{$ELSEIF DEFINED(GO32V2)}
+  {$LINKLIB c}
+  function setenv(const VarStr: PChar; const VarVal: PChar; Repl: cint): cint; cdecl; external;
 {$ELSE}
-  {$IFDEF GO32V2}
-    function setenv(const VarStr: PChar; const VarVal: PChar; Repl: cint): cint;
-    begin
-      {$WARNING setenv stub!}
-      result := 0
-    end;
-  {$ELSE}
-    {$LINKLIB c}
-    const clib = 'c';
-    function setenv(const VarStr: PChar; const VarVal: PChar; Repl: cint): cint; cdecl; external clib name 'setenv';
-  {$ENDIF}
+  {$LINKLIB c}
+  function setenv(const VarStr: PChar; const VarVal: PChar; Repl: cint): cint; cdecl; external 'c' name 'setenv';
 {$ENDIF}
 
 function SetEnvVar(const VarName: AnsiString; const VarVal: AnsiString): Boolean;
index 78c6f41f158f10301c163e2c56a7e8dbb46181f8..0d00c6a2359d6f37e8cf4d270f59f45becebfd88 100644 (file)
@@ -83,10 +83,10 @@ interface
       1: (mem: TMem);
       2: (unknown: TUnknown);
       {$IFDEF ANDROID}
-      3: (androidio: TAndroidIO);
+      //3: (androidio: TAndroidIO);
       {$ENDIF}
       {$IFDEF WINDOWS}
-      3: (windowsio: TWindowsIO);
+      //3: (windowsio: TWindowsIO);
       {$ENDIF}
     end;
 
@@ -375,12 +375,10 @@ implementation
     maxKeyBuffer = 64;
 
   var
-    __crt0_argv: PPchar; cvar; external;
-    myargv: array [0..255] of Pchar;
     keyring: array [0..maxKeyBuffer - 1] of Integer;
     keybeg, keyend: Integer;
-
-    ticks: UInt32; (* !!! VOLATILE !!! *)
+    ticks: UInt32;
+    quit: Boolean;
 
   function IsEmptyKeyboard: Boolean;
   begin
@@ -410,9 +408,7 @@ implementation
       keyend := (keyend + 1) mod maxKeyBuffer
     end
   end;
-  procedure KeyboardWatcherEND;
-  begin
-  end;
+  procedure KeyboardWatcherEND; begin end;
 
   /// MACRO ///
 
@@ -550,28 +546,26 @@ implementation
   begin
     inc(ticks)
   end;
-  procedure AllegroTimerCallbackEND;
-  begin
-  end;
-
-
+  procedure AllegroTimerCallbackEND; begin end;
 
   function SDL_GetPerformanceCounter: UInt64;
   begin
     //e_LogWriteln('SDL_GetPerformanceCounter');
+    (* TODO *)
     result := ticks;
   end;
 
   function SDL_GetPerformanceFrequency: UInt64;
   begin
     //e_LogWriteln('SDL_GetPerformanceFrequency');
+    (* TODO *)
     result := 1
   end;
 
   procedure SDL_Delay(ms: UInt32);
   begin
     //e_LogWriteln('SDL_Delay');
-    //rest(ms)
+    rest(ms)
   end;
 
   function SDL_GetTicks: UInt32;
@@ -643,10 +637,7 @@ implementation
     e_LogWritefln('SDL_CreateWindow %s %s %s %s %s %u', [title, x, y, w, h, flags]);
     result := nil;
 
-{$IF DEFINED(AL_TEXT)}
-    mode := GFX_TEXT;
-    w := 0; h := 0;
-{$ELSEIF DEFINED(GO32V2)}
+{$IF DEFINED(GO32V2)}
     mode := GFX_AUTODETECT;
 {$ELSE}
     if (flags and (SDL_WINDOW_FULLSCREEN or SDL_WINDOW_FULLSCREEN_DESKTOP)) <> 0 then
@@ -659,17 +650,13 @@ implementation
     if set_gfx_mode(mode, w, h, 0, 0) = 0 then
     begin
       new(window);
-{$IF NOT DEFINED(AL_TEXT)}
       set_window_title(title);
       if sdl2allegro_screen <> nil then
         destroy_bitmap(sdl2allegro_screen);
-      //sdl2allegro_screen := create_video_bitmap(w, h);
-      //if sdl2allegro_screen = nil then
-        sdl2allegro_screen := create_system_bitmap(w, h);
+      sdl2allegro_screen := create_system_bitmap(w, h);
       if sdl2allegro_screen = nil then
         sdl2allegro_screen := create_bitmap(w, h);
       ASSERT(sdl2allegro_screen <> nil);
-{$ENDIF}
       window.w := w;
       window.h := h;
       window.mode := mode;
@@ -684,10 +671,7 @@ implementation
     result := -1;
     if window = nil then exit;
 
-{$IF DEFINED(AL_TEXT)}
-    mode := GFX_TEXT;
-    window.w := 0; window.h := 0;
-{$ELSEIF DEFINED(GO32V2)}
+{$IF DEFINED(GO32V2)}
     mode := GFX_AUTODETECT;
 {$ELSE}
     if (flags and (SDL_WINDOW_FULLSCREEN or SDL_WINDOW_FULLSCREEN_DESKTOP)) <> 0 then
@@ -699,19 +683,13 @@ implementation
     set_color_depth(DEFAULT_DEPTH);
     if set_gfx_mode(mode, window.w, window.h, 0, 0) = 0 then
     begin
-{$IF NOT DEFINED(AL_TEXT)}
-(* 
      if sdl2allegro_screen <> nil then
         destroy_bitmap(sdl2allegro_screen);
-*)
-      //sdl2allegro_screen := create_video_bitmap(window.w, window.h);
-      //if sdl2allegro_screen = nil then
-        sdl2allegro_screen := create_system_bitmap(window.w, window.h);
+      sdl2allegro_screen := create_system_bitmap(window.w, window.h);
       if sdl2allegro_screen = nil then
         sdl2allegro_screen := create_bitmap(window.w, window.h);
       ASSERT(sdl2allegro_screen <> nil);
       set_palette(desktop_palette);
-{$ENDIF}
       window.mode := mode;
       result := 0
     end
@@ -721,24 +699,16 @@ implementation
   begin
     e_LogWritefln('SDL_SetWindowSize %s %s', [w, h]);
     if window = nil then exit;
-{$IF DEFINED(AL_TEXT)}
-  window.mode := GFX_TEXT;
-  w := 0; h := 0;
-{$ENDIF}
     set_color_depth(DEFAULT_DEPTH);
     if set_gfx_mode(window.mode, w, h, 0, 0) = 0 then
     begin
-{$IF NOT DEFINED(AL_TEXT)}
       if sdl2allegro_screen <> nil then
         destroy_bitmap(sdl2allegro_screen);
-      //sdl2allegro_screen := create_video_bitmap(w, h);
-      //if sdl2allegro_screen = nil then
-        sdl2allegro_screen := create_system_bitmap(w, h);
+      sdl2allegro_screen := create_system_bitmap(w, h);
       if sdl2allegro_screen = nil then
         sdl2allegro_screen := create_bitmap(w, h);
       ASSERT(sdl2allegro_screen <> nil);
       set_palette(desktop_palette);
-{$ENDIF}
       window.w := w;
       window.h := h;
     end
@@ -804,12 +774,12 @@ implementation
     var res: cint;
   begin
     //e_LogWriteln('SDL_GL_SwapWindow');
-{$IF NOT DEFINED(AL_TEXT)}
     ASSERT(sdl2allegro_screen <> nil);
+    acquire_screen;
     blit(sdl2allegro_screen, screen, 0, 0, 0, 0, sdl2allegro_screen.w, sdl2allegro_screen.h);
     res := show_video_bitmap(screen);
-    //ASSERT(res = 0);
-{$ENDIF}
+    release_screen;
+//    ASSERT(res = 0);
   end;
 
   function SDL_GL_CreateContext(window: PSDL_Window): TSDL_GLContext;
@@ -840,8 +810,11 @@ implementation
 
   function SDL_PushEvent(event: PSDL_Event): SInt32;
   begin
-    e_LogWriteln('SDL_PushEvent');
-    result := 0
+    result := 1;
+    case event.type_ of
+      SDL_QUITEV: quit := True;
+      else ASSERT(FALSE); result := 0
+    end
   end;
 
   function allegro_to_sdl_scancode (x: Integer): Integer;
@@ -928,9 +901,18 @@ implementation
   function SDL_PollEvent(event: PSDL_Event): SInt32;
     var alscan: Integer;
   begin
-    //e_LogWriteln('SDL_PollEvent');
-    poll_keyboard;
     result := 0;
+
+    if quit then
+    begin
+      quit := False;
+      event.type_ := SDL_QUITEV;
+      event.quit.timestamp := ticks;
+      result := 1;
+      Exit
+    end;
+
+    poll_keyboard;
     if not IsEmptyKeyboard then
     begin
       alscan := NextScancode;
@@ -938,18 +920,19 @@ implementation
         event.type_ := SDL_KEYDOWN
       else
         event.type_ := SDL_KEYUP;
-      event.key.timestamp := 0;
+      event.key.timestamp := ticks;
       event.key.windowID := 0;
-      (* df not use it?
+      (**** df not use it?
       if alscan and $80 = 0 then
         event.key.state := SDL_PRESSED
       else
         event.key.state := SDL_RELEASED;
-      *)
+      ****)
       event.key.keysym.scancode := allegro_to_sdl_scancode(alscan);
       event.key.keysym.sym := 0; (* df not use it? *)
       event.key.keysym._mod := 0; (* df not use it? *)
-      result := 1
+      result := 1;
+      Exit
     end
   end;
 
@@ -963,6 +946,12 @@ implementation
 
 (********** SDL **********)
 
+  procedure AllegroQuitCallback; cdecl;
+  begin
+    quit := True
+  end;
+  procedure AllegroQuitCallbackEND; begin end;
+
   function SDL_SetHint( const name: PChar; const value: PChar) : boolean;
   begin
     e_LogWritefln('SDL_SetHint %s %s', [name, value]);
@@ -975,16 +964,30 @@ implementation
     result := allegro_error;
   end;
 
-  function SDL_Init(flags: UInt32): SInt32;
+{$IFDEF GO32V2}
+  (* HACK: allegro crashes while init without this *)
+  var
+    __crt0_argv: PPchar; cvar; external;
+    myargv: array [0..255] of Pchar;
+
+  procedure FIX_ARGV;
   begin
-    e_LogWritefln('SDL_Init %u', [flags]);
-    result := -1;
     __crt0_argv := @myargv[0];
     myargv[0] := PChar(ParamStr(0));
     e_LogWritefln('argv[0] = %s', [myargv[0]]);
+  end;
+{$ENDIF}
+
+  function SDL_Init(flags: UInt32): SInt32;
+  begin
+    e_LogWritefln('SDL_Init %u', [flags]);
+    result := -1;
+    {$IFDEF GO32V2}
+      FIX_ARGV;
+    {$ENDIF}
     if allegro_init = 0 then
     begin
-      e_LogWriteln('SDL_Init inited! ' + ParamStr(0) + ' tickssize=' + IntToStr(sizeof(keyring)) );
+      e_LogWriteln('Allegro Init: ok');
       {$IFDEF GO32V2}
         (* without this df dies with fire when swapped *)
         lock_data(ticks, sizeof(ticks));
@@ -993,12 +996,15 @@ implementation
         lock_data(keyend, sizeof(keyend));
         lock_data(keyring, sizeof(keyring));
         lock_code(@KeyboardWatcher, PtrUInt(@KeyboardWatcherEND) - PtrUInt(@KeyboardWatcher));
+        lock_data(quit, sizeof(quit));
+        lock_code(@AllegroQuitCallback, PtrUInt(@AllegroQuitCallbackEND) - PtrUInt(@AllegroQuitCallback));
       {$ENDIF}
       install_timer;
       install_keyboard;
       keyboard_lowlevel_callback := KeyboardWatcher;
       set_keyboard_rate(0, 0);
       install_int_ex(AllegroTimerCallback, MSEC_TO_TIMER(1));
+      set_close_button_callback(AllegroQuitCallback);
       result := 0
     end
   end;
@@ -1006,6 +1012,7 @@ implementation
   procedure SDL_Quit;
   begin
     e_LogWriteln('SDL_Quit');
+    set_close_button_callback(nil);
     remove_keyboard;
     remove_timer;
     {$IFDEF GO32V2}
@@ -1015,7 +1022,8 @@ implementation
       unlock_data(keyend, sizeof(keyend));
       unlock_data(keyring, sizeof(keyring));
       unlock_code(@KeyboardWatcher, PtrUInt(@KeyboardWatcherEND) - PtrUInt(@KeyboardWatcher));
+      unlock_data(quit, sizeof(quit));
+      unlock_code(@AllegroQuitCallback, PtrUInt(@AllegroQuitCallbackEND) - PtrUInt(@AllegroQuitCallback));
     {$ENDIF}
     allegro_exit
   end;
-