From 582f6e32edb7687774b2ae3102ff1df453c1404e Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Fri, 25 Aug 2023 10:33:42 -0500 Subject: [PATCH] Slideshow - Add support for maps as textures (#9150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Slideshow - Add support for maps as textures * Update script_mod.hpp * Update fnc_mapImage.sqf * cleanup * Update fnc_mapImage.sqf * Apply suggestions from code review Co-authored-by: jonpas * mapImage_init comments * Update fnc_mapImage.sqf * Apply suggestions from code review Co-authored-by: Jouni Järvinen * add support for mission config maps --------- Co-authored-by: jonpas Co-authored-by: Jouni Järvinen --- addons/slideshow/GUI.hpp | 35 ++++++++++ addons/slideshow/XEH_PREP.hpp | 3 +- addons/slideshow/config.cpp | 1 + addons/slideshow/functions/fnc_mapImage.sqf | 67 +++++++++++++++++++ .../slideshow/functions/fnc_mapImage_init.sqf | 67 +++++++++++++++++++ docs/wiki/framework/slideshow-framework.md | 62 +++++++++++++++++ 6 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 addons/slideshow/GUI.hpp create mode 100644 addons/slideshow/functions/fnc_mapImage.sqf create mode 100644 addons/slideshow/functions/fnc_mapImage_init.sqf diff --git a/addons/slideshow/GUI.hpp b/addons/slideshow/GUI.hpp new file mode 100644 index 0000000000..87b42aa570 --- /dev/null +++ b/addons/slideshow/GUI.hpp @@ -0,0 +1,35 @@ +class GVAR(mapDisplay) { + onLoad = QUOTE(call FUNC(mapImage_init)); + idd = -1; + class Controls {}; +}; + +class ctrlMap; +class GVAR(mapNormal): ctrlMap { + maxSatelliteAlpha = 0; + sizeExLabel = 0; + sizeExUnits = 0; + sizeExInfo = 0; + sizeExLevel = 0; + sizeEx = 0; + scaleMin = 0.005; + scaleMax = 10; + showCountourInterval = 0; + drawShaded = 0.15; + shadedSea = 0.15; + showMarkers = 0; +}; +class GVAR(mapTopo): GVAR(mapNormal) { + drawShaded = 0.35; + shadedSea = 0.35; + sizeExLevel = 0.02; + colorCountlines[] = {0.647059, 0.533333, 0.286275, 0.5}; + colorMainCountlines[] = {0.858824, 0, 0,0.5}; + ptsPerSquareObj = 2000; // don't show buildings +}; +class GVAR(mapSat): GVAR(mapNormal) { + // ref https://feedback.bistudio.com/T170918 - may have problems loading sat textures + maxSatelliteAlpha = 0.95; + colorForest[] = {0, 1, 0, 0}; + colorForestBorder[] = {0, 1, 0, 0}; +}; diff --git a/addons/slideshow/XEH_PREP.hpp b/addons/slideshow/XEH_PREP.hpp index ca31404b53..52c5cb4217 100644 --- a/addons/slideshow/XEH_PREP.hpp +++ b/addons/slideshow/XEH_PREP.hpp @@ -1,5 +1,6 @@ - PREP(addSlideActions); PREP(autoTransition); PREP(createSlideshow); +PREP(mapImage); +PREP(mapImage_init); PREP(moduleInit); diff --git a/addons/slideshow/config.cpp b/addons/slideshow/config.cpp index 93378a3e82..8b375b7f74 100644 --- a/addons/slideshow/config.cpp +++ b/addons/slideshow/config.cpp @@ -16,3 +16,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" +#include "GUI.hpp" diff --git a/addons/slideshow/functions/fnc_mapImage.sqf b/addons/slideshow/functions/fnc_mapImage.sqf new file mode 100644 index 0000000000..0d985d5e57 --- /dev/null +++ b/addons/slideshow/functions/fnc_mapImage.sqf @@ -0,0 +1,67 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Returns a procedural texture that will display a custom map. + * Needs to be run on all machines. + * + * Arguments: + * 0: Position (default: center of map) + * 1: Scale (1.0 fits entire map in x-dimension) (default: 1.25) + * 2: Markers (default: []) + * - 0: Position 2D/3D (default: [0, 0, 0]) + * - 1: Text (default: "") + * - 2: Marker Type or Icon Name (default: "mil_dot") + * - 3: Color (default: [1, 0, 0, 1]) + * 3: Map Type (0: Normal, 1: Topographic, 2: Satellite) or any custom class (even mission config) (default: 0) + * 4: Code to run on init (will be passed [_map, _display, _displayID]) (default: {}) + * 5: Resolution (default: 4096) + * + * Return Value: + * Procedural Texture + * + * Example: + * [] call ace_slideshow_fnc_mapImage + * [getPos player, 0.3, [], 1] call ace_slideshow_fnc_mapImage + * [[5000, 5000], 0.5, [[getpos player, "obj"]], 2, {}] call ace_slideshow_fnc_mapImage + * + * Public: Yes + */ + +params [ + ["_pos", [worldSize / 2, worldSize / 2], [[]]], + ["_scale", 1.25, [0]], + ["_markers", [], [[]]], + ["_mapType", 0, [0, ""]], // 2.14 may allow config type as well + ["_userCode", {}, [{}]], + ["_resolution", 4096, [0]] +]; +TRACE_6("",_pos,_scale,count _markers,_mapType,_userCode isEqualTo {},_resolution); + +_markers = _markers apply { // convert marker array to draw command + _x params [["_xPos", [0,0,0], [[]]], ["_xText", "", [""]], ["_xIcon", "mil_dot", [""]], ["_xColor", [1,0,0,1], [[]]]]; + private _size = 0; + private _config = configFile >> "CfgMarkers" >> _xIcon; + if (isClass _config) then { + _size = 0.5 * getNumber (_config >> "size"); + _xIcon = getText (_config >> "icon"); // don't swap order + } else { + if (_xIcon != "") then { _size = 16 }; // could be a file or a CfgVehicleIcons class + }; + [_xIcon, _xColor, _xPos, _size, _size, 0, _xText, 0, 0.08] +}; + +if (_mapType isEqualType 0) then { + _mapType = [QGVAR(mapNormal), QGVAR(mapTopo), QGVAR(mapSat)] select _mapType; +}; +if ((!isClass (configFile >> _mapType)) && {(!isClass (missionConfigFile >> _mapType))}) then { + ERROR_1("bad map type %1",_mapType); +}; + +// set data in hash +if (isNil QGVAR(mapData)) then { GVAR(mapData) = createHashMap; }; +private _displayID = format ["ace_s_%1", count GVAR(mapData)]; +TRACE_1("setting hash",_displayID); +GVAR(mapData) set [_displayID, [_pos, _scale, _markers, _mapType, _userCode]]; + +// return texture name +format ['#(rgb,%1,%1,1)ui("%2","%3")', _resolution, QGVAR(mapDisplay), _displayID] diff --git a/addons/slideshow/functions/fnc_mapImage_init.sqf b/addons/slideshow/functions/fnc_mapImage_init.sqf new file mode 100644 index 0000000000..1c84b98740 --- /dev/null +++ b/addons/slideshow/functions/fnc_mapImage_init.sqf @@ -0,0 +1,67 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Initializes the map texture display. + * + * Arguments: + * 0: Display (default: displayNull) + * 1: Disply ID (default: "") + * + * Return Value: + * None + * + * Example: + * [findDisplay "ace_s_0"] call ace_slideshow_fnc_mapImage_init + * + * Public: No + */ + +params [["_display", displayNull], ["_displayID", ""]]; // only one of these will be valid +// On primary call from the display's onload we will only have the actual display +if (_displayID == "") then { _displayID = displayUniqueName _display; }; +// On the delayed call (due to hash missing) we will only have the displayID +if (isNull _display) then { _display = findDisplay _displayID; }; +TRACE_2("mapImage_init",_display,_displayID); + +// seems like display can sometimes not exist even though it does +// it won't be updated correctly, seems to depend on resolution, seems to be fixed mostly by the 2nd update run +if (isNull findDisplay _displayID) then { WARNING_1("possible problem with texture %1",_displayID); }; + +// make sure data exists in hash, there can be a race if server broadcasts texture before client can finish init.sqf +if (isNil QGVAR(mapData) || {!(_displayID in GVAR(mapData))}) exitWith { + WARNING_1("texture %1 has no data in hash",_displayID); + if (!isNull (param [0, displayNull])) then { // not a retry, checking using value from _this + [FUNC(mapImage_init), [displayNull, _displayID], 5] call CBA_fnc_waitAndExecute; + }; +}; + +(GVAR(mapData) get _displayID) params ["_posCenter", "_scale", "_markers", "_mapType", "_userCode"]; +TRACE_4("data",_posCenter,_scale,count _markers,_mapType); + +private _map = _display ctrlCreate [_mapType, -1]; +_map ctrlSetPosition [0, 0, 1, 1]; +_map ctrlCommit 0; +_map ctrlMapSetPosition []; + +_map ctrlMapAnimAdd [0, _scale, _posCenter]; +ctrlMapAnimCommit _map; + +[_map, _display, _displayID] call _userCode; + +// add drawEH to draw markers next update (they will get drawn 3 times total) +_map setVariable ["markers", _markers]; +_map ctrlAddEventHandler ["draw", { + params ["_map"]; + private _markers = _map getVariable ["markers", []]; + TRACE_2("drawing markers",_map,count _markers); + { _map drawIcon _x } forEach _markers; +}]; + +private _update = { + private _display = findDisplay _this; + if (isNull _display) exitWith {}; + TRACE_2("updating",_display,displayUniqueName _display); + displayUpdate _display; +}; +[_update, _displayID] call CBA_fnc_execNextFrame; // update after a frame so the map anim has time to take effect +[_update, _displayID, 2] call CBA_fnc_waitAndExecute; // update a bit later so textures hopefully have time to load diff --git a/docs/wiki/framework/slideshow-framework.md b/docs/wiki/framework/slideshow-framework.md index 5d27cbc697..0697116039 100644 --- a/docs/wiki/framework/slideshow-framework.md +++ b/docs/wiki/framework/slideshow-framework.md @@ -58,3 +58,65 @@ _Note: Set Name argument added in 3.9.1._ 4 | `5` | 5s slide duration before change to next image 5 | `"My Slides"` | Main interaction point name, for easier distinguishing of multiple slideshow sets 6 | `1` | Uses texture selection 1 for objects with multiple options + +### 2.2 Create Map Images + +`ace_slideshow_fnc_mapImage` + +```sqf + * Returns a procedural texture that will display a custom map. + * Needs to be run on all machines. + * + * Arguments: + * 0: Position (default: center of map) + * 1: Scale (1.0 fits entire map in x-dimension) (default: 1.25) + * 2: Markers (default: []) + * - 0: Position 2D/3D (default: [0, 0, 0]) + * - 1: Text (default: "") + * - 2: Marker Type or Icon Name (default: "mil_dot") + * - 3: Color (default: [1, 0, 0, 1]) + * 3: Map Type (0: Normal, 1: Topographic, 2: Satelite) or any custom class (even mission config) (default: 0) + * 4: Code to run on init (will be passed [_map, _display, _displayID]) (default: {}) + * 5: Resolution (default: 4096) +``` + +### 2.2.1 Map Slideshow Example + +```sqf +tex1 = [] call ace_slideshow_fnc_mapImage; +tex2 = [(getPos aWhiteboard), 0.5, [[getpos aWhiteboard, "you", "mil_start"]], 0] call ace_slideshow_fnc_mapImage; +tex3 = [[4000, 4000], 0.5, [[[5000, 5000], "target", "mil_objective"]], 2] call ace_slideshow_fnc_mapImage; +[[aWhiteboard], [], [tex1, tex2, tex3], ["Full", "Sat Start", "Sat Objective"]] call ace_slideshow_fnc_createSlideshow; +``` + +### 2.2.2 Map Slideshow Advanced Example + +```sqf +private _initCode = { + params ["_map", "", "_displayID"]; + + // Add custom draw event handler (will only be called when display is actually updated) + _map ctrlAddEventHandler ["draw", { + params ["_map"]; + _map drawIcon ["\A3\Drones_F\Air_F_Gamma\UAV_02\Data\UI\Map_UAV_02_CA.paa", [0, 0, 1, 1], getPos theUAV, 24, 24, getDir theUAV]; + }]; + + // Live update the map + [{ + params ["_displayID","_idPFH"]; + private _display = findDisplay _displayID; + if (isNull _display) exitWith { + systemChat format ["%1 - removing pfeh", _this]; + [_idPFH] call CBA_fnc_removePerFrameHandler; + }; + displayUpdate _display; + + private _map = _display displayCtrl 1; + _map ctrlMapAnimAdd [0, 0.3, getpos theUAV]; + ctrlMapAnimCommit _map; + }, 0, _displayID ] call CBA_fnc_addPerFrameHandler; +}; + +tex4 = [nil, 0.3, [[getpos aComputer, "you", "mil_start"]], 2, _initCode] call ace_slideshow_fnc_mapImage; +[[aComputer, aComputer2], [], [tex4], ["Sat Follow UAV"]] call ace_slideshow_fnc_createSlideshow; +```