From 033792078cd904d79c0d1ca0a31db10626d1a145 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 19 Feb 2017 11:31:58 +0200 Subject: [PATCH 1/3] Fixed compilation with GCC/Clang src/menu/messagebox.cpp:70:95: error: no viable conversion from 'hfunc' (aka 'void (*)()') to 'VMValue' --- src/menu/messagebox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index 8cbaa3e241..795bb60e4d 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -67,7 +67,7 @@ DMenu *CreateMessageBoxMenu(DMenu *parent, const char *message, int messagemode, { auto c = PClass::FindClass("MessageBoxMenu"); auto p = c->CreateNew(); - VMValue params[] = { p, parent, FString(message), messagemode, playsound, action.GetIndex(), handler }; + VMValue params[] = { p, parent, FString(message), messagemode, playsound, action.GetIndex(), reinterpret_cast(handler) }; auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); From 8db1646056e3960e74ed04a4900311599d2c9ff0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Feb 2017 10:33:10 +0100 Subject: [PATCH 2/3] - fixed: Strife dialogues remembered the last menu's selection index, but with the possibility of changing sets of replies between calls of the same dialogue it should be the reply's index in the list of replies that gets remembered. --- src/p_conversation.cpp | 86 ++++++++++++++++------- wadsrc/static/zscript/menu/messagebox.txt | 2 +- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 3977d6a01f..ae120182ce 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -113,6 +113,7 @@ static int ConversationMenuY; static int ConversationPauseTic; static bool ShowGold; +static int StaticLastReply; static bool LoadScriptFile(int lumpnum, FileReader *lump, int numnodes, bool include, int type); static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeakerType); @@ -689,6 +690,27 @@ static bool ShouldSkipReply(FStrifeDialogueReply *reply, player_t *player) return false; } +static void SendConversationReply(int node, int reply) +{ + switch (node) + { + case -1: + Net_WriteByte(DEM_CONVNULL); + break; + + case -2: + Net_WriteByte(DEM_CONVCLOSE); + break; + + default: + Net_WriteByte(DEM_CONVREPLY); + Net_WriteWord(node); + Net_WriteByte(reply); + break; + } + StaticLastReply = reply; +} + //============================================================================ // // The conversation menu @@ -699,6 +721,7 @@ class DConversationMenu : public DMenu { DECLARE_CLASS(DConversationMenu, DMenu) +public: FString mSpeaker; FBrokenLines *mDialogueLines; TArray mResponseLines; @@ -707,9 +730,7 @@ class DConversationMenu : public DMenu FStrifeDialogueNode *mCurNode; int mYpos; player_t *mPlayer; - -public: - static int mSelection; + int mSelection; //============================================================================= // @@ -717,7 +738,7 @@ public: // //============================================================================= - DConversationMenu(FStrifeDialogueNode *CurNode, player_t *player) + DConversationMenu(FStrifeDialogueNode *CurNode, player_t *player, int activereply) { mCurNode = CurNode; mPlayer = player; @@ -750,15 +771,20 @@ public: toSay = "."; } mDialogueLines = V_BreakLines (SmallFont, screen->GetWidth()/CleanXfac - 24*2, toSay); + mSelection = -1; FStrifeDialogueReply *reply; + int r = -1; int i,j; for (reply = CurNode->Children, i = 1; reply != NULL; reply = reply->Next) { + r++; if (ShouldSkipReply(reply, mPlayer)) { continue; } + if (activereply == r) mSelection = i - 1; + mShowGold |= reply->NeedsGold; const char *ReplyText = reply->Reply; @@ -776,9 +802,14 @@ public: { mResponseLines.Push(ReplyLines[j].Text); } + ++i; V_FreeBrokenLines (ReplyLines); } + if (mSelection == -1) + { + mSelection = r < activereply ? r + 1 : 0; + } const char *goodbyestr = CurNode->Goodbye; if (*goodbyestr == 0) { @@ -841,6 +872,25 @@ public: return false; } + int GetReplyNum() + { + assert((unsigned)mCurNode->ThisNodeNum < StrifeDialogues.Size()); + assert(StrifeDialogues[mCurNode->ThisNodeNum] == mCurNode); + + // This is needed because mSelection represents the replies currently being displayed which will + // not match up with what's supposed to be selected if there are any hidden/skipped replies. [FishyClockwork] + FStrifeDialogueReply *reply = mCurNode->Children; + int replynum = mSelection; + for (int i = 0; i <= mSelection && reply != nullptr; reply = reply->Next) + { + if (ShouldSkipReply(reply, mPlayer)) + replynum++; + else + i++; + } + return replynum; + } + //============================================================================= // // @@ -870,36 +920,21 @@ public: } else if (mkey == MKEY_Back) { - Net_WriteByte (DEM_CONVNULL); + SendConversationReply(-1, GetReplyNum()); Close(); return true; } else if (mkey == MKEY_Enter) { + int replynum = GetReplyNum(); if ((unsigned)mSelection >= mResponses.Size()) { - Net_WriteByte(DEM_CONVCLOSE); + SendConversationReply(-1, replynum); } else { - assert((unsigned)mCurNode->ThisNodeNum < StrifeDialogues.Size()); - assert(StrifeDialogues[mCurNode->ThisNodeNum] == mCurNode); - - // This is needed because mSelection represents the replies currently being displayed which will - // not match up with what's supposed to be selected if there are any hidden/skipped replies. [FishyClockwork] - FStrifeDialogueReply *reply = mCurNode->Children; - int replynum = mSelection; - for (int i = 0; i <= mSelection && reply != nullptr; reply = reply->Next) - { - if (ShouldSkipReply(reply, mPlayer)) - replynum++; - else - i++; - } // Send dialogue and reply numbers across the wire. - Net_WriteByte(DEM_CONVREPLY); - Net_WriteWord(mCurNode->ThisNodeNum); - Net_WriteByte(replynum); + SendConversationReply(mCurNode->ThisNodeNum, replynum); } Close(); return true; @@ -1108,7 +1143,6 @@ public: }; IMPLEMENT_CLASS(DConversationMenu, true, false) -int DConversationMenu::mSelection; // needs to be preserved if the same dialogue is restarted //============================================================================ @@ -1228,12 +1262,12 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang S_Sound (npc, CHAN_VOICE|CHAN_NOPAUSE, CurNode->SpeakerVoice, 1, ATTN_NORM); } - DConversationMenu *cmenu = new DConversationMenu(CurNode, pc->player); + DConversationMenu *cmenu = new DConversationMenu(CurNode, pc->player, StaticLastReply); if (CurNode != PrevNode) { // Only reset the selection if showing a different menu. - DConversationMenu::mSelection = 0; + StaticLastReply = 0; PrevNode = CurNode; } diff --git a/wadsrc/static/zscript/menu/messagebox.txt b/wadsrc/static/zscript/menu/messagebox.txt index deb73046e2..d952985462 100644 --- a/wadsrc/static/zscript/menu/messagebox.txt +++ b/wadsrc/static/zscript/menu/messagebox.txt @@ -58,7 +58,7 @@ class MessageBoxMenu : Menu mMouseLeft = 140; mMouseY = 0x80000000; int mr1 = 170 + SmallFont.StringWidth(Stringtable.Localize("$TXT_YES")); - int mr2 = 170 + SmallFont.StringWidth(Stringtable.Localize("TXT_NO")); + int mr2 = 170 + SmallFont.StringWidth(Stringtable.Localize("$TXT_NO")); mMouseRight = MAX(mr1, mr2); mParentMenu = parent; mMessage = SmallFont.BreakLines(message, 300); From 129787546df64e12ef3e1be805dc69bf76236e59 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Feb 2017 10:46:53 +0100 Subject: [PATCH 3/3] - transitioned the Conversation menu from FBrokenLines to DBrokenLines so that the internal representation matches scriptable types. --- src/p_conversation.cpp | 46 ++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index ae120182ce..9dc0d4ae60 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -711,6 +711,28 @@ static void SendConversationReply(int node, int reply) StaticLastReply = reply; } + +// Needed for the conversion process. +class DBrokenLines : public DObject +{ + DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject) + +public: + FBrokenLines *mBroken; + unsigned int mCount; + + DBrokenLines(FBrokenLines *broken, unsigned int count) + { + mBroken = broken; + mCount = count; + } + + void OnDestroy() override + { + V_FreeBrokenLines(mBroken); + } +}; + //============================================================================ // // The conversation menu @@ -723,7 +745,7 @@ class DConversationMenu : public DMenu public: FString mSpeaker; - FBrokenLines *mDialogueLines; + DBrokenLines *mDialogueLines; TArray mResponseLines; TArray mResponses; bool mShowGold; @@ -770,7 +792,10 @@ public: { toSay = "."; } - mDialogueLines = V_BreakLines (SmallFont, screen->GetWidth()/CleanXfac - 24*2, toSay); + unsigned int count; + auto bl = V_BreakLines (SmallFont, screen->GetWidth()/CleanXfac - 24*2, toSay, true, &count); + mDialogueLines = new DBrokenLines(bl, count); + mSelection = -1; FStrifeDialogueReply *reply; @@ -833,11 +858,8 @@ public: mResponseLines.Push(FString(goodbyestr)); // Determine where the top of the reply list should be positioned. - i = OptionSettings.mLinespacing; - mYpos = MIN (140, 192 - mResponseLines.Size() * i); - for (i = 0; mDialogueLines[i].Width >= 0; ++i) - { } - i = 44 + i * 10; + mYpos = MIN (140, 192 - mResponseLines.Size() * OptionSettings.mLinespacing); + i = 44 + count * (OptionSettings.mLinespacing + 2); if (mYpos - 100 < i - screen->GetHeight() / CleanYfac / 2) { mYpos = i - screen->GetHeight() / CleanYfac / 2 + 100; @@ -861,7 +883,7 @@ public: void OnDestroy() override { - V_FreeBrokenLines(mDialogueLines); + mDialogueLines->Destroy(); mDialogueLines = NULL; I_SetMusicVolume (1.f); Super::OnDestroy(); @@ -1055,9 +1077,7 @@ public: // Dim the screen behind the dialogue (but only if there is no backdrop). if (!CurNode->Backdrop.isValid()) { - int i; - for (i = 0; mDialogueLines[i].Width >= 0; ++i) - { } + int i = mDialogueLines->mCount; screen->Dim (0, 0.45f, 14 * screen->GetWidth() / 320, 13 * screen->GetHeight() / 200, 308 * screen->GetWidth() / 320 - 14 * screen->GetWidth () / 320, speakerName == NULL ? linesize * i + 6 * CleanYfac @@ -1078,9 +1098,9 @@ public: y += linesize * 3 / 2; } x = 24 * screen->GetWidth() / 320; - for (int i = 0; mDialogueLines[i].Width >= 0; ++i) + for (int i = 0; i < mDialogueLines->mCount; ++i) { - screen->DrawText (SmallFont, CR_UNTRANSLATED, x, y, mDialogueLines[i].Text, + screen->DrawText (SmallFont, CR_UNTRANSLATED, x, y, mDialogueLines->mBroken[i].Text, DTA_CleanNoMove, true, TAG_DONE); y += linesize; }