diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr
index bbbcdd3089eeacf26c5e688d19b377a3e1b76990..268e281a029f8e05fefb378a13db5d7fd20b6117 100644 (file)
--- a/src/game/Doom2DF.lpr
+++ b/src/game/Doom2DF.lpr
uses
{$IFDEF ANDROID}
- ctypes,
+ ctypes, jni,
{$ENDIF}
{$IFDEF UNIX}
cthreads, BaseUnix,
r_texture in 'opengl/r_texture.pas',
r_weapons in 'opengl/r_weapons.pas',
r_window in 'opengl/r_window.pas',
+ r_render in 'opengl/r_render.pas',
{$IFDEF USE_FMOD}
fmod in '../lib/FMOD/fmod.pas',
fui_ctls in '../flexui/fui_ctls.pas',
{$ENDIF}
{$I ../shared/vampimg.inc}
- SysUtils;
+
+ SysUtils, Classes;
{$IFDEF WINDOWS}
{$R *.res}
{$ENDIF}
+ const
+ autoexecScript = 'autoexec.cfg';
+
var
noct: Boolean = False;
binPath: AnsiString = '';
forceBinDir: Boolean = False;
+ wLoadingQuit: Boolean = false;
+ Time, Time_Delta, Time_Old: Int64;
+ Frame: Int64;
+ flag: Boolean = false;
+
+ NoSound: Boolean;
+
+procedure Update ();
+begin
+ // remember old mobj positions, prepare for update
+ g_Game_PreUpdate();
+ // server: receive client commands for new frame
+ // client: receive game state changes from server
+ if (NetMode = NET_SERVER) then g_Net_Host_Update()
+ else if (NetMode = NET_CLIENT) then g_Net_Client_Update();
+ // think
+ g_Game_Update();
+ // server: send any accumulated outgoing data to clients
+ if NetMode = NET_SERVER then g_Net_Flush();
+end;
+
+function ProcessMessage (): Boolean;
+var
+ i, t: Integer;
+begin
+ result := sys_HandleInput();
+
+ Time := sys_GetTicks();
+ Time_Delta := Time-Time_Old;
+
+ flag := false;
+
+ if wNeedTimeReset then
+ begin
+ Frame := 0;
+ Time_Delta := 28;
+ wNeedTimeReset := false;
+ end;
+
+ g_Map_ProfilersBegin();
+ g_Mons_ProfilersBegin();
+
+ t := Time_Delta div 28;
+ if (t > 0) then
+ begin
+ flag := true;
+ for i := 1 to t do
+ Update();
+ end;
+
+ g_Map_ProfilersEnd();
+ g_Mons_ProfilersEnd();
+
+ if wLoadingQuit then
+ begin
+ g_Game_Free();
+ g_Game_Quit();
+ end;
+
+ if (gExit = EXIT_QUIT) then
+ begin
+ result := true;
+ exit;
+ end;
+
+ // Время предыдущего обновления
+ if flag then
+ Time_Old := Time - (Time_Delta mod 28);
+
+ // don't wait if VSync is on, GL already probably waits enough
+ if gLerpActors then
+ flag := (Time - Frame >= gFrameTime) or gVSync;
+
+ if flag then
+ begin
+ if gPause or (not gLerpActors) or (gState = STATE_FOLD) then
+ gLerpFactor := 1.0
+ else
+ gLerpFactor := nmin(1.0, (Time - Time_Old) / 28.0);
+ r_Game_Draw;
+ sys_Repaint;
+ Frame := Time
+ end
+ else
+ sys_Delay(1);
+
+ e_SoundUpdate();
+end;
+
+procedure DebugOptions;
+var
+ idx: Integer;
+ arg: AnsiString;
+ mdfo: TStream;
+ {$IFDEF ENABLE_HOLMES}
+ itmp: Integer;
+ valres: Word;
+ {$ENDIF}
+begin
+ idx := 1;
+ while (idx <= ParamCount) do
+ begin
+ arg := ParamStr(idx);
+ Inc(idx);
+ //if arg = '--twinkletwinkle' then gwin_k8_enable_light_experiments := true;
+ if arg = '--jah' then g_profile_history_size := 100;
+ if arg = '--no-particles' then gpart_dbg_enabled := false;
+ if arg = '--no-los' then gmon_dbg_los_enabled := false;
+
+ if arg = '--profile-render' then g_profile_frame_draw := true;
+ if arg = '--profile-coldet' then g_profile_collision := true;
+ if arg = '--profile-los' then g_profile_los := true;
+
+ if arg = '--no-part-phys' then gpart_dbg_phys_enabled := false;
+ if arg = '--no-part-physics' then gpart_dbg_phys_enabled := false;
+ if arg = '--no-particles-phys' then gpart_dbg_phys_enabled := false;
+ if arg = '--no-particles-physics' then gpart_dbg_phys_enabled := false;
+ if arg = '--no-particle-phys' then gpart_dbg_phys_enabled := false;
+ if arg = '--no-particle-physics' then gpart_dbg_phys_enabled := false;
+
+ if arg = '--debug-input' then g_dbg_input := True;
+
+ {.$IF DEFINED(D2F_DEBUG)}
+ if arg = '--aimline' then g_dbg_aimline_on := true;
+ {.$ENDIF}
+
+{$IFDEF ENABLE_HOLMES}
+ if arg = '--holmes' then begin g_holmes_enabled := true; g_Game_SetDebugMode(); end;
+
+ if (arg = '--holmes-ui-scale') or (arg = '-holmes-ui-scale') then
+ begin
+ if (idx <= ParamCount) then
+ begin
+ if not conParseFloat(fuiRenderScale, ParamStr(idx)) then fuiRenderScale := 1.0;
+ Inc(idx);
+ end;
+ end;
+
+ if (arg = '--holmes-font') or (arg = '-holmes-font') then
+ begin
+ if (idx <= ParamCount) then
+ begin
+ itmp := 0;
+ val(ParamStr(idx), itmp, valres);
+ {$IFNDEF HEADLESS}
+ if (valres = 0) and (not g_holmes_imfunctional) then
+ begin
+ case itmp of
+ 8: uiContext.font := 'win8';
+ 14: uiContext.font := 'win14';
+ 16: uiContext.font := 'win16';
+ end;
+ end;
+ {$ELSE}
+ // fuck off, fpc!
+ itmp := itmp;
+ valres := valres;
+ {$ENDIF}
+ Inc(idx);
+ end;
+ end;
+{$ENDIF}
+
+ if (arg = '--game-scale') or (arg = '-game-scale') then
+ begin
+ if (idx <= ParamCount) then
+ begin
+ if not conParseFloat(g_dbg_scale, ParamStr(idx)) then g_dbg_scale := 1.0;
+ Inc(idx);
+ end;
+ end;
+
+ if (arg = '--write-mapdef') or (arg = '-write-mapdef') then
+ begin
+ mdfo := createDiskFile('mapdef.txt');
+ mdfo.WriteBuffer(defaultMapDef[1], Length(defaultMapDef));
+ mdfo.Free();
+ Halt(0);
+ end;
+
+ if (arg = '--pixel-scale') or (arg = '-pixel-scale') then
+ begin
+ if (idx <= ParamCount) then
+ begin
+ if not conParseFloat(r_pixel_scale, ParamStr(idx)) then r_pixel_scale := 1.0;
+ Inc(idx);
+ end;
+ end;
+ end;
+end;
+
function GetBinaryPath (): AnsiString;
{$IFDEF LINUX}
var sl: AnsiString;
AddDir(AllMapDirs, MegawadDirs[i]);
OptimizeDirs(AllMapDirs);
- if LogFileName = '' then
- begin
- rwdir := e_GetWriteableDir(LogDirs, false);
- if rwdir <> '' then
- begin
- {$IFDEF HEADLESS}
- LogFileName := e_CatPath(rwdir, 'Doom2DF_H.log');
- {$ELSE}
- LogFileName := e_CatPath(rwdir, 'Doom2DF.log');
- {$ENDIF}
- end
- end;
-
// HACK: ensure the screenshots folder also has a stats subfolder in it
rwdir := e_GetWriteableDir(ScreenshotDirs, false);
if rwdir <> '' then CreateDir(rwdir + '/stats');
end;
-procedure InitPrep;
- {$IF DEFINED(ANDROID) AND DEFINED(USE_SDLMIXER)}
- var timiditycfg: AnsiString;
- {$ENDIF}
- var i: Integer;
-begin
- {$IFDEF HEADLESS}
- conbufDumpToStdOut := true;
- {$ENDIF}
- for i := 1 to ParamCount do
+ procedure EntryParams;
+ var i: Integer;
begin
- case ParamStr(i) of
- '--con-stdout': conbufDumpToStdOut := true;
- '--no-fbo': glRenderToFBO := false;
+ i := 1;
+ while i <= ParamCount do
+ begin
+ case ParamStr(i) of
+ '--gdb': noct := true;
+ '--log', '--con-stdout': conbufDumpToStdOut := true;
+ '--safe-log': e_SetSafeSlowLog(true);
+ '--log-file':
+ if i + 1 <= ParamCount then
+ begin
+ Inc(i);
+ LogFileName := ParamStr(i)
+ end;
+ '--no-fbo': glRenderToFBO := false;
+ end;
+ Inc(i)
end
end;
- if LogFileName <> '' then
- e_InitLog(LogFileName, TWriteMode.WM_NEWFILE);
- e_InitWritelnDriver();
- e_WriteLog('Doom 2D: Forever version ' + GAME_VERSION + ' proto ' + IntToStr(NET_PROTOCOL_VER), TMsgType.Notify);
- e_WriteLog('Build date: ' + GAME_BUILDDATE + ' ' + GAME_BUILDTIME, TMsgType.Notify);
- e_WriteLog('Build hash: ' + g_GetBuildHash(), TMsgType.Notify);
- e_WriteLog('Build by: ' + g_GetBuilderName(), TMsgType.Notify);
-
- e_LogWritefln('Force bin dir: %s', [forceBinDir], TMsgType.Notify);
- e_LogWritefln('BINARY PATH: [%s]', [binPath], TMsgType.Notify);
-
- PrintDirs('DataDirs', DataDirs);
- PrintDirs('ModelDirs', ModelDirs);
- PrintDirs('MegawadDirs', MegawadDirs);
- PrintDirs('MapDirs', MapDirs);
- PrintDirs('WadDirs', WadDirs);
-
- PrintDirs('LogDirs', LogDirs);
- PrintDirs('SaveDirs', SaveDirs);
- PrintDirs('CacheDirs', CacheDirs);
- PrintDirs('ConfigDirs', ConfigDirs);
- PrintDirs('ScreenshotDirs', ScreenshotDirs);
- PrintDirs('StatsDirs', StatsDirs);
- PrintDirs('MapDownloadDirs', MapDownloadDirs);
- PrintDirs('WadDownloadDirs', WadDownloadDirs);
-
- GameWAD := e_FindWad(DataDirs, GameWADName);
- if GameWad = '' then
+ procedure InitLog;
+ var rwdir: AnsiString;
begin
- e_WriteLog('WAD ' + GameWADName + ' not found in data directories.', TMsgType.Fatal);
- {$IF DEFINED(USE_SDL2) AND NOT DEFINED(HEADLESS)}
- if forceBinDir = false then
- SDL_ShowSimpleMessageBox(
- SDL_MESSAGEBOX_ERROR,
- 'Doom 2D Forever',
- PChar('WAD ' + GameWADName + ' not found in data directories.'),
- nil
- );
- {$ENDIF}
- e_DeinitLog;
- Halt(1);
- end;
-
- {$IF DEFINED(ANDROID) AND DEFINED(USE_SDLMIXER)}
- timiditycfg := 'timidity.cfg';
- if e_FindResource(ConfigDirs, timiditycfg) = true then
+ if LogFileName = '' then
begin
- timiditycfg := ExpandFileName(timiditycfg);
- SetEnvVar('TIMIDITY_CFG', timiditycfg);
- e_LogWritefln('Set TIMIDITY_CFG = "%s"', [timiditycfg]);
+ rwdir := e_GetWriteableDir(LogDirs, false);
+ if rwdir <> '' then
+ begin
+ {$IFDEF HEADLESS}
+ LogFileName := e_CatPath(rwdir, 'Doom2DF_H.log');
+ {$ELSE}
+ LogFileName := e_CatPath(rwdir, 'Doom2DF.log');
+ {$ENDIF}
+ end
end;
- {$ENDIF}
-end;
-
-procedure Main;
-{$IFDEF ENABLE_HOLMES}
- var flexloaded: Boolean;
-{$ENDIF}
-begin
- InitPath;
- InitPrep;
- e_InitInput;
- sys_Init;
+ if LogFileName <> '' then
+ e_InitLog(LogFileName, TWriteMode.WM_NEWFILE);
+ e_InitWritelnDriver
+ end;
- sys_CharPress := @CharPress;
+ procedure InitPrep;
+ {$IF DEFINED(ANDROID) AND DEFINED(USE_SDLMIXER)}
+ var timiditycfg: AnsiString;
+ {$ENDIF}
+ begin
+ e_WriteLog('Doom 2D: Forever version ' + GAME_VERSION + ' proto ' + IntToStr(NET_PROTOCOL_VER), TMsgType.Notify);
+ e_WriteLog('Build date: ' + GAME_BUILDDATE + ' ' + GAME_BUILDTIME, TMsgType.Notify);
+ e_WriteLog('Build hash: ' + g_GetBuildHash(), TMsgType.Notify);
+ e_WriteLog('Build by: ' + g_GetBuilderName(), TMsgType.Notify);
+
+ e_LogWritefln('Force bin dir: %s', [forceBinDir], TMsgType.Notify);
+ e_LogWritefln('BINARY PATH: [%s]', [binPath], TMsgType.Notify);
+
+ PrintDirs('DataDirs', DataDirs);
+ PrintDirs('ModelDirs', ModelDirs);
+ PrintDirs('MegawadDirs', MegawadDirs);
+ PrintDirs('MapDirs', MapDirs);
+ PrintDirs('WadDirs', WadDirs);
+
+ PrintDirs('LogDirs', LogDirs);
+ PrintDirs('SaveDirs', SaveDirs);
+ PrintDirs('CacheDirs', CacheDirs);
+ PrintDirs('ConfigDirs', ConfigDirs);
+ PrintDirs('ScreenshotDirs', ScreenshotDirs);
+ PrintDirs('StatsDirs', StatsDirs);
+ PrintDirs('MapDownloadDirs', MapDownloadDirs);
+ PrintDirs('WadDownloadDirs', WadDownloadDirs);
+
+ {$IFDEF HEADLESS}
+ {$IFDEF USE_SDLMIXER}
+ NoSound := False; // hope env has set SDL_AUDIODRIVER to dummy
+ {$ELSE}
+ NoSound := True; // FMOD backend will sort it out
+ {$ENDIF}
+ {$ELSE}
+ NoSound := False;
+ {$ENDIF}
- g_Options_SetDefault;
- g_Options_SetDefaultVideo;
- g_Console_SysInit;
- if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = False then
- raise Exception.Create('Failed to set videomode on startup.');
+ {$IF DEFINED(ANDROID) AND DEFINED(USE_SDLMIXER)}
+ timiditycfg := 'timidity.cfg';
+ if e_FindResource(ConfigDirs, timiditycfg) = true then
+ begin
+ timiditycfg := ExpandFileName(timiditycfg);
+ SetEnvVar('TIMIDITY_CFG', timiditycfg);
+ e_LogWritefln('Set TIMIDITY_CFG = "%s"', [timiditycfg]);
+ end;
+ {$ENDIF}
- e_WriteLog(gLanguage, TMsgType.Notify);
- g_Language_Set(gLanguage);
+ GameWAD := e_FindWad(DataDirs, GameWADName);
+ if GameWad = '' then
+ begin
+ e_WriteLog('WAD ' + GameWADName + ' not found in data directories.', TMsgType.Fatal);
+ {$IF DEFINED(USE_SDL2) AND NOT DEFINED(HEADLESS)}
+ if forceBinDir = false then
+ SDL_ShowSimpleMessageBox(
+ SDL_MESSAGEBOX_ERROR,
+ 'Doom 2D Forever',
+ PChar('WAD ' + GameWADName + ' not found in data directories.'),
+ nil
+ );
+ {$ENDIF}
+ e_DeinitLog;
+ Halt(1);
+ end
+ end;
-{$IF not DEFINED(HEADLESS) and DEFINED(ENABLE_HOLMES)}
- flexloaded := true;
- if not fuiAddWad('flexui.wad') then
+{$IFDEF ENABLE_HOLMES}
+ procedure InitHolmes;
+ var flexloaded: Boolean;
begin
- if not fuiAddWad('./data/flexui.wad') then fuiAddWad('./flexui.wad');
- end;
- try
- fuiGfxLoadFont('win8', 'flexui/fonts/win8.fuifont');
- fuiGfxLoadFont('win14', 'flexui/fonts/win14.fuifont');
- fuiGfxLoadFont('win16', 'flexui/fonts/win16.fuifont');
- fuiGfxLoadFont('dos8', 'flexui/fonts/dos8.fuifont');
- fuiGfxLoadFont('msx6', 'flexui/fonts/msx6.fuifont');
- except on e: Exception do
+ flexloaded := true;
+ if not fuiAddWad('flexui.wad') then
begin
- writeln('ERROR loading FlexUI fonts');
- flexloaded := false;
- //raise;
+ if not fuiAddWad('./data/flexui.wad') then fuiAddWad('./flexui.wad');
end;
- else
- begin
- flexloaded := false;
- //raise;
- end;
- end;
- if (flexloaded) then
- begin
try
- e_LogWriteln('FlexUI: loading stylesheet...');
- uiLoadStyles('flexui/widgets.wgs');
- except on e: TParserException do
+ fuiGfxLoadFont('win8', 'flexui/fonts/win8.fuifont');
+ fuiGfxLoadFont('win14', 'flexui/fonts/win14.fuifont');
+ fuiGfxLoadFont('win16', 'flexui/fonts/win16.fuifont');
+ fuiGfxLoadFont('dos8', 'flexui/fonts/dos8.fuifont');
+ fuiGfxLoadFont('msx6', 'flexui/fonts/msx6.fuifont');
+ except on e: Exception do
begin
- writeln('ERROR at (', e.tokLine, ',', e.tokCol, '): ', e.message);
- //raise;
+ writeln('ERROR loading FlexUI fonts');
flexloaded := false;
+ //raise;
end;
else
begin
- //raise;
flexloaded := false;
+ //raise;
end;
end;
+ if flexloaded then
+ begin
+ try
+ e_LogWriteln('FlexUI: loading stylesheet...');
+ uiLoadStyles('flexui/widgets.wgs');
+ except on e: TParserException do
+ begin
+ writeln('ERROR at (', e.tokLine, ',', e.tokCol, '): ', e.message);
+ //raise;
+ flexloaded := false;
+ end;
+ else
+ begin
+ //raise;
+ flexloaded := false;
+ end;
+ end;
+ end;
+ g_holmes_imfunctional := not flexloaded;
+ if not g_holmes_imfunctional then
+ begin
+ uiInitialize();
+ uiContext.font := 'win14';
+ end;
+ if assigned(oglInitCB) then oglInitCB;
end;
- g_holmes_imfunctional := not flexloaded;
- if (not g_holmes_imfunctional) then
+ procedure FreeHolmes;
begin
- uiInitialize();
- uiContext.font := 'win14';
+ if assigned(oglDeinitCB) then
+ oglDeinitCB
end;
-
- if assigned(oglInitCB) then oglInitCB;
{$ENDIF}
- //g_Res_CreateDatabases(true); // it will be done before connecting to the server for the first time
-
- e_WriteLog('Entering SDLMain', TMsgType.Notify);
-
- {$WARNINGS OFF}
- SDLMain();
- {$WARNINGS ON}
-
- {$IFDEF ENABLE_HOLMES}
- if assigned(oglDeinitCB) then oglDeinitCB;
- {$ENDIF}
-
- g_Console_WriteGameConfig;
- sys_Final;
-end;
-
-
-procedure EntryParams;
- var f: Integer;
-begin
- f := 1;
- while f <= ParamCount do
+ procedure Startup;
begin
- case ParamStr(f) of
- '--gdb': noct := true;
- '--log': conbufDumpToStdOut := true;
- '--safe-log': e_SetSafeSlowLog(true);
- '--log-file':
- if f + 1 <= ParamCount then
- begin
- Inc(f);
- LogFileName := ParamStr(f)
- end
- end;
- Inc(f)
- end
-end;
-
-procedure EntryPoint;
-begin
- SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]); //k8: fuck off, that's why
- EntryParams;
- if noct then
- Main
- else
- try
- Main;
+ Randomize;
+ InitPath;
+ InitLog;
+ InitPrep;
+ e_Input_Initialize;
+ e_InitSoundSystem(NoSound);
+ sys_Init;
+ sys_CharPress := @CharPress; (* install hook *)
+ g_Options_SetDefault;
+ g_Options_SetDefaultVideo;
+ g_Console_Initialize;
+ // TODO move load configs here
+ g_Language_Set(gLanguage);
+ r_Render_Initialize;
+ g_Touch_Init;
+ DebugOptions;
+ g_Net_InitLowLevel;
+ // TODO init serverlist
+ {$IFDEF ENABLE_HOLMES}
+ InitHolmes;
+ {$ENDIF}
+ g_Game_Init;
+ {$IFNDEF HEADLESS}
+ g_Menu_Init;
+ g_GUI_Init;
+ {$ENDIF}
+ g_Game_Process_Params;
+ // TODO reload GAME textures
+ g_Console_Init; // welcome message
+ {$IFNDEF HEADLESS}
+ if (not gGameOn) and gAskLanguage then
+ g_Menu_AskLanguage;
+ {$ENDIF}
+ Time_Old := sys_GetTicks();
+ while not ProcessMessage() do begin end;
+ g_Console_WriteGameConfig;
+ {$IFNDEF HEADLESS}
+ g_GUI_Destroy;
+ g_Menu_Free;
+ {$ENDIF}
+ {$IFDEF ENABLE_HOLMES}
+ FreeHolmes;
+ {$ENDIF}
+ g_Net_Slist_ShutdownAll;
+ g_Net_DeinitLowLevel;
+ (* g_Touch_Finalize; *)
+ r_Render_Finalize;
+ sys_Final;
+ g_Console_Finalize;
+ e_ReleaseSoundSystem;
+ e_Input_Finalize;
e_WriteLog('Shutdown with no errors.', TMsgType.Notify)
- except on e: Exception do
- e_WriteStackTrace(e.message)
- else
- e_WriteStackTrace('FATAL ERROR')
end;
- e_DeinitLog;
-end;
+ procedure EntryPoint;
+ begin
+ SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]); //k8: fuck off, that's why
+ EntryParams;
+ e_Log_Initialize;
+ {$IFDEF HEADLESS}
+ conbufDumpToStdOut := true;
+ {$ENDIF}
+ if noct then
+ Startup
+ else
+ try
+ Startup
+ except on e: Exception do
+ e_WriteStackTrace(e.message)
+ else
+ e_WriteStackTrace('FATAL ERROR')
+ end;
+ e_Log_Finalize
+ end;
{$IFDEF ANDROID}
function SDL_main (argc: CInt; argv: PPChar): CInt; cdecl;
result := 0
end;
- exports SDL_main;
+ function JNI_OnLoad (vm: PJavaVM; reserved: pointer): JInt; cdecl;
+ begin
+ result:= JNI_VERSION_1_6;
+ end;
+
+ procedure JNI_OnUnload(vm: PJavaVM; reserved: pointer); cdecl;
+ begin
+ end;
+
+ // DONT REMOVE JNI FUNCTIONS. SPECIAL HANDLING BY FPC.
+ exports SDL_main name 'SDL_main';
+ exports JNI_OnLoad name 'JNI_OnLoad';
+ exports JNI_OnUnload name 'JNI_Unload';
{$ELSE}
begin
EntryPoint