DEADSOFTWARE

df now can be comiled for go32v2
[d2df-sdl.git] / src / shared / utils.pas
index d0a0ac53375a5b563b46cdfe99be12a61b5eec5c..641cae7ddf44bc4d36a1360e0d3e6bd46394ace1 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C)  DooM 2D:Forever Developers
+(* Copyright (C)  Doom 2D: Forever Developers
  *
  * 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
@@ -22,6 +22,11 @@ uses
   SysUtils, Classes;
 
 
+// ////////////////////////////////////////////////////////////////////////// //
+type
+  SSArray = array of ShortString;
+
+
 // ////////////////////////////////////////////////////////////////////////// //
 type
   TUtf8DecoderFast = packed record
@@ -76,15 +81,15 @@ function isWadPath (const fn: AnsiString): Boolean;
 function addWadExtension (const fn: AnsiString): AnsiString;
 
 // convert number to strig with nice commas
-function Int64ToStrComma (i: Int64): AnsiString;
+function int64ToStrComma (i: Int64): AnsiString;
 
-function UpCase1251 (ch: Char): Char;
-function LoCase1251 (ch: Char): Char;
+function upcase1251 (ch: AnsiChar): AnsiChar; inline;
+function locase1251 (ch: AnsiChar): AnsiChar; inline;
 
 function toLowerCase1251 (const s: AnsiString): AnsiString;
 
 // `true` if strings are equal; ignoring case for cp1251
-function StrEquCI1251 (const s0, s1: AnsiString): Boolean;
+function strEquCI1251 (const s0, s1: AnsiString): Boolean;
 
 function utf8Valid (const s: AnsiString): Boolean;
 
@@ -95,6 +100,9 @@ function utf8to1251 (s: AnsiString): AnsiString;
 // nobody cares about shitdoze, so i'll use the same code path for it
 function findFileCI (var pathname: AnsiString; lastIsDir: Boolean=false): Boolean;
 
+// return fixed AnsiString or empty AnsiString
+function findDiskWad (fname: AnsiString): AnsiString;
+
 // they throws
 function openDiskFileRO (pathname: AnsiString): TStream;
 function createDiskFile (pathname: AnsiString): TStream;
@@ -157,7 +165,9 @@ function nmin (a, b: Int64): Int64; inline; overload;
 function nmin (a, b: UInt64): UInt64; inline; overload;
 function nmin (a, b: Single): Single; inline; overload;
 function nmin (a, b: Double): Double; inline; overload;
+{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
 function nmin (a, b: Extended): Extended; inline; overload;
+{$ENDIF}
 
 function nmax (a, b: Byte): Byte; inline; overload;
 function nmax (a, b: ShortInt): ShortInt; inline; overload;
@@ -169,8 +179,9 @@ function nmax (a, b: Int64): Int64; inline; overload;
 function nmax (a, b: UInt64): UInt64; inline; overload;
 function nmax (a, b: Single): Single; inline; overload;
 function nmax (a, b: Double): Double; inline; overload;
+{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
 function nmax (a, b: Extended): Extended; inline; overload;
-
+{$ENDIF}
 function nclamp (v, a, b: Byte): Byte; inline; overload;
 function nclamp (v, a, b: ShortInt): ShortInt; inline; overload;
 function nclamp (v, a, b: Word): Word; inline; overload;
@@ -181,8 +192,9 @@ function nclamp (v, a, b: Int64): Int64; inline; overload;
 function nclamp (v, a, b: UInt64): UInt64; inline; overload;
 function nclamp (v, a, b: Single): Single; inline; overload;
 function nclamp (v, a, b: Double): Double; inline; overload;
+{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
 function nclamp (v, a, b: Extended): Extended; inline; overload;
-
+{$ENDIF}
 
 type
   TFormatStrFCallback = procedure (constref buf; len: SizeUInt);
@@ -532,25 +544,25 @@ var
     if (code < 0) or (code > $10FFFF) then begin result := '?'; exit; end;
     if (code <= $7f) then
     begin
-      result := Char(code and $ff);
+      result := AnsiChar(code and $ff);
     end
     else if (code <= $7FF) then
     begin
-      result := Char($C0 or (code shr 6));
-      result += Char($80 or (code and $3F));
+      result := AnsiChar($C0 or (code shr 6));
+      result += AnsiChar($80 or (code and $3F));
     end
     else if (code <= $FFFF) then
     begin
-      result := Char($E0 or (code shr 12));
-      result += Char($80 or ((code shr 6) and $3F));
-      result += Char($80 or (code and $3F));
+      result := AnsiChar($E0 or (code shr 12));
+      result += AnsiChar($80 or ((code shr 6) and $3F));
+      result += AnsiChar($80 or (code and $3F));
     end
     else if (code <= $10FFFF) then
     begin
-      result := Char($F0 or (code shr 18));
-      result += Char($80 or ((code shr 12) and $3F));
-      result += Char($80 or ((code shr 6) and $3F));
-      result += Char($80 or (code and $3F));
+      result := AnsiChar($F0 or (code shr 18));
+      result += AnsiChar($80 or ((code shr 12) and $3F));
+      result += AnsiChar($80 or ((code shr 6) and $3F));
+      result += AnsiChar($80 or (code and $3F));
     end
     else
     begin
@@ -801,7 +813,7 @@ var
   ext: AnsiString;
 begin
   ext := getFilenameExt(fn);
-  result := StrEquCI1251(ext, '.wad') or StrEquCI1251(ext, '.pk3') or StrEquCI1251(ext, '.zip');
+  result := StrEquCI1251(ext, '.wad') or StrEquCI1251(ext, '.pk3') or StrEquCI1251(ext, '.zip') or StrEquCI1251(ext, '.dfz');
 end;
 
 
@@ -827,7 +839,7 @@ begin
       if (pos-4 > 1) and (fn[pos-4] = '.') and ((fn[pos+1] = '\') or (fn[pos+1] = '/')) then
       begin
         s := Copy(fn, pos-4, 4);
-        if StrEquCI1251(s, '.wad') or StrEquCI1251(s, '.pk3') or StrEquCI1251(s, '.zip') then
+        if StrEquCI1251(s, '.wad') or StrEquCI1251(s, '.pk3') or StrEquCI1251(s, '.zip') or StrEquCI1251(s, '.dfz') then
         begin
           result := true;
           exit;
@@ -839,7 +851,7 @@ begin
 end;
 
 
-function Int64ToStrComma (i: Int64): AnsiString;
+function int64ToStrComma (i: Int64): AnsiString;
 var
   f: Integer;
 begin
@@ -852,7 +864,7 @@ begin
 end;
 
 
-function UpCase1251 (ch: Char): Char;
+function upcase1251 (ch: AnsiChar): AnsiChar; inline;
 begin
   if ch < #128 then
   begin
@@ -876,7 +888,7 @@ begin
 end;
 
 
-function LoCase1251 (ch: Char): Char;
+function locase1251 (ch: AnsiChar): AnsiChar; inline;
 begin
   if ch < #128 then
   begin
@@ -900,7 +912,7 @@ begin
 end;
 
 
-function StrEquCI1251 (const s0, s1: AnsiString): Boolean;
+function strEquCI1251 (const s0, s1: AnsiString): Boolean;
 var
   i: Integer;
 begin
@@ -986,7 +998,7 @@ const
   );
 
 
-function decodeUtf8Char (s: AnsiString; var pos: Integer): char;
+function decodeUtf8Char (s: AnsiString; var pos: Integer): AnsiChar;
 var
   b, c: Integer;
 begin
@@ -1004,7 +1016,7 @@ begin
 
   b := Byte(s[pos]);
   Inc(pos);
-  if b < $80 then begin result := char(b); exit; end;
+  if b < $80 then begin result := AnsiChar(b); exit; end;
 
   // mask out unused bits
        if (b and $FE) = $FC then b := b and $01
@@ -1025,7 +1037,7 @@ begin
   end;
 
   // done, try 1251
-  for c := 128 to 255 do if uni2wint[c] = b then begin result := char(c and $FF); exit; end;
+  for c := 128 to 255 do if uni2wint[c] = b then begin result := AnsiChar(c and $FF); exit; end;
   // alas
 end;
 
@@ -1117,6 +1129,34 @@ begin
 end;
 
 
+const fileExtensions: array [0..6] of AnsiString = ('.wad', '.dfzip', '.dfwad', '.pk3', '.pak', '.zip', '.dfz');
+
+function findDiskWad (fname: AnsiString): AnsiString;
+var
+  origExt: AnsiString = '';
+  newExt: AnsiString = '';
+begin
+  result := '';
+  //writeln('findDiskWad00: fname=<', fname, '>');
+  if (findFileCI(fname)) then begin result := fname; exit; end;
+  origExt := getFilenameExt(fname);
+  fname := forceFilenameExt(fname, '');
+  //writeln(' findDiskWad01: fname=<', fname, '>; origExt=<', origExt, '>');
+  for newExt in fileExtensions do
+  begin
+    //writeln(' findDiskWad02: fname=<', fname, '>; origExt=<', origExt, '>; newExt=<', newExt, '>');
+    if (StrEquCI1251(newExt, origExt)) then
+    begin
+      //writeln('   SKIP');
+      continue;
+    end;
+    result := fname+newExt;
+    if (findFileCI(result)) then exit;
+  end;
+  result := '';
+end;
+
+
 function openDiskFileRO (pathname: AnsiString): TStream;
 begin
   if not findFileCI(pathname) then raise Exception.Create('can''t open file "'+pathname+'"');
@@ -1181,7 +1221,7 @@ end;
 
 function checkSign (st: TStream; const sign: AnsiString): Boolean;
 var
-  buf: packed array[0..7] of Char;
+  buf: packed array[0..7] of AnsiChar;
   f: Integer;
 begin
   result := false;
@@ -1316,7 +1356,9 @@ function nmin (a, b: Int64): Int64; inline; overload; begin if (a < b) then resu
 function nmin (a, b: UInt64): UInt64; inline; overload; begin if (a < b) then result := a else result := b; end;
 function nmin (a, b: Single): Single; inline; overload; begin if (a < b) then result := a else result := b; end;
 function nmin (a, b: Double): Double; inline; overload; begin if (a < b) then result := a else result := b; end;
+{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
 function nmin (a, b: Extended): Extended; inline; overload; begin if (a < b) then result := a else result := b; end;
+{$ENDIF}
 
 function nmax (a, b: Byte): Byte; inline; overload; begin if (a > b) then result := a else result := b; end;
 function nmax (a, b: ShortInt): ShortInt; inline; overload; begin if (a > b) then result := a else result := b; end;
@@ -1328,7 +1370,9 @@ function nmax (a, b: Int64): Int64; inline; overload; begin if (a > b) then resu
 function nmax (a, b: UInt64): UInt64; inline; overload; begin if (a > b) then result := a else result := b; end;
 function nmax (a, b: Single): Single; inline; overload; begin if (a > b) then result := a else result := b; end;
 function nmax (a, b: Double): Double; inline; overload; begin if (a > b) then result := a else result := b; end;
+{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
 function nmax (a, b: Extended): Extended; inline; overload; begin if (a > b) then result := a else result := b; end;
+{$ENDIF}
 
 function nclamp (v, a, b: Byte): Byte; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
 function nclamp (v, a, b: ShortInt): ShortInt; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
@@ -1340,14 +1384,54 @@ function nclamp (v, a, b: Int64): Int64; inline; overload; begin if (v < a) then
 function nclamp (v, a, b: UInt64): UInt64; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
 function nclamp (v, a, b: Single): Single; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
 function nclamp (v, a, b: Double): Double; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
+{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
 function nclamp (v, a, b: Extended): Extended; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
-
+{$ENDIF}
 
 // ////////////////////////////////////////////////////////////////////////// //
 {$IFDEF WINDOWS}
 function snprintf (buf: PAnsiChar; bufsize: SizeUInt; const fmt: PAnsiChar): SizeUInt; cdecl; varargs; external 'msvcrt.dll' name '_snprintf';
 {$ELSE}
+  {$IFDEF GO32V2}
+
+function snprintf (buf: PAnsiChar; bufsize: SizeUInt; const fmt: PAnsiChar): SizeUInt;
+begin
+  {$WARNING snprintf not implemented!}
+  buf[0] := #0;
+  result := 0
+end;
+
+function snprintf (buf: PAnsiChar; bufsize: SizeUInt; const fmt: PAnsiChar; x: LongInt): SizeUInt; overload;
+begin
+  {$WARNING snprintf+longint not implemented!}
+  buf[0] := #0;
+  result := 0
+end;
+
+function snprintf (buf: PAnsiChar; bufsize: SizeUInt; const fmt: PAnsiChar; x: PAnsiChar): SizeUInt; overload;
+begin
+  {$WARNING snprintf+string not implemented!}
+  buf[0] := #0;
+  result := 0
+end;
+
+function snprintf (buf: PAnsiChar; bufsize: SizeUInt; const fmt: PAnsiChar; x: Char): SizeUInt; overload;
+begin
+  {$WARNING snprintf+char not implemented!}
+  buf[0] := #0;
+  result := 0
+end;
+
+function snprintf (buf: PAnsiChar; bufsize: SizeUInt; const fmt: PAnsiChar; x: Double): SizeUInt; overload;
+begin
+  {$WARNING snprintf+double not implemented!}
+  buf[0] := #0;
+  result := 0
+end;
+
+  {$ELSE}
 function snprintf (buf: PAnsiChar; bufsize: SizeUInt; const fmt: PAnsiChar): SizeUInt; cdecl; varargs; external 'libc' name 'snprintf';
+  {$ENDIF}
 {$ENDIF}