diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 73c8ddf3a8c60127b66c8c7a37349a50b52abad2..d1ffd7ade5d35568897b3a5b825e0ec55a682da4 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
procedure g_Game_ClientWAD(NewWAD: String; WHash: TMD5Digest);
procedure g_Game_SaveOptions();
function g_Game_StartMap(Map: String; Force: Boolean = False; const oldMapPath: AnsiString=''): Boolean;
-procedure g_Game_ChangeMap(MapPath: String);
-procedure g_Game_ExitLevel(Map: Char16);
+procedure g_Game_ChangeMap(const MapPath: String);
+procedure g_Game_ExitLevel(const Map: AnsiString);
function g_Game_GetFirstMap(WAD: String): String;
function g_Game_GetNextMap(): String;
procedure g_Game_NextLevel();
g_rlayer_water: Boolean = true;
g_rlayer_fore: Boolean = true;
- g_dbg_scale: Single = 1.0;
-
procedure g_ResetDynlights ();
procedure g_AddDynLight (x, y, radius: Integer; r, g, b, a: Single);
implementation
uses
- g_textures, g_main, g_window, g_menu,
+ e_texture, g_textures, g_main, g_window, g_menu,
e_input, e_log, g_console, g_items, g_map, g_panel,
g_playermodel, g_gfx, g_options, g_weapons, Math,
g_triggers, g_monsters, e_sound, CONFIG,
end;
+procedure renderAmbientQuad (hasAmbient: Boolean; constref ambColor: TDFColor);
+begin
+ if not hasAmbient then exit;
+ e_AmbientQuad(sX, sY, sWidth, sHeight, ambColor.r, ambColor.g, ambColor.b, ambColor.a);
+end;
+
+
// setup sX, sY, sWidth, sHeight, and transformation matrix before calling this!
+//FIXME: broken for splitscreen mode
procedure renderDynLightsInternal ();
var
+ //hasAmbient: Boolean;
+ //ambColor: TDFColor;
lln: Integer;
lx, ly, lrad: Integer;
+ scxywh: array[0..3] of GLint;
+ wassc: Boolean;
begin
+ if e_NoGraphics then exit;
+
//TODO: lights should be in separate grid, i think
// but on the other side: grid may be slower for dynlights, as their lifetime is short
- if not gwin_has_stencil or (g_dynLightCount < 1) then exit;
+ if (not g_playerLight) or (not gwin_has_stencil) or (g_dynLightCount < 1) then exit;
+
+ // rendering mode
+ //ambColor := gCurrentMap['light_ambient'].rgba;
+ //hasAmbient := (not ambColor.isOpaque) or (not ambColor.isBlack);
+
+ { // this will multiply incoming color to alpha from framebuffer
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_DST_ALPHA, GL_ONE);
+ }
+
+ (*
+ * light rendering: (INVALID!)
+ * glStencilFunc(GL_EQUAL, 0, $ff);
+ * for each light:
+ * glClear(GL_STENCIL_BUFFER_BIT);
+ * glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
+ * draw shadow volume into stencil buffer
+ * glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // modify color buffer
+ * glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // don't modify stencil buffer
+ * turn off blending
+ * draw color-less quad with light alpha (WARNING! don't touch color!)
+ * glEnable(GL_BLEND);
+ * glBlendFunc(GL_DST_ALPHA, GL_ONE);
+ * draw all geometry up to and including walls (with alpha-testing, probably) -- this does lighting
+ *)
+
+ wassc := (glIsEnabled(GL_SCISSOR_TEST) <> 0);
+ if wassc then glGetIntegerv(GL_SCISSOR_BOX, @scxywh[0]) else glGetIntegerv(GL_VIEWPORT, @scxywh[0]);
// setup OpenGL parameters
glStencilMask($FFFFFFFF);
lx := g_dynLights[lln].x;
ly := g_dynLights[lln].y;
lrad := g_dynLights[lln].radius;
- if lrad < 3 then continue;
+ if (lrad < 3) then continue;
- if lx-sX+lrad < 0 then continue;
- if ly-sY+lrad < 0 then continue;
- if lx-sX-lrad >= gPlayerScreenSize.X then continue;
- if ly-sY-lrad >= gPlayerScreenSize.Y then continue;
+ if (lx-sX+lrad < 0) then continue;
+ if (ly-sY+lrad < 0) then continue;
+ if (lx-sX-lrad >= gPlayerScreenSize.X) then continue;
+ if (ly-sY-lrad >= gPlayerScreenSize.Y) then continue;
// set scissor to optimize drawing
- //FIXME: broken for splitscreen mode
- glScissor((lx-sX)-lrad+2, gPlayerScreenSize.Y-(ly-sY)-lrad-1+2, lrad*2-4, lrad*2-4);
- // no need to clear stencil buffer, light blitting will do it for us
+ if (g_dbg_scale = 1.0) then
+ begin
+ glScissor((lx-sX)-lrad+2, gPlayerScreenSize.Y-(ly-sY)-lrad-1+2, lrad*2-4, lrad*2-4);
+ end
+ else
+ begin
+ glScissor(0, 0, gWinSizeX, gWinSizeY);
+ end;
+ // no need to clear stencil buffer, light blitting will do it for us... but only for normal scale
+ if (g_dbg_scale <> 1.0) then glClear(GL_STENCIL_BUFFER_BIT);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
// draw extruded panels
glDisable(GL_TEXTURE_2D);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
glDisable(GL_SCISSOR_TEST);
- glScissor(0, 0, sWidth, sHeight);
+ //glScissor(0, 0, sWidth, sHeight);
+
+ glScissor(scxywh[0], scxywh[1], scxywh[2], scxywh[3]);
+ if wassc then glEnable(GL_SCISSOR_TEST) else glDisable(GL_SCISSOR_TEST);
end;
@@ -2806,6 +2856,11 @@ procedure renderMapInternal (backXOfs, backYOfs: Integer; setTransMatrix: Boolea
type
TDrawCB = procedure ();
+var
+ hasAmbient: Boolean;
+ ambColor: TDFColor;
+ doAmbient: Boolean = false;
+
procedure drawPanelType (profname: AnsiString; panType: DWord; doDraw: Boolean);
var
tagmask: Integer;
begin
pan := TPanel(gDrawPanelList.front());
if ((pan.tag and tagmask) = 0) then break;
- if doDraw then pan.Draw();
+ if doDraw then pan.Draw(doAmbient, ambColor);
gDrawPanelList.popFront();
end;
end
else
begin
- if doDraw then g_Map_DrawPanels(panType);
+ if doDraw then g_Map_DrawPanels(panType, hasAmbient, ambColor);
end;
profileFrameDraw.sectionEnd();
end;
if setTransMatrix then
begin
+ //if (g_dbg_scale <> 1.0) then glTranslatef(0.0, -0.375/2, 0);
glScalef(g_dbg_scale, g_dbg_scale, 1.0);
glTranslatef(-sX, -sY, 0);
end;
+ // rendering mode
+ ambColor := gCurrentMap['light_ambient'].rgba;
+ hasAmbient := (not ambColor.isOpaque) or (not ambColor.isBlack);
+
+ {
+ if hasAmbient then
+ begin
+ //writeln('color: (', ambColor.r, ',', ambColor.g, ',', ambColor.b, ',', ambColor.a, ')');
+ glColor4ub(ambColor.r, ambColor.g, ambColor.b, ambColor.a);
+ glClear(GL_COLOR_BUFFER_BIT);
+ end;
+ }
+ //writeln('color: (', ambColor.r, ',', ambColor.g, ',', ambColor.b, ',', ambColor.a, ')');
+
+
drawPanelType('*back', PANEL_BACK, g_rlayer_back);
drawPanelType('*step', PANEL_STEP, g_rlayer_step);
drawOther('items', @g_Items_Draw);
drawPanelType('*acid2', PANEL_ACID2, g_rlayer_acid2);
drawPanelType('*water', PANEL_WATER, g_rlayer_water);
drawOther('dynlights', @renderDynLightsInternal);
+
+ if hasAmbient {and ((not g_playerLight) or (not gwin_has_stencil) or (g_dynLightCount < 1))} then
+ begin
+ renderAmbientQuad(hasAmbient, ambColor);
+ end;
+
+ doAmbient := true;
drawPanelType('*fore', PANEL_FORE, g_rlayer_fore);
+
if g_debug_HealthBar then
begin
g_Monsters_DrawHealth();
g_Options_Write_Video(GameDir+'/'+CONFIG_FILENAME);
end;
-procedure g_Game_ChangeMap(MapPath: String);
+procedure g_Game_ChangeMap(const MapPath: String);
var
Force: Boolean;
begin
MapList := nil;
end;
-procedure g_Game_ExitLevel(Map: Char16);
+procedure g_Game_ExitLevel(const Map: AnsiString);
begin
gNextMap := Map;
procedure g_Game_DeleteTestMap();
var
a: Integer;
- MapName: Char16;
+ //MapName: AnsiString;
WadName: string;
{
WAD: TWADFile;
begin
a := Pos('.wad:\', toLowerCase1251(gMapToDelete));
if (a = 0) then a := Pos('.wad:/', toLowerCase1251(gMapToDelete));
- if a = 0 then
- Exit;
+ if (a = 0) then exit;
-// Âûäåëÿåì èìÿ wad-ôàéëà è èìÿ êàðòû:
- WadName := Copy(gMapToDelete, 1, a + 3);
- Delete(gMapToDelete, 1, a + 5);
+ // Âûäåëÿåì èìÿ wad-ôàéëà è èìÿ êàðòû
+ WadName := Copy(gMapToDelete, 1, a+3);
+ Delete(gMapToDelete, 1, a+5);
gMapToDelete := UpperCase(gMapToDelete);
- MapName := '';
- CopyMemory(@MapName[0], @gMapToDelete[1], Min(16, Length(gMapToDelete)));
+ //MapName := '';
+ //CopyMemory(@MapName[0], @gMapToDelete[1], Min(16, Length(gMapToDelete)));
{
// Èìÿ êàðòû íå ñòàíäàðòíîå òåñòîâîå:
end;
end;
+procedure PrintHeapStats();
+var
+ hs: TFPCHeapStatus;
+begin
+ hs := GetFPCHeapStatus();
+ e_LogWriteLn ('v===== heap status =====v');
+ e_LogWriteFln('max heap size = %d k', [hs.MaxHeapSize div 1024]);
+ e_LogWriteFln('max heap used = %d k', [hs.MaxHeapUsed div 1024]);
+ e_LogWriteFln('cur heap size = %d k', [hs.CurrHeapSize div 1024]);
+ e_LogWriteFln('cur heap used = %d k', [hs.CurrHeapUsed div 1024]);
+ e_LogWriteFln('cur heap free = %d k', [hs.CurrHeapFree div 1024]);
+ e_LogWriteLn ('^=======================^');
+end;
procedure DebugCommands(P: SArray);
var
begin
for a := 1 to 8 do
g_Console_Add(e_JoystickStateToString(a));
+ end
+ else if (cmd = 'd_mem') then
+ begin
+ PrintHeapStats();
end;
end
else
conRegVar('dbg_holmes', @g_holmes_enabled, 'enable/disable Holmes', 'Holmes', true);
- conRegVar('dbg_scale', @g_dbg_scale, 0.01, 5.0, 'experimental deBUG scale mode', '', true);
+ conRegVar('dbg_scale', @g_dbg_scale, 0.01, 100.0, 'experimental deBUG scale mode', '', false);
end.