|
|
1.1 ! root 1: /*****************************************************************************/ ! 2: /* Generator - Sega Genesis emulation - (c) James Ponder 1997-2000 */ ! 3: /*****************************************************************************/ ! 4: /* */ ! 5: /* ui-console - generic 640x480 console emulation */ ! 6: /* */ ! 7: /*****************************************************************************/ ! 8: ! 9: #include <stdlib.h> ! 10: #include <stdio.h> ! 11: #include <stdarg.h> ! 12: #include <time.h> ! 13: #include <string.h> ! 14: ! 15: #include "generator.h" ! 16: ! 17: #include "cpu68k.h" ! 18: #include "cpuz80.h" ! 19: #include "ui.h" ! 20: #include "vdp.h" ! 21: #include "reg68k.h" ! 22: #include "gensound.h" ! 23: #include "mem68k.h" ! 24: #include "logo.h" ! 25: #include "font.h" ! 26: #include "uip.h" ! 27: #include "ui-console.h" ! 28: ! 29: #define UI_LOGLINESIZE 128 ! 30: #define UI_LOGLINES 64 ! 31: ! 32: uint8 ui_vdpsimple = 0; /* 0=raster, 1=cell based plotter */ ! 33: uint8 ui_clearnext = 0; /* flag indicating redraw required */ ! 34: uint8 ui_info = 1; /* does the user want info onscreen or not */ ! 35: uint8 ui_vsync = 0; /* does the user want us to wait for vsync */ ! 36: ! 37: /*** forward reference declarations ***/ ! 38: ! 39: void ui_endframe(void); ! 40: void ui_exithandler(void); ! 41: void ui_printlog(void); ! 42: void ui_newframe(void); ! 43: void ui_convertdata(uint8 *indata, uint8 *outdata, unsigned int pixels); ! 44: void ui_plotsprite_acorn(uint16 *logo, uint16 width, uint16 height, ! 45: uint16 x, uint16 y); ! 46: int ui_unpackfont(void); ! 47: uint16 ui_plotstring(const char *text, uint16 xpos, uint16 ypos); ! 48: uint16 ui_plotint2(uint8 num, uint16 xpos, uint16 ypos); ! 49: void ui_plotsettings(void); ! 50: void ui_drawbox(uint16 colour, uint16 x, uint16 y, uint16 width, ! 51: uint16 height); ! 52: ! 53: /*** static variables ***/ ! 54: ! 55: static uint8 ui_vga = 0; /* flag for whether in VGA more or not */ ! 56: static uint8 ui_frameskip = 0; /* 0 for dynamic */ ! 57: static uint8 ui_actualskip = 0; /* the last skip we did (1..) */ ! 58: static uint8 ui_state = 0; /* 0=stop, 1=paused, 2=play */ ! 59: static uint32 ui_palcache[192]; ! 60: static char *ui_initload = NULL; /* filename to load on init */ ! 61: static char ui_loglines[UI_LOGLINES][UI_LOGLINESIZE]; ! 62: static uint32 ui_logline = 0; ! 63: static uint8 ui_plotframe; /* flag indicating plotting this frame */ ! 64: static uint16 *ui_font; /* unpacked font */ ! 65: static uint8 bigbuffer[8192]; /* stupid no-vsnprintf platforms */ ! 66: static uint16 ui_logcount = 0; /* log counter */ ! 67: static t_uipinfo ui_uipinfo; /* uipinfo filled in by uip 'sub-system' */ ! 68: ! 69: /*** Program entry point ***/ ! 70: ! 71: int ui_init(int argc, char *argv[]) ! 72: { ! 73: int i; ! 74: ! 75: for(i = 0; i < UI_LOGLINES; i++) { ! 76: ui_loglines[i][0] = '\0'; ! 77: } ! 78: if (ui_unpackfont() == -1) { ! 79: fprintf(stderr, "Failed to unpack font, out of memory?\n"); ! 80: return 1; ! 81: } ! 82: if (argc == 2) { ! 83: if ((ui_initload = malloc(strlen(argv[1])+1)) == NULL) { ! 84: fprintf(stderr, "Out of memory\n"); ! 85: return 1; ! 86: } ! 87: strcpy(ui_initload, argv[1]); ! 88: } ! 89: if (atexit(ui_exithandler) == -1) { ! 90: LOG_CRITICAL(("Failed to set exit handler")); ! 91: return 1; ! 92: } ! 93: if (uip_init(&ui_uipinfo)) { ! 94: LOG_CRITICAL(("Failed to initialise platform dependent UI")); ! 95: return 1; ! 96: } ! 97: return 0; ! 98: } ! 99: ! 100: void ui_printlog(void) ! 101: { ! 102: unsigned int i; ! 103: char *p; ! 104: ! 105: printf("**** Last lines logged:\n"); ! 106: for (i = ui_logline; i < (UI_LOGLINES+ui_logline); i++) { ! 107: p = ui_loglines[(i < UI_LOGLINES) ? i : (i-UI_LOGLINES)]; ! 108: if (*p) ! 109: printf("%s\n", p); ! 110: } ! 111: printf("**** END\n"); ! 112: } ! 113: ! 114: void ui_exithandler(void) ! 115: { ! 116: if (ui_vga) ! 117: uip_textmode(); ! 118: ui_vga = 0; ! 119: ui_printlog(); ! 120: } ! 121: ! 122: void ui_final(void) ! 123: { ! 124: if (ui_vga) ! 125: uip_textmode(); ! 126: ui_vga = 0; ! 127: ui_printlog(); ! 128: } ! 129: ! 130: /*** ui_drawbox - plot a box ***/ ! 131: ! 132: void ui_drawbox(uint16 colour, uint16 x, uint16 y, uint16 width, ! 133: uint16 height) ! 134: { ! 135: uint16 *p, *q; ! 136: unsigned int i; ! 137: ! 138: p = (uint16 *)(ui_uipinfo.screenmem_w+y*ui_uipinfo.linewidth+x*2); ! 139: q = (uint16 *)((uint8 *)p+(height-1)*ui_uipinfo.linewidth); ! 140: for (i = 0; i < width; i++) ! 141: *p++ = *q++ = colour; ! 142: p = (uint16 *)(ui_uipinfo.screenmem_w+y*ui_uipinfo.linewidth+x*2); ! 143: for (i = 0; i < height; i++) { ! 144: p[0] = colour; ! 145: p[width-1] = colour; ! 146: p = (uint16 *)((uint8 *)p+ui_uipinfo.linewidth); ! 147: } ! 148: } ! 149: ! 150: /*** ui_unpackfont - unpack the font file ***/ ! 151: ! 152: int ui_unpackfont(void) ! 153: { ! 154: unsigned int c, y, x; ! 155: unsigned char packed; ! 156: uint16 *cdata; ! 157: ! 158: if ((ui_font = malloc(128*6*10*2)) == NULL) /* 128 chars, 6x, 10y, 16bit */ ! 159: return -1; ! 160: for (c = 0; c < 128; c++) { /* 128 characters */ ! 161: cdata = ui_font+c*6*10; ! 162: for (y = 0; y < 10; y++) { /* 10 pixels height */ ! 163: packed = generator_font[c*10+y]; ! 164: for (x = 0; x < 6; x++) { /* 6 pixels width */ ! 165: *cdata++ = (packed & 1<<(7-x)) ? 0xffff : 0; ! 166: } ! 167: } ! 168: } ! 169: return 0; ! 170: } ! 171: ! 172: /*** ui_plotint2 - plot a 2-char wide integer ***/ ! 173: ! 174: uint16 ui_plotint2(uint8 num, uint16 xpos, uint16 ypos) ! 175: { ! 176: char buf[3]; ! 177: ! 178: buf[0] = '0' + (num / 10) % 10; ! 179: buf[1] = '0' + (num % 10); ! 180: buf[2] = '\0'; ! 181: return ui_plotstring(buf, xpos, ypos); ! 182: } ! 183: ! 184: /*** ui_plotstring - plot a string ***/ ! 185: ! 186: uint16 ui_plotstring(const char *text, uint16 xpos, uint16 ypos) ! 187: { ! 188: const unsigned char *p; ! 189: const uint16 *cdata; ! 190: unsigned int x,y; ! 191: uint16 *scr; ! 192: ! 193: for (p = text; *p; p++) { ! 194: if (*p > 128) ! 195: cdata = ui_font+'.'*6*10; ! 196: else ! 197: cdata = ui_font+(*p)*6*10; ! 198: for (y = 0; y < 10; y++) { ! 199: scr = (uint16 *)(ui_uipinfo.screenmem_w+(ypos+y)*ui_uipinfo.linewidth ! 200: +xpos*2); ! 201: for (x = 0; x < 6; x++) ! 202: *scr++ = *cdata++; ! 203: } ! 204: xpos+= 6; ! 205: } ! 206: return xpos; ! 207: } ! 208: ! 209: /*** ui_plotsprite - plot a sprite ***/ ! 210: ! 211: void ui_plotsprite_acorn(uint16 *logo, uint16 width, uint16 height, ! 212: uint16 x, uint16 y) ! 213: { ! 214: uint16 a, b; ! 215: uint16 *p, *q; ! 216: uint16 word; ! 217: uint8 red, green, blue; ! 218: ! 219: for (b = 0; b < height; b++) { ! 220: p = (uint16 *)(ui_uipinfo.screenmem_w+(y+b)*ui_uipinfo.linewidth+x*2); ! 221: for (a = 0; a < width; a++) { ! 222: word = (((uint8 *)logo)[1]<<8) | ((uint8 *)logo)[0]; ! 223: green = (word>>5) & 0x1f; ! 224: red = word & 0x1f; ! 225: blue = (word>>10) & 0x1f; ! 226: *p++ = red<<ui_uipinfo.redshift | green<<ui_uipinfo.greenshift | ! 227: blue<<ui_uipinfo.blueshift; ! 228: logo++; ! 229: } ! 230: } ! 231: } ! 232: ! 233: /*** ui_setupscreen - plot borders and stuff ***/ ! 234: ! 235: void ui_setupscreen(void) ! 236: { ! 237: uint16 grey = 24<<ui_uipinfo.redshift | 24<<ui_uipinfo.greenshift | ! 238: 24<<ui_uipinfo.blueshift; ! 239: uint16 red = 24<<ui_uipinfo.redshift; ! 240: ! 241: ui_drawbox(red, 140, 100, 360, 280); ! 242: ui_drawbox(grey, 141, 101, 358, 278); ! 243: if (!ui_info) ! 244: return; ! 245: ui_plotsprite_acorn((uint16 *)logo, 282, 40, 179, 80); ! 246: ui_plotsprite_acorn((uint16 *)logo, 282, 40, 179, 360); ! 247: ui_drawbox(red, 0, 415, 640, 1); ! 248: ui_drawbox(grey, 0, 416, 640, 1); ! 249: ui_drawbox(red, 0, 65, 640, 1); ! 250: ui_drawbox(grey, 0, 66, 640, 1); ! 251: ; ! 252: /* draw marker for 320x224 box */ ! 253: // ui_drawbox(grey, 160, 128, 320, 224); ! 254: /* draw marker for 320x240 box */ ! 255: // ui_drawbox(grey, 160, 120, 320, 240); ! 256: /* draw marker for 256x224 box */ ! 257: // ui_drawbox(grey, 192, 128, 256, 224); ! 258: /* draw marker for 256x240 box */ ! 259: // ui_drawbox(grey, 192, 120, 256, 240); ! 260: ; ! 261: ui_plotstring("Generator is (c) James Ponder 1997-2000, " ! 262: "all rights reserved.", 0, 0); ! 263: ui_plotstring(VERSTRING, 640-(strlen(VERSTRING)*6), 0); ! 264: ; ! 265: ui_plotstring("[A] A button", 0, 420); ! 266: ui_plotstring("[S] B button", 0, 430); ! 267: ui_plotstring("[D] C button", 0, 440); ! 268: ui_plotstring("[RETURN] Start", 0, 450); ! 269: ui_plotstring("[ARROWS] D-pad", 0, 460); ! 270: ui_plotstring("[ESCAPE] QUIT", 0, 470); ! 271: ; ! 272: ui_plotstring("FPS: 00", 120, 420); ! 273: ui_plotstring("Skip: 00", 120, 430); ! 274: ui_plotstring(":", 622, 470); ! 275: ; ! 276: ui_plotstring("[F5] Toggle info:", 0, 20); ! 277: ui_plotstring("[F6] Toggle video:", 0, 30); ! 278: ui_plotstring("[F7] Toggle country:", 0, 40); ! 279: ui_plotstring("[F8] Toggle plotter:", 0, 50); ! 280: ui_plotstring("[F9] Toggle vsync:", 216, 20); ! 281: ui_plotstring("[F12] Restart game", 216, 50); ! 282: ; ! 283: ui_plotstring("[1] B lo:", 64*6, 20); ! 284: ui_plotstring("[2] B hi:", 64*6, 30); ! 285: ui_plotstring("[3] A lo:", 64*6, 40); ! 286: ui_plotstring("[4] A hi:", 64*6, 50); ! 287: ui_plotstring("[5] W lo:", 78*6, 20); ! 288: ui_plotstring("[6] W hi:", 78*6, 30); ! 289: ui_plotstring("[7] H: ", 78*6, 40); ! 290: ui_plotstring("[8] S lo:", 92*6, 20); ! 291: ui_plotstring("[9] S hi:", 92*6, 30); ! 292: ; ! 293: ui_plotsettings(); ! 294: ; ! 295: sprintf(bigbuffer, "%s %X %s", gen_cartinfo.version, ! 296: gen_cartinfo.checksum, gen_cartinfo.country); ! 297: ui_plotstring(bigbuffer, 216, 420); ! 298: ui_plotstring(gen_cartinfo.name_domestic, 216, 430); ! 299: ui_plotstring(gen_cartinfo.name_overseas, 216, 440); ! 300: } ! 301: ! 302: void ui_plotsettings(void) ! 303: { ! 304: ui_plotstring(ui_info ? "On " : "Off", 126, 20); ! 305: ui_plotstring(vdp_pal ? "Pal " : "NTSC", 126, 30); ! 306: ui_plotstring(vdp_overseas ? "USA/Europe" : "Japan ", 126, 40); ! 307: ui_plotstring(ui_vdpsimple ? "Cell (fast) " : "Raster (slow)", 126, 50); ! 308: ui_plotstring(ui_vsync ? "On " : "Off", 342, 20); ! 309: ; ! 310: ui_plotstring(vdp_layerB ? "On " : "Off", (64+10)*6, 20); ! 311: ui_plotstring(vdp_layerBp ? "On " : "Off", (64+10)*6, 30); ! 312: ui_plotstring(vdp_layerA ? "On " : "Off", (64+10)*6, 40); ! 313: ui_plotstring(vdp_layerAp ? "On " : "Off", (64+10)*6, 50); ! 314: ui_plotstring(vdp_layerW ? "On " : "Off", (78+10)*6, 20); ! 315: ui_plotstring(vdp_layerWp ? "On " : "Off", (78+10)*6, 30); ! 316: ui_plotstring(vdp_layerH ? "On " : "Off", (78+10)*6, 40); ! 317: ui_plotstring(vdp_layerS ? "On " : "Off", (92+10)*6, 20); ! 318: ui_plotstring(vdp_layerSp ? "On " : "Off", (92+10)*6, 30); ! 319: } ! 320: ! 321: /*** ui_loop - main UI loop ***/ ! 322: ! 323: int ui_loop(void) ! 324: { ! 325: char *p; ! 326: ! 327: if (ui_initload) { ! 328: p = gen_loadimage(ui_initload); ! 329: if (p) { ! 330: LOG_CRITICAL(("Failed to load ROM image: %s", p)); ! 331: return 1; ! 332: } ! 333: ui_state = 2; ! 334: } else { ! 335: LOG_CRITICAL(("You must specify a ROM to load")); ! 336: return 1; ! 337: } ! 338: if (uip_vgamode()) { ! 339: LOG_CRITICAL(("Failed to start VGA mode")); ! 340: return 1; ! 341: } ! 342: gen_quit = 0; ! 343: while(!uip_checkkeyboard()) { ! 344: switch(ui_state) { ! 345: case 0: /* stopped */ ! 346: break; ! 347: case 1: /* paused */ ! 348: break; ! 349: case 2: /* playing */ ! 350: ui_newframe(); ! 351: reg68k_framestep(); ! 352: break; ! 353: } ! 354: } ! 355: return 0; ! 356: } ! 357: ! 358: void ui_newframe(void) ! 359: { ! 360: static int hmode = 0; ! 361: static int skipcount = 0; ! 362: static char frameplots[60]; /* 60 for NTSC, 50 for PAL */ ! 363: static unsigned int frameplots_i = 0; ! 364: char buf[8]; ! 365: unsigned int i; ! 366: int fps; ! 367: time_t t = time(NULL); ! 368: struct tm *tm_p = localtime(&t); ! 369: ! 370: if (frameplots_i > vdp_framerate) ! 371: frameplots_i = 0; ! 372: ui_plotframe = 0; ! 373: if (ui_frameskip == 0) { ! 374: if (sound_feedback != -1) ! 375: ui_plotframe = 1; ! 376: } else { ! 377: if (cpu68k_frames % ui_frameskip == 0) ! 378: ui_plotframe = 1; ! 379: } ! 380: if (!ui_plotframe) { ! 381: skipcount++; ! 382: frameplots[frameplots_i++] = 0; ! 383: return; ! 384: } ! 385: if (hmode != (vdp_reg[12]&1)) ! 386: ui_clearnext = 2; ! 387: if (ui_clearnext) { ! 388: /* horizontal size has changed, so clear whole screen and setup ! 389: borders etc again */ ! 390: ui_clearnext--; ! 391: hmode = vdp_reg[12]&1; ! 392: uip_clearscreen(); ! 393: ui_setupscreen(); ! 394: } ! 395: /* count the frames we've plotted in the last vdp_framerate real frames */ ! 396: fps = 0; ! 397: for (i = 0; i < vdp_framerate; i++) { ! 398: if (frameplots[i]) ! 399: fps++; ! 400: } ! 401: frameplots[frameplots_i++] = 1; ! 402: if (!ui_info) ! 403: return; ! 404: ui_plotint2(fps, 156, 420); ! 405: ui_plotint2(skipcount+1, 156, 430); ! 406: skipcount = 0; ! 407: ui_plotint2(tm_p->tm_hour, 610, 470); ! 408: ui_plotint2(tm_p->tm_min, 628, 470); ! 409: } ! 410: ! 411: void ui_checkpalcache(int flag) ! 412: { ! 413: uint32 pal; ! 414: unsigned int col; ! 415: uint8 *p; ! 416: ! 417: /* this code requires that there be at least 4 bits per colour, that ! 418: is, three bits that come from the console's palette, and one more bit ! 419: when we do a dim or bright colour, i.e. this code works with 12bpp ! 420: upwards */ ! 421: ! 422: /* this code assumes 5 bits per colour in it's calculations */ ! 423: ! 424: /* the flag forces it to do the check despite the vdp_cramf buffer */ ! 425: ! 426: for (col = 0; col < 64; col++) { ! 427: if (!flag && !vdp_cramf[col]) ! 428: continue; ! 429: vdp_cramf[col] = 0; ! 430: p = (uint8 *)vdp_cram+2*col; ! 431: ui_palcache[col] = /* normal */ ! 432: (p[0]&0xE)<<(ui_uipinfo.blueshift+1) | ! 433: (p[1]&0xE)<<(ui_uipinfo.redshift+1) | ! 434: ((p[1]&0xE0)>>4)<<(ui_uipinfo.greenshift+1); ! 435: ui_palcache[col+64] = /* hilight */ ! 436: (p[0]&0xE)<<ui_uipinfo.blueshift | ! 437: (p[1]&0xE)<<ui_uipinfo.redshift | ! 438: ((p[1]&0xE0)>>4)<<ui_uipinfo.greenshift | ! 439: (16 << ui_uipinfo.blueshift) | (16 << ui_uipinfo.redshift) | ! 440: (16 << ui_uipinfo.greenshift); ! 441: ui_palcache[col+128] = /* shadow */ ! 442: (p[0]&0xE)<<ui_uipinfo.blueshift | ! 443: (p[1]&0xE)<<ui_uipinfo.redshift | ! 444: ((p[1]&0xE0)>>4)<<ui_uipinfo.greenshift; ! 445: } ! 446: } ! 447: ! 448: /*** ui_convertdata - convert genesis data to 16 bit colour */ ! 449: ! 450: void ui_convertdata(uint8 *indata, uint8 *outdata, unsigned int pixels) ! 451: { ! 452: unsigned int ui; ! 453: uint32 data; ! 454: ! 455: ui_checkpalcache(0); ! 456: /* not scaled, 16bpp */ ! 457: for (ui = 0; ui < pixels; ui++) { ! 458: data = ui_palcache[indata[ui]]; ! 459: ((uint16 *)outdata)[ui] = data; /* already in local endian */ ! 460: } ! 461: } ! 462: ! 463: /*** ui_line - it is time to render a line ***/ ! 464: ! 465: void ui_line(unsigned int line) ! 466: { ! 467: static uint8 gfx[320]; ! 468: uint16 *scr; ! 469: ! 470: if (ui_plotframe && !ui_vdpsimple) { ! 471: if (((vdp_reg[12]>>1) & 3) == 3) ! 472: vdp_renderline_interlace2(line*2+vdp_oddframe, (uint8 *)gfx); ! 473: else ! 474: vdp_renderline(line, (uint8 *)gfx); ! 475: ui_convertdata(gfx, (ui_uipinfo.screenmem_w+320+((vdp_reg[12]&1)?0:64)+ ! 476: ui_uipinfo.linewidth*(120+line+ ! 477: ((vdp_reg[1]&1<<3)?0:8))), ! 478: (vdp_reg[12]&1)?320:256); ! 479: } ! 480: } ! 481: ! 482: /*** ui_endfield - end of field reached ***/ ! 483: ! 484: void ui_endfield(void) ! 485: { ! 486: ui_endframe(); ! 487: } ! 488: ! 489: /*** ui_endframe - end of frame reached ***/ ! 490: ! 491: void ui_endframe(void) ! 492: { ! 493: static uint8 gfx[(320+16)*(240+16)]; ! 494: static int counter = 0; ! 495: unsigned int line; ! 496: uint16 *scr; ! 497: ! 498: if (ui_plotframe) { ! 499: if (ui_vdpsimple) { ! 500: /* cell mode - entire frame done here */ ! 501: vdp_renderframe(gfx+(8*(320+16))+8, 320+16); /* plot frame */ ! 502: for (line = 0; line < vdp_vislines; line++) { ! 503: ui_convertdata(gfx+8+(line+8)*(320+16), ! 504: (ui_uipinfo.screenmem_w+320+((vdp_reg[12]&1)?0:64)+ ! 505: ui_uipinfo.linewidth*(120+line+ ! 506: ((vdp_reg[1]&1<<3)?0:8))), ! 507: (vdp_reg[12]&1)?320:256); ! 508: } ! 509: } ! 510: uip_displaybank(-1); ! 511: if (ui_vsync) ! 512: uip_vsync(); ! 513: } ! 514: if (ui_frameskip == 0) { ! 515: counter++; ! 516: if (sound_feedback >= 0) { ! 517: ui_actualskip = counter; ! 518: counter = 0; ! 519: } ! 520: } else { ! 521: ui_actualskip = ui_frameskip; ! 522: } ! 523: } ! 524: ! 525: /*** logging functions ***/ ! 526: ! 527: /* logging is done this way because this was the best I could come up with ! 528: whilst battling with macros that can only take fixed numbers of arguments */ ! 529: ! 530: #define LOG_FUNC(name,level,txt) void ui_log_ ## name ## (const char *text, ...) \ ! 531: { \ ! 532: va_list ap; \ ! 533: char *ll = ui_loglines[ui_logline]; \ ! 534: char *p = bigbuffer; \ ! 535: if (gen_loglevel >= level) { \ ! 536: p+= sprintf(p, "%d ", ui_logcount++); \ ! 537: p+= sprintf(p, txt); \ ! 538: va_start(ap, text); \ ! 539: vsprintf(p, text, ap); \ ! 540: va_end(ap); \ ! 541: strncpy(ll, bigbuffer, UI_LOGLINESIZE); \ ! 542: if (++ui_logline >= UI_LOGLINES) \ ! 543: ui_logline = 0; \ ! 544: } \ ! 545: } ! 546: ! 547: LOG_FUNC(debug3, 7, "DEBG "); ! 548: LOG_FUNC(debug2, 6, "DEBG "); ! 549: LOG_FUNC(debug1, 5, "DEBG "); ! 550: LOG_FUNC(user, 4, "USER "); ! 551: LOG_FUNC(verbose, 3, "---- "); ! 552: LOG_FUNC(normal, 2, "---- "); ! 553: LOG_FUNC(critical, 1, "CRIT "); ! 554: LOG_FUNC(request, 0, "---- "); ! 555: ! 556: /*** ui_err - log error message and quit ***/ ! 557: ! 558: void ui_err(const char *text, ...) ! 559: { ! 560: va_list ap; ! 561: char *ll = ui_loglines[ui_logline]; ! 562: char *p = bigbuffer; ! 563: ! 564: p+= sprintf(p, "ERROR: "); ! 565: va_start(ap, text); ! 566: vsprintf(p, text, ap); ! 567: va_end(ap); ! 568: strncpy(ll, bigbuffer, UI_LOGLINESIZE); ! 569: if (++ui_logline >= UI_LOGLINES) ! 570: ui_logline = 0; ! 571: ui_printlog(); ! 572: exit(0); /* don't exit(1) because windows makes an error then! */ ! 573: } ! 574: ! 575: /*** ui_setinfo - there is new cart information ***/ ! 576: ! 577: char *ui_setinfo(t_cartinfo *cartinfo) ! 578: { ! 579: return NULL; ! 580: } ! 581: ! 582: /*** ui_topbit - given an integer return the top most bit set ***/ ! 583: ! 584: int ui_topbit(unsigned long int bits) ! 585: { ! 586: long int bit = 31; ! 587: unsigned long int mask = 1<<31; ! 588: ! 589: for (; bit >= 0; bit--, mask>>= 1) { ! 590: if (bits & mask) ! 591: return bit; ! 592: } ! 593: return -1; ! 594: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.