X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=03c029f6404dad7c884a4647d9752216b9ab6482;hb=b36923c380a9760c74967bc8c850517c386747db;hp=eb351a0c495808585b3e2f42cb6f51e3333104e1;hpb=8028f947967b9156e80eea51b7f8b50f3c5862b3;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index eb351a0..03c029f 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -20,7 +20,7 @@ interface uses SysUtils, Classes, mempool, - g_base, r_graphics, g_basic, MAPDEF, g_textures, + g_base, g_basic, MAPDEF, g_phys, utils, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec; type @@ -31,6 +31,7 @@ type Author: String; MusicName: String; SkyName: String; + SkyFullName: String; // used by render Height: Word; Width: Word; end; @@ -52,7 +53,6 @@ type State: Byte; Count: Integer; CaptureTime: LongWord; - Animation: TAnimation; Direction: TDirection; NeedSend: Boolean; end; @@ -152,6 +152,7 @@ const FLAG_RED = 1; FLAG_BLUE = 2; FLAG_DOM = 3; + FLAG_LAST = FLAG_DOM; FLAG_STATE_NONE = 0; FLAG_STATE_NORMAL = 1; @@ -196,15 +197,6 @@ const GridDrawableMask = (GridTagBack or GridTagStep or GridTagWall or GridTagDoor or GridTagAcid1 or GridTagAcid2 or GridTagWater or GridTagFore); - -type - TBinHeapPanelDrawCmp = class - public - class function less (const a, b: TPanel): Boolean; inline; - end; - - TBinHeapPanelDraw = specialize TBinaryHeapBase; - var gWalls: TPanelArray; gRenderBackgrounds: TPanelArray; @@ -216,18 +208,15 @@ var gFlags: array [FLAG_RED..FLAG_BLUE] of TFlag; //gDOMFlags: array of TFlag; gMapInfo: TMapInfo; - gBackSize: TDFPoint; gDoorMap: array of array of DWORD; gLiftMap: array of array of DWORD; gWADHash: TMD5Digest; - BackID: DWORD = DWORD(-1); gExternalResources: array of TDiskFileInfo = nil; gMovingWallIds: array of Integer = nil; gdbg_map_use_accel_render: Boolean = true; gdbg_map_use_accel_coldet: Boolean = true; profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY! - gDrawPanelList: TBinHeapPanelDraw = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()` gCurrentMap: TDynRecord = nil; gCurrentMapFileName: AnsiString = ''; // so we can skip texture reloading @@ -248,13 +237,17 @@ var (* private state *) implementation -uses - e_input, 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, r_textures, r_animations, - Math, g_monsters, g_saveload, g_language, g_netmsg, - sfs, xstreams, hashtable, wadreader, - g_res_downloader; + uses + {$IFDEF ENABLE_GFX} + g_gfx, + {$ENDIF} + e_input, e_log, e_res, g_items, 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, + sfs, xstreams, hashtable, wadreader, + g_res_downloader + ; const FLAGRECT: TRectWH = (X:15; Y:12; Width:33; Height:52); @@ -515,14 +508,6 @@ begin end; end; - -class function TBinHeapPanelDrawCmp.less (const a, b: TPanel): Boolean; inline; -begin - if (a.tag < b.tag) then begin result := true; exit; end; - if (a.tag > b.tag) then begin result := false; exit; end; - result := (a.arrIdx < b.arrIdx); -end; - var TextNameHash: THashStrInt = nil; // key: texture name; value: index in `Textures` BadTextNameHash: THashStrInt = nil; // set; so we won't spam with non-existing texture messages @@ -874,7 +859,6 @@ begin SetLength(Textures, Length(Textures) + 1); Textures[High(Textures)].TextureName := RecName; Textures[High(Textures)].FullName := ''; - Textures[High(Textures)].Anim := False; Result := High(Textures); TextNameHash.put(RecName, result); end; @@ -972,154 +956,98 @@ begin addResToExternalResList(GetReplacementWad(g_ExtractWadName(map.SkyName))); end; - -function CreateTexture (RecName: AnsiString; Map: string; log: Boolean): Integer; -var - WAD: TWADFile; - WADName, ResName: String; - ResData: Pointer; - ResLen: Integer; -begin - RecName := toLowerCase1251(RecName); - if (TextNameHash = nil) then TextNameHash := THashStrInt.Create(); - if TextNameHash.get(RecName, result) then + function CreateTexture (RecName: AnsiString; Map: String; log: Boolean): Integer; + var + HName: AnsiString; + WAD, WADz: TWADFile; + WADName, ResName: String; + ResData, ReszData: Pointer; + ResLen, ReszLen: Integer; + cfg: TConfig; + id: Integer; begin - // i found her! - //e_LogWritefln('texture ''%s'' already loaded (%s)', [RecName, result]); - exit; - end; - - Result := -1; - - if (BadTextNameHash <> nil) and BadTextNameHash.has(RecName) then - exit; // don't do it again and again - - case RecName of - TEXTURE_NAME_WATER, TEXTURE_NAME_ACID1, TEXTURE_NAME_ACID2: + Result := -1; + HName := toLowerCase1251(RecName); + if (TextNameHash = nil) then + TextNameHash := THashStrInt.Create(); + if TextNameHash.get(HName, Result) then begin - SetLength(Textures, Length(Textures) + 1); - Textures[High(Textures)].FullName := RecName; - Textures[High(Textures)].TextureName := RecName; - Textures[High(Textures)].Anim := False; - Result := High(Textures); - TextNameHash.put(RecName, result); + // e_LogWritefln('CreateTexture: found loaded %s', [Result]); end - else - WADName := GetReplacementWad(g_ExtractWadName(RecName)); - if (WADName <> '') then - addResToExternalResList(WADName); - if WADName = '' then - WADName := Map; - ResName := g_ExtractFilePathName(RecName); - - // !!! we have a better way to check that resource exists? - WAD := TWADFile.Create(); - if WAD.ReadFile(WadName) and WAD.GetResource(ResName, ResData, ResLen, log) then - begin - FreeMem(ResData); - SetLength(Textures, Length(Textures) + 1); - Textures[High(Textures)].FullName := WADName + ':' + ResName; - Textures[High(Textures)].TextureName := RecName; - Textures[High(Textures)].Anim := False; - Result := High(Textures); - TextNameHash.put(RecName, result); - end; - WAD.Free; - end; -end; - - -function CreateAnimTexture(RecName: String; Map: string; log: Boolean): Integer; -var - WAD: TWADFile; - TextureWAD: PChar = nil; - TextData: Pointer = nil; - cfg: TConfig = nil; - WADName: String; - ResLength: Integer; - f: Integer; -begin - RecName := toLowerCase1251(RecName); - if (TextNameHash = nil) then TextNameHash := THashStrInt.Create(); - if TextNameHash.get(RecName, result) then - begin - // i found her! - //e_LogWritefln('animated texture ''%s'' already loaded (%s)', [RecName, result]); - exit; - end; - - result := -1; - - //e_LogWritefln('*** Loading animated texture "%s"', [RecName]); - - if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create(); - if BadTextNameHash.get(RecName, f) then - begin - //e_WriteLog(Format('no animation texture %s (don''t worry)', [RecName]), MSG_NOTIFY); - exit; - end; - - // ×èòàåì 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(); - try - WAD.ReadFile(WADName); - if not WAD.GetResource(g_ExtractFilePathName(RecName), TextureWAD, ResLength, log) then + else begin - if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create(); - if log and (not BadTextNameHash.get(RecName, f)) then + Result := -1; + if (BadTextNameHash = nil) or not BadTextNameHash.has(HName) then begin - e_WriteLog(Format('Error loading animation texture %s', [RecName]), TMsgType.Warning); - //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING); + case RecName of + TEXTURE_NAME_WATER, TEXTURE_NAME_ACID1, TEXTURE_NAME_ACID2: + begin + SetLength(Textures, Length(Textures) + 1); + Textures[High(Textures)].FullName := RecName; + Textures[High(Textures)].TextureName := RecName; + Result := High(Textures); + TextNameHash.put(RecName, result); + end + else + WADName := GetReplacementWad(g_ExtractWadName(RecName)); + if (WADName <> '') then + addResToExternalResList(WADName); + if WADName = '' then + WADName := Map; + ResName := g_ExtractFilePathName(RecName); + WAD := TWADFile.Create(); + if WAD.ReadFile(WadName) then + begin + if WAD.GetResource(ResName, ResData, ResLen, log) then + begin + if IsWadData(ResData, ResLen) then + begin + WADz := TWADFile.Create(); + if WADz.ReadMemory(ResData, ResLen) then + begin + if WADz.GetResource('TEXT/ANIM', ReszData, ReszLen) then + begin + cfg := TConfig.CreateMem(ReszData, ReszLen); + if cfg <> nil then + begin + SetLength(Textures, Length(Textures) + 1); + Textures[High(Textures)].TextureName := RecName; + Textures[High(Textures)].FullName := WadName + ':' + ResName; + Textures[High(Textures)].FramesCount := cfg.ReadInt('', 'framecount', 0); + Textures[High(Textures)].Speed := cfg.ReadInt('', 'waitcount', 0); + Result := High(Textures); + TextNameHash.put(HName, result); + cfg.Free; + end; + FreeMem(ReszData); + end + end; + WADz.Free; + end + else + begin + SetLength(Textures, Length(Textures) + 1); + Textures[High(Textures)].FullName := WADName + ':' + ResName; + Textures[High(Textures)].TextureName := RecName; + Result := High(Textures); + TextNameHash.put(HName, result); + end; + FreeMem(ResData); + end + end; + WAD.Free; + end end; - BadTextNameHash.put(RecName, -1); - exit; end; - WAD.FreeWAD(); - - // íåò, ýòî ñóïåðìåí! - if not WAD.ReadMemory(TextureWAD, ResLength) then + if Result < 0 then begin - e_WriteLog(Format('Animated texture WAD file "%s" is invalid', [RecName]), TMsgType.Warning); - BadTextNameHash.put(RecName, -1); - exit; - end; - - // ×èòàåì INI-ðåñóðñ àíèì. òåêñòóðû è çàïîìèíàåì åãî óñòàíîâêè: - if not WAD.GetResource('TEXT/ANIM', TextData, ResLength) then - begin - e_WriteLog(Format('Animated texture file "%s" has invalid INI', [RecName]), TMsgType.Warning); - BadTextNameHash.put(RecName, -1); - exit; - end; - - WAD.Free(); - WAD := nil; - - cfg := TConfig.CreateMem(TextData, ResLength); - if cfg <> nil then - begin - SetLength(Textures, Length(Textures) + 1); - Textures[High(Textures)].TextureName := RecName; - Textures[High(Textures)].FullName := WadName + ':' + g_ExtractFilePathName(RecName); - Textures[High(Textures)].Anim := True; - Textures[High(Textures)].FramesCount := cfg.ReadInt('', 'framecount', 0); - Textures[High(Textures)].Speed := cfg.ReadInt('', 'waitcount', 0); - result := High(Textures); - TextNameHash.put(RecName, result); - cfg.Free(); - cfg := nil; - end; - finally - WAD.Free(); - cfg.Free(); - if (TextureWAD <> nil) then FreeMem(TextureWAD); - if (TextData <> nil) then FreeMem(TextData); + if (BadTextNameHash = nil) then + BadTextNameHash := THashStrInt.Create(); + if log and (not BadTextNameHash.get(HName, id)) then + e_WriteLog(Format('Error loading texture %s', [RecName]), TMsgType.Warning); + BadTextNameHash.put(HName, -1); + end end; -end; procedure CreateItem(Item: TDynRecord); begin @@ -1136,7 +1064,6 @@ end; procedure CreateArea(Area: TDynRecord); var a: Integer; - id: DWORD = 0; begin case Area.AreaType of AREA_DMPOINT, AREA_PLAYERPOINT1, AREA_PLAYERPOINT2, @@ -1176,14 +1103,7 @@ begin with gFlags[a] do begin - case a of - FLAG_RED: g_Frames_Get(id, 'FRAMES_FLAG_RED'); - FLAG_BLUE: g_Frames_Get(id, 'FRAMES_FLAG_BLUE'); - end; - - Animation := TAnimation.Create(id, True, 8); Obj.Rect := FLAGRECT; - g_Map_ResetFlag(a); end; end; @@ -1444,7 +1364,7 @@ var FileName, mapResName, TexName, s: AnsiString; Data: Pointer; Len: Integer; - ok, isAnim: Boolean; + ok: Boolean; CurTex, ntn: Integer; rec, texrec: TDynRecord; pttit: PTRec; @@ -1622,23 +1542,17 @@ begin else begin {$IF DEFINED(D2F_DEBUG_TXLOAD)} - e_LogWritefln(' Loading texture #%d: %s', [cnt, rec.Resource]); + e_LogWritefln(' Loading texture #%d: %s', [cnt, rec.Resource]); {$ENDIF} - //if g_Map_IsSpecialTexture(s) then e_WriteLog(' SPECIAL!', MSG_NOTIFY); - if rec.Anim then - begin - // Àíèìèðîâàííàÿ òåêñòóðà - ntn := CreateAnimTexture(rec.Resource, FileName, True); - if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [rec.Resource])); - end - else + ntn := CreateTexture(rec.Resource, FileName, True); + if ntn < 0 then begin - // Îáû÷íàÿ òåêñòóðà - ntn := CreateTexture(rec.Resource, FileName, True); - if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [rec.Resource])); + if rec.Anim then + g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [rec.Resource])) + else + g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [rec.Resource])); + ntn := CreateNullTexture(rec.Resource) end; - if (ntn < 0) then ntn := CreateNullTexture(rec.Resource); - rec.tagInt := ntn; // remember texture number end; g_Game_StepLoading(); @@ -1778,39 +1692,7 @@ begin if (k = NNF_NAME_BEFORE) or (k = NNF_NAME_AFTER) then begin - // Ïðîáóåì äîáàâèòü íîâóþ òåêñòóðó - if texrec.Anim then - begin - // Íà÷àëüíàÿ - àíèìèðîâàííàÿ, èùåì àíèìèðîâàííóþ - isAnim := True; - //e_LogWritefln('000: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); - ok := CreateAnimTexture(TexName, FileName, False) >= 0; - //e_LogWritefln('001: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); - if not ok then - begin - // Íåò àíèìèðîâàííîé, èùåì îáû÷íóþ - isAnim := False; - //e_LogWritefln('002: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); - ok := CreateTexture(TexName, FileName, False) >= 0; - //e_LogWritefln('003: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); - end; - end - else - begin - // Íà÷àëüíàÿ - îáû÷íàÿ, èùåì îáû÷íóþ - isAnim := False; - //e_LogWritefln('004: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); - ok := CreateTexture(TexName, FileName, False) >= 0; - //e_LogWritefln('005: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); - if not ok then - begin - // Íåò îáû÷íîé, èùåì àíèìèðîâàííóþ - isAnim := True; - //e_LogWritefln('006: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); - ok := CreateAnimTexture(TexName, FileName, False) >= 0; - //e_LogWritefln('007: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); - end; - end; + ok := CreateTexture(TexName, FileName, False) >= 0; // Îíà ñóùåñòâóåò. Çàíîñèì åå ID â ñïèñîê ïàíåëè if ok then @@ -1822,7 +1704,6 @@ begin begin SetLength(AddTextures, Length(AddTextures)+1); AddTextures[High(AddTextures)].Texture := c; - AddTextures[High(AddTextures)].Anim := isAnim; break; end; end; @@ -1831,7 +1712,6 @@ begin begin SetLength(AddTextures, Length(AddTextures)+1); AddTextures[High(AddTextures)].Texture := c; - AddTextures[High(AddTextures)].Anim := isAnim; end; end; end @@ -1842,7 +1722,6 @@ begin // Çàíîñèì òåêóùóþ òåêñòóðó íà ñâîå ìåñòî SetLength(AddTextures, Length(AddTextures)+1); AddTextures[High(AddTextures)].Texture := rec.tagInt; // internal texture number, not map index - AddTextures[High(AddTextures)].Anim := texrec.Anim; CurTex := High(AddTextures); ok := true; end @@ -1862,8 +1741,6 @@ begin // Çàíîñèì òîëüêî òåêóùóþ òåêñòóðó SetLength(AddTextures, 1); AddTextures[0].Texture := rec.tagInt; // internal texture number, not map index - AddTextures[0].Anim := false; - if (texrec <> nil) then AddTextures[0].Anim := texrec.Anim; CurTex := 0; end; @@ -1979,15 +1856,12 @@ begin //mapReader := nil; // Çàãðóçêà íåáà + gMapInfo.SkyFullName := ''; if (gMapInfo.SkyName <> '') then begin e_WriteLog(' Loading sky: ' + gMapInfo.SkyName, TMsgType.Notify); g_Game_SetLoadingText(_lc[I_LOAD_SKY], 0, False); - 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])) + gMapInfo.SkyFullName := e_GetResourcePath(WadDirs, gMapInfo.SkyName, g_ExtractWadName(Res)); end; // Çàãðóçêà ìóçûêè @@ -2012,8 +1886,10 @@ begin g_Weapon_Init(); g_Monsters_Init(); - // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé: - if not gLoadGameMode then g_GFX_Init(); + {$IFDEF ENABLE_GFX} + // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé: + if not gLoadGameMode then g_GFX_Init(); + {$ENDIF} // Ñáðîñ ëîêàëüíûõ ìàññèâîâ: mapTextureList := nil; @@ -2191,7 +2067,9 @@ procedure g_Map_Free(freeTextures: Boolean=true); end; begin - g_GFX_Free(); + {$IFDEF ENABLE_GFX} + g_GFX_Free; + {$ENDIF} g_Weapon_Free(); g_Items_Free(); g_Triggers_Free(); @@ -2247,14 +2125,6 @@ begin FreePanelArray(gBlockMon); gMovingWallIds := nil; - if BackID <> DWORD(-1) then - begin - gBackSize.X := 0; - gBackSize.Y := 0; - e_DeleteTexture(BackID); - BackID := DWORD(-1); - end; - g_Game_StopAllSounds(False); gMusic.FreeSound(); g_Sound_Delete(gMapInfo.MusicName); @@ -2305,8 +2175,6 @@ begin begin with gFlags[a] do begin - if gFlags[a].Animation <> nil then gFlags[a].Animation.Update(); - Obj.oldX := Obj.X; Obj.oldY := Obj.Y; @@ -2680,7 +2548,10 @@ begin if pan.Enabled and mapGrid.proxyEnabled[pan.proxyId] then exit; pan.Enabled := True; - g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, true); + + {$IFDEF ENABLE_GFX} + g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, true); + {$ENDIF} mapGrid.proxyEnabled[pan.proxyId] := true; //if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := true @@ -2706,7 +2577,9 @@ begin if (not pan.Enabled) and (not mapGrid.proxyEnabled[pan.proxyId]) then exit; pan.Enabled := False; - g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, false); + {$IFDEF ENABLE_GFX} + g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, false); + {$ENDIF} mapGrid.proxyEnabled[pan.proxyId] := false; //if (pan.proxyId >= 0) then begin mapGrid.removeBody(pan.proxyId); pan.proxyId := -1; end; @@ -2747,15 +2620,16 @@ begin begin LiftType := t; - g_Mark(X, Y, Width, Height, MARK_LIFT, false); - //TODO: make separate lift tags, and change tag here - - case LiftType of - LIFTTYPE_UP: g_Mark(X, Y, Width, Height, MARK_LIFTUP); - LIFTTYPE_DOWN: g_Mark(X, Y, Width, Height, MARK_LIFTDOWN); - LIFTTYPE_LEFT: g_Mark(X, Y, Width, Height, MARK_LIFTLEFT); - LIFTTYPE_RIGHT: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT); - end; + {$IFDEF ENABLE_GFX} + g_Mark(X, Y, Width, Height, MARK_LIFT, false); + //TODO: make separate lift tags, and change tag here + case LiftType of + LIFTTYPE_UP: g_Mark(X, Y, Width, Height, MARK_LIFTUP); + LIFTTYPE_DOWN: g_Mark(X, Y, Width, Height, MARK_LIFTDOWN); + LIFTTYPE_LEFT: g_Mark(X, Y, Width, Height, MARK_LIFTLEFT); + LIFTTYPE_RIGHT: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT); + end; + {$ENDIF} //if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid); // mark platform as interesting @@ -2955,8 +2829,11 @@ begin loadPanels(); ///// ///// - // Îáíîâëÿåì êàðòó ñòîëêíîâåíèé è ñåòêó - g_GFX_Init(); + {$IFDEF ENABLE_GFX} + // Îáíîâëÿåì êàðòó ñòîëêíîâåíèé è ñåòêó + g_GFX_Init(); + {$ENDIF} + //mapCreateGrid(); ///// Çàãðóæàåì ìóçûêó: /////