diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 4c0871cadee413d049215045122de52313e69251..23bf9bdc49cfa87e47d2093907cd62ab78a84abe 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
interface
-uses
- SysUtils, Classes,
- MAPDEF,
- g_basic, g_player, r_graphics, g_res_downloader,
- g_sound, g_gui, utils, md5, mempool, xprofiler,
- g_touch, g_weapons;
+ uses
+ {$IFNDEF HEADLESS}
+ g_gui, g_touch,
+ {$ENDIF}
+ SysUtils, Classes, MAPDEF,
+ g_base, g_basic, g_player, g_res_downloader,
+ g_sound, utils, md5, mempool, xprofiler,
+ g_weapons
+ ;
type
TGameSettings = record
procedure g_Game_Update();
procedure g_Game_PreUpdate();
procedure g_Game_Quit();
-procedure g_Game_SetupScreenSize();
-procedure g_Game_ChangeResolution(newWidth, newHeight: Word; nowFull, nowMax: Boolean);
function g_Game_ModeToText(Mode: Byte): string;
function g_Game_TextToMode(Mode: string): Byte;
procedure g_Game_ExecuteEvent(Name: String);
procedure g_Game_NextLevel();
procedure g_Game_Pause(Enable: Boolean);
procedure g_Game_HolmesPause(Enable: Boolean);
-procedure g_Game_InGameMenu(Show: Boolean);
+{$IFNDEF HEADLESS}
+ procedure g_Game_InGameMenu(Show: Boolean);
+{$ENDIF}
function g_Game_IsWatchedPlayer(UID: Word): Boolean;
function g_Game_IsWatchedTeam(Team: Byte): Boolean;
procedure g_Game_Message(Msg: String; Time: Word);
procedure g_Game_Announce_BodyKill(SpawnerUID: Word);
procedure g_Game_StartVote(Command, Initiator: string);
procedure g_Game_CheckVote;
-procedure g_TakeScreenShot(Filename: string = '');
+{$IFNDEF HEADLESS}
+ procedure g_TakeScreenShot(Filename: string = '');
+{$ENDIF}
procedure g_FatalError(Text: String);
procedure g_SimpleError(Text: String);
function g_Game_IsTestMap(): Boolean;
function GetActivePlayerID_Next(Skip: Integer = -1): Integer;
procedure SortGameStat(var stat: TPlayerStatArray);
+procedure KeyPress (K: Word);
+
+{$IFNDEF HEADLESS}
+ procedure CharPress (C: AnsiChar);
+{$ENDIF}
+
{ procedure SetWinPause(Enable: Boolean); }
const
GM_COOP = 4;
GM_SINGLE = 5;
- MESSAGE_DIKEY = WM_USER + 1;
-
EXIT_QUIT = 1;
EXIT_SIMPLE = 2;
EXIT_RESTART = 3;
STATFILE_VERSION = $03;
var
- gStdFont: DWORD;
gGameSettings: TGameSettings;
gPlayer1Settings: TPlayerSettings;
gPlayer2Settings: TPlayerSettings;
g_rlayer_water: Boolean = true;
g_rlayer_fore: Boolean = true;
+ wNeedTimeReset: Boolean = false;
procedure g_ResetDynlights ();
procedure g_AddDynLight (x, y, radius: Integer; r, g, b, a: Single);
StatShotDone: Boolean;
StatFilename: string = ''; // used by stat screenshot to save with the same name as the csv
SingleStat: TEndSingleGameStat;
- hasPBarGfx: Boolean;
LoadingStat: TLoadingStat;
MessageText: String;
IsDrawStat: Boolean;
g_playerLight: Boolean;
g_dynLights: array of TDynLight = nil;
g_dynLightCount: Integer = 0;
+ EndPicPath: AnsiString; // full path, used by render
implementation
uses
-{$INCLUDE ../nogl/noGLuses.inc}
-{$IFDEF ENABLE_HOLMES}
- g_holmes,
-{$ENDIF}
- e_texture, e_res, g_textures, g_window, g_menu,
- e_input, e_log, g_console, r_console, g_items, g_map, g_panel,
+ {$IFDEF ENABLE_HOLMES}
+ g_holmes,
+ {$ENDIF}
+ {$IFNDEF HEADLESS}
+ r_render, g_menu, g_system,
+ {$ENDIF}
+ e_res, g_window,
+ e_input, e_log, g_console, g_items, g_map, g_panel,
g_playermodel, g_gfx, g_options, Math,
g_triggers, g_monsters, e_sound, CONFIG,
- g_language, g_net, g_main, g_phys,
+ g_language, g_net, g_phys,
ENet, e_msg, g_netmsg, g_netmaster,
- sfs, wadreader, g_system, r_playermodel;
+ sfs, wadreader;
+
+ var
+ charbuff: packed array [0..15] of AnsiChar = (
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
+ );
+
+function Translit (const S: AnsiString): AnsiString;
+var
+ i: Integer;
+begin
+ Result := S;
+ for i := 1 to Length(Result) do
+ begin
+ case Result[i] of
+ #$C9: Result[i] := 'Q';
+ #$D6: Result[i] := 'W';
+ #$D3: Result[i] := 'E';
+ #$CA: Result[i] := 'R';
+ #$C5: Result[i] := 'T';
+ #$CD: Result[i] := 'Y';
+ #$C3: Result[i] := 'U';
+ #$D8: Result[i] := 'I';
+ #$D9: Result[i] := 'O';
+ #$C7: Result[i] := 'P';
+ #$D5: Result[i] := '['; //Chr(219);
+ #$DA: Result[i] := ']'; //Chr(221);
+ #$D4: Result[i] := 'A';
+ #$DB: Result[i] := 'S';
+ #$C2: Result[i] := 'D';
+ #$C0: Result[i] := 'F';
+ #$CF: Result[i] := 'G';
+ #$D0: Result[i] := 'H';
+ #$CE: Result[i] := 'J';
+ #$CB: Result[i] := 'K';
+ #$C4: Result[i] := 'L';
+ #$C6: Result[i] := ';'; //Chr(186);
+ #$DD: Result[i] := #39; //Chr(222);
+ #$DF: Result[i] := 'Z';
+ #$D7: Result[i] := 'X';
+ #$D1: Result[i] := 'C';
+ #$CC: Result[i] := 'V';
+ #$C8: Result[i] := 'B';
+ #$D2: Result[i] := 'N';
+ #$DC: Result[i] := 'M';
+ #$C1: Result[i] := ','; //Chr(188);
+ #$DE: Result[i] := '.'; //Chr(190);
+ end;
+ end;
+end;
+
+
+function CheckCheat (ct: TStrings_Locale; eofs: Integer=0): Boolean;
+var
+ ls1, ls2: string;
+begin
+ ls1 := CheatEng[ct];
+ ls2 := Translit(CheatRus[ct]);
+ if length(ls1) = 0 then ls1 := '~';
+ if length(ls2) = 0 then ls2 := '~';
+ result :=
+ (Copy(charbuff, 17-Length(ls1)-eofs, Length(ls1)) = ls1) or
+ (Translit(Copy(charbuff, 17-Length(ls1)-eofs, Length(ls1))) = ls1) or
+ (Copy(charbuff, 17-Length(ls2)-eofs, Length(ls2)) = ls2) or
+ (Translit(Copy(charbuff, 17-Length(ls2)-eofs, Length(ls2))) = ls2);
+ {
+ if ct = I_GAME_CHEAT_JETPACK then
+ begin
+ e_WriteLog('ls1: ['+ls1+']', MSG_NOTIFY);
+ e_WriteLog('ls2: ['+ls2+']', MSG_NOTIFY);
+ e_WriteLog('bf0: ['+Copy(charbuff, 17-Length(ls1)-eofs, Length(ls1))+']', MSG_NOTIFY);
+ e_WriteLog('bf1: ['+Translit(Copy(charbuff, 17-Length(ls1)-eofs, Length(ls1)))+']', MSG_NOTIFY);
+ e_WriteLog('bf2: ['+Copy(charbuff, 17-Length(ls2)-eofs, Length(ls2))+']', MSG_NOTIFY);
+ e_WriteLog('bf3: ['+Translit(Copy(charbuff, 17-Length(ls2)-eofs, Length(ls2)))+']', MSG_NOTIFY);
+ end;
+ }
+end;
+
+procedure Cheat ();
+const
+ CHEAT_DAMAGE = 500;
+label
+ Cheated;
+var
+ s, s2: string;
+ c: ShortString;
+ a: Integer;
+begin
+ {
+ if (not gGameOn) or (not gCheats) or ((gGameSettings.GameType <> GT_SINGLE) and
+ (gGameSettings.GameMode <> GM_COOP) and (not gDebugMode))
+ or g_Game_IsNet then Exit;
+ }
+ if not gGameOn then exit;
+ if not conIsCheatsEnabled then exit;
+
+ s := 'SOUND_GAME_RADIO';
+
+ //
+ if CheckCheat(I_GAME_CHEAT_GODMODE) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.GodMode := not gPlayer1.GodMode;
+ if gPlayer2 <> nil then gPlayer2.GodMode := not gPlayer2.GodMode;
+ goto Cheated;
+ end;
+ // RAMBO
+ if CheckCheat(I_GAME_CHEAT_WEAPONS) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.AllRulez(False);
+ if gPlayer2 <> nil then gPlayer2.AllRulez(False);
+ goto Cheated;
+ end;
+ // TANK
+ if CheckCheat(I_GAME_CHEAT_HEALTH) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.AllRulez(True);
+ if gPlayer2 <> nil then gPlayer2.AllRulez(True);
+ goto Cheated;
+ end;
+ // IDDQD
+ if CheckCheat(I_GAME_CHEAT_DEATH) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.Damage(CHEAT_DAMAGE, 0, 0, 0, HIT_TRAP);
+ if gPlayer2 <> nil then gPlayer2.Damage(CHEAT_DAMAGE, 0, 0, 0, HIT_TRAP);
+ s := 'SOUND_MONSTER_HAHA';
+ goto Cheated;
+ end;
+ //
+ if CheckCheat(I_GAME_CHEAT_DOORS) then
+ begin
+ g_Triggers_OpenAll();
+ goto Cheated;
+ end;
+ // GOODBYE
+ if CheckCheat(I_GAME_CHEAT_NEXTMAP) then
+ begin
+ if gTriggers <> nil then
+ for a := 0 to High(gTriggers) do
+ if gTriggers[a].TriggerType = TRIGGER_EXIT then
+ begin
+ gExitByTrigger := True;
+ //g_Game_ExitLevel(gTriggers[a].Data.MapName);
+ g_Game_ExitLevel(gTriggers[a].tgcMap);
+ Break;
+ end;
+ goto Cheated;
+ end;
+ //
+ s2 := Copy(charbuff, 15, 2);
+ if CheckCheat(I_GAME_CHEAT_CHANGEMAP, 2) and (s2[1] >= '0') and (s2[1] <= '9') and (s2[2] >= '0') and (s2[2] <= '9') then
+ begin
+ if g_Map_Exist(gGameSettings.WAD + ':\MAP' + s2) then
+ begin
+ c := 'MAP' + s2;
+ g_Game_ExitLevel(c);
+ end;
+ goto Cheated;
+ end;
+ //
+ if CheckCheat(I_GAME_CHEAT_FLY) then
+ begin
+ gFly := not gFly;
+ goto Cheated;
+ end;
+ // BULLFROG
+ if CheckCheat(I_GAME_CHEAT_JUMPS) then
+ begin
+ VEL_JUMP := 30-VEL_JUMP;
+ goto Cheated;
+ end;
+ // FORMULA1
+ if CheckCheat(I_GAME_CHEAT_SPEED) then
+ begin
+ MAX_RUNVEL := 32-MAX_RUNVEL;
+ goto Cheated;
+ end;
+ // CONDOM
+ if CheckCheat(I_GAME_CHEAT_SUIT) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.GiveItem(ITEM_SUIT);
+ if gPlayer2 <> nil then gPlayer2.GiveItem(ITEM_SUIT);
+ goto Cheated;
+ end;
+ //
+ if CheckCheat(I_GAME_CHEAT_AIR) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.GiveItem(ITEM_OXYGEN);
+ if gPlayer2 <> nil then gPlayer2.GiveItem(ITEM_OXYGEN);
+ goto Cheated;
+ end;
+ // PURELOVE
+ if CheckCheat(I_GAME_CHEAT_BERSERK) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.GiveItem(ITEM_MEDKIT_BLACK);
+ if gPlayer2 <> nil then gPlayer2.GiveItem(ITEM_MEDKIT_BLACK);
+ goto Cheated;
+ end;
+ //
+ if CheckCheat(I_GAME_CHEAT_JETPACK) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.GiveItem(ITEM_JETPACK);
+ if gPlayer2 <> nil then gPlayer2.GiveItem(ITEM_JETPACK);
+ goto Cheated;
+ end;
+ // CASPER
+ if CheckCheat(I_GAME_CHEAT_NOCLIP) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.SwitchNoClip;
+ if gPlayer2 <> nil then gPlayer2.SwitchNoClip;
+ goto Cheated;
+ end;
+ //
+ if CheckCheat(I_GAME_CHEAT_NOTARGET) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.NoTarget := not gPlayer1.NoTarget;
+ if gPlayer2 <> nil then gPlayer2.NoTarget := not gPlayer2.NoTarget;
+ goto Cheated;
+ end;
+ // INFERNO
+ if CheckCheat(I_GAME_CHEAT_NORELOAD) then
+ begin
+ if gPlayer1 <> nil then gPlayer1.NoReload := not gPlayer1.NoReload;
+ if gPlayer2 <> nil then gPlayer2.NoReload := not gPlayer2.NoReload;
+ goto Cheated;
+ end;
+ if CheckCheat(I_GAME_CHEAT_AIMLINE) then
+ begin
+ gAimLine := not gAimLine;
+ goto Cheated;
+ end;
+ if CheckCheat(I_GAME_CHEAT_AUTOMAP) then
+ begin
+ gShowMap := not gShowMap;
+ goto Cheated;
+ end;
+ Exit;
+
+Cheated:
+ g_Sound_PlayEx(s);
+end;
+
+
+procedure KeyPress (K: Word);
+{$IFNDEF HEADLESS}
+var
+ Msg: g_gui.TMessage;
+{$ENDIF}
+begin
+{$IFNDEF HEADLESS}
+ case K of
+ VK_ESCAPE: // <Esc>:
+ begin
+ if (g_ActiveWindow <> nil) then
+ begin
+ Msg.Msg := WM_KEYDOWN;
+ Msg.WParam := VK_ESCAPE;
+ g_ActiveWindow.OnMessage(Msg);
+ if (not g_Game_IsNet) and (g_ActiveWindow = nil) then g_Game_Pause(false); //Fn loves to do this
+ end
+ else if (gState <> STATE_FOLD) then
+ begin
+ if gGameOn or (gState = STATE_INTERSINGLE) or (gState = STATE_INTERCUSTOM) then
+ begin
+ g_Game_InGameMenu(True);
+ end
+ else if (gExit = 0) and (gState <> STATE_SLIST) then
+ begin
+ if (gState <> STATE_MENU) then
+ begin
+ if (NetMode <> NET_NONE) then
+ begin
+ g_Game_StopAllSounds(True);
+ g_Game_Free;
+ gState := STATE_MENU;
+ Exit;
+ end;
+ end;
+ g_GUI_ShowWindow('MainMenu');
+ g_Sound_PlayEx('MENU_OPEN');
+ end;
+ end;
+ end;
+
+ IK_F2, IK_F3, IK_F4, IK_F5, IK_F6, IK_F7, IK_F10:
+ begin // <F2> .. <F6> � <F12>
+ if gGameOn and (not gConsoleShow) and (not gChatShow) then
+ begin
+ while (g_ActiveWindow <> nil) do g_GUI_HideWindow(False);
+ if (not g_Game_IsNet) then g_Game_Pause(True);
+ case K of
+ IK_F2: g_Menu_Show_SaveMenu();
+ IK_F3: g_Menu_Show_LoadMenu();
+ IK_F4: g_Menu_Show_GameSetGame();
+ IK_F5: g_Menu_Show_OptionsVideo();
+ IK_F6: g_Menu_Show_OptionsSound();
+ IK_F7: g_Menu_Show_EndGameMenu();
+ IK_F10: g_Menu_Show_QuitGameMenu();
+ end;
+ end;
+ end;
+
+ else
+ begin
+ gJustChatted := False;
+ if gConsoleShow or gChatShow then
+ begin
+ g_Console_Control(K);
+ end
+ else if (g_ActiveWindow <> nil) then
+ begin
+ Msg.Msg := WM_KEYDOWN;
+ Msg.WParam := K;
+ g_ActiveWindow.OnMessage(Msg);
+ end
+ else if (gState = STATE_MENU) then
+ begin
+ g_GUI_ShowWindow('MainMenu');
+ g_Sound_PlayEx('MENU_OPEN');
+ end;
+ end;
+ end;
+{$ENDIF}
+end;
+
+{$IFNDEF HEADLESS}
+procedure CharPress (C: AnsiChar);
+var
+ Msg: g_gui.TMessage;
+ a: Integer;
+begin
+ if gConsoleShow or gChatShow then
+ begin
+ g_Console_Char(C)
+ end
+ else if (g_ActiveWindow <> nil) then
+ begin
+ Msg.Msg := WM_CHAR;
+ Msg.WParam := Ord(C);
+ g_ActiveWindow.OnMessage(Msg);
+ end
+ else
+ begin
+ for a := 0 to 14 do charbuff[a] := charbuff[a+1];
+ charbuff[15] := upcase1251(C);
+ Cheat();
+ end;
+end;
+{$ENDIF}
// ////////////////////////////////////////////////////////////////////////// //
UPSTime: LongWord;
DataLoaded: Boolean = False;
MessageTime: Word;
- MessageLineLength: Integer = 80;
MapList: SSArray = nil;
MapIndex: Integer = -1;
InterReadyTime: Integer = -1;
info: TMegaWADInfo;
endpic: String;
endmus: String;
- res: record
- text: Array of ShortString;
- anim: Array of ShortString;
- pic: Array of ShortString;
- mus: Array of ShortString;
- end;
- triggers: Array of record
- event: ShortString;
- actions: Array of record
- action, p1, p2: Integer;
- end;
- end;
- cur_trigger: Integer;
- cur_action: Integer;
end;
- //InterPic: String;
InterText: record
lines: SSArray;
img: String;
FreeMem(p);
end;
-procedure g_Game_FreeWAD();
-var
- a: Integer;
-begin
- for a := 0 to High(MegaWAD.res.pic) do
- if MegaWAD.res.pic[a] <> '' then
- g_Texture_Delete(MegaWAD.res.pic[a]);
-
- for a := 0 to High(MegaWAD.res.mus) do
- if MegaWAD.res.mus[a] <> '' then
- g_Sound_Delete(MegaWAD.res.mus[a]);
-
- MegaWAD.res.pic := nil;
- MegaWAD.res.text := nil;
- MegaWAD.res.anim := nil;
- MegaWAD.res.mus := nil;
- MegaWAD.triggers := nil;
-
- g_Texture_Delete('TEXTURE_endpic');
- g_Sound_Delete('MUSIC_endmus');
-
- ZeroMemory(@MegaWAD, SizeOf(MegaWAD));
- gGameSettings.WAD := '';
-end;
+ procedure g_Game_FreeWAD;
+ begin
+ EndPicPath := '';
+ g_Sound_Delete('MUSIC_endmus');
+ ZeroMemory(@MegaWAD, SizeOf(MegaWAD));
+ gGameSettings.WAD := '';
+ end;
procedure g_Game_LoadWAD(WAD: string);
var
w: TWADFile;
cfg: TConfig;
p: Pointer;
- {b, }len: Integer;
+ len: Integer;
s: AnsiString;
begin
g_Game_FreeWAD();
cfg := TConfig.CreateMem(p, len);
- {b := 1;
- while True do
- begin
- s := cfg.ReadStr('pic', 'pic'+IntToStr(b), '');
- if s = '' then Break;
- b := b+1;
-
- SetLength(MegaWAD.res.pic, Length(MegaWAD.res.pic)+1);
- MegaWAD.res.pic[High(MegaWAD.res.pic)] := s;
-
- g_Texture_CreateWADEx(s, s);
- end;
-
- b := 1;
- while True do
- begin
- s := cfg.ReadStr('mus', 'mus'+IntToStr(b), '');
- if s = '' then Break;
- b := b+1;
-
- SetLength(MegaWAD.res.mus, Length(MegaWAD.res.mus)+1);
- MegaWAD.res.mus[High(MegaWAD.res.mus)] := s;
-
- g_Music_CreateWADEx(s, s);
- end;}
-
+ EndPicPath := '';
MegaWAD.endpic := cfg.ReadStr('megawad', 'endpic', '');
if MegaWAD.endpic <> '' then
- begin
- TEXTUREFILTER := GL_LINEAR;
- s := e_GetResourcePath(WadDirs, MegaWAD.endpic, WAD);
- g_Texture_CreateWADEx('TEXTURE_endpic', s);
- TEXTUREFILTER := GL_NEAREST;
- end;
+ EndPicPath := e_GetResourcePath(WadDirs, MegaWAD.endpic, WAD);
+
MegaWAD.endmus := cfg.ReadStr('megawad', 'endmus', 'Standart.wad:D2DMUS\КОНЕЦ');
if MegaWAD.endmus <> '' then
begin
gDelayedEvents[n].DENum := Num;
gDelayedEvents[n].DEStr := Str;
if DEType = DE_GLOBEVENT then
- gDelayedEvents[n].Time := (sys_GetTicks() {div 1000}) + Time
+ gDelayedEvents[n].Time := (GetTickCount64() {div 1000}) + Time
else
gDelayedEvents[n].Time := gTime + Time;
Result := n;
MessageText := '';
EndingGameCounter := 0;
+
+{$IFNDEF HEADLESS}
g_ActiveWindow := nil;
+{$ENDIF}
gLMSRespawn := LMS_RESPAWN_NONE;
gLMSRespawnTime := 0;
EXIT_SIMPLE: // Выход через меню или конец теста
begin
g_Game_Free();
-
if gMapOnce then
- begin // Это был тест
- g_Game_Quit();
- end
+ begin // Это был тест
+ g_Game_Quit();
+ end
else
- begin // Выход в главное меню
- gMusic.SetByName('MUSIC_MENU');
- gMusic.Play();
- if gState <> STATE_SLIST then
- begin
- g_GUI_ShowWindow('MainMenu');
- gState := STATE_MENU;
- end else
+ begin // Выход в главное меню
+{$IFDEF HEADLESS}
+ gState := STATE_MENU; // ???
+{$ELSE}
+ gMusic.SetByName('MUSIC_MENU');
+ gMusic.Play();
+ if gState <> STATE_SLIST then
+ begin
+ g_GUI_ShowWindow('MainMenu');
+ gState := STATE_MENU;
+ end else
+ begin
+ // Обновляем список серверов
+ slReturnPressed := True;
+ if g_Net_Slist_Fetch(slCurrent) then
begin
- // Обновляем список серверов
- slReturnPressed := True;
- if g_Net_Slist_Fetch(slCurrent) then
- begin
- if slCurrent = nil then
- slWaitStr := _lc[I_NET_SLIST_NOSERVERS];
- end
- else
- slWaitStr := _lc[I_NET_SLIST_ERROR];
- g_Serverlist_GenerateTable(slCurrent, slTable);
- end;
-
- g_Game_ExecuteEvent('ongameend');
+ if slCurrent = nil then
+ slWaitStr := _lc[I_NET_SLIST_NOSERVERS];
+ end
+ else
+ slWaitStr := _lc[I_NET_SLIST_ERROR];
+ g_Serverlist_GenerateTable(slCurrent, slTable);
end;
+{$ENDIF}
+ g_Game_ExecuteEvent('ongameend');
+ end;
end;
EXIT_RESTART: // Начать уровень сначала
end;
procedure g_Game_Init();
-var
- SR: TSearchRec;
- knownFiles: array of AnsiString = nil;
- found: Boolean;
- wext, s: AnsiString;
- f: Integer;
begin
gExit := 0;
gMapToDelete := '';
sfsGCDisable(); // temporary disable removing of temporary volumes
try
- TEXTUREFILTER := GL_LINEAR;
- g_Texture_CreateWADEx('MENU_BACKGROUND', GameWAD+':TEXTURES\TITLE');
- g_Texture_CreateWADEx('INTER', GameWAD+':TEXTURES\INTER');
- g_Texture_CreateWADEx('ENDGAME_EN', GameWAD+':TEXTURES\ENDGAME_EN');
- g_Texture_CreateWADEx('ENDGAME_RU', GameWAD+':TEXTURES\ENDGAME_RU');
- TEXTUREFILTER := GL_NEAREST;
-
- LoadStdFont('STDTXT', 'STDFONT', gStdFont);
- LoadFont('MENUTXT', 'MENUFONT', gMenuFont);
- LoadFont('SMALLTXT', 'SMALLFONT', gMenuSmallFont);
-
g_Game_ClearLoading();
g_Game_SetLoadingText(Format('Doom 2D: Forever %s', [GAME_VERSION]), 0, False);
g_Game_SetLoadingText('', 0, False);
- g_Game_SetLoadingText(_lc[I_LOAD_CONSOLE], 0, False);
- r_Console_Init;
- g_Console_Init();
-
- g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False);
- r_PlayerModel_Initialize;
-
- // load models from all possible wad types, in all known directories
- // this does a loosy job (linear search, ooph!), but meh
- for wext in wadExtensions do
- begin
- for f := High(ModelDirs) downto Low(ModelDirs) do
- begin
- if (FindFirst(ModelDirs[f]+DirectorySeparator+'*'+wext, faAnyFile, SR) = 0) then
- begin
- repeat
- found := false;
- for s in knownFiles do
- begin
- if (strEquCI1251(forceFilenameExt(SR.Name, ''), forceFilenameExt(ExtractFileName(s), ''))) then
- begin
- found := true;
- break;
- end;
- end;
- if not found then
- begin
- SetLength(knownFiles, length(knownFiles)+1);
- knownFiles[High(knownFiles)] := ModelDirs[f]+DirectorySeparator+SR.Name;
- end;
- until (FindNext(SR) <> 0);
- end;
- FindClose(SR);
- end;
- end;
-
- if (length(knownFiles) = 0) then raise Exception.Create('no player models found!');
-
- if (length(knownFiles) = 1) then e_LogWriteln('1 player model found.', TMsgType.Notify) else e_LogWritefln('%d player models found.', [Integer(length(knownFiles))], TMsgType.Notify);
- for s in knownFiles do
- begin
- if not g_PlayerModel_Load(s) then e_LogWritefln('Error loading model "%s"', [s], TMsgType.Warning);
- end;
+// g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False);
gGameOn := false;
gPauseMain := false;
g_Sound_CreateWADEx('MUSIC_ROUNDMUS', GameWAD+':MUSIC\ROUNDMUS', True, True);
g_Sound_CreateWADEx('MUSIC_STDENDMUS', GameWAD+':MUSIC\ENDMUS', True);
-{$IFNDEF HEADLESS}
- g_Game_SetLoadingText(_lc[I_LOAD_MENUS], 0, False);
- g_Menu_Init();
-{$ENDIF}
-
gMusic := TMusic.Create();
gMusic.SetByName('MUSIC_MENU');
gMusic.Play();
end
end;
+{$IFNDEF HEADLESS}
// HACK: add dynlight here
if gwin_k8_enable_light_experiments then
begin
end;
if gwin_has_stencil and g_playerLight then g_AddDynLight(plr.GameX+32, plr.GameY+40, 128, 1, 1, 0, 0.6);
+{$ENDIF}
end;
// HACK: don't have a "key was pressed" function
end;
procedure g_Game_Update();
-var
- Msg: g_gui.TMessage;
- Time: Int64;
- a: Byte;
- w: Word;
- i, b: Integer;
+ var
+ {$IFNDEF HEADLESS}
+ Msg: g_gui.TMessage;
+ w: Word;
+ {$ENDIF}
+ Time: Int64;
+ a: Byte;
+ i, b: Integer;
function sendMonsPos (mon: TMonster): Boolean;
begin
// no need to, as we'll do it in event handler
// Обновляем консоль (движение и сообщения):
- r_Console_Update;
g_Console_Update();
if (NetMode = NET_NONE) and (g_Game_IsNet) and (gGameOn or (gState in [STATE_FOLD, STATE_INTERCUSTOM])) then
e_KeyPressed(JOY2_ATTACK) or e_KeyPressed(JOY3_ATTACK)
)
and (not gJustChatted) and (not gConsoleShow) and (not gChatShow)
+{$IFNDEF HEADLESS}
and (g_ActiveWindow = nil)
+{$ENDIF}
)
or (g_Game_IsNet and ((gInterTime > gInterEndTime) or ((gInterReadyCount >= NetClientCount) and (NetClientCount > 0))))
)
begin
// Выход в главное меню:
g_Game_Free;
+{$IFNDEF HEADLESS}
g_GUI_ShowWindow('MainMenu');
gMusic.SetByName('MUSIC_MENU');
gMusic.Play();
+{$ENDIF}
gState := STATE_MENU;
end else
begin
e_KeyPressed(JOY2_ATTACK) or e_KeyPressed(JOY3_ATTACK)
)
and (not gJustChatted) and (not gConsoleShow) and (not gChatShow)
+{$IFNDEF HEADLESS}
and (g_ActiveWindow = nil)
+{$ENDIF}
)
then
begin
// Обрабатываем клавиши игроков:
if gPlayer1 <> nil then gPlayer1.ReleaseKeys();
if gPlayer2 <> nil then gPlayer2.ReleaseKeys();
+{$IFDEF HEADLESS}
+ if (not gConsoleShow) and (not gChatShow) then
+{$ELSE}
if (not gConsoleShow) and (not gChatShow) and (g_ActiveWindow = nil) then
+{$ENDIF}
begin
ProcessPlayerControls(gPlayer1, 0, P1MoveButton);
ProcessPlayerControls(gPlayer2, 1, P2MoveButton);
end; // if server
// Наблюдатель
- if (gPlayer1 = nil) and (gPlayer2 = nil) and
- (not gConsoleShow) and (not gChatShow) and (g_ActiveWindow = nil) then
+ if (gPlayer1 = nil) and (gPlayer2 = nil)
+ and (not gConsoleShow) and (not gChatShow)
+{$IFNDEF HEADLESS}
+ and (g_ActiveWindow = nil)
+{$ENDIF}
+ then
begin
if not gSpectKeyPress then
begin
end; // if gameOn ...
// Активно окно интерфейса - передаем клавиши ему:
+{$IFNDEF HEADLESS}
if g_ActiveWindow <> nil then
begin
w := e_GetFirstKeyPressed();
// Нужно сменить разрешение:
if gResolutionChange then
begin
- e_WriteLog('Changing resolution', TMsgType.Notify);
- g_Game_ChangeResolution(gRC_Width, gRC_Height, gRC_FullScreen, gRC_Maximized);
+ {$IFNDEF HEADLESS}
+ e_WriteLog('Changing resolution', TMsgType.Notify);
+ r_Render_Apply;
+ {$ENDIF}
gResolutionChange := False;
g_ActiveWindow := nil;
end;
//e_WriteLog('Read language file', MSG_NOTIFY);
//g_Language_Load(DataDir + gLanguage + '.txt');
g_Language_Set(gLanguage);
-{$IFNDEF HEADLESS}
g_Menu_Reset();
-{$ENDIF}
gLanguageChange := False;
end;
end;
begin
KeyPress(IK_F10);
end;
+{$ENDIF} // NOT HEADLESS
- Time := sys_GetTicks() {div 1000};
+ Time := GetTickCount64() {div 1000};
// Обработка отложенных событий:
if gDelayedEvents <> nil then
end;
procedure g_Game_LoadData();
-var
- wl, hl: Integer;
- wr, hr: Integer;
- wb, hb: Integer;
- wm, hm: Integer;
begin
if DataLoaded then Exit;
e_WriteLog('Loading game data...', TMsgType.Notify);
- 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');
-
- 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
- begin
- hasPBarGfx := false;
- end;
- end;
-
- g_Frames_CreateWAD(nil, 'FRAMES_TELEPORT', GameWAD+':TEXTURES\TELEPORT', 64, 64, 10, False);
- g_Frames_CreateWAD(nil, 'FRAMES_PUNCH', GameWAD+':WEAPONS\PUNCH', 64, 64, 4, False);
- g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_UP', GameWAD+':WEAPONS\PUNCH_UP', 64, 64, 4, False);
- g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_DN', GameWAD+':WEAPONS\PUNCH_DN', 64, 64, 4, False);
- g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_BERSERK', GameWAD+':WEAPONS\PUNCHB', 64, 64, 4, False);
- g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_BERSERK_UP', GameWAD+':WEAPONS\PUNCHB_UP', 64, 64, 4, False);
- g_Frames_CreateWAD(nil, 'FRAMES_PUNCH_BERSERK_DN', GameWAD+':WEAPONS\PUNCHB_DN', 64, 64, 4, False);
g_Sound_CreateWADEx('SOUND_GAME_TELEPORT', GameWAD+':SOUNDS\TELEPORT');
g_Sound_CreateWADEx('SOUND_GAME_NOTELEPORT', GameWAD+':SOUNDS\NOTELEPORT');
g_Sound_CreateWADEx('SOUND_GAME_SECRET', GameWAD+':SOUNDS\SECRET');
g_Game_StopAllSounds(True);
gMusic.Free();
g_Game_FreeData();
- r_PlayerModel_Finalize;
g_PlayerModel_FreeData();
- g_Texture_DeleteAll();
- g_Frames_DeleteAll();
{$IFNDEF HEADLESS}
//g_Menu_Free(); //k8: this segfaults after resolution change; who cares?
{$ENDIF}
g_Game_DeleteTestMap();
gExit := EXIT_QUIT;
- sys_RequestQuit;
+
+ {$IFNDEF HEADLESS}
+ sys_RequestQuit;
+ {$ENDIF}
end;
procedure g_Game_FreeData();
e_WriteLog('Releasing game data...', TMsgType.Notify);
- 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');
- g_Frames_DeleteByName('FRAMES_TELEPORT');
- g_Frames_DeleteByName('FRAMES_PUNCH');
- g_Frames_DeleteByName('FRAMES_PUNCH_UP');
- g_Frames_DeleteByName('FRAMES_PUNCH_DN');
- g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK');
- g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK_UP');
- g_Frames_DeleteByName('FRAMES_PUNCH_BERSERK_DN');
g_Sound_Delete('SOUND_GAME_TELEPORT');
g_Sound_Delete('SOUND_GAME_NOTELEPORT');
g_Sound_Delete('SOUND_GAME_SECRET');
e_WriteLog(Format(_lc[I_SIMPLE_ERROR], [Text]), TMsgType.Warning);
end;
-procedure g_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 g_Game_ChangeResolution(newWidth, newHeight: Word; nowFull, nowMax: Boolean);
-begin
- sys_SetDisplayMode(newWidth, newHeight, gBPP, nowFull, nowMax);
-end;
-
procedure g_Game_AddPlayer(Team: Byte = TEAM_NONE);
begin
if ((not gGameOn) and (gState <> STATE_INTERCUSTOM))
g_Game_ExecuteEvent('ongamestart');
-// Установка размеров окон игроков:
- g_Game_SetupScreenSize();
-
// Создание первого игрока:
gPlayer1 := g_Player_Get(g_Player_Create(gPlayer1Settings.Model,
gPlayer1Settings.Color,
g_Game_ExecuteEvent('ongamestart');
-// Установка размеров окон игроков:
- g_Game_SetupScreenSize();
-
// Режим наблюдателя:
if nPlayers = 0 then
begin
g_Game_ExecuteEvent('ongamestart');
-// Установка размеров окна игрока
- g_Game_SetupScreenSize();
-
// Режим наблюдателя:
if nPlayers = 0 then
begin
g_Game_ExecuteEvent('ongamestart');
-// Установка размеров окон игроков:
- g_Game_SetupScreenSize();
-
NetState := NET_STATE_AUTH;
g_Game_SetLoadingText(_lc[I_LOAD_CONNECT], 0, False);
begin
//result := g_Map_Load(gGameSettings.WAD + ':\' + ResName);
result := g_Map_Load(NewWAD+':\'+ResName);
+ {$IFNDEF HEADLESS}
+ r_Render_LoadTextures;
+ {$ENDIF}
end;
if Result then
begin
g_Player_ResetAll(Force or gLastMap, gGameSettings.GameType = GT_SINGLE);
gState := STATE_NONE;
- g_ActiveWindow := nil;
+ {$IFNDEF HEADLESS}
+ g_ActiveWindow := nil;
+ {$ENDIF}
gGameOn := True;
DisableCheats();
- ResetTimer();
+ wNeedTimeReset := True;
if gGameSettings.GameMode = GM_CTF then
begin
chstr := '';
if cmd = 'pause' then
begin
- if (g_ActiveWindow = nil) then
+ {$IFNDEF HEADLESS}
+ if (g_ActiveWindow = nil) then
+ g_Game_Pause(not gPauseMain);
+ {$ELSE}
g_Game_Pause(not gPauseMain);
+ {$ENDIF}
end
else if cmd = 'endgame' then
gExit := EXIT_SIMPLE
end
else if cmd = 'screenshot' then
begin
- g_TakeScreenShot()
+ {$IFNDEF HEADLESS}
+ g_TakeScreenShot()
+ {$ENDIF}
end
else if cmd = 'weapon' then
begin
g_Game_Free();
g_Game_Quit();
end;
+{$IFNDEF HEADLESS}
'r_reset':
- begin
- gRC_Width := Max(1, gRC_Width);
- gRC_Height := Max(1, gRC_Height);
- gBPP := Max(1, gBPP);
- if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = True then
- e_LogWriteln('resolution changed')
- else
- e_LogWriteln('resolution not changed');
- sys_EnableVSync(gVSync);
- end;
+ r_Render_Apply;
+{$ENDIF}
'r_maxfps':
begin
if Length(p) = 2 then
end;
end;
+{$IFNDEF HEADLESS}
procedure g_TakeScreenShot(Filename: string = '');
- var s: TStream; t: TDateTime; dir, date, name: String;
+ var t: TDateTime; dir, date, name: String;
begin
- if e_NoGraphics then Exit;
- try
- dir := e_GetWriteableDir(ScreenshotDirs);
+ if e_NoGraphics then
+ Exit;
- if Filename = '' then
- begin
- t := Now;
- DateTimeToString(date, 'yyyy-mm-dd-hh-nn-ss', t);
- Filename := 'screenshot-' + date;
- end;
-
- name := e_CatPath(dir, Filename + '.png');
- s := createDiskFile(name);
- try
- e_MakeScreenshot(s, gScreenWidth, gScreenHeight);
- s.Free;
- g_Console_Add(Format(_lc[I_CONSOLE_SCREENSHOT], [name]))
- except
- g_Console_Add(Format(_lc[I_CONSOLE_ERROR_WRITE], [name]));
- s.Free;
- DeleteFile(name)
- end
- except
- g_Console_Add('oh shit, i can''t create screenshot!')
- end
+ dir := e_GetWriteableDir(ScreenshotDirs);
+ if Filename = '' then
+ begin
+ t := Now;
+ DateTimeToString(date, 'yyyy-mm-dd-hh-nn-ss', t);
+ Filename := 'screenshot-' + date;
+ end;
+
+ name := e_CatPath(dir, Filename + '.png');
+ if r_Render_WriteScreenShot(name) then
+ g_Console_Add(Format(_lc[I_CONSOLE_SCREENSHOT], [name]))
+ else
+ g_Console_Add(Format(_lc[I_CONSOLE_ERROR_WRITE], [name]));
end;
+{$ENDIF}
+{$IFNDEF HEADLESS}
procedure g_Game_InGameMenu(Show: Boolean);
begin
if (g_ActiveWindow = nil) and Show then
g_Game_Pause(False);
end;
end;
+{$ENDIF}
procedure g_Game_Pause (Enable: Boolean);
var
end;
end;
-procedure g_Game_Message(Msg: string; Time: Word);
-begin
- MessageLineLength := (gScreenWidth - 204) div e_CharFont_GetMaxWidth(gMenuFont);
- MessageText := b_Text_Wrap(b_Text_Format(Msg), MessageLineLength);
- MessageTime := Time;
-end;
+ procedure g_Game_Message (Msg: string; Time: Word);
+ begin
+ MessageText := Msg;
+ MessageTime := Time;
+ end;
procedure g_Game_ChatSound(Text: String; Taunt: Boolean = True);
const
PBarWasHere := false;
end;
- g_ActiveWindow := nil;
+ {$IFNDEF HEADLESS}
+ g_ActiveWindow := nil;
+ {$ENDIF}
ProcessLoading(true);
end;
conRegVar('dbg_ignore_level_bounds', @g_dbg_ignore_bounds, 'ignore level bounds', '', false);
- conRegVar('r_scale', @g_dbg_scale, 0.01, 100.0, 'render scale', '', false);
- conRegVar('r_resolution_scale', @r_pixel_scale, 0.01, 100.0, 'upscale factor', '', false);
-
conRegVar('light_enabled', @gwin_k8_enable_light_experiments, 'enable/disable dynamic lighting', 'lighting');
conRegVar('light_player_halo', @g_playerLight, 'enable/disable player halo', 'player light halo');