void HU_FragsDrawer() { int i, y; char tempstr[50]; if(!deathmatch) return; if(!action_frags) { if(players[displayplayer].playerstate != PST_DEAD || walkcam_active || !show_scores) return; } // "frags" V_DrawPatch(FRAGSX, FRAGSY, 0, fragspic); y = NAMEY; for(i=0; i<num_players; i++) { // write their name sprintf(tempstr, "%s%s", !demoplayback && sortedplayers[i]==players+consoleplayer ? FC_GRAY : FC_RED, sortedplayers[i]->name); V_WriteText(tempstr, NAMEX - V_StringWidth(tempstr), y); // box behind frag pic V_DrawPatchTranslated ( FRAGNUMX, y, 0, fragbox, sortedplayers[i]->colormap ? (char*)translationtables+256*(sortedplayers[i]->colormap-1) : cr_red, 13 ); // draw the frags sprintf(tempstr, "%i", sortedplayers[i]->totalfrags); V_WriteText(tempstr, FRAGNUMX + 16 - V_StringWidth(tempstr)/2, y); y += 10; } }
// // M_SaveGame & Cie. // [ML] 7 Sept 08: Bringing game saving/loading in from // zdoom 1.22 source, see MAINTAINERS // void M_DrawSave(void) { int i; if (gameinfo.gametype & GAME_Heretic) { LoadDef.y = 30; LoadDef.x = 70; screen->DrawTextLargeClean(0,160 - V_LargeStringWidth("SAVE GAME") / 2, 10,"SAVE GAME"); for (i = 0; i < load_end; i++) { M_DrawSaveLoadSlot (LoadDef.x, LoadDef.y+HTCLINEHEIGHT*i); screen->DrawTextCleanMove (CR_RED, LoadDef.x+4, LoadDef.y+HTCLINEHEIGHT*i+5, savegamestrings[i]); } } else { screen->DrawPatchClean ((patch_t *)W_CacheLumpName ("M_SAVEG",PU_CACHE), 72, 28); for (i = 0; i < load_end; i++) { M_DrawSaveLoadBorder (LoadDef.x, LoadDef.y+LINEHEIGHT*i, 24); screen->DrawTextCleanMove (CR_RED, LoadDef.x, LoadDef.y+LINEHEIGHT*i, savegamestrings[i]); } } if (genStringEnter) { i = V_StringWidth(savegamestrings[saveSlot]); screen->DrawTextCleanMove (CR_RED, LoadDef.x + i, LoadDef.y+LINEHEIGHT*saveSlot, "_"); } }
// Draw hu_font text. void DrawText(int x, int y, const float scale, const x_align_t x_align, const y_align_t y_align, const x_align_t x_origin, const y_align_t y_origin, const char* str, const int color, const bool force_opaque) { // No string? Don't bother with this function. if (!str) { return; } // Calculate width and height of string unsigned short w = V_StringWidth(str); unsigned short h = 7; // Turn our scaled coordinates into real coordinates. int x_scale, y_scale; calculateOrigin(x, y, w, h, scale, x_scale, y_scale, x_align, y_align, x_origin, y_origin); if (force_opaque) { screen->DrawTextStretched(color, x, y, str, x_scale, y_scale); } else { screen->DrawTextStretchedLuc(color, x, y, str, x_scale, y_scale); } }
static void WriteCentredText(char *message) { static char *tempbuf = NULL; static int allocedsize=0; char *rover, *addrover; int x, y; // rather than reallocate memory every time we draw it, // use one buffer and increase the size as neccesary if(strlen(message) > allocedsize) { if(tempbuf) tempbuf = Z_Realloc(tempbuf, strlen(message)+3, PU_STATIC, 0); else tempbuf = Z_Malloc(strlen(message)+3, PU_STATIC, 0); allocedsize = strlen(message); } y = (SCREENHEIGHT - V_StringHeight(popup_message)) / 2; addrover = tempbuf; rover = message; while(*rover) { if(*rover == '\n') { *addrover = '\0'; // end string x = (SCREENWIDTH - V_StringWidth(tempbuf)) / 2; V_WriteText(tempbuf, x, y); addrover = tempbuf; // reset addrover y += 7; // next line } else // add next char { *addrover = *rover; addrover++; } rover++; } // dont forget the last line.. prob. not \n terminated *addrover = '\0'; x = (SCREENWIDTH - V_StringWidth(tempbuf)) / 2; V_WriteText(tempbuf, x, y); }
static int libd_stringWidth(lua_State *L) { const char *str = luaL_checkstring(L, 1); INT32 flags = luaL_optinteger(L, 2, V_ALLOWLOWERCASE); if (!hud_running) return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!"); lua_pushinteger(L, V_StringWidth(str, flags)); return 1; }
void MN_PopupDrawer() { if(gamestate == GS_CONSOLE || gamestate == GS_SERVERWAIT) { int wid = V_StringWidth(popup_message) + 10; int height = V_StringHeight(popup_message) + 3; V_DrawBox((SCREENWIDTH - wid) / 2, (SCREENHEIGHT - height) / 2 - 3, wid, height); } WriteCentredText(popup_message); }
void ST_nameDraw (int y) { player_t *plyr = &displayplayer(); if (plyr == &consoleplayer()) return; char *string = plyr->userinfo.netname; size_t x = (screen->width - V_StringWidth (string)*CleanXfac) >> 1; if (level.time < NameUp) screen->DrawTextClean (CR_GREEN, x, y, string); else screen->DrawTextCleanLuc (CR_GREEN, x, y, string); }
// // M_SaveGame & Cie. // [ML] 7 Sept 08: Bringing game saving/loading in from // zdoom 1.22 source, see MAINTAINERS // void M_DrawSave(void) { int i; screen->DrawPatchClean ((patch_t *)W_CacheLumpName("M_SAVEG",PU_CACHE), 72, 28); for (i = 0; i < load_end; i++) { M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i,24); screen->DrawTextCleanMove (CR_RED, LoadDef.x, LoadDef.y+LINEHEIGHT*i, savegamestrings[i]); } if (genStringEnter) { i = V_StringWidth(savegamestrings[saveSlot]); screen->DrawTextCleanMove (CR_RED, LoadDef.x + i, LoadDef.y+LINEHEIGHT*saveSlot, "_"); } }
static int libd_stringWidth(lua_State *L) { const char *str = luaL_checkstring(L, 1); INT32 flags = luaL_optinteger(L, 2, V_ALLOWLOWERCASE); enum widtht widtht = luaL_checkoption(L, 3, "normal", widtht_opt); HUDONLY switch(widtht) { case widtht_normal: // hu_font lua_pushinteger(L, V_StringWidth(str, flags)); break; case widtht_small: // hu_font, 0.5x scale lua_pushinteger(L, V_SmallStringWidth(str, flags)); break; case widtht_thin: // tny_font lua_pushinteger(L, V_ThinStringWidth(str, flags)); break; } return 1; }
static void D_Display(void) { static boolean menuactivestate = false; static gamestate_t oldgamestate = -1; boolean redrawsbar = false; static boolean wipe = false; if (dedicated) return; if (nodrawers) return; // for comparative timing/profiling // check for change of screen size (video mode) if (setmodeneeded && !wipe) SCR_SetMode(); // change video mode if (vid.recalc) SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() // change the view size if needed if (setsizeneeded) { R_ExecuteSetViewSize(); oldgamestate = -1; // force background redraw redrawsbar = true; } // save the current screen if about to wipe if (gamestate != wipegamestate) { wipe = true; #ifndef SHUFFLE if (rendermode == render_soft) #endif F_WipeStartScreen(); } else wipe = false; // Hardware mode does not fade wipe. // Thus, don't delay it unless needed for synchronisity. #ifndef SHUFFLE if (rendermode != render_soft /*&& !netgame*/) { if (gamestate != GS_INTRO && gamestate != GS_INTRO2 && gamestate != GS_CUTSCENE) wipe = false; } #endif // draw buffered stuff to screen // Used only by linux GGI version I_UpdateNoBlit(); // Fade to black first if (rendermode != render_none) { if (wipe) { if (!(mapheaderinfo[gamemap-1]->interscreen[0] == '#' && gamestate == GS_INTERMISSION)) { V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); #if defined (SHUFFLE) && defined (HWRENDER) if(rendermode != render_soft) { HWR_PrepFadeToBlack(); } #endif } F_WipeEndScreen(0, 0, vid.width, vid.height); F_RunWipe(2*TICRATE, gamestate != GS_TIMEATTACK); WipeInAction = false; } F_WipeStartScreen(); } // do buffered drawing switch (gamestate) { case GS_LEVEL: if (!gametic) break; HU_Erase(); if (automapactive) AM_Drawer(); if (wipe || menuactivestate || (rendermode != render_soft && rendermode != render_none) || vid.recalc) redrawsbar = true; break; case GS_INTERMISSION: Y_IntermissionDrawer(); HU_Erase(); HU_Drawer(); break; case GS_TIMEATTACK: break; case GS_INTRO: case GS_INTRO2: F_IntroDrawer(); break; case GS_CUTSCENE: F_CutsceneDrawer(); HU_Erase(); HU_Drawer(); break; case GS_GAMEEND: F_GameEndDrawer(); break; case GS_EVALUATION: F_GameEvaluationDrawer(); break; case GS_CREDITS: F_CreditDrawer(); HU_Erase(); HU_Drawer(); break; case GS_TITLESCREEN: F_TitleScreenDrawer(); break; case GS_DEMOSCREEN: D_PageDrawer(pagename); case GS_DEDICATEDSERVER: case GS_WAITINGPLAYERS: case GS_NULL: break; } // Transitions for Introduction if (gamestate == GS_INTRO && oldgamestate == GS_INTRO2) wipe = true; else if (gamestate == GS_INTRO2 && oldgamestate == GS_INTRO) wipe = true; // clean up border stuff // see if the border needs to be initially drawn if (gamestate == GS_LEVEL) { if (oldgamestate != GS_LEVEL) { #if 0 R_FillBackScreen(); // draw the pattern into the back screen #endif } // draw the view directly if (!automapactive && !dedicated && cv_renderview.value) { if (players[displayplayer].mo) { topleft = screens[0] + viewwindowy*vid.width + viewwindowx; #ifdef HWRENDER if (rendermode != render_soft) HWR_RenderPlayerView(0, &players[displayplayer]); else #endif if (rendermode != render_none) R_RenderPlayerView(&players[displayplayer]); } // render the second screen if (secondarydisplayplayer != consoleplayer && players[secondarydisplayplayer].mo) { #ifdef HWRENDER if (rendermode != render_soft) HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); else #endif if (rendermode != render_none) { viewwindowy = vid.height / 2; M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); topleft = screens[0] + viewwindowy*vid.width + viewwindowx; R_RenderPlayerView(&players[secondarydisplayplayer]); viewwindowy = 0; M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); } } // Image postprocessing effect if (postimgtype) V_DoPostProcessor(0, postimgtype, postimgparam); if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); } if (lastdraw) { if (rendermode == render_soft) VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); lastdraw = false; } ST_Drawer(redrawsbar); HU_Drawer(); } // change gamma if needed if (gamestate != oldgamestate && gamestate != GS_LEVEL) V_SetPalette(0); menuactivestate = menuactive; oldgamestate = wipegamestate = gamestate; // draw pause pic if (paused && (!menuactive || netgame)) { INT32 py; patch_t *patch; if (automapactive) py = 4; else py = viewwindowy + 4; patch = W_CachePatchName("M_PAUSE", PU_CACHE); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch); } // vid size change is now finished if it was on... vid.recalc = 0; // FIXME: draw either console or menu, not the two if (gamestate != GS_TIMEATTACK) CON_Drawer(); M_Drawer(); // menu is drawn even on top of everything NetUpdate(); // send out any new accumulation // It's safe to end the game now. if (G_GetExitGameFlag()) { Command_ExitGame_f(); G_ClearExitGameFlag(); } // // normal update // if (!wipe) { if (cv_netstat.value) { char s[50]; Net_GetNetStat(); s[sizeof s - 1] = '\0'; snprintf(s, sizeof s - 1, "get %d b/s", getbps); V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT-40, V_YELLOWMAP, s); snprintf(s, sizeof s - 1, "send %d b/s", sendbps); V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT-30, V_YELLOWMAP, s); snprintf(s, sizeof s - 1, "GameMiss %.2f%%", gamelostpercent); V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT-20, V_YELLOWMAP, s); snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent); V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s); } I_FinishUpdate(); // page flip or blit buffer if (takescreenshot) // Only take screenshots after drawing. M_DoScreenShot(); return; } // // wipe update // if (rendermode != render_none) { F_WipeEndScreen(0, 0, vid.width, vid.height); F_RunWipe(2*TICRATE, gamestate != GS_TIMEATTACK); WipeInAction = false; } }
static void displayticrate(fixed_t value) { int j,l,i; static tic_t lasttic; tic_t tics,t; t = I_GetTime(); tics = (t - lasttic)/NEWTICRATERATIO; lasttic = t; if (tics > OLDTICRATE) tics = OLDTICRATE; for (i=0; i<OLDTICRATE-1; i++) fpsgraph[i]=fpsgraph[i+1]; fpsgraph[OLDTICRATE-1]=OLDTICRATE-tics; if (value == 1 || value == 3) { char s[11]; sprintf(s, "FPS: %d/%u", OLDTICRATE-tics+1, OLDTICRATE); V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT+24, V_YELLOWMAP, s); } if (value == 1) return; if (rendermode == render_soft) { int k; // draw dots for (j=0; j<=OLDTICRATE*SCALE*vid.dupy; j+=2*SCALE*vid.dupy) { l=(vid.height-1-j)*vid.width*vid.bpp; for (i=0; i<OLDTICRATE*SCALE*vid.dupx; i+=2*SCALE*vid.dupx) screens[0][l+i]=0xff; } // draw the graph for (i=0; i<OLDTICRATE; i++) for (k=0; k<SCALE*vid.dupx; k++) PUTDOT(i*SCALE*vid.dupx+k, vid.height-1-(fpsgraph[i]*SCALE*vid.dupy),0xff); } #ifdef HWRENDER else { fline_t p; for (j=0; j<=OLDTICRATE*SCALE*vid.dupy; j+=2*SCALE*vid.dupy) { l=(vid.height-1-j); for (i=0; i<OLDTICRATE*SCALE*vid.dupx; i+=2*SCALE*vid.dupx) { p.a.x = i; p.a.y = l; p.b.x = i+1; p.b.y = l; HWR_drawAMline(&p, 0xff); } } for (i=1; i<OLDTICRATE; i++) { p.a.x = SCALE * (i-1); p.a.y = vid.height-1-fpsgraph[i-1]*SCALE*vid.dupy; p.b.x = SCALE * i; p.b.y = vid.height-1-fpsgraph[i]*SCALE*vid.dupy; HWR_drawAMline(&p, 0xff); } } #endif }
// poly : the convex polygon that encloses all child subsectors static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *bbox) { node_t *bsp; poly_t *backpoly, *frontpoly; fdivline_t fdivline; polyvertex_t *pt; INT32 i; // Found a subsector? if (bspnum & NF_SUBSECTOR) { if (bspnum == -1) { // BP: i think this code is useless and wrong because // - bspnum==-1 happens only when numsubsectors == 0 // - it can't happens in bsp recursive call since bspnum is a INT32 and children is UINT16 // - the BSP is complet !! (there just can have subsector without segs) (i am not sure of this point) // do we have a valid polygon ? if (poly && poly->numpts > 2) { DEBPRINT("Adding a new subsector\n"); if (addsubsector == numsubsectors + NEWSUBSECTORS) I_Error("WalkBSPNode: not enough addsubsectors\n"); else if (addsubsector > 0x7fff) I_Error("WalkBSPNode: addsubsector > 0x7fff\n"); *leafnode = (UINT16)((UINT16)addsubsector | NF_SUBSECTOR); extrasubsectors[addsubsector].planepoly = poly; addsubsector++; } //add subsectors without segs here? //HWR_SubsecPoly(0, NULL); } else { HWR_SubsecPoly(bspnum&(~NF_SUBSECTOR), poly); //Hurdler: implement a loading status if (ls_count-- <= 0) { char s[16]; int x, y; I_OsPolling(); ls_count = numsubsectors/50; CON_Drawer(); sprintf(s, "%d%%", (++ls_percent)<<1); x = BASEVIDWIDTH/2; y = BASEVIDHEIGHT/2; V_DrawFill(0, 0, vid.width, vid.height, 31); // Black background to match fade in effect //V_DrawPatchFill(W_CachePatchName("SRB2BACK",PU_CACHE)); // SRB2 background, ehhh too bright. M_DrawTextBox(x-58, y-8, 13, 1); V_DrawString(x-50, y, V_YELLOWMAP, "Loading..."); V_DrawString(x+50-V_StringWidth(s), y, V_YELLOWMAP, s); // Is this really necessary at this point..? V_DrawCenteredString(BASEVIDWIDTH/2, 40, V_YELLOWMAP, "OPENGL MODE IS INCOMPLETE AND MAY"); V_DrawCenteredString(BASEVIDWIDTH/2, 50, V_YELLOWMAP, "NOT DISPLAY SOME SURFACES."); V_DrawCenteredString(BASEVIDWIDTH/2, 70, V_YELLOWMAP, "USE AT SONIC'S RISK."); I_UpdateNoVsync(); } } M_ClearBox(bbox); poly = extrasubsectors[bspnum&~NF_SUBSECTOR].planepoly; for (i = 0, pt = poly->pts; i < poly->numpts; i++,pt++) M_AddToBox(bbox, FLOAT_TO_FIXED(pt->x), FLOAT_TO_FIXED(pt->y)); return; } bsp = &nodes[bspnum]; SearchDivline(bsp, &fdivline); SplitPoly(&fdivline, poly, &frontpoly, &backpoly); poly = NULL; //debug if (!backpoly) nobackpoly++; // Recursively divide front space. if (frontpoly) { WalkBSPNode(bsp->children[0], frontpoly, &bsp->children[0],bsp->bbox[0]); // copy child bbox M_Memcpy(bbox, bsp->bbox[0], 4*sizeof (fixed_t)); } else I_Error("WalkBSPNode: no front poly?"); // Recursively divide back space. if (backpoly) { // Correct back bbox to include floor/ceiling convex polygon WalkBSPNode(bsp->children[1], backpoly, &bsp->children[1], bsp->bbox[1]); // enlarge bbox with seconde child M_AddToBox(bbox, bsp->bbox[1][BOXLEFT ], bsp->bbox[1][BOXTOP ]); M_AddToBox(bbox, bsp->bbox[1][BOXRIGHT ], bsp->bbox[1][BOXBOTTOM]); } }