note
	description: "[
		r_main.c
		Rendering main loop and setup functions,
		 utility functions (BSP, geometry, trigonometry).
		See tables.c, too
	]"
	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_MAIN

inherit
	TABLES

	DOOMDEF_H

create 
	make

feature 

	i_main: I_MAIN

	make (a_i_main: like i_main)
		local
			i: INTEGER_32
		do
			i_main := a_i_main
			create viewplayer.make
			validcount := 1
			create scalelightfixed.make_filled (Void, 0, Maxlightscale - 1)
			create viewangletox.make_filled (0, 0, Fineangles // 2 - 1)
			from
				create scalelight.make_filled (create {ARRAY [detachable INDEX_IN_ARRAY [LIGHTTABLE_T]]}.make_empty, 0, Lightlevels - 1)
				i := 0
			until
				i >= Lightlevels
			loop
				scalelight [i] := create {ARRAY [detachable INDEX_IN_ARRAY [LIGHTTABLE_T]]}.make_filled (Void, 0, Maxlightscale - 1)
				i := i + 1
			end
			from
				create zlight.make_filled (create {ARRAY [detachable INDEX_IN_ARRAY [LIGHTTABLE_T]]}.make_empty, 0, Lightlevels - 1)
				i := 0
			until
				i >= Lightlevels
			loop
				zlight [i] := create {ARRAY [detachable INDEX_IN_ARRAY [LIGHTTABLE_T]]}.make_filled (Void, 0, Maxlightz - 1)
				i := i + 1
			end
		end
	
feature 

	viewx: FIXED_T

	viewy: FIXED_T

	viewz: FIXED_T
	
feature 

	viewplayer: PLAYER_T

	viewangle: ANGLE_T

	viewangleoffset: INTEGER_32

	extralight: INTEGER_32

	viewsin: FIXED_T

	viewcos: FIXED_T

	sscount: INTEGER_32 assign set_sscount

	set_sscount (a_sscount: like sscount)
		do
			sscount := a_sscount
		end

	linecount: INTEGER_32

	loopcount: INTEGER_32

	fixedcolormap: detachable INDEX_IN_ARRAY [LIGHTTABLE_T]
			-- lighttable_t*

	scalelightfixed: ARRAY [detachable INDEX_IN_ARRAY [LIGHTTABLE_T]]
			-- lighttable_t* []

	zlight: ARRAY [ARRAY [detachable INDEX_IN_ARRAY [LIGHTTABLE_T]]]
			-- ligghttable_t* [][]

	validcount: INTEGER_32 assign set_validcount
			-- increment every time a check is made

	set_validcount (a_validcount: like validcount)
		do
			validcount := a_validcount
		end

	Fieldofview: INTEGER_32 = 2048
			-- Fineangles in the SCREENWIDTH wide window.
	
feature 

	centerx: INTEGER_32

	centery: INTEGER_32

	centerxfrac: FIXED_T

	centeryfrac: FIXED_T

	projection: FIXED_T
	
feature 

	colfunc: detachable PROCEDURE assign set_colfunc

	set_colfunc (a_colfunc: like colfunc)
		do
			colfunc := a_colfunc
		end

	basecolfunc: detachable PROCEDURE

	fuzzcolfunc: detachable PROCEDURE

	transcolfunc: detachable PROCEDURE

	spanfunc: detachable PROCEDURE
	
feature 

	detailshift: INTEGER_32
			-- 0 = high, 1 = low
	
feature -- Lighting constants.

	Lightlevels: INTEGER_32 = 16

	Lightsegshift: INTEGER_32 = 4

	Maxlightscale: INTEGER_32 = 48

	Lightscaleshift: INTEGER_32 = 12

	Maxlightz: INTEGER_32 = 128

	Lightzshift: INTEGER_32 = 20

	Numcolormaps: INTEGER_32 = 32
			-- Number of diminishing brightness levels.
			-- There a 0-31, i.e. 32 LUT in the COLORMAP lump.

	scalelight: ARRAY [ARRAY [detachable INDEX_IN_ARRAY [LIGHTTABLE_T]]]
			-- lighttable_t* [][]
	
feature 

	Finecosine: ARRAY [FIXED_T]
		local
			l_start: INTEGER_32
			i: INTEGER_32
		once
			l_start := Fineangles // 4
			create Result.make_filled (create {FIXED_T}.from_integer (0), 0, Finesine.count - l_start - 1)
			from
				i := 0
			until
				i > Result.upper
			loop
				Result [i] := create {FIXED_T}.from_integer (Finesine [i + l_start])
				i := i + 1
			end
		ensure
			instance_free: class
		end

	Xtoviewangle: ARRAY [ANGLE_T]
			-- maps a screen pixel
			-- to the lowest viewangle that maps back to x ranges
			-- from clipangle to -clipangle
		once
			create Result.make_filled (create {ANGLE_T}.from_natural ({NATURAL_32} 0), 0, {DOOMDEF_H}.screenwidth)
		end

	r_pointonsegside (x, y: FIXED_T; line: SEG_T): INTEGER_32
		local
			lx: FIXED_T
			ly: FIXED_T
			ldx: FIXED_T
			ldy: FIXED_T
			dx: FIXED_T
			dy: FIXED_T
			left: FIXED_T
			right: FIXED_T
		do
			lx := line.v1.x
			ly := line.v1.y
			ldx := line.v2.x - lx
			ldy := line.v2.y - ly
			if ldx = create {FIXED_T}.from_integer (0) then
				if x <= lx then
					Result := (ldy > create {FIXED_T}.from_integer (0)).to_integer
				else
					Result := (ldy < create {FIXED_T}.from_integer (0)).to_integer
				end
			elseif ldy = create {FIXED_T}.from_integer (0) then
				if y <= ly then
					Result := (ldx < create {FIXED_T}.from_integer (0)).to_integer
				else
					Result := (ldx > create {FIXED_T}.from_integer (0)).to_integer
				end
			else
				dx := (x - lx)
				dy := (y - ly)
				if (ldy.bit_xor (ldx).bit_xor (dx).bit_xor (dy) & create {FIXED_T}.from_integer ((2147483648).to_integer_32)) /= create {FIXED_T}.from_integer (0) then
					if (ldy.bit_xor (dx)) & create {FIXED_T}.from_integer ((2147483648).to_integer_32) /= create {FIXED_T}.from_integer (0) then
						Result := 1
					else
						Result := 0
					end
				else
					left := {M_FIXED}.fixedmul (ldy |>> {M_FIXED}.fracbits, dx)
					right := {M_FIXED}.fixedmul (dy, ldx |>> {M_FIXED}.fracbits)
					if right < left then
						Result := 0
					else
						Result := 1
					end
				end
			end
		end
	
feature -- R_SetViewSize

	setsizeneeded: BOOLEAN

	setblocks: INTEGER_32

	setdetail: INTEGER_32

	r_setviewsize (blocks: INTEGER_32; detail: INTEGER_32)
			-- Do not really change anything here,
			--  because it might be in the middle of a refresh.
			-- The change will take effect next refresh.
		do
			setsizeneeded := True
			setblocks := blocks
			setdetail := detail
		end
	
feature -- precalculated math tables

	clipangle: ANGLE_T

	viewangletox: ARRAY [INTEGER_32]
			-- The viewangletox[viewangle + FINEANGLES/4] lookup
			-- maps the visible view angles to screen X coordinates,
			-- flattening the arc to a flat projection plane.
			-- There will be many angles mapped to the same X.
	
feature 

	r_scalefromglobalangle (visangle: ANGLE_T): FIXED_T
			-- Returns the texture mapping scale
			-- for the current line (horizontal span)
			-- at the given angle.
			-- rw_distance must be calculated first
		local
			scale: FIXED_T
			anglea: ANGLE_T
			angleb: ANGLE_T
			sinea: INTEGER_32
			sineb: INTEGER_32
			num: FIXED_T
			den: INTEGER_32
		do
			anglea := Ang90 + (visangle - viewangle)
			angleb := Ang90 + (visangle - i_main.R_segs.rw_normalangle)
			sinea := Finesine [anglea |>> Angletofineshift.as_integer_32]
			sineb := Finesine [angleb |>> Angletofineshift.as_integer_32]
			num := {M_FIXED}.fixedmul (projection, create {FIXED_T}.from_integer (sineb)) |<< detailshift
			den := {M_FIXED}.fixedmul (i_main.R_segs.rw_distance, create {FIXED_T}.from_integer (sinea)).to_integer_32
			if den > num |>> 16.as_integer_32 then
				scale := {M_FIXED}.fixeddiv (num, create {FIXED_T}.from_integer (den))
				if scale > create {FIXED_T}.from_integer (64 * {M_FIXED}.fracunit) then
					scale := create {FIXED_T}.from_integer (64 * {M_FIXED}.fracunit)
				elseif scale < create {FIXED_T}.from_integer (256) then
					scale := create {FIXED_T}.from_integer (256)
				end
			else
				scale := create {FIXED_T}.from_integer (64 * {M_FIXED}.fracunit)
			end
			Result := scale
		end

	r_executesetviewsize
		local
			cosadj: FIXED_T
			dy: FIXED_T
			i, j: INTEGER_32
			level: INTEGER_32
			startmap: INTEGER_32
		do
			setsizeneeded := False
			if setblocks = 11 then
				i_main.R_draw.scaledviewwidth := {DOOMDEF_H}.screenwidth
				i_main.R_draw.viewheight := {DOOMDEF_H}.screenheight
			else
				i_main.R_draw.scaledviewwidth := setblocks * 32
				i_main.R_draw.viewheight := (setblocks * 168 // 10).bit_and ((7).bit_not)
			end
			detailshift := setdetail
			i_main.R_draw.viewwidth := i_main.R_draw.scaledviewwidth |>> detailshift
			centery := i_main.R_draw.viewheight // 2
			centerx := i_main.R_draw.viewwidth // 2
			centerxfrac := create {FIXED_T}.from_integer (centerx |<< {M_FIXED}.fracbits)
			centeryfrac := create {FIXED_T}.from_integer (centery |<< {M_FIXED}.fracbits)
			projection := centerxfrac
			if detailshift = 0 then
				colfunc := agent i_main.R_draw.r_drawcolumn
				basecolfunc := agent i_main.R_draw.r_drawcolumn
				transcolfunc := agent i_main.R_draw.r_drawtranslatedcolumn
				spanfunc := agent i_main.R_draw.r_drawspan
			else
				colfunc := agent i_main.R_draw.r_drawcolumnlow
				basecolfunc := agent i_main.R_draw.r_drawcolumnlow
				fuzzcolfunc := agent i_main.R_draw.r_drawfuzzcolumn
				transcolfunc := agent i_main.R_draw.r_drawtranslatedcolumn
				spanfunc := agent i_main.R_draw.r_drawspanlow
			end
			i_main.R_draw.r_initbuffer (i_main.R_draw.scaledviewwidth, i_main.R_draw.viewheight)
			r_inittexturemapping
			i_main.R_things.pspritescale := create {FIXED_T}.from_integer ({M_FIXED}.fracunit * i_main.R_draw.viewwidth // Screenwidth)
			i_main.R_things.pspriteiscale := create {FIXED_T}.from_integer ({M_FIXED}.fracunit * Screenwidth // i_main.R_draw.viewwidth)
			from
				i := 0
			until
				i >= i_main.R_draw.viewwidth
			loop
				i_main.R_things.screenheightarray [i] := i_main.R_draw.viewheight.as_integer_16
				i := i + 1
			end
			from
				i := 0
			until
				i >= i_main.R_draw.viewheight
			loop
				dy := create {FIXED_T}.from_integer (((i - i_main.R_draw.viewheight // 2) |<< {M_FIXED}.fracbits) + {M_FIXED}.fracunit // 2)
				dy := create {FIXED_T}.from_integer (dy.abs)
				i_main.R_plane.Yslope [i] := {M_FIXED}.fixeddiv (create {FIXED_T}.from_integer ((i_main.R_draw.viewwidth |<< detailshift) // 2 * {M_FIXED}.fracunit), dy)
				i := i + 1
			end
			from
				i := 0
			until
				i >= i_main.R_draw.viewwidth
			loop
				cosadj := create {FIXED_T}.from_integer (Finecosine [Xtoviewangle [i] |>> Angletofineshift.as_integer_32].abs)
				i_main.R_plane.Distscale [i] := {M_FIXED}.fixeddiv (create {FIXED_T}.from_integer ({M_FIXED}.fracunit), cosadj)
				i := i + 1
			end
			from
				i := 0
			until
				i >= Lightlevels
			loop
				startmap := ((Lightlevels - 1 - i) * 2) * Numcolormaps // Lightlevels
				from
					j := 0
				until
					j >= Maxlightscale
				loop
					level := startmap - j * Screenwidth // (i_main.R_draw.viewwidth |<< detailshift) // Distmap
					if level < 0 then
						level := 0
					end
					if level >= Numcolormaps then
						level := Numcolormaps - 1
					end
					scalelight [i] [j] := create {INDEX_IN_ARRAY [LIGHTTABLE_T]}.make (level * 256, i_main.R_data.colormaps)
					j := j + 1
				end
				i := i + 1
			end
		end
	
feature 

	r_initpointtoangle
		do
		end

	r_inittables
		do
		end

	r_pointtodist (x, y: FIXED_T): FIXED_T
		local
			angle: INTEGER_32
			dx: FIXED_T
			dy: FIXED_T
			temp: FIXED_T
			dist: FIXED_T
		do
			dx := create {FIXED_T}.from_integer ((x - viewx).abs)
			dy := create {FIXED_T}.from_integer ((y - viewy).abs)
			if dy > dx then
				temp := dx
				dx := dy
				dy := temp
			end
			angle := (Tantoangle [{M_FIXED}.fixeddiv (dy, dx).to_integer_32 |>> Dbits] + Ang90) |>> Angletofineshift.as_integer_32
			dist := {M_FIXED}.fixeddiv (dx, create {FIXED_T}.from_integer (Finesine [angle]))
			Result := dist
		end

	r_inittexturemapping
		local
			i: INTEGER_32
			x: INTEGER_32
			t: INTEGER_32
			focallength: FIXED_T
		do
			focallength := {M_FIXED}.fixeddiv (centerxfrac, create {FIXED_T}.from_integer ({TABLES}.finetangent [Fineangles // 4 + {R_MAIN}.fieldofview // 2]))
			from
				i := 0
			until
				i >= Fineangles // 2
			loop
				if Finetangent [i] > {M_FIXED}.fracunit * 2 then
					t := -1
				elseif Finetangent [i] < - {M_FIXED}.fracunit * 2 then
					t := i_main.R_draw.viewwidth + 1
				else
					t := {M_FIXED}.fixedmul (create {FIXED_T}.from_integer (Finetangent [i]), focallength).to_integer_32
					t := ((centerxfrac - create {FIXED_T}.from_integer (t) + create {FIXED_T}.from_integer ({M_FIXED}.fracunit) - create {FIXED_T}.from_integer (1)) |>> {M_FIXED}.fracbits).to_integer_32
					if t < -1 then
						t := -1
					elseif t > i_main.R_draw.viewwidth + 1 then
						t := i_main.R_draw.viewwidth + 1
					end
				end
				viewangletox [i] := t
				i := i + 1
			end
			from
				x := 0
			until
				x > i_main.R_draw.viewwidth
			loop
				from
					i := 0
				until
					viewangletox [i] <= x
				loop
					i := i + 1
				end
				Xtoviewangle [x] := create {ANGLE_T}.from_natural (((i |<< Angletofineshift) - Ang90.as_integer_32).to_natural_32)
				x := x + 1
			end
			from
				i := 0
			until
				i >= Fineangles // 2
			loop
				t := {M_FIXED}.fixedmul (create {FIXED_T}.from_integer (Finetangent [i]), focallength).to_integer_32
				t := centerx - t
				if viewangletox [i] = -1 then
					viewangletox [i] := 0
				elseif viewangletox [i] = i_main.R_draw.viewwidth + 1 then
					viewangletox [i] := i_main.R_draw.viewwidth
				end
				i := i + 1
			end
			clipangle := Xtoviewangle [0]
		end
	
feature -- R_InitLightTables

	Distmap: INTEGER_32 = 2

	r_initlighttables
			-- Only inits the zlight table,
			-- because the scalelight table changes with view size
		local
			i: INTEGER_32
			j: INTEGER_32
			level: INTEGER_32
			startmap: INTEGER_32
			scale: INTEGER_32
		do
			from
				i := 0
			until
				i >= Lightlevels
			loop
				startmap := ((Lightlevels - 1 - i) * 2) * Numcolormaps // Lightlevels
				from
					j := 0
				until
					j >= Maxlightz
				loop
					scale := {M_FIXED}.fixeddiv (create {FIXED_T}.from_integer (Screenwidth // 2 * {M_FIXED}.fracunit), create {FIXED_T}.from_integer ((j + 1) |<< Lightzshift)).to_integer_32
					scale := scale |>> Lightscaleshift
					level := startmap - scale // Distmap
					if level < 0 then
						level := 0
					end
					if level >= Numcolormaps then
						level := Numcolormaps - 1
					end
					zlight [i] [j] := create {INDEX_IN_ARRAY [LIGHTTABLE_T]}.make (level * 256, i_main.R_data.colormaps)
					j := j + 1
				end
				i := i + 1
			end
		end
	
feature -- R_Init

	framecount: INTEGER_32
			-- just for profiling purposes

	r_init
		do
			i_main.R_data.r_initdata
			print ("%NR_InitData")
			r_initpointtoangle
			print ("%NR_InitPointToAngle")
			r_inittables
			print ("%NR_InitTables")
			r_setviewsize (i_main.M_menu.screenblocks, i_main.M_menu.detaillevel)
			i_main.R_plane.r_initplanes
			print ("%NR_InitPlanes")
			r_initlighttables
			print ("%NR_InitLightTables")
			i_main.R_sky.r_initskymap
			print ("%NR_InitSkyMap")
			i_main.R_draw.r_inittranslationtables
			print ("%NR_InitTranslationsTables")
			framecount := 0
		end
	
feature 

	r_pointtoangle2 (x1, y1, x2, y2: FIXED_T): ANGLE_T
		do
			viewx := x1
			viewy := y1
			Result := r_pointtoangle (x2, y2)
		end

	r_pointtoangle (a_x, a_y: FIXED_T): ANGLE_T
			-- To get a global angle from cartesian coordinates,
			--  the coordinates are flipped until they are in
			--  the first octant of the coordinate system, then
			--  the y (<= x) is scaled and divided by x to get a
			--  tangent (slope) value which is looked up in the
			--  tantoangle[] table.
		local
			x, y: FIXED_T
		do
			x := a_x - viewx
			y := a_y - viewy
			if x = create {FIXED_T}.from_integer (0) and y = create {FIXED_T}.from_integer (0) then
				Result := create {ANGLE_T}.from_natural ({NATURAL_32} 0)
			else
				if x >= create {FIXED_T}.from_integer (0) then
					if y >= create {FIXED_T}.from_integer (0) then
						if x > y then
							Result := Tantoangle [slopediv (y.as_natural_32, x.as_natural_32)]
						else
							Result := Ang90 - create {ANGLE_T}.from_natural ((1).as_natural_32) - Tantoangle [slopediv (x.as_natural_32, y.as_natural_32)]
						end
					else
						y := - y
						if x > y then
							Result := - Tantoangle [slopediv (y.as_natural_32, x.as_natural_32)]
						else
							Result := create {ANGLE_T}.from_natural ((Ang270 + Tantoangle [slopediv (x.as_natural_32, y.as_natural_32)]).as_natural_32)
						end
					end
				else
					x := - x
					if y >= create {FIXED_T}.from_integer (0) then
						if x > y then
							Result := Ang180 - create {ANGLE_T}.from_natural ((1).as_natural_32) - Tantoangle [slopediv (y.as_natural_32, x.as_natural_32)]
						else
							Result := Ang90 + Tantoangle [slopediv (x.as_natural_32, y.as_natural_32)]
						end
					else
						y := - y
						if x > y then
							Result := Ang180 + Tantoangle [slopediv (y.as_natural_32, x.as_natural_32)]
						else
							Result := Ang270 - create {ANGLE_T}.from_natural ((1).as_natural_32) - Tantoangle [slopediv (x.as_natural_32, y.as_natural_32)]
						end
					end
				end
			end
		end
	
feature 

	r_renderplayerview (player: PLAYER_T)
		do
			r_setupframe (player)
			i_main.R_bsp.r_clearclipsegs
			i_main.R_bsp.r_cleardrawsegs
			i_main.R_plane.r_clearplanes
			i_main.R_things.r_clearsprites
			i_main.D_net.netupdate
			i_main.R_bsp.r_renderbspnode (i_main.P_setup.nodes.count - 1)
			i_main.D_net.netupdate
			i_main.R_plane.r_drawplanes
			i_main.D_net.netupdate
			i_main.R_things.r_drawmasked
			i_main.D_net.netupdate
		end

	r_setupframe (player: PLAYER_T)
		local
			i: INTEGER_32
		do
			viewplayer := player
			check
					attached player.mo as mo
			then
				viewx := mo.x
				viewy := mo.y
				viewangle := mo.angle + create {ANGLE_T}.from_natural (viewangleoffset.to_natural_32)
			end
			extralight := player.extralight
			viewz := player.viewz
			viewsin := create {FIXED_T}.from_integer (Finesine [viewangle |>> Angletofineshift.as_integer_32])
			viewcos := Finecosine [viewangle |>> Angletofineshift.as_integer_32]
			sscount := 0
			if player.fixedcolormap /= 0 then
				fixedcolormap := create {INDEX_IN_ARRAY [LIGHTTABLE_T]}.make (player.fixedcolormap, i_main.R_data.colormaps)
				i_main.R_segs.walllights := scalelightfixed
				from
					i := 0
				until
					i >= Maxlightscale
				loop
					check
							attached fixedcolormap as fcm
					then
						scalelightfixed [i] := fcm
					end
					i := i + 1
				end
			else
				fixedcolormap := Void
			end
			framecount := framecount + 1
			validcount := validcount + 1
		end

	r_pointonside (x, y: FIXED_T; node: NODE_T): BOOLEAN
			-- Traverse BSP (sub) tree,
			-- check point against partition plane.
			-- Returns side False (front) or True (back)
		local
			dx: FIXED_T
			dy: FIXED_T
			left: FIXED_T
			right: FIXED_T
		do
			if node.dx = create {FIXED_T}.from_integer (0) then
				if x <= node.x then
					Result := node.dy > create {FIXED_T}.from_integer (0)
				else
					Result := node.dy < create {FIXED_T}.from_integer (0)
				end
			elseif node.dy = create {FIXED_T}.from_integer (0) then
				if y <= node.y then
					Result := node.dx < create {FIXED_T}.from_integer (0)
				else
					Result := node.dx > create {FIXED_T}.from_integer (0)
				end
			else
				dx := (x - node.x)
				dy := (y - node.y)
				if (node.dy.bit_xor (node.dx).bit_xor (dx).bit_xor (dy) & create {FIXED_T}.from_integer (({INTEGER_32} -2147483648))).to_boolean then
					if (node.dy.bit_xor (dx) & create {FIXED_T}.from_integer (({INTEGER_32} -2147483648))).to_boolean then
						Result := True
					else
						Result := False
					end
				else
					left := {M_FIXED}.fixedmul (node.dy |>> {M_FIXED}.fracbits, dx)
					right := {M_FIXED}.fixedmul (dy, node.dx |>> {M_FIXED}.fracbits)
					if right < left then
						Result := False
					else
						Result := True
					end
				end
			end
		end
	
feature 

	r_pointinsubsector (x, y: FIXED_T): SUBSECTOR_T
		local
			node: NODE_T
			side: INTEGER_32
			nodenum: INTEGER_32
		do
			if i_main.P_setup.numnodes = 0 then
				Result := i_main.P_setup.subsectors [i_main.P_setup.subsectors.lower]
			else
				nodenum := i_main.P_setup.numnodes - 1
				from
				until
					nodenum & {DOOMDATA_H}.nf_subsector /= 0
				loop
					node := i_main.P_setup.nodes [nodenum]
					side := r_pointonside (x, y, node).to_integer
					nodenum := node.children [side].to_integer_32
				end
				Result := i_main.P_setup.subsectors [nodenum & {DOOMDATA_H}.nf_subsector.bit_not]
			end
		end
	
invariant
		viewangletox.lower = 0
		viewangletox.count = Fineangles // 2
		scalelightfixed.lower = 0 and scalelightfixed.count = Maxlightscale
		scalelight.lower = 0 and scalelight.count = Lightlevels and across
			scalelight as sc_level
		all
			sc_level.item.lower = 0 and sc_level.item.count = Maxlightscale
		end
		zlight.lower = 0 and zlight.count = Lightlevels and across
			zlight as zl_level
		all
			zl_level.item.lower = 0 and zl_level.item.count = Maxlightz
		end

end -- class R_MAIN

Generated by ISE EiffelStudio