DEADSOFTWARE

render: move textures loaders to render
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Sun, 20 Jun 2021 11:53:46 +0000 (14:53 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Tue, 29 Jun 2021 09:51:12 +0000 (12:51 +0300)
20 files changed:
src/game/Doom2DF.lpr
src/game/g_game.pas
src/game/g_gui.pas
src/game/g_items.pas
src/game/g_map.pas
src/game/g_menu.pas
src/game/g_monsters.pas
src/game/g_netmsg.pas
src/game/g_player.pas
src/game/g_playermodel.pas
src/game/g_textures.pas
src/game/g_triggers.pas
src/game/g_weapons.pas
src/game/opengl/r_animations.pas
src/game/opengl/r_console.pas
src/game/opengl/r_game.pas
src/game/opengl/r_panel.pas
src/game/opengl/r_player.pas
src/game/opengl/r_playermodel.pas
src/game/opengl/r_textures.pas [new file with mode: 0644]

index 13d80a68c135550367fd68f8290b131028036950..500f7034b7b61fc85ddff1b797ca45c5de0edce7 100644 (file)
@@ -166,6 +166,7 @@ uses
   r_playermodel in 'opengl/r_playermodel.pas',
   r_render in 'opengl/r_render.pas',
   r_texture in 'opengl/r_texture.pas',
+  r_textures in 'opengl/r_textures.pas',
   r_weapons in 'opengl/r_weapons.pas',
   r_window in 'opengl/r_window.pas',
 
index 9c548caf4f6ff14337465df3d362cec8ca043e83..a0f3090746d54008a174c4864b6513d0b10ab19b 100644 (file)
@@ -439,7 +439,7 @@ uses
 {$IFDEF ENABLE_HOLMES}
   g_holmes,
 {$ENDIF}
-  e_res, g_textures, g_window, g_menu, r_render,
+  e_res, g_window, g_menu, r_render, r_textures, r_animations,
   e_input, e_log, g_console, r_console, g_items, g_map, g_panel,
   g_playermodel, g_gfx, g_options, Math,
   g_triggers, g_monsters, e_sound, CONFIG,
index 8e45c5df9e5cfee2c55dff8928cb1dbdfdbf08e8..960ba747cc4f083b5b29019809632ec9242b54cf 100644 (file)
@@ -550,7 +550,7 @@ procedure g_GUI_LoadMenuPos();
 implementation
 
 uses
-  g_textures, g_sound, SysUtils, e_res,
+  g_sound, SysUtils, e_res, r_textures,
   g_game, Math, StrUtils, g_player, g_options, r_playermodel,
   g_map, g_weapons, xdynrec, wadreader;
 
index 6c8041ddd97bfe0ba46c4e2081f5dd1ffd8ab866..c578d2f16a98f291e816fbc568133a399eadd39d 100644 (file)
@@ -91,7 +91,7 @@ implementation
 
 uses
   Math,
-  g_basic, g_sound, g_gfx, g_map,
+  g_basic, g_sound, g_gfx, g_map, r_textures, r_animations,
   g_game, g_triggers, g_console, g_player, g_net, g_netmsg,
   e_log, g_options,
   g_grid, binheap, idpool, utils, xstreams;
index eb9454263364990821dbb6ab0bdd5b4bc4ded22c..a33ceda485c5bef327fed088b944340dc0796151 100644 (file)
@@ -248,7 +248,7 @@ implementation
 uses
   e_input, e_log, e_res, g_items, g_gfx, g_console,
   g_weapons, g_game, g_sound, e_sound, CONFIG,
-  g_options, g_triggers, g_player,
+  g_options, g_triggers, g_player, r_textures, r_animations,
   Math, g_monsters, g_saveload, g_language, g_netmsg,
   sfs, xstreams, hashtable, wadreader,
   ImagingTypes, Imaging, ImagingUtility,
index bca5dbed9f2efa8a557964db5a7702d3662e560c..af62dbad5a1af745fd02e56be0cfb809237610e3 100644 (file)
@@ -43,7 +43,7 @@ var
 implementation
 
 uses
-  g_gui, g_textures, r_graphics, g_game, g_map,
+  g_gui, r_textures, r_graphics, g_game, g_map,
   g_base, g_basic, g_console, g_sound, g_gfx, g_player, g_options, g_weapons,
   e_log, SysUtils, CONFIG, g_playermodel, DateUtils,
   MAPDEF, Math, g_saveload,
index 5824ffe082020edf16f9c29e215005f4e38a789f..d8c3fba04e3a4be5adae33bd8cd43d68d671475e 100644 (file)
@@ -488,7 +488,7 @@ var
 implementation
 
 uses
-  e_log, g_sound, g_gfx, g_player, g_game,
+  e_log, g_sound, g_gfx, g_player, g_game, r_textures, r_animations,
   g_weapons, g_triggers, g_items, g_options,
   g_console, g_map, Math, g_menu, wadreader,
   g_language, g_netmsg, idpool, utils, xstreams;
index c49ffaa6aa6ae4a192465faad13ef82a7e3e3973..c699c4b53ccbea82609e6a47e6c2898be4b9988e 100644 (file)
@@ -276,7 +276,7 @@ function IsValidFilePath(const S: String): Boolean;
 implementation
 
 uses
-  Math, ENet, e_input, e_log, g_base, g_basic,
+  Math, ENet, e_input, e_log, g_base, g_basic, r_textures, r_animations,
   g_textures, g_gfx, g_sound, g_console, g_options,
   g_game, g_player, g_map, g_panel, g_items, g_weapons, g_phys, g_gui,
   g_language, g_monsters, g_netmaster, utils, wadreader, MAPDEF;
index 9e410bfd95016f1df3d25c7ef1191127eede250c..b346d3b1e35904b4f689c30ae1e78b29077a740d 100644 (file)
@@ -635,7 +635,7 @@ uses
 {$IFDEF ENABLE_HOLMES}
   g_holmes,
 {$ENDIF}
-  e_log, g_map, g_items, g_console, g_gfx, Math,
+  e_log, g_map, g_items, g_console, g_gfx, Math, r_textures, r_animations,
   g_options, g_triggers, g_menu, g_game, g_grid, e_res,
   wadreader, g_monsters, CONFIG, g_language,
   g_net, g_netmsg,
index b2f57e6c95997ff2835acc80f58380b4ec6827ca..af56f51bbce5cabce54bb8cee797cdbb57e3ce99 100644 (file)
@@ -167,7 +167,7 @@ function  g_PlayerModel_GetGibs(ModelName: String; var Gibs: TGibsArray): Boolea
 implementation
 
 uses
-  g_sound, g_console, SysUtils, g_player, CONFIG,
+  g_sound, g_console, SysUtils, g_player, CONFIG, r_textures, r_animations,
   e_sound, g_options, g_map, Math, e_log, wadreader;
 
 type
index e95fc6d73312eea7fac07bfe042d510896fd9ded..d12a9a24e4ba74789cfbe74fbaa0713e4b0c376f 100644 (file)
@@ -83,656 +83,12 @@ type
     property id: LongWord read mId;
   end;
 
-
-function g_Texture_CreateWAD (var ID: LongWord; const Resource: AnsiString; filterHint: Boolean = False): Boolean;
-function g_Texture_CreateFile (var ID: LongWord; const FileName: AnsiString): Boolean;
-function g_Texture_CreateWADEx (const textureName, Resource: AnsiString; filterHint: Boolean = False): Boolean;
-function g_Texture_CreateFileEx (const textureName, FileName: AnsiString): Boolean;
-function g_Texture_Get (const textureName: AnsiString; var ID: LongWord): Boolean;
-function g_Texture_GetSize (const textureName: AnsiString; var w, h: Integer): Boolean; overload;
-function g_Texture_GetSize (ID: LongWord; var w, h: Integer): Boolean; overload;
-procedure g_Texture_Delete (const textureName: AnsiString);
-procedure g_Texture_DeleteAll ();
-
-function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; const Name: AnsiString; BackAnimation: Boolean=false): Boolean;
-
-function g_Frames_CreateWAD (ID: PDWORD; const Name, Resource: AnsiString; mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
-function g_Frames_CreateFile (ID: PDWORD; const Name, FileName: AnsiString; mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
-function g_Frames_CreateMemory (ID: PDWORD; const Name: AnsiString; pData: Pointer; dataSize: LongInt;
-                                mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
-function g_Frames_Dup (const NewName, OldName: AnsiString): Boolean;
-//function g_Frames_CreateRevert(ID: PDWORD; Name: ShortString; Frames: string): Boolean;
-function g_Frames_Get (out ID: LongWord; const FramesName: AnsiString): Boolean;
-function g_Frames_GetTexture (out ID: LongWord; const FramesName: AnsiString; Frame: Word): Boolean;
-function g_Frames_Exists (const FramesName: AnsiString): Boolean;
-procedure g_Frames_DeleteByName (const FramesName: AnsiString);
-procedure g_Frames_DeleteByID (ID: LongWord);
-procedure g_Frames_DeleteAll ();
-
-procedure DumpTextureNames ();
-
-  type (* private state *)
-    TFrames = record
-      texturesID: array of LongWord;
-      name: AnsiString;
-      frameWidth, frameHeight: Word;
-      used: Boolean;
-    end;
-
-  var (* private state *)
-    framesArray: array of TFrames = nil;
-
 implementation
 
 uses
-  g_game, e_log, g_basic, g_console, wadreader,
+  g_game, e_log, g_basic, g_console, wadreader, r_animations,
   g_language, utils, xstreams;
 
-type
-  _TTexture = record
-    name: AnsiString;
-    id: LongWord;
-    width, height: Word;
-    used: Boolean;
-  end;
-
-var
-  texturesArray: array of _TTexture = nil;
-
-
-const
-  ANIM_SIGNATURE = $4D494E41; // 'ANIM'
-
-
-function allocTextureSlot (): LongWord;
-var
-  f: integer;
-begin
-  for f := 0 to High(texturesArray) do
-  begin
-    if (not texturesArray[f].used) then
-    begin
-      result := f;
-      exit;
-    end;
-  end;
-
-  result := Length(texturesArray);
-  SetLength(texturesArray, result+64);
-  for f := result to High(texturesArray) do
-  begin
-    with texturesArray[f] do
-    begin
-      name := '';
-      id := 0;
-      width := 0;
-      height := 0;
-      used := false;
-    end;
-  end;
-end;
-
-
-function allocFrameSlot (): LongWord;
-var
-  f: integer;
-begin
-  for f := 0 to High(framesArray) do
-  begin
-    if (not framesArray[f].used) then
-    begin
-      result := f;
-      exit;
-    end;
-  end;
-
-  result := Length(framesArray);
-  SetLength(framesArray, result+64);
-  for f := result to High(framesArray) do
-  begin
-    with framesArray[f] do
-    begin
-      texturesID := nil;
-      name := '';
-      frameWidth := 0;
-      frameHeight := 0;
-      used := false;
-    end;
-  end;
-end;
-
-
-// ////////////////////////////////////////////////////////////////////////// //
-function g_Texture_CreateWAD (var ID: LongWord; const Resource: AnsiString; filterHint: Boolean = False): Boolean;
-var
-  WAD: TWADFile;
-  FileName: AnsiString;
-  TextureData: Pointer;
-  ResourceLength: Integer;
-begin
-  result := false;
-  FileName := g_ExtractWadName(Resource);
-
-  WAD := TWADFile.Create;
-  WAD.ReadFile(FileName);
-
-  if WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
-  begin
-    if e_CreateTextureMem(TextureData, ResourceLength, ID, filterHint) then
-      result := true;
-    FreeMem(TextureData)
-  end
-  else
-  begin
-    e_WriteLog(Format('Error loading texture %s', [Resource]), TMsgType.Warning);
-    //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
-  end;
-  WAD.Free();
-end;
-
-
-function g_Texture_CreateFile (var ID: LongWord; const FileName: AnsiString): Boolean;
-begin
-  result := true;
-  if not e_CreateTexture(FileName, ID) then
-  begin
-    e_WriteLog(Format('Error loading texture %s', [FileName]), TMsgType.Warning);
-    result := false;
-  end;
-end;
-
-
-function g_Texture_CreateWADEx (const textureName, Resource: AnsiString; filterHint: Boolean = False): Boolean;
-var
-  WAD: TWADFile;
-  FileName: AnsiString;
-  TextureData: Pointer;
-  find_id: LongWord;
-  ResourceLength: Integer;
-begin
-  FileName := g_ExtractWadName(Resource);
-
-  find_id := allocTextureSlot();
-
-  WAD := TWADFile.Create;
-  WAD.ReadFile(FileName);
-
-  if WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
-  begin
-    result := e_CreateTextureMem(TextureData, ResourceLength, texturesArray[find_id].ID, filterHint);
-    if result then
-    begin
-      e_GetTextureSize(texturesArray[find_id].ID, @texturesArray[find_id].width, @texturesArray[find_id].height);
-      texturesArray[find_id].used := true;
-      texturesArray[find_id].Name := textureName;
-    end;
-    FreeMem(TextureData)
-  end
-  else
-  begin
-    e_WriteLog(Format('Error loading texture %s', [Resource]), TMsgType.Warning);
-    //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
-    result := false;
-  end;
-  WAD.Free();
-end;
-
-
-function g_Texture_CreateFileEx (const textureName, FileName: AnsiString): Boolean;
-var
-  find_id: LongWord;
-begin
-  find_id := allocTextureSlot();
-  result := e_CreateTexture(FileName, texturesArray[find_id].ID);
-  if result then
-  begin
-    texturesArray[find_id].used := true;
-    texturesArray[find_id].Name := textureName;
-    e_GetTextureSize(texturesArray[find_id].ID, @texturesArray[find_id].width, @texturesArray[find_id].height);
-  end
-  else e_WriteLog(Format('Error loading texture %s', [FileName]), TMsgType.Warning);
-end;
-
-
-function g_Texture_Get (const textureName: AnsiString; var id: LongWord): Boolean;
-var
-  a: Integer;
-begin
-  result := false;
-  if (Length(texturesArray) = 0) or (Length(textureName) = 0) then exit;
-  for a := 0 to High(texturesArray) do
-  begin
-    if (StrEquCI1251(texturesArray[a].name, textureName)) then
-    begin
-      id := texturesArray[a].id;
-      result := true;
-      break;
-    end;
-  end;
-  //if not Result then g_ConsoleAdd('Texture '+TextureName+' not found');
-end;
-
-
-function g_Texture_GetSize (const textureName: AnsiString; var w, h: Integer): Boolean; overload;
-var
-  a: Integer;
-begin
-  result := false;
-  w := 0;
-  h := 0;
-  if (Length(texturesArray) = 0) or (Length(textureName) = 0) then exit;
-  for a := 0 to High(texturesArray) do
-  begin
-    if (StrEquCI1251(texturesArray[a].name, textureName)) then
-    begin
-      w := texturesArray[a].width;
-      h := texturesArray[a].height;
-      result := true;
-      break;
-    end;
-  end;
-end;
-
-
-function g_Texture_GetSize (ID: LongWord; var w, h: Integer): Boolean; overload;
-var
-  a: Integer;
-begin
-  result := false;
-  w := 0;
-  h := 0;
-  if (Length(texturesArray) = 0) then exit;
-  for a := 0 to High(texturesArray) do
-  begin
-    if (texturesArray[a].id = ID) then
-    begin
-      w := texturesArray[a].width;
-      h := texturesArray[a].height;
-      result := true;
-      break;
-    end;
-  end;
-end;
-
-
-procedure g_Texture_Delete (const textureName: AnsiString);
-var
-  a: Integer;
-begin
-  if (Length(texturesArray) = 0) or (Length(textureName) = 0) then exit;
-  for a := 0 to High(texturesArray) do
-  begin
-    if (StrEquCI1251(texturesArray[a].name, textureName)) then
-    begin
-      e_DeleteTexture(texturesArray[a].ID);
-      texturesArray[a].used := false;
-      texturesArray[a].name := '';
-      texturesArray[a].id := 0;
-      texturesArray[a].width := 0;
-      texturesArray[a].height := 0;
-    end;
-  end;
-end;
-
-
-procedure g_Texture_DeleteAll ();
-var
-  a: Integer;
-begin
-  for a := 0 to High(texturesArray) do
-  begin
-    if (texturesArray[a].used) then e_DeleteTexture(texturesArray[a].ID);
-  end;
-  texturesArray := nil;
-end;
-
-
-function g_Frames_CreateFile (ID: PDWORD; const Name, FileName: AnsiString;
-                              mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
-var
-  a: Integer;
-  find_id: LongWord;
-begin
-  result := false;
-
-  find_id := allocFrameSlot();
-
-  if (mCount <= 2) then BackAnimation := false;
-
-  if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
-  else SetLength(framesArray[find_id].TexturesID, mCount);
-
-  for a := 0 to mCount-1 do
-  begin
-    if not e_CreateTextureEx(FileName, framesArray[find_id].TexturesID[a], a*mWidth, 0, mWidth, mHeight) then exit;
-  end;
-
-  if BackAnimation then
-  begin
-    for a := 1 to mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
-  end;
-
-  framesArray[find_id].used := true;
-  framesArray[find_id].FrameWidth := mWidth;
-  framesArray[find_id].FrameHeight := mHeight;
-  if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
-
-  if (ID <> nil) then ID^ := find_id;
-
-  result := true;
-end;
-
-
-function CreateFramesMem (pData: Pointer; dataSize: LongInt; ID: PDWORD; Name: AnsiString;
-                          mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
-var
-  find_id: LongWord;
-  a: Integer;
-begin
-  result := false;
-
-  find_id := allocFrameSlot();
-
-  if (mCount <= 2) then BackAnimation := false;
-
-  if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
-  else SetLength(framesArray[find_id].TexturesID, mCount);
-
-  for a := 0 to mCount-1 do
-    if not e_CreateTextureMemEx(pData, dataSize, framesArray[find_id].TexturesID[a], a*mWidth, 0, mWidth, mHeight) then
-    begin
-      //!!!FreeMem(pData);
-      exit;
-    end;
-
-  if BackAnimation then
-  begin
-    for a := 1 to mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
-  end;
-
-  framesArray[find_id].used := true;
-  framesArray[find_id].FrameWidth := mWidth;
-  framesArray[find_id].FrameHeight := mHeight;
-  if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
-
-  if (ID <> nil) then ID^ := find_id;
-
-  result := true;
-end;
-
-
-function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; const Name: AnsiString; BackAnimation: Boolean = false): Boolean;
-var
-  find_id: LongWord;
-  a, mCount: Integer;
-begin
-  result := false;
-  find_id := allocFrameSlot();
-
-  mCount := Length(ia);
-
-  //e_WriteLog(Format('+++ creating %d frames [%s]', [FCount, Name]), MSG_NOTIFY);
-
-  if (mCount < 1) then exit;
-  if (mCount <= 2) then BackAnimation := false;
-
-  if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
-  else SetLength(framesArray[find_id].TexturesID, mCount);
-
-  //e_WriteLog(Format('+++ creating %d frames, %dx%d', [FCount, ia[0].width, ia[0].height]), MSG_NOTIFY);
-
-  for a := 0 to mCount-1 do
-  begin
-    if not e_CreateTextureImg(ia[a], framesArray[find_id].TexturesID[a]) then exit;
-    //e_WriteLog(Format('+++   frame %d, %dx%d', [a, ia[a].width, ia[a].height]), MSG_NOTIFY);
-  end;
-
-  if BackAnimation then
-  begin
-    for a := 1 to mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
-  end;
-
-  framesArray[find_id].used := true;
-  framesArray[find_id].FrameWidth := ia[0].width;
-  framesArray[find_id].FrameHeight := ia[0].height;
-  if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
-
-  if (ID <> nil) then ID^ := find_id;
-
-  result := true;
-end;
-
-
-function g_Frames_CreateWAD (ID: PDWORD; const Name, Resource: AnsiString;
-                             mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
-var
-  WAD: TWADFile;
-  FileName: AnsiString;
-  TextureData: Pointer;
-  ResourceLength: Integer;
-begin
-  result := false;
-
-  // models without "advanced" animations asks for "nothing" like this; don't spam log
-  if (Length(Resource) > 0) and ((Resource[Length(Resource)] = '/') or (Resource[Length(Resource)] = '\')) then exit;
-
-  FileName := g_ExtractWadName(Resource);
-
-  WAD := TWADFile.Create();
-  WAD.ReadFile(FileName);
-
-  if not WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
-  begin
-    WAD.Free();
-    e_WriteLog(Format('Error loading texture %s', [Resource]), TMsgType.Warning);
-    //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
-    exit;
-  end;
-
-  if not CreateFramesMem(TextureData, ResourceLength, ID, Name, mWidth, mHeight, mCount, BackAnimation) then
-  begin
-    FreeMem(TextureData);
-    WAD.Free();
-    exit;
-  end;
-
-  FreeMem(TextureData);
-  WAD.Free();
-
-  result := true;
-end;
-
-
-function g_Frames_CreateMemory (ID: PDWORD; const Name: AnsiString; pData: Pointer; dataSize: LongInt;
-                                mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
-begin
-  result := CreateFramesMem(pData, dataSize, ID, Name, mWidth, mHeight, mCount, BackAnimation);
-end;
-
-
-{function g_Frames_CreateRevert(ID: PDWORD; Name: ShortString; Frames: string): Boolean;
-var
-  find_id, b: DWORD;
-  a, c: Integer;
-begin
- Result := False;
-
- if not g_Frames_Get(b, Frames) then Exit;
-
- find_id := FindFrame();
-
- FramesArray[find_id].Name := Name;
- FramesArray[find_id].FrameWidth := FramesArray[b].FrameWidth;
- FramesArray[find_id].FrameHeight := FramesArray[b].FrameHeight;
-
- c := High(FramesArray[find_id].TexturesID);
-
- for a := 0 to c do
-  FramesArray[find_id].TexturesID[a] := FramesArray[b].TexturesID[c-a];
-
- Result := True;
-end;}
-
-
-function g_Frames_Dup (const NewName, OldName: AnsiString): Boolean;
-var
-  find_id, b: LongWord;
-  a, c: Integer;
-begin
-  result := false;
-
-  if not g_Frames_Get(b, OldName) then exit;
-
-  find_id := allocFrameSlot();
-
-  framesArray[find_id].used := true;
-  framesArray[find_id].Name := NewName;
-  framesArray[find_id].FrameWidth := framesArray[b].FrameWidth;
-  framesArray[find_id].FrameHeight := framesArray[b].FrameHeight;
-
-  c := High(framesArray[b].TexturesID);
-  SetLength(framesArray[find_id].TexturesID, c+1);
-
-  for a := 0 to c do framesArray[find_id].TexturesID[a] := framesArray[b].TexturesID[a];
-
-  result := true;
-end;
-
-
-procedure g_Frames_DeleteByName (const FramesName: AnsiString);
-var
-  a, b: Integer;
-begin
-  if (Length(framesArray) = 0) then exit;
-  for a := 0 to High(framesArray) do
-  begin
-    if (StrEquCI1251(framesArray[a].Name, FramesName)) then
-    begin
-      if framesArray[a].TexturesID <> nil then
-      begin
-        for b := 0 to High(framesArray[a].TexturesID) do e_DeleteTexture(framesArray[a].TexturesID[b]);
-      end;
-      framesArray[a].used := false;
-      framesArray[a].TexturesID := nil;
-      framesArray[a].Name := '';
-      framesArray[a].FrameWidth := 0;
-      framesArray[a].FrameHeight := 0;
-    end;
-  end;
-end;
-
-
-procedure g_Frames_DeleteByID (ID: LongWord);
-var
-  b: Integer;
-begin
-  if (Length(framesArray) = 0) then exit;
-  if (framesArray[ID].TexturesID <> nil) then
-  begin
-    for b := 0 to High(framesArray[ID].TexturesID) do e_DeleteTexture(framesArray[ID].TexturesID[b]);
-  end;
-  framesArray[ID].used := false;
-  framesArray[ID].TexturesID := nil;
-  framesArray[ID].Name := '';
-  framesArray[ID].FrameWidth := 0;
-  framesArray[ID].FrameHeight := 0;
-end;
-
-
-procedure g_Frames_DeleteAll ();
-var
-  a, b: Integer;
-begin
-  for a := 0 to High(framesArray) do
-  begin
-    if (framesArray[a].used) then
-    begin
-      for b := 0 to High(framesArray[a].TexturesID) do e_DeleteTexture(framesArray[a].TexturesID[b]);
-    end;
-    framesArray[a].used := false;
-    framesArray[a].TexturesID := nil;
-    framesArray[a].Name := '';
-    framesArray[a].FrameWidth := 0;
-    framesArray[a].FrameHeight := 0;
-  end;
-  framesArray := nil;
-end;
-
-
-function g_Frames_Get (out ID: LongWord; const FramesName: AnsiString): Boolean;
-var
-  a: Integer;
-begin
-  result := false;
-  if (Length(framesArray) = 0) then exit;
-  for a := 0 to High(framesArray) do
-  begin
-    if (StrEquCI1251(framesArray[a].Name, FramesName)) then
-    begin
-      ID := a;
-      result := true;
-      break;
-    end;
-  end;
-  if not result then g_FatalError(Format(_lc[I_GAME_ERROR_FRAMES], [FramesName]));
-end;
-
-
-function g_Frames_GetTexture (out ID: LongWord; const FramesName: AnsiString; Frame: Word): Boolean;
-var
-  a: Integer;
-begin
-  result := false;
-  if (Length(framesArray) = 0) then exit;
-  for a := 0 to High(framesArray) do
-  begin
-    if (StrEquCI1251(framesArray[a].Name, FramesName)) then
-    begin
-      if (Frame < Length(framesArray[a].TexturesID)) then
-      begin
-        ID := framesArray[a].TexturesID[Frame];
-        result := true;
-        break;
-      end;
-    end;
-  end;
-  if not result then g_FatalError(Format(_lc[I_GAME_ERROR_FRAMES], [FramesName]));
-end;
-
-
-function g_Frames_Exists (const FramesName: AnsiString): Boolean;
-var
-  a: Integer;
-begin
-  result := false;
-  if (Length(framesArray) = 0) then exit;
-  for a := 0 to High(framesArray) do
-  begin
-    if (StrEquCI1251(framesArray[a].Name, FramesName)) then
-    begin
-      result := true;
-      exit;
-    end;
-  end;
-end;
-
-
-procedure DumpTextureNames ();
-var
-  i: Integer;
-begin
-  e_WriteLog('BEGIN Textures:', TMsgType.Notify);
-  for i := 0 to High(texturesArray) do e_WriteLog('   '+IntToStr(i)+'. '+texturesArray[i].Name, TMsgType.Notify);
-  e_WriteLog('END Textures.', TMsgType.Notify);
-
-  e_WriteLog('BEGIN Frames:', TMsgType.Notify);
-  for i := 0 to High(framesArray) do e_WriteLog('   '+IntToStr(i)+'. '+framesArray[i].Name, TMsgType.Notify);
-  e_WriteLog('END Frames.', TMsgType.Notify);
-end;
-
-
-{ TAnimation }
-
 constructor TAnimation.Create (aframesID: LongWord; aloop: Boolean; aspeed: Byte);
 begin
   if (aframesID >= Length(framesArray)) then
index e8891a06467dffaf806ba96cb96dabc9dbe824b1..1c8e0c778d77f6a573818596ff3f6d4df02d8537 100644 (file)
@@ -103,7 +103,7 @@ implementation
 
 uses
   Math,
-  g_player, g_map, g_panel, g_gfx, g_game, g_textures,
+  g_player, g_map, g_panel, g_gfx, g_game, g_textures, r_textures, r_animations,
   g_console, g_monsters, g_items, g_phys, g_weapons,
   wadreader, e_log, g_language, e_res,
   g_options, g_net, g_netmsg, utils, xparser, xstreams;
index 81767e653f03be80e7d7a5b58fb7dd0970db4413..bf9a0953c5cd188ff87fba09f52609c084a243be 100644 (file)
@@ -114,7 +114,7 @@ implementation
 
 uses
   Math, g_map, g_player, g_gfx, g_sound, g_panel,
-  g_console, g_options, g_game,
+  g_console, g_options, g_game, r_textures, r_animations,
   g_triggers, MAPDEF, e_log, g_monsters, g_saveload,
   g_language, g_netmsg, g_grid,
   geom, binheap, hashtable, utils, xstreams;
index 71d752a79da7606ed47a7c035dd134917c42d3a8..1b634051753716d481178091eaf2134a6bbe88bb 100644 (file)
@@ -17,14 +17,44 @@ unit r_animations;
 
 interface
 
-  uses g_base, g_textures, MAPDEF; // TMirrorType, TAnimation, TDFPoint
+  uses g_base, g_textures, MAPDEF, Imaging; // TMirrorType, TAnimation, TDFPoint, TDynImageDataArray
 
   procedure r_Animation_Draw (t: TAnimation; x, y: Integer; mirror: TMirrorType);
   procedure r_Animation_DrawEx (t: TAnimation; x, y: Integer; mirror: TMirrorType; rpoint: TDFPoint; angle: SmallInt);
 
+  function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; const Name: AnsiString; BackAnimation: Boolean = false): Boolean;
+
+  function g_Frames_CreateWAD (ID: PDWORD; const Name, Resource: AnsiString; mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
+  function g_Frames_CreateFile (ID: PDWORD; const Name, FileName: AnsiString; mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
+  function g_Frames_CreateMemory (ID: PDWORD; const Name: AnsiString; pData: Pointer; dataSize: LongInt; mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
+  function g_Frames_Dup (const NewName, OldName: AnsiString): Boolean;
+  function g_Frames_Get (out ID: LongWord; const FramesName: AnsiString): Boolean;
+  function g_Frames_GetTexture (out ID: LongWord; const FramesName: AnsiString; Frame: Word): Boolean;
+  function g_Frames_Exists (const FramesName: AnsiString): Boolean;
+  procedure g_Frames_DeleteByName (const FramesName: AnsiString);
+  procedure g_Frames_DeleteByID (ID: LongWord);
+  procedure g_Frames_DeleteAll;
+
+  type
+    TFrames = record
+      texturesID: array of LongWord;
+      name: AnsiString;
+      frameWidth, frameHeight: Word;
+      used: Boolean;
+    end;
+
+  var
+    framesArray: array of TFrames = nil;
+
 implementation
 
-  uses r_graphics;
+  uses
+    SysUtils, Classes, Math,
+    WadReader, utils,
+    e_log,
+    r_graphics,
+    g_language, g_game
+  ;
 
   procedure r_Animation_Draw (t: TAnimation; x, y: Integer; mirror: TMirrorType);
   begin
@@ -38,4 +68,328 @@ implementation
       e_DrawAdv(framesArray[t.id].TexturesID[t.currentFrame], x, y, t.alpha, true, t.blending, angle, @rpoint, mirror)
   end;
 
+function allocFrameSlot (): LongWord;
+var
+  f: integer;
+begin
+  for f := 0 to High(framesArray) do
+  begin
+    if (not framesArray[f].used) then
+    begin
+      result := f;
+      exit;
+    end;
+  end;
+
+  result := Length(framesArray);
+  SetLength(framesArray, result+64);
+  for f := result to High(framesArray) do
+  begin
+    with framesArray[f] do
+    begin
+      texturesID := nil;
+      name := '';
+      frameWidth := 0;
+      frameHeight := 0;
+      used := false;
+    end;
+  end;
+end;
+
+function g_Frames_CreateFile (ID: PDWORD; const Name, FileName: AnsiString;
+                              mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
+var
+  a: Integer;
+  find_id: LongWord;
+begin
+  result := false;
+
+  find_id := allocFrameSlot();
+
+  if (mCount <= 2) then BackAnimation := false;
+
+  if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
+  else SetLength(framesArray[find_id].TexturesID, mCount);
+
+  for a := 0 to mCount-1 do
+  begin
+    if not e_CreateTextureEx(FileName, framesArray[find_id].TexturesID[a], a*mWidth, 0, mWidth, mHeight) then exit;
+  end;
+
+  if BackAnimation then
+  begin
+    for a := 1 to mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
+  end;
+
+  framesArray[find_id].used := true;
+  framesArray[find_id].FrameWidth := mWidth;
+  framesArray[find_id].FrameHeight := mHeight;
+  if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
+
+  if (ID <> nil) then ID^ := find_id;
+
+  result := true;
+end;
+
+function CreateFramesMem (pData: Pointer; dataSize: LongInt; ID: PDWORD; Name: AnsiString;
+                          mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
+var
+  find_id: LongWord;
+  a: Integer;
+begin
+  result := false;
+
+  find_id := allocFrameSlot();
+
+  if (mCount <= 2) then BackAnimation := false;
+
+  if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
+  else SetLength(framesArray[find_id].TexturesID, mCount);
+
+  for a := 0 to mCount-1 do
+    if not e_CreateTextureMemEx(pData, dataSize, framesArray[find_id].TexturesID[a], a*mWidth, 0, mWidth, mHeight) then
+    begin
+      //!!!FreeMem(pData);
+      exit;
+    end;
+
+  if BackAnimation then
+  begin
+    for a := 1 to mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
+  end;
+
+  framesArray[find_id].used := true;
+  framesArray[find_id].FrameWidth := mWidth;
+  framesArray[find_id].FrameHeight := mHeight;
+  if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
+
+  if (ID <> nil) then ID^ := find_id;
+
+  result := true;
+end;
+
+function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; const Name: AnsiString; BackAnimation: Boolean = false): Boolean;
+var
+  find_id: LongWord;
+  a, mCount: Integer;
+begin
+  result := false;
+  find_id := allocFrameSlot();
+
+  mCount := Length(ia);
+
+  //e_WriteLog(Format('+++ creating %d frames [%s]', [FCount, Name]), MSG_NOTIFY);
+
+  if (mCount < 1) then exit;
+  if (mCount <= 2) then BackAnimation := false;
+
+  if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
+  else SetLength(framesArray[find_id].TexturesID, mCount);
+
+  //e_WriteLog(Format('+++ creating %d frames, %dx%d', [FCount, ia[0].width, ia[0].height]), MSG_NOTIFY);
+
+  for a := 0 to mCount-1 do
+  begin
+    if not e_CreateTextureImg(ia[a], framesArray[find_id].TexturesID[a]) then exit;
+    //e_WriteLog(Format('+++   frame %d, %dx%d', [a, ia[a].width, ia[a].height]), MSG_NOTIFY);
+  end;
+
+  if BackAnimation then
+  begin
+    for a := 1 to mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
+  end;
+
+  framesArray[find_id].used := true;
+  framesArray[find_id].FrameWidth := ia[0].width;
+  framesArray[find_id].FrameHeight := ia[0].height;
+  if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
+
+  if (ID <> nil) then ID^ := find_id;
+
+  result := true;
+end;
+
+function g_Frames_CreateWAD (ID: PDWORD; const Name, Resource: AnsiString;
+                             mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
+var
+  WAD: TWADFile;
+  FileName: AnsiString;
+  TextureData: Pointer;
+  ResourceLength: Integer;
+begin
+  result := false;
+
+  // models without "advanced" animations asks for "nothing" like this; don't spam log
+  if (Length(Resource) > 0) and ((Resource[Length(Resource)] = '/') or (Resource[Length(Resource)] = '\')) then exit;
+
+  FileName := g_ExtractWadName(Resource);
+
+  WAD := TWADFile.Create();
+  WAD.ReadFile(FileName);
+
+  if not WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
+  begin
+    WAD.Free();
+    e_WriteLog(Format('Error loading texture %s', [Resource]), TMsgType.Warning);
+    //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
+    exit;
+  end;
+
+  if not CreateFramesMem(TextureData, ResourceLength, ID, Name, mWidth, mHeight, mCount, BackAnimation) then
+  begin
+    FreeMem(TextureData);
+    WAD.Free();
+    exit;
+  end;
+
+  FreeMem(TextureData);
+  WAD.Free();
+
+  result := true;
+end;
+
+function g_Frames_CreateMemory (ID: PDWORD; const Name: AnsiString; pData: Pointer; dataSize: LongInt;
+                                mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
+begin
+  result := CreateFramesMem(pData, dataSize, ID, Name, mWidth, mHeight, mCount, BackAnimation);
+end;
+
+function g_Frames_Dup (const NewName, OldName: AnsiString): Boolean;
+var
+  find_id, b: LongWord;
+  a, c: Integer;
+begin
+  result := false;
+
+  if not g_Frames_Get(b, OldName) then exit;
+
+  find_id := allocFrameSlot();
+
+  framesArray[find_id].used := true;
+  framesArray[find_id].Name := NewName;
+  framesArray[find_id].FrameWidth := framesArray[b].FrameWidth;
+  framesArray[find_id].FrameHeight := framesArray[b].FrameHeight;
+
+  c := High(framesArray[b].TexturesID);
+  SetLength(framesArray[find_id].TexturesID, c+1);
+
+  for a := 0 to c do framesArray[find_id].TexturesID[a] := framesArray[b].TexturesID[a];
+
+  result := true;
+end;
+
+
+procedure g_Frames_DeleteByName (const FramesName: AnsiString);
+var
+  a, b: Integer;
+begin
+  if (Length(framesArray) = 0) then exit;
+  for a := 0 to High(framesArray) do
+  begin
+    if (StrEquCI1251(framesArray[a].Name, FramesName)) then
+    begin
+      if framesArray[a].TexturesID <> nil then
+      begin
+        for b := 0 to High(framesArray[a].TexturesID) do e_DeleteTexture(framesArray[a].TexturesID[b]);
+      end;
+      framesArray[a].used := false;
+      framesArray[a].TexturesID := nil;
+      framesArray[a].Name := '';
+      framesArray[a].FrameWidth := 0;
+      framesArray[a].FrameHeight := 0;
+    end;
+  end;
+end;
+
+procedure g_Frames_DeleteByID (ID: LongWord);
+var
+  b: Integer;
+begin
+  if (Length(framesArray) = 0) then exit;
+  if (framesArray[ID].TexturesID <> nil) then
+  begin
+    for b := 0 to High(framesArray[ID].TexturesID) do e_DeleteTexture(framesArray[ID].TexturesID[b]);
+  end;
+  framesArray[ID].used := false;
+  framesArray[ID].TexturesID := nil;
+  framesArray[ID].Name := '';
+  framesArray[ID].FrameWidth := 0;
+  framesArray[ID].FrameHeight := 0;
+end;
+
+procedure g_Frames_DeleteAll ();
+var
+  a, b: Integer;
+begin
+  for a := 0 to High(framesArray) do
+  begin
+    if (framesArray[a].used) then
+    begin
+      for b := 0 to High(framesArray[a].TexturesID) do e_DeleteTexture(framesArray[a].TexturesID[b]);
+    end;
+    framesArray[a].used := false;
+    framesArray[a].TexturesID := nil;
+    framesArray[a].Name := '';
+    framesArray[a].FrameWidth := 0;
+    framesArray[a].FrameHeight := 0;
+  end;
+  framesArray := nil;
+end;
+
+
+function g_Frames_Get (out ID: LongWord; const FramesName: AnsiString): Boolean;
+var
+  a: Integer;
+begin
+  result := false;
+  if (Length(framesArray) = 0) then exit;
+  for a := 0 to High(framesArray) do
+  begin
+    if (StrEquCI1251(framesArray[a].Name, FramesName)) then
+    begin
+      ID := a;
+      result := true;
+      break;
+    end;
+  end;
+  if not result then g_FatalError(Format(_lc[I_GAME_ERROR_FRAMES], [FramesName]));
+end;
+
+function g_Frames_GetTexture (out ID: LongWord; const FramesName: AnsiString; Frame: Word): Boolean;
+var
+  a: Integer;
+begin
+  result := false;
+  if (Length(framesArray) = 0) then exit;
+  for a := 0 to High(framesArray) do
+  begin
+    if (StrEquCI1251(framesArray[a].Name, FramesName)) then
+    begin
+      if (Frame < Length(framesArray[a].TexturesID)) then
+      begin
+        ID := framesArray[a].TexturesID[Frame];
+        result := true;
+        break;
+      end;
+    end;
+  end;
+  if not result then g_FatalError(Format(_lc[I_GAME_ERROR_FRAMES], [FramesName]));
+end;
+
+function g_Frames_Exists (const FramesName: AnsiString): Boolean;
+var
+  a: Integer;
+begin
+  result := false;
+  if (Length(framesArray) = 0) then exit;
+  for a := 0 to High(framesArray) do
+  begin
+    if (StrEquCI1251(framesArray[a].Name, FramesName)) then
+    begin
+      result := true;
+      exit;
+    end;
+  end;
+end;
+
 end.
index 1d5081efaa2975ed967e95eff00af459d3b87533..1204fcda617d533c1654580f3c5e785f79613178 100644 (file)
@@ -25,9 +25,9 @@ implementation
 
   uses
     SysUtils, Classes, Math,
-    e_log, r_graphics, g_options,
+    e_log, r_graphics, g_options, r_textures,
     conbuf,
-    g_base, g_console, g_game, g_menu, g_textures
+    g_base, g_console, g_game, g_menu
   ;
 
 (* ====== Console ====== *)
index df9e82d7ab15812c1b6104a4fc4c7f90d27bf723..1ea8aeffd331880b7aa33b4cbb449eb366b80ed0 100644 (file)
@@ -32,10 +32,10 @@ implementation
     g_base, r_graphics,
     g_system, g_touch,
     MAPDEF, xprofiler, utils, wadreader,
-    g_textures, e_input, e_sound,
+    e_input, e_sound,
     g_language, g_console, g_menu, g_triggers, g_player, g_options, g_monsters, g_map, g_panel,
     g_items, g_weapons, g_gfx, g_phys, g_net, g_gui, g_netmaster,
-    g_game, r_console, r_gfx, r_items, r_map, r_panel, r_monsters, r_weapons, r_netmaster, r_player
+    g_game, r_console, r_gfx, r_items, r_map, r_panel, r_monsters, r_weapons, r_netmaster, r_player, r_textures
   ;
 
   var
index c9de77c350ddd6c333686c092f056b1e03c1fa8c..a8446312d03a6a6d66180ae16bf656de4e14eedc 100644 (file)
@@ -27,8 +27,8 @@ implementation
   uses
     {$INCLUDE ../nogl/noGLuses.inc}
     SysUtils, Classes, Math,
-    r_graphics, g_options, r_animations,
-    g_base, g_basic, g_textures
+    r_graphics, g_options, r_animations, r_textures,
+    g_base, g_basic
   ;
 
   // TODO: remove WITH operator
index 32e7ca871dc1b279f36f4f8a308784a031449d5b..faff88b0a63cdd2a576af72e10f28b483e539901 100644 (file)
@@ -42,11 +42,11 @@ implementation
   uses
     SysUtils, Classes, Math,
     MAPDEF, utils,
-    g_basic, g_game, g_phys, g_map, g_textures, g_menu, g_language, g_weapons, g_items, g_net, g_options,
+    g_basic, g_game, g_phys, g_map, g_menu, g_language, g_weapons, g_items, g_net, g_options,
 {$IFDEF ENABLE_HOLMES}
     g_holmes,
 {$ENDIF}
-    r_playermodel, r_graphics, r_animations
+    r_playermodel, r_graphics, r_animations, r_textures
   ;
 
   procedure r_Player_DrawAll;
index fc1576069450c8e54e812952e8cee5140f0a57fa..c15a713800114833cd4fe50d89af4b2705410d05 100644 (file)
@@ -28,8 +28,8 @@ implementation
   uses
     SysUtils, Classes, Math,
     MAPDEF,
-    r_graphics, g_options, r_animations,
-    g_base, g_basic, g_map, g_weapons, g_textures
+    r_graphics, g_options, r_animations, r_textures,
+    g_base, g_basic, g_map, g_weapons
   ;
 
   const
diff --git a/src/game/opengl/r_textures.pas b/src/game/opengl/r_textures.pas
new file mode 100644 (file)
index 0000000..9445049
--- /dev/null
@@ -0,0 +1,259 @@
+(* 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
+ * the Free Software Foundation, version 3 of the License ONLY.
+ *
+ * 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}
+unit r_textures;
+
+interface
+
+  function g_Texture_CreateWAD (var ID: LongWord; const Resource: AnsiString; filterHint: Boolean = False): Boolean;
+  function g_Texture_CreateFile (var ID: LongWord; const FileName: AnsiString): Boolean;
+  function g_Texture_CreateWADEx (const textureName, Resource: AnsiString; filterHint: Boolean = False): Boolean;
+  function g_Texture_CreateFileEx (const textureName, FileName: AnsiString): Boolean;
+  function g_Texture_Get (const textureName: AnsiString; var ID: LongWord): Boolean;
+  function g_Texture_GetSize (const textureName: AnsiString; var w, h: Integer): Boolean; overload;
+  function g_Texture_GetSize (ID: LongWord; var w, h: Integer): Boolean; overload;
+  procedure g_Texture_Delete (const textureName: AnsiString);
+  procedure g_Texture_DeleteAll;
+
+implementation
+
+  uses
+    SysUtils, Classes, Math,
+    WadReader, utils,
+    e_log,
+    r_graphics,
+    g_language, g_game
+  ;
+
+  type
+    _TTexture = record
+      name: AnsiString;
+      id: LongWord;
+      width, height: Word;
+      used: Boolean;
+    end;
+
+  var
+    texturesArray: array of _TTexture = nil;
+
+function allocTextureSlot (): LongWord;
+var
+  f: integer;
+begin
+  for f := 0 to High(texturesArray) do
+  begin
+    if (not texturesArray[f].used) then
+    begin
+      result := f;
+      exit;
+    end;
+  end;
+
+  result := Length(texturesArray);
+  SetLength(texturesArray, result+64);
+  for f := result to High(texturesArray) do
+  begin
+    with texturesArray[f] do
+    begin
+      name := '';
+      id := 0;
+      width := 0;
+      height := 0;
+      used := false;
+    end;
+  end;
+end;
+
+function g_Texture_CreateWAD (var ID: LongWord; const Resource: AnsiString; filterHint: Boolean = False): Boolean;
+var
+  WAD: TWADFile;
+  FileName: AnsiString;
+  TextureData: Pointer;
+  ResourceLength: Integer;
+begin
+  result := false;
+  FileName := g_ExtractWadName(Resource);
+
+  WAD := TWADFile.Create;
+  WAD.ReadFile(FileName);
+
+  if WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
+  begin
+    if e_CreateTextureMem(TextureData, ResourceLength, ID, filterHint) then
+      result := true;
+    FreeMem(TextureData)
+  end
+  else
+  begin
+    e_WriteLog(Format('Error loading texture %s', [Resource]), TMsgType.Warning);
+    //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
+  end;
+  WAD.Free();
+end;
+
+
+function g_Texture_CreateFile (var ID: LongWord; const FileName: AnsiString): Boolean;
+begin
+  result := true;
+  if not e_CreateTexture(FileName, ID) then
+  begin
+    e_WriteLog(Format('Error loading texture %s', [FileName]), TMsgType.Warning);
+    result := false;
+  end;
+end;
+
+function g_Texture_CreateWADEx (const textureName, Resource: AnsiString; filterHint: Boolean = False): Boolean;
+var
+  WAD: TWADFile;
+  FileName: AnsiString;
+  TextureData: Pointer;
+  find_id: LongWord;
+  ResourceLength: Integer;
+begin
+  FileName := g_ExtractWadName(Resource);
+
+  find_id := allocTextureSlot();
+
+  WAD := TWADFile.Create;
+  WAD.ReadFile(FileName);
+
+  if WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
+  begin
+    result := e_CreateTextureMem(TextureData, ResourceLength, texturesArray[find_id].ID, filterHint);
+    if result then
+    begin
+      e_GetTextureSize(texturesArray[find_id].ID, @texturesArray[find_id].width, @texturesArray[find_id].height);
+      texturesArray[find_id].used := true;
+      texturesArray[find_id].Name := textureName;
+    end;
+    FreeMem(TextureData)
+  end
+  else
+  begin
+    e_WriteLog(Format('Error loading texture %s', [Resource]), TMsgType.Warning);
+    //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
+    result := false;
+  end;
+  WAD.Free();
+end;
+
+
+function g_Texture_CreateFileEx (const textureName, FileName: AnsiString): Boolean;
+var
+  find_id: LongWord;
+begin
+  find_id := allocTextureSlot();
+  result := e_CreateTexture(FileName, texturesArray[find_id].ID);
+  if result then
+  begin
+    texturesArray[find_id].used := true;
+    texturesArray[find_id].Name := textureName;
+    e_GetTextureSize(texturesArray[find_id].ID, @texturesArray[find_id].width, @texturesArray[find_id].height);
+  end
+  else e_WriteLog(Format('Error loading texture %s', [FileName]), TMsgType.Warning);
+end;
+
+
+function g_Texture_Get (const textureName: AnsiString; var id: LongWord): Boolean;
+var
+  a: Integer;
+begin
+  result := false;
+  if (Length(texturesArray) = 0) or (Length(textureName) = 0) then exit;
+  for a := 0 to High(texturesArray) do
+  begin
+    if (StrEquCI1251(texturesArray[a].name, textureName)) then
+    begin
+      id := texturesArray[a].id;
+      result := true;
+      break;
+    end;
+  end;
+  //if not Result then g_ConsoleAdd('Texture '+TextureName+' not found');
+end;
+
+function g_Texture_GetSize (const textureName: AnsiString; var w, h: Integer): Boolean; overload;
+var
+  a: Integer;
+begin
+  result := false;
+  w := 0;
+  h := 0;
+  if (Length(texturesArray) = 0) or (Length(textureName) = 0) then exit;
+  for a := 0 to High(texturesArray) do
+  begin
+    if (StrEquCI1251(texturesArray[a].name, textureName)) then
+    begin
+      w := texturesArray[a].width;
+      h := texturesArray[a].height;
+      result := true;
+      break;
+    end;
+  end;
+end;
+
+
+function g_Texture_GetSize (ID: LongWord; var w, h: Integer): Boolean; overload;
+var
+  a: Integer;
+begin
+  result := false;
+  w := 0;
+  h := 0;
+  if (Length(texturesArray) = 0) then exit;
+  for a := 0 to High(texturesArray) do
+  begin
+    if (texturesArray[a].id = ID) then
+    begin
+      w := texturesArray[a].width;
+      h := texturesArray[a].height;
+      result := true;
+      break;
+    end;
+  end;
+end;
+
+
+procedure g_Texture_Delete (const textureName: AnsiString);
+var
+  a: Integer;
+begin
+  if (Length(texturesArray) = 0) or (Length(textureName) = 0) then exit;
+  for a := 0 to High(texturesArray) do
+  begin
+    if (StrEquCI1251(texturesArray[a].name, textureName)) then
+    begin
+      e_DeleteTexture(texturesArray[a].ID);
+      texturesArray[a].used := false;
+      texturesArray[a].name := '';
+      texturesArray[a].id := 0;
+      texturesArray[a].width := 0;
+      texturesArray[a].height := 0;
+    end;
+  end;
+end;
+
+procedure g_Texture_DeleteAll ();
+var
+  a: Integer;
+begin
+  for a := 0 to High(texturesArray) do
+  begin
+    if (texturesArray[a].used) then e_DeleteTexture(texturesArray[a].ID);
+  end;
+  texturesArray := nil;
+end;
+
+end.