From 99f458dafa10e96c671159b74f9cefa9b795ee34 Mon Sep 17 00:00:00 2001 From: Andrei Prykhodko Date: Sat, 21 Jul 2018 12:14:03 +0300 Subject: GRAPHICS: MACMENU: added menu parser from Win32 PE executable --- graphics/macgui/macmenu.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++ graphics/macgui/macmenu.h | 2 ++ 2 files changed, 57 insertions(+) diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp index 0228798e38..c52a421f81 100644 --- a/graphics/macgui/macmenu.cpp +++ b/graphics/macgui/macmenu.cpp @@ -56,6 +56,15 @@ enum { kFontStyleExtended = 64 }; +enum { + kGrayed = 1, + kInactive = 2, + kPopUp = 16, + kMenuBarBreak = 32, + kMenuBreak = 64, + kEndMenu = 128, +}; + struct MacMenuSubItem { Common::String text; Common::U32String unicodeText; @@ -162,6 +171,52 @@ Common::StringArray *MacMenu::readMenuFromResource(Common::SeekableReadStream *r return result; } +static Common::U32String readUnicodeString(Common::SeekableReadStream *stream) { + Common::Array strData; + uint16 wchar; + while ((wchar = stream->readUint16LE()) != '\0') { + strData.push_back(wchar); + } + return strData.empty() ? Common::U32String() : Common::U32String(strData.data(), strData.size()); +} + + +MacMenu *MacMenu::createMenuFromPEexe(Common::PEResources &exe, MacWindowManager *wm) { + Common::SeekableReadStream *menuData = exe.getResource(Common::kPEMenu, 128); + if (!menuData) + return nullptr; + + menuData->readUint16LE(); // wVersion + menuData->readUint16LE(); // cbHeaderSize + + MacMenu *menu = wm->addMenu(); + + int depth = 0; + int curMenuItemId = 0; + while (depth >= 0) { + uint16 flags = menuData->readUint16LE(); + if (flags & kPopUp) { + if (depth == 0) { + menu->addMenuItem(readUnicodeString(menuData)); + } else { + // TODO + // for now skip + readUnicodeString(menuData); + } + if (!(flags & kEndMenu)) { + depth++; + } + } else { + menuData->readUint16LE(); // menu id + menu->addMenuSubItem(curMenuItemId, readUnicodeString(menuData), 0); + if (flags & kEndMenu) { + depth--; + } + } + } + return menu; +} + void MacMenu::addStaticMenus(const MacMenuData *data) { MacMenuItem *about = new MacMenuItem(_wm->_fontMan->hasBuiltInFonts() ? "\xa9" : "\xf0"); // (c) Symbol as the most resembling apple _items.push_back(about); diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h index b9d8e0125b..36cd06a2ff 100644 --- a/graphics/macgui/macmenu.h +++ b/graphics/macgui/macmenu.h @@ -24,6 +24,7 @@ #define GRAPHICS_MACGUI_MACMENU_H #include "common/str-array.h" +#include "common/winexe_pe.h" namespace Common { class U32String; @@ -48,6 +49,7 @@ public: ~MacMenu(); static Common::StringArray *readMenuFromResource(Common::SeekableReadStream *res); + static MacMenu *createMenuFromPEexe(Common::PEResources &exe, MacWindowManager *wm); void setCommandsCallback(void (*callback)(int, Common::String &, void *), void *data) { _ccallback = callback; _cdata = data; } void setCommandsCallback(void (*callback)(int, Common::U32String &, void *), void *data) { _unicodeccallback = callback; _cdata = data; } -- cgit v1.2.3