From: DeaDDooMER Date: Sat, 29 Jan 2022 11:36:31 +0000 (+0300) Subject: game: disable gibs for server X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=16342bee09fa001d05697571124e48a93cd35f2c;p=d2df-sdl.git game: disable gibs for server --- diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr index c576b7c..dc4d79c 100644 --- a/src/game/Doom2DF.lpr +++ b/src/game/Doom2DF.lpr @@ -126,6 +126,9 @@ uses {$IFDEF ENABLE_GFX} g_gfx in 'g_gfx.pas', {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs in 'g_gibs.pas', + {$ENDIF} g_items in 'g_items.pas', g_map in 'g_map.pas', g_monsters in 'g_monsters.pas', diff --git a/src/game/g_console.pas b/src/game/g_console.pas index aa06ac0..9a8fd11 100644 --- a/src/game/g_console.pas +++ b/src/game/g_console.pas @@ -109,6 +109,9 @@ uses {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} g_textures, e_input, g_game, g_player, g_items, SysUtils, g_basic, g_options, Math, e_res, g_language, g_net, g_netmsg, e_log, conbuf; @@ -2004,7 +2007,9 @@ begin WriteLn(f, 'g_max_particles ', g_GFX_GetMax()); {$ENDIF} WriteLn(f, 'g_max_shells ', g_Shells_GetMax()); - WriteLn(f, 'g_max_gibs ', g_Gibs_GetMax()); + {$IFDEF ENABLE_GIBS} + WriteLn(f, 'g_max_gibs ', g_Gibs_GetMax()); + {$ENDIF} WriteLn(f, 'g_max_corpses ', g_Corpses_GetMax()); WriteLn(f, 'sv_intertime ', gDefInterTime); diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 512f5bf..019fdc4 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -451,6 +451,9 @@ uses {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} {$IFNDEF HEADLESS} r_render, g_system, {$ENDIF} @@ -2178,6 +2181,9 @@ begin g_GFX_Update; {$ENDIF} g_Player_UpdateAll(); + {$IFDEF ENABLE_GIBS} + g_Gibs_Update; + {$ENDIF} g_Player_UpdatePhysicalObjects(); // server: send newly spawned monsters unconditionally @@ -3986,12 +3992,18 @@ begin begin if Length(p) = 2 then begin - a := Max(0, StrToInt(p[1])); - g_Gibs_SetMax(a) + {$IFDEF ENABLE_GIBS} + a := Max(0, StrToInt(p[1])); + g_Gibs_SetMax(a) + {$ENDIF} end else if Length(p) = 1 then begin - e_LogWritefln('%s', [g_Gibs_GetMax()]) + {$IFDEF ENABLE_GIBS} + e_LogWritefln('%s', [g_Gibs_GetMax()]) + {$ELSE} + e_LogWritefln('%s', [0]) + {$ENDIF} end else begin diff --git a/src/game/g_gibs.pas b/src/game/g_gibs.pas new file mode 100644 index 0000000..627764b --- /dev/null +++ b/src/game/g_gibs.pas @@ -0,0 +1,246 @@ +(* Copyright (C) Doom 2D: Forever Developers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License ONLY. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *) +{$INCLUDE ../shared/a_modes.inc} +unit g_gibs; + +interface + + uses g_phys, g_base; + + const + DefaultGibsCount = 32; + DefaultGibsMax = 150; + + type + PGib = ^TGib; + TGib = record + alive: Boolean; + RAngle: Integer; + Color: TRGB; + Obj: TObj; + ModelID: Integer; + GibID: Integer; + + procedure getMapBox (out x, y, w, h: Integer); inline; + procedure moveBy (dx, dy: Integer); inline; + procedure positionChanged; inline; //WARNING! call this after entity position was changed, or coldet will not w> + end; + + var + gGibsCount: Integer = DefaultGibsCount; // !!! make it private + gGibs: Array of TGib; + + procedure g_Gibs_SetMax (Count: Word); + function g_Gibs_GetMax (): Word; + + procedure g_Gibs_Create (fX, fY, mid: Integer; fColor: TRGB); + procedure g_Gibs_Update; + +implementation + + uses + {$IFDEF ENABLE_GFX} + g_gfx, + {$ENDIF} + {$IFNDEF HEADLESS} + r_render, + {$ENDIF} + g_playermodel, g_options, g_game + ; + + type + TGibsArray = Array of Integer; + + var + CurrentGib: Integer = 0; + MaxGibs: Word = DefaultGibsMax; + + procedure TGib.getMapBox (out x, y, w, h: Integer); inline; + begin + x := Obj.X + Obj.Rect.X; + y := Obj.Y + Obj.Rect.Y; + w := Obj.Rect.Width; + h := Obj.Rect.Height; + end; + + procedure TGib.moveBy (dx, dy: Integer); inline; + begin + if (dx <> 0) or (dy <> 0) then + begin + Obj.X += dx; + Obj.Y += dy; + positionChanged; + end; + end; + + procedure TGib.positionChanged (); inline; + begin + end; + + procedure g_Gibs_SetMax (Count: Word); + begin + MaxGibs := Count; + SetLength(gGibs, Count); + if CurrentGib >= Count then + CurrentGib := 0; + end; + + function g_Gibs_GetMax (): Word; + begin + Result := MaxGibs; + end; + + function g_Gibs_Get (ModelID: Integer; var Gibs: TGibsArray): Boolean; + var i, b: Integer; c: Boolean; + begin + Gibs := nil; + Result := False; + if (PlayerModelsArray = nil) or (gGibsCount = 0) then + Exit; + + c := False; + SetLength(Gibs, gGibsCount); + for i := 0 to High(Gibs) do + begin + if c and (PlayerModelsArray[ModelID].GibsCount = 1) then + begin + SetLength(Gibs, i); + Break; + end; + + repeat + b := Random(PlayerModelsArray[ModelID].GibsCount); + until not ((PlayerModelsArray[ModelID].GibsOnce = b + 1) and c); + + Gibs[i] := b; + + c := PlayerModelsArray[ModelID].GibsOnce = b + 1; + end; + Result := True; + end; + + procedure g_Gibs_Create (fX, fY, mid: Integer; fColor: TRGB); + var + a: Integer; + GibsArray: TGibsArray; + {$IFDEF ENABLE_GFX} + Blood: TModelBlood; + {$ENDIF} + begin + if mid = -1 then + Exit; + if (gGibs = nil) or (Length(gGibs) = 0) then + Exit; + if not g_Gibs_Get(mid, GibsArray) then + Exit; + + {$IFDEF ENABLE_GFX} + Blood := PlayerModelsArray[mid].Blood; + {$ENDIF} + + for a := 0 to High(GibsArray) do + begin + with gGibs[CurrentGib] do + begin + ModelID := mid; + GibID := GibsArray[a]; + Color := fColor; + alive := True; + g_Obj_Init(@Obj); + {$IFNDEF HEADLESS} + Obj.Rect := r_Render_GetGibRect(ModelID, GibID); + {$ELSE} + Obj.Rect.X := 16; + Obj.Rect.Y := 16; + Obj.Rect.Width := 16; + Obj.Rect.Height := 16; + {$ENDIF} + Obj.X := fX - Obj.Rect.X - (Obj.Rect.Width div 2); + Obj.Y := fY - Obj.Rect.Y - (Obj.Rect.Height div 2); + g_Obj_PushA(@Obj, 25 + Random(10), Random(361)); + positionChanged; // this updates spatial accelerators + RAngle := Random(360); + {$IFDEF ENABLE_GFX} + if gBloodCount > 0 then + begin + g_GFX_Blood( + fX, + fY, + 16 * gBloodCount + Random(5 * gBloodCount), + -16 + Random(33), + -16 + Random(33), + Random(48), + Random(48), + Blood.R, + Blood.G, + Blood.B, + Blood.Kind + ); + end; + {$ENDIF} + if CurrentGib >= High(gGibs) then + CurrentGib := 0 + else + Inc(CurrentGib); + end; + end; + end; + + procedure g_Gibs_Update; + var i: Integer; vel: TPoint2i; mr: Word; + begin + if gGibs = nil then + Exit; + for i := 0 to High(gGibs) do + if gGibs[i].alive then + with gGibs[i] do + begin + Obj.oldX := Obj.X; + Obj.oldY := Obj.Y; + + vel := Obj.Vel; + mr := g_Obj_Move(@Obj, True, False, True); + positionChanged(); // this updates spatial accelerators + + if WordBool(mr and MOVE_FALLOUT) then + begin + alive := False; + Continue; + end; + + // Отлетает от удара о стену/потолок/пол: + if WordBool(mr and MOVE_HITWALL) then + Obj.Vel.X := -(vel.X div 2); + if WordBool(mr and (MOVE_HITCEIL or MOVE_HITLAND)) then + Obj.Vel.Y := -(vel.Y div 2); + + if (Obj.Vel.X >= 0) then + begin // Clockwise + RAngle := RAngle + Abs(Obj.Vel.X)*6 + Abs(Obj.Vel.Y); + if RAngle >= 360 then + RAngle := RAngle mod 360; + end else begin // Counter-clockwise + RAngle := RAngle - Abs(Obj.Vel.X)*6 - Abs(Obj.Vel.Y); + if RAngle < 0 then + RAngle := (360 - (Abs(RAngle) mod 360)) mod 360; + end; + + // Сопротивление воздуха для куска трупа: + if gTime mod (GAME_TICK*3) = 0 then + Obj.Vel.X := z_dec(Obj.Vel.X, 1); + end; + end; + +end. diff --git a/src/game/g_menu.pas b/src/game/g_menu.pas index 6daf00c..62bf314 100644 --- a/src/game/g_menu.pas +++ b/src/game/g_menu.pas @@ -42,6 +42,9 @@ uses {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} g_gui, r_textures, r_graphics, g_game, g_map, g_base, g_basic, g_console, g_sound, g_player, g_options, g_weapons, e_log, SysUtils, CONFIG, g_playermodel, DateUtils, @@ -139,16 +142,20 @@ begin g_GFX_SetMax(TGUIScroll(menu.GetControl('scParticlesCount')).Value*1000); {$ENDIF} g_Shells_SetMax(TGUIScroll(menu.GetControl('scShellsMax')).Value*30); - g_Gibs_SetMax(TGUIScroll(menu.GetControl('scGibsMax')).Value*25); + {$IFDEF ENABLE_GIBS} + g_Gibs_SetMax(TGUIScroll(menu.GetControl('scGibsMax')).Value*25); + {$ENDIF} g_Corpses_SetMax(TGUIScroll(menu.GetControl('scCorpsesMax')).Value*5); - case TGUISwitch(menu.GetControl('swGibsCount')).ItemIndex of - 0: gGibsCount := 0; - 1: gGibsCount := 8; - 2: gGibsCount := 16; - 3: gGibsCount := 32; - else gGibsCount := 48; - end; + {$IFDEF ENABLE_GIBS} + case TGUISwitch(menu.GetControl('swGibsCount')).ItemIndex of + 0: gGibsCount := 0; + 1: gGibsCount := 8; + 2: gGibsCount := 16; + 3: gGibsCount := 32; + else gGibsCount := 48; + end; + {$ENDIF} gBloodCount := TGUISwitch(menu.GetControl('swBloodCount')).ItemIndex; gFlash := TGUISwitch(menu.GetControl('swScreenFlash')).ItemIndex; @@ -535,7 +542,9 @@ begin TGUIScroll(menu.GetControl('scParticlesCount')).Value := g_GFX_GetMax() div 1000; {$ENDIF} TGUIScroll(menu.GetControl('scShellsMax')).Value := g_Shells_GetMax() div 30; - TGUIScroll(menu.GetControl('scGibsMax')).Value := g_Gibs_GetMax() div 25; + {$IFDEF ENABLE_GIBS} + TGUIScroll(menu.GetControl('scGibsMax')).Value := g_Gibs_GetMax() div 25; + {$ENDIF} TGUIScroll(menu.GetControl('scCorpsesMax')).Value := g_Corpses_GetMax() div 5; TGUISwitch(menu.GetControl('swBloodCount')).ItemIndex := gBloodCount; @@ -551,14 +560,18 @@ begin with TGUISwitch(menu.GetControl('swGibsType')) do if gAdvGibs then ItemIndex := 1 else ItemIndex := 0; - with TGUISwitch(menu.GetControl('swGibsCount')) do - case gGibsCount of - 0: ItemIndex := 0; - 8: ItemIndex := 1; - 16: ItemIndex := 2; - 32: ItemIndex := 3; - else ItemIndex := 4; + {$IFDEF ENABLE_GIBS} + with TGUISwitch(menu.GetControl('swGibsCount')) do + begin + case gGibsCount of + 0: ItemIndex := 0; + 8: ItemIndex := 1; + 16: ItemIndex := 2; + 32: ItemIndex := 3; + else ItemIndex := 4; + end; end; + {$ENDIF} with TGUISwitch(menu.GetControl('swBackGround')) do if gDrawBackGround then ItemIndex := 0 else ItemIndex := 1; diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index e3374e4..78ae1a4 100644 --- a/src/game/g_monsters.pas +++ b/src/game/g_monsters.pas @@ -529,6 +529,9 @@ uses {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} e_log, g_sound, g_player, g_game, g_weapons, g_triggers, g_items, g_options, g_console, g_map, Math, wadreader, @@ -2523,29 +2526,31 @@ begin end else // "Наземные" монстры begin - // Возможно, пинаем куски: - if (FObj.Vel.X <> 0) and (gGibs <> nil) then - begin - b := Abs(FObj.Vel.X); - if b > 1 then b := b * (Random(8 div b) + 1); - for a := 0 to High(gGibs) do + {$IFDEF ENABLE_GIBS} + // Возможно, пинаем куски: + if (FObj.Vel.X <> 0) and (gGibs <> nil) then begin - if gGibs[a].alive and - g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, - FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then + b := Abs(FObj.Vel.X); + if b > 1 then b := b * (Random(8 div b) + 1); + for a := 0 to High(gGibs) do begin - // Пинаем куски - if FObj.Vel.X < 0 then - begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120); // налево - end - else + if gGibs[a].alive and + g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, + FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + // Пинаем куски + if FObj.Vel.X < 0 then + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120); // налево + end + else + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + end; end; end; end; - end; + {$ENDIF} // Боссы могут пинать трупы: if (FMonsterType in [MONSTER_CYBER, MONSTER_SPIDER, MONSTER_ROBO]) and (FObj.Vel.X <> 0) and (gCorpses <> nil) then @@ -3400,30 +3405,32 @@ begin end else // "Наземные" монстры begin - // Возможно, пинаем куски: - if (FObj.Vel.X <> 0) and (gGibs <> nil) then - begin - b := Abs(FObj.Vel.X); - if b > 1 then b := b * (Random(8 div b) + 1); - for a := 0 to High(gGibs) do + {$IFDEF ENBALE_GIBS} + // Возможно, пинаем куски: + if (FObj.Vel.X <> 0) and (gGibs <> nil) then begin - if gGibs[a].alive and - g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, - FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then + b := Abs(FObj.Vel.X); + if b > 1 then b := b * (Random(8 div b) + 1); + for a := 0 to High(gGibs) do begin - // Пинаем куски - if FObj.Vel.X < 0 then - begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120); // налево - end - else + if gGibs[a].alive and + g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, + FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + // Пинаем куски + if FObj.Vel.X < 0 then + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120); // налево + end + else + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + end; + positionChanged(); // this updates spatial accelerators end; - positionChanged(); // this updates spatial accelerators end; end; - end; + {$ENDIF} // Боссы могут пинать трупы: if (FMonsterType in [MONSTER_CYBER, MONSTER_SPIDER, MONSTER_ROBO]) and (FObj.Vel.X <> 0) and (gCorpses <> nil) then diff --git a/src/game/g_options.pas b/src/game/g_options.pas index e825938..706b902 100644 --- a/src/game/g_options.pas +++ b/src/game/g_options.pas @@ -49,7 +49,6 @@ var gAdvCorpses: Boolean; gAdvBlood: Boolean; gAdvGibs: Boolean; - gGibsCount: Integer; gBloodCount: Integer; gFlash: Integer; gDrawBackGround: Boolean; @@ -129,6 +128,9 @@ uses {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} e_log, e_input, g_console, g_sound, g_player, Math, g_map, g_net, g_netmaster, SysUtils, CONFIG, g_game, g_items, wadreader, envvars; @@ -285,9 +287,11 @@ begin g_GFX_SetMax(2000); {$ENDIF} g_Shells_SetMax(300); - g_Gibs_SetMax(150); g_Corpses_SetMax(20); - gGibsCount := 32; + {$IFDEF ENABLE_GIBS} + g_Gibs_SetMax(DefaultGibsMax); + gGibsCount := DefaultGibsCount; + {$ENDIF} gBloodCount := 4; gAdvBlood := True; gAdvCorpses := True; @@ -397,7 +401,9 @@ initialization {$ENDIF} (* Game *) - conRegVar('g_gibs_count', @gGibsCount, '', ''); + {$IFDEF ENABLE_GIBS} + conRegVar('g_gibs_count', @gGibsCount, '', ''); + {$ENDIF} conRegVar('g_blood_count', @gBloodCount, '', ''); conRegVar('g_adv_blood', @gAdvBlood, '', ''); conRegVar('g_adv_corpses', @gAdvCorpses, '', ''); diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas index ee8e17d..f9b7371 100644 --- a/src/game/g_panel.pas +++ b/src/game/g_panel.pas @@ -220,6 +220,9 @@ implementation {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} g_basic, g_map, g_game, g_weapons, g_triggers, g_console, g_language, g_monsters, g_player, g_grid, e_log, geom, utils, xstreams ; @@ -574,7 +577,9 @@ var px, py, pw, ph, pdx, pdy: Integer; squash: Boolean; plr: TPlayer; - gib: PGib; + {$IFDEF ENABLE_GIBS} + gib: PGib; + {$ENDIF} cor: TCorpse; mon: TMonster; mpfrid: LongWord; @@ -683,19 +688,21 @@ begin if not g_Game_IsClient and squash then plr.Damage(15000, 0, 0, 0, HIT_TRAP); end; - // process gibs - for f := 0 to High(gGibs) do - begin - gib := @gGibs[f]; - if not gib.alive then continue; - gib.getMapBox(px, py, pw, ph); - if not g_Collide(px, py, pw, ph, cx0, cy0, cw, ch) then continue; - if tryMPlatMove(px, py, pw, ph, pdx, pdy, squash, @ontop) then + {$IFDEF ENABLE_GIBS} + // process gibs + for f := 0 to High(gGibs) do begin - // set new position - gib.moveBy(pdx, pdy); // this will call `positionChanged()` for us + gib := @gGibs[f]; + if not gib.alive then continue; + gib.getMapBox(px, py, pw, ph); + if not g_Collide(px, py, pw, ph, cx0, cy0, cw, ch) then continue; + if tryMPlatMove(px, py, pw, ph, pdx, pdy, squash, @ontop) then + begin + // set new position + gib.moveBy(pdx, pdy); // this will call `positionChanged()` for us + end; end; - end; + {$ENDIF} // move and push corpses for f := 0 to High(gCorpses) do diff --git a/src/game/g_player.pas b/src/game/g_player.pas index db43832..68bee9a 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -501,23 +501,6 @@ type procedure LoadState (st: TStream); override; end; - PGib = ^TGib; - TGib = record - alive: Boolean; - RAngle: Integer; - Color: TRGB; - Obj: TObj; - - ModelID: Integer; - GibID: Integer; - - procedure getMapBox (out x, y, w, h: Integer); inline; - procedure moveBy (dx, dy: Integer); inline; - - procedure positionChanged (); inline; //WARNING! call this after entity position was changed, or coldet will not work right! - end; - - PShell = ^TShell; TShell = record alive: Boolean; @@ -570,7 +553,6 @@ type var gPlayers: Array of TPlayer; gCorpses: Array of TCorpse; - gGibs: Array of TGib; gShells: Array of TShell; gTeamStat: TTeamStat; gFly: Boolean = False; @@ -587,8 +569,6 @@ var function Lerp(X, Y, Factor: Integer): Integer; -procedure g_Gibs_SetMax(Count: Word); -function g_Gibs_GetMax(): Word; procedure g_Corpses_SetMax(Count: Word); function g_Corpses_GetMax(): Word; procedure g_Shells_SetMax(Count: Word); @@ -609,7 +589,6 @@ function g_Player_GetCount(): Byte; function g_Player_GetStats(): TPlayerStatArray; function g_Player_ValidName(Name: String): Boolean; function g_Player_CreateCorpse(Player: TPlayer): Integer; -procedure g_Player_CreateGibs (fX, fY, mid: Integer; fColor: TRGB); procedure g_Player_CreateShell(fX, fY, dX, dY: Integer; T: Byte); procedure g_Player_UpdatePhysicalObjects(); procedure g_Player_RemoveAllCorpses(); @@ -636,6 +615,9 @@ uses {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} e_log, g_map, g_items, g_console, Math, g_options, g_triggers, g_game, g_grid, e_res, wadreader, g_monsters, CONFIG, g_language, @@ -709,10 +691,8 @@ const BOTLIST_FILENAME = 'botlist.txt'; var - MaxGibs: Word = 150; MaxCorpses: Word = 20; MaxShells: Word = 300; - CurrentGib: Integer = 0; CurrentShell: Integer = 0; BotNames: Array of String; BotList: Array of TBotProfile; @@ -739,20 +719,6 @@ begin Result := g_Player_Get(UID1).FTeam = g_Player_Get(UID2).FTeam; end; -procedure g_Gibs_SetMax(Count: Word); -begin - MaxGibs := Count; - SetLength(gGibs, Count); - - if CurrentGib >= Count then - CurrentGib := 0; -end; - -function g_Gibs_GetMax(): Word; -begin - Result := MaxGibs; -end; - procedure g_Shells_SetMax(Count: Word); begin MaxShells := Count; @@ -1553,7 +1519,13 @@ begin with Player do begin - if (FHealth >= -50) or (gGibsCount = 0) then +{$IFDEF ENABLE_GIBS} + if (FHealth < -50) and (gGibsCount > 0) then + begin + g_Gibs_Create(FObj.X + PLAYER_RECT_CX, FObj.Y + PLAYER_RECT_CY, FModel.id, FModel.Color); + end + else +{$ENDIF} begin if (gCorpses = nil) or (Length(gCorpses) = 0) then Exit; @@ -1577,8 +1549,6 @@ begin Result := find_id; end - else - g_Player_CreateGibs(FObj.X + PLAYER_RECT_CX, FObj.Y + PLAYER_RECT_CY, FModel.id, FModel.Color); end; end; @@ -1618,73 +1588,6 @@ begin end; end; -procedure g_Player_CreateGibs (fX, fY, mid: Integer; fColor: TRGB); -var - a: Integer; - GibsArray: TGibsArray; - {$IFDEF ENABLE_GFX} - Blood: TModelBlood; - {$ENDIF} -begin - if mid = -1 then - Exit; - if (gGibs = nil) or (Length(gGibs) = 0) then - Exit; - if not g_PlayerModel_GetGibs(mid, GibsArray) then - Exit; - - {$IFDEF ENABLE_GFX} - Blood := PlayerModelsArray[mid].Blood; - {$ENDIF} - - for a := 0 to High(GibsArray) do - with gGibs[CurrentGib] do - begin - ModelID := mid; - GibID := GibsArray[a]; - Color := fColor; - alive := True; - g_Obj_Init(@Obj); - {$IFNDEF HEADLESS} - Obj.Rect := r_Render_GetGibRect(ModelID, GibID); - {$ELSE} - Obj.Rect.X := 16; - Obj.Rect.Y := 16; - Obj.Rect.Width := 16; - Obj.Rect.Height := 16; - {$ENDIF} - Obj.X := fX - Obj.Rect.X - (Obj.Rect.Width div 2); - Obj.Y := fY - Obj.Rect.Y - (Obj.Rect.Height div 2); - g_Obj_PushA(@Obj, 25 + Random(10), Random(361)); - positionChanged(); // this updates spatial accelerators - RAngle := Random(360); - - {$IFDEF ENABLE_GFX} - if gBloodCount > 0 then - begin - g_GFX_Blood( - fX, - fY, - 16 * gBloodCount + Random(5 * gBloodCount), - -16 + Random(33), - -16 + Random(33), - Random(48), - Random(48), - Blood.R, - Blood.G, - Blood.B, - Blood.Kind - ); - end; - {$ENDIF} - - if CurrentGib >= High(gGibs) then - CurrentGib := 0 - else - Inc(CurrentGib); - end; -end; - procedure g_Player_UpdatePhysicalObjects(); var i: Integer; @@ -1703,47 +1606,6 @@ var end; begin -// Куски мяса: - if gGibs <> nil then - for i := 0 to High(gGibs) do - if gGibs[i].alive then - with gGibs[i] do - begin - Obj.oldX := Obj.X; - Obj.oldY := Obj.Y; - - vel := Obj.Vel; - mr := g_Obj_Move(@Obj, True, False, True); - positionChanged(); // this updates spatial accelerators - - if WordBool(mr and MOVE_FALLOUT) then - begin - alive := False; - Continue; - end; - - // Отлетает от удара о стену/потолок/пол: - if WordBool(mr and MOVE_HITWALL) then - Obj.Vel.X := -(vel.X div 2); - if WordBool(mr and (MOVE_HITCEIL or MOVE_HITLAND)) then - Obj.Vel.Y := -(vel.Y div 2); - - if (Obj.Vel.X >= 0) then - begin // Clockwise - RAngle := RAngle + Abs(Obj.Vel.X)*6 + Abs(Obj.Vel.Y); - if RAngle >= 360 then - RAngle := RAngle mod 360; - end else begin // Counter-clockwise - RAngle := RAngle - Abs(Obj.Vel.X)*6 - Abs(Obj.Vel.Y); - if RAngle < 0 then - RAngle := (360 - (Abs(RAngle) mod 360)) mod 360; - end; - - // Сопротивление воздуха для куска трупа: - if gTime mod (GAME_TICK*3) = 0 then - Obj.Vel.X := z_dec(Obj.Vel.X, 1); - end; - // Трупы: if gCorpses <> nil then for i := 0 to High(gCorpses) do @@ -1808,26 +1670,6 @@ begin end; end; - -procedure TGib.getMapBox (out x, y, w, h: Integer); inline; -begin - x := Obj.X+Obj.Rect.X; - y := Obj.Y+Obj.Rect.Y; - w := Obj.Rect.Width; - h := Obj.Rect.Height; -end; - -procedure TGib.moveBy (dx, dy: Integer); inline; -begin - if (dx <> 0) or (dy <> 0) then - begin - Obj.X += dx; - Obj.Y += dy; - positionChanged(); - end; -end; - - procedure TShell.getMapBox (out x, y, w, h: Integer); inline; begin x := Obj.X; @@ -1846,20 +1688,22 @@ begin end; end; - -procedure TGib.positionChanged (); inline; begin end; procedure TShell.positionChanged (); inline; begin end; procedure g_Player_RemoveAllCorpses(); -var - i: Integer; + var i: Integer; + {$IFDEF ENABLE_GIBS} + var maxgibs: Integer; + {$ENDIF} begin - gGibs := nil; + {$IFDEF ENABLE_GIBS} + maxgibs := g_Gibs_GetMax(); + g_Gibs_SetMax(0); + g_Gibs_SetMax(maxgibs); + {$ENDIF} gShells := nil; - SetLength(gGibs, MaxGibs); - SetLength(gShells, MaxGibs); - CurrentGib := 0; + SetLength(gShells, MaxShells); CurrentShell := 0; if gCorpses <> nil then @@ -4045,8 +3889,9 @@ begin end; procedure TPlayer.Run(Direction: TDirection); -var - a, b: Integer; + {$IFDEF ENABLE_GIBS} + var a, b: Integer; + {$ENDIF} begin if MAX_RUNVEL > 8 then FlySmoke(); @@ -4061,30 +3906,32 @@ begin if FObj.Vel.X < MAX_RUNVEL then FObj.Vel.X := FObj.Vel.X + (MAX_RUNVEL shr 3); -// Возможно, пинаем куски: - if (FObj.Vel.X <> 0) and (gGibs <> nil) then - begin - b := Abs(FObj.Vel.X); - if b > 1 then b := b * (Random(8 div b) + 1); - for a := 0 to High(gGibs) do + {$IFDEF ENABLE_GIBS} + // Возможно, пинаем куски: + if (FObj.Vel.X <> 0) and (gGibs <> nil) then begin - if gGibs[a].alive and - g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, - FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then + b := Abs(FObj.Vel.X); + if b > 1 then b := b * (Random(8 div b) + 1); + for a := 0 to High(gGibs) do begin - // Пинаем куски - if FObj.Vel.X < 0 then - begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120) // налево - end - else + if gGibs[a].alive and + g_Obj_Collide(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y+FObj.Rect.Height-4, + FObj.Rect.Width, 8, @gGibs[a].Obj) and (Random(3) = 0) then begin - g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + // Пинаем куски + if FObj.Vel.X < 0 then + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)+120) // налево + end + else + begin + g_Obj_PushA(@gGibs[a].Obj, b, Random(61)); // направо + end; + gGibs[a].positionChanged(); // this updates spatial accelerators end; - gGibs[a].positionChanged(); // this updates spatial accelerators end; end; - end; + {$ENDIF} SetAction(A_WALK); end; @@ -5827,13 +5674,14 @@ begin FDamage := FDamage + Value; +{$IFDEF ENABLE_GIBS} if FDamage > 150 then begin if FModel <> nil then begin FState := CORPSE_STATE_REMOVEME; - g_Player_CreateGibs( + g_Gibs_Create( FObj.X + FObj.Rect.X + (FObj.Rect.Width div 2), FObj.Y + FObj.Rect.Y + (FObj.Rect.Height div 2), FModel.id, @@ -5853,17 +5701,18 @@ begin end end else - begin - FObj.Vel.X := FObj.Vel.X + vx; - FObj.Vel.Y := FObj.Vel.Y + vy; - {$IFDEF ENABLE_GFX} - Blood := FModel.GetBlood(); - g_GFX_Blood(FObj.X+PLAYER_CORPSERECT.X+(PLAYER_CORPSERECT.Width div 2), - FObj.Y+PLAYER_CORPSERECT.Y+(PLAYER_CORPSERECT.Height div 2), - Value, vx, vy, 16, (PLAYER_CORPSERECT.Height*2) div 3, - Blood.R, Blood.G, Blood.B, Blood.Kind); - {$ENDIF} - end; +{$ENDIF} + begin + FObj.Vel.X := FObj.Vel.X + vx; + FObj.Vel.Y := FObj.Vel.Y + vy; + {$IFDEF ENABLE_GFX} + Blood := FModel.GetBlood(); + g_GFX_Blood(FObj.X+PLAYER_CORPSERECT.X+(PLAYER_CORPSERECT.Width div 2), + FObj.Y+PLAYER_CORPSERECT.Y+(PLAYER_CORPSERECT.Height div 2), + Value, vx, vy, 16, (PLAYER_CORPSERECT.Height*2) div 3, + Blood.R, Blood.G, Blood.B, Blood.Kind); + {$ENDIF} + end; end; procedure TCorpse.Update(); diff --git a/src/game/g_playermodel.pas b/src/game/g_playermodel.pas index 34dbdfd..c2c7d4e 100644 --- a/src/game/g_playermodel.pas +++ b/src/game/g_playermodel.pas @@ -87,8 +87,6 @@ type TModelSoundArray = Array of TModelSound; - TGibsArray = Array of Integer; - TPlayerModel = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF} private FDirection: TDirection; @@ -136,7 +134,6 @@ procedure g_PlayerModel_FreeData(); function g_PlayerModel_Load(FileName: String): Boolean; function g_PlayerModel_GetNames(): SSArray; function g_PlayerModel_Get(ModelName: String): TPlayerModel; -function g_PlayerModel_GetGibs (ModelID: Integer; var Gibs: TGibsArray): Boolean; function g_PlayerModel_GetIndex (ModelName: String): Integer; {$IFDEF ENABLE_GFX} @@ -166,10 +163,12 @@ procedure g_PlayerModel_LoadFake (ModelName, FileName: String); // ======================= FileName: String; Anim: TModelTextures; - GibsCount: Integer; - GibsResource:String; - GibsMask: String; - GibsOnce: Integer; + {$IFDEF ENABLE_GIBS} + GibsCount: Integer; + GibsResource:String; + GibsMask: String; + GibsOnce: Integer; + {$ENDIF} end; var @@ -462,10 +461,12 @@ begin SlopSound := Min(Max(config.ReadInt('Sound', 'slop', 0), 0), 2); - GibsCount := config.ReadInt('Gibs', 'count', 0); - GibsResource := config.ReadStr('Gibs', 'resource', 'GIBS'); - GibsMask := config.ReadStr('Gibs', 'mask', 'GIBSMASK'); - GibsOnce := config.ReadInt('Gibs', 'once', -1); + {$IFDEF ENABLE_GIBS} + GibsCount := config.ReadInt('Gibs', 'count', 0); + GibsResource := config.ReadStr('Gibs', 'resource', 'GIBS'); + GibsMask := config.ReadStr('Gibs', 'mask', 'GIBSMASK'); + GibsOnce := config.ReadInt('Gibs', 'once', -1); + {$ENDIF} ok := True; for aa := WP_FIRST + 1 to WP_LAST do @@ -598,35 +599,6 @@ begin end; end; - function g_PlayerModel_GetGibs (ModelID: Integer; var Gibs: TGibsArray): Boolean; - var i, b: Integer; c: Boolean; - begin - Gibs := nil; - Result := False; - if (PlayerModelsArray = nil) or (gGibsCount = 0) then - Exit; - - c := False; - SetLength(Gibs, gGibsCount); - for i := 0 to High(Gibs) do - begin - if c and (PlayerModelsArray[ModelID].GibsCount = 1) then - begin - SetLength(Gibs, i); - Break; - end; - - repeat - b := Random(PlayerModelsArray[ModelID].GibsCount); - until not ((PlayerModelsArray[ModelID].GibsOnce = b + 1) and c); - - Gibs[i] := b; - - c := PlayerModelsArray[ModelID].GibsOnce = b + 1; - end; - Result := True; - end; - function g_PlayerModel_GetNames(): SSArray; var i: DWORD; diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas index b8c35a8..0353a85 100644 --- a/src/game/g_weapons.pas +++ b/src/game/g_weapons.pas @@ -114,6 +114,9 @@ implementation {$IFDEF ENABLE_GFX} g_gfx, {$ENDIF} + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} Math, g_map, g_player, g_sound, g_panel, g_console, g_options, g_game, g_triggers, MAPDEF, e_log, g_monsters, g_saveload, @@ -989,9 +992,10 @@ var end; end; -var - i, h, dx, dy, m, mm: Integer; - _angle: SmallInt; + var i, h, dx, dy, m, mm: Integer; + {$IFDEF ENABLE_GIBS} + var _angle: SmallInt; + {$ENDIF} begin result := false; @@ -1053,30 +1057,28 @@ begin end; end; - h := High(gGibs); - - if gAdvGibs and (h <> -1) then - for i := 0 to h do - if gGibs[i].alive then - with gGibs[i] do - begin - dx := Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2)-X; - dy := Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2)-Y; - - if dx > 1000 then dx := 1000; - if dy > 1000 then dy := 1000; - - if dx*dx+dy*dy < r then + {$IFDEF ENABLE_GIBS} + h := High(gGibs); + if gAdvGibs and (h <> -1) then + for i := 0 to h do + if gGibs[i].alive then + with gGibs[i] do begin - m := PointToRect(X, Y, Obj.X+Obj.Rect.X, Obj.Y+Obj.Rect.Y, - Obj.Rect.Width, Obj.Rect.Height); - _angle := GetAngle(Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2), - Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2), X, Y); - - g_Obj_PushA(@Obj, Round(15*(rad-m)/rad), _angle); - positionChanged(); // this updates spatial accelerators + dx := Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2)-X; + dy := Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2)-Y; + if dx > 1000 then dx := 1000; + if dy > 1000 then dy := 1000; + if dx*dx+dy*dy < r then + begin + m := PointToRect(X, Y, Obj.X+Obj.Rect.X, Obj.Y+Obj.Rect.Y, + Obj.Rect.Width, Obj.Rect.Height); + _angle := GetAngle(Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2), + Obj.Y+Obj.Rect.Y+(Obj.Rect.Height div 2), X, Y); + g_Obj_PushA(@Obj, Round(15*(rad-m)/rad), _angle); + positionChanged(); // this updates spatial accelerators + end; end; - end; + {$ENDIF} end; procedure g_Weapon_Init(); diff --git a/src/game/opengl/r_game.pas b/src/game/opengl/r_game.pas index f838360..3a64ad5 100644 --- a/src/game/opengl/r_game.pas +++ b/src/game/opengl/r_game.pas @@ -1549,7 +1549,9 @@ begin drawOther('weapons', @r_Weapon_Draw); drawOther('shells', @r_Player_DrawShells); drawOther('drawall', @r_Player_DrawAll); - drawOther('gibs', @r_PlayerModel_DrawGibs); + {$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); diff --git a/src/game/opengl/r_playermodel.pas b/src/game/opengl/r_playermodel.pas index e987730..cc10d12 100644 --- a/src/game/opengl/r_playermodel.pas +++ b/src/game/opengl/r_playermodel.pas @@ -25,13 +25,18 @@ interface procedure r_PlayerModel_Free; procedure r_PlayerModel_Update; procedure r_PlayerModel_Draw (pm: TPlayerModel; X, Y: Integer; Alpha: Byte = 0); - procedure r_PlayerModel_DrawGibs; - function r_PlayerModel_GetGibRect (m, id: Integer): TRectWH; + {$IFDEF ENABLE_GIBS} + procedure r_PlayerModel_DrawGibs; + function r_PlayerModel_GetGibRect (m, id: Integer): TRectWH; + {$ENDIF} implementation uses + {$IFDEF ENABLE_GIBS} + g_gibs, + {$ENDIF} SysUtils, Classes, Math, MAPDEF, utils, e_log, wadreader, ImagingTypes, Imaging, ImagingUtility, @@ -53,20 +58,24 @@ implementation base: DWORD; mask: DWORD; end; - Gibs: Array of record - base: DWORD; - mask: DWORD; - rect: TRectWH; - end; + {$IFDEF ENABLE_GIBS} + Gibs: Array of record + base: DWORD; + mask: DWORD; + rect: TRectWH; + end; + {$ENDIF} end; RedFlagFrames: DWORD; BlueFlagFrames: DWORD; FlagAnimState: TAnimationState; +{$IFDEF ENABLE_GIBS} function r_PlayerModel_GetGibRect (m, id: Integer): TRectWH; begin Result := Models[m].Gibs[id].rect end; +{$ENDIF} procedure r_PlayerModel_Initialize; begin @@ -180,12 +189,10 @@ implementation end; procedure r_PlayerModel_Load; - var - ID1, ID2: DWORD; - i, a, b: Integer; - prefix, aname: String; - base, mask: Pointer; - baseLen, maskLen: Integer; + {$IFDEF ENABLE_GIBS} + var base, mask: Pointer; baseLen, maskLen: Integer; + {$ENDIF} + var ID1, ID2: DWORD; i, a, b: Integer; prefix, aname: String; begin g_Frames_CreateWAD(@RedFlagFrames, 'FRAMES_FLAG_RED', GameWAD + ':TEXTURES\FLAGRED', 64, 64, 5, False); g_Frames_CreateWAD(@BlueFlagFrames, 'FRAMES_FLAG_BLUE', GameWAD + ':TEXTURES\FLAGBLUE', 64, 64, 5, False); @@ -234,28 +241,30 @@ implementation end end end; - SetLength(Models[i].Gibs, PlayerModelsArray[i].GibsCount); - if PlayerModelsArray[i].GibsCount > 0 then - begin - r_PlayerModel_LoadResource(prefix + PlayerModelsArray[i].GibsResource, base, baseLen); - r_PlayerModel_LoadResource(prefix + PlayerModelsArray[i].GibsMask, mask, maskLen); - if (base <> nil) and (mask <> nil) then + {$IFDEF ENABLE_GIBS} + SetLength(Models[i].Gibs, PlayerModelsArray[i].GibsCount); + if PlayerModelsArray[i].GibsCount > 0 then begin - for a := 0 to PlayerModelsArray[i].GibsCount - 1 do + r_PlayerModel_LoadResource(prefix + PlayerModelsArray[i].GibsResource, base, baseLen); + r_PlayerModel_LoadResource(prefix + PlayerModelsArray[i].GibsMask, mask, maskLen); + if (base <> nil) and (mask <> nil) then begin - if e_CreateTextureMemEx(base, baseLen, Models[i].Gibs[a].base, a * 32, 0, 32, 32) and - e_CreateTextureMemEx(mask, maskLen, Models[i].Gibs[a].mask, a * 32, 0, 32, 32) then + for a := 0 to PlayerModelsArray[i].GibsCount - 1 do begin - Models[i].Gibs[a].rect := g_PlayerModel_CalcGibSize(base, baseLen, a * 32, 0, 32, 32); - with Models[i].Gibs[a].Rect do - if Height > 3 then - Height := Height - 1 - Random(2); // ??? + if e_CreateTextureMemEx(base, baseLen, Models[i].Gibs[a].base, a * 32, 0, 32, 32) and + e_CreateTextureMemEx(mask, maskLen, Models[i].Gibs[a].mask, a * 32, 0, 32, 32) then + begin + Models[i].Gibs[a].rect := g_PlayerModel_CalcGibSize(base, baseLen, a * 32, 0, 32, 32); + with Models[i].Gibs[a].Rect do + if Height > 3 then + Height := Height - 1 - Random(2); // ??? + end end - end - end; - FreeMem(mask); - FreeMem(base); - end + end; + FreeMem(mask); + FreeMem(base); + end + {$ENDIF} end end end; @@ -393,6 +402,7 @@ begin e_Colors.B := 255; end; +{$IFDEF ENABLE_GIBS} procedure r_PlayerModel_DrawGibs; var i, fX, fY, m, id: Integer; a: TDFPoint; pobj: ^TObj; begin @@ -420,5 +430,6 @@ end; end end end; +{$ENDIF} end. diff --git a/src/game/opengl/r_render.pas b/src/game/opengl/r_render.pas index b49c5a9..253ff7d 100644 --- a/src/game/opengl/r_render.pas +++ b/src/game/opengl/r_render.pas @@ -36,7 +36,9 @@ interface function r_Render_WriteScreenShot (filename: String): Boolean; - function r_Render_GetGibRect (m, id: Integer): TRectWH; + {$IFDEF ENABLE_GIBS} + function r_Render_GetGibRect (m, id: Integer): TRectWH; + {$ENDIF} {$IFDEF ENABLE_GFX} procedure r_Render_QueueEffect (AnimType, X, Y: Integer); @@ -323,10 +325,12 @@ implementation end end; +{$IFDEF ENABLE_GIBS} function r_Render_GetGibRect (m, id: Integer): TRectWH; begin Result := r_PlayerModel_GetGibRect(m, id) end; +{$ENDIF} {$IFDEF ENABLE_GFX} procedure r_Render_QueueEffect (AnimType, X, Y: Integer); diff --git a/src/shared/a_modes.inc b/src/shared/a_modes.inc index ae6ded6..494c574 100644 --- a/src/shared/a_modes.inc +++ b/src/shared/a_modes.inc @@ -120,6 +120,11 @@ {$UNDEF ENABLE_GFX} {$DEFINE DISABLE_GFX} {$ENDIF} + {$IFDEF ENABLE_GIBS} + {$WARNING Gibs in headless mode has no sense. Disabled.} + {$UNDEF ENABLE_GIBS} + {$DEFINE DISABLE_GIBS} + {$ENDIF} {$ENDIF} {$IF DEFINED(ENABLE_MENU) AND DEFINED(DISABLE_MENU)} @@ -155,6 +160,17 @@ {$ENDIF} {$ENDIF} +{$IF DEFINED(ENABLE_GIBS) AND DEFINED(DISABLE_GIBS)} + {$ERROR Select ENABLE_GIBS or DISABLE_GIBS} +{$ELSEIF NOT DEFINED(ENABLE_GIBS) AND NOT DEFINED(DISABLE_GIBS)} + // default ENABLE/DISABLE gibs + {$IFDEF HEADLESS} + {$DEFINE DISABLE_GIBS} + {$ELSE} + {$DEFINE ENABLE_GIBS} + {$ENDIF} +{$ENDIF} + {$IF DEFINED(USE_SYSSTUB)} {$IF DEFINED(USE_SDL) OR DEFINED(USE_SDL2)} {$ERROR Only one system driver must be selected!}