]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Initial guide menu
authorTimePath <andrew.hardaker1995@gmail.com>
Sun, 16 Aug 2015 04:32:29 +0000 (14:32 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sun, 16 Aug 2015 08:04:40 +0000 (18:04 +1000)
qcsrc/Makefile
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/common/oo.qh
qcsrc/menu/classes.inc
qcsrc/menu/xonotic/dialog_media_guide.qc [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_media_guide_entries.qc [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_media_guide_topics.qc [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_multiplayer_media.qc

index f53707e829f482c39e0f6dcdee0c54d54d4aa3c1..7ac264f943c05c6888ed746262b593e4a242c9a2 100644 (file)
@@ -13,7 +13,7 @@ QCCFLAGS ?= \
        -std=gmqcc \
        -O3 -flno \
        -Werror -fno-bail-on-werror -Wall \
-       -fftepp -fftepp-predefs -Wcpp -futf8 \
+       -fftepp -fftepp-predefs -Wcpp -futf8 -freturn-assignments \
        $(QCCFLAGS_WTFS) \
        $(QCCFLAGS_FEATURES) \
        $(QCCFLAGS_EXTRA) $(QCCFLAGS_WATERMARK)
index 0b851d53b0c5299c7625055d6f470f7925b90564..da45a491c7fd4e4ed42364b48586ce2889b61cf9 100644 (file)
@@ -252,11 +252,9 @@ string unquote(string s)
        return "";
 }
 
-float MapInfo_Get_ByID(float i)
+bool MapInfo_Get_ByID(int i)
 {
-       if(MapInfo_Get_ByName(MapInfo_BSPName_ByID(i), 0, 0))
-               return 1;
-       return 0;
+       return MapInfo_Get_ByName(MapInfo_BSPName_ByID(i), 0, 0) ? true : false;
 }
 
 string _MapInfo_Map_worldspawn_music;
index 22b17d900de78e4e4fb451363d27fd29360e00c8..f2f5b5c2837a963ae3d5110e7a70b42c429c134b 100644 (file)
@@ -28,7 +28,6 @@ CLASS(Gametype, Object)
         this.team = gteamplay;
         this.model2 = defaults;
         this.gametype_description = gdescription;
-        return this;
     }
 ENDCLASS(Gametype)
 
index aa660ab15d96de375fd87d11c374d6088840ec48..48511b393c70cfff57b76fa29ddf27b0d852e653 100644 (file)
@@ -47,7 +47,8 @@ entity __spawn(string _classname, string _sourceFile, int _sourceLine) {
     OVERLOAD(spawn##cname, this, ##__VA_ARGS__)
 
 #define CONSTRUCTOR(cname, ...) \
-    cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
+    cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) { return = this; } \
+    [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
 
 .string vtblname;
 .entity vtblbase;
@@ -110,6 +111,7 @@ ACCUMULATE_FUNCTION(__static_init, RegisterClasses)
     [[last]] INIT(cname) { return this; }
 
 #define SUPER(cname) (cname##_vtbl.vtblbase)
+#define super (this.vtblbase.vtblbase)
 
 #define spawn_static(this)
 #define spawn_1(this)
index 01a7c8a040f47526e09ee027a125068acacb78ef..2e86017f9f7f0ee6028b8e4326409d3b5ad557eb 100644 (file)
@@ -60,6 +60,9 @@
 #include "xonotic/dialog_hudpanel_vote.qc"
 #include "xonotic/dialog_hudpanel_weapons.qc"
 #include "xonotic/dialog_hudsetup_exit.qc"
+#include "xonotic/dialog_media_guide.qc"
+#include "xonotic/dialog_media_guide_entries.qc"
+#include "xonotic/dialog_media_guide_topics.qc"
 #include "xonotic/dialog_monstertools.qc"
 #include "xonotic/dialog_multiplayer.qc"
 #include "xonotic/dialog_multiplayer_create.qc"
diff --git a/qcsrc/menu/xonotic/dialog_media_guide.qc b/qcsrc/menu/xonotic/dialog_media_guide.qc
new file mode 100644 (file)
index 0000000..b5179de
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef DIALOG_MEDIA_GUIDE_H
+#define DIALOG_MEDIA_GUIDE_H
+#include "dialog_media_guide_topics.qc"
+#include "dialog_media_guide_entries.qc"
+#include "tab.qc"
+CLASS(XonoticGuideTab, XonoticTab)
+    ATTRIB(XonoticGuideTab, rows, float, 21)
+    ATTRIB(XonoticGuideTab, columns, float, 6)
+    METHOD(XonoticGuideTab, fill, void(entity))
+    METHOD(XonoticGuideTab, topicChangeNotify, void(entity))
+    METHOD(XonoticGuideTab, topicSelectNotify, void(entity))
+
+       entity Topics_get(int i);
+       int Topics_reload(string filter);
+       .string mdl, message;
+    ATTRIB(XonoticGuideTab, topicList, entity, NEW(XonoticTopicList, Topics_get, func_null, Topics_reload, mdl, message, func_null, this))
+
+    entity XonoticGuideTab_maps_get(int i);
+    int XonoticGuideTab_maps_indexOf(string s);
+    int XonoticGuideTab_maps_reload(string s);
+    void XonoticGuideTab_maps_destroy(entity this);
+    .string icon, name;
+    ATTRIB(XonoticGuideTab, entryList, entity, NEW(XonoticEntryList, XonoticGuideTab_maps_get, XonoticGuideTab_maps_indexOf, XonoticGuideTab_maps_reload, icon, name, XonoticGuideTab_maps_destroy))
+
+    INIT(XonoticGuideTab) {
+       this.topicList.entryIconPrefix = "gametype_";
+        this.configureDialog(this);
+    }
+ENDCLASS(XonoticGuideTab)
+#endif
+
+#ifdef IMPLEMENTATION
+
+void XonoticGuideTab_fill(entity this)
+{
+    entity topics = this.topicList;
+    entity entries = this.entryList;
+    entity filter = entries.stringFilterBox = makeXonoticInputBox(false, string_null);
+        filter.keyDown = MapList_StringFilterBox_keyDown;
+        filter.onChange = MapList_StringFilterBox_Change;
+        filter.onChangeEntity = entries;
+    entries.controlledTextbox = filter;
+
+    this.gotoRC(this, 0, 0);
+        this.TD(this, 1, 3 / 2, makeXonoticHeaderLabel(_("Topic")));
+    this.TR(this);
+        this.TD(this, this.rows - 1, 3 / 2, topics);
+
+    this.gotoRC(this, 0, 3 / 2);
+        this.setFirstColumn(this, this.currentColumn);
+        this.TD(this, 1, 2, makeXonoticHeaderLabel(_("Entry")));
+    this.TR(this);
+        this.TD(this, this.rows - 1 - 1, 2, entries);
+
+    this.gotoRC(this, this.rows - 1, this.firstColumn);
+        this.TD(this, 1, 0.3, makeXonoticTextLabel(0, _("Filter:")));
+        this.TD(this, 1, 2 - 0.3, filter);
+
+    this.topicChangeNotify(this);
+}
+
+void XonoticGuideTab_topicChangeNotify(entity this)
+{
+    entity entries = this.entryList;
+    entries.refilter(entries);
+}
+
+void XonoticGuideTab_topicSelectNotify(entity this) { this.setFocus(this, this.entryList); }
+
+entity Topics_get(int i) { return MAPINFO_TYPES[i]; }
+
+int Topics_reload(string filter) { return MAPINFO_TYPE_COUNT; }
+
+entity XonoticGuideTab_maps_get(int i)
+{
+    if (!MapInfo_Get_ByID(i)) return NULL;
+    static entity e;
+    if (!e) e = new(entry);
+    e.name = MapInfo_Map_titlestring;
+    string path = strcat("/maps/", MapInfo_Map_bspname);
+    string img = draw_PictureSize(path) ? path : "nopreview_map";
+    e.icon = img;
+    MapInfo_ClearTemps();
+    return e;
+}
+
+int XonoticGuideTab_maps_indexOf(string s)
+{
+    MapInfo_FindName(s);
+    return MapInfo_FindName_firstResult;
+}
+
+int XonoticGuideTab_maps_reload(string s)
+{
+    MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 0, 0, 0);
+    if (s) MapInfo_FilterString(s);
+    return MapInfo_count;
+}
+
+void XonoticGuideTab_maps_destroy(entity this) { MapInfo_Shutdown(); }
+
+#endif
diff --git a/qcsrc/menu/xonotic/dialog_media_guide_entries.qc b/qcsrc/menu/xonotic/dialog_media_guide_entries.qc
new file mode 100644 (file)
index 0000000..e7498b3
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef DIALOG_MEDIA_GUIDE_ENTRIES_H
+#define DIALOG_MEDIA_GUIDE_ENTRIES_H
+#include "listbox.qc"
+CLASS(XonoticEntryList, XonoticListBox)
+    ATTRIB(XonoticEntryList, alphaBG, float, 0)
+    ATTRIB(XonoticEntryList, columnNameOrigin, float, 0)
+    ATTRIB(XonoticEntryList, columnNameSize, float, 0)
+    ATTRIB(XonoticEntryList, columnPreviewOrigin, float, 0)
+    ATTRIB(XonoticEntryList, columnPreviewSize, float, 0)
+    ATTRIB(XonoticEntryList, itemAbsSize, vector, '0 0 0')
+    ATTRIB(XonoticEntryList, origin, vector, '0 0 0')
+    ATTRIB(XonoticEntryList, realFontSize, vector, '0 0 0')
+    ATTRIB(XonoticEntryList, realUpperMargin1, float, 0)
+    ATTRIB(XonoticEntryList, realUpperMargin2, float, 0)
+    ATTRIB(XonoticEntryList, rowsPerItem, float, 4)
+    ATTRIB(XonoticEntryList, stringFilterBox, entity, NULL)
+    ATTRIB(XonoticEntryList, stringFilter, string, string_null)
+    ATTRIB(XonoticEntryList, typeToSearchString, string, string_null)
+    ATTRIB(XonoticEntryList, typeToSearchTime, float, 0)
+
+    METHOD(XonoticEntryList, drawListBoxItem, void(entity, int, vector, bool, bool))
+    METHOD(XonoticEntryList, keyDown, float(entity, float, float, float))
+    METHOD(XonoticEntryList, refilter, void(entity))
+    METHOD(XonoticEntryList, resizeNotify, void(entity, vector, vector, vector, vector))
+
+    INIT(XonoticEntryList) {
+        this.configureXonoticListBox(this);
+    }
+
+    .string stringfield_null;
+    ATTRIB(XonoticEntryList, destroy, void(entity), func_null)
+    ATTRIB(XonoticEntryList, entries, void(int), func_null)
+    ATTRIB(XonoticEntryList, entryIcon, .string, stringfield_null)
+    ATTRIB(XonoticEntryList, entryName, .string, stringfield_null)
+    ATTRIB(XonoticEntryList, indexOf, int(string), func_null)
+    ATTRIB(XonoticEntryList, reload, int(string), func_null)
+
+    CONSTRUCTOR(XonoticEntryList, entity _entries(int), int _indexOf(string), int _reload(string), .string _entryIcon, .string _entryName, void _destroy(entity)) {
+        CONSTRUCT(XonoticEntryList);
+        this.entries = _entries;
+        this.indexOf = _indexOf;
+        this.reload = _reload;
+        this.entryIcon = _entryIcon;
+        this.entryName = _entryName;
+        this.destroy = _destroy;
+        this.refilter(this);
+    }
+
+ENDCLASS(XonoticEntryList)
+#endif
+
+#ifdef IMPLEMENTATION
+
+void XonoticEntryList_drawListBoxItem(entity this, int i, vector absSize, bool isSelected, bool isFocused)
+{
+    entity e = this.entries(i);
+    if (!e) return;
+
+    if (isSelected) {
+        draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+    } else if (isFocused) {
+        this.focusedItemAlpha = getFadedAlpha(this.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+        draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, this.focusedItemAlpha);
+    }
+    string s = draw_TextShortenToWidth(strdecolorize(e.name), this.columnNameSize, 0, this.realFontSize);
+    draw_Picture(this.columnPreviewOrigin * eX, e.icon, this.columnPreviewSize * eX + eY, '1 1 1', SKINALPHA_LISTBOX_SELECTED);
+    draw_Text(this.realUpperMargin1 * eY + (this.columnNameOrigin + 0.00 * (this.columnNameSize - draw_TextWidth(s, 0, this.realFontSize))) * eX, s, this.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+}
+
+float XonoticEntryList_keyDown(entity this, float scan, float ascii, float shift)
+{
+    if (this.nItems <= 0) {
+        return super.keyDown(this, scan, ascii, shift);
+    } else if (scan == K_BACKSPACE) {
+        if (time < this.typeToSearchTime) {
+            string save = substring(this.typeToSearchString, 0, strlen(this.typeToSearchString) - 1);
+            if (this.typeToSearchString) strunzone(this.typeToSearchString);
+            this.typeToSearchString = strzone(save);
+            this.typeToSearchTime = time + 0.5;
+            if (strlen(this.typeToSearchString)) {
+                int idx = this.indexOf(this.typeToSearchString);
+                if (idx >= 0) this.setSelected(this, idx);
+            }
+        }
+    } else if (ascii >= 32 && ascii != 127) {
+        string ch = chr(ascii);
+        string save = (time > this.typeToSearchTime) ? ch : strcat(this.typeToSearchString, ch);
+        if (this.typeToSearchString) strunzone(this.typeToSearchString);
+        this.typeToSearchString = strzone(save);
+        this.typeToSearchTime = time + 0.5;
+        int idx = this.indexOf(this.typeToSearchString);
+        if (idx >= 0) this.setSelected(this, idx);
+    } else if (shift & S_CTRL && scan == 'f') {
+        this.parent.setFocus(this.parent, this.stringFilterBox);
+    } else if (shift & S_CTRL && scan == 'u') {
+        this.stringFilterBox.setText(this.stringFilterBox, "");
+        if (this.stringFilter) strunzone(this.stringFilter);
+        this.stringFilter = string_null;
+        this.refilter(this);
+    }
+    return super.keyDown(this, scan, ascii, shift);
+}
+
+void XonoticEntryList_refilter(entity this)
+{
+    this.nItems = this.reload(this.stringFilter);
+    for (int i = 0, n = this.nItems; i < n; ++i) {
+        draw_PreloadPicture(this.entries(i).icon);
+    }
+}
+
+void XonoticEntryList_resizeNotify(entity this, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
+{
+    this.itemAbsSize = '0 0 0';
+    super.resizeNotify(this, relOrigin, relSize, absOrigin, absSize);
+
+    this.realFontSize_y = this.fontSize / (this.itemAbsSize_y = (absSize.y * this.itemHeight));
+    this.realFontSize_x = this.fontSize / (this.itemAbsSize_x = (absSize.x * (1 - this.controlWidth)));
+    this.realUpperMargin1 = 0.5 * (1 - 2.5 * this.realFontSize.y);
+    this.realUpperMargin2 = this.realUpperMargin1 + 1.5 * this.realFontSize.y;
+
+    this.columnPreviewOrigin = 0;
+    this.columnPreviewSize = this.itemAbsSize.y / this.itemAbsSize.x * 4 / 3;
+    this.columnNameOrigin = this.columnPreviewOrigin + this.columnPreviewSize + this.realFontSize.x;
+    this.columnNameSize = 1 - this.columnPreviewSize - 2 * this.realFontSize.x;
+}
+#endif
diff --git a/qcsrc/menu/xonotic/dialog_media_guide_topics.qc b/qcsrc/menu/xonotic/dialog_media_guide_topics.qc
new file mode 100644 (file)
index 0000000..5624216
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef DIALOG_MEDIA_GUIDE_TOPICS_H
+#define DIALOG_MEDIA_GUIDE_TOPICS_H
+#include "listbox.qc"
+CLASS(XonoticTopicList, XonoticListBox)
+    ATTRIB(XonoticTopicList, columnIconOrigin, float, 0)
+    ATTRIB(XonoticTopicList, columnIconSize, float, 0)
+    ATTRIB(XonoticTopicList, columnNameOrigin, float, 0)
+    ATTRIB(XonoticTopicList, columnNameSize, float, 0)
+    ATTRIB(XonoticTopicList, realFontSize, vector, '0 0 0')
+    ATTRIB(XonoticTopicList, realUpperMargin, float, 0)
+    ATTRIB(XonoticTopicList, rowsPerItem, float, 3)
+
+    METHOD(XonoticTopicList, clickListBoxItem, void(entity, float, vector))
+    METHOD(XonoticTopicList, drawListBoxItem, void(entity, int, vector, bool, bool))
+    METHOD(XonoticTopicList, keyDown, bool(entity, float, float, float))
+    METHOD(XonoticTopicList, resizeNotify, void(entity, vector, vector, vector, vector))
+    METHOD(XonoticTopicList, setSelected, void(entity, int))
+
+    INIT(XonoticTopicList) {
+        this.configureXonoticListBox(this);
+    }
+
+    .string stringfield_null;
+    ATTRIB(XonoticTopicList, entries, entity(int), func_null)
+    ATTRIB(XonoticTopicList, entryIconPrefix, string, "")
+    ATTRIB(XonoticTopicList, entryIcon, .string, stringfield_null)
+    ATTRIB(XonoticTopicList, entryName, .string, stringfield_null)
+    ATTRIB(XonoticTopicList, listener, entity, NULL)
+
+    CONSTRUCTOR(XonoticTopicList, entity(int) _entries, int _indexOf(string), int _reload(string), .string _entryIcon, .string _entryName, void _destroy(entity), entity _listener) {
+       CONSTRUCT(XonoticTopicList);
+       this.entries = _entries;
+       this.nItems = _reload("");
+       this.entryIcon = _entryIcon;
+       this.entryName = _entryName;
+       this.listener = _listener;
+    }
+ENDCLASS(XonoticTopicList)
+#endif
+
+#ifdef IMPLEMENTATION
+
+void XonoticTopicList_clickListBoxItem(entity this, float i, vector where)
+{
+    m_play_click_sound(MENU_SOUND_SELECT);
+}
+
+void XonoticTopicList_drawListBoxItem(entity this, int i, vector absSize, bool isSelected, bool isFocused)
+{
+    if (isSelected) {
+        draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+    } else if (isFocused) {
+        this.focusedItemAlpha = getFadedAlpha(this.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+        draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, this.focusedItemAlpha);
+    }
+    entity entry = this.entries(i);
+    string icon = strcat(this.entryIconPrefix, entry.(this.entryIcon));
+    string name = entry.(this.entryName);
+    draw_Picture(this.columnIconOrigin * eX, icon, this.columnIconSize * eX + eY, '1 1 1', SKINALPHA_LISTBOX_SELECTED);
+    vector save_fontscale = draw_fontscale;
+    float f = draw_CondensedFontFactor(name, false, this.realFontSize, 1);
+    draw_fontscale.x *= f;
+    vector fs = this.realFontSize;
+    fs.x *= f;
+    draw_Text(this.realUpperMargin * eY + this.columnNameOrigin * eX, name, fs, '1 1 1', SKINALPHA_TEXT, 0);
+    draw_fontscale = save_fontscale;
+}
+
+bool XonoticTopicList_keyDown(entity this, float scan, float ascii, float shift)
+{
+    if (scan == K_ENTER || scan == K_KP_ENTER) {
+        m_play_click_sound(MENU_SOUND_EXECUTE);
+        entity l = this.listener;
+        if (l) {
+               void(entity) func = l.topicSelectNotify;
+               if (func) {
+                       func(l);
+               }
+        }
+        return true;
+    }
+    return super.keyDown(this, scan, ascii, shift);
+}
+
+void XonoticTopicList_resizeNotify(entity this, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
+{
+    this.itemAbsSize = '0 0 0';
+    super.resizeNotify(this, relOrigin, relSize, absOrigin, absSize);
+
+    this.realFontSize_y = this.fontSize / (this.itemAbsSize_y = (absSize.y * this.itemHeight));
+    this.realFontSize_x = this.fontSize / (this.itemAbsSize_x = (absSize.x * (1 - this.controlWidth)));
+    this.realUpperMargin = 0.5 * (1 - this.realFontSize.y);
+    this.columnIconOrigin = 0;
+    this.columnIconSize = this.itemAbsSize.y / this.itemAbsSize.x;
+    this.columnNameOrigin = this.columnIconOrigin + this.columnIconSize + (0.5 * this.realFontSize.x);
+    this.columnNameSize = 1 - this.columnIconSize - (1.5 * this.realFontSize.x);
+}
+
+void XonoticTopicList_setSelected(entity this, int i)
+{
+    super.setSelected(this, i);
+    entity l = this.listener;
+       if (l) {
+               void(entity) func = l.topicChangeNotify;
+               if (func) {
+                       func(l);
+               }
+       }
+}
+#endif
index 03ffd0f36dc361d814707081bb8b6efd18eb9890..0000d1d608917a8e65e52c64ad1968b7a2cfacbb 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticMediaTab, XonoticTab)
        METHOD(XonoticMediaTab, fill, void(entity))
        ATTRIB(XonoticMediaTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticMediaTab, rows, float, 23)
-       ATTRIB(XonoticMediaTab, columns, float, 3)
+       ATTRIB(XonoticMediaTab, columns, float, 4)
        ATTRIB(XonoticMediaTab, name, string, "Media")
 ENDCLASS(XonoticMediaTab)
 entity makeXonoticMediaTab();
@@ -25,6 +25,7 @@ void XonoticMediaTab_fill(entity me)
        mc = makeXonoticTabController(me.rows - 2);
 
        me.gotoRC(me, 0.5, 0);
+               me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Guide"), NEW(XonoticGuideTab)));
                me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Demos"), makeXonoticDemoBrowserTab()));
                me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Screenshots"), makeXonoticScreenshotBrowserTab()));
                me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Music Player"), makeXonoticMusicPlayerTab()));