Merge pull request #1347 from PJB3005/master

Lighting optimizations.
This commit is contained in:
Fox-McCloud
2015-06-20 17:38:58 -04:00
15 changed files with 219 additions and 51 deletions
@@ -7,4 +7,9 @@
#define LIGHTING_RESOLUTION 1 // resolution of the lighting overlays, powers of 2 only, max of 32
#define LIGHTING_LAYER 10 // drawing layer for lighting overlays
#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects
#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects
#ifdef LIGHTING_TRANSITIONS
#define LIGHTING_TRANSITION_SPEED (LIGHTING_INTERVAL - 1)
#endif
#define LIGHTING_ROUND_VALUE (1 / 128) //Value used to round lumcounts, values smaller than 1/255 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY.
+3 -1
View File
@@ -10,4 +10,6 @@
#define T20C 293.15 // 20degC
#define TCMB 2.7 // -270.3degC
#define CLAMP01(x) max(0, min(1, x))
#define Clamp(x, y, z) (x <= y ? y : (x >= z ? z : x))
#define CLAMP01(x) (Clamp(x, 0, 1))
+5 -2
View File
@@ -17,8 +17,11 @@ var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
/proc/Ceiling(x)
return -round(-x)
//Replaced in /code/__DEFINES/math.dm because holy shit man a define is faster.
/*
/proc/Clamp(val, min, max)
return max(min, min(val, max))
*/
// cotangent
/proc/Cot(x)
@@ -117,7 +120,7 @@ var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
var/d = max - min
var/t = Floor((val - min) / d)
return val - (t * d)
/proc/RaiseToPower(num, power)
if(!power) return 1
return (power-- > 1 ? num * RaiseToPower(num, power) : num)
@@ -146,4 +149,4 @@ var/gaussian_next
R1 *= working
gaussian_next = R2 * working
return (mean + stddev * R1)
#undef ACCURACY
#undef ACCURACY
+22 -1
View File
@@ -1658,4 +1658,25 @@ atom/proc/GetTypeInAllContents(typepath)
if(direction & WEST)
dest_x = max(0, dest_x-distance)
return locate(dest_x,dest_y,dest_z)
return locate(dest_x,dest_y,dest_z)
//Version of view() which ignores darkness, because BYOND doesn't have it.
/proc/dview(var/range = world.view, var/center, var/invis_flags = 0)
if(!center)
return
var/global/mob/dview/DV
if(!DV)
DV = new
DV.loc = center
DV.see_in_dark = range
DV.see_invisible = invis_flags
. = view(range, DV)
DV.loc = null
/mob/dview
invisibility = 101
density = 0
+1 -1
View File
@@ -28,7 +28,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon = 'icons/turf/areas.dmi'
icon_state = "unknown"
layer = 10
luminosity = 1
luminosity = 0
mouse_opacity = 0
var/lightswitch = 1
+16 -1
View File
@@ -1,6 +1,7 @@
/turf
icon = 'icons/turf/floors.dmi'
level = 1.0
luminosity = 0
//for floors, use is_plating(), is_plasteel_floor() and is_light_floor()
var/intact = 1
@@ -36,7 +37,9 @@
spawn( 0 )
src.Entered(AM)
return
return
if(!dynamic_lighting)
luminosity = 1
// Adds the adjacent turfs to the current atmos processing
/turf/Del()
@@ -232,6 +235,12 @@
var/old_opacity = opacity
var/old_dynamic_lighting = dynamic_lighting
var/list/old_affecting_lights = affecting_lights
#if LIGHTING_RESOLUTION == 1
var/old_lighting_overlay = lighting_overlay
#else
var/old_lighting_overlay = lighting_overlays
#endif
if(air_master)
air_master.remove_from_active(src)
@@ -244,6 +253,12 @@
for(var/turf/space/S in range(W,1))
S.update_starlight()
#if LIGHTING_RESOLUTION == 1
lighting_overlay = old_lighting_overlay
#else
lighting_overlays = old_lighting_overlay
#endif
affecting_lights = old_affecting_lights
if((old_opacity != opacity) || (dynamic_lighting != old_dynamic_lighting))
reconsider_lights()
+59 -17
View File
@@ -60,13 +60,16 @@
if(top_atom != source_atom)
if(!top_atom.light_sources) top_atom.light_sources = list()
top_atom.light_sources += src
lighting_update_lights += src
needs_update = 1
if(!needs_update) //Incase we're already updating either way.
lighting_update_lights += src
needs_update = 1
/datum/light_source/proc/force_update()
needs_update = 1
force_update = 1
lighting_update_lights += src
if(!needs_update) //Incase we're already updating either way.
needs_update = 1
lighting_update_lights += src
/datum/light_source/proc/check()
if(!source_atom || !light_range || !light_power)
@@ -142,28 +145,67 @@
/datum/light_source/proc/apply_lum()
applied = 1
if(istype(source_turf))
for(var/atom/movable/lighting_overlay/O in view(light_range, source_turf))
var/strength = light_power * falloff(O)
#if LIGHTING_RESOLUTION == 1
for(var/turf/T in dview(light_range, source_turf, INVISIBILITY_LIGHTING))
if(T.lighting_overlay)
var/strength = light_power * falloff(T.lighting_overlay)
if(!strength) //Don't add turfs that aren't affected to the affected turfs.
continue
effect_r[O] = lum_r * strength
effect_g[O] = lum_g * strength
effect_b[O] = lum_b * strength
effect_r[T.lighting_overlay] = round(lum_r * strength, LIGHTING_ROUND_VALUE)
effect_g[T.lighting_overlay] = round(lum_g * strength, LIGHTING_ROUND_VALUE)
effect_b[T.lighting_overlay] = round(lum_b * strength, LIGHTING_ROUND_VALUE)
T.lighting_overlay.update_lumcount(
round(lum_r * strength, LIGHTING_ROUND_VALUE),
round(lum_g * strength, LIGHTING_ROUND_VALUE),
round(lum_b * strength, LIGHTING_ROUND_VALUE)
)
if(!T.affecting_lights)
T.affecting_lights = list()
O.update_lumcount(lum_r * strength, lum_g * strength, lum_b * strength)
for(var/turf/T in view(light_range, source_turf))
if(!T.affecting_lights) T.affecting_lights = list()
T.affecting_lights += src
effect_turf += T
#else
for(var/turf/T in dview(light_range, source_turf, INVISIBILITY_LIGHTING))
for(var/atom/movable/lighting_overlay/L in T.lighting_overlays)
var/strength = light_power * falloff(L)
effect_r[L] = round(lum_r * strength, LIGHTING_ROUND_VALUE)
effect_g[L] = round(lum_g * strength, LIGHTING_ROUND_VALUE)
effect_b[L] = round(lum_b * strength, LIGHTING_ROUND_VALUE)
L.update_lumcount(
round(lum_r * strength, LIGHTING_ROUND_VALUE),
round(lum_g * strength, LIGHTING_ROUND_VALUE),
round(lum_b * strength, LIGHTING_ROUND_VALUE)
)
if(!T.affecting_lights)
T.affecting_lights = list()
T.affecting_lights += src
effect_turf += T
#endif
/datum/light_source/proc/remove_lum()
applied = 0
for(var/atom/movable/lighting_overlay/O in effect_r)
O.update_lumcount(-effect_r[O], -effect_g[O], -effect_b[O])
for(var/turf/T in effect_turf)
if(T.affecting_lights) T.affecting_lights -= src
if(T.affecting_lights)
T.affecting_lights -= src
#if LIGHTING_RESOLUTION == 1
if(T.lighting_overlay)
T.lighting_overlay.update_lumcount(-effect_r[T.lighting_overlay], -effect_g[T.lighting_overlay], -effect_b[T.lighting_overlay])
#else
for(var/atom/movable/lighting_overlay/L in T.lighting_overlays)
L.lighting_overlay.update_lumcount(-effect_r[L], -effect_g[L], -effect_b[L])
#endif
effect_r.Cut()
effect_g.Cut()
effect_b.Cut()
effect_turf.Cut()
effect_turf.Cut()
+56 -4
View File
@@ -35,12 +35,32 @@
return (lum - minlum) / (maxlum - minlum)
/atom/movable/lighting_overlay/proc/update_lumcount(delta_r, delta_g, delta_b)
if(!delta_r && !delta_g && !delta_b) //Nothing is being changed all together.
return
var/should_update = 0
if(!needs_update) //If this isn't true, we're already updating anyways.
if(max(lum_r, lum_g, lum_b) < 1) //Any change that could happen WILL change appearance.
should_update = 1
else if(max(lum_r + delta_r, lum_g + delta_g, lum_b + delta_b) < 1) //The change would bring us under 1 max lum, again, guaranteed to change appearance.
should_update = 1
else //We need to make sure that the colour ratios won't change in this code block.
var/mx1 = max(lum_r, lum_g, lum_b)
var/mx2 = max(lum_r + delta_r, lum_g + delta_g, lum_b + delta_b)
if(lum_r / mx1 != (lum_r + delta_r) / mx2 || lum_g / mx1 != (lum_g + delta_g) / mx2 || lum_b / mx1 != (lum_b + delta_b) / mx2) //Stuff would change.
should_update = 1
lum_r += delta_r
lum_g += delta_g
lum_b += delta_b
needs_update = 1
lighting_update_overlays += src
if(!needs_update && should_update)
needs_update = 1
lighting_update_overlays += src
/atom/movable/lighting_overlay/proc/update_overlay()
var/mx = max(lum_r, lum_g, lum_b)
@@ -50,14 +70,46 @@
#if LIGHTING_TRANSITIONS == 1
animate(src,
color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .),
LIGHTING_INTERVAL - 1
LIGHTING_TRANSITION_SPEED
)
#else
color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .)
#endif
var/turf/T = loc
if(istype(T)) //Incase we're not on a turf, pool ourselves, something happened.
if(color != "#000000")
T.luminosity = 1
else //No light, set the turf's luminosity to 0 to remove it from view()
#if LIGHTING_TRANSITIONS == 1
spawn(LIGHTING_TRANSITION_SPEED)
T.luminosity = 0
#else
T.luminosity = 0
#endif
else
warning("A lighting overlay realised it's loc was NOT a turf (actual loc: [loc], [loc.type]) in update_overlay() and got qdel'd!")
qdel(src)
/atom/movable/lighting_overlay/singularity_act()
return
/atom/movable/lighting_overlay/singularity_pull()
return
return
/atom/movable/lighting_overlay/Destroy()
lighting_update_overlays -= src
var/turf/T = loc
if(istype(T))
#if LIGHTING_RESOLUTION == 1
T.lighting_overlay = null
#else
T.lighting_overlays -= src
#endif
for(var/datum/light_source/D in T.affecting_lights) //Remove references to us on the light sources affecting us.
D.effect_r -= src
D.effect_g -= src
D.effect_b -= src
+4
View File
@@ -15,6 +15,7 @@
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(T)
O.icon_state = state
T.lighting_overlay = O
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
@@ -24,6 +25,7 @@
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
T.lighting_overlays += O
#endif
else
for(var/x = 1; x <= world.maxx; x++)
@@ -35,6 +37,7 @@
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(T)
O.icon_state = state
T.lighting_overlay = O
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
@@ -44,4 +47,5 @@
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
T.lighting_overlays += O
#endif
+37 -19
View File
@@ -1,29 +1,47 @@
/turf
var/list/affecting_lights
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/lighting_overlay
#else
var/list/lighting_overlays[0]
#endif
/turf/proc/reconsider_lights()
for(var/datum/light_source/L in affecting_lights)
L.force_update()
/turf/proc/lighting_clear_overlays()
for(var/atom/movable/lighting_overlay/L in src)
L.loc = null
#if LIGHTING_RESOLUTION == 1
if(lighting_overlay)
qdel(lighting_overlay)
#else
for(var/atom/movable/lighting_overlay/L in lighting_overlays)
qdel(L)
#endif
/turf/proc/lighting_build_overlays()
if(!locate(/atom/movable/lighting_overlay) in src)
var/state = "light[LIGHTING_RESOLUTION]"
var/area/A = loc
if(A.lighting_use_dynamic)
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(src)
O.icon_state = state
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
var/atom/movable/lighting_overlay/O = new(src)
O.pixel_x = i * (32 / LIGHTING_RESOLUTION)
O.pixel_y = j * (32 / LIGHTING_RESOLUTION)
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
#endif
#if LIGHTING_RESOLUTION == 1
if(lighting_overlay)
#else
if(lighting_overlays.len)
#endif
return
var/state = "light[LIGHTING_RESOLUTION]"
var/area/A = loc
if(A.lighting_use_dynamic)
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(src)
O.icon_state = state
lighting_overlay = O
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
var/atom/movable/lighting_overlay/O = new(src)
O.pixel_x = i * (32 / LIGHTING_RESOLUTION)
O.pixel_y = j * (32 / LIGHTING_RESOLUTION)
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
lighting_overlays += O
#endif
@@ -1151,6 +1151,8 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(85 to INFINITY)
damageoverlay.overlays += brutefireloss_overlays["6"]//image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay6")
//damageoverlay.overlays += I
see_invisible = SEE_INVISIBLE_LIVING
if( stat == DEAD )
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = 8
@@ -1186,6 +1188,8 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
see_in_dark = (G.darkness_view ? see_in_dark + G.darkness_view : species.darksight) // Otherwise we keep our darkness view with togglable nightvision.
if(G.vision_flags) // MESONS
sight |= G.vision_flags
if(!druggy)
see_invisible = SEE_INVISIBLE_MINIMUM
if(!G.see_darkness)
see_invisible = SEE_INVISIBLE_MINIMUM
/* HUD shit goes here, as long as it doesn't modify sight flags */
@@ -1204,6 +1208,8 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(istype(H))
if(H.vision_flags) // MESONS
sight |= H.vision_flags
if(!druggy)
see_invisible = SEE_INVISIBLE_MINIMUM
if(!H.see_darkness)
see_invisible = SEE_INVISIBLE_MINIMUM
/* HUD shit goes here, as long as it doesn't modify sight flags */
+1 -1
View File
@@ -217,7 +217,7 @@
return
/mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person
fire_stacks = Clamp(fire_stacks + add_fire_stacks, min = -20, max = 20)
fire_stacks = Clamp(fire_stacks + add_fire_stacks, -20, 20)
/mob/living/proc/handle_fire()
if(fire_stacks < 0)
+2 -1
View File
@@ -108,7 +108,8 @@
if(isnum(val))
desired_temp = Clamp(desired_temp+val, 0, 1000)
else if(val == "input")
desired_temp = Clamp(input("Please input the target temperature", name) as num, 0, 1000)
var/target = input("Please input the target temperature", name) as num
desired_temp = Clamp(target, 0, 1000)
else
return 0
. = 1