diff --git a/code/__DEFINES/__game.dm b/code/__DEFINES/__game.dm index 87c5e2255b52..aff21f41cf32 100644 --- a/code/__DEFINES/__game.dm +++ b/code/__DEFINES/__game.dm @@ -549,3 +549,13 @@ #define PERF_TOGGLE_SHUTTLES (1<<3) /// Disables loading Techwebs and additional Z-Levels #define PERF_TOGGLE_TECHWEBS (1<<4) + +#define PIXEL_SCALING_AUTO 0 +#define PIXEL_SCALING_1X 1 +#define PIXEL_SCALING_1_2X 1.5 +#define PIXEL_SCALING_2X 2 +#define PIXEL_SCALING_3X 3 + +#define SCALING_METHOD_NORMAL "normal" +#define SCALING_METHOD_DISTORT "distort" +#define SCALING_METHOD_BLUR "blur" diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 47aa0e732c76..8d0ce9128244 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -109,6 +109,8 @@ // Subsystems shutdown in the reverse of the order they initialize in // The numbers just define the ordering, they are meaningless otherwise. +#define SS_INIT_TICKER_SPAWN 999 +#define SS_INIT_TITLE 990 #define SS_INIT_PROFILER 86 #define SS_INIT_INPUT 85 #define SS_INIT_TOPIC 83 diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index fb9d6bfb4faf..33cad9400d6c 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -722,7 +722,7 @@ #define FIRE_MULTIPLIER_EXTREME 2 #define FIRE_MULTIPLIER_DEADLY 3 -#define TRAPPER_VIEWRANGE 13 +#define TRAPPER_VIEWRANGE 6 #define SECRETE_RESIN_INTERRUPT -1 #define SECRETE_RESIN_FAIL 0 diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm index 85e102a3c1ac..87fd5f900a5c 100644 --- a/code/__HELPERS/sanitize_values.dm +++ b/code/__HELPERS/sanitize_values.dm @@ -6,6 +6,13 @@ return number return default +/proc/sanitize_float(number, min=0, max=1, accuracy=1, default=0) + if(isnum(number)) + number = round(number, accuracy) + if(min <= number && number <= max) + return number + return default + /proc/sanitize_text(text, default="") if(istext(text)) return text diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 72e298d32729..de54b282e520 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -327,7 +327,7 @@ /client/proc/change_view(new_size, atom/source) if(SEND_SIGNAL(mob, COMSIG_MOB_CHANGE_VIEW, new_size) & COMPONENT_OVERRIDE_VIEW) return TRUE - view = mob.check_view_change(new_size, source) + view = new_size apply_clickcatcher() mob.reload_fullscreens() @@ -382,17 +382,12 @@ /proc/getviewsize(view) - var/viewX - var/viewY if(isnum(view)) - var/totalviewrange = 1 + 2 * view - viewX = totalviewrange - viewY = totalviewrange + var/totalviewrange = (view < 0 ? -1 : 1) + 2 * view + return list(totalviewrange, totalviewrange) else var/list/viewrangelist = splittext(view,"x") - viewX = text2num(viewrangelist[1]) - viewY = text2num(viewrangelist[2]) - return list(viewX, viewY) + return list(text2num(viewrangelist[1]), text2num(viewrangelist[2])) #if DEBUG_CLICK_RATE diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index e2572e5e2d61..a4c1aa662138 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -439,7 +439,7 @@ The default value assumes youtube-dl is in your system PATH /datum/config_entry/string/default_view - config_entry_value = "15x15" + config_entry_value = "19x15" /datum/config_entry/string/default_view_square config_entry_value = "15x15" diff --git a/code/datums/emergency_calls/contractor.dm b/code/datums/emergency_calls/contractor.dm index 05d6ab7b4671..584d39d6d8ba 100644 --- a/code/datums/emergency_calls/contractor.dm +++ b/code/datums/emergency_calls/contractor.dm @@ -117,7 +117,7 @@ var/mob/living/carbon/human/H = new(spawn_loc) H.key = M.key if(H.client) - H.client.change_view(GLOB.world_view_size) + H.client.view_size.reset_to_default() if(!leader && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(H.client, JOB_SQUAD_LEADER, time_required_for_job)) //First one spawned is always the leader. leader = H diff --git a/code/datums/emergency_calls/pmc.dm b/code/datums/emergency_calls/pmc.dm index 2f43e94828d6..ae64ece45007 100644 --- a/code/datums/emergency_calls/pmc.dm +++ b/code/datums/emergency_calls/pmc.dm @@ -120,7 +120,7 @@ var/mob/living/carbon/human/H = new(spawn_loc) H.key = M.key if(H.client) - H.client.change_view(GLOB.world_view_size) + H.client.view_size.reset_to_default() if(!leader && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(H.client, JOB_SQUAD_LEADER, time_required_for_job)) //First one spawned is always the leader. leader = H diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 945f4d0a5351..36b9026543d5 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -68,7 +68,7 @@ SSround_recording.recorder.update_key(new_character) if(new_character.client) new_character.client.init_verbs() - new_character.client.change_view(GLOB.world_view_size) //reset view range to default. + new_character.client.view_size.reset_to_default() //reset view range to default. new_character.client.pixel_x = 0 new_character.client.pixel_y = 0 if(usr && usr.open_uis) diff --git a/code/datums/view.dm b/code/datums/view.dm new file mode 100644 index 000000000000..c25ba62722d2 --- /dev/null +++ b/code/datums/view.dm @@ -0,0 +1,150 @@ +//This is intended to be a full wrapper. DO NOT directly modify its values +///Container for client viewsize +/datum/view_data + ///width ratio of the owneing clients view + var/width = 0 + ///height ratio of the owneing clients view + var/height = 0 + ///Default view size, formatted as a string + var/default = "" + + ///Bool that determines whether we want it to ignore any other changes after we applied some changes + var/suppress_changes = FALSE + ///the owner of this view data + var/client/chief = null + +/datum/view_data/New(client/owner, view_string) + default = view_string + chief = owner + apply() + +///sets the default view size froma string +/datum/view_data/proc/set_default(string) + default = string + apply() + +///Updates formatting while considering zoom +/datum/view_data/proc/safe_apply_formatting() + if(is_zooming()) + assert_format() + return + update_pixel_format() + +///Resets the format type +/datum/view_data/proc/assert_format() + winset(chief, "mapwindow.map", "zoom=0") + +///applies the current clients preferred pixel size setting +/datum/view_data/proc/update_pixel_format() + winset(chief, "mapwindow.map", "zoom=[chief.prefs.pixel_size]") + +///applies the preferred clients scaling method +/datum/view_data/proc/update_zoom_mode() + winset(chief, "mapwindow.map", "zoom-mode=[chief.prefs.scaling_method]") + +///Returns a boolean if the client has any form of zoom +/datum/view_data/proc/is_zooming() + return (width || height) + +///Resets the zoom to the default string +/datum/view_data/proc/reset_to_default() + width = 0 + height = 0 + apply() + +///adds the number inputted to the zoom and applies it +/datum/view_data/proc/add(num_to_add) + width += num_to_add + height += num_to_add + apply() + +///adds the size, which can also be a string, to the default and applies it +/datum/view_data/proc/add_size(toAdd) + var/list/new_size = getviewsize(toAdd) + width += new_size[1] + height += new_size[2] + apply() + +///sets the size, which can also be a string and applies it +/datum/view_data/proc/set_view_radius_to(toAdd) + var/list/new_size = getviewsize(toAdd) //Backward compatability to account + width = new_size[1] //for a change in how sizes get calculated. we used to include world.view in + height = new_size[2] //this, but it was jank, so I had to move it + apply() + +///sets width and height as numbers +/datum/view_data/proc/set_width_and_height(new_width, new_height) + width = new_width + height = new_height + apply() + +///sets the width of the view +/datum/view_data/proc/set_width(new_width) + width = new_width + apply() + +///sets the height of the view +/datum/view_data/proc/set_height(new_height) + height = new_height + apply() + +///adds the inputted width to the view +/datum/view_data/proc/add_to_width(width_to_add) + width += width_to_add + apply() + +///adds the inputted height to the view +/datum/view_data/proc/add_to_height(height_to_add) + height += height_to_add + apply() + +///applies all current outstanding changes to the client +/datum/view_data/proc/apply() + chief.change_view(get_client_view_size()) + safe_apply_formatting() + +///supresses any further view changes until it is unsupressed +/datum/view_data/proc/suppress() + suppress_changes = TRUE + apply() + +///unsupresses to allow further view changes +/datum/view_data/proc/unsuppress() + suppress_changes = FALSE + apply() + +///returns the client view size in string format +/datum/view_data/proc/get_client_view_size() + var/list/temp = getviewsize(default) + if(suppress_changes) + return "[temp[1]]x[temp[2]]" + return "[width + temp[1]]x[height + temp[2]]" + +///Zooms the client back in with an animate pretty simple +/datum/view_data/proc/zoom_in() + reset_to_default() + animate(chief, pixel_x = 0, pixel_y = 0, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW) + +///zooms out the client with a given radius and offset as well as a direction +/datum/view_data/proc/zoom_out(radius = 0, offset = 0, direction = NONE) + if(direction) + var/_x = 0 + var/_y = 0 + switch(direction) + if(NORTH) + _y = offset + if(EAST) + _x = offset + if(SOUTH) + _y = -offset + if(WEST) + _x = -offset + animate(chief, pixel_x = world.icon_size*_x, pixel_y = world.icon_size*_y, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW) + + set_view_radius_to(radius) + +///gets the current screen size as defined in config +/proc/get_screen_size(widescreen) + if(widescreen) + return CONFIG_GET(string/default_view) + return CONFIG_GET(string/default_view_square) diff --git a/code/game/cas_manager/datums/cas_fire_envelope.dm b/code/game/cas_manager/datums/cas_fire_envelope.dm index cc38b034c764..d2a64a97cbea 100644 --- a/code/game/cas_manager/datums/cas_fire_envelope.dm +++ b/code/game/cas_manager/datums/cas_fire_envelope.dm @@ -216,7 +216,7 @@ M.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE M.sync_lighting_plane_alpha() if(linked_console.upgraded == MATRIX_WIDE) - M.client?.change_view(7, M) + M.client?.view_size.reset_to_default() else return @@ -324,7 +324,7 @@ /datum/cas_fire_envelope/uscm_dropship fire_length = 12 - grace_period = 5 SECONDS + grace_period = 5 SECONDS flyto_period = 4 SECONDS //sleep in the FM itself has been increased by one more second flyoff_period = 5 SECONDS cooldown_period = 10 SECONDS diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm index 30e179949be5..816c05f0e09b 100644 --- a/code/game/gamemodes/cm_initialize.dm +++ b/code/game/gamemodes/cm_initialize.dm @@ -661,7 +661,7 @@ Additional game mode variables. // Let the round recorder know that the key has changed SSround_recording.recorder.update_key(new_xeno) if(new_xeno.client) - new_xeno.client.change_view(GLOB.world_view_size) + new_xeno.client.view_size.reset_to_default() msg_admin_niche("[new_xeno.key] has joined as [new_xeno].") if(isxeno(new_xeno)) //Dear lord diff --git a/code/game/gamemodes/colonialmarines/huntergames.dm b/code/game/gamemodes/colonialmarines/huntergames.dm index 310785070458..2648179fbe89 100644 --- a/code/game/gamemodes/colonialmarines/huntergames.dm +++ b/code/game/gamemodes/colonialmarines/huntergames.dm @@ -234,7 +234,8 @@ H = new(picked) H.key = M.key - if(H.client) H.client.change_view(GLOB.world_view_size) + if(H.client) + H.client.view_size.reset_to_default() if(!H.mind) H.mind = new(H.key) diff --git a/code/game/machinery/computer/groundside_operations.dm b/code/game/machinery/computer/groundside_operations.dm index 52ff558cde89..1f58c300c0ad 100644 --- a/code/game/machinery/computer/groundside_operations.dm +++ b/code/game/machinery/computer/groundside_operations.dm @@ -308,7 +308,7 @@ usr.UnregisterSignal(cam, COMSIG_PARENT_QDELETING) cam = null usr.reset_view(null) - else if(usr.client.view != GLOB.world_view_size) + else if(usr.client.view_size.get_client_view_size() != usr.client.view_size.default) to_chat(usr, SPAN_WARNING("You're too busy peering through binoculars.")) else if(cam) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index fcd431c33d26..cbe8b56e4824 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -831,9 +831,9 @@ cases. Override_icon_state should be a list.*/ else if(!zoom) do_zoom(user, tileoffset, viewsize, keep_zoom) return - unzoom(user) + unzoom(user, tileoffset) -/obj/item/proc/unzoom(mob/living/user) +/obj/item/proc/unzoom(mob/living/user, tileoffset) if(user.interactee == src) user.unset_interaction() var/zoom_device = zoomdevicename ? "\improper [zoomdevicename] of [src]" : "\improper [src]" @@ -851,7 +851,8 @@ cases. Override_icon_state should be a list.*/ UnregisterSignal(user, COMSIG_MOB_MOVE_OR_LOOK) //General reset in case anything goes wrong, the view will always reset to default unless zooming in. if(user.client) - user.client.change_view(GLOB.world_view_size, src) + user.client.view_size.reset_to_default() + animate(user.client, 3*(tileoffset/7), pixel_x = 0, pixel_y = 0) user.client.pixel_x = 0 user.client.pixel_y = 0 @@ -874,8 +875,6 @@ cases. Override_icon_state should be a list.*/ else user.set_interaction(src) if(user.client) - user.client.change_view(viewsize, src) - RegisterSignal(src, list( COMSIG_ITEM_DROPPED, COMSIG_ITEM_UNWIELD, @@ -885,22 +884,8 @@ cases. Override_icon_state should be a list.*/ zoom_initial_mob_dir = user.dir - var/tilesize = 32 - var/viewoffset = tilesize * tileoffset - - switch(user.dir) - if(NORTH) - user.client.pixel_x = 0 - user.client.pixel_y = viewoffset - if(SOUTH) - user.client.pixel_x = 0 - user.client.pixel_y = -viewoffset - if(EAST) - user.client.pixel_x = viewoffset - user.client.pixel_y = 0 - if(WEST) - user.client.pixel_x = -viewoffset - user.client.pixel_y = 0 + user.client.view_size.add(viewsize) + change_zoom_offset(user, zoom_offset = tileoffset) SEND_SIGNAL(src, COMSIG_ITEM_ZOOM, user) var/zoom_device = zoomdevicename ? "\improper [zoomdevicename] of [src]" : "\improper [src]" @@ -908,6 +893,29 @@ cases. Override_icon_state should be a list.*/ SPAN_NOTICE("You peer through \the [zoom_device].")) zoom = !zoom +///applies the offset of the zooming, using animate for smoothing. +/obj/item/proc/change_zoom_offset(mob/user, newdir, zoom_offset) + SIGNAL_HANDLER + if(!istype(user)) + return + + var/viewoffset + if(zoom_offset) + viewoffset = zoom_offset * 32 + + var/zoom_offset_time = 3*((viewoffset/32)/7) + var/dirtooffset = newdir ? newdir : user.dir + + switch(dirtooffset) + if(NORTH) + animate(user.client, pixel_x = 0, pixel_y = viewoffset, time = zoom_offset_time) + if(SOUTH) + animate(user.client, pixel_x = 0, pixel_y = -viewoffset, time = zoom_offset_time) + if(EAST) + animate(user.client, pixel_x = viewoffset, pixel_y = 0, time = zoom_offset_time) + if(WEST) + animate(user.client, pixel_x = -viewoffset, pixel_y = 0, time = zoom_offset_time) + /obj/item/proc/get_icon_state(mob/user_mob, slot) var/mob_state var/item_state_slot_state = LAZYACCESS(item_state_slots, slot) diff --git a/code/modules/admin/tabs/admin_tab.dm b/code/modules/admin/tabs/admin_tab.dm index 356762b5edd7..c598bf75bc96 100644 --- a/code/modules/admin/tabs/admin_tab.dm +++ b/code/modules/admin/tabs/admin_tab.dm @@ -103,7 +103,7 @@ if(body && !body.key) body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus if(body.client) - body.client.change_view(GLOB.world_view_size) //reset view range to default. + body.client.view_size.reset_to_default() //reset view range to default. //re-open STUI if(new_STUI) diff --git a/code/modules/admin/topic/topic.dm b/code/modules/admin/topic/topic.dm index ecef2627ed3c..05ba49cf0fd4 100644 --- a/code/modules/admin/topic/topic.dm +++ b/code/modules/admin/topic/topic.dm @@ -1082,7 +1082,8 @@ H.mind.transfer_to(M) else M.key = H.key - if(M.client) M.client.change_view(GLOB.world_view_size) + if(M.client) + M.client.view_size.reset_to_default() if(M.skills) qdel(M.skills) diff --git a/code/modules/admin/verbs/mob_verbs.dm b/code/modules/admin/verbs/mob_verbs.dm index abb43461c2fe..ad6f8186b70b 100644 --- a/code/modules/admin/verbs/mob_verbs.dm +++ b/code/modules/admin/verbs/mob_verbs.dm @@ -24,7 +24,7 @@ message_admins("[key_name_admin(usr)] modified [key_name(M)]'s ckey to [new_ckey]", 1) M.ckey = new_ckey - M.client?.change_view(GLOB.world_view_size) + M.client?.view_size.reset_to_default() /client/proc/cmd_admin_changekey(mob/O in GLOB.mob_list) set name = "Change CKey" diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 2facce7c3a59..4ae3414f8a42 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -131,3 +131,5 @@ ///datum that controls the displaying and hiding of tooltips var/datum/tooltip/tooltips + + var/datum/view_data/view_size diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 5796d5ff505e..4eafb529afae 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -420,11 +420,17 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list( if(prefs.lastchangelog != GLOB.changelog_hash) //bolds the changelog button on the interface so we know there are updates. winset(src, "infowindow.changelog", "background-color=#ED9F9B;font-style=bold") + view_size = new(src, get_screen_size(prefs.widescreenpref)) + view_size.update_pixel_format() + view_size.update_zoom_mode() + fit_viewport() + + /* if(prefs.toggle_prefs & TOGGLE_FULLSCREEN) toggle_fullscreen(TRUE) else toggle_fullscreen(FALSE) - + */ var/file = file2text("config/donators.txt") var/lines = splittext(file, "\n") @@ -442,8 +448,6 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list( load_player_data() - view = GLOB.world_view_size - SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CLIENT_LOGGED_IN, src) ////////////// diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 113d585e44ef..4b351a569032 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -236,6 +236,11 @@ GLOBAL_LIST_INIT(bgstate_options, list( /// if this client has custom cursors enabled var/custom_cursors = TRUE + var/widescreenpref = TRUE + + var/pixel_size = 0 + + var/scaling_method = SCALING_METHOD_NORMAL /// if this client has tooltips enabled var/tooltips = TRUE @@ -583,6 +588,7 @@ GLOBAL_LIST_INIT(bgstate_options, list( dat += "