X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fshared%2Futils.pas;h=89ecb9097fa605ac105f6b1e9cb4b5d6409f39ce;hb=a8ae9a0f86f53daa34053a6fd142935594a8da68;hp=59a49f251dbb3b927cfea195b442f38ab3656ae8;hpb=e4b651a876eccee3cdc7f96cef3203db81db369b;p=d2df-sdl.git diff --git a/src/shared/utils.pas b/src/shared/utils.pas index 59a49f2..89ecb90 100644 --- a/src/shared/utils.pas +++ b/src/shared/utils.pas @@ -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 @@ -100,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; @@ -162,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; @@ -174,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; @@ -186,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); @@ -266,9 +273,15 @@ procedure ZeroMemory (Dest: Pointer; Len: LongWord); inline; implementation -uses - xstreams; + uses + xstreams, StrUtils, e_Log; + const + {$IFDEF GO32V2} + DirSep = '\'; + {$ELSE} + DirSep = '/'; + {$ENDIF} // ////////////////////////////////////////////////////////////////////////// // procedure CopyMemory (Dest: Pointer; Src: Pointer; Len: LongWord); inline; @@ -751,7 +764,7 @@ var pos: Integer; ch: AnsiChar; begin - if (Length(fn) = 0) then begin result := './'; exit; end; + if (Length(fn) = 0) then begin result := '.' + DirSep; exit; end; if (fn[Length(fn)] = '/') or (fn[Length(fn)] = '\') then begin result := fn; exit; end; pos := Length(fn); while (pos > 0) do @@ -760,7 +773,7 @@ begin if (ch = '/') or (ch = '\') then begin result := Copy(fn, 1, pos); exit; end; Dec(pos); end; - result := './'; // no path -> current dir + result := '.' + DirSep; // no path -> current dir end; @@ -787,7 +800,7 @@ begin pos := 1; while (pos <= Length(fn)) and ((fn[pos] = '/') or (fn[pos] = '\')) do Inc(pos); result := path; - if (Length(result) > 0) and ((result[Length(result)] <> '/') and (result[Length(result)] <> '\')) then result += '/'; + if (Length(result) > 0) and ((result[Length(result)] <> '/') and (result[Length(result)] <> '\')) then result += DirSep; if (pos <= Length(fn)) then begin result += Copy(fn, pos, Length(fn)-pos+1); @@ -796,7 +809,7 @@ begin begin Delete(result, Length(result), 1); end; - if (fn[Length(fn)] = '/') or (fn[Length(fn)] = '\') then result += '/'; + if (fn[Length(fn)] = '/') or (fn[Length(fn)] = '\') then result += DirSep; end; end; @@ -806,7 +819,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; @@ -832,7 +845,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; @@ -1069,7 +1082,7 @@ var begin npt := pathname; result := (length(npt) > 0); - if (length(npt) > 0) and ((npt[1] = '/') or (npt[1] = '\')) then newname := '/'; + if (length(npt) > 0) and ((npt[1] = '/') or (npt[1] = '\')) then newname := DirSep; while length(npt) > 0 do begin // remove trailing slashes @@ -1085,7 +1098,7 @@ begin // remove trailing slashes again while (length(npt) > 0) and ((npt[1] = '/') or (npt[1] = '\')) do Delete(npt, 1, 1); wantdir := lastIsDir or (length(npt) > 0); // do we want directory here? - //writeln(Format('npt=[%s]; newname=[%s]; curname=[%s]; wantdir=%d', [npt, newname, curname, Integer(wantdir)])); + //e_LogWritefln('npt=[%s]; newname=[%s]; curname=[%s]; wantdir=%d', [npt, newname, curname, Integer(wantdir)]); // try the easiest case first attr := FileGetAttr(newname+curname); if attr <> -1 then @@ -1094,11 +1107,11 @@ begin begin // i found her! newname := newname+curname; - if wantdir then newname := newname+'/'; + if wantdir then newname := newname + DirSep; continue; end; end; - //writeln(Format('npt=[%s]; newname=[%s]; curname=[%s]; wantdir=%d', [npt, newname, curname, Integer(wantdir)])); + //e_LogWritefLn('npt=[%s]; newname=[%s]; curname=[%s]; wantdir=%d', [npt, newname, curname, Integer(wantdir)]); // alas, either not found, or invalid attributes foundher := false; try @@ -1108,7 +1121,7 @@ begin begin // i found her! newname := newname+sr.name; - if wantdir then newname := newname+'/'; + if wantdir then newname := newname + DirSep; foundher := true; break; end; @@ -1122,8 +1135,52 @@ begin end; +(** Replace slashes to backslashes for DOS **) +function FixFileName (filename: AnsiString): AnsiString; +begin + {$IFDEF GO32V2} + Result := StringReplace(filename, '/', '\', [rfReplaceAll, rfIgnoreCase]) + {$ELSE} + Result := filename + {$ENDIF} +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 := ''; +{$IFDEF GO32V2} + // FIXIT: it didn't work under MSDOS for some reason, so i just cut extension replacement + result := FixFileName(fname); +{$ELSE} + //e_LogWriteLn('findDiskWad00: fname=<' + fname + '>'); + if (findFileCI(fname)) then begin result := fname; exit; end; + origExt := getFilenameExt(fname); + fname := forceFilenameExt(fname, ''); + //e_LogWriteLn(' findDiskWad01: fname=<' + fname + '>; origExt=<' + origExt + '>'); + for newExt in fileExtensions do + begin + //e_LogWriteLn(' findDiskWad02: fname=<' + fname + '>; origExt=<' + origExt + '>; newExt=<' + newExt + '>'); + if (StrEquCI1251(newExt, origExt)) then + begin + //e_LogWriteLn(' SKIP'); + continue; + end; + result := fname+newExt; + if (findFileCI(result)) then exit; + end; + result := ''; +{$ENDIF} +end; + function openDiskFileRO (pathname: AnsiString): TStream; begin + pathname := FixFileName(pathname); if not findFileCI(pathname) then raise Exception.Create('can''t open file "'+pathname+'"'); result := TFileStream.Create(pathname, fmOpenRead or {fmShareDenyWrite}fmShareDenyNone); end; @@ -1132,6 +1189,7 @@ function createDiskFile (pathname: AnsiString): TStream; var path: AnsiString; begin + pathname := FixFileName(pathname); path := ExtractFilePath(pathname); if length(path) > 0 then begin @@ -1321,7 +1379,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; @@ -1333,7 +1393,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; @@ -1345,14 +1407,19 @@ 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; cdecl; varargs; external; + {$ELSE} function snprintf (buf: PAnsiChar; bufsize: SizeUInt; const fmt: PAnsiChar): SizeUInt; cdecl; varargs; external 'libc' name 'snprintf'; + {$ENDIF} {$ENDIF}