index 326fcd0e4317b77693e6174d74fbfb2e4cf58fb2..371b13db5ac8810e30444257144ad501c272054e 100644 (file)
procedure r_Map_DrawPlayerModel (pm: TPlayerModel; x, y: Integer; alpha: Byte);
{$ENDIF}
+ procedure r_Map_Reset;
procedure r_Map_Update;
procedure r_Map_Draw (x, y, w, h, camx, camy: Integer; player: TPlayer; out acx, acy: Integer);
TMonsterAnims = array [0..ANIM_LAST, TDirection] of TGLMultiTexture;
var
+ UseAccel: Boolean;
+ DebugFrames: Boolean;
+ DebugHealth: Boolean;
DebugCameraScale: Single;
FillOutsizeArea: Boolean;
SkyTexture: TGLTexture;
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;
r_Common_FreeAndNil(Items[i].tex);
end;
+ procedure r_Map_FreeTextures;
+ var i: Integer;
+ begin
+ plist.Clear;
+ r_Common_FreeAndNil(SkyTexture);
+ if RenTextures <> nil then
+ for i := 0 to High(RenTextures) do
+ r_Common_FreeAndNil(RenTextures[i].tex);
+ SetLength(RenTextures, 0);
+ end;
+
procedure r_Map_LoadTextures;
const DefaultAnimInfo: TAnimInfo = (loop: true; delay: 1; frames: 1; back: false);
var i, n: Integer; txt: TAnimTextInfo;
begin
+ r_Map_FreeTextures;
if Textures <> nil then
begin
n := Length(Textures);
r_Common_SetLoading(_lc[I_LOAD_TEXTURES], n);
for i := 0 to n - 1 do
begin
- txt.anim := DefaultAnimInfo;
RenTextures[i].tex := nil;
+ RenTextures[i].anim := DefaultAnimInfo;
case Textures[i].TextureName of
TEXTURE_NAME_WATER: RenTextures[i].spec := TEXTURE_SPECIAL_WATER;
TEXTURE_NAME_ACID1: RenTextures[i].spec := TEXTURE_SPECIAL_ACID1;
else
RenTextures[i].spec := 0;
RenTextures[i].tex := r_Textures_LoadMultiTextFromFile(Textures[i].FullName, txt, []);
- if RenTextures[i].tex = nil then
- e_LogWritefln('r_Map_LoadTextures: failed to load texture: %s', [Textures[i].FullName])
- else
+ if RenTextures[i].tex <> nil then
+ begin
+ RenTextures[i].anim := txt.anim;
r_Common_StepLoading(1);
+ end
+ else
+ begin
+ e_LogWritefln('r_Map_LoadTextures: failed to load texture: %s', [Textures[i].FullName]);
+ end;
end;
- RenTextures[i].anim := txt.anim;
+ ASSERT(RenTextures[i].anim.frames > 0);
+ ASSERT(RenTextures[i].anim.delay > 0);
end;
end;
if gMapInfo.SkyFullName <> '' then
plist.Clear;
end;
- procedure r_Map_FreeTextures;
- var i: Integer;
- begin
- plist.Clear;
- r_Common_FreeAndNil(SkyTexture);
- if RenTextures <> nil then
- for i := 0 to High(RenTextures) do
- r_Common_FreeAndNil(RenTextures[i].tex);
- SetLength(RenTextures, 0);
- end;
-
procedure r_Map_DrawPanel (p: TPanel);
- var Texture: Integer; t: TGLMultiTexture; tex: TGLTexture; count, frame: LongInt; a: TAnimInfo;
+ var Texture, spec: 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
+ ASSERT(p.FCurTexture <= High(p.TextureIDs));
Texture := p.TextureIDs[p.FCurTexture].Texture;
- t := RenTextures[Texture].tex;
- if (RenTextures[Texture].spec = 0) or (t <> nil) then
+ ASSERT(Texture >= -1); (* Texture = -1 -> texture not found *)
+ if Texture >= 0 then
begin
- count := 0; frame := 0;
- if p.AnimTime <= gTime then
- begin
- a := RenTextures[Texture].anim;
- a.loop := p.AnimLoop;
- g_Anim_GetFrameByTime(a, (gTime - p.AnimTime) DIV GAME_TICK, count, frame);
- end;
+ ASSERT(Texture <= High(RenTextures));
+ t := RenTextures[Texture].tex;
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);
+ count := 0; frame := 0;
+ if p.AnimTime <= gTime then
+ begin
+ a := RenTextures[Texture].anim;
+ a.loop := p.AnimLoop;
+ g_Anim_GetFrameByTime(a, (gTime - p.AnimTime) DIV GAME_TICK, count, frame);
+ end;
+ r_Draw_TextureRepeat(t.GetTexture(frame), p.x, p.y, p.width, p.height, false, 255, 255, 255, 255 - p.alpha, p.blending);
end
- else
+ else if RenTextures[Texture].spec = 0 then
+ begin
r_Draw_TextureRepeat(nil, p.x, p.y, p.width, p.height, false, 255, 255, 255, 255, false);
- end;
-
- if t = nil then
- begin
+ end;
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
- end
+ else
+ begin
+ r_Draw_TextureRepeat(nil, p.x, p.y, p.width, p.height, false, 255, 255, 255, 255, false);
+ end;
+ end;
+ end;
+
+ 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
+ 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
+ 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
- p := TPanel(plist.Front());
- if (p.tag and tagMask) = 0 then
- break;
- r_Map_DrawPanel(p);
- Inc(i);
- plist.PopFront
+ 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;
r_Common_GetObjectPos(it.obj, xx, yy);
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 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;
a := mon.MonsterAnim;
d := mon.GameDirection;
+ 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);
end;
-
- // TODO draw g_debug_frames
+ if DebugFrames 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 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;
end;
procedure r_Map_DrawMonsters (x, y, w, h: Integer);
end;
procedure r_Map_DrawBubble (x, y: Integer; cb, cf: TRGB);
- var dot: Integer;
+ const w = 20; h = 14;
+ const dx = 6; dy = 8; dot = 6; size = 2;
+ const tx = 6; ty = h - 1;
begin
- // Outer borders
- r_Draw_Rect(x + 1, y, x + 18, y + 13, cb.R, cb.G, cb.B, 255);
- r_Draw_Rect(x, y + 1, x + 19, y + 12, cb.R, cb.G, cb.B, 255);
+ // Outer box (top/down)
+ r_Draw_FillRect(x + 1, y, x + w - 1, y + 1, cb.R, cb.G, cb.B, 255);
+ r_Draw_FillRect(x + 1, y + h - 1, x + w - 1, y + h, cb.R, cb.G, cb.B, 255);
+ // Outer box (left/right)
+ r_Draw_FillRect(x, y + 1, x + 1, y + h - 1, cb.R, cb.G, cb.B, 255);
+ r_Draw_FillRect(x + w - 1, y + 1, x + w, y + h - 1, cb.R, cb.G, cb.B, 255);
+ // Outer tail
+ r_Draw_FillRect(x + tx - 1, y + ty + 0, x + tx + 3 + 1, y + ty + 1, cb.R, cb.G, cb.B, 255);
+ r_Draw_FillRect(x + tx - 1, y + ty + 1, x + tx + 2 + 1, y + ty + 2, cb.R, cb.G, cb.B, 255);
+ r_Draw_FillRect(x + tx - 1, y + ty + 2, x + tx + 1 + 1, y + ty + 3, cb.R, cb.G, cb.B, 255);
+ r_Draw_FillRect(x + tx - 1, y + ty + 3, x + tx + 0 + 1, y + ty + 4, cb.R, cb.G, cb.B, 255);
+ // Inner tail
+ r_Draw_FillRect(x + tx, y + ty + 0, x + tx + 3, y + ty + 1, cf.R, cf.G, cf.B, 255);
+ r_Draw_FillRect(x + tx, y + ty + 1, x + tx + 2, y + ty + 2, cf.R, cf.G, cf.B, 255);
+ r_Draw_FillRect(x + tx, y + ty + 2, x + tx + 1, y + ty + 3, cf.R, cf.G, cf.B, 255);
// Inner box
- r_Draw_FillRect(x + 1, y + 1, x + 18, y + 12, cf.R, cf.G, cf.B, 255);
- // TODO Tail
+ r_Draw_FillRect(x + 1, y + 1, x + w - 1, y + h - 1, cf.R, cf.G, cf.B, 255);
// Dots
- dot := 6;
- r_Draw_FillRect(x + dot + 0, y + 8, x + dot + 0 + 1 + 1, y + 9 + 1, cb.R, cb.G, cb.B, 255);
- r_Draw_FillRect(x + dot + 3, y + 8, x + dot + 3 + 1 + 1, y + 9 + 1, cb.R, cb.G, cb.B, 255);
- r_Draw_FillRect(x + dot + 6, y + 8, x + dot + 6 + 1 + 1, y + 9 + 1, cb.R, cb.G, cb.B, 255);
+ r_Draw_FillRect(x + dx + 0*3, y + dy, x + dx + 0*3 + size, y + dy + size, cb.R, cb.G, cb.B, 255);
+ r_Draw_FillRect(x + dx + 1*3, y + dy, x + dx + 1*3 + size, y + dy + size, cb.R, cb.G, cb.B, 255);
+ r_Draw_FillRect(x + dx + 2*3, y + dy, x + dx + 2*3 + size, y + dy + size, cb.R, cb.G, cb.B, 255);
end;
procedure r_Map_DrawTalkBubble (p: TPlayer);
r_Map_DrawPlayerModel(p.Model, x, y, alpha);
end;
- // TODO draw g_debug_frames
+
+ if DebugFrames 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 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
end;
end;
end;
- // TODO draw g_debug_frames
end;
{$ENDIF}
end;
end;
end;
- // TODO draw g_debug_frames
end;
{$ENDIF}
end;
end;
+ procedure r_Map_ResetGFX;
+ begin
+ SetLength(gfxlist, 0);
+ end;
+
procedure r_Map_UpdateGFX (tick: LongWord);
var i: Integer; count: LongInt;
begin
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);
+ if DebugFrames 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);
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 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}
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);
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);
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_Texture(SkyTexture, sx, sy, sw, sh, false, 255, 255, 255, 255, false);
r_Map_DrawGame(xx, yy, ww, hh, player);
if FillOutsizeArea and (DebugCameraScale = 1.0) then
begin
- r_Draw_FillRect(0 - limit, 0 - limit, gMapInfo.Width + limit, 0 - 1, 0, 0, 0, 255);
- r_Draw_FillRect(0 - limit, 0, 0 - 1, gMapInfo.Height + limit, 0, 0, 0, 255);
- r_Draw_FillRect(gMapInfo.Width, 0, gMapInfo.Width + limit, gMapInfo.Height + limit, 0, 0, 0, 255);
- r_Draw_FillRect(0 - limit, gMapInfo.Height, gMapInfo.Width + limit, gMapInfo.Height + limit, 0, 0, 0, 255);
+ (* top *) r_Draw_FillRect(0 - limit, 0 - limit, gMapInfo.Width + limit, 0, 0, 0, 0, 255);
+ (* left *) r_Draw_FillRect(0 - limit, 0, 0, gMapInfo.Height + limit, 0, 0, 0, 255);
+ (* right *) r_Draw_FillRect(gMapInfo.Width, 0, gMapInfo.Width + limit, gMapInfo.Height + limit, 0, 0, 0, 255);
+ (* bottom *) r_Draw_FillRect(0 - limit, gMapInfo.Height, gMapInfo.Width + limit, gMapInfo.Height + limit, 0, 0, 0, 255);
end;
glTranslatef(cx, cy, 0);
end;
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;
r_Map_DrawScreenEffects(x, y, w, h, player);
end;
+ procedure r_Map_Reset;
+ begin
+ {$IFDEF ENABLE_GFX}
+ r_Map_ResetGFX;
+ {$ENDIF}
+ end;
+
procedure r_Map_Update;
var i, count, tick: LongInt;
begin
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.