A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 775 lines 18 kB view raw
1/* Emacs style mode select -*- C++ -*- 2 *----------------------------------------------------------------------------- 3 * 4 * 5 * PrBoom a Doom port merged with LxDoom and LSDLDoom 6 * based on BOOM, a modified and improved DOOM engine 7 * Copyright (C) 1999 by 8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman 9 * Copyright (C) 1999-2000 by 10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 25 * 02111-1307, USA. 26 * 27 * DESCRIPTION: heads-up text and input code 28 * 29 *----------------------------------------------------------------------------- 30 */ 31 32#include "doomdef.h" 33#include "doomstat.h" 34#include "v_video.h" 35#include "m_swap.h" 36#include "hu_lib.h" 37#include "hu_stuff.h" 38#include "r_main.h" 39#include "r_draw.h" 40 41#include "rockmacros.h" 42 43// boolean : whether the screen is always erased 44#define noterased viewwindowx 45 46extern int key_backspace; // phares 47extern int key_enter; // phares 48 49// 50// not used currently 51// code to initialize HUlib would go here if needed 52// 53void HUlib_init(void) 54{ 55} 56 57//////////////////////////////////////////////////////// 58// 59// Basic text line widget 60// 61//////////////////////////////////////////////////////// 62 63// 64// HUlib_clearTextLine() 65// 66// Blank the internal text line in a hu_textline_t widget 67// 68// Passed a hu_textline_t, returns nothing 69// 70void HUlib_clearTextLine(hu_textline_t* t) 71{ 72 t->linelen = // killough 1/23 98: support multiple lines 73 t->len = 0; 74 t->l[0] = 0; 75 t->needsupdate = true; 76} 77 78// 79// HUlib_initTextLine() 80// 81// Initialize a hu_textline_t widget. Set the position, font, start char 82// of the font, and color range to be used. 83// 84// Passed a hu_textline_t, and the values used to initialize 85// Returns nothing 86// 87void HUlib_initTextLine(hu_textline_t* t, int x, int y, 88 const patchnum_t* f, int sc, int cm ) 89//jff 2/16/98 add color range parameter 90{ 91 t->x = x; 92 t->y = y; 93 t->f = f; 94 t->sc = sc; 95 t->cm = cm; 96 HUlib_clearTextLine(t); 97} 98 99// 100// HUlib_addCharToTextLine() 101// 102// Adds a character at the end of the text line in a hu_textline_t widget 103// 104// Passed the hu_textline_t and the char to add 105// Returns false if already at length limit, true if the character added 106// 107boolean HUlib_addCharToTextLine 108( hu_textline_t* t, 109 char ch ) 110{ 111 // killough 1/23/98 -- support multiple lines 112 if (t->linelen == HU_MAXLINELENGTH) 113 return false; 114 else 115 { 116 t->linelen++; 117 if (ch == '\n') 118 t->linelen=0; 119 120 t->l[t->len++] = ch; 121 t->l[t->len] = 0; 122 t->needsupdate = 4; 123 return true; 124 } 125 126} 127 128// 129// HUlib_delCharFromTextLine() 130// 131// Deletes a character at the end of the text line in a hu_textline_t widget 132// 133// Passed the hu_textline_t 134// Returns false if already empty, true if the character deleted 135// 136boolean HUlib_delCharFromTextLine(hu_textline_t* t) 137{ 138 if (!t->len) return false; 139 else 140 { 141 t->l[--t->len] = 0; 142 t->needsupdate = 4; 143 return true; 144 } 145} 146 147// 148// HUlib_drawTextLine() 149// 150// Draws a hu_textline_t widget 151// 152// Passed the hu_textline_t and flag whether to draw a cursor 153// Returns nothing 154// 155void HUlib_drawTextLine 156( hu_textline_t* l, 157 boolean drawcursor ) 158{ 159 160 int i; 161 int w; 162 int x; 163 unsigned char c; 164 int oc = l->cm; //jff 2/17/98 remember default color 165 int y = l->y; // killough 1/18/98 -- support multiple lines 166 167 // draw the new stuff 168 x = l->x; 169 for (i=0;i<l->len;i++) 170 { 171 c = toupper(l->l[i]); //jff insure were not getting a cheap toupper conv. 172 173 if (c=='\n') // killough 1/18/98 -- support multiple lines 174 x=0,y+=8; 175 else if (c=='\t') // killough 1/23/98 -- support tab stops 176 x=x-x%80+80; 177 else if (c=='\x1b') //jff 2/17/98 escape code for color change 178 { //jff 3/26/98 changed to actual escape char 179 if (++i<l->len) 180 if (l->l[i]>='0' && l->l[i]<='9') 181 l->cm = l->l[i]-'0'; 182 } 183 else if (c != ' ' && c >= l->sc && c <= 127) 184 { 185 w = SHORT(l->f[c - l->sc].width); 186 if (x+w > BASE_WIDTH) 187 break; 188 // killough 1/18/98 -- support multiple lines: 189 // CPhipps - patch drawing updated 190 V_DrawNumPatch(x, y, FG, l->f[c - l->sc].lumpnum, l->cm, VPT_TRANS | VPT_STRETCH); 191 x += w; 192 } 193 else 194 { 195 x += 4; 196 if (x >= BASE_WIDTH) 197 break; 198 } 199 } 200 l->cm = oc; //jff 2/17/98 restore original color 201 202 // draw the cursor if requested 203 if (drawcursor && x + SHORT(l->f['_' - l->sc].width) <= BASE_WIDTH) 204 { 205 // killough 1/18/98 -- support multiple lines 206 // CPhipps - patch drawing updated 207 V_DrawNumPatch(x, y, FG, l->f['_' - l->sc].lumpnum, CR_DEFAULT, VPT_NONE | VPT_STRETCH); 208 } 209} 210 211// 212// HUlib_eraseTextLine() 213// 214// Erases a hu_textline_t widget when screen border is behind text 215// Sorta called by HU_Erase and just better darn get things straight 216// 217// Passed the hu_textline_t 218// Returns nothing 219// 220void HUlib_eraseTextLine(hu_textline_t* l) 221{ 222// KK - If someone finds a use for this code, please fix it, I havn't seen the need 223// And it's not written to take into account scaling. Causing some nasty effects 224// on smaller screens. 225 (void)l; 226#if 0 227 int lh; 228 int y; 229 int yoffset; 230 231 // Only erases when NOT in automap and the screen is reduced, 232 // and the text must either need updating or refreshing 233 // (because of a recent change back from the automap) 234 235 if (!(automapmode & am_active) && viewwindowx && l->needsupdate) 236 { 237 lh = SHORT(l->f[0].height) + 1; 238 for (y=l->y,yoffset=y*SCREENWIDTH ; y<l->y+lh ; y++,yoffset+=SCREENWIDTH) 239 { 240 if (y < viewwindowy || y >= viewwindowy + viewheight) 241 R_VideoErase(yoffset, SCREENWIDTH); // erase entire line 242 else 243 { 244 // erase left border 245 R_VideoErase(yoffset, viewwindowx); 246 // erase right border 247 R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx); 248 } 249 } 250 } 251 if (l->needsupdate) l->needsupdate--; 252#endif 253} 254 255//////////////////////////////////////////////////////// 256// 257// Player message widget (up to 4 lines of text) 258// 259//////////////////////////////////////////////////////// 260 261// 262// HUlib_initSText() 263// 264// Initialize a hu_stext_t widget. Set the position, number of lines, font, 265// start char of the font, and color range to be used, and whether enabled. 266// 267// Passed a hu_stext_t, and the values used to initialize 268// Returns nothing 269// 270void HUlib_initSText 271( hu_stext_t* s, 272 int x, 273 int y, 274 int h, 275 const patchnum_t* font, 276 int startchar, 277 int cm, //jff 2/16/98 add color range parameter 278 boolean* on ) 279{ 280 281 int i; 282 283 s->h = h; 284 s->on = on; 285 s->laston = true; 286 s->cl = 0; 287 for (i=0;i<h;i++) 288 HUlib_initTextLine 289 ( 290 &s->l[i], 291 x, 292 y - i*(SHORT(font[0].height)+1), 293 font, 294 startchar, 295 cm 296 ); 297} 298 299// 300// HUlib_addLineToSText() 301// 302// Adds a blank line to a hu_stext_t widget 303// 304// Passed a hu_stext_t 305// Returns nothing 306// 307void HUlib_addLineToSText(hu_stext_t* s) 308{ 309 310 int i; 311 312 // add a clear line 313 if (++s->cl == s->h) 314 s->cl = 0; 315 HUlib_clearTextLine(&s->l[s->cl]); 316 317 // everything needs updating 318 for (i=0 ; i<s->h ; i++) 319 s->l[i].needsupdate = 4; 320 321} 322 323// 324// HUlib_addMessageToSText() 325// 326// Adds a message line with prefix to a hu_stext_t widget 327// 328// Passed a hu_stext_t, the prefix string, and a message string 329// Returns nothing 330// 331void HUlib_addMessageToSText(hu_stext_t* s, const char* prefix, const char* msg) 332{ 333 HUlib_addLineToSText(s); 334 if (prefix) 335 while (*prefix) 336 HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++)); 337 338 while (*msg) 339 HUlib_addCharToTextLine(&s->l[s->cl], *(msg++)); 340} 341 342// 343// HUlib_drawSText() 344// 345// Displays a hu_stext_t widget 346// 347// Passed a hu_stext_t 348// Returns nothing 349// 350void HUlib_drawSText(hu_stext_t* s) 351{ 352 int i, idx; 353 hu_textline_t *l; 354 355 if (!*s->on) 356 return; // if not on, don't draw 357 358 // draw everything 359 for (i=0 ; i<s->h ; i++) 360 { 361 idx = s->cl - i; 362 if (idx < 0) 363 idx += s->h; // handle queue of lines 364 365 l = &s->l[idx]; 366 367 // need a decision made here on whether to skip the draw 368 HUlib_drawTextLine(l, false); // no cursor, please 369 } 370} 371 372// 373// HUlib_eraseSText() 374// 375// Erases a hu_stext_t widget, when the screen is not fullsize 376// 377// Passed a hu_stext_t 378// Returns nothing 379// 380void HUlib_eraseSText(hu_stext_t* s) 381{ 382 int i; 383 384 for (i=0 ; i<s->h ; i++) 385 { 386 if (s->laston && !*s->on) 387 s->l[i].needsupdate = 4; 388 HUlib_eraseTextLine(&s->l[i]); 389 } 390 s->laston = *s->on; 391} 392 393//////////////////////////////////////////////////////// 394// 395// Scrolling message review widget 396// 397// jff added 2/26/98 398// 399//////////////////////////////////////////////////////// 400 401// 402// HUlib_initMText() 403// 404// Initialize a hu_mtext_t widget. Set the position, width, number of lines, 405// font, start char of the font, color range, background font, and whether 406// enabled. 407// 408// Passed a hu_mtext_t, and the values used to initialize 409// Returns nothing 410// 411void HUlib_initMText(hu_mtext_t *m, int x, int y, int w, int h, 412 const patchnum_t* font, int startchar, int cm, 413 const patchnum_t* bgfont, boolean *on) 414{ 415 int i; 416 417 m->nl = 0; 418 m->nr = 0; 419 m->cl = -1; //jff 4/28/98 prepare for pre-increment 420 m->x = x; 421 m->y = y; 422 m->w = w; 423 m->h = h; 424 m->bg = bgfont; 425 m->on = on; 426 for (i=0;i<HU_MAXMESSAGES;i++) 427 { 428 HUlib_initTextLine 429 ( 430 &m->l[i], 431 x, 432 y + (hud_list_bgon? i+1 : i)*HU_REFRESHSPACING, 433 font, 434 startchar, 435 cm 436 ); 437 } 438} 439 440// 441// HUlib_addLineToMText() 442// 443// Adds a blank line to a hu_mtext_t widget 444// 445// Passed a hu_mtext_t 446// Returns nothing 447// 448void HUlib_addLineToMText(hu_mtext_t* m) 449{ 450 // add a clear line 451 if (++m->cl == hud_msg_lines) 452 m->cl = 0; 453 HUlib_clearTextLine(&m->l[m->cl]); 454 455 if (m->nl<hud_msg_lines) 456 m->nl++; 457 458 // needs updating 459 m->l[m->cl].needsupdate = 4; 460} 461 462// 463// HUlib_addMessageToMText() 464// 465// Adds a message line with prefix to a hu_mtext_t widget 466// 467// Passed a hu_mtext_t, the prefix string, and a message string 468// Returns nothing 469// 470void HUlib_addMessageToMText(hu_mtext_t* m, const char* prefix, const char* msg) 471{ 472 HUlib_addLineToMText(m); 473 if (prefix) 474 while (*prefix) 475 HUlib_addCharToTextLine(&m->l[m->cl], *(prefix++)); 476 477 while (*msg) 478 HUlib_addCharToTextLine(&m->l[m->cl], *(msg++)); 479} 480 481// 482// HUlib_drawMBg() 483// 484// Draws a background box which the message display review widget can 485// display over 486// 487// Passed position, width, height, and the background patches 488// Returns nothing 489// 490void HUlib_drawMBg 491( int x, 492 int y, 493 int w, 494 int h, 495 const patchnum_t* bgp 496) 497{ 498 int xs = bgp[0].width; 499 int ys = bgp[0].height; 500 int i,j; 501 502 // CPhipps - patch drawing updated 503 // top rows 504 V_DrawNumPatch(x, y, FG, bgp[0].lumpnum, CR_DEFAULT, VPT_STRETCH); // ul 505 for (j=x+xs;j<x+w-xs;j+=xs) // uc 506 V_DrawNumPatch(j, y, FG, bgp[1].lumpnum, CR_DEFAULT, VPT_STRETCH); 507 V_DrawNumPatch(j, y, FG, bgp[2].lumpnum, CR_DEFAULT, VPT_STRETCH); // ur 508 509 // middle rows 510 for (i=y+ys;i<y+h-ys;i+=ys) 511 { 512 V_DrawNumPatch(x, i, FG, bgp[3].lumpnum, CR_DEFAULT, VPT_STRETCH); // cl 513 for (j=x+xs;j<x+w-xs;j+=xs) // cc 514 V_DrawNumPatch(j, i, FG, bgp[4].lumpnum, CR_DEFAULT, VPT_STRETCH); 515 V_DrawNumPatch(j, i, FG, bgp[5].lumpnum, CR_DEFAULT, VPT_STRETCH); // cr 516 } 517 518 // bottom row 519 V_DrawNumPatch(x, i, FG, bgp[6].lumpnum, CR_DEFAULT, VPT_STRETCH); // ll 520 for (j=x+xs;j<x+w-xs;j+=xs) // lc 521 V_DrawNumPatch(j, i, FG, bgp[7].lumpnum, CR_DEFAULT, VPT_STRETCH); 522 V_DrawNumPatch(j, i, FG, bgp[8].lumpnum, CR_DEFAULT, VPT_STRETCH); // lr 523} 524 525// 526// HUlib_drawMText() 527// 528// Displays a hu_mtext_t widget 529// 530// Passed a hu_mtext_t 531// Returns nothing 532// 533void HUlib_drawMText(hu_mtext_t* m) 534{ 535 int i, idx; 536 hu_textline_t *l; 537 538 if (!*m->on) 539 return; // if not on, don't draw 540 541 // draw everything 542 if (hud_list_bgon) 543 HUlib_drawMBg(m->x,m->y,m->w,m->h,m->bg); 544 545 for (i=0 ; i<m->nl ; i++) 546 { 547 idx = m->cl - i; 548 if (idx < 0) 549 idx += m->nl; // handle queue of lines 550 551 l = &m->l[idx]; 552 if (hud_list_bgon) 553 { 554 l->x = m->x + 4; 555 l->y = m->y + (i+1)*HU_REFRESHSPACING; 556 } 557 else 558 { 559 l->x = m->x; 560 l->y = m->y + i*HU_REFRESHSPACING; 561 } 562 563 // need a decision made here on whether to skip the draw 564 HUlib_drawTextLine(l, false); // no cursor, please 565 } 566} 567 568// 569// HUlib_eraseMBg() 570// 571// Erases background behind hu_mtext_t widget, when the screen is not fullsize 572// 573// Passed a hu_mtext_t 574// Returns nothing 575// 576static void HUlib_eraseMBg(hu_mtext_t* m) 577{ 578 int lh; 579 int y; 580 int yoffset; 581 582 // Only erases when NOT in automap and the screen is reduced, 583 // and the text must either need updating or refreshing 584 // (because of a recent change back from the automap) 585 586 if (!(automapmode & am_active) && viewwindowx) 587 { 588 lh = SHORT(m->l[0].f[0].height) + 1; 589 for (y=m->y,yoffset=y*SCREENWIDTH ; y<m->y+lh*(hud_msg_lines+2) ; y++,yoffset+=SCREENWIDTH) 590 { 591 if (y < viewwindowy || y >= viewwindowy + viewheight) 592 R_VideoErase(yoffset, SCREENWIDTH); // erase entire line 593 else 594 { 595 // erase left border 596 R_VideoErase(yoffset, viewwindowx); 597 // erase right border 598 R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx); 599 600 } 601 } 602 } 603} 604 605// 606// HUlib_eraseMText() 607// 608// Erases a hu_mtext_t widget, when the screen is not fullsize 609// 610// Passed a hu_mtext_t 611// Returns nothing 612// 613void HUlib_eraseMText(hu_mtext_t* m) 614{ 615 int i; 616 617 if (hud_list_bgon) 618 HUlib_eraseMBg(m); 619 620 for (i=0 ; i< m->nl ; i++) 621 { 622 m->l[i].needsupdate = 4; 623 HUlib_eraseTextLine(&m->l[i]); 624 } 625} 626 627//////////////////////////////////////////////////////// 628// 629// Interactive text entry widget 630// 631//////////////////////////////////////////////////////// 632 633// 634// HUlib_initIText() 635// 636// Initialize a hu_itext_t widget. Set the position, font, 637// start char of the font, color range, and whether enabled. 638// 639// Passed a hu_itext_t, and the values used to initialize 640// Returns nothing 641// 642void HUlib_initIText 643( hu_itext_t* it, 644 int x, 645 int y, 646 const patchnum_t* font, 647 int startchar, 648 int cm, //jff 2/16/98 add color range parameter 649 boolean* on ) 650{ 651 it->lm = 0; // default left margin is start of text 652 it->on = on; 653 it->laston = true; 654 HUlib_initTextLine(&it->l, x, y, font, startchar, cm); 655} 656 657// The following deletion routines adhere to the left margin restriction 658 659// 660// HUlib_delCharFromIText() 661// 662// Deletes a character at the end of the text line in a hu_itext_t widget 663// 664// Passed the hu_itext_t 665// Returns nothing 666// 667void HUlib_delCharFromIText(hu_itext_t* it) 668{ 669 if (it->l.len != it->lm) 670 HUlib_delCharFromTextLine(&it->l); 671} 672 673// 674// HUlib_eraseLineFromIText() 675// 676// Deletes all characters from a hu_itext_t widget 677// 678// Passed the hu_itext_t 679// Returns nothing 680// 681void HUlib_eraseLineFromIText(hu_itext_t* it) 682{ 683 while (it->lm != it->l.len) 684 HUlib_delCharFromTextLine(&it->l); 685} 686 687// 688// HUlib_resetIText() 689// 690// Deletes all characters from a hu_itext_t widget 691// Resets left margin as well 692// 693// Passed the hu_itext_t 694// Returns nothing 695// 696void HUlib_resetIText(hu_itext_t* it) 697{ 698 it->lm = 0; 699 HUlib_clearTextLine(&it->l); 700} 701 702// 703// HUlib_addPrefixToIText() 704// 705// Adds a prefix string passed to a hu_itext_t widget 706// Sets left margin to length of string added 707// 708// Passed the hu_itext_t and the prefix string 709// Returns nothing 710// 711void HUlib_addPrefixToIText 712( hu_itext_t* it, 713 char* str ) 714{ 715 while (*str) 716 HUlib_addCharToTextLine(&it->l, *(str++)); 717 it->lm = it->l.len; 718} 719 720// 721// HUlib_keyInIText() 722// 723// Wrapper function for handling general keyed input. 724// 725// Passed the hu_itext_t and the char input 726// Returns true if it ate the key 727// 728boolean HUlib_keyInIText 729( hu_itext_t* it, 730 unsigned char ch ) 731{ 732 733 if (ch >= ' ' && ch <= '_') 734 HUlib_addCharToTextLine(&it->l, (char) ch); 735 else if (ch == key_backspace) // phares 736 HUlib_delCharFromIText(it); 737 else if (ch != key_enter) // phares 738 return false; // did not eat key 739 740 return true; // ate the key 741} 742 743// 744// HUlib_drawIText() 745// 746// Displays a hu_itext_t widget 747// 748// Passed the hu_itext_t 749// Returns nothing 750// 751void HUlib_drawIText(hu_itext_t* it) 752{ 753 hu_textline_t *l = &it->l; 754 755 if (!*it->on) 756 return; 757 HUlib_drawTextLine(l, true); // draw the line w/ cursor 758} 759 760// 761// HUlib_eraseIText() 762// 763// Erases a hu_itext_t widget when the screen is not fullsize 764// 765// Passed the hu_itext_t 766// Returns nothing 767// 768void HUlib_eraseIText(hu_itext_t* it) 769{ 770 if (it->laston && !*it->on) 771 it->l.needsupdate = 4; 772 HUlib_eraseTextLine(&it->l); 773 it->laston = *it->on; 774} 775