X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_game.pas;h=693798382f8943bdb8cfbf2858d7fca05e9e4af8;hb=2249a689b020a4e0d2860e58eafde84010e8f3f4;hp=811148cf456bfb8fb4a54703ca79ebf0ad567361;hpb=f0c98dc86657bdc08f6049872f12b554e1654fa4;p=d2df-sdl.git diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 811148c..6937983 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -309,6 +309,10 @@ var P1MoveButton: Byte = 0; P2MoveButton: Byte = 0; +procedure g_ResetDynlights (); +procedure g_AddDynLight (x, y, radius: Integer; r, g, b, a: Single); +procedure g_DynLightExplosion (x, y, radius: Integer; r, g, b: Single); + implementation uses @@ -320,6 +324,76 @@ uses ENet, e_fixedbuffer, g_netmsg, g_netmaster, GL, GLExt, utils, sfs; +type + TDynLight = record + x, y, radius: Integer; + r, g, b, a: Single; + exploCount: Integer; + exploRadius: Integer; + end; + +var + g_dynLights: array of TDynLight = nil; + g_dynLightCount: Integer = 0; + g_playerLight: Boolean = false; + +procedure g_ResetDynlights (); +var + lnum, idx: Integer; +begin + lnum := 0; + for idx := 0 to g_dynLightCount-1 do + begin + if g_dynLights[idx].exploCount = -666 then + begin + // skip it + end + else + begin + // explosion + Inc(g_dynLights[idx].exploCount); + if (g_dynLights[idx].exploCount < 10) then + begin + g_dynLights[idx].radius := g_dynLights[idx].exploRadius+g_dynLights[idx].exploCount*8; + g_dynLights[idx].a := 0.4+g_dynLights[idx].exploCount/10; + if (g_dynLights[idx].a > 0.8) then g_dynLights[idx].a := 0.8; + if lnum <> idx then g_dynLights[lnum] := g_dynLights[idx]; + Inc(lnum); + end; + end; + end; + g_dynLightCount := lnum; +end; + +procedure g_AddDynLight (x, y, radius: Integer; r, g, b, a: Single); +begin + if g_dynLightCount = length(g_dynLights) then SetLength(g_dynLights, g_dynLightCount+1024); + g_dynLights[g_dynLightCount].x := x; + g_dynLights[g_dynLightCount].y := y; + g_dynLights[g_dynLightCount].radius := radius; + g_dynLights[g_dynLightCount].r := r; + g_dynLights[g_dynLightCount].g := g; + g_dynLights[g_dynLightCount].b := b; + g_dynLights[g_dynLightCount].a := a; + g_dynLights[g_dynLightCount].exploCount := -666; + Inc(g_dynLightCount); +end; + +procedure g_DynLightExplosion (x, y, radius: Integer; r, g, b: Single); +begin + if g_dynLightCount = length(g_dynLights) then SetLength(g_dynLights, g_dynLightCount+1024); + g_dynLights[g_dynLightCount].x := x; + g_dynLights[g_dynLightCount].y := y; + g_dynLights[g_dynLightCount].radius := 0; + g_dynLights[g_dynLightCount].exploRadius := radius; + g_dynLights[g_dynLightCount].r := r; + g_dynLights[g_dynLightCount].g := g; + g_dynLights[g_dynLightCount].b := b; + g_dynLights[g_dynLightCount].a := 0; + g_dynLights[g_dynLightCount].exploCount := 0; + Inc(g_dynLightCount); +end; + type TEndCustomGameStat = record PlayerStat: TPlayerStatArray; @@ -1285,6 +1359,18 @@ begin if isKeyPressed(KeyWeapon[i], KeyWeapon2[i]) then plr.QueueWeaponSwitch(i); // all choices are passed there, and god will take the best end; + + // HACK: add dynlight here + if e_KeyPressed(IK_F8) and gGameOn and (not gConsoleShow) and (g_ActiveWindow = nil) then + begin + g_playerLight := true; + end; + if e_KeyPressed(IK_F9) and gGameOn and (not gConsoleShow) and (g_ActiveWindow = nil) then + begin + g_playerLight := false; + end; + + if (g_playerLight) then g_AddDynLight(plr.GameX+32, plr.GameY+40, 128, 1, 1, 0, 0.6); end; procedure g_Game_Update(); @@ -1295,6 +1381,7 @@ var w: Word; i, b: Integer; begin + g_ResetDynlights(); // Ïîðà âûêëþ÷àòü èãðó: if gExit = EXIT_QUIT then Exit; @@ -1813,6 +1900,8 @@ begin UPSCounter := 0; UPSTime := Time; end; + + if gGameOn then g_Weapon_AddDynLights(); end; procedure g_Game_LoadData(); @@ -2512,6 +2601,7 @@ begin glTranslatef(-x, -y, 0); + g_Map_BuildPVP(sX, sY, sX+sWidth-1, sY+sHeight-1); g_Map_DrawPanels(PANEL_BACK); g_Map_DrawPanels(PANEL_STEP); g_Items_Draw(); @@ -2533,6 +2623,7 @@ begin g_Monsters_DrawHealth(); g_Player_DrawHealth(); end; + g_Map_ResetPVP(); glPopMatrix(); end; @@ -2541,6 +2632,8 @@ procedure DrawPlayer(p: TPlayer); var px, py, a, b, c, d: Integer; //R: TRect; + lln: Integer; + lx, ly, lrad: Integer; begin if (p = nil) or (p.FDummy) then begin @@ -2626,6 +2719,8 @@ begin glTranslatef(a, b+p.IncCam, 0); + g_Map_BuildPVP(sX, sY, sX+sWidth-1, sY+sHeight-1); + g_Map_DrawPanels(PANEL_BACK); g_Map_DrawPanels(PANEL_STEP); g_Items_Draw(); @@ -2641,6 +2736,59 @@ begin g_Map_DrawPanels(PANEL_ACID1); g_Map_DrawPanels(PANEL_ACID2); g_Map_DrawPanels(PANEL_WATER); + + if gwin_has_stencil and (g_dynLightCount > 0) then + begin + // setup OpenGL parameters + glStencilMask($FFFFFFFF); + glStencilFunc(GL_ALWAYS, 0, $FFFFFFFF); + glEnable(GL_STENCIL_TEST); + glEnable(GL_SCISSOR_TEST); + glClear(GL_STENCIL_BUFFER_BIT); + glStencilFunc(GL_EQUAL, 0, $ff); + + for lln := 0 to g_dynLightCount-1 do + begin + lx := g_dynLights[lln].x; + ly := g_dynLights[lln].y; + lrad := g_dynLights[lln].radius; + if lrad < 3 then continue; + // set scissor to optimize drawing + glScissor((lx-sX)-lrad+2, gPlayerScreenSize.Y-(ly-sY)-lrad-1+2, lrad*2-4, lrad*2-4); + // clear stencil buffer + //glClear(GL_STENCIL_BUFFER_BIT); //!!! + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + // draw extruded panels + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no need to modify color buffer + if (lrad > 4) then g_Map_DrawPanelShadowVolumes(lx, ly, lrad); + // render light texture + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // modify color buffer + //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); // draw light, and clear stencil buffer + // blend it + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_TEXTURE_2D); + // color and opacity + glColor4f(g_dynLights[lln].r, g_dynLights[lln].g, g_dynLights[lln].b, g_dynLights[lln].a); + glBindTexture(GL_TEXTURE_2D, g_Texture_Light()); + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex2i(lx-lrad, ly-lrad); // top-left + glTexCoord2f(1.0, 0.0); glVertex2i(lx+lrad, ly-lrad); // top-right + glTexCoord2f(1.0, 1.0); glVertex2i(lx+lrad, ly+lrad); // bottom-right + glTexCoord2f(0.0, 1.0); glVertex2i(lx-lrad, ly+lrad); // bottom-left + glEnd(); + end; + + // done + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + glDisable(GL_SCISSOR_TEST); + glScissor(0, 0, sWidth, sHeight); + end; + g_Map_DrawPanels(PANEL_FORE); if g_debug_HealthBar then begin @@ -2671,6 +2819,7 @@ begin } glPopMatrix(); + g_Map_ResetPVP(); p.DrawPain(); p.DrawPickup(); @@ -6488,7 +6637,12 @@ begin // Debug mode: s := Find_Param_Value(pars, '--debug'); if (s <> '') then + begin g_Game_SetDebugMode(); + s := Find_Param_Value(pars, '--netdump'); + if (s <> '') then + NetDump := True; + end; // Connect when game loads ip := Find_Param_Value(pars, '-connect');