X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fopengl%2Fr_game.pas;h=3a64ad534e7236e1eefcc9524d7ea8f1586e9591;hb=16342bee09fa001d05697571124e48a93cd35f2c;hp=ca85e9e806aa6bd8539dcd9b89cdf06c5f332e5e;hpb=5c816a8e702fd39c65d0928a3315d81e979f30fb;p=d2df-sdl.git diff --git a/src/game/opengl/r_game.pas b/src/game/opengl/r_game.pas index ca85e9e..3a64ad5 100644 --- a/src/game/opengl/r_game.pas +++ b/src/game/opengl/r_game.pas @@ -17,25 +17,45 @@ unit r_game; interface + procedure r_Game_Load; + procedure r_Game_Free; + + procedure r_Game_LoadTextures; + procedure r_Game_FreeTextures; + procedure r_Game_Draw; procedure r_Game_DrawLoadingStat; procedure r_Game_DrawMenuBackground (tex: AnsiString); + procedure r_Game_SetupScreenSize; + + var + gStdFont: DWORD; + gMenuFont: DWORD; + gMenuSmallFont: DWORD; + implementation uses {$INCLUDE ../nogl/noGLuses.inc} -{$IFDEF ENABLE_HOLMES} - g_holmes, -{$ENDIF} + {$IFDEF ENABLE_HOLMES} + g_holmes, + {$ENDIF} + {$IFDEF ENABLE_MENU} + g_gui, g_menu, + {$ENDIF} + {$IFDEF ENABLE_GFX} + g_gfx, r_gfx, + {$ENDIF} SysUtils, Classes, Math, - r_graphics, - g_system, g_touch, - MAPDEF, xprofiler, utils, wadreader, - g_textures, e_input, e_sound, - g_language, g_console, g_menu, g_triggers, g_player, g_options, g_monsters, g_map, g_panel, g_window, - g_items, g_weapons, g_gfx, g_phys, g_net, g_gui, g_netmaster, - g_game, r_console, r_gfx, r_items, r_map, r_panel, r_monsters, r_weapons, r_netmaster, r_player + g_base, g_basic, r_graphics, + g_system, + MAPDEF, xprofiler, utils, wadreader, CONFIG, + e_input, e_sound, + g_language, g_console, g_triggers, g_player, g_options, g_monsters, g_map, g_panel, + g_items, g_weapons, g_phys, g_net, g_netmaster, + g_game, r_console, r_items, r_map, r_monsters, r_weapons, r_netmaster, r_player, r_textures, + r_playermodel ; var @@ -44,6 +64,229 @@ implementation FPS: Word; FPSCounter: Word; FPSTime: LongWord; + hasPBarGfx: Boolean; + + BackID: DWORD = DWORD(-1); + gBackSize: TDFPoint; + +procedure LoadStdFont(cfgres, texture: string; var FontID: DWORD); +var + cwdt, chgt: Byte; + spc: ShortInt; + ID: DWORD; + wad: TWADFile; + cfgdata: Pointer; + cfglen: Integer; + config: TConfig; +begin + cfglen := 0; + + wad := TWADFile.Create; + if wad.ReadFile(GameWAD) then + wad.GetResource('FONTS/'+cfgres, cfgdata, cfglen); + wad.Free(); + + if cfglen <> 0 then + begin + g_Texture_CreateWADEx('FONT_STD', GameWAD+':FONTS\'+texture); + + config := TConfig.CreateMem(cfgdata, cfglen); + cwdt := Min(Max(config.ReadInt('FontMap', 'CharWidth', 0), 0), 255); + chgt := Min(Max(config.ReadInt('FontMap', 'CharHeight', 0), 0), 255); + spc := Min(Max(config.ReadInt('FontMap', 'Kerning', 0), -128), 127); + + if g_Texture_Get('FONT_STD', ID) then + e_TextureFontBuild(ID, FontID, cwdt, chgt, spc); + + config.Free(); + end; + + if cfglen <> 0 then FreeMem(cfgdata); +end; + +procedure LoadFont(txtres, fntres: string; var FontID: DWORD); +var + cwdt, chgt: Byte; + spc: ShortInt; + CharID: DWORD; + wad: TWADFile; + cfgdata, fntdata: Pointer; + cfglen, fntlen: Integer; + config: TConfig; + chrwidth: Integer; + a: Byte; +begin + cfglen := 0; + fntlen := 0; + + wad := TWADFile.Create; + if wad.ReadFile(GameWAD) then + begin + wad.GetResource('FONTS/'+txtres, cfgdata, cfglen); + wad.GetResource('FONTS/'+fntres, fntdata, fntlen); + end; + wad.Free(); + + if cfglen <> 0 then + begin + config := TConfig.CreateMem(cfgdata, cfglen); + cwdt := Min(Max(config.ReadInt('FontMap', 'CharWidth', 0), 0), 255); + chgt := Min(Max(config.ReadInt('FontMap', 'CharHeight', 0), 0), 255); + + spc := Min(Max(config.ReadInt('FontMap', 'Kerning', 0), -128), 127); + FontID := e_CharFont_Create(spc); + + for a := 0 to 255 do + begin + chrwidth := config.ReadInt(IntToStr(a), 'Width', 0); + if chrwidth = 0 then Continue; + + if e_CreateTextureMemEx(fntdata, fntlen, CharID, cwdt*(a mod 16), chgt*(a div 16), + cwdt, chgt) then + e_CharFont_AddChar(FontID, CharID, Chr(a), chrwidth); + end; + + config.Free(); + end; + + if cfglen <> 0 then FreeMem(cfgdata); + if fntlen <> 0 then FreeMem(fntdata); +end; + + procedure r_Game_Load; + var + wl, hl: Integer; + wr, hr: Integer; + wb, hb: Integer; + wm, hm: Integer; + begin + // early load + g_Texture_CreateWADEx('MENU_BACKGROUND', GameWAD + ':TEXTURES\TITLE', gTextureFilter); + g_Texture_CreateWADEx('INTER', GameWAD + ':TEXTURES\INTER', gTextureFilter); + g_Texture_CreateWADEx('ENDGAME_EN', GameWAD + ':TEXTURES\ENDGAME_EN', gTextureFilter); + g_Texture_CreateWADEx('ENDGAME_RU', GameWAD + ':TEXTURES\ENDGAME_RU', gTextureFilter); + LoadStdFont('STDTXT', 'STDFONT', gStdFont); + LoadFont('MENUTXT', 'MENUFONT', gMenuFont); + LoadFont('SMALLTXT', 'SMALLFONT', gMenuSmallFont); + // game data + g_Texture_CreateWADEx('NOTEXTURE', GameWAD + ':TEXTURES\NOTEXTURE'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_HUD', GameWAD + ':TEXTURES\HUD'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_HUDAIR', GameWAD + ':TEXTURES\AIRBAR'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_HUDJET', GameWAD + ':TEXTURES\JETBAR'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_HUDBG', GameWAD + ':TEXTURES\HUDBG'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_ARMORHUD', GameWAD + ':TEXTURES\ARMORHUD'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG', GameWAD + ':TEXTURES\FLAGHUD_R_BASE'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG_S', GameWAD + ':TEXTURES\FLAGHUD_R_STOLEN'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG_D', GameWAD + ':TEXTURES\FLAGHUD_R_DROP'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG', GameWAD + ':TEXTURES\FLAGHUD_B_BASE'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG_S', GameWAD + ':TEXTURES\FLAGHUD_B_STOLEN'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG_D', GameWAD + ':TEXTURES\FLAGHUD_B_DROP'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_TALKBUBBLE', GameWAD + ':TEXTURES\TALKBUBBLE'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_INVULPENTA', GameWAD + ':TEXTURES\PENTA'); + g_Texture_CreateWADEx('TEXTURE_PLAYER_INDICATOR', GameWAD + ':TEXTURES\PLRIND'); + // bar + hasPBarGfx := true; + if not g_Texture_CreateWADEx('UI_GFX_PBAR_LEFT', GameWAD+':TEXTURES\LLEFT') then hasPBarGfx := false; + if not g_Texture_CreateWADEx('UI_GFX_PBAR_MARKER', GameWAD+':TEXTURES\LMARKER') then hasPBarGfx := false; + if not g_Texture_CreateWADEx('UI_GFX_PBAR_MIDDLE', GameWAD+':TEXTURES\LMIDDLE') then hasPBarGfx := false; + if not g_Texture_CreateWADEx('UI_GFX_PBAR_RIGHT', GameWAD+':TEXTURES\LRIGHT') then hasPBarGfx := false; + if hasPBarGfx then + begin + g_Texture_GetSize('UI_GFX_PBAR_LEFT', wl, hl); + g_Texture_GetSize('UI_GFX_PBAR_RIGHT', wr, hr); + g_Texture_GetSize('UI_GFX_PBAR_MIDDLE', wb, hb); + g_Texture_GetSize('UI_GFX_PBAR_MARKER', wm, hm); + if (wl > 0) and (hl > 0) and (wr > 0) and (hr = hl) and (wb > 0) and (hb = hl) and (wm > 0) and (hm > 0) and (hm <= hl) then + begin + // yay! + end + else + hasPBarGfx := false; + end; + end; + + procedure r_Game_Free; + begin + g_Texture_Delete('NOTEXTURE'); + g_Texture_Delete('TEXTURE_PLAYER_HUD'); + g_Texture_Delete('TEXTURE_PLAYER_HUDBG'); + g_Texture_Delete('TEXTURE_PLAYER_ARMORHUD'); + g_Texture_Delete('TEXTURE_PLAYER_REDFLAG'); + g_Texture_Delete('TEXTURE_PLAYER_REDFLAG_S'); + g_Texture_Delete('TEXTURE_PLAYER_REDFLAG_D'); + g_Texture_Delete('TEXTURE_PLAYER_BLUEFLAG'); + g_Texture_Delete('TEXTURE_PLAYER_BLUEFLAG_S'); + g_Texture_Delete('TEXTURE_PLAYER_BLUEFLAG_D'); + g_Texture_Delete('TEXTURE_PLAYER_TALKBUBBLE'); + g_Texture_Delete('TEXTURE_PLAYER_INVULPENTA'); + end; + +procedure r_Game_SetupScreenSize; +const + RES_FACTOR = 4.0 / 3.0; +var + s: Single; + rf: Single; + bw, bh: Word; +begin +// Размер экранов игроков: + gPlayerScreenSize.X := gScreenWidth-196; + if (gPlayer1 <> nil) and (gPlayer2 <> nil) then + gPlayerScreenSize.Y := gScreenHeight div 2 + else + gPlayerScreenSize.Y := gScreenHeight; + +// Размер заднего плана: + if BackID <> DWORD(-1) then + begin + s := SKY_STRETCH; + if (gScreenWidth*s > gMapInfo.Width) or + (gScreenHeight*s > gMapInfo.Height) then + begin + gBackSize.X := gScreenWidth; + gBackSize.Y := gScreenHeight; + end + else + begin + e_GetTextureSize(BackID, @bw, @bh); + rf := Single(bw) / Single(bh); + if (rf > RES_FACTOR) then bw := Round(Single(bh) * RES_FACTOR) + else if (rf < RES_FACTOR) then bh := Round(Single(bw) / RES_FACTOR); + s := Max(gScreenWidth / bw, gScreenHeight / bh); + if (s < 1.0) then s := 1.0; + gBackSize.X := Round(bw*s); + gBackSize.Y := Round(bh*s); + end; + end; +end; + + procedure r_Game_LoadTextures; + begin + g_Texture_CreateWADEx('TEXTURE_endpic', EndPicPath, gTextureFilter); + if gMapInfo.SkyFullName <> '' then + g_Texture_CreateWAD(BackID, gMapInfo.SkyFullName, gTextureFilter); + r_Game_SetupScreenSize; + end; + + procedure r_Game_FreeTextures; + begin + g_Texture_Delete('TEXTURE_endpic'); + if BackID <> DWORD(-1) then + begin + gBackSize.X := 0; + gBackSize.Y := 0; + e_DeleteTexture(BackID); + BackID := DWORD(-1); + end + end; + +procedure r_Map_DrawBack(dx, dy: Integer); +begin + if gDrawBackGround and (BackID <> DWORD(-1)) then + e_DrawSize(BackID, dx, dy, 0, False, False, gBackSize.X, gBackSize.Y) + else + e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0); +end; function GetActivePlayer_ByID(ID: Integer): TPlayer; var @@ -560,7 +803,9 @@ begin // HACK: take stats screenshot immediately after the first frame of the stats showing if gScreenshotStats and (not StatShotDone) and (Length(CustomStat.PlayerStat) > 1) then begin +{$IFNDEF HEADLESS} g_TakeScreenShot('stats/' + StatFilename); +{$ENDIF} StatShotDone := True; end; end; @@ -1028,6 +1273,65 @@ begin e_AmbientQuad(sX, sY, sWidth, sHeight, ambColor.r, ambColor.g, ambColor.b, ambColor.a); end; +// ////////////////////////////////////////////////////////////////////////// // +var + ltexid: GLuint = 0; + +function g_Texture_Light (): Integer; +const + Radius: Integer = 128; +var + tex, tpp: PByte; + x, y, a: Integer; + dist: Double; +begin + if ltexid = 0 then + begin + GetMem(tex, (Radius*2)*(Radius*2)*4); + tpp := tex; + for y := 0 to Radius*2-1 do + begin + for x := 0 to Radius*2-1 do + begin + dist := 1.0-sqrt((x-Radius)*(x-Radius)+(y-Radius)*(y-Radius))/Radius; + if (dist < 0) then + begin + tpp^ := 0; Inc(tpp); + tpp^ := 0; Inc(tpp); + tpp^ := 0; Inc(tpp); + tpp^ := 0; Inc(tpp); + end + else + begin + //tc.setPixel(x, y, Color(cast(int)(dist*255), cast(int)(dist*255), cast(int)(dist*255))); + if (dist > 0.5) then dist := 0.5; + a := round(dist*255); + if (a < 0) then a := 0 else if (a > 255) then a := 255; + tpp^ := 255; Inc(tpp); + tpp^ := 255; Inc(tpp); + tpp^ := 255; Inc(tpp); + tpp^ := Byte(a); Inc(tpp); + end; + end; + end; + + glGenTextures(1, @ltexid); + //if (tid == 0) assert(0, "VGL: can't create screen texture"); + + glBindTexture(GL_TEXTURE_2D, ltexid); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + //GLfloat[4] bclr = 0.0; + //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bclr.ptr); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Radius*2, Radius*2, 0, GL_RGBA{gltt}, GL_UNSIGNED_BYTE, tex); + end; + + result := ltexid; +end; // setup sX, sY, sWidth, sHeight, and transformation matrix before calling this! //FIXME: broken for splitscreen mode @@ -1245,12 +1549,17 @@ begin drawOther('weapons', @r_Weapon_Draw); drawOther('shells', @r_Player_DrawShells); drawOther('drawall', @r_Player_DrawAll); + {$IFDEF ENABLE_GIBS} + drawOther('gibs', @r_PlayerModel_DrawGibs); + {$ENDIF} drawOther('corpses', @r_Player_DrawCorpses); drawPanelType('*wall', PANEL_WALL, g_rlayer_wall); drawOther('monsters', @r_Monsters_Draw); drawOther('itemdrop', @r_Items_DrawDrop); drawPanelType('*door', PANEL_CLOSEDOOR, g_rlayer_door); - drawOther('gfx', @r_GFX_Draw); + {$IFDEF ENABLE_GFX} + drawOther('gfx', @r_GFX_Draw); + {$ENDIF} drawOther('flags', @r_Map_DrawFlags); drawPanelType('*acid1', PANEL_ACID1, g_rlayer_acid1); drawPanelType('*acid2', PANEL_ACID2, g_rlayer_acid2); @@ -1501,10 +1810,12 @@ var back: string; plView1, plView2: TPlayer; Split: Boolean; + MsgLineLength: Integer; + MsgText: String; begin if gExit = EXIT_QUIT then Exit; - Time := sys_GetTicks() {div 1000}; + Time := GetTickCount64() {div 1000}; FPSCounter := FPSCounter+1; if Time - FPSTime >= 1000 then begin @@ -1648,12 +1959,14 @@ begin w := 0; h := 0; e_CharFont_GetSizeFmt(gMenuFont, MessageText, w, h); + MsgLineLength := (gScreenWidth - 204) div e_CharFont_GetMaxWidth(gMenuFont); + MsgText := b_Text_Wrap(b_Text_Format(MessageText), MsgLineLength); if Split then e_CharFont_PrintFmt(gMenuFont, (gScreenWidth div 2)-(w div 2), - (gScreenHeight div 2)-(h div 2), MessageText) + (gScreenHeight div 2)-(h div 2), MsgText) else e_CharFont_PrintFmt(gMenuFont, (gScreenWidth div 2)-(w div 2), - Round(gScreenHeight / 2.75)-(h div 2), MessageText); + Round(gScreenHeight / 2.75)-(h div 2), MsgText); end; if IsDrawStat or (gSpectMode = SPECT_STATS) then @@ -1707,7 +2020,11 @@ begin end; end; +{$IFDEF ENABLE_MENU} if gPauseMain and gGameOn and (g_ActiveWindow = nil) then +{$ELSE} + if gPauseMain and gGameOn then +{$ENDIF} begin //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); @@ -1719,26 +2036,30 @@ begin if not gGameOn then begin - if (gState = STATE_MENU) then - begin - if (g_ActiveWindow = nil) or (g_ActiveWindow.BackTexture = '') then r_Game_DrawMenuBackground('MENU_BACKGROUND'); - // F3 at menu will show game loading dialog - if e_KeyPressed(IK_F3) then g_Menu_Show_LoadMenu(true); - if (g_ActiveWindow <> nil) then - begin - //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); - e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); - end - else + {$IFDEF ENABLE_MENU} + if (gState = STATE_MENU) then begin - // F3 at titlepic will show game loading dialog - if e_KeyPressed(IK_F3) then + if (g_ActiveWindow = nil) or (g_ActiveWindow.BackTexture = '') then r_Game_DrawMenuBackground('MENU_BACKGROUND'); + // F3 at menu will show game loading dialog + if e_KeyPressed(IK_F3) then g_Menu_Show_LoadMenu(true); + if (g_ActiveWindow <> nil) then begin - g_Menu_Show_LoadMenu(true); - if (g_ActiveWindow <> nil) then e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); + e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + end + else + begin + // F3 at titlepic will show game loading dialog + if e_KeyPressed(IK_F3) then + begin + g_Menu_Show_LoadMenu(true); + if (g_ActiveWindow <> nil) then e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + end; end; end; - end; + {$ELSE} + r_Game_DrawMenuBackground('MENU_BACKGROUND'); + {$ENDIF} if gState = STATE_FOLD then begin @@ -1760,11 +2081,13 @@ begin DrawCustomStat(); - if g_ActiveWindow <> nil then - begin - //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); - e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); - end; + {$IFDEF ENABLE_MENU} + if g_ActiveWindow <> nil then + begin + //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); + e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + end; + {$ENDIF} end; if gState = STATE_INTERSINGLE then @@ -1781,11 +2104,13 @@ begin DrawSingleStat(); - if g_ActiveWindow <> nil then - begin - //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); - e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); - end; + {$IFDEF ENABLE_MENU} + if g_ActiveWindow <> nil then + begin + //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); + e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + end; + {$ENDIF} end; end; @@ -1795,11 +2120,13 @@ begin if g_Texture_Get('TEXTURE_endpic', ID) then r_Game_DrawMenuBackground('TEXTURE_endpic') else r_Game_DrawMenuBackground(_lc[I_TEXTURE_ENDPIC]); - if g_ActiveWindow <> nil then - begin - //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); - e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); - end; + {$IFDEF ENABLE_MENU} + if g_ActiveWindow <> nil then + begin + //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180); + e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + end; + {$ENDIF} end; if gState = STATE_SLIST then @@ -1815,6 +2142,7 @@ begin end; end; +{$IFDEF ENABLE_MENU} if g_ActiveWindow <> nil then begin if gGameOn then @@ -1824,6 +2152,7 @@ begin end; g_ActiveWindow.Draw(); end; +{$ENDIF} {$IFNDEF HEADLESS} r_Console_Draw(); @@ -1858,10 +2187,6 @@ begin e_SetRendertarget(False); e_SetViewPort(0, 0, gWinSizeX, gWinSizeY); e_BlitFramebuffer(gWinSizeX, gWinSizeY); - - // draw the overlay stuff on top of it - - g_Touch_Draw; end; end.