summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2013-04-05 18:59:12 +0400
committerAndrey Nazarov <skuller@skuller.net>2013-04-05 19:00:46 +0400
commit303545aa555395813a864e6e6987d13c16355e13 (patch)
tree0c833d170c6547fb1189ef23b5839835be0a22da /src
parentb39f8ea8ba472f5f44747be38091b341cb19d425 (diff)
Clean up and fix demo browser menu.
Don't list ‘..’ entry in the root directory. Fix crash when there are no demo entries in list. Check that initial browsing directory actually exists before opening menu.
Diffstat (limited to 'src')
-rw-r--r--src/client/ui/demos.c129
1 files changed, 84 insertions, 45 deletions
diff --git a/src/client/ui/demos.c b/src/client/ui/demos.c
index 8ec2866..8c4d1eb 100644
--- a/src/client/ui/demos.c
+++ b/src/client/ui/demos.c
@@ -47,10 +47,10 @@ DEMOS MENU
#define COL_MAX 5
typedef struct {
- unsigned type;
- size_t size;
- time_t mtime;
- char name[1];
+ unsigned type;
+ size_t size;
+ time_t mtime;
+ char name[1];
} demoEntry_t;
typedef struct m_demos_s {
@@ -250,8 +250,14 @@ static void CalcHash(void **list)
static menuSound_t Change(menuCommon_t *self)
{
- demoEntry_t *e = m_demos.list.items[m_demos.list.curvalue];
+ demoEntry_t *e;
+
+ if (!m_demos.list.numItems) {
+ m_demos.menu.status = "No demos found";
+ return QMS_BEEP;
+ }
+ e = m_demos.list.items[m_demos.list.curvalue];
switch (e->type) {
case ENTRY_DEMO:
m_demos.menu.status = "Press Enter to play demo";
@@ -260,6 +266,7 @@ static menuSound_t Change(menuCommon_t *self)
m_demos.menu.status = "Press Enter to change directory";
break;
}
+
return QMS_SILENT;
}
@@ -274,6 +281,7 @@ static void BuildList(void)
// this can be a lengthy process
S_StopAllSounds();
+
m_demos.menu.status = "Building list...";
SCR_UpdateScreen();
@@ -297,7 +305,7 @@ static void BuildList(void)
// start with minimum size
m_demos.menu.size(&m_demos.menu);
- if (m_demos.browse[0]) {
+ if (strcmp(m_demos.browse, "/")) {
BuildDir("..", ENTRY_UP);
}
@@ -334,11 +342,9 @@ static void BuildList(void)
}
// update status line and sort
- if (m_demos.list.numItems) {
- Change(&m_demos.list.generic);
- if (m_demos.list.sortdir) {
- m_demos.list.sort(&m_demos.list);
- }
+ Change(&m_demos.list.generic);
+ if (m_demos.list.sortdir) {
+ m_demos.list.sort(&m_demos.list);
}
// resize columns
@@ -368,16 +374,21 @@ static void FreeList(void)
}
}
-static void LeaveDirectory(void)
+static menuSound_t LeaveDirectory(void)
{
- char *s;
- int i;
+ char *s;
+ int i;
s = strrchr(m_demos.browse, '/');
if (!s) {
- return;
+ return QMS_BEEP;
+ }
+
+ if (s == m_demos.browse) {
+ strcpy(m_demos.browse, "/");
+ } else {
+ *s = 0;
}
- *s = 0;
// rebuild list
FreeList();
@@ -393,43 +404,64 @@ static void LeaveDirectory(void)
}
}
- if (s == m_demos.browse) {
- m_demos.browse[0] = '/';
- m_demos.browse[1] = 0;
+ return QMS_OUT;
+}
+
+static menuSound_t EnterDirectory(demoEntry_t *e)
+{
+ size_t baselen, len;
+
+ baselen = strlen(m_demos.browse);
+ len = strlen(e->name);
+ if (baselen + 1 + len >= sizeof(m_demos.browse)) {
+ return QMS_BEEP;
+ }
+
+ if (baselen == 0 || m_demos.browse[baselen - 1] != '/') {
+ m_demos.browse[baselen++] = '/';
+ }
+
+ memcpy(m_demos.browse + baselen, e->name, len + 1);
+
+ // rebuild list
+ FreeList();
+ BuildList();
+ MenuList_Init(&m_demos.list);
+ return QMS_IN;
+}
+
+static menuSound_t PlayDemo(demoEntry_t *e)
+{
+ char buffer[MAX_STRING_CHARS];
+ size_t len;
+
+ len = Q_snprintf(buffer, sizeof(buffer), "demo \"%s/%s\"\n",
+ strcmp(m_demos.browse, "/") ? m_demos.browse : "",
+ e->name);
+ if (len >= sizeof(buffer)) {
+ return QMS_BEEP;
}
+
+ Cbuf_AddText(&cmd_buffer, buffer);
+ return QMS_SILENT;
}
static menuSound_t Activate(menuCommon_t *self)
{
- size_t len, baselen;
- demoEntry_t *e = m_demos.list.items[m_demos.list.curvalue];
+ demoEntry_t *e;
+ if (!m_demos.list.numItems) {
+ return QMS_BEEP;
+ }
+
+ e = m_demos.list.items[m_demos.list.curvalue];
switch (e->type) {
case ENTRY_UP:
- LeaveDirectory();
- return QMS_OUT;
-
+ return LeaveDirectory();
case ENTRY_DN:
- baselen = strlen(m_demos.browse);
- len = strlen(e->name);
- if (baselen + 1 + len >= sizeof(m_demos.browse)) {
- return QMS_BEEP;
- }
- if (!baselen || m_demos.browse[baselen - 1] != '/') {
- m_demos.browse[baselen++] = '/';
- }
- memcpy(m_demos.browse + baselen, e->name, len + 1);
-
- // rebuild list
- FreeList();
- BuildList();
- MenuList_Init(&m_demos.list);
- return QMS_IN;
-
+ return EnterDirectory(e);
case ENTRY_DEMO:
- Cbuf_AddText(&cmd_buffer, va("demo \"%s/%s\"\n", m_demos.browse[1] ?
- m_demos.browse : "", e->name));
- return QMS_SILENT;
+ return PlayDemo(e);
}
return QMS_NOTHANDLED;
@@ -529,6 +561,7 @@ static menuSound_t Keydown(menuFrameWork_t *self, int key)
LeaveDirectory();
return QMS_OUT;
}
+
return QMS_NOTHANDLED;
}
@@ -557,7 +590,15 @@ static void Expose(menuFrameWork_t *self)
m_demos.year = tm->tm_year;
}
+ // check that target directory exists
+ if (strcmp(m_demos.browse, "/")
+ && ui_listalldemos->integer == 0
+ && os_access(va("%s%s", fs_gamedir, m_demos.browse), F_OK)) {
+ strcpy(m_demos.browse, "/");
+ }
+
BuildList();
+
// move cursor to previous position
MenuList_SetValue(&m_demos.list, m_demos.selection);
}
@@ -640,5 +681,3 @@ void M_Menu_Demos(void)
List_Append(&ui_menus, &m_demos.menu.entry);
}
-
-