Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(a380x/avionics): First implementation of taxi cam #9716

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ size_mm=768,1024
pixel_size=768,1024
texture=$SCREEN_DU_NDL

htmlgauge00=WasmInstrument/WasmInstrument.html?wasm_module=terronnd.wasm&wasm_gauge=terronnd,0,0,768,1024,L
htmlgauge01=A380X/ND/nd.html?Index=1&duID=1, 0,0,768,1024
htmlgauge00=WasmInstrument/WasmInstrument.html?wasm_module=terronnd.wasm&wasm_gauge=MapView3D,0,0,768,1024,L
;htmlgauge01=A380X/ND/nd.html?Index=1&duID=1, 0,0,768,1024

[VCockpit08]
size_mm=768,1024
Expand Down
3 changes: 2 additions & 1 deletion fbw-common/src/wasm/terronnd/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ clang++ \
-I "${MSFS_SDK}/WASM/include" \
-I "${MSFS_SDK}/SimConnect SDK/include" \
-I "${DIR}/../cpp-msfs-framework/lib/" \
"${DIR}/src/main.cpp" \
"${DIR}/src/main_taxi_cam.cpp" \
"${DIR}/src/Shared.cpp" \
"${DIR}/src/nanovg/nanovg.cpp" \
"${DIR}/src/navigationdisplay/collection.cpp" \
"${DIR}/src/navigationdisplay/displaybase.cpp" \
Expand Down
111 changes: 111 additions & 0 deletions fbw-common/src/wasm/terronnd/src/Shared.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <MSFS/MSFS_MapView.h>
#include <MSFS\Legacy\gauges.h>
#include <MSFS\MSFS.h>
#include "MSFS\MSFS_Render.h"
#include "MSFS\Render\nanovg.h"

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <map>

float DegToRad(float deg) {
return (deg * 3.14159265359) / 180.f;
}

int isBlack(NVGcolor col) {
if (col.r == 0.0f && col.g == 0.0f && col.b == 0.0f && col.a == 0.0f) {
return 1;
}
return 0;
}

char* cpToUTF8(int cp, char* str) {
int n = 0;
if (cp < 0x80)
n = 1;
else if (cp < 0x800)
n = 2;
else if (cp < 0x10000)
n = 3;
else if (cp < 0x200000)
n = 4;
else if (cp < 0x4000000)
n = 5;
else if (cp <= 0x7fffffff)
n = 6;
str[n] = '\0';
switch (n) {
case 6:
str[5] = 0x80 | (cp & 0x3f);
cp = cp >> 6;
cp |= 0x4000000;
case 5:
str[4] = 0x80 | (cp & 0x3f);
cp = cp >> 6;
cp |= 0x200000;
case 4:
str[3] = 0x80 | (cp & 0x3f);
cp = cp >> 6;
cp |= 0x10000;
case 3:
str[2] = 0x80 | (cp & 0x3f);
cp = cp >> 6;
cp |= 0x800;
case 2:
str[1] = 0x80 | (cp & 0x3f);
cp = cp >> 6;
cp |= 0xc0;
case 1:
str[0] = cp;
}
return str;
}

