X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=7ec904be0437189e8670f3079ed3a3ff8481c4e5;hb=01ca3b4324c78f00caae7d5b16cd49efce31f831;hp=95bb1a02fd813f82536e759ee6a2b0cfa1f86f8c;hpb=414f2873efa0cce84499f64774db7000e6268971;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 95bb1a0..7ec904b 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -20,7 +20,7 @@ interface uses SysUtils, Classes, mempool, - e_graphics, g_basic, MAPDEF, g_textures, + g_base, r_graphics, g_basic, MAPDEF, g_textures, g_phys, utils, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec; type @@ -65,10 +65,6 @@ procedure g_Map_Update(); function g_Map_PanelByGUID (aguid: Integer): TPanel; inline; -procedure g_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor); // unaccelerated -procedure g_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer); - -procedure g_Map_DrawBack(dx, dy: Integer); function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; b1x3: Boolean=false): Boolean; function g_Map_CollideLiquid_Texture(X, Y: Integer; Width, Height: Word): DWORD; @@ -89,17 +85,15 @@ function g_Map_IsSpecialTexture(Texture: String): Boolean; function g_Map_GetPoint(PointType: Byte; var RespawnPoint: TRespawnPoint): Boolean; function g_Map_GetPointCount(PointType: Byte): Word; +function g_Map_GetRandomPointType(): Byte; function g_Map_HaveFlagPoints(): Boolean; procedure g_Map_ResetFlag(Flag: Byte); -procedure g_Map_DrawFlags(); procedure g_Map_SaveState (st: TStream); procedure g_Map_LoadState (st: TStream); -procedure g_Map_DrawPanelShadowVolumes(lightX: Integer; lightY: Integer; radius: Integer); - // returns panel or nil // sets `ex` and `ey` to `x1` and `y1` when no hit was detected function g_Map_traceToNearestWall (x0, y0, x1, y1: Integer; hitx: PInteger=nil; hity: PInteger=nil): TPanel; @@ -252,8 +246,7 @@ var implementation uses - {$INCLUDE ../nogl/noGLuses.inc} - e_input, g_main, e_log, e_texture, e_res, g_items, g_gfx, g_console, + e_input, g_main, e_log, e_res, g_items, g_gfx, g_console, g_weapons, g_game, g_sound, e_sound, CONFIG, g_options, g_triggers, g_player, Math, g_monsters, g_saveload, g_language, g_netmsg, @@ -529,12 +522,6 @@ begin result := (a.arrIdx < b.arrIdx); end; -procedure dplClear (); -begin - if (gDrawPanelList = nil) then gDrawPanelList := TBinHeapPanelDraw.Create() else gDrawPanelList.clear(); -end; - - var Textures: TLevelTextureArray = nil; TextNameHash: THashStrInt = nil; // key: texture name; value: index in `Textures` @@ -900,21 +887,100 @@ begin end; +function extractWadName (resourceName: string): string; +var + posN: Integer; +begin + posN := Pos(':', resourceName); + if posN > 0 then + Result:= Copy(resourceName, 0, posN-1) + else + Result := ''; +end; + + +procedure addResToExternalResList (res: AnsiString); +var + uname: AnsiString; + f: Integer; + fi: TDiskFileInfo; +begin + if g_Game_IsClient or not g_Game_IsNet then exit; + if (length(res) = 0) then exit; // map wad + //res := extractWadName(res); + //if (length(res) = 0) then exit; // map wad + uname := toLowerCase1251(res); + // do not add duplicates + for f := 0 to High(gExternalResources) do + begin + if (gExternalResources[f].userName = uname) then exit; + end; + //writeln('***(000) addResToExternalResList: res=[', res, ']'); + // add new resource + fi.userName := uname; + if not findFileCI(res) then exit; + //writeln('***(001) addResToExternalResList: res=[', res, ']'); + fi.diskName := res; + if (not GetDiskFileInfo(res, fi)) then + begin + fi.tag := -1; + end + else + begin + //writeln('***(002) addResToExternalResList: res=[', res, ']'); + fi.tag := 0; // non-zero means "cannot caclucate hash" + try + fi.hash := MD5File(fi.diskName); + except + fi.tag := -1; + end; + end; + //e_LogWritefln('addext: res=[%s]; uname=[%s]; diskName=[%s]', [res, fi.userName, fi.diskName]); + SetLength(gExternalResources, length(gExternalResources)+1); + gExternalResources[High(gExternalResources)] := fi; +end; + + +procedure compactExtResList (); +var + src, dest: Integer; +begin + src := 0; + dest := 0; + for src := 0 to High(gExternalResources) do + begin + if (gExternalResources[src].tag = 0) then + begin + // copy it + if (dest <> src) then gExternalResources[dest] := gExternalResources[src]; + Inc(dest); + end; + end; + if (dest <> length(gExternalResources)) then SetLength(gExternalResources, dest); +end; + + function GetReplacementWad (WadName: AnsiString): AnsiString; begin result := ''; if WadName <> '' then begin result := WadName; - if g_Game_IsClient then - result := g_Res_FindReplacementWad(WadName); - if (result = WadName) then - result := e_FindWad(WadDirs, result) + if g_Game_IsClient then result := g_Res_FindReplacementWad(WadName); + if (result = WadName) then result := e_FindWad(WadDirs, result) end; end; -function CreateTexture(RecName: AnsiString; Map: string; log: Boolean): Integer; +procedure generateExternalResourcesList (map: TDynRecord); +begin + SetLength(gExternalResources, 0); + addResToExternalResList(GetReplacementWad(g_ExtractWadName(map.MusicName))); + addResToExternalResList(GetReplacementWad(g_ExtractWadName(map.SkyName))); +end; + + +function CreateTexture (RecName: AnsiString; Map: string; log: Boolean): Integer; var WAD: TWADFile; TextureData: Pointer; @@ -973,6 +1039,7 @@ begin // Çàãðóæàåì ðåñóðñ òåêñòóðû â ïàìÿòü èç WAD'à: WADName := GetReplacementWad(g_ExtractWadName(RecName)); + if (WADName <> '') then addResToExternalResList(WADName); if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else WAD := TWADFile.Create(); @@ -1059,6 +1126,7 @@ begin // ×èòàåì WAD-ðåñóðñ àíèì.òåêñòóðû èç WAD'à â ïàìÿòü: WADName := GetReplacementWad(g_ExtractWadName(RecName)); + if (WADName <> '') then addResToExternalResList(WADName); if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else WAD := TWADFile.Create(); @@ -1449,82 +1517,6 @@ begin g_Mons_ForEach(monsDieTrig); end; -function extractWadName(resourceName: string): string; -var - posN: Integer; -begin - posN := Pos(':', resourceName); - if posN > 0 then - Result:= Copy(resourceName, 0, posN-1) - else - Result := ''; -end; - - -procedure addResToExternalResList (res: AnsiString); -var - uname: AnsiString; - f: Integer; - fi: TDiskFileInfo; -begin - if g_Game_IsClient or not g_Game_IsNet then exit; - if (length(res) = 0) then exit; // map wad - res := extractWadName(res); - if (length(res) = 0) then exit; // map wad - uname := toLowerCase1251(res); - // do not add duplicates - for f := 0 to High(gExternalResources) do - begin - if (gExternalResources[f].userName = uname) then exit; - end; - // add new resource - fi.userName := uname; - if (not GetDiskFileInfo(GameDir+'/wads/'+res, fi)) then - begin - fi.tag := -1; - end - else - begin - fi.tag := 0; // non-zero means "cannot caclucate hash" - try - fi.hash := MD5File(fi.diskName); - except - fi.tag := -1; - end; - end; - //e_LogWritefln('addext: res=[%s]; uname=[%s]; diskName=[%s]', [res, fi.userName, fi.diskName]); - SetLength(gExternalResources, length(gExternalResources)+1); - gExternalResources[High(gExternalResources)] := fi; -end; - - -procedure compactExtResList (); -var - src, dest: Integer; -begin - src := 0; - dest := 0; - for src := 0 to High(gExternalResources) do - begin - if (gExternalResources[src].tag = 0) then - begin - // copy it - if (dest <> src) then gExternalResources[dest] := gExternalResources[src]; - Inc(dest); - end; - end; - if (dest <> length(gExternalResources)) then SetLength(gExternalResources, dest); -end; - - -procedure generateExternalResourcesList (map: TDynRecord); -begin - SetLength(gExternalResources, 0); - addResToExternalResList(map.MusicName); - addResToExternalResList(map.SkyName); -end; - - procedure mapCreateGrid (); var mapX0: Integer = $3fffffff; @@ -1864,14 +1856,7 @@ begin ntn := CreateTexture(rec.Resource, FileName, True); if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [rec.Resource])); end; - if (ntn < 0) then - begin - ntn := CreateNullTexture(rec.Resource); - end - else - begin - addResToExternalResList(rec.Resource); - end; + if (ntn < 0) then ntn := CreateNullTexture(rec.Resource); rec.tagInt := ntn; // remember texture number end; @@ -2217,16 +2202,11 @@ begin begin e_WriteLog(' Loading sky: ' + gMapInfo.SkyName, TMsgType.Notify); g_Game_SetLoadingText(_lc[I_LOAD_SKY], 0, False); - if gTextureFilter then TEXTUREFILTER := GL_LINEAR else TEXTUREFILTER := GL_NEAREST; - try - s := e_GetResourcePath(WadDirs, gMapInfo.SkyName, g_ExtractWadName(Res)); - if g_Texture_CreateWAD(BackID, s) then - g_Game_SetupScreenSize - else - g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s])) - finally - TEXTUREFILTER := GL_NEAREST; - end; + s := e_GetResourcePath(WadDirs, gMapInfo.SkyName, g_ExtractWadName(Res)); + if g_Texture_CreateWAD(BackID, s, gTextureFilter) then + g_Game_SetupScreenSize + else + g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s])) end; // Çàãðóçêà ìóçûêè @@ -2625,71 +2605,6 @@ begin end; end; - -// old algo -procedure g_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor); - - procedure DrawPanels (constref panels: TPanelArray; drawDoors: Boolean=False); - var - idx: Integer; - begin - if (panels <> nil) then - begin - // alas, no visible set - for idx := 0 to High(panels) do - begin - if not (drawDoors xor panels[idx].Door) then panels[idx].Draw(hasAmbient, ambColor); - end; - end; - end; - -begin - case PanelType of - PANEL_WALL: DrawPanels(gWalls); - PANEL_CLOSEDOOR: DrawPanels(gWalls, True); - PANEL_BACK: DrawPanels(gRenderBackgrounds); - PANEL_FORE: DrawPanels(gRenderForegrounds); - PANEL_WATER: DrawPanels(gWater); - PANEL_ACID1: DrawPanels(gAcid1); - PANEL_ACID2: DrawPanels(gAcid2); - PANEL_STEP: DrawPanels(gSteps); - end; -end; - - -// new algo -procedure g_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer); -var - mwit: PPanel; - it: TPanelGrid.Iter; -begin - dplClear(); - it := mapGrid.forEachInAABB(x0, y0, wdt, hgt, GridDrawableMask); - for mwit in it do if (((mwit^.tag and GridTagDoor) <> 0) = mwit^.Door) then gDrawPanelList.insert(mwit^); - it.release(); - // list will be rendered in `g_game.DrawPlayer()` -end; - - -procedure g_Map_DrawPanelShadowVolumes (lightX: Integer; lightY: Integer; radius: Integer); -var - mwit: PPanel; - it: TPanelGrid.Iter; -begin - it := mapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, (GridTagWall or GridTagDoor)); - for mwit in it do mwit^.DrawShadowVolume(lightX, lightY, radius); - it.release(); -end; - - -procedure g_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 g_Map_CollidePanelOld(X, Y: Integer; Width, Height: Word; PanelType: Word; b1x3: Boolean=false): Boolean; var @@ -3124,6 +3039,14 @@ begin Result := Result + 1; end; +function g_Map_GetRandomPointType(): Byte; +begin + if RespawnPoints = nil then + Result := 255 + else + Result := RespawnPoints[Random(Length(RespawnPoints))].PointType; +end; + function g_Map_HaveFlagPoints(): Boolean; begin Result := (FlagPoints[FLAG_RED] <> nil) and (FlagPoints[FLAG_BLUE] <> nil); @@ -3150,46 +3073,6 @@ begin end; end; -procedure g_Map_DrawFlags(); -var - i, dx: Integer; - Mirror: TMirrorType; -begin - if gGameSettings.GameMode <> GM_CTF then - Exit; - - for i := FLAG_RED to FLAG_BLUE do - with gFlags[i] do - if State <> FLAG_STATE_CAPTURED then - begin - if State = FLAG_STATE_NONE then - continue; - - if Direction = TDirection.D_LEFT then - begin - Mirror := TMirrorType.Horizontal; - dx := -1; - end - else - begin - Mirror := TMirrorType.None; - dx := 1; - end; - - Animation.Draw(Obj.X+dx, Obj.Y+1, Mirror); - - if g_debug_Frames then - begin - e_DrawQuad(Obj.X+Obj.Rect.X, - Obj.Y+Obj.Rect.Y, - Obj.X+Obj.Rect.X+Obj.Rect.Width-1, - Obj.Y+Obj.Rect.Y+Obj.Rect.Height-1, - 0, 255, 0); - end; - end; -end; - - procedure g_Map_SaveState (st: TStream); var str: String;