Slideshow - Add support for maps as textures (#9150)

* 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 <jonpas33@gmail.com>

* mapImage_init comments

* Update fnc_mapImage.sqf

* Apply suggestions from code review

Co-authored-by: Jouni Järvinen <rautamiekka@users.noreply.github.com>

* add support for mission config maps

---------

Co-authored-by: jonpas <jonpas33@gmail.com>
Co-authored-by: Jouni Järvinen <rautamiekka@users.noreply.github.com>
This commit is contained in:
PabstMirror 2023-08-25 10:33:42 -05:00 committed by GitHub
parent 65d5ccf600
commit 582f6e32ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 234 additions and 1 deletions

35
addons/slideshow/GUI.hpp Normal file
View File

@ -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};
};

View File

@ -1,5 +1,6 @@
PREP(addSlideActions);
PREP(autoTransition);
PREP(createSlideshow);
PREP(mapImage);
PREP(mapImage_init);
PREP(moduleInit);

View File

@ -16,3 +16,4 @@ class CfgPatches {
#include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp"
#include "GUI.hpp"

View File

@ -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 <ARRAY> (default: center of map)
* 1: Scale (1.0 fits entire map in x-dimension) <NUMBER> (default: 1.25)
* 2: Markers <ARRAY> (default: [])
* - 0: Position 2D/3D <ARRAY> (default: [0, 0, 0])
* - 1: Text <STRING> (default: "")
* - 2: Marker Type or Icon Name <STRING> (default: "mil_dot")
* - 3: Color <ARRAY> (default: [1, 0, 0, 1])
* 3: Map Type (0: Normal, 1: Topographic, 2: Satellite) or any custom class (even mission config) <NUMBER, STRING> (default: 0)
* 4: Code to run on init (will be passed [_map, _display, _displayID]) <CODE> (default: {})
* 5: Resolution <NUMBER> (default: 4096)
*
* Return Value:
* Procedural Texture <STRING>
*
* 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]

View File

@ -0,0 +1,67 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Initializes the map texture display.
*
* Arguments:
* 0: Display <DISPLAY> (default: displayNull)
* 1: Disply ID <STRING> (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

View File

@ -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 <ARRAY> (default: center of map)
* 1: Scale (1.0 fits entire map in x-dimension) <NUMBER> (default: 1.25)
* 2: Markers <ARRAY> (default: [])
* - 0: Position 2D/3D <ARRAY> (default: [0, 0, 0])
* - 1: Text <STRING> (default: "")
* - 2: Marker Type or Icon Name <STRING> (default: "mil_dot")
* - 3: Color <ARRAY> (default: [1, 0, 0, 1])
* 3: Map Type (0: Normal, 1: Topographic, 2: Satelite) or any custom class (even mission config) <NUMBER, STRING> (default: 0)
* 4: Code to run on init (will be passed [_map, _display, _displayID]) <CODE> (default: {})
* 5: Resolution <NUMBER> (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;
```