void drawButton(NVGcontext* vg, int preicon, const char* text, float x, float y, float w, float h, NVGcolor col, float fontSize) {
NVGpaint bg;
char icon[8];
float cornerRadius = 4.0f;
float tw = 0, iw = 0;

bg = nvgLinearGradient(vg, x, y, x, y + h, nvgRGBA(255, 255, 255, isBlack(col) ? 16 : 32), nvgRGBA(0, 0, 0, isBlack(col) ? 16 : 32));
nvgBeginPath(vg);
nvgRoundedRect(vg, x + 1, y + 1, w - 2, h - 2, cornerRadius - 1);
if (!isBlack(col)) {
nvgFillColor(vg, col);
nvgFill(vg);
}
nvgFillPaint(vg, bg);
nvgFill(vg);

nvgBeginPath(vg);
nvgRoundedRect(vg, x + 0.5f, y + 0.5f, w - 1, h - 1, cornerRadius - 0.5f);
nvgStrokeColor(vg, nvgRGBA(0, 0, 0, 48));
nvgStroke(vg);

nvgFontSize(vg, fontSize);
nvgFontFace(vg, "sans-bold");
tw = nvgTextBounds(vg, 0, 0, text, NULL, NULL);
if (preicon != 0) {
nvgFontSize(vg, h * 1.3f);
nvgFontFace(vg, "icons");
iw = nvgTextBounds(vg, 0, 0, cpToUTF8(preicon, icon), NULL, NULL);
iw += h * 0.15f;
}

if (preicon != 0) {
nvgFontSize(vg, h * 1.3f);
nvgFontFace(vg, "icons");
nvgFillColor(vg, nvgRGBA(255, 255, 255, 96));
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
nvgText(vg, x + w * 0.5f - tw * 0.5f - iw * 0.75f, y + h * 0.5f, cpToUTF8(preicon, icon), NULL);
}

nvgFontSize(vg, fontSize);
nvgFontFace(vg, "sans-bold");
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
nvgFillColor(vg, nvgRGBA(0, 0, 0, 160));
nvgText(vg, x + w * 0.5f - tw * 0.5f + iw * 0.25f, y + h * 0.5f - 1, text, NULL);
nvgFillColor(vg, nvgRGBA(255, 255, 255, 160));
nvgText(vg, x + w * 0.5f - tw * 0.5f + iw * 0.25f, y + h * 0.5f, text, NULL);
}
17 changes: 17 additions & 0 deletions fbw-common/src/wasm/terronnd/src/Shared.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#define DEMO_BUTTON_PY 10.f
#define DEMO_BUTTON_1_PX 10.f
#define DEMO_BUTTON_2_PX 170.f
#define DEMO_BUTTON_3_PX 330.f
#define DEMO_BUTTON_4_PX 490.f
#define DEMO_BUTTON_5_PX 650.f
#define DEMO_BUTTON_6_PX 810.f
#define DEMO_BUTTON_SX 150.f
#define DEMO_BUTTON_SY 75.f

#define MAP_VIEW_RES_X 768
#define MAP_VIEW_RES_Y 500

void drawButton(struct NVGcontext* vg, int preicon, const char* text, float x, float y, float w, float h, NVGcolor col, float fontSize);
char* cpToUTF8(int cp, char* str);
Binary file not shown.
Binary file added fbw-common/src/wasm/terronnd/src/data/entypo.ttf
Binary file not shown.
210 changes: 210 additions & 0 deletions fbw-common/src/wasm/terronnd/src/main_taxi_cam.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
// Copyright (c) Asobo Studio, All rights reserved. www.asobostudio.com

#include <MSFS/MSFS_MapView.h>
#include <MSFS\Legacy\gauges.h>
#include <MSFS\MSFS.h>
#include <MSFS\MSFS_Render.h>
#include <MSFS\Render\nanovg.h>
#include "Shared.h"

#include <time.h>
#include <random>

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <map>

#ifdef _MSC_VER
#define snprintf _snprintf_s
#elif !defined(__MINGW32__)
#include <iconv.h>
#endif

std::map<FsContext, NVGcontext*> g_MapView3DNVGcontext;

static FsTextureId mapViewTextureId = -1;

static struct {
FsMapViewMode eViewMode = FS_MAP_VIEW_MODE_ALTITUDE;
FsMapViewAltitudeReference eAltRef = FS_MAP_VIEW_ALTITUDE_REFERENCE_GEOID;
FsMapView3DOrientation ePosition = FS_MAP_VIEW_3D_ORIENTATION_FRONTVIEW;

float fCustomPitch;
float fCustomBank;
float fCustomHead;

bool bEnable3D = true;

bool bNeedUpdate = false;

unsigned count = 0;
} mapView3DParam;

// ------------------------
// Callbacks
extern "C" {
MSFS_CALLBACK bool MapView3D_gauge_callback(FsContext ctx, int service_id, void* pData) {
switch (service_id) {
case PANEL_SERVICE_PRE_INSTALL:
return true;
break;
case PANEL_SERVICE_POST_INSTALL: {
srand(time(0));

NVGparams params;
params.userPtr = ctx;
params.edgeAntiAlias = true;
g_MapView3DNVGcontext[ctx] = nvgCreateInternal(&params);

nvgCreateFont(g_MapView3DNVGcontext[ctx], "icons", "./data/entypo.ttf");
nvgCreateFont(g_MapView3DNVGcontext[ctx], "sans-bold", "./data/Roboto-Bold.ttf");

mapViewTextureId = fsMapViewCreate(ctx, 768, 500, 0);
if (mapViewTextureId == -1) {
return false;
}

fsMapViewSetVisibility(ctx, mapViewTextureId, true);
fsMapViewSetViewMode(ctx, mapViewTextureId, FS_MAP_VIEW_MODE_AERIAL);
fsMapViewSet3D(ctx, mapViewTextureId, true);
fsMapViewSet2DViewFollowMode(ctx, mapViewTextureId, true);
fsMapViewSet2DViewRadiusInMeters(ctx, mapViewTextureId, 10000.f);
fsMapViewSetWeatherRadarVisibility(ctx, mapViewTextureId, false);
fsMapViewSetAltitudeRangeInFeet(ctx, mapViewTextureId, -100, 15000);

mapView3DParam.bNeedUpdate = true;

const int size = 8;
FsColor colors[size] = {
{0.f, 0.f, 0.f, 1.f},
{0.f, 0.f, 1.f, 1.f},
{0.f, 1.f, 0.f, 1.f},
{0.f, 1.f, 1.f, 1.f},
{1.f, 0.f, 0.f, 1.f},
{1.f, 0.f, 1.f, 1.f},
{1.f, 1.f, 0.f, 1.f},
{1.f, 1.f, 1.f, 1.f},
};
fsMapViewSetAltitudeColorList(ctx, mapViewTextureId, colors, size);
return true;
} break;

case PANEL_SERVICE_PRE_UPDATE: {
// we might not nned custom orientation
/* if (mapView3DParam.bEnable3D && mapView3DParam.ePosition == FS_MAP_VIEW_3D_ORIENTATION_CUSTOM) {
if (++mapView3DParam.count > 200) {
mapView3DParam.fCustomPitch = nvgDegToRad(rand() % 360 - 180);
mapView3DParam.fCustomBank = nvgDegToRad(rand() % 360 - 180);
mapView3DParam.fCustomHead = nvgDegToRad(rand() % 360 - 180);
mapView3DParam.count = 0;

fsMapViewSet3DCustomViewOrientationInRadians(ctx, mapViewTextureId, mapView3DParam.fCustomPitch, mapView3DParam.fCustomBank,
mapView3DParam.fCustomHead);
}
} */

if (mapView3DParam.bNeedUpdate) {
fsMapViewSetViewMode(ctx, mapViewTextureId, mapView3DParam.eViewMode);
fsMapViewSetAltitudeReference(ctx, mapViewTextureId, mapView3DParam.eAltRef);
fsMapViewSet3DViewOrientation(ctx, mapViewTextureId, mapView3DParam.ePosition);
fsMapViewSet3D(ctx, mapViewTextureId, mapView3DParam.bEnable3D);

mapView3DParam.bNeedUpdate = false;
}
return true;
} break;

case PANEL_SERVICE_PRE_DRAW: {
NVGcontext* vg = g_MapView3DNVGcontext[ctx];
sGaugeDrawData* p_draw_data = (sGaugeDrawData*)pData;

float pxRatio = (float)p_draw_data->fbWidth / (float)p_draw_data->winWidth;
nvgBeginFrame(vg, p_draw_data->winWidth, p_draw_data->winHeight, pxRatio);
nvgResetTransform(vg);

// NetBingView
if (mapViewTextureId >= 0) {
NVGpaint netBingViewPaint = nvgImagePattern(vg, 0, 0, MAP_VIEW_RES_X, MAP_VIEW_RES_Y, 0.0f, mapViewTextureId, 1.f);
nvgBeginPath(vg);
nvgRect(vg, 0, 0, MAP_VIEW_RES_X, MAP_VIEW_RES_Y);
nvgFillPaint(vg, netBingViewPaint);
nvgFill(vg);
}

const char* text;
text = mapView3DParam.eViewMode == FS_MAP_VIEW_MODE_AERIAL ? "AERIAL" : "ALTITUDE";
drawButton(vg, 0, text, DEMO_BUTTON_1_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f);

text = mapView3DParam.eAltRef == FS_MAP_VIEW_ALTITUDE_REFERENCE_GEOID ? "GEOID" : "PLANE";
drawButton(vg, 0, text, DEMO_BUTTON_2_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f);

text = mapView3DParam.bEnable3D ? "3D" : "2D";
drawButton(vg, 0, text, DEMO_BUTTON_3_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f);

drawButton(vg, 0, "3D FRONT VIEW", DEMO_BUTTON_4_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f);
drawButton(vg, 0, "3D TOP VIEW", DEMO_BUTTON_5_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f);
drawButton(vg, 0, "3D CUSTOM", DEMO_BUTTON_6_PX, DEMO_BUTTON_PY, DEMO_BUTTON_SX, DEMO_BUTTON_SY, nvgRGBA(50, 50, 50, 255), 25.f);

nvgEndFrame(vg);

return true;
} break;
case PANEL_SERVICE_PRE_KILL: {
NVGcontext* vg = g_MapView3DNVGcontext[ctx];

fsMapViewDelete(ctx, mapViewTextureId);
mapViewTextureId = -1;
nvgDeleteInternal(vg);
g_MapView3DNVGcontext.erase(ctx);
return true;
} break;
}
return false;
}

MSFS_CALLBACK void MapView3D_mouse_callback(float fX, float fY, int iFlags) {
switch (iFlags) {
// Mouse click event
case MOUSE_LEFTSINGLE:

// Switch to the next demo
if (fX >= DEMO_BUTTON_1_PX && fX < DEMO_BUTTON_1_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY &&
fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) {
if (mapView3DParam.eViewMode == FS_MAP_VIEW_MODE_AERIAL)
mapView3DParam.eViewMode = FS_MAP_VIEW_MODE_ALTITUDE;
else
mapView3DParam.eViewMode = FS_MAP_VIEW_MODE_AERIAL;

mapView3DParam.bNeedUpdate = true;
} else if (fX >= DEMO_BUTTON_2_PX && fX < DEMO_BUTTON_2_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY &&
fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) {
if (mapView3DParam.eAltRef == FS_MAP_VIEW_ALTITUDE_REFERENCE_GEOID)
mapView3DParam.eAltRef = FS_MAP_VIEW_ALTITUDE_REFERENCE_PLANE;
else
mapView3DParam.eAltRef = FS_MAP_VIEW_ALTITUDE_REFERENCE_GEOID;

mapView3DParam.bNeedUpdate = true;
} else if (fX >= DEMO_BUTTON_3_PX && fX < DEMO_BUTTON_3_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY &&
fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) {
mapView3DParam.bEnable3D = !mapView3DParam.bEnable3D;
mapView3DParam.bNeedUpdate = true;
} else if (fX >= DEMO_BUTTON_4_PX && fX < DEMO_BUTTON_4_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY &&
fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) {
mapView3DParam.ePosition = FS_MAP_VIEW_3D_ORIENTATION_FRONTVIEW;
mapView3DParam.bNeedUpdate = true;
} else if (fX >= DEMO_BUTTON_5_PX && fX < DEMO_BUTTON_5_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY &&
fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) {
mapView3DParam.ePosition = FS_MAP_VIEW_3D_ORIENTATION_TOPVIEW;
mapView3DParam.bNeedUpdate = true;
} else if (fX >= DEMO_BUTTON_6_PX && fX < DEMO_BUTTON_6_PX + DEMO_BUTTON_SX && fY >= DEMO_BUTTON_PY &&
fY < DEMO_BUTTON_PY + DEMO_BUTTON_SY) {
mapView3DParam.ePosition = FS_MAP_VIEW_3D_ORIENTATION_CUSTOM;
mapView3DParam.bNeedUpdate = true;
}
break;
default:
break;
}
}
}
Loading