-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)
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;
this.team = gteamplay;
this.model2 = defaults;
this.gametype_description = gdescription;
- return this;
}
ENDCLASS(Gametype)
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;
[[last]] INIT(cname) { return this; }
#define SUPER(cname) (cname##_vtbl.vtblbase)
+#define super (this.vtblbase.vtblbase)
#define spawn_static(this)
#define spawn_1(this)
#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"
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
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();
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()));