X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=blobdiff_plain;f=src%2Fgame%2Fopengl%2Fr_playermodel.pas;h=1602f23e0d2b346d9c4f10e77665ca249486657d;hp=c15a713800114833cd4fe50d89af4b2705410d05;hb=7f57e4b195f1a553c5bb01638cc7d9908c992c88;hpb=c9fc9bdd334338e3f77750416c57fa55c5665fc0 diff --git a/src/game/opengl/r_playermodel.pas b/src/game/opengl/r_playermodel.pas index c15a713..1602f23 100644 --- a/src/game/opengl/r_playermodel.pas +++ b/src/game/opengl/r_playermodel.pas @@ -19,15 +19,16 @@ interface uses g_playermodel; // TPlayerModel - procedure r_PlayerModel_Initialize; - procedure r_PlayerModel_Finalize; + procedure r_PlayerModel_Load; + procedure r_PlayerModel_Free; procedure r_PlayerModel_Draw (pm: TPlayerModel; X, Y: Integer; Alpha: Byte = 0); implementation uses SysUtils, Classes, Math, - MAPDEF, + MAPDEF, utils, + ImagingTypes, Imaging, ImagingUtility, r_graphics, g_options, r_animations, r_textures, g_base, g_basic, g_map, g_weapons ; @@ -35,27 +36,128 @@ implementation const WeapNames: Array [WP_FIRST + 1..WP_LAST] of String = ('csaw', 'hgun', 'sg', 'ssg', 'mgun', 'rkt', 'plz', 'bfg', 'spl', 'flm'); + type + TDirIdx = TDirection.D_LEFT..TDirection.D_RIGHT; + TAnimIdx = A_STAND..A_LAST; + var WeaponID: Array [WP_FIRST + 1..WP_LAST, W_POS_NORMAL..W_POS_DOWN, W_ACT_NORMAL..W_ACT_FIRE] of DWORD; + Models: Array of record + Frames: Array [TDirIdx, TAnimIdx] of record + base: DWORD; + mask: DWORD; + end; + end; -procedure r_PlayerModel_Initialize; -var - a: Integer; -begin - for a := WP_FIRST + 1 to WP_LAST do + procedure ExtAnimFromBaseAnim(MName: String; AIdx: Integer); + const + CopyAnim: array [A_LASTBASE+1..A_LASTEXT] of Integer = ( + A_WALK, A_WALK, A_WALK, A_WALK, A_WALK, + A_STAND, A_WALK, A_ATTACK, A_WALK, A_SEEUP, A_SEEDOWN, + A_ATTACKUP, A_ATTACKDOWN + ); + var + OIdx: Integer; + AName, OName: String; + begin + // HACK: shitty workaround to duplicate base animations + // in place of extended, replace with something better later + + Assert((AIdx > A_LASTBASE) and (AIdx <= A_LASTEXT)); + OIdx := CopyAnim[AIdx]; + + AName := MName + '_RIGHTANIM' + IntToStr(AIdx); + OName := MName + '_RIGHTANIM' + IntToStr(OIdx); + Assert(g_Frames_Dup(AName, OName)); + Assert(g_Frames_Dup(AName + '_MASK', OName + '_MASK')); + AName := MName + '_LEFTANIM' + IntToStr(AIdx); + OName := MName + '_LEFTANIM' + IntToStr(OIdx); + if g_Frames_Exists(AName) then + begin + g_Frames_Dup(AName, OName); + g_Frames_Dup(AName + '_MASK', OName + '_MASK'); + end; + end; + + procedure r_PlayerModel_Load; + var ID1, ID2: DWORD; i, a, b: Integer; prefix, aname: String; 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'); + 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; + Models := nil; + if PlayerModelsArray <> nil then + begin + SetLength(Models, Length(PlayerModelsArray)); + for i := 0 to High(PlayerModelsArray) do + begin + prefix := PlayerModelsArray[i].FileName + ':TEXTURES\'; + for b := A_STAND to A_LAST do + begin + aname := PlayerModelsArray[i].Info.Name + '_RIGHTANIM' + IntToStr(b); + with PlayerModelsArray[i].Anim[TDirection.D_RIGHT, b] do + begin + if not (g_Frames_CreateWAD(@ID1, aname, prefix + Resource, 64, 64, Frames, Back) and + g_Frames_CreateWAD(@ID2, aname + '_MASK', prefix + Mask, 64, 64, Frames, Back)) then + begin + if b > A_LASTBASE then + begin + ExtAnimFromBaseAnim(PlayerModelsArray[i].Info.Name, b); + continue + end + end; + Models[i].Frames[TDirection.D_RIGHT, b].base := ID1; + Models[i].Frames[TDirection.D_RIGHT, b].mask := ID2; + end; + with PlayerModelsArray[i].Anim[TDirection.D_LEFT, b] do + begin + if (Resource <> '') and (Mask <> '') then + begin + aname := PlayerModelsArray[i].Info.Name + '_LEFTANIM' + IntToStr(b); + g_Frames_CreateWAD(@ID1, aname, prefix + Resource, 64, 64, Frames, Back); + g_Frames_CreateWAD(@ID2, aname + '_MASK', prefix + Mask, 64, 64, Frames, Back); + Models[i].Frames[TDirection.D_LEFT, b].base := ID1; + Models[i].Frames[TDirection.D_LEFT, b].mask := ID2; + end + end + end + end + end end; -end; - procedure r_PlayerModel_Finalize; - var a, b, c: Integer; + procedure r_PlayerModel_Free; + var i, a, b, c: Integer; begin + if PlayerModelsArray = nil then Exit; + for i := 0 to High(PlayerModelsArray) do + begin + with PlayerModelsArray[i] do + begin + for a := A_STAND to A_LAST do + begin + g_Frames_DeleteByName(Info.Name+'_LEFTANIM'+IntToStr(a)); + g_Frames_DeleteByName(Info.Name+'_LEFTANIM'+IntToStr(a)+'_MASK'); + g_Frames_DeleteByName(Info.Name+'_RIGHTANIM'+IntToStr(a)); + g_Frames_DeleteByName(Info.Name+'_RIGHTANIM'+IntToStr(a)+'_MASK'); + end; + if Gibs <> nil then + begin + for a := 0 to High(Gibs) do + begin + e_DeleteTexture(Gibs[a].ID); + e_DeleteTexture(Gibs[a].MaskID); + Gibs[a].ID := DWORD(-1); + Gibs[a].MaskID := DWORD(-1); + end + end + end + end; 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 @@ -67,6 +169,7 @@ var Mirror: TMirrorType; pos, act: Byte; p: TDFPoint; + FramesID: DWORD; begin // Флаги: if pm.Direction = TDirection.D_LEFT then @@ -90,7 +193,7 @@ begin else Mirror := TMirrorType.Horizontal; - if pm.DrawWeapon and (not (pm.CurrentAnimation in [A_DIE1, A_DIE2, A_PAIN])) and (pm.CurrentWeapon in [WP_FIRST + 1..WP_LAST]) then + if PlayerModelsArray[pm.id].Info.HaveWeapon and (not (pm.CurrentAnimation in [A_DIE1, A_DIE2, A_PAIN])) and (pm.CurrentWeapon in [WP_FIRST + 1..WP_LAST]) then begin if pm.CurrentAnimation in [A_SEEUP, A_ATTACKUP] then pos := W_POS_UP @@ -106,38 +209,45 @@ begin act := W_ACT_NORMAL; if Alpha < 201 then - e_Draw(WeaponID[pm.CurrentWeapon][pos][act], - X + pm.WeaponPoints[pm.CurrentWeapon, pm.CurrentAnimation, pm.Direction, - pm.Anim[TDirection.D_RIGHT][pm.CurrentAnimation].CurrentFrame].X, - Y + pm.WeaponPoints[pm.CurrentWeapon, pm.CurrentAnimation, pm.Direction, - pm.Anim[TDirection.D_RIGHT][pm.CurrentAnimation].CurrentFrame].Y, - 0, True, False, Mirror); + e_Draw( + WeaponID[pm.CurrentWeapon][pos][act], + X + PlayerModelsArray[pm.id].WeaponPoints[pm.CurrentWeapon, pm.CurrentAnimation, pm.Direction, pm.AnimState.CurrentFrame].X, + Y + PlayerModelsArray[pm.id].WeaponPoints[pm.CurrentWeapon, pm.CurrentAnimation, pm.Direction, pm.AnimState.CurrentFrame].Y, + 0, + True, + False, + Mirror + ); end; // Модель: - if (pm.Direction = TDirection.D_LEFT) and (pm.Anim[TDirection.D_LEFT][pm.CurrentAnimation] <> nil) then + if (pm.Direction = TDirection.D_LEFT) and (Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].base <> 0) then begin - pm.Anim[TDirection.D_LEFT][pm.CurrentAnimation].Alpha := Alpha; - r_Animation_Draw(pm.Anim[TDirection.D_LEFT][pm.CurrentAnimation], X, Y, TMirrorType.None); + pm.AnimState.Alpha := Alpha; // !!! + FramesID := Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].base; + r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, TMirrorType.None); end else begin - pm.Anim[TDirection.D_RIGHT][pm.CurrentAnimation].Alpha := Alpha; - r_Animation_Draw(pm.Anim[TDirection.D_RIGHT][pm.CurrentAnimation], X, Y, Mirror); + pm.AnimState.Alpha := Alpha; // !!! + FramesID := Models[pm.id].Frames[TDirection.D_RIGHT, pm.CurrentAnimation].base; + r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Mirror); end; // Маска модели: e_Colors := pm.Color; - if (pm.Direction = TDirection.D_LEFT) and (pm.MaskAnim[TDirection.D_LEFT][pm.CurrentAnimation] <> nil) then + if (pm.Direction = TDirection.D_LEFT) and (Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].mask <> 0) then begin - pm.MaskAnim[TDirection.D_LEFT][pm.CurrentAnimation].Alpha := Alpha; - r_Animation_Draw(pm.MaskAnim[TDirection.D_LEFT][pm.CurrentAnimation], X, Y, TMirrorType.None); + pm.AnimState.Alpha := Alpha; // !!! + FramesID := Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].mask; + r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, TMirrorType.None); end else begin - pm.MaskAnim[TDirection.D_RIGHT][pm.CurrentAnimation].Alpha := Alpha; - r_Animation_Draw(pm.MaskAnim[TDirection.D_RIGHT][pm.CurrentAnimation], X, Y, Mirror); + pm.AnimState.Alpha := Alpha; // !!! + FramesID := Models[pm.id].Frames[TDirection.D_RIGHT, pm.CurrentAnimation].mask; + r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Mirror); end; e_Colors.R := 255;