DEADSOFTWARE

render: separate player model logic and drawing
[d2df-sdl.git] / src / game / g_playermodel.pas
index 6ffea1fbc3fc094fb714fb25df4ef20623235c4a..f91620eac842e0b6a9d1c4a9857015fad79f27f1 100644 (file)
@@ -56,6 +56,15 @@ const
   MODELSOUND_PAIN = 0;
   MODELSOUND_DIE  = 1;
 
+  W_POS_NORMAL = 0;
+  W_POS_UP     = 1;
+  W_POS_DOWN   = 2;
+
+  W_ACT_NORMAL = 0;
+  W_ACT_FIRE   = 1;
+
+  FLAG_BASEPOINT: TDFPoint = (X:16; Y:43);
+
 type
   TModelInfo = record
     Name:        String;
@@ -85,6 +94,7 @@ type
   TWeaponPoints = Array [WP_FIRST + 1..WP_LAST] of
                   Array [A_STAND..A_LAST] of
                   Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array of TDFPoint;
+  TModelMatrix = Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array [A_STAND..A_LAST] of TAnimation;
 
   TPlayerModel = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
   private
@@ -93,8 +103,8 @@ type
     FColor:            TRGB;
     FBlood:            TModelBlood;
     FCurrentAnimation: Byte;
-    FAnim:             Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array [A_STAND..A_LAST] of TAnimation;
-    FMaskAnim:         Array [TDirection.D_LEFT..TDirection.D_RIGHT] of Array [A_STAND..A_LAST] of TAnimation;
+    FAnim:             TModelMatrix;
+    FMaskAnim:         TModelMatrix;
     FWeaponPoints:     TWeaponPoints;
     FPainSounds:       TModelSoundArray;
     FDieSounds:        TModelSoundArray;
@@ -119,7 +129,6 @@ type
     procedure   SetFire(Fire: Boolean);
     function    PlaySound(SoundType, Level: Byte; X, Y: Integer): Boolean;
     procedure   Update();
-    procedure   Draw(X, Y: Integer; Alpha: Byte = 0);
 
   published
     property    Fire: Boolean read FFire;
@@ -131,9 +140,21 @@ type
   public
     property    Color: TRGB read FColor write FColor;
     property    Blood: TModelBlood read FBlood;
+
+    property    Anim: TModelMatrix read FAnim;
+    property    MaskAnim: TModelMatrix read FMaskAnim;
+    property    CurrentAnimation: Byte read FCurrentAnimation;
+
+    property    CurrentWeapon: Byte read FCurrentWeapon;
+    property    DrawWeapon: Boolean read FDrawWeapon;
+    property    WeaponPoints: TWeaponPoints read FWeaponPoints;
+
+    property    Flag: Byte read FFlag;
+    property    FlagAnim: TAnimation read FFlagAnim;
+    property    FlagAngle: SmallInt read FFlagAngle;
+    property    FlagPoint: TDFPoint read FFlagPoint;
   end;
 
-procedure g_PlayerModel_LoadData();
 procedure g_PlayerModel_FreeData();
 function  g_PlayerModel_Load(FileName: String): Boolean;
 function  g_PlayerModel_GetNames(): SSArray;
@@ -166,14 +187,6 @@ type
   end;
 
 const
-  W_POS_NORMAL = 0;
-  W_POS_UP     = 1;
-  W_POS_DOWN   = 2;
-
-  W_ACT_NORMAL = 0;
-  W_ACT_FIRE   = 1;
-
-  FLAG_BASEPOINT: TDFPoint = (X:16; Y:43);
   FLAG_DEFPOINT:  TDFPoint = (X:32; Y:16);
   FLAG_DEFANGLE = -20;
   WEAPONBASE: Array [WP_FIRST + 1..WP_LAST] of TDFPoint =
@@ -193,26 +206,8 @@ const
              ('csaw', 'hgun', 'sg', 'ssg', 'mgun', 'rkt', 'plz', 'bfg', 'spl', 'flm');
 
 var
-  WeaponID: Array [WP_FIRST + 1..WP_LAST] of
-            Array [W_POS_NORMAL..W_POS_DOWN] of
-            Array [W_ACT_NORMAL..W_ACT_FIRE] of DWORD;
   PlayerModelsArray: Array of TPlayerModelInfo;
 
-procedure g_PlayerModel_LoadData();
-var
-  a: Integer;
-begin
-  for a := WP_FIRST + 1 to WP_LAST do
-  begin
-    g_Texture_CreateWAD(WeaponID[a][W_POS_NORMAL][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a]));
-    g_Texture_CreateWAD(WeaponID[a][W_POS_NORMAL][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_FIRE');
-    g_Texture_CreateWAD(WeaponID[a][W_POS_UP][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_UP');
-    g_Texture_CreateWAD(WeaponID[a][W_POS_UP][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_UP_FIRE');
-    g_Texture_CreateWAD(WeaponID[a][W_POS_DOWN][W_ACT_NORMAL], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_DN');
-    g_Texture_CreateWAD(WeaponID[a][W_POS_DOWN][W_ACT_FIRE], GameWAD+':WEAPONS\'+UpperCase(WeapNames[a])+'_DN_FIRE');
-  end;
-end;
-
 function GetPoint(var str: String; var point: TDFPoint): Boolean;
 var
   a, x, y: Integer;
@@ -828,13 +823,8 @@ end;
 procedure g_PlayerModel_FreeData();
 var
   i: DWORD;
-  a, b, c: Integer;
+  a, b: Integer;
 begin
-  for a := WP_FIRST + 1 to WP_LAST do
-    for b := W_POS_NORMAL to W_POS_DOWN do
-      for c := W_ACT_NORMAL to W_ACT_FIRE do
-        e_DeleteTexture(WeaponID[a][b][c]);
-
   e_WriteLog('Releasing models...', TMsgType.Notify);
 
   if PlayerModelsArray = nil then Exit;
@@ -906,97 +896,6 @@ begin
   inherited;
 end;
 
-procedure TPlayerModel.Draw(X, Y: Integer; Alpha: Byte = 0);
-var
-  Mirror: TMirrorType;
-  pos, act: Byte;
-  p: TDFPoint;
-begin
-// Ôëàãè:
-  if Direction = TDirection.D_LEFT then
-    Mirror := TMirrorType.None
-  else
-    Mirror := TMirrorType.Horizontal;
-
-  if (FFlag <> FLAG_NONE) and (FFlagAnim <> nil) and
-     (not (FCurrentAnimation in [A_DIE1, A_DIE2])) then
-  begin
-    p.X := IfThen(Direction = TDirection.D_LEFT,
-                  FLAG_BASEPOINT.X,
-                  64-FLAG_BASEPOINT.X);
-    p.Y := FLAG_BASEPOINT.Y;
-
-    FFlagAnim.DrawEx(X+IfThen(Direction = TDirection.D_LEFT, FFlagPoint.X-1, 2*FLAG_BASEPOINT.X-FFlagPoint.X+1)-FLAG_BASEPOINT.X,
-                     Y+FFlagPoint.Y-FLAG_BASEPOINT.Y+1, Mirror, p,
-                     IfThen(FDirection = TDirection.D_RIGHT, FFlagAngle, -FFlagAngle));
-  end;
-
-// Îðóæèå:
-  if Direction = TDirection.D_RIGHT then
-    Mirror := TMirrorType.None
-  else
-    Mirror := TMirrorType.Horizontal;
-
-  if FDrawWeapon and
-    (not (FCurrentAnimation in [A_DIE1, A_DIE2, A_PAIN])) and
-    (FCurrentWeapon in [WP_FIRST + 1..WP_LAST]) then
-  begin
-    if FCurrentAnimation in [A_SEEUP, A_ATTACKUP] then
-      pos := W_POS_UP
-    else
-      if FCurrentAnimation in [A_SEEDOWN, A_ATTACKDOWN] then
-        pos := W_POS_DOWN
-      else
-        pos := W_POS_NORMAL;
-
-    if (FCurrentAnimation in [A_ATTACK, A_ATTACKUP, A_ATTACKDOWN]) or
-       FFire then
-      act := W_ACT_FIRE
-    else
-      act := W_ACT_NORMAL;
-
-    if Alpha < 201 then
-      e_Draw(WeaponID[FCurrentWeapon][pos][act],
-             X+FWeaponPoints[FCurrentWeapon, FCurrentAnimation, FDirection,
-                             FAnim[TDirection.D_RIGHT][FCurrentAnimation].CurrentFrame].X,
-             Y+FWeaponPoints[FCurrentWeapon, FCurrentAnimation, FDirection,
-                             FAnim[TDirection.D_RIGHT][FCurrentAnimation].CurrentFrame].Y,
-             0, True, False, Mirror);
-  end;
-
-// Ìîäåëü:
-  if (FDirection = TDirection.D_LEFT) and
-     (FAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
-  begin
-    FAnim[TDirection.D_LEFT][FCurrentAnimation].Alpha := Alpha;
-    FAnim[TDirection.D_LEFT][FCurrentAnimation].Draw(X, Y, TMirrorType.None);
-  end
-  else
-  begin
-    FAnim[TDirection.D_RIGHT][FCurrentAnimation].Alpha := Alpha;
-    FAnim[TDirection.D_RIGHT][FCurrentAnimation].Draw(X, Y, Mirror);
-  end;
-
-// Ìàñêà ìîäåëè:
-  e_Colors := FColor;
-
-  if (FDirection = TDirection.D_LEFT) and
-     (FMaskAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then
-  begin
-    FMaskAnim[TDirection.D_LEFT][FCurrentAnimation].Alpha := Alpha;
-    FMaskAnim[TDirection.D_LEFT][FCurrentAnimation].Draw(X, Y, TMirrorType.None);
-  end
-  else
-  begin
-    FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation].Alpha := Alpha;
-    FMaskAnim[TDirection.D_RIGHT][FCurrentAnimation].Draw(X, Y, Mirror);
-  end;
-
-  e_Colors.R := 255;
-  e_Colors.G := 255;
-  e_Colors.B := 255;
-end;
-
 function TPlayerModel.GetCurrentAnimation: TAnimation;
 begin
   if (FDirection = TDirection.D_LEFT) and (FAnim[TDirection.D_LEFT][FCurrentAnimation] <> nil) then