X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Frenders%2Fopengl%2Fr_map.pas;h=e04405795493fda75933b7d211339e470ec91ad2;hb=fea837e895e2571f8ce3b5291f635d325e8c3756;hp=eff895d9b528d404a0560b035f1958efe48bf619;hpb=bd40762ed00ea73717966bb0e5a44ae73a179be0;p=d2df-sdl.git diff --git a/src/game/renders/opengl/r_map.pas b/src/game/renders/opengl/r_map.pas index eff895d..e044057 100644 --- a/src/game/renders/opengl/r_map.pas +++ b/src/game/renders/opengl/r_map.pas @@ -42,6 +42,7 @@ interface procedure r_Map_Update; procedure r_Map_Draw (x, y, w, h, camx, camy: Integer; player: TPlayer; out acx, acy: Integer); + procedure r_Map_GetSpectatorLimits (out x0, y0, x1, y1: Integer); implementation @@ -69,6 +70,11 @@ implementation ; const + MAXGIBW = 32; + MAXGIBH = 32; + + MAXMONW = 256; + MAXMONH = 128; MTABLE: array [0..MONSTER_MAN] of record w, h: Integer; end = ( @@ -97,6 +103,8 @@ implementation VILEFIRE_DX = 32; VILEFIRE_DY = 128; + MAXITEMW = 64; + MAXITEMH = 64; ItemAnim: array [0..ITEM_LAST] of record name: AnsiString; w, h: Integer; @@ -174,36 +182,37 @@ implementation ShotAnim: array [0..WEAPON_LAST] of record name: AnsiString; + x, y: Integer; w, h: Integer; anim: TAnimInfo; end = ( - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 0 KASTET - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 1 SAW - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 2 PISTOL - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 3 SHOTGUN1 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 4 SHOTGUN2 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 5 CHAINGUN - (name: 'BROCKET'; w: 64; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)), // 6 ROCKETLAUNCHER - (name: 'BPLASMA'; w: 16; h: 16; anim: (loop: true; delay: 5; frames: 2; back: false)), // 7 PLASMA - (name: 'BBFG'; w: 64; h: 64; anim: (loop: true; delay: 6; frames: 2; back: false)), // 8 BFG - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 9 SUPERPULEMET - (name: 'FLAME'; w: 32; h: 32; anim: (loop: true; delay: 6; frames: 0{11}; back: false)), // 10 FLAMETHROWER - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 11 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 12 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 13 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 14 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 15 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 16 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 17 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 18 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 19 - (name: ''; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 20 ZOMPY_PISTOL - (name: 'BIMPFIRE'; w: 16; h: 16; anim: (loop: true; delay: 4; frames: 2; back: false)), // 21 IMP_FIRE - (name: 'BBSPFIRE'; w: 16; h: 16; anim: (loop: true; delay: 4; frames: 2; back: false)), // 22 BSP_FIRE - (name: 'BCACOFIRE'; w: 16; h: 16; anim: (loop: true; delay: 4; frames: 2; back: false)), // 23 CACO_FIRE - (name: 'BBARONFIRE'; w: 64; h: 16; anim: (loop: true; delay: 4; frames: 2; back: false)), // 24 BARON_FIRE - (name: 'BMANCUBFIRE'; w: 64; h: 32; anim: (loop: true; delay: 4; frames: 2; back: false)), // 25 MANCUB_FIRE - (name: 'BSKELFIRE'; w: 64; h: 64; anim: (loop: true; delay: 5; frames: 2; back: false)) // 26 SKEL_FIRE + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 0 KASTET + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 1 SAW + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 2 PISTOL + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 3 SHOTGUN1 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 4 SHOTGUN2 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 5 CHAINGUN + (name: 'BROCKET'; x: 0; y: 0; w: 64; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)), // 6 ROCKETLAUNCHER + (name: 'BPLASMA'; x: 0; y: 0; w: 16; h: 16; anim: (loop: true; delay: 5; frames: 2; back: false)), // 7 PLASMA + (name: 'BBFG'; x: 6; y: 7; w: 64; h: 64; anim: (loop: true; delay: 6; frames: 2; back: false)), // 8 BFG + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 9 SUPERPULEMET + (name: 'FLAME'; x: 0; y: 0; w: 32; h: 32; anim: (loop: true; delay: 6; frames: 0{11}; back: false)), // 10 FLAMETHROWER + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 11 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 12 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 13 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 14 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 15 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 16 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 17 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 18 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 19 + (name: ''; x: 0; y: 0; w: 0; h: 0; anim: (loop: true; delay: 0; frames: 0; back: false)), // 20 ZOMPY_PISTOL + (name: 'BIMPFIRE'; x: 0; y: 0; w: 16; h: 16; anim: (loop: true; delay: 4; frames: 2; back: false)), // 21 IMP_FIRE + (name: 'BBSPFIRE'; x: 0; y: 0; w: 16; h: 16; anim: (loop: true; delay: 4; frames: 2; back: false)), // 22 BSP_FIRE + (name: 'BCACOFIRE'; x: 0; y: 0; w: 16; h: 16; anim: (loop: true; delay: 4; frames: 2; back: false)), // 23 CACO_FIRE + (name: 'BBARONFIRE'; x: 0; y: 0; w: 64; h: 16; anim: (loop: true; delay: 4; frames: 2; back: false)), // 24 BARON_FIRE + (name: 'BMANCUBFIRE'; x: 0; y: 0; w: 64; h: 32; anim: (loop: true; delay: 4; frames: 2; back: false)), // 25 MANCUB_FIRE + (name: 'BSKELFIRE'; x: 0; y: 0; w: 64; h: 64; anim: (loop: true; delay: 5; frames: 2; back: false)) // 26 SKEL_FIRE ); {$IFDEF ENABLE_SHELLS} @@ -232,6 +241,9 @@ implementation TMonsterAnims = array [0..ANIM_LAST, TDirection] of TGLMultiTexture; var + UseAccel: Boolean; + DebugFrames: Boolean; + DebugHealth: Boolean; DebugCameraScale: Single; FillOutsizeArea: Boolean; SkyTexture: TGLTexture; @@ -285,9 +297,9 @@ implementation class function TBinHeapPanelDrawCmp.less (const a, b: TPanel): Boolean; inline; begin - if a.tag < b.tag then begin result := true; exit; end; - if a.tag > b.tag then begin result := false; exit; end; - result := a.arrIdx < b.arrIdx; + if a.tag < b.tag then result := true + else if a.tag > b.tag then result := false + else result := a.arrIdx < b.arrIdx; end; procedure r_Map_Initialize; @@ -459,7 +471,7 @@ implementation end; {$ENDIF} // --------- shots --------- // - r_Common_SetLoading('Weapon splahses', WEAPON_LAST + 1); + r_Common_SetLoading('Weapon splashes', WEAPON_LAST + 1); for i := 0 to WEAPON_LAST do begin if ShotAnim[i].anim.frames > 0 then @@ -581,20 +593,21 @@ implementation end; procedure r_Map_DrawPanel (p: TPanel); - var Texture: Integer; t: TGLMultiTexture; tex: TGLTexture; count, frame: LongInt; a: TAnimInfo; + var Texture, x, y, w, h: Integer; t: TGLMultiTexture; count, frame: LongInt; a: TAnimInfo; begin ASSERT(p <> nil); + ASSERT(p.FCurTexture >= -1); (* p.FCurTexture = -1 -> invisible texture *) if p.FCurTexture >= 0 then begin + r_Common_GetPanelPos(p, x, y, w, h); ASSERT(p.FCurTexture <= High(p.TextureIDs)); Texture := p.TextureIDs[p.FCurTexture].Texture; - t := nil; - ASSERT(Texture >= -1); - ASSERT(Texture <= High(RenTextures)); + ASSERT(Texture >= -1); (* Texture = -1 -> texture not found *) if Texture >= 0 then begin + ASSERT(Texture <= High(RenTextures)); t := RenTextures[Texture].tex; - if (RenTextures[Texture].spec = 0) or (t <> nil) then + if t <> nil then begin count := 0; frame := 0; if p.AnimTime <= gTime then @@ -603,40 +616,66 @@ implementation a.loop := p.AnimLoop; g_Anim_GetFrameByTime(a, (gTime - p.AnimTime) DIV GAME_TICK, count, frame); end; - if t <> nil then - begin - tex := t.GetTexture(frame); - r_Draw_TextureRepeat(tex, p.x, p.y, p.width, p.height, false, 255, 255, 255, 255 - p.alpha, p.blending); - end - else - r_Draw_TextureRepeat(nil, p.x, p.y, p.width, p.height, false, 255, 255, 255, 255, false); + r_Draw_TextureRepeat(t.GetTexture(frame), x, y, w, h, false, 255, 255, 255, 255 - p.alpha, p.blending); + end + else if RenTextures[Texture].spec = 0 then + begin + r_Draw_TextureRepeat(nil, x, y, w, h, false, 255, 255, 255, 255, false); + end; + case RenTextures[Texture].spec of + TEXTURE_SPECIAL_WATER: r_Draw_Filter(x, y, x + w, y + h, 0, 0, 255, 255); + TEXTURE_SPECIAL_ACID1: r_Draw_Filter(x, y, x + w, y + h, 0, 230, 0, 255); + TEXTURE_SPECIAL_ACID2: r_Draw_Filter(x, y, x + w, y + h, 230, 0, 0, 255); end; + end + else + begin + r_Draw_TextureRepeat(nil, x, y, w, h, false, 255, 255, 255, 255, false); end; + end; + end; - if t = nil then + procedure r_Map_DrawPanels (constref panels: TPanelArray; drawDoors: Boolean = false); + var i: Integer; p: TPanel; + begin + if panels <> nil then + begin + for i := 0 to High(panels) do begin - case RenTextures[Texture].spec of - TEXTURE_SPECIAL_WATER: r_Draw_Filter(p.x, p.y, p.x + p.width, p.y + p.height, 0, 0, 255, 255); - TEXTURE_SPECIAL_ACID1: r_Draw_Filter(p.x, p.y, p.x + p.width, p.y + p.height, 0, 230, 0, 255); - TEXTURE_SPECIAL_ACID2: r_Draw_Filter(p.x, p.y, p.x + p.width, p.y + p.height, 230, 0, 0, 255); - end - end - end + p := panels[i]; + if p.enabled and not (drawDoors xor p.door) then + r_Map_DrawPanel(p); + end; + end; end; procedure r_Map_DrawPanelType (panelTyp: DWORD); - var tagMask, i: Integer; p: TPanel; + var tagMask: Integer; p: TPanel; begin - i := 0; - tagMask := PanelTypeToTag(panelTyp); - while plist.count > 0 do + if UseAccel then begin - p := TPanel(plist.Front()); - if (p.tag and tagMask) = 0 then - break; - r_Map_DrawPanel(p); - Inc(i); - plist.PopFront + tagMask := PanelTypeToTag(panelTyp); + while plist.count > 0 do + begin + p := TPanel(plist.Front()); + if (p.tag and tagMask) = 0 then + break; + r_Map_DrawPanel(p); + plist.PopFront; + end; + end + else + begin + case panelTyp of + PANEL_BACK: if g_rlayer_back then r_Map_DrawPanels(gRenderBackgrounds); + PANEL_STEP: if g_rlayer_step then r_Map_DrawPanels(gSteps); + PANEL_WALL: if g_rlayer_wall then r_Map_DrawPanels(gWalls); + PANEL_CLOSEDOOR: if g_rlayer_door then r_Map_DrawPanels(gWalls, True); + PANEL_ACID1: if g_rlayer_acid1 then r_Map_DrawPanels(gAcid1); + PANEL_ACID2: if g_rlayer_acid2 then r_Map_DrawPanels(gAcid2); + PANEL_WATER: if g_rlayer_water then r_Map_DrawPanels(gWater); + PANEL_FORE: if g_rlayer_fore then r_Map_DrawPanels(gRenderForegrounds); + end; end; end; @@ -645,26 +684,40 @@ implementation begin if ggItems <> nil then begin + (* hack: prevent visual disappearance *) + x := x - MAXITEMW; + y := y - MAXITEMH; + w := w + MAXITEMW*2; + h := h + MAXITEMH*2; for i := 0 to High(ggItems) do begin it := @ggItems[i]; if it.used and it.alive and (it.dropped = drop) and (it.ItemType > ITEM_NONE) and (it.ItemType <= ITEM_LAST) then begin - t := Items[it.ItemType].tex; - if g_Collide(it.obj.x, it.obj.y, t.width, t.height, x, y, w, h) then + r_Common_GetObjectPos(it.obj, xx, yy); + if g_Collide(xx + it.obj.rect.x, yy + it.obj.rect.y, it.obj.rect.width, it.obj.rect.height, x, y, w, h) then begin - r_Common_GetObjectPos(it.obj, xx, yy); + t := Items[it.ItemType].tex; tex := t.GetTexture(Items[it.ItemType].frame); r_Draw_TextureRepeat(tex, xx, yy, tex.width, tex.height, false, 255, 255, 255, 255, false); + if DebugFrames and not (gGameSettings.GameType in [GT_SERVER, GT_CLIENT]) then + begin + r_Draw_Rect( + xx + it.obj.rect.x, // it.obj.x + it.obj.rect.x, + yy + it.obj.rect.y, // it.obj.y + it.obj.rect.y, + xx + it.obj.rect.x + it.obj.rect.width, // it.obj.x + it.obj.rect.x + it.obj.rect.width, + yy + it.obj.rect.y + it.obj.rect.height, // it.obj.y + it.obj.rect.y + it.obj.rect.height, + 0, 255, 0, 255 + ); + end; end; end; end; end; - // TODO draw g_debug_frames end; function r_Map_GetMonsterTexture (m, a: Integer; d: TDirection; out t: TGLMultiTexture; out dx, dy: Integer; out flip: Boolean): Boolean; - // var c: Integer; + var w: Integer; begin t := nil; dx := 0; dy := 0; flip := false; result := MonTextures[m, a, d] <> nil; @@ -689,9 +742,8 @@ implementation end; if flip then begin -// c := (MONSTERTABLE[MonsterType].Rect.X - dx) + MONSTERTABLE[MonsterType].Rect.Width; -// dx := MTABLE[m].width - c - MONSTERTABLE[MonsterType].Rect.X; - dx := -dx; + if (m = MONSTER_SOUL) and (a = ANIM_DIE) then w := 64 else w := 0; + dx := -dx - w; end; end; end; @@ -714,19 +766,42 @@ implementation end; procedure r_Map_DrawMonster (constref mon: TMonster); - var m, a, xx, yy, dx, dy: Integer; d: TDirection; flip: Boolean; t: TGLMultiTexture; + var m, a, xx, yy, dx, dy: Integer; d, da: TDirection; flip: Boolean; t: TGLMultiTexture; begin m := mon.MonsterType; a := mon.MonsterAnim; d := mon.GameDirection; + (* hack: barrel tracks player, fix it in game logic *) + if m = MONSTER_BARREL then d := TDirection.D_LEFT; + + r_Common_GetObjectPos(mon.obj, xx, yy); if r_Map_GetMonsterTexture(m, a, d, t, dx, dy, flip) then begin - r_Common_GetObjectPos(mon.obj, xx, yy); - r_Draw_MultiTextureRepeat(t, mon.DirAnim[a, d], false, xx + dx, yy + dy, t.width, t.height, flip, 255, 255, 255, 255, false); + da := mon.GameDirection; + r_Draw_MultiTextureRepeat(t, mon.DirAnim[a, da], false, xx + dx, yy + dy, t.width, t.height, flip, 255, 255, 255, 255, false); + end; + if DebugFrames and not (gGameSettings.GameType in [GT_SERVER, GT_CLIENT]) then + begin + r_Draw_Rect( + xx + mon.obj.rect.x, // mon.obj.x + mon.obj.rect.x, + yy + mon.obj.rect.y, // mon.obj.y + mon.obj.rect.y, + xx + mon.obj.rect.x + mon.obj.rect.width, // mon.obj.x + mon.obj.rect.x + mon.obj.rect.width, + yy + mon.obj.rect.y + mon.obj.rect.height, // mon.obj.y + mon.obj.rect.y + mon.obj.rect.height, + 0, 255, 0, 255 + ); + end; + if DebugHealth and mon.alive and not (gGameSettings.GameType in [GT_SERVER, GT_CLIENT]) then + begin + r_Common_DrawText( + IntToStr(mon.MonsterHealth), + xx + mon.obj.rect.x + mon.obj.rect.width div 2, + yy + mon.obj.rect.y, + 255, 255, 255, 255, + stdfont, + TBasePoint.BP_DOWN + ); end; - - // TODO draw g_debug_frames end; procedure r_Map_DrawMonsters (x, y, w, h: Integer); @@ -734,6 +809,11 @@ implementation begin if gMonsters <> nil then begin + (* hack: prevent visual disappearance *) + x := x - MAXMONW; + y := y - MAXMONH; + w := w + MAXMONW*2; + h := h + MAXMONH*2; for i := 0 to High(gMonsters) do begin m := gMonsters[i]; @@ -904,6 +984,46 @@ implementation end; end; + procedure r_Map_DrawAim (p: TPlayer); + var x0, y0, x1, y1, a, len: Integer; + begin + ASSERT(p <> nil); + r_Common_GetPlayerPos(p, x0, y0); + x0 := x0 + WEAPONPOINT[p.Direction].X + IfThen(p.Direction = TDirection.D_LEFT, 7, -7); + y0 := y0 + WEAPONPOINT[p.Direction].Y; + a := p.Angle_; + len := 1024; + case p.CurrWeap of + WEAPON_KASTET: len := 12; + WEAPON_SAW: len := 24; + WEAPON_PISTOL, WEAPON_SHOTGUN1, WEAPON_SHOTGUN2, WEAPON_CHAINGUN, + WEAPON_ROCKETLAUNCHER, WEAPON_SUPERPULEMET, WEAPON_FLAMETHROWER: + begin + if a = ANGLE_RIGHTUP then DEC(a, 2); + if a = ANGLE_RIGHTDOWN then INC(a, 4); + if a = ANGLE_LEFTUP then INC(a, 2); + if a = ANGLE_LEFTDOWN then DEC(a, 4); + end; + WEAPON_PLASMA: + begin + if a = ANGLE_RIGHTUP then DEC(a, 1); + if a = ANGLE_RIGHTDOWN then INC(a, 3); + if a = ANGLE_LEFTUP then INC(a, 1); + if a = ANGLE_LEFTDOWN then DEC(a, 3); + end; + WEAPON_BFG: + begin + if a = ANGLE_RIGHTUP then DEC(a, 1); + if a = ANGLE_RIGHTDOWN then INC(a, 2); + if a = ANGLE_LEFTUP then INC(a, 1); + if a = ANGLE_LEFTDOWN then DEC(a, 2); + end; + end; + x1 := x0 + Trunc(Cos(-DegToRad(a)) * len); + y1 := y0 + Trunc(Sin(-DegToRad(a)) * len); + r_Draw_Line(x0, y0, x1, y1, 255, 0, 0, 158); + end; + procedure r_Map_DrawPlayer (p, drawed: TPlayer); var x, y, ax, ay, w, h: Integer; b, flip: Boolean; t: TGLMultiTexture; tex: TGLTexture; alpha: Byte; count, frame: LongInt; begin @@ -960,13 +1080,36 @@ implementation r_Map_DrawPlayerModel(p.Model, x, y, alpha); end; - // TODO draw g_debug_frames + + if DebugFrames and not (gGameSettings.GameType in [GT_SERVER, GT_CLIENT]) then + begin + r_Draw_Rect( + x + p.obj.rect.x, // p.obj.x + p.obj.rect.x, + y + p.obj.rect.y, // p.obj.y + p.obj.rect.y, + x + p.obj.rect.x + p.obj.rect.width, // p.obj.x + p.obj.rect.x + p.obj.rect.width, + y + p.obj.rect.y + p.obj.rect.height, // p.obj.y + p.obj.rect.y + p.obj.rect.height, + 0, 255, 0, 255 + ); + end; + + if DebugHealth and p.alive and not (gGameSettings.GameType in [GT_SERVER, GT_CLIENT]) then + begin + r_Common_DrawText( + IntToStr(p.health) + '/' + IntToStr(p.armor), + x + p.obj.rect.x + p.obj.rect.width div 2, + y - 24, + 255, 255, 255, 255, + stdfont, + TBasePoint.BP_DOWN + ); + end; if (gChatBubble > 0) and p.FKeys[KEY_CHAT].Pressed and (p.Ghost = false) then if (p.FMegaRulez[MR_INVIS] <= gTime) or ((drawed <> nil) and ((p = drawed) or (p.Team = drawed.Team) and (gGameSettings.GameMode <> GM_DM))) then r_Map_DrawTalkBubble(p); - // TODO draw aim + if gAimLine and p.alive and ((p = gPlayer1) or (p = gPlayer2)) then + r_Map_DrawAim(p); end; procedure r_Map_DrawPlayers (x, y, w, h: Integer; player: TPlayer); @@ -989,6 +1132,11 @@ implementation begin if gGibs <> nil then begin + (* hack: prevent visual disappearance *) + x := x - MAXGIBW; + y := y - MAXGIBH; + w := w + MAXGIBW*2; + h := h + MAXGIBH*2; for i := 0 to High(gGibs) do begin if gGibs[i].alive then @@ -1015,7 +1163,6 @@ implementation end; end; end; - // TODO draw g_debug_frames end; {$ENDIF} @@ -1035,7 +1182,6 @@ implementation end; end; end; - // TODO draw g_debug_frames end; {$ENDIF} @@ -1197,12 +1343,21 @@ implementation pY := Shots[i].Obj.Rect.Height div 2; g_Anim_GetFrameByTime(ShotAnim[typ].anim, (gTime - Shots[i].time) DIV GAME_TICK, count, frame); tex := t.GetTexture(frame); - r_Draw_TextureRepeatRotate(tex, xx, yy, tex.width, tex.height, false, 255, 255, 255, 255, false, pX, pY, a); + r_Draw_TextureRepeatRotate(tex, xx - ShotAnim[typ].x, yy - ShotAnim[typ].y, tex.width, tex.height, false, 255, 255, 255, 255, false, pX, pY, a); + if DebugFrames and not (gGameSettings.GameType in [GT_SERVER, GT_CLIENT]) then + begin + r_Draw_Rect( + xx + Shots[i].obj.rect.x, // Shots[i].obj.x + Shots[i].obj.rect.x, + yy + Shots[i].obj.rect.y, // Shots[i].obj.y + Shots[i].obj.rect.y, + xx + Shots[i].obj.rect.x + Shots[i].obj.rect.width, // Shots[i].obj.x + Shots[i].obj.rect.x + Shots[i].obj.rect.width, + yy + Shots[i].obj.rect.y + Shots[i].obj.rect.height, // Shots[i].obj.y + Shots[i].obj.rect.y + Shots[i].obj.rect.height, + 0, 255, 0, 255 + ); + end; end; end; end; end; - // TODO draw g_debug_frames end; procedure r_Map_DrawFlags (x, y, w, h: Integer); @@ -1219,11 +1374,20 @@ implementation if flip then dx := -1 else dx := +1; t := FlagTextures[i]; tex := t.GetTexture(FlagFrame); - r_Draw_TextureRepeat(tex, xx + dx, yy + 1, tex.width, tex.height, flip, 255, 255, 255, 255, false) + r_Draw_TextureRepeat(tex, xx + dx, yy + 1, tex.width, tex.height, flip, 255, 255, 255, 255, false); + if DebugFrames and not (gGameSettings.GameType in [GT_SERVER, GT_CLIENT]) then + begin + r_Draw_Rect( + xx + gFlags[i].obj.rect.x, // gFlags[i].obj.x + gFlags[i].obj.rect.x, + yy + gFlags[i].obj.rect.y, // gFlags[i].obj.y + gFlags[i].obj.rect.y, + xx + gFlags[i].obj.rect.x + gFlags[i].obj.rect.width, // gFlags[i].obj.x + gFlags[i].obj.rect.x + gFlags[i].obj.rect.width, + yy + gFlags[i].obj.rect.y + gFlags[i].obj.rect.height, // gFlags[i].obj.y + gFlags[i].obj.rect.y + gFlags[i].obj.rect.height, + 0, 255, 0, 255 + ); + end; end; end; end; - // TODO g_debug_frames end; {$IFDEF ENABLE_SHELLS} @@ -1414,16 +1578,34 @@ implementation end; end; + function r_Map_GetDrawableGridMask (): Integer; + var mask: Integer; + begin + mask := 0; + if g_rlayer_back then mask := mask or GridTagBack; + if g_rlayer_step then mask := mask or GridTagStep; + if g_rlayer_wall then mask := mask or GridTagWall; + if g_rlayer_door then mask := mask or GridTagDoor; + if g_rlayer_acid1 then mask := mask or GridTagAcid1; + if g_rlayer_acid2 then mask := mask or GridTagAcid2; + if g_rlayer_water then mask := mask or GridTagWater; + if g_rlayer_fore then mask := mask or GridTagFore; + result := mask; + end; + procedure r_Map_DrawGame (xx, yy, ww, hh: Integer; player: TPlayer); (* xx/yy/ww/hh are in map units *) var iter: TPanelGrid.Iter; p: PPanel; begin - plist.Clear; - iter := mapGrid.ForEachInAABB(xx, yy, ww, hh, GridDrawableMask); - for p in iter do - if ((p^.tag and GridTagDoor) <> 0) = p^.door then - plist.Insert(p^); - iter.Release; + if UseAccel then + begin + plist.Clear; + iter := mapGrid.ForEachInAABB(xx, yy, ww, hh, r_Map_GetDrawableGridMask()); + for p in iter do + if ((p^.tag and GridTagDoor) <> 0) = p^.door then + plist.Insert(p^); + iter.Release; + end; r_Map_DrawPanelType(PANEL_BACK); r_Map_DrawPanelType(PANEL_STEP); @@ -1452,8 +1634,6 @@ implementation r_Map_DrawPanelType(PANEL_ACID2); r_Map_DrawPanelType(PANEL_WATER); r_Map_DrawPanelType(PANEL_FORE); - // TODO draw monsters health bar - // TODO draw players health bar end; procedure r_Map_DrawScaled (w, h, camx, camy: Integer; player: TPlayer; out acx, acy, acw, ach, axx, ayy, aww, ahh: Integer); @@ -1528,9 +1708,10 @@ implementation glTranslatef(-w div 2, -h div 2, 0); end; - if SkyTexture <> nil then + if gDrawBackGround and (SkyTexture <> nil) then begin r_Map_CalcSkyParallax(cx, cy, w, h, SkyTexture.width, SkyTexture.height, gMapInfo.Width, gMapInfo.Height, sx, sy, sw, sh); + r_Draw_SetFilter(SkyTexture, gTextureFilter); r_Draw_Texture(SkyTexture, sx, sy, sw, sh, false, 255, 255, 255, 255, false); end; @@ -1572,8 +1753,6 @@ implementation r_Map_DrawPlayerIndicators(player, cx, cy, cw, ch); end; - // TODO draw g_debug_player - //glTranslatef(-x, -y, 0); r_Draw_SetRect(l, t, r, b); glPopMatrix; @@ -1598,9 +1777,43 @@ implementation g_Anim_GetFrameByTime(FlagAnim, tick, count, FlagFrame); end; + procedure r_Map_GetSpectatorLimits (out x0, y0, x1, y1: Integer); + var w, h: Integer; + begin + w := Round(gScreenWidth / g_dbg_scale); + if gMapInfo.Width > w then + begin + x0 := w div 2; + x1 := gMapInfo.Width - w div 2 - 1; + end + else + begin + x0 := gMapInfo.Width div 2; + x1 := gMapInfo.Width div 2; + end; + + h := Round(gScreenHeight / g_dbg_scale); + if gMapInfo.Height > h then + begin + y0 := h div 2; + y1 := gMapInfo.Height - h div 2 - 1; + end + else + begin + y0 := gMapInfo.Height div 2; + y1 := gMapInfo.Height div 2; + end; + end; + initialization + conRegVar('r_sq_draw', @UseAccel, 'accelerated spatial queries in rendering', 'accelerated rendering'); conRegVar('r_debug_camera_scale', @DebugCameraScale, 0.0001, 1000.0, '', ''); conRegVar('r_gl_fill_outside', @FillOutsizeArea, '', ''); + conRegVar('d_frames', @DebugFrames, '', ''); + conRegVar('d_health', @DebugHealth, '', ''); + UseAccel := true; DebugCameraScale := 1.0; FillOutsizeArea := true; + DebugFrames := false; + DebugHealth := false; end.