Well the whole VC I have working on the Endurance. I can post that code later. But I am using the same for this vessel. I need to remove code til I figure out what is wrong. It loads the vc mesh ok. It is when I press f1 I get a ctd.
Well the whole VC I have working on the Endurance. I can post that code later. But I am using the same for this vessel. I need to remove code til I figure out what is wrong. It loads the vc mesh ok. It is when I press f1 I get a ctd.
#include "ClassicMfdTalon.h"
#include "TALONVCMESH.h"
ClassicMfd::ClassicMfd(int const mfdQtd,
HFONT const labelFont, DWORD const labelColor, HBRUSH const buttonBrush, HBRUSH const buttonLabelBrush,
DIMENSION const * const buttonFnDim, RECT const buttonFnRect[],
DIMENSION const * const buttonSysDim, RECT const buttonSysRect[])
: mfdQtd(mfdQtd),
labelFont(labelFont), buttonBrush(buttonBrush), buttonLabelBrush(buttonLabelBrush), labelColor(labelColor),
buttonFnDim(buttonFnDim), buttonFnRect(buttonFnRect), buttonSysDim(buttonSysDim), buttonSysRect(buttonSysRect)
{
}
ClassicMfd::~ClassicMfd() {}
void ClassicMfd::HandleLoadMesh(UINT const meshi, MESHHANDLE const meshhg)
{
meshi_VC = meshi;
meshhg_VC = meshhg;
}
bool ClassicMfd::HandleLoadVC(UINT const vcId)
{
this->vcId = vcId;
DefineMfds();
DefineMfdsButtons();
return true;
}
bool ClassicMfd::HandleRedrawEvent(int const aid, int const event, SURFHANDLE const surf)
{
switch (aid) {
case AID_PILOT_MFD_LEFT_BTNS_FN:
RedrawMFDButtons(surf, PILOT_MFD_LEFT);
return true;
case AID_PILOT_MFD_RIGHT_BTNS_FN:
RedrawMFDButtons(surf, PILOT_MFD_RIGHT);
return true;
case AID_PILOT_MFD_CENTER_BTNS_FN:
RedrawMFDButtons(surf, PILOT_MFD_CENTER);
return true;
}
return false;
}
bool ClassicMfd::HandleMouseEvent(int const aid, int const event, VECTOR3 const &p)
{
switch (aid) {
case AID_PILOT_MFD_LEFT_BTNS_FN:
return ProcessMfdFnButton(PILOT_MFD_LEFT, event, p);
case AID_PILOT_MFD_LEFT_BTNS_SYS:
return ProcessMfdSysButton(PILOT_MFD_LEFT, event, p);
case AID_PILOT_MFD_RIGHT_BTNS_FN:
return ProcessMfdFnButton(PILOT_MFD_RIGHT, event, p);
case AID_PILOT_MFD_RIGHT_BTNS_SYS:
return ProcessMfdSysButton(PILOT_MFD_RIGHT, event, p);
case AID_PILOT_MFD_CENTER_BTNS_FN:
return ProcessMfdFnButton(PILOT_MFD_CENTER, event, p);
case AID_PILOT_MFD_CENTER_BTNS_SYS:
return ProcessMfdSysButton(PILOT_MFD_CENTER, event, p);
}
return false;
}
bool ClassicMfd::ProcessMfdFnButton(int const mfd, int const event, VECTOR3 const &p)
{
if (p.x > 0.07 && p.x < 0.93) return false;
int index = (int)(p.y * 11);
if (index == 0 || index / 2 != (index - 1) / 2) {
index /= 2;
if (p.x > 0.5) index += 6;
oapiProcessMFDButton(mfd, index, event);
return true;
}
return false;
}
bool ClassicMfd::ProcessMfdSysButton(int const mfd, int const event, VECTOR3 const &p)
{
if (event & PANEL_MOUSE_LBDOWN) {
if (p.x < 0.1) {
oapiToggleMFD_on(mfd);
return true;
}
else if (p.x > 0.9) {
oapiSendMFDKey(mfd, OAPI_KEY_GRAVE);
return true;
}
else if (p.x > 0.8) {
oapiSendMFDKey(mfd, OAPI_KEY_F1);
return true;
}
}
return false;
}
void ClassicMfd::HandleMFDMode(int const mfd, int const mode)
{
switch (mfd) {
case PILOT_MFD_LEFT:
oapiVCTriggerRedrawArea(-1, AID_PILOT_MFD_LEFT_BTNS_FN);
break;
case PILOT_MFD_RIGHT:
oapiVCTriggerRedrawArea(-1, AID_PILOT_MFD_RIGHT_BTNS_FN);
break;
case PILOT_MFD_CENTER:
oapiVCTriggerRedrawArea(-1, AID_PILOT_MFD_CENTER_BTNS_FN);
break;
}
}
void ClassicMfd::DefineMfds()
{
DefineMfd(PILOT_MFD_LEFT, GRP_TALON_VCNEW_PILOT_MFD_LEFT_SCREEN);
DefineMfd(PILOT_MFD_RIGHT, GRP_TALON_VCNEW_PILOT_MFD_RIGHT_SCREEN);
DefineMfd(PILOT_MFD_CENTER, GRP_TALON_VCNEW_PILOT_MFD_CENTER_SCREEN);
}
void ClassicMfd::DefineMfd(UINT const mfdId, UINT const screenGroupId)
{
VCMFDSPEC mfds;
mfds.nmesh = meshi_VC;
mfds.ngroup = screenGroupId;
oapiVCRegisterMFD(mfdId, &mfds);
}
void ClassicMfd::DefineMfdsButtons()
{
// Pilot Left
DefineMfdButtons(
TEX_TALON_VCNEW_MFD_DYNAMIC_05,
AID_PILOT_MFD_LEFT_BTNS_FN, GRP_TALON_VCNEW_PILOT_MFD_LEFT_BTNS_FN, buttonFnRect[PILOT_MFD_LEFT],
AID_PILOT_MFD_LEFT_BTNS_SYS, GRP_TALON_VCNEW_PILOT_MFD_LEFT_BTNS_SYS
);
// Pilot Right
DefineMfdButtons(
TEX_TALON_VCNEW_MFD_DYNAMIC_05,
AID_PILOT_MFD_RIGHT_BTNS_FN, GRP_TALON_VCNEW_PILOT_MFD_RIGHT_BTNS_FN, buttonFnRect[PILOT_MFD_RIGHT],
AID_PILOT_MFD_RIGHT_BTNS_SYS, GRP_TALON_VCNEW_PILOT_MFD_RIGHT_BTNS_SYS
);
DefineMfdButtons(
TEX_TALON_VCNEW_MFD_DYNAMIC_05,
AID_PILOT_MFD_CENTER_BTNS_FN, GRP_TALON_VCNEW_PILOT_CENTER_MFD_BTNS_FN, buttonFnRect[PILOT_MFD_CENTER],
AID_PILOT_MFD_CENTER_BTNS_SYS, GRP_TALON_VCNEW_PILOT_CENTER_MFD_BTNS_SYS
);
}
void ClassicMfd::DefineMfdButtons(
UINT const texId,
UINT const fuctionAreaId, UINT const functionGroupId, RECT const functionRect,
UINT const sysAreaId, UINT const sysGroupId
)
{
SURFHANDLE const texDyn = oapiGetTextureHandle(meshhg_VC, texId);
oapiVCRegisterArea(fuctionAreaId, functionRect, PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED | PANEL_MOUSE_ONREPLAY, PANEL_MAP_NONE, texDyn);
DefineStaticClickArea(oapiMeshGroup(meshhg_VC, functionGroupId), fuctionAreaId, true);
oapiVCRegisterArea(sysAreaId, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_ONREPLAY);
DefineStaticClickArea(oapiMeshGroup(meshhg_VC, sysGroupId), sysAreaId, true);
}
static int get_font_height(HDC const hDC)
{
TEXTMETRIC tm;
if (GetTextMetrics(hDC, &tm))
{
return abs(tm.tmAscent);
}
return 5; // Wild, crazy guessing
}
void ClassicMfd::RedrawMFDButtons(SURFHANDLE const surf, int const mfd)
{
int const btnWidth = buttonFnDim->width;
int const btnHeight = buttonFnDim->height;
RECT const draw_area = _R(0, 0, buttonFnRect[mfd].right - buttonFnRect[mfd].left, buttonFnRect[mfd].bottom - buttonFnRect[mfd].top);
HDC const hDC = oapiGetDC(surf);
SelectObject(hDC, buttonBrush);
SetBkMode(hDC, OPAQUE);
Rectangle(hDC, draw_area.left, draw_area.top, draw_area.right, draw_area.bottom);
HFONT pFont = (HFONT)SelectObject(hDC, labelFont);
SetTextColor(hDC, labelColor);
SetTextAlign(hDC, TA_CENTER);
int const half_font_height = get_font_height(hDC) / 2;
char const * label;
int const label_x_offset = (btnWidth / 2);
int const label_y_offset = (btnHeight / 2) - buttonFnDim->marginHeight - half_font_height;
for (int i = 0; i < 12; i++) {
int const x = i / 6;
int const y = i % 6;
if (label = oapiMFDButtonLabel(mfd, i)) {
int const xwidth = (x * btnWidth);
int const yheight = (y * btnHeight);
SelectObject(hDC, buttonLabelBrush);
SetBkMode(hDC, OPAQUE);
Rectangle(hDC,
draw_area.left + xwidth + buttonFnDim->marginWidth,
draw_area.top + yheight + buttonFnDim->marginHeight,
draw_area.left + xwidth + btnWidth - buttonFnDim->marginWidth,
draw_area.top + yheight + btnHeight - buttonFnDim->marginHeight
);
SetBkMode(hDC, TRANSPARENT);
TextOut(hDC, draw_area.left + xwidth + label_x_offset, draw_area.top + yheight + label_y_offset, label, strlen(label));
}
else break;
}
SelectObject(hDC, pFont);
oapiReleaseDC(surf, hDC);
}
void ClassicMfd::DefineStaticClickArea(MESHGROUP const * const gr, int const id, bool const rect, const VECTOR3& revert, const VECTOR3& maxShift)
{
float minX, maxX, minY, maxY, minZ, maxZ, x, y, z;
minX = minY = minZ = 1000.0f;
maxX = maxY = maxZ = -1000.0f;
for (DWORD i = 0; i < gr->nVtx; i++) {
x = gr->Vtx[i].x;
y = gr->Vtx[i].y;
z = gr->Vtx[i].z;
if (x < minX) minX = x;
if (y < minY) minY = y;
if (z < minZ) minZ = z;
if (x > maxX) maxX = x + (float)maxShift.x;
if (y > maxY) maxY = y + (float)maxShift.y;
if (z > maxZ) maxZ = z + (float)maxShift.z;
}
if (rect) {
VECTOR3 p1 = _V(revert.x > 0 ? maxX : minX, revert.y > 0 ? minY : maxY, revert.z > 0 ? minZ : maxZ);
VECTOR3 p2 = _V(revert.x > 0 ? minX : maxX, revert.y > 0 ? minY : maxY, revert.z > 0 ? minZ : maxZ);
VECTOR3 p3 = _V(revert.x > 0 ? maxX : minX, revert.y > 0 ? maxY : minY, revert.z > 0 ? maxZ : minZ);
VECTOR3 p4 = _V(revert.x > 0 ? minX : maxX, revert.y > 0 ? maxY : minY, revert.z > 0 ? maxZ : minZ);
oapiVCSetAreaClickmode_Quadrilateral(id, p1, p2, p3, p4);
}
else {
double distX = Distance(minX, maxX);
double distY = Distance(minY, maxY);
double distZ = Distance(minZ, maxZ);
VECTOR3 center = _V(minX + distX / 2.0f, minY + distY / 2.0f, minZ + distZ / 2.0f);
double rad = max(distX, max(distY, distZ)) / 2.0;
oapiVCSetAreaClickmode_Spherical(id, center, rad);
}
}
#pragma once
#define AID_FIRST_ID 0
#define AID_PILOT_MFD_LEFT_BTNS_FN 1
#define AID_PILOT_MFD_LEFT_BTNS_SYS 2
#define AID_PILOT_MFD_RIGHT_BTNS_FN 3
#define AID_PILOT_MFD_RIGHT_BTNS_SYS 4
#define AID_PILOT_MFD_CENTER_BTNS_FN 5
#define AID_PILOT_MFD_CENTER_BTNS_SYS 6
#pragma once
#define FILENAME_TALON_VCNEW "TALON\\TALON_VCNEW"
// Number of mesh groups:
#define NGRP_TALON_VCNEW 15
// Named mesh groups:
#define GRP_TALON_VCNEW_HUD 9
#define GRP_TALON_VCNEW_MESH02 2
#define GRP_TALON_VCNEW_MESH08 14
#define GRP_TALON_VCNEW_MESH10 0
#define GRP_TALON_VCNEW_MESH106 13
#define GRP_TALON_VCNEW_MESH107 1
#define GRP_TALON_VCNEW_PILOT_CENTER_MFD_BTNS_FN 12
#define GRP_TALON_VCNEW_PILOT_CENTER_MFD_BTNS_SYS 5
#define GRP_TALON_VCNEW_PILOT_MFD_CENTER_SCREEN 8
#define GRP_TALON_VCNEW_PILOT_MFD_LEFT_BTNS_FN 11
#define GRP_TALON_VCNEW_PILOT_MFD_LEFT_BTNS_SYS 4
#define GRP_TALON_VCNEW_PILOT_MFD_LEFT_SCREEN 7
#define GRP_TALON_VCNEW_PILOT_MFD_RIGHT_BTNS_FN 10
#define GRP_TALON_VCNEW_PILOT_MFD_RIGHT_BTNS_SYS 3
#define GRP_TALON_VCNEW_PILOT_MFD_RIGHT_SCREEN 6
// Number of materials:
#define NMAT_TALON_VCNEW 8
// Named materials:
#define MAT_TALON_VCNEW_ALU4INT 1
#define MAT_TALON_VCNEW_GREY0 8
#define MAT_TALON_VCNEW_INTERIORGREY 2
#define MAT_TALON_VCNEW_MFDBLACK7 5
#define MAT_TALON_VCNEW_MFDBUTTON59 6
#define MAT_TALON_VCNEW_MFDBUTTONSPOWER2 3
#define MAT_TALON_VCNEW_MFDSCREEN0113 4
#define MAT_TALON_VCNEW_TALONVC 7
// Number of textures:
#define NTEX_TALON_VCNEW 7
// Named textures:
#define TEX_TALON_VCNEW_ALU 1
#define TEX_TALON_VCNEW_DARKGREY 2
#define TEX_TALON_VCNEW_DG_VC1 3
#define TEX_TALON_VCNEW_MFDBLACK 5
#define TEX_TALON_VCNEW_MFD_DYNAMIC_05 6
#define TEX_TALON_VCNEW_SCREEN 4
#define TEX_TALON_VCNEW_TALONVC_0 7
TALON::TALON (OBJHANDLE hObj, int fmodel)
: VESSEL3 (hObj, fmodel)
void ClassicMfd::DefineMfdButtons(
UINT const texId,
UINT const fuctionAreaId, UINT const functionGroupId, RECT const functionRect,
UINT const sysAreaId, UINT const sysGroupId
)
{
SURFHANDLE const texDyn = oapiGetTextureHandle(meshhg_VC, texId);
oapiVCRegisterArea(fuctionAreaId, functionRect, PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED | PANEL_MOUSE_ONREPLAY, PANEL_MAP_NONE, texDyn);
DefineStaticClickArea(oapiMeshGroup(meshhg_VC, functionGroupId), fuctionAreaId, true);
oapiVCRegisterArea(sysAreaId, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_ONREPLAY);
DefineStaticClickArea(oapiMeshGroup(meshhg_VC, sysGroupId), sysAreaId, true);
}
RECT const draw_area = _R(0, 0, buttonFnRect[mfd].right - buttonFnRect[mfd].left, buttonFnRect[mfd].bottom - buttonFnRect[mfd].top);
yes. Oh so for the first mfd the area is:
_R(0, 0, buttonFnRect[mfd].right - buttonFnRect[mfd].left, buttonFnRect[mfd].bottom - buttonFnRect[mfd].top);
But the 2nd one should be 100,0?
const RECT &draw_area = buttonFnRect[mfd];
RECT const draw_area = _R(0, 0, buttonFnRect[mfd].right - buttonFnRect[mfd].left, buttonFnRect[mfd].bottom - buttonFnRect[mfd].top);
const RECT &draw_area = buttonFnRect[mfd];
void ClassicMfd::RedrawMFDButtons(SURFHANDLE const surf, int const mfd)
{
int const btnWidth = buttonFnDim->width;
int const btnHeight = buttonFnDim->height;
HDC const hDC = oapiGetDC(surf);
const RECT &draw_area = buttonFnRect[mfd];
HDC const hDC = oapiGetDC(surf);
SelectObject(hDC, buttonBrush);
SetBkMode(hDC, OPAQUE);
Rectangle(hDC, draw_area.left, draw_area.top, draw_area.right, draw_area.bottom);