note description: "[ r_data.c Preparation for data rendering, generation of lookups, caching, retrieval by name. ]" license: "[ Copyright (C) 1993-1996 by id Software, Inc. Copyright (C) 2005-2014 Simon Howard Copyright (C) 2021 Ilgiz Mustafin 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; either version 2 of the License, or (at your option) any later version. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ]" class R_DATA create make feature i_main: I_MAIN make (a_i_main: like i_main) do i_main := a_i_main create colormaps.make_empty create textures.make_empty create flattranslation.make_empty create texturetranslation.make_empty create textureheight.make_empty create texturewidthmask.make_empty end feature colormaps: ARRAY [LIGHTTABLE_T] numtextures: INTEGER_32 textures: ARRAY [TEXTURE_T] firstflat: INTEGER_32 lastflat: INTEGER_32 numflats: INTEGER_32 flattranslation: ARRAY [INTEGER_32] texturetranslation: ARRAY [INTEGER_32] textureheight: ARRAY [INTEGER_32] texturewidthmask: ARRAY [INTEGER_32] texturecolumnlump: detachable ARRAY [detachable ARRAY [INTEGER_16]] texturecolumnofs: detachable ARRAY [detachable ARRAY [NATURAL_16]] texturecomposite: detachable ARRAY [detachable MANAGED_POINTER] texturecompositesize: detachable ARRAY [INTEGER_32] firstspritelump: INTEGER_32 lastspritelump: INTEGER_32 numspritelumps: INTEGER_32 spritewidth: detachable ARRAY [FIXED_T] spriteoffset: detachable ARRAY [FIXED_T] spritetopoffset: detachable ARRAY [FIXED_T] feature r_inittextures -- Initializes the texture list -- with the textures from the world map. local i: INTEGER_32 j: INTEGER_32 maptex1: TEXTUREX maptex2: TEXTUREX names: PNAMES patchlookup: ARRAY [INTEGER_32] do create names.from_pointer (i_main.W_wad.w_cachelumpname ("PNAMES")) create patchlookup.make_filled (0, 0, names.names.count - 1) from i := 0 until i > names.names.upper loop patchlookup [i] := i_main.W_wad.w_checknumforname (names.names [i]) i := i + 1 variant names.names.upper - i + 1 end create maptex1.from_pointer (i_main.W_wad.w_cachelumpname ("TEXTURE1")) numtextures := maptex1.textures.count if i_main.W_wad.w_checknumforname ("TEXTURE2") /= -1 then create maptex2.from_pointer (i_main.W_wad.w_cachelumpname ("TEXTURE2")) numtextures := numtextures + maptex2.textures.count end create textures.make_filled (create {TEXTURE_T}.make, 0, numtextures - 1) create texturewidthmask.make_filled (0, 0, numtextures - 1) create textureheight.make_filled (0, 0, numtextures - 1) create texturecolumnlump.make_filled (Void, 0, numtextures - 1) create texturecomposite.make_filled (Void, 0, numtextures - 1) create texturecompositesize.make_filled (0, 0, numtextures - 1) create texturecolumnofs.make_filled (Void, 0, numtextures - 1) from i := 0 until i >= maptex1.textures.count loop textures [i] := create {TEXTURE_T}.make_from_maptexture_t (maptex1.textures [i], patchlookup) i := i + 1 end if attached maptex2 as m2 then from j := 0 until j >= m2.textures.count loop textures [i] := create {TEXTURE_T}.make_from_maptexture_t (m2.textures [j], patchlookup) i := i + 1 j := j + 1 end end from i := textures.lower until i > textures.upper loop check attached texturecolumnlump as tcl then tcl [i] := create {ARRAY [INTEGER_16]}.make_filled (0, 0, textures [i].width - 1.to_integer_32) end check attached texturecolumnofs as tco then tco [i] := create {ARRAY [NATURAL_16]}.make_filled (0, 0, textures [i].width - 1.to_integer_32) end from j := 1 until j * 2 > textures [i].width.to_integer_32 loop j := j |<< 1 end texturewidthmask [i] := j - 1 textureheight [i] := textures [i].height.to_integer_32 |<< {M_FIXED}.fracbits i := i + 1 end from i := 0 until i >= numtextures loop r_generatelookup (i) i := i + 1 end create texturetranslation.make_filled (0, 0, numtextures + 1) from i := 0 until i >= numtextures loop texturetranslation [i] := i i := i + 1 end ensure not texturetranslation.is_empty not texturewidthmask.is_empty end r_generatelookup (texnum: INTEGER_32) local texture: TEXTURE_T patchcount: ARRAY [INTEGER_32] patch: INTEGER_32 realpatch: PATCH_T x: INTEGER_32 x1: INTEGER_32 x2: INTEGER_32 i: INTEGER_32 collump: ARRAY [INTEGER_16] colofs: ARRAY [NATURAL_16] do texture := textures [texnum] check attached texturecomposite as tc then tc [texnum] := Void end check attached texturecompositesize as tcs then tcs [texnum] := 0 end check attached texturecolumnlump as tcl then collump := tcl [texnum] end check attached texturecolumnofs as tcofs then check attached tcofs [texnum] as tcofs_texnum then colofs := tcofs [texnum] end end create patchcount.make_filled (0, 0, texture.width - 1.to_integer_32) from i := 0 patch := 0 until i >= texture.patches.count loop realpatch := create {PATCH_T}.from_pointer (i_main.W_wad.w_cachelumpnum (texture.patches [patch].patch)) x1 := texture.patches [patch].originx x2 := x1 + realpatch.width.to_integer_32 if x1 < 0 then x := 0 else x := x1 end if x2 > texture.width.to_integer_32 then x2 := texture.width.to_integer_32 end from until x >= x2 loop patchcount [x] := patchcount [x] + 1 check attached collump as cl then collump [x] := texture.patches [patch].patch.to_integer_16 end check attached colofs then colofs [x] := (realpatch.columnofs [x - x1] + 3).to_natural_16 end x := x + 1 end i := i + 1 patch := patch + 1 end from x := 0 until x >= texture.width.to_integer_32 loop if patchcount [x] = 0 then print ("R_GenerateLookup: column without a patch (" + texture.name + ")%N") x := texture.width.to_integer_32 elseif patchcount [x] > 1 then check attached collump as cl then cl [x] := -1 end check attached texturecompositesize as tcs then check attached colofs then colofs [x] := tcs [texnum].to_natural_16 end if tcs [texnum] > 65536 - texture.height.to_integer_32 then {I_MAIN}.i_error ("R_GenerateLookup: texture " + texnum.out + " is > 64k") end tcs [texnum] := tcs [texnum] + texture.height.to_integer_32 end end x := x + 1 end end r_initflats local i: INTEGER_32 do firstflat := i_main.W_wad.w_getnumforname ("F_START") + 1 lastflat := i_main.W_wad.w_getnumforname ("F_END") - 1 numflats := lastflat - firstflat + 1 create flattranslation.make_filled (0, 0, numflats + 1) from i := 0 until i >= numflats loop flattranslation [i] := i i := i + 1 end end r_initspritelumps -- Finds the width and hoffset of all sprites in the wad, -- so the sprite does not need to be cached completely -- just for having the header info ready during rendering. local i: INTEGER_32 patch: PATCH_T do print ("R_InitSpriteLumps%N") firstspritelump := i_main.W_wad.w_getnumforname ("S_START") + 1 lastspritelump := i_main.W_wad.w_getnumforname ("S_END") - 1 numspritelumps := lastspritelump - firstspritelump + 1 create spritewidth.make_filled (create {FIXED_T}.from_integer (0), 0, numspritelumps - 1) create spriteoffset.make_filled (create {FIXED_T}.from_integer (0), 0, numspritelumps - 1) create spritetopoffset.make_filled (create {FIXED_T}.from_integer (0), 0, numspritelumps - 1) from i := 0 until i >= numspritelumps loop patch := create {PATCH_T}.from_pointer (i_main.W_wad.w_cachelumpnum (firstspritelump + i)) check attached spritewidth as sw and then attached spriteoffset as so and then attached spritetopoffset as st then sw [i] := create {FIXED_T}.from_integer (patch.width.to_integer_32 |<< {M_FIXED}.fracbits) so [i] := create {FIXED_T}.from_integer (patch.leftoffset.to_integer_32 |<< {M_FIXED}.fracbits) st [i] := create {FIXED_T}.from_integer (patch.topoffset.to_integer_32 |<< {M_FIXED}.fracbits) end i := i + 1 end end r_initcolormaps local i: INTEGER_32 lump, length: INTEGER_32 p: MANAGED_POINTER do lump := i_main.W_wad.w_getnumforname ("COLORMAP") length := i_main.W_wad.w_lumplength (lump) create colormaps.make_filled (create {LIGHTTABLE_T}.from_natural_8 ({NATURAL_8} 0), 0, length - 1) p := i_main.W_wad.w_readlump (lump) from i := 0 until i > colormaps.upper loop colormaps [i] := create {LIGHTTABLE_T}.from_natural_8 (p.read_natural_8_le (i)) i := i + 1 end end r_initdata do r_inittextures print ("%NInitTextures") r_initflats print ("%NInitFlats") r_initspritelumps print ("%NInitSprites") r_initcolormaps print ("%NInitColormaps") end r_texturenumforname (name: STRING_8): INTEGER_32 -- Calls R_CheckTextureForName, -- aborts with error message do Result := r_checktexturenumforname (name) if Result = -1 then {I_MAIN}.i_error ("R_TextureNumForName: " + name + " not found%N") end end r_checktexturenumforname (name: STRING_8): INTEGER_32 -- Check whether texture is available. -- Filter out NoTexture indicator. do if name.starts_with ("-") then Result := 0 else from Result := 0 until Result >= numtextures or else textures [Result].name.as_upper ~ name.as_upper loop Result := Result + 1 end if Result >= numtextures then Result := -1 end end end r_flatnumforname (name: STRING_8): INTEGER_32 -- Retrieval, get a flat number for a flat name. do Result := i_main.W_wad.w_checknumforname (name) if Result = -1 then {I_MAIN}.i_error ("R_FlatNumForName: " + name + " not found%N") end Result := Result - firstflat end r_precachelevel do {NOT_IMPLEMENTED}.not_implemented ("R_PrecacheLevel", False) end r_getcolumn (tex, a_col: INTEGER_32): MANAGED_POINTER_WITH_OFFSET local lump: INTEGER_32 ofs: INTEGER_32 col: INTEGER_32 do col := a_col col := col & texturewidthmask [tex] check attached texturecolumnlump as tcl then check attached tcl [tex] as tcl_tex then check attached tcl_tex [col] as tcl_tex_col then lump := tcl_tex_col.to_integer_32 end end end check attached texturecolumnofs as tcofs then check attached tcofs [tex] as tcofs_tex then ofs := tcofs_tex [col].to_integer_32 end end if lump > 0 then create Result.make (i_main.W_wad.w_cachelumpnum (lump), ofs) else check attached texturecomposite as tc_ar then if tc_ar [tex] = Void then r_generatecomposite (tex) end check attached tc_ar [tex] as tc then create Result.make (tc, ofs) end end end end r_generatecomposite (texnum: INTEGER_32) -- Using the texture definition, -- the composite texture is created from the patches, -- and each column is cached local block: MANAGED_POINTER texture: TEXTURE_T patch: INTEGER_32 realpatch: PATCH_T x: INTEGER_32 x1: INTEGER_32 x2: INTEGER_32 i: INTEGER_32 collump: ARRAY [INTEGER_16] colofs: ARRAY [NATURAL_16] do texture := textures [texnum] check attached texturecompositesize as tcs then check attached texturecomposite as tc then block := create {MANAGED_POINTER}.make (tcs [texnum]) tc [texnum] := block end end check attached texturecolumnlump as tcl then collump := tcl [texnum] end check attached texturecolumnofs as tcofs then check attached tcofs [texnum] as tcofs_texnum then colofs := tcofs_texnum end end from i := 0 patch := 0 until i >= texture.patches.count loop realpatch := create {PATCH_T}.from_pointer (i_main.W_wad.w_cachelumpnum (texture.patches [patch].patch)) x1 := texture.patches [patch].originx x2 := x1 + realpatch.width.to_integer_32 if x1 < 0 then x := 0 else x := x1 end if x2 > texture.width.to_integer_32 then x2 := texture.width.to_integer_32 end from until x >= x2 loop check attached collump then if collump [x] >= 0 then else r_drawcolumnincache (realpatch, x - x1, block, colofs [x].to_integer_32, texture.patches [patch].originy, texture.height.to_integer_32) end end x := x + 1 end i := i + 1 patch := patch + 1 end end r_drawcolumnincache (real_patch: PATCH_T; col_num: INTEGER_32; cache: MANAGED_POINTER; cache_ofs: INTEGER_32; originy: INTEGER_32; cacheheight: INTEGER_32) local count: INTEGER_32 position: INTEGER_32 source: ARRAY [NATURAL_8] column: COLUMN_T post_num: INTEGER_32 do from column := real_patch.columns [col_num + 1] post_num := 1 until post_num > column.posts.upper loop source := column.posts [post_num].body count := column.posts [post_num].length.to_integer_32 position := originy + column.posts [post_num].topdelta.to_integer_32 if position < 0 then count := count + position position := 0 end if position + count > cacheheight then count := cacheheight - position end if count > 0 then cache.put_array (source.subarray (0, count - 1), cache_ofs + position) end post_num := post_num + 1 end end end -- class R_DATA
Generated by ISE EiffelStudio