62 changes: 29 additions & 33 deletions src/intelmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ static bool intAddMessageForm(bool playCurrent)
switch (psMessage->type)
{
case MSG_RESEARCH:
psResearch = getResearchForMsg((VIEWDATA *)psMessage->pViewData);
psResearch = getResearchForMsg(psMessage->pViewData);
if (psResearch)
{
button->setTip(psResearch->name);
Expand Down Expand Up @@ -407,12 +407,11 @@ bool intAddMessageView(MESSAGE *psMessage)
return false;
}

if (psMessage->type != MSG_RESEARCH &&
((VIEWDATA *)psMessage->pViewData)->type == VIEW_RPL)
if (psMessage->type != MSG_RESEARCH && psMessage->pViewData->type == VIEW_RPL)
{
VIEW_REPLAY *psViewReplay;

psViewReplay = (VIEW_REPLAY *)((VIEWDATA *)psMessage->pViewData)->pData;
psViewReplay = (VIEW_REPLAY *)psMessage->pViewData->pData;

/* Add a big tabbed text box for the subtitle text */
IntListTabWidget *seqList = new IntListTabWidget(intMapMsgView);
Expand Down Expand Up @@ -449,7 +448,7 @@ bool intAddMessageView(MESSAGE *psMessage)

ASSERT_OR_RETURN(false, psMessage->type != MSG_PROXIMITY, "Invalid message type for research");

psResearch = getResearchForMsg((VIEWDATA *)psMessage->pViewData);
psResearch = getResearchForMsg(psMessage->pViewData);

ASSERT_OR_RETURN(false, psResearch != nullptr, "Research not found");
//sLabInit.pText=psResearch->pName;
Expand Down Expand Up @@ -558,9 +557,9 @@ static bool intDisplaySeqTextViewPage(VIEW_REPLAY *psViewReplay,
/* add each message */
unsigned i;
unsigned sequence;
for (sequence = *cur_seq, i = *cur_seqpage; sequence < psViewReplay->numSeq; sequence++)
for (sequence = *cur_seq, i = *cur_seqpage; sequence < psViewReplay->seqList.size(); sequence++)
{
SEQ_DISPLAY *psSeqDisplay = &psViewReplay->pSeqList[sequence];
const SEQ_DISPLAY *psSeqDisplay = &psViewReplay->seqList.at(sequence);
for (; i < psSeqDisplay->textMsg.size(); i++)
{
if (render)
Expand Down Expand Up @@ -621,21 +620,20 @@ static void StartMessageSequences(MESSAGE *psMessage, bool Start)

ASSERT_OR_RETURN(, psMessage->pViewData != nullptr, "Invalid ViewData pointer");

if (((VIEWDATA *)psMessage->pViewData)->type == VIEW_RPL)
if (psMessage->pViewData->type == VIEW_RPL)
{
VIEW_REPLAY *psViewReplay;
UDWORD Sequence;

// Surely we don't need to set up psCurrentMsg when we pass the message into this routine ... tim
psViewReplay = (VIEW_REPLAY *)((VIEWDATA *)psMessage->pViewData)->pData;
psViewReplay = (VIEW_REPLAY *)psMessage->pViewData->pData;

seq_ClearSeqList();

//add any sequences to the list to be played when the first one is finished
for (Sequence = 0; Sequence < psViewReplay->numSeq; Sequence++)

for (Sequence = 0; Sequence < psViewReplay->seqList.size(); Sequence++)
{
if (psViewReplay->pSeqList[Sequence].flag == 1)
if (psViewReplay->seqList.at(Sequence).flag == 1)
{
bLoop = true;
}
Expand All @@ -644,11 +642,10 @@ static void StartMessageSequences(MESSAGE *psMessage, bool Start)
bLoop = false;
}


seq_AddSeqToList(psViewReplay->pSeqList[Sequence].sequenceName, psViewReplay->pSeqList[Sequence].pAudio, nullptr, bLoop);
seq_AddSeqToList(psViewReplay->seqList.at(Sequence).sequenceName, psViewReplay->seqList.at(Sequence).audio, nullptr, bLoop);

debug(LOG_GUI, "StartMessageSequences: sequence=%d", Sequence);
addVideoText(&psViewReplay->pSeqList[Sequence], Sequence);
addVideoText(&psViewReplay->seqList.at(Sequence), Sequence);
}
//play first full screen video
if (Start == true)
Expand All @@ -657,15 +654,15 @@ static void StartMessageSequences(MESSAGE *psMessage, bool Start)
}
}

else if (((VIEWDATA *)psMessage->pViewData)->type == VIEW_RES)
else if (psMessage->pViewData->type == VIEW_RES)
{
VIEW_RESEARCH *psViewReplay;
//UDWORD Sequence;

psViewReplay = (VIEW_RESEARCH *)((VIEWDATA *)psCurrentMsg->pViewData)->pData;
psViewReplay = (VIEW_RESEARCH *)psCurrentMsg->pViewData->pData;

seq_ClearSeqList();
seq_AddSeqToList(psViewReplay->sequenceName, psViewReplay->pAudio, nullptr, false);
seq_AddSeqToList(psViewReplay->sequenceName, psViewReplay->audio, nullptr, false);
//play first full screen video
if (Start == true)
{
Expand Down Expand Up @@ -739,22 +736,21 @@ void intIntelButtonPressed(bool proxMsg, UDWORD id)
return;
}

if ((VIEWDATA *)psMessage->pViewData)
{ // If its a video sequence then play it anyway
if (((VIEWDATA *)psMessage->pViewData)->type == VIEW_RPL)
if (psMessage->pViewData)
{
// If its a video sequence then play it anyway
if (psMessage->pViewData->type == VIEW_RPL)
{

if (psMessage->pViewData)
{
intAddMessageView(psMessage);
}

StartMessageSequences(psMessage, true);

}
else if (((VIEWDATA *)psMessage->pViewData)->type == VIEW_RES)
else if (psMessage->pViewData->type == VIEW_RES)
{
psResearch = getResearchForMsg((VIEWDATA *)psMessage->pViewData);
psResearch = getResearchForMsg(psMessage->pViewData);
if (psResearch != nullptr)
{
static const float maxVolume = 1.f;
Expand Down Expand Up @@ -945,7 +941,7 @@ void IntMessageButton::display(int xOffset, int yOffset)
switch (psMsg->type)
{
case MSG_RESEARCH:
pResearch = getResearchForMsg((VIEWDATA *)psMsg->pViewData);
pResearch = getResearchForMsg(psMsg->pViewData);
//IMDType = IMDTYPE_RESEARCH;
//set the IMDType depending on what stat is associated with the research
if (pResearch && pResearch->psStat)
Expand Down Expand Up @@ -1035,18 +1031,18 @@ void intDisplayPIEView(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset)
//moved from after close render
RenderWindowFrame(FRAME_NORMAL, x0 - 1, y0 - 1, x1 - x0 + 2, y1 - y0 + 2);

if (((VIEWDATA *)psMessage->pViewData)->type != VIEW_RES)
if (psMessage->pViewData->type != VIEW_RES)
{
ASSERT(false, "intDisplayPIEView: Invalid message type");
return;
}

//render an object
psResearch = getResearchForMsg((VIEWDATA *)psCurrentMsg->pViewData);
psResearch = getResearchForMsg(psCurrentMsg->pViewData);
renderResearchToBuffer(psResearch, x0 + (x1 - x0) / 2, y0 + (y1 - y0) / 2);

//draw image icon in top left of window
image = (SWORD)getResearchForMsg((VIEWDATA *)psMessage->pViewData)->iconID;
image = (SWORD)getResearchForMsg(psMessage->pViewData)->iconID;
if (image > 0)
{
iV_DrawImage(IntImages, image, x0, y0);
Expand All @@ -1073,14 +1069,14 @@ void intDisplayFLICView(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset)
int x1 = x0 + psWidget->width();
int y1 = y0 + psWidget->height();

if (((VIEWDATA *)psMessage->pViewData)->type != VIEW_RES)
if (psMessage->pViewData->type != VIEW_RES)
{
ASSERT(false, "intDisplayFLICView: Invalid message type");
return;
}

RenderWindowFrame(FRAME_NORMAL, x0, y0, x1 - x0, y1 - y0);
psViewResearch = (VIEW_RESEARCH *)((VIEWDATA *)psCurrentMsg->pViewData)->pData;
psViewResearch = (VIEW_RESEARCH *)psCurrentMsg->pViewData->pData;
// set the dimensions to window size & position
seq_SetDisplaySize(192, 168, x0, y0);
//render a frame of the current movie *must* force above resolution!
Expand Down Expand Up @@ -1116,7 +1112,7 @@ void intDisplayTEXTView(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset)

iV_SetTextColour(WZCOL_TEXT_BRIGHT);
//add each message
for (unsigned i = 0; i < ((VIEWDATA *)psMessage->pViewData)->textMsg.size(); i++)
for (unsigned i = 0; i < psMessage->pViewData->textMsg.size(); i++)
{
//check haven't run out of room first!
if (i * linePitch > psWidget->height())
Expand All @@ -1125,7 +1121,7 @@ void intDisplayTEXTView(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset)
return;
}
//need to check the string will fit!
iV_DrawText(_(((VIEWDATA *)psMessage->pViewData)->textMsg[i].toUtf8().constData()), x0 + TEXT_XINDENT,
iV_DrawText(_(psMessage->pViewData->textMsg[i].toUtf8().constData()), x0 + TEXT_XINDENT,
(ty + TEXT_YINDENT * 3) + (i * linePitch), font_regular);
}
}
Expand Down
186 changes: 70 additions & 116 deletions src/message.cpp

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ void viewDataShutDown(const char *fileName);

/** Looks through the players list of messages to find one with the same viewData
* pointer and which is the same type of message - used in scriptFuncs. */
MESSAGE *findMessage(MSG_VIEWDATA *pViewdata, MESSAGE_TYPE type, UDWORD player);
MESSAGE *findMessage(const VIEWDATA *pViewdata, MESSAGE_TYPE type, UDWORD player);
MESSAGE *findMessage(const BASE_OBJECT *psObj, MESSAGE_TYPE type, UDWORD player);

/** 'Displays' a proximity display. */
void displayProximityMessage(PROXIMITY_DISPLAY *psProxDisp);
Expand Down
73 changes: 36 additions & 37 deletions src/messagedef.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@
#ifndef __INCLUDED_MESSAGEDEF_H__
#define __INCLUDED_MESSAGEDEF_H__

#include <vector>
#include <QtCore/QStringList>
#include "positiondef.h"
#include "stringdef.h"

struct iIMDShape;

/// max number of text strings or sequences for VIEWDATA
static const unsigned int MAX_DATA = 4;
struct BASE_OBJECT;

enum MESSAGE_TYPE
{
Expand Down Expand Up @@ -63,33 +62,36 @@ enum PROX_TYPE
PROX_TYPES,
};

struct VIEW_BASE
{
virtual ~VIEW_BASE() {} // will cause destructors to be called for subclasses

This comment has been minimized.

Copy link
@Cyp

Cyp Jul 29, 2017

Not really important, but could be virtual ~VIEW_BASE() = default; for more modern syntax.

};

// info required to view an object in Intelligence screen
struct VIEW_RESEARCH
struct VIEW_RESEARCH : VIEW_BASE
{
iIMDShape *pIMD;
iIMDShape *pIMD2; //allows base plates and turrets to be drawn as well
char sequenceName[MAX_STR_LENGTH]; //which windowed flic to display
char *pAudio; /*name of audio track to play (for this seq)*/
iIMDShape *pIMD = nullptr;
iIMDShape *pIMD2 = nullptr; // allows base plates and turrets to be drawn as well
QString sequenceName; // which windowed flic to display
QString audio; // name of audio track to play (for this seq)
};

struct SEQ_DISPLAY
{
char sequenceName[MAX_STR_LENGTH];

QString sequenceName;
UBYTE flag; //flag data to control video playback 1 = loop till audio finish
QStringList textMsg; //Text messages - if any
char *pAudio; /*name of audio track to play (for this seq)*/
QString audio; // name of audio track to play (for this seq)
};

//info required to view a flic in Intelligence Screen
struct VIEW_REPLAY
struct VIEW_REPLAY : VIEW_BASE
{
UBYTE numSeq;
SEQ_DISPLAY *pSeqList;
std::vector<SEQ_DISPLAY> seqList;
};

// info required to view a proximity message
struct VIEW_PROXIMITY
struct VIEW_PROXIMITY : VIEW_BASE
{
UDWORD x; //world coords for position of Proximity message
UDWORD y;
Expand All @@ -102,44 +104,41 @@ struct VIEW_PROXIMITY

struct VIEWDATA
{
char *pName; //name ID of the message - used for loading in and identifying
QString name; //name ID of the message - used for loading in and identifying
VIEW_TYPE type; //the type of view
QStringList textMsg; //Text messages, if any
void *pData; /*the data required to view - either a
VIEW_RESEARCH, VIEW_PROXIMITY or VIEW_REPLAY*/
const char *fileName; //file it came from, for piecemeal destruction (pretty lame reason)
VIEW_BASE *pData = nullptr; // the data required to view - either VIEW_RESEARCH, VIEW_PROXIMITY or VIEW_REPLAY
QString fileName; // file it came from, for piecemeal destruction (pretty lame reason)
};

typedef void *MSG_VIEWDATA;

enum MSG_DATA_TYPE
{
MSG_DATA_DEFAULT, // Message's pViewData has a BASE_OBJECT stored
MSG_DATA_BEACON, // Message's pViewData has beacon data stored
MSG_DATA_DEFAULT,
MSG_DATA_BEACON,
};

//base structure for each message
struct MESSAGE
{
MESSAGE_TYPE type; //The type of message
UDWORD id; //ID number of the message
MSG_VIEWDATA *pViewData; //Pointer to view data - if any - should be some!
bool read; //flag to indicate whether message has been read
UDWORD player; //which player this message belongs to
MSG_DATA_TYPE dataType; //stores actual type of data pViewData points to
//only relevant for messages of type MSG_PROXIMITY

MESSAGE *psNext; //pointer to the next in the list
MESSAGE_TYPE type; // The type of message
UDWORD id; // ID number of the message
VIEWDATA *pViewData = nullptr; // Pointer to view data - if any - should be some!
BASE_OBJECT *psObj = nullptr;
bool read = false; // flag to indicate whether message has been read
UDWORD player; // which player this message belongs to
MSG_DATA_TYPE dataType;

MESSAGE *psNext = nullptr; // pointer to the next in the list
};

//used to display the proximity messages
struct PROXIMITY_DISPLAY : public OBJECT_POSITION
{
MESSAGE *psMessage; //message associated with this 'button'
UDWORD timeLastDrawn; //stores the time the 'button' was last drawn for animation
UDWORD strobe; //id of image last used
UDWORD buttonID; //id of the button for the interface
PROXIMITY_DISPLAY *psNext; //pointer to the next in the list
MESSAGE *psMessage = nullptr; // message associated with this 'button'
UDWORD timeLastDrawn = 0; // stores the time the 'button' was last drawn for animation
UDWORD strobe = 0; // id of image last used
UDWORD buttonID = 0; // id of the button for the interface
PROXIMITY_DISPLAY *psNext = nullptr; // pointer to the next in the list
};

#endif // __INCLUDED_MESSAGEDEF_H__
1 change: 1 addition & 0 deletions src/qtscript.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,6 @@ bool triggerEventKeyPressed(int meta, int key);
// Debug functions

void jsDebugSelected(const BASE_OBJECT *psObj);
void jsDebugMessageUpdate();

#endif
59 changes: 59 additions & 0 deletions src/qtscriptdebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include "hci.h"
#include "display.h"
#include "keybind.h"
#include "message.h"

#include "qtscript.h"
#include "qtscriptfuncs.h"
Expand Down Expand Up @@ -115,6 +116,42 @@ void ScriptDebugger::fogButtonClicked()
kf_ToggleFog();
}

static void fillMessageModel(QStandardItemModel &m)
{
const QStringList msg_type = { "RESEARCH", "CAMPAIGN", "MISSION", "PROXIMITY" };
const QStringList view_type = { "RES", "PPL", "PROX", "RPLX", "BEACON" };
const QStringList msg_data_type = { "OBJ", "VIEW" };
const QStringList obj_type = { "DROID", "STRUCTURE", "FEATURE", "PROJECTILE", "TARGET" };
int row = 0;
m.setRowCount(0);
m.setHorizontalHeaderLabels({"ID", "Type", "Data Type", "Player", "Name", "ViewData Type"});
for (int i = 0; i < MAX_PLAYERS; i++)
{
for (const MESSAGE *psCurr = apsMessages[i]; psCurr != nullptr; psCurr = psCurr->psNext)
{
ASSERT(psCurr->type < msg_type.size(), "Bad message type");
ASSERT(psCurr->dataType < msg_data_type.size(), "Bad viewdata type");
m.setItem(row, 0, new QStandardItem(QString::number(psCurr->id)));
m.setItem(row, 1, new QStandardItem(msg_type.at(psCurr->type)));
m.setItem(row, 2, new QStandardItem(msg_data_type.at(psCurr->dataType)));
m.setItem(row, 3, new QStandardItem(QString::number(psCurr->player)));
ASSERT(!psCurr->pViewData || !psCurr->psObj, "Both viewdata and object in message should be impossible!");
if (psCurr->pViewData)
{
ASSERT(psCurr->pViewData->type < view_type.size(), "Bad viewdata type");
m.setItem(row, 4, new QStandardItem(psCurr->pViewData->name));
m.setItem(row, 5, new QStandardItem(view_type.at(psCurr->pViewData->type)));
}
else if (psCurr->psObj)
{
m.setItem(row, 4, new QStandardItem(objInfo(psCurr->psObj)));
m.setItem(row, 5, new QStandardItem(obj_type.at(psCurr->psObj->type)));
}
row++;
}
}
}

ScriptDebugger::ScriptDebugger(const MODELMAP &models, QStandardItemModel *triggerModel) : QDialog(nullptr, Qt::Window)
{
modelMap = models;
Expand Down Expand Up @@ -208,6 +245,14 @@ ScriptDebugger::ScriptDebugger(const MODELMAP &models, QStandardItemModel *trigg
triggerView.setSelectionBehavior(QAbstractItemView::SelectRows);
tab.addTab(&triggerView, "Triggers");

// Add messages
messageView.setModel(&messageModel);
messageView.setSelectionMode(QAbstractItemView::NoSelection);
messageView.setSelectionBehavior(QAbstractItemView::SelectRows);
tab.addTab(&messageView, "Messages");
fillMessageModel(messageModel);
messageView.resizeColumnToContents(0);

// Add labels
labelModel = createLabelModel();
labelModel->setParent(this); // take ownership to avoid memory leaks
Expand Down Expand Up @@ -247,6 +292,12 @@ ScriptDebugger::ScriptDebugger(const MODELMAP &models, QStandardItemModel *trigg
activateWindow();
}

void ScriptDebugger::updateMessages()
{
fillMessageModel(messageModel);
messageView.resizeColumnToContents(0);
}

void ScriptDebugger::runClicked(QObject *obj)
{
QScriptEngine *engine = (QScriptEngine *)obj;
Expand Down Expand Up @@ -560,6 +611,14 @@ ScriptDebugger::~ScriptDebugger()
{
}

void jsDebugMessageUpdate()
{
if (globalDialog)
{
globalDialog->updateMessages();
}
}

void jsDebugSelected(const BASE_OBJECT *psObj)
{
if (globalDialog)
Expand Down
5 changes: 4 additions & 1 deletion src/qtscriptdebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,17 @@ class ScriptDebugger : public QDialog
ScriptDebugger(const MODELMAP &models, QStandardItemModel *triggerModel);
~ScriptDebugger();
void selected(const BASE_OBJECT *psObj);
void updateMessages();

private:
QTabWidget tab;
QStandardItemModel *labelModel;
QStandardItemModel selectedModel;
QStandardItemModel messageModel;
QTreeView selectedView;
QTreeView labelView;
QTreeView triggerView;
QTreeView messageView;
MODELMAP modelMap;
EDITMAP editMap;
int powerValue = 0;
Expand Down Expand Up @@ -90,6 +93,6 @@ protected slots:
void jsDebugCreate(const MODELMAP &models, QStandardItemModel *triggerModel);
bool jsDebugShutdown();

// jsDebugSelected() defined in qtscript.h since it is used widely
// jsDebugSelected() and jsDebugMessageUpdate() defined in qtscript.h since it is used widely

#endif
16 changes: 10 additions & 6 deletions src/qtscriptfuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2813,13 +2813,14 @@ static QScriptValue js_gameOverMessage(QScriptContext *context, QScriptEngine *e
if (psMessage)
{
//set the data
psMessage->pViewData = (MSG_VIEWDATA *)psViewData;
psMessage->pViewData = psViewData;
displayImmediateMessage(psMessage);
stopReticuleButtonFlash(IDRET_INTEL_MAP);

//we need to set this here so the VIDEO_QUIT callback is not called
setScriptWinLoseVideo(gameWon ? PLAY_WIN : PLAY_LOSE);
}
jsDebugMessageUpdate();
displayGameOver(gameWon);
if (challengeActive)
{
Expand Down Expand Up @@ -3757,6 +3758,7 @@ static QScriptValue js_removeBeacon(QScriptContext *context, QScriptEngine *engi
}
}
}
jsDebugMessageUpdate();
return QScriptValue(true);
}

Expand Down Expand Up @@ -3976,8 +3978,8 @@ static QScriptValue js_hackAddMessage(QScriptContext *context, QScriptEngine *)
{
VIEWDATA *psViewData = getViewData(mess.toUtf8().constData());
SCRIPT_ASSERT(context, psViewData, "Viewdata not found");
psMessage->pViewData = (MSG_VIEWDATA *)psViewData;
debug(LOG_MSG, "Adding %s pViewData=%p", psViewData->pName, psMessage->pViewData);
psMessage->pViewData = psViewData;
debug(LOG_MSG, "Adding %s pViewData=%p", psViewData->name.toUtf8().constData(), psMessage->pViewData);
if (msgType == MSG_PROXIMITY)
{
VIEW_PROXIMITY *psProx = (VIEW_PROXIMITY *)psViewData->pData;
Expand All @@ -3993,6 +3995,7 @@ static QScriptValue js_hackAddMessage(QScriptContext *context, QScriptEngine *)
displayImmediateMessage(psMessage);
}
}
jsDebugMessageUpdate();
return QScriptValue();
}

Expand All @@ -4005,16 +4008,17 @@ static QScriptValue js_hackRemoveMessage(QScriptContext *context, QScriptEngine
int player = context->argument(2).toInt32();
VIEWDATA *psViewData = getViewData(mess.toUtf8().constData());
SCRIPT_ASSERT(context, psViewData, "Viewdata not found");
MESSAGE *psMessage = findMessage((MSG_VIEWDATA *)psViewData, msgType, player);
MESSAGE *psMessage = findMessage(psViewData, msgType, player);
if (psMessage)
{
debug(LOG_MSG, "Removing %s", psViewData->pName);
debug(LOG_MSG, "Removing %s", psViewData->name.toUtf8().constData());
removeMessage(psMessage, player);
}
else
{
debug(LOG_ERROR, "cannot find message - %s", psViewData->pName);
debug(LOG_ERROR, "cannot find message - %s", psViewData->name.toUtf8().constData());
}
jsDebugMessageUpdate();
return QScriptValue();
}

Expand Down
5 changes: 3 additions & 2 deletions src/research.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,8 @@ void researchResult(UDWORD researchIndex, UBYTE player, bool bDisplay, STRUCTURE
pMessage = addMessage(MSG_RESEARCH, false, player);
if (pMessage != nullptr)
{
pMessage->pViewData = (MSG_VIEWDATA *)pResearch->pViewData;
pMessage->pViewData = pResearch->pViewData;
jsDebugMessageUpdate();
}
}
}
Expand Down Expand Up @@ -754,7 +755,7 @@ void cancelResearch(STRUCTURE *psBuilding, QUEUE_MODE mode)
}

/* For a given view data get the research this is related to */
RESEARCH *getResearchForMsg(VIEWDATA *pViewData)
RESEARCH *getResearchForMsg(const VIEWDATA *pViewData)
{
for (auto &inc : asResearch)
{
Expand Down
8 changes: 3 additions & 5 deletions src/research.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@

#include "objectdef.h"

struct VIEWDATA;

#define NO_RESEARCH_ICON 0
//max 'research complete' console message length
#define MAX_RESEARCH_MSG_SIZE 200


//used for loading in the research stats into the appropriate list
enum
{
Expand All @@ -39,7 +40,6 @@ enum
RES_LIST
};


enum
{
RID_ROCKET,
Expand All @@ -65,7 +65,6 @@ enum
RID_MAXRID
};


/* The store for the research stats */
extern std::vector<RESEARCH> asResearch;

Expand Down Expand Up @@ -104,8 +103,7 @@ RESEARCH *getResearch(const char *pName);
void cancelResearch(STRUCTURE *psBuilding, QUEUE_MODE mode);

/* For a given view data get the research this is related to */
struct VIEWDATA;
RESEARCH *getResearchForMsg(VIEWDATA *pViewData);
RESEARCH *getResearchForMsg(const VIEWDATA *pViewData);

/* Sets the 'possible' flag for a player's research so the topic will appear in
the research list next time the Research Facilty is selected */
Expand Down
4 changes: 3 additions & 1 deletion src/researchdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "lib/framework/frame.h"
#include "statsdef.h"

struct VIEWDATA;

/* Research struct type definitions */
enum TECH_CODE
{
Expand Down Expand Up @@ -60,7 +62,7 @@ struct RESEARCH : public BASE_STATS
QList<COMPONENT_STATS *> componentResults; ///< List of Components that are possible after this research
QList<RES_COMP_REPLACEMENT> componentReplacement; ///< List of Components that are automatically replaced with new onew after research
QJsonValue results; ///< Research upgrades
const struct VIEWDATA *pViewData; // data used to display a message in the Intelligence Screen
VIEWDATA *pViewData; ///< Data used to display a message in the Intelligence Screen
UWORD iconID; /* the ID from 'Framer' for which graphic to draw in interface*/
BASE_STATS *psStat; /* A stat used to define which graphic is drawn instead of the two fields below */
iIMDShape *pIMD; /* the IMD to draw for this research topic */
Expand Down
59 changes: 28 additions & 31 deletions src/scriptfuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,7 @@ bool scrAddMessage()
MESSAGE_TYPE msgType;
SDWORD player;
int32_t playImmediate; // was BOOL (int) ** see warning about conversion
VIEWDATA *psViewData;
VIEWDATA *psViewData = nullptr;
UDWORD height;


Expand All @@ -1408,8 +1408,8 @@ bool scrAddMessage()
if (psMessage)
{
//set the data
psMessage->pViewData = (MSG_VIEWDATA *)psViewData;
debug(LOG_MSG, "Adding %s pViewData=%p", psViewData->pName, psMessage->pViewData);
psMessage->pViewData = psViewData;
debug(LOG_MSG, "Adding %s pViewData=%p", psViewData->name.toUtf8().constData(), psMessage->pViewData);
if (msgType == MSG_PROXIMITY)
{
//check the z value is at least the height of the terrain
Expand All @@ -1429,6 +1429,7 @@ bool scrAddMessage()
//stopReticuleButtonFlash(IDRET_INTEL_MAP);
}
}
jsDebugMessageUpdate();

return true;
}
Expand All @@ -1440,7 +1441,7 @@ bool scrRemoveMessage()
MESSAGE *psMessage;
MESSAGE_TYPE msgType;
SDWORD player;
VIEWDATA *psViewData;
VIEWDATA *psViewData = nullptr;

if (!stackPopParams(3, ST_INTMESSAGE, &psViewData , VAL_INT, &msgType, VAL_INT, &player))
{
Expand All @@ -1450,17 +1451,18 @@ bool scrRemoveMessage()
ASSERT_OR_RETURN(false, player >= 0 && player < MAX_PLAYERS, "Invalid player number");

//find the message
psMessage = findMessage((MSG_VIEWDATA *)psViewData, msgType, player);
psMessage = findMessage(psViewData, msgType, player);
if (psMessage)
{
//delete it
debug(LOG_MSG, "Removing %s", psViewData->pName);
debug(LOG_MSG, "Removing %s", psViewData->name.toUtf8().constData());
removeMessage(psMessage, player);
}
else
{
debug(LOG_ERROR, "cannot find message - %s", psViewData->pName);
debug(LOG_ERROR, "cannot find message - %s", psViewData->name.toUtf8().constData());
}
jsDebugMessageUpdate();

return true;
}
Expand Down Expand Up @@ -3051,7 +3053,7 @@ bool scrGameOverMessage()
MESSAGE *psMessage;
MESSAGE_TYPE msgType;
SDWORD player;
VIEWDATA *psViewData;
VIEWDATA *psViewData = nullptr;

if (!stackPopParams(4, ST_INTMESSAGE, &psViewData , VAL_INT, &msgType,
VAL_INT, &player, VAL_BOOL, &gameWon))
Expand All @@ -3078,7 +3080,7 @@ bool scrGameOverMessage()
if (psMessage)
{
//set the data
psMessage->pViewData = (MSG_VIEWDATA *)psViewData;
psMessage->pViewData = psViewData;
displayImmediateMessage(psMessage);
stopReticuleButtonFlash(IDRET_INTEL_MAP);

Expand All @@ -3096,6 +3098,8 @@ bool scrGameOverMessage()
updateChallenge(gameWon);
}

jsDebugMessageUpdate();

return true;
}

Expand Down Expand Up @@ -8969,7 +8973,6 @@ bool scrPlayerLoaded()
bool addBeaconBlip(SDWORD locX, SDWORD locY, SDWORD forPlayer, SDWORD sender, const char *textMsg)
{
MESSAGE *psMessage;
VIEWDATA *pTempData;

if (forPlayer >= MAX_PLAYERS)
{
Expand All @@ -8989,12 +8992,9 @@ bool addBeaconBlip(SDWORD locX, SDWORD locY, SDWORD forPlayer, SDWORD sender, co
psMessage = addBeaconMessage(MSG_PROXIMITY, false, forPlayer);
if (psMessage)
{
pTempData = CreateBeaconViewData(sender, locX, locY);

VIEWDATA *pTempData = CreateBeaconViewData(sender, locX, locY);
ASSERT_OR_RETURN(false, pTempData != nullptr, "Empty help data for radar beacon");

psMessage->pViewData = (MSG_VIEWDATA *)pTempData;

psMessage->pViewData = pTempData;
debug(LOG_MSG, "blip added, pViewData=%p", psMessage->pViewData);
}
else
Expand Down Expand Up @@ -9032,23 +9032,26 @@ bool addBeaconBlip(SDWORD locX, SDWORD locY, SDWORD forPlayer, SDWORD sender, co

bool sendBeaconToPlayer(SDWORD locX, SDWORD locY, SDWORD forPlayer, SDWORD sender, const char *beaconMsg)
{
bool retval;
if (sender == forPlayer || myResponsibility(forPlayer)) //if destination player is on this machine
{
debug(LOG_WZ, "sending beacon to player %d (local player) from %d", forPlayer, sender);
return addBeaconBlip(locX, locY, forPlayer, sender, beaconMsg);
retval = addBeaconBlip(locX, locY, forPlayer, sender, beaconMsg);
}
else
{
debug(LOG_WZ, "sending beacon to player %d (remote player) from %d", forPlayer, sender);
return sendBeacon(locX, locY, forPlayer, sender, beaconMsg);
retval = sendBeacon(locX, locY, forPlayer, sender, beaconMsg);
}
jsDebugMessageUpdate();
return retval;
}

//prepare viewdata for help blip
VIEWDATA *CreateBeaconViewData(SDWORD sender, UDWORD LocX, UDWORD LocY)
{
UDWORD height;
VIEWDATA *psViewData;
VIEWDATA *psViewData = nullptr;
SDWORD audioID;
char name[MAXSTRLEN];

Expand All @@ -9057,7 +9060,7 @@ VIEWDATA *CreateBeaconViewData(SDWORD sender, UDWORD LocX, UDWORD LocY)

//store name
sprintf(name, _("Beacon %d"), sender);
psViewData->pName = name;
psViewData->name = name;

//store text message, hardcoded for now
psViewData->textMsg.push_back(QString::fromUtf8(getPlayerName(sender)));
Expand All @@ -9066,13 +9069,7 @@ VIEWDATA *CreateBeaconViewData(SDWORD sender, UDWORD LocX, UDWORD LocY)
psViewData->type = VIEW_BEACON;

//allocate memory for blip location etc
psViewData->pData = (VIEW_PROXIMITY *) malloc(sizeof(VIEW_PROXIMITY));
if (psViewData->pData == nullptr)
{
ASSERT(false, "prepairHelpViewData() - Unable to allocate memory");
delete psViewData;
return nullptr;
}
psViewData->pData = new VIEW_PROXIMITY;

//store audio
audioID = NO_SOUND;
Expand Down Expand Up @@ -9103,17 +9100,15 @@ VIEWDATA *CreateBeaconViewData(SDWORD sender, UDWORD LocX, UDWORD LocY)
/* Looks through the players list of messages to find VIEW_BEACON (one per player!) pointer */
MESSAGE *findBeaconMsg(UDWORD player, SDWORD sender)
{
MESSAGE *psCurr;

for (psCurr = apsMessages[player]; psCurr != nullptr; psCurr = psCurr->psNext)
for (MESSAGE *psCurr = apsMessages[player]; psCurr != nullptr; psCurr = psCurr->psNext)
{
//look for VIEW_BEACON, should only be 1 per player
if (psCurr->dataType == MSG_DATA_BEACON)
{
if (((VIEWDATA *)psCurr->pViewData)->type == VIEW_BEACON)
if (psCurr->pViewData->type == VIEW_BEACON)
{
debug(LOG_WZ, "findBeaconMsg: %d ALREADY HAS A MESSAGE STORED", player);
if (((VIEW_PROXIMITY *)((VIEWDATA *)psCurr->pViewData)->pData)->sender == sender)
if (((VIEW_PROXIMITY *)psCurr->pViewData->pData)->sender == sender)
{
debug(LOG_WZ, "findBeaconMsg: %d ALREADY HAS A MESSAGE STORED from %d", player, sender);
return psCurr;
Expand Down Expand Up @@ -9169,6 +9164,8 @@ bool scrRemoveBeacon()
triggerEventBeaconRemoved(sender, player);
}

jsDebugMessageUpdate();

return true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/scriptobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ bool scrValDefSave(INTERP_VAL *psVal, WzConfig &ini)
psIntMessage = (VIEWDATA *)psVal->v.oval;
if (psIntMessage != nullptr)
{
ini.setValue("data", QString(psIntMessage->pName));
ini.setValue("data", psIntMessage->name);
}
break;
case ST_BASEOBJECT:
Expand Down
8 changes: 4 additions & 4 deletions src/seqdisp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static bool seq_StartFullScreenVideo(const QString& videoName, const QString& au
/***************************************************************************/

/* Renders a video sequence specified by filename to a buffer*/
bool seq_RenderVideoToBuffer(const char *sequenceName, int seqCommand)
bool seq_RenderVideoToBuffer(const QString &sequenceName, int seqCommand)
{
static enum
{
Expand Down Expand Up @@ -562,15 +562,15 @@ void seq_ClearSeqList()
}

//add a sequence to the list to be played
void seq_AddSeqToList(const char *pSeqName, const char *pAudioName, const char *pTextName, bool bLoop)
void seq_AddSeqToList(const QString &pSeqName, const QString &audioName, const char *pTextName, bool bLoop)
{
currentSeq++;

ASSERT_OR_RETURN(, currentSeq < MAX_SEQ_LIST, "too many sequences");

//OK so add it to the list
aSeqList[currentSeq].pSeq = pSeqName;
aSeqList[currentSeq].pAudio = pAudioName;
aSeqList[currentSeq].pAudio = audioName;
aSeqList[currentSeq].bSeqLoop = bLoop;
if (pTextName != nullptr)
{
Expand All @@ -581,7 +581,7 @@ void seq_AddSeqToList(const char *pSeqName, const char *pAudioName, const char *
if (bSeqSubtitles)
{
char aSubtitleName[MAX_STR_LENGTH];
sstrcpy(aSubtitleName, pSeqName);
sstrcpy(aSubtitleName, pSeqName.toUtf8().constData());

// check for a subtitle file
char *extension = strrchr(aSubtitleName, '.');
Expand Down
4 changes: 2 additions & 2 deletions src/seqdisp.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ enum SEQ_TEXT_POSITIONING
*/
/***************************************************************************/
//buffer render
bool seq_RenderVideoToBuffer(const char *sequenceName, int seqCommand);
bool seq_RenderVideoToBuffer(const QString &sequenceName, int seqCommand);

bool seq_UpdateFullScreenVideo(int *bClear);

Expand All @@ -77,7 +77,7 @@ bool seq_AddTextForVideo(const char *pText, SDWORD xOffset, SDWORD yOffset, doub
//clear the sequence list
void seq_ClearSeqList();
//add a sequence to the list to be played
void seq_AddSeqToList(const char *pSeqName, const char *pAudioName, const char *pTextName, bool bLoop);
void seq_AddSeqToList(const QString &pSeqName, const QString &audioName, const char *pTextName, bool bLoop);
/*checks to see if there are any sequences left in the list to play*/
bool seq_AnySeqLeft();

Expand Down
2 changes: 1 addition & 1 deletion src/visibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ static void processVisibilityLevel(BASE_OBJECT *psObj)
psMessage = addMessage(MSG_PROXIMITY, true, player);
if (psMessage)
{
psMessage->pViewData = (MSG_VIEWDATA *)psObj;
psMessage->psObj = psObj;
debug(LOG_MSG, "Added message for oil well or artefact, pViewData=%p", psMessage->pViewData);
}
if (!bInTutorial && player == selectedPlayer)
Expand Down