From 2523c9c11e2d2c6ccbf89e7e21c2bf306a3a08d2 Mon Sep 17 00:00:00 2001 From: divverent Date: Sat, 4 Apr 2009 15:05:38 +0000 Subject: [PATCH] a nice improvement to the loading plaque: displaying the name of what's being loaded git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8855 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_screen.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ gl_backend.h | 2 -- model_shared.c | 31 +++++++++++++++++-- screen.h | 7 +++++ 4 files changed, 119 insertions(+), 4 deletions(-) diff --git a/cl_screen.c b/cl_screen.c index e9fd17ac..98fc38ff 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -1609,12 +1609,91 @@ void SCR_DrawScreen (void) R_Mesh_Finish(); } +typedef struct loadingscreenstack_s +{ + struct loadingscreenstack_s *prev; + char msg[MAX_QPATH]; + float absolute_loading_amount_min; // this corresponds to relative completion 0 of this item + float absolute_loading_amount_len; // this corresponds to relative completion 1 of this item + float relative_completion; // 0 .. 1 +} +loadingscreenstack_t; +static loadingscreenstack_t *loadingscreenstack = NULL; + +void SCR_PushLoadingScreen (const char *msg, float len_in_parent) +{ + loadingscreenstack_t *s = (loadingscreenstack_t *) Z_Malloc(sizeof(loadingscreenstack_t)); + s->prev = loadingscreenstack; + loadingscreenstack = s; + + strlcpy(s->msg, msg, sizeof(s->msg)); + s->relative_completion = 0; + + if(s->prev) + { + s->absolute_loading_amount_min = s->prev->absolute_loading_amount_min + s->prev->absolute_loading_amount_len * s->prev->relative_completion; + s->absolute_loading_amount_len = s->prev->absolute_loading_amount_len * len_in_parent; + } + else + { + s->absolute_loading_amount_min = 0; + s->absolute_loading_amount_len = 1; + } + + SCR_UpdateLoadingScreen(true); +} + +void SCR_PopLoadingScreen () +{ + loadingscreenstack_t *s = loadingscreenstack; + loadingscreenstack = s->prev; + if(s->prev) + s->prev->relative_completion = (s->absolute_loading_amount_min + s->absolute_loading_amount_len - s->prev->absolute_loading_amount_min) / s->prev->absolute_loading_amount_len; + Z_Free(s); + SCR_UpdateLoadingScreen(true); +} + +static float SCR_DrawLoadingStack_r(loadingscreenstack_t *s, float y) +{ + float size = 8; + float x; + size_t len; + float total; + + total = 0; + if(s) + { + if(!s->prev || strcmp(s->msg, s->prev->msg)) + { + len = strlen(s->msg); + x = (vid_conwidth.integer - DrawQ_TextWidth_Font(s->msg, len, true, FONT_INFOBAR) * size) / 2; + y -= size; + DrawQ_String_Font(x, y, s->msg, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR); + total += size; + } + total += SCR_DrawLoadingStack_r(s->prev, y); + } + return total; +} + +static void SCR_DrawLoadingStack() +{ + float height; + height = SCR_DrawLoadingStack_r(loadingscreenstack, vid_conheight.integer); + if(loadingscreenstack) + { + height = 32; // sorry, using the normal one is ugly + DrawQ_Fill((vid_conwidth.integer + 2) * loadingscreenstack->absolute_loading_amount_min - 2, vid_conheight.integer - height, 2, height, 1, 0, 0, 1, DRAWFLAG_ADDITIVE); + } +} + void SCR_UpdateLoadingScreen (qboolean clear) { float x, y; cachepic_t *pic; float vertex3f[12]; float texcoord2f[8]; + // don't do anything if not initialized yet if (vid_hidden || !scr_refresh.integer) return; @@ -1662,17 +1741,21 @@ void SCR_UpdateLoadingScreen (qboolean clear) texcoord2f[2] = 1;texcoord2f[3] = 0; texcoord2f[4] = 1;texcoord2f[5] = 1; texcoord2f[6] = 0;texcoord2f[7] = 1; + if (vid.stereobuffer) { qglDrawBuffer(GL_FRONT_LEFT); R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); + SCR_DrawLoadingStack(); qglDrawBuffer(GL_FRONT_RIGHT); R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); + SCR_DrawLoadingStack(); } else { qglDrawBuffer(GL_FRONT); R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); + SCR_DrawLoadingStack(); } R_Mesh_Finish(); // refresh diff --git a/gl_backend.h b/gl_backend.h index 5ecff60f..3feb0230 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -120,8 +120,6 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, unsigned char *buffer3, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean gammacorrect); // used by R_Envmap_f and internally in backend, clears the frame void R_ClearScreen(qboolean fogcolor); -// invoke refresh of loading plaque (nothing else seen) -void SCR_UpdateLoadingScreen(qboolean clear); #endif diff --git a/model_shared.c b/model_shared.c index c8cbc433..3e48438f 100644 --- a/model_shared.c +++ b/model_shared.c @@ -50,14 +50,25 @@ static q3shader_data_t* q3shader_data; static void mod_start(void) { - int i; + int i, count; int nummodels = Mem_ExpandableArray_IndexRange(&models); dp_model_t *mod; + SCR_PushLoadingScreen("Loading models", 1.0); + count = 0; + for (i = 0;i < nummodels;i++) + if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*') + if (mod->used) + ++count; for (i = 0;i < nummodels;i++) if ((mod = (dp_model_t*) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*') if (mod->used) + { + SCR_PushLoadingScreen(mod->name, 1.0 / count); Mod_LoadModel(mod, true, false); + SCR_PopLoadingScreen(); + } + SCR_PopLoadingScreen(); } static void mod_shutdown(void) @@ -264,6 +275,8 @@ dp_model_t *Mod_LoadModel(dp_model_t *mod, qboolean crash, qboolean checkdisk) if (developer_loading.integer) Con_Printf("loading model %s\n", mod->name); + + SCR_PushLoadingScreen(mod->name, 1); // LordHavoc: unload the existing model in this slot (if there is one) if (mod->loaded || mod->mempool) @@ -325,6 +338,9 @@ dp_model_t *Mod_LoadModel(dp_model_t *mod, qboolean crash, qboolean checkdisk) // LordHavoc: Sys_Error was *ANNOYING* Con_Printf ("Mod_LoadModel: %s not found\n", mod->name); } + + SCR_PopLoadingScreen(); + return mod; } @@ -423,12 +439,23 @@ Reloads all models if they have changed */ void Mod_Reload(void) { - int i; + int i, count; int nummodels = Mem_ExpandableArray_IndexRange(&models); dp_model_t *mod; + + SCR_PushLoadingScreen("Reloading models", 1.0); + count = 0; for (i = 0;i < nummodels;i++) if ((mod = (dp_model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used) + ++count; + for (i = 0;i < nummodels;i++) + if ((mod = (dp_model_t *) Mem_ExpandableArray_RecordAtIndex(&models, i)) && mod->name[0] && mod->name[0] != '*' && mod->used) + { + SCR_PushLoadingScreen(mod->name, 1.0 / count); Mod_LoadModel(mod, true, true); + SCR_PopLoadingScreen(); + } + SCR_PopLoadingScreen(); } unsigned char *mod_base; diff --git a/screen.h b/screen.h index 5feeed44..db78cbe5 100644 --- a/screen.h +++ b/screen.h @@ -28,6 +28,13 @@ void SCR_CenterPrint(const char *str); void SCR_BeginLoadingPlaque (void); +// invoke refresh of loading plaque (nothing else seen) +void SCR_UpdateLoadingScreen(qboolean clear); + +// pushes an item on the loading screen +void SCR_PushLoadingScreen (const char *msg, float len_in_parent); +void SCR_PopLoadingScreen (); + extern float scr_con_current; // current height of displayed console extern int sb_lines; -- 2.39.2