diff options
author | Andrey Nazarov <skuller@skuller.net> | 2013-04-05 18:59:12 +0400 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2013-04-05 19:00:46 +0400 |
commit | 303545aa555395813a864e6e6987d13c16355e13 (patch) | |
tree | 0c833d170c6547fb1189ef23b5839835be0a22da /src | |
parent | b39f8ea8ba472f5f44747be38091b341cb19d425 (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.c | 129 |
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); } - - |