X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fopengl%2Fr_playermodel.pas;h=cc10d127d89fb67e0a73a1e191771e8328b3e842;hb=16342bee09fa001d05697571124e48a93cd35f2c;hp=f17be32d3e1ed99f8a1a6e9cd70761cb9ba0f0ac;hpb=79b65a82e3f122c0715a55b683ef2a92eff39a29;p=d2df-sdl.git diff --git a/src/game/opengl/r_playermodel.pas b/src/game/opengl/r_playermodel.pas index f17be32..cc10d12 100644 --- a/src/game/opengl/r_playermodel.pas +++ b/src/game/opengl/r_playermodel.pas @@ -17,7 +17,7 @@ unit r_playermodel; interface - uses g_playermodel; // TPlayerModel + uses g_playermodel, g_base; // TPlayerModel, TRectWH procedure r_PlayerModel_Initialize; procedure r_PlayerModel_Finalize; @@ -26,14 +26,22 @@ interface procedure r_PlayerModel_Update; procedure r_PlayerModel_Draw (pm: TPlayerModel; X, Y: Integer; Alpha: Byte = 0); + {$IFDEF ENABLE_GIBS} + procedure r_PlayerModel_DrawGibs; + function r_PlayerModel_GetGibRect (m, id: Integer): TRectWH; + {$ENDIF} + implementation uses + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} SysUtils, Classes, Math, - MAPDEF, utils, + MAPDEF, utils, e_log, wadreader, ImagingTypes, Imaging, ImagingUtility, r_graphics, g_options, r_animations, r_textures, - g_base, g_basic, g_map, g_weapons, g_textures + g_basic, g_map, g_weapons, g_textures, g_player, g_phys, g_game ; const @@ -50,11 +58,25 @@ implementation base: DWORD; mask: DWORD; end; + {$IFDEF ENABLE_GIBS} + Gibs: Array of record + base: DWORD; + mask: DWORD; + rect: TRectWH; + end; + {$ENDIF} end; RedFlagFrames: DWORD; BlueFlagFrames: DWORD; FlagAnimState: TAnimationState; +{$IFDEF ENABLE_GIBS} + function r_PlayerModel_GetGibRect (m, id: Integer): TRectWH; + begin + Result := Models[m].Gibs[id].rect + end; +{$ENDIF} + procedure r_PlayerModel_Initialize; begin FlagAnimState := TAnimationState.Create(True, 8, 5); @@ -96,7 +118,80 @@ implementation end; end; + procedure r_PlayerModel_LoadResource (resource: AnsiString; var pData: Pointer; var len: Integer); + var WAD: TWADFile; + begin + pData := nil; + len := 0; + WAD := TWADFile.Create; + WAD.ReadFile(g_ExtractWadName(resource)); + WAD.GetResource(g_ExtractFilePathName(resource), pData, len); + WAD.Free; + end; + + function g_PlayerModel_CalcGibSize (pData: Pointer; dataSize, x, y, w, h: Integer): TRectWH; + var i, j: Integer; done: Boolean; img: TImageData; + + function IsVoid (i, j: Integer): Boolean; + begin + result := Byte((PByte(img.bits) + (y+j)*img.width*4 + (x+i)*4 + 3)^) = 0 + end; + + begin + InitImage(img); + assert(LoadImageFromMemory(pData, dataSize, img)); + + (* trace x from right to left *) + done := false; i := 0; + while not done and (i < w) do + begin + j := 0; + while (j < h) and IsVoid(i, j) do inc(j); + done := (j < h) and (IsVoid(i, j) = false); + result.x := i; + inc(i); + end; + + (* trace y from up to down *) + done := false; j := 0; + while not done and (j < h) do + begin + i := 0; + while (i < w) and IsVoid(i, j) do inc(i); + done := (i < w) and (IsVoid(i, j) = false); + result.y := j; + inc(j); + end; + + (* trace x from right to left *) + done := false; i := w - 1; + while not done and (i >= 0) do + begin + j := 0; + while (j < h) and IsVoid(i, j) do inc(j); + done := (j < h) and (IsVoid(i, j) = false); + result.width := i - result.x + 1; + dec(i); + end; + + (* trace y from down to up *) + done := false; j := h - 1; + while not done and (j >= 0) do + begin + i := 0; + while (i < w) and IsVoid(i, j) do inc(i); + done := (i < w) and (IsVoid(i, j) = false); + result.height := j - result.y + 1; + dec(j); + end; + + FreeImage(img); + end; + procedure r_PlayerModel_Load; + {$IFDEF ENABLE_GIBS} + var base, mask: Pointer; baseLen, maskLen: Integer; + {$ENDIF} var ID1, ID2: DWORD; i, a, b: Integer; prefix, aname: String; begin g_Frames_CreateWAD(@RedFlagFrames, 'FRAMES_FLAG_RED', GameWAD + ':TEXTURES\FLAGRED', 64, 64, 5, False); @@ -145,7 +240,31 @@ implementation Models[i].Frames[TDirection.D_LEFT, b].mask := ID2; end end - end + end; + {$IFDEF ENABLE_GIBS} + SetLength(Models[i].Gibs, PlayerModelsArray[i].GibsCount); + if PlayerModelsArray[i].GibsCount > 0 then + begin + r_PlayerModel_LoadResource(prefix + PlayerModelsArray[i].GibsResource, base, baseLen); + r_PlayerModel_LoadResource(prefix + PlayerModelsArray[i].GibsMask, mask, maskLen); + if (base <> nil) and (mask <> nil) then + begin + for a := 0 to PlayerModelsArray[i].GibsCount - 1 do + begin + if e_CreateTextureMemEx(base, baseLen, Models[i].Gibs[a].base, a * 32, 0, 32, 32) and + e_CreateTextureMemEx(mask, maskLen, Models[i].Gibs[a].mask, a * 32, 0, 32, 32) then + begin + Models[i].Gibs[a].rect := g_PlayerModel_CalcGibSize(base, baseLen, a * 32, 0, 32, 32); + with Models[i].Gibs[a].Rect do + if Height > 3 then + Height := Height - 1 - Random(2); // ??? + end + end + end; + FreeMem(mask); + FreeMem(base); + end + {$ENDIF} end end end; @@ -167,17 +286,8 @@ implementation g_Frames_DeleteByName(Name + '_RIGHTANIM' + IntToStr(a)); g_Frames_DeleteByName(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 + // !!! delete gibs textures here end; for a := WP_FIRST + 1 to WP_LAST do for b := W_POS_NORMAL to W_POS_DOWN do @@ -220,7 +330,9 @@ begin FlagAnimState, X + IfThen(pm.Direction = TDirection.D_LEFT, fp.X - 1, 2 * FLAG_BASEPOINT.X - fp.X + 1) - FLAG_BASEPOINT.X, Y + fp.Y - FLAG_BASEPOINT.Y + 1, + 0, Mirror, + False, p, IfThen(pm.Direction = TDirection.D_RIGHT, fa, -fa) ); @@ -262,15 +374,13 @@ begin // Модель: if (pm.Direction = TDirection.D_LEFT) and (Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].base <> 0) then begin - 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); + r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Alpha, TMirrorType.None, False); end else begin - pm.AnimState.Alpha := Alpha; // !!! FramesID := Models[pm.id].Frames[TDirection.D_RIGHT, pm.CurrentAnimation].base; - r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Mirror); + r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Alpha, Mirror, False); end; // Маска модели: @@ -278,15 +388,13 @@ begin if (pm.Direction = TDirection.D_LEFT) and (Models[pm.id].Frames[TDirection.D_LEFT, pm.CurrentAnimation].mask <> 0) then begin - 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); + r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Alpha, TMirrorType.None, False); end else begin - pm.AnimState.Alpha := Alpha; // !!! FramesID := Models[pm.id].Frames[TDirection.D_RIGHT, pm.CurrentAnimation].mask; - r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Mirror); + r_AnimationState_Draw(FramesID, pm.AnimState, X, Y, Alpha, Mirror, False); end; e_Colors.R := 255; @@ -294,4 +402,34 @@ begin e_Colors.B := 255; end; +{$IFDEF ENABLE_GIBS} + procedure r_PlayerModel_DrawGibs; + var i, fX, fY, m, id: Integer; a: TDFPoint; pobj: ^TObj; + begin + if gGibs <> nil then + begin + for i := 0 to High(gGibs) do + begin + if gGibs[i].alive then + begin + pobj := @gGibs[i].Obj; + if not g_Obj_Collide(sX, sY, sWidth, sHeight, pobj) then + Continue; + pobj.lerp(gLerpFactor, fX, fY); + a.X := pobj.Rect.X + (pobj.Rect.Width div 2); + a.y := pobj.Rect.Y + (pobj.Rect.Height div 2); + m := gGibs[i].ModelID; + id := gGibs[i].GibID; + e_DrawAdv(Models[m].Gibs[id].base, fX, fY, 0, True, False, gGibs[i].RAngle, @a, TMirrorType.None); + e_Colors := gGibs[i].Color; + e_DrawAdv(Models[m].Gibs[id].mask, fX, fY, 0, True, False, gGibs[i].RAngle, @a, TMirrorType.None); + e_Colors.R := 255; + e_Colors.G := 255; + e_Colors.B := 255; + end + end + end + end; +{$ENDIF} + end.