DEADSOFTWARE

Holmes now require "data/flexui.wad" (it is not fatal to not have this file; Holmes...
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Tue, 3 Oct 2017 19:15:53 +0000 (22:15 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Tue, 3 Oct 2017 19:16:22 +0000 (22:16 +0300)
src/flexui/fui_ctls.pas
src/flexui/fui_style.pas
src/flexui/fui_wadread.pas [new file with mode: 0644]
src/game/Doom2DF.lpr
src/game/g_holmes.pas
src/game/g_main.pas
src/sfs/sfsZipFS.pas
src/shared/utils.pas
src/shared/wadreader.pas

index 797c73fa5ba87a81a31fa5f0a5f7a49e0d0f0842..ef5ab367e43e2bd11e0d8fe558c20dfb2fca4f52 100644 (file)
@@ -3040,6 +3040,10 @@ begin
       mDefSize.w += ww+mShadowSize;
       mDefSize.h += mShadowSize;
     end;
+  end
+  else
+  begin
+    ods := TLaySize.Create(0, 0); // fpc is dumb!
   end;
   inherited layPrepare();
   if (not mSkipLayPrepare) then mDefSize := ods;
index 31bbf2151767023e7526f184db7e9091cd34504a..1125a265acaa20929de9e4b37cfaccd7f8a10026 100644 (file)
@@ -122,29 +122,15 @@ function uiFindStyle (const stname: AnsiString): TUIStyle;
 
 implementation
 
+uses
+  fui_wadread;
+
 
-// ////////////////////////////////////////////////////////////////////////// //
-const
-  defaultStyleStr =
-    'default {'#10+
-    '  back-color: #008;'#10+
-    '  #active: { text-color: #fff; hot-color: #f00; switch-color: #fff; frame-color: #fff; frame-text-color: #fff; frame-icon-color: #0f0; }'#10+
-    '  #inactive: { text-color: #aaa; hot-color: #a00; switch-color: #aaa; frame-color: #aaa; frame-text-color: #aaa; frame-icon-color: #0a0; }'#10+
-    '  #disabled: { text-color: #666; hot-color: #600; switch-color: #666; frame-color: #888; frame-text-color: #888; frame-icon-color: #080; }'#10+
-    '  @window: { #inactive(#active): { darken: 128; } }'#10+
-    '  @button: { back-color: #999; text-color: #000; hot-color: #600; #active: { back-color: #fff; hot-color: #c00; } #disabled: { back-color: #444; text-color: #333; hot-color: #333; } }'#10+
-    '  @label: { #inactive(#active); }'#10+
-    '  @static: { text-color: #ff0; #inactive(#active); }'#10+
-    '  @box: { #inactive(#active); }'#10+
-    '  @switchbox: { #active: { back-color: #080; } #inactive: { switch-color: #fff; } }'#10+
-    '  @checkbox(@switchbox): {}'#10+
-    '  @radiobox(@switchbox): {}'#10+
-    '}'#10+
-    '';
 var
   styles: array of TUIStyle = nil;
 
 
+{
 function createDefaultStyle (): TUIStyle;
 var
   st: TStream;
@@ -158,6 +144,7 @@ begin
     FreeAndNil(st);
   end;
 end;
+}
 
 
 function uiFindStyle (const stname: AnsiString): TUIStyle;
@@ -169,10 +156,13 @@ begin
     for stl in styles do if (strEquCI1251(stl.mId, stname)) then begin result := stl; exit; end;
   end;
   for stl in styles do if (strEquCI1251(stl.mId, 'default')) then begin result := stl; exit; end;
+  raise Exception.Create('FlexUI FATAL: no "default" style in stylesheet');
+  {
   stl := createDefaultStyle();
   SetLength(styles, Length(styles)+1);
   styles[High(styles)] := stl;
   result := stl;
+  }
 end;
 
 
@@ -180,7 +170,8 @@ procedure uiLoadStyles (const fname: AnsiString);
 var
   st: TStream;
 begin
-  st := openDiskFileRO(fname);
+  st := fuiOpenFile(fname);
+  if (st = nil) then raise Exception.Create('FlexUI file '''+fname+''' not found!');
   try
     uiLoadStyles(st);
   finally
@@ -224,9 +215,12 @@ begin
   end;
   // we should have "default" style
   for f := 0 to High(styles) do if (strEquCI1251(styles[f].mId, 'default')) then exit;
+  raise Exception.Create('FlexUI FATAL: no "default" style in stylesheet');
+  {
   stl := createDefaultStyle();
   SetLength(styles, Length(styles)+1);
   styles[High(styles)] := stl;
+  }
 end;
 
 
diff --git a/src/flexui/fui_wadread.pas b/src/flexui/fui_wadread.pas
new file mode 100644 (file)
index 0000000..44f9d87
--- /dev/null
@@ -0,0 +1,245 @@
+(* coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
+ * Understanding is not required. Only obedience.
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+{.$DEFINE FUI_WADREAD_DEBUG}
+unit fui_wadread;
+
+interface
+
+uses
+  SysUtils, Classes;
+
+
+function fuiAddWad (const wadfile: AnsiString): Boolean;
+
+// returns `nil` if file wasn't found
+function fuiOpenFile (const fname: AnsiString): TStream;
+
+
+var
+  fuiDiskFirst: Boolean = true;
+
+
+implementation
+
+uses
+  sfs, utils;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+type
+  TFUIWad = class
+  public
+    wadname: AnsiString;
+    iter: TSFSFileList;
+
+  public
+    constructor Create (const awadname: AnsiString);
+    destructor Destroy (); override;
+
+    // returns `nil` if file wasn't found
+    function openFile (const fname: AnsiString): TStream;
+  end;
+
+
+constructor TFUIWad.Create (const awadname: AnsiString);
+{$IFDEF FUI_WADREAD_DEBUG}
+var
+  f: Integer;
+{$ENDIF}
+begin
+  if not SFSAddDataFile(awadname, true) then raise Exception.Create('cannot open wad');
+  wadname := awadname;
+  iter := SFSFileList(awadname);
+  {$IFDEF FUI_WADREAD_DEBUG}
+  if (iter <> nil) then
+  begin
+    writeln('==== ', awadname, ' ====');
+    for f := 0 to iter.Count-1 do
+    begin
+      if (iter.Files[f] = nil) then continue;
+      writeln('  ', f, ': ', iter.Files[f].path, iter.Files[f].name);
+    end;
+    writeln('========');
+  end;
+  {$ENDIF}
+end;
+
+
+destructor TFUIWad.Destroy ();
+begin
+  wadname := '';
+  FreeAndNil(iter);
+  inherited;
+end;
+
+
+function TFUIWad.openFile (const fname: AnsiString): TStream;
+var
+  f: Integer;
+  fi: TSFSFileInfo;
+begin
+  result := nil;
+  if (iter = nil) then exit;
+  // backwards, due to possible similar names and such
+  for f := iter.Count-1 downto 0 do
+  begin
+    fi := iter.Files[f];
+    if (fi = nil) then continue;
+    if (StrEquCI1251(fi.path+fi.name, fname)) then
+    begin
+      try
+        result := iter.volume.OpenFileByIndex(f);
+      except
+        result := nil;
+      end;
+      if (result <> nil) then exit;
+    end;
+  end;
+end;
+
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+function getExeDataPath (): AnsiString;
+begin
+  result := getFilenamePath(ParamStr(0))+'data/';
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+var
+  wadlist: array of TFUIWad = nil;
+
+
+function fuiAddWad (const wadfile: AnsiString): Boolean;
+var
+  exepath: AnsiString;
+  awadname: AnsiString;
+  f, c: Integer;
+  wad: TFUIWad;
+begin
+  result := false;
+
+  // find disk file
+  if (Length(wadfile) = 0) then exit;
+
+  if (Length(wadfile) > 2) and (wadfile[1] = '.') and ((wadfile[2] = '/') or (wadfile[2] = '\')) then
+  begin
+    awadname := wadfile;
+    awadname := findDiskWad(awadname);
+    if (Length(awadname) = 0) then
+    begin
+      writeln('WARNING: FlexUI WAD ''', wadfile, ''' not found');
+      exit;
+    end;
+  end
+  else
+  begin
+    exepath := getExeDataPath();
+    awadname := exepath+wadfile;
+    awadname := findDiskWad(awadname);
+    if (Length(awadname) = 0) then
+    begin
+      awadname := wadfile;
+      awadname := findDiskWad(awadname);
+      if (Length(awadname) = 0) then
+      begin
+        writeln('WARNING: FlexUI WAD ''', exepath+wadfile, ''' not found');
+        exit;
+      end;
+    end;
+  end;
+
+  // check if we already have this file opened
+  for f := 0 to High(wadlist) do
+  begin
+    wad := wadlist[f];
+    if (strEquCI1251(awadname, wad.wadname)) then
+    begin
+      // i found her! move it to the bottom of the list, so it will be checked first
+      for c := f+1 to High(wadlist) do wadlist[c-1] := wadlist[c];
+      wadlist[High(wadlist)] := wad;
+      exit;
+    end;
+  end;
+
+  // create new wad file
+  try
+    wad := TFUIWad.Create(awadname);
+  except // sorry
+    writeln('WARNING: error opening FlexUI WAD ''', wadfile, '''');
+    exit;
+  end;
+
+  SetLength(wadlist, Length(wadlist)+1);
+  wadlist[High(wadlist)] := wad;
+  {$IFDEF FUI_WADREAD_DEBUG}writeln('FUI: added WAD: ''', wad.wadname, '''');{$ENDIF}
+
+  result := true;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// returns `nil` if file wasn't found
+function tryDiskFile (const fname: AnsiString): TStream;
+var
+  fn: AnsiString;
+begin
+  fn := getExeDataPath()+fname;
+  try
+    result := openDiskFileRO(fn);
+    {$IFDEF FUI_WADREAD_DEBUG}writeln('FUI: opened DISK file: ''', fn, '''');{$ENDIF}
+  except
+    result := nil;
+  end;
+end;
+
+
+// returns `nil` if file wasn't found
+function fuiOpenFile (const fname: AnsiString): TStream;
+var
+  f: Integer;
+begin
+  // disk
+  if (fuiDiskFirst) then
+  begin
+    result := tryDiskFile(fname);
+    if (result <> nil) then exit;
+  end;
+  // wads
+  for f := High(wadlist) downto 0 do
+  begin
+    result := wadlist[f].openFile(fname);
+    if (result <> nil) then
+    begin
+      {$IFDEF FUI_WADREAD_DEBUG}writeln('FUI: opened WAD file: ''', fname, ''' (from ''', wadlist[f].wadname, ''')');{$ENDIF}
+      exit;
+    end;
+  end;
+  // disk
+  if (not fuiDiskFirst) then
+  begin
+    result := tryDiskFile(fname);
+    if (result <> nil) then exit;
+  end;
+  {$IFDEF FUI_WADREAD_DEBUG}writeln('FUI: file: ''', fname, ''' NOT FOUND!');{$ENDIF}
+  result := nil;
+end;
+
+
+end.
index 54df1940ba57a22617baa590dc4cf613a00319df..4d9d2fa429172242dc2b106d38043792b3078958 100644 (file)
@@ -105,6 +105,7 @@ uses
   sdlcarcass in '../flexui/sdlcarcass.pas',
   //sdlstandalone in '../flexui/sdlstandalone.pas',
 
+  fui_wadread in '../flexui/fui_wadread.pas',
   fui_common in '../flexui/fui_common.pas',
   fui_gfx_gl in '../flexui/fui_gfx_gl.pas',
   fui_events in '../flexui/fui_events.pas',
index bcb2cfadb4ed56f09d3816b4121e313213a34b49..965000a29597da84dbbe184d0b29e857e0ab60a2 100644 (file)
@@ -42,6 +42,7 @@ procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer);
 
 
 var
+  g_holmes_imfunctional: Boolean = false;
   g_holmes_enabled: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}false{$ENDIF};
 
 
@@ -1322,6 +1323,7 @@ var
 begin
   if g_Game_IsNet then exit;
   if not g_holmes_enabled then exit;
+  if g_holmes_imfunctional then exit;
 
   holmesInitCommands();
   holmesInitBinds();
@@ -1356,6 +1358,7 @@ var
 begin
   if g_Game_IsNet then exit;
   if not g_holmes_enabled then exit;
+  if g_holmes_imfunctional then exit;
 
   holmesInitCommands();
   holmesInitBinds();
@@ -1433,6 +1436,7 @@ procedure g_Holmes_DrawUI ();
 begin
   if g_Game_IsNet then exit;
   if not g_holmes_enabled then exit;
+  if g_holmes_imfunctional then exit;
   {$IF not DEFINED(HEADLESS)}
   gGfxDoClear := false;
   //if assigned(prerenderFrameCB) then prerenderFrameCB();
@@ -1714,12 +1718,14 @@ end;
 procedure onMouseEvent (var ev: THMouseEvent);
 begin
   if not g_holmes_enabled then exit;
+  if g_holmes_imfunctional then exit;
   g_Holmes_MouseEvent(ev);
 end;
 
 procedure onKeyEvent (var ev: THKeyEvent);
 begin
   if not g_holmes_enabled then exit;
+  if g_holmes_imfunctional then exit;
   g_Holmes_KeyEvent(ev);
 end;
 
index 57f12e98a45349501ccb52fd666817503eae7731..734ae36ff49f1d76f11d66d7930c63d7c81c5908 100644 (file)
@@ -41,8 +41,9 @@ uses
   e_graphics, e_input, g_game, g_console, g_gui,
   e_sound, g_options, g_sound, g_player,
   g_weapons, SysUtils, g_triggers, MAPDEF, g_map,
-  g_menu, g_language, g_net,
-  utils, conbuf, envvars;
+  g_menu, g_language, g_net, g_holmes,
+  utils, conbuf, envvars, fui_wadread, fui_style,
+  xparser;
 
 
 var
@@ -99,13 +100,35 @@ begin
   SDL_StartTextInput();
 {$ENDIF}
 
+{$IFNDEF HEADLESS}
+  if not fuiAddWad('flexui.wad') then
+  begin
+    if not fuiAddWad('./data/flexui.wad') then fuiAddWad('./flexui.wad');
+  end;
+  g_holmes_imfunctional := true;
+  try
+    e_LogWriteln('FlexUI: loading stylesheet...');
+    uiLoadStyles('flexui/widgets.wgs');
+    g_holmes_imfunctional := false;
+  except on e: TParserException do
+    begin
+      writeln('ERROR at (', e.tokLine, ',', e.tokCol, '): ', e.message);
+      //raise;
+    end;
+  else
+    begin
+      //raise;
+    end;
+  end;
+{$ENDIF}
+
   e_WriteLog('Entering SDLMain', TMsgType.Notify);
 
 {$WARNINGS OFF}
   SDLMain();
 {$WARNINGS ON}
 
-{$IFDEF HEADLESS}
+{$IFNDEF HEADLESS}
   SDL_StopTextInput();
 {$ENDIF}
 
index 73263e73d5f7aa5ed563109060a9075760e11afc..bafe55ffb04efd97b9f6b09f45885c826c3ced2d 100644 (file)
@@ -417,7 +417,8 @@ begin
   result :=
     StrEquCI1251(prefix, 'zip') or
     StrEquCI1251(prefix, 'pk3') or
-    StrEquCI1251(prefix, 'dfwad');
+    StrEquCI1251(prefix, 'dfwad') or
+    StrEquCI1251(prefix, 'dfzip');
 end;
 
 procedure TSFSZipVolumeFactory.Recycle (vol: TSFSVolume);
index 59a49f251dbb3b927cfea195b442f38ab3656ae8..73c7274740d204b637a1b5443cb2cd1ea57e2f37 100644 (file)
@@ -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;
@@ -1122,6 +1125,34 @@ begin
 end;
 
 
+const fileExtensions: array [0..5] of AnsiString = ('.wad', '.dfzip', '.dfwad', '.pk3', '.pak', '.zip');
+
+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+'"');
index 09bb5033dcda43c19fac864f90e13649f4d23a6c..1e7a163142b200155c49f8f9ea6d8d0121251110 100644 (file)
@@ -64,9 +64,6 @@ function g_ExtractFilePath (resourceStr: AnsiString): AnsiString;
 function g_ExtractFileName (resourceStr: AnsiString): AnsiString; // without path
 function g_ExtractFilePathName (resourceStr: AnsiString): AnsiString;
 
-// return fixed AnsiString or empty AnsiString
-function findDiskWad (fname: AnsiString): AnsiString;
-
 
 var
   wadoptDebug: Boolean = false;
@@ -79,33 +76,6 @@ uses
   SysUtils, e_log, MAPDEF, xdynrec;
 
 
-function findDiskWad (fname: AnsiString): AnsiString;
-begin
-  result := '';
-  if not findFileCI(fname) then
-  begin
-    //e_WriteLog(Format('findDiskWad: error looking for [%s]', [fname]), MSG_NOTIFY);
-    if StrEquCI1251(ExtractFileExt(fname), '.wad') then
-    begin
-      fname := ChangeFileExt(fname, '.pk3');
-      //e_WriteLog(Format('  looking for [%s]', [fname]), MSG_NOTIFY);
-      if not findFileCI(fname) then
-      begin
-        fname := ChangeFileExt(fname, '.zip');
-        //e_WriteLog(Format('  looking for [%s]', [fname]), MSG_NOTIFY);
-        if not findFileCI(fname) then exit;
-      end;
-    end
-    else
-    begin
-      exit;
-    end;
-  end;
-  //e_WriteLog(Format('findDiskWad: FOUND [%s]', [fname]), MSG_NOTIFY);
-  result := fname;
-end;
-
-
 function normSlashes (s: AnsiString): AnsiString;
 var
   f: Integer;