gui.cpp
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include "compat.h" 5 #include "baselayer.h" 6 #include "build.h" 7 #include "common_game.h" 8 #include "gfx.h" 9 #include "globals.h" 10 #include "gui.h" 11 #include "keyboard.h" 12 #include "resource.h" 13 #include "screen.h" 14 #include "music.h" 15 16 17 Resource gGuiRes; 18 19 QFONT* pFont; 20 21 QBITMAP* pMouseCursor; 22 23 inline char ScanToAsciiShifted(int scan) 24 { 25 if (scan < 128) 26 return g_keyAsciiTableShift[scan]; 27 return 0; 28 } 29 30 int blinkClock; 31 32 void SetBlinkOn(void) 33 { 34 blinkClock = 0; 35 } 36 37 void SetBlinkOff(void) 38 { 39 blinkClock = 60; 40 } 41 42 char IsBlinkOn(void) 43 { 44 return blinkClock < 60; 45 } 46 47 void UpdateBlinkClock(int n) 48 { 49 blinkClock += n; 50 while (blinkClock >= 100) 51 blinkClock -= 100; 52 } 53 54 void CenterLabel(int a1, int a2, const char *a3, int a4) 55 { 56 if (pFont) 57 a2 -= pFont->at13/2; 58 59 a1 -= gfxGetLabelLen(a3, pFont) / 2; 60 gfxDrawLabel(a1, a2, a4, a3, pFont); 61 } 62 63 void DrawBevel(int x0, int y0, int x1, int y1, int c0, int c1) 64 { 65 gColor = c0; 66 gfxHLine(y0, x0, x1 - 2); 67 gfxVLine(x0, y0 + 1, y1 - 2); 68 gColor = c1; 69 gfxHLine(y1 - 1, x0 + 1, x1 - 1); 70 gfxVLine(x1 - 1, y0 + 1, y1 - 2); 71 } 72 73 void DrawRect(int x0, int y0, int x1, int y1, int c) 74 { 75 gColor = c; 76 gfxHLine(y0, x0, x1 - 1); 77 gfxHLine(y1 - 1, x0, x1 - 1); 78 gfxVLine(x0, y0 + 1, y1 - 2); 79 gfxVLine(x1 - 1, y0 + 1, y1 - 2); 80 } 81 82 void DrawButtonFace(int x0, int y0, int x1, int y1, char a5) 83 { 84 gColor = gStdColor[20]; 85 gfxFillBox(x0, y0, x1, y1); 86 87 if (a5) 88 { 89 gColor = gStdColor[26]; 90 gfxHLine(y0, x0, x1 - 1); 91 gfxVLine(x0, y0 + 1, y1 - 1); 92 gColor = gStdColor[24]; 93 gfxHLine(y0 + 1, x0 + 1, x1 - 1); 94 gfxVLine(x0 + 1, y0 + 2, y1 - 1); 95 DrawBevel(x0+2, y0+2, x1, y1, gStdColor[19], gStdColor[22]); 96 } 97 else 98 { 99 DrawBevel(x0, y0, x1, y1, gStdColor[16], gStdColor[24]); 100 DrawBevel(x0+1, y0+1, x1-1, y1-1, gStdColor[18], gStdColor[22]); 101 } 102 } 103 104 void DrawMouseCursor(int x, int y) 105 { 106 dassert(pMouseCursor != NULL); 107 108 gfxDrawBitmap(pMouseCursor, x, y); 109 } 110 111 char GetHotKey(const char *pzLabel) 112 { 113 for (const char* s = pzLabel; *s != 0; s++) 114 { 115 if (*s == '&') 116 return (char)toupper(*(s+1)); 117 } 118 return 0; 119 } 120 121 Label::Label(int a1, int a2, const char* a3) : Widget(a1, a2, 0, 0) 122 { 123 at8 = strlen(a3); 124 strcpy(at24, a3); 125 } 126 127 void Label::Paint(int x, int y, char) 128 { 129 gfxDrawLabel(x, y, gStdColor[0], at24, pFont); 130 } 131 132 Container::Container(int a1, int a2, int a3, int a4) : Widget(a1, a2, a3, a4) 133 { 134 at1e = 1; 135 at24 = 0; 136 at25 = MODAL_RESULT_0; 137 138 at2e.at10 = at2e.at14 = &at2e; 139 at26 = &at2e; 140 141 at2a = NULL; 142 } 143 144 Container::~Container() 145 { 146 for (Widget* pWidget = at2e.at14; pWidget != &at2e; pWidget = at2e.at14) 147 { 148 Remove(pWidget); 149 delete pWidget; 150 } 151 } 152 153 char Container::SetFocus(int a1) 154 { 155 do 156 { 157 if (at26->at1e && ((Container*)at26)->SetFocus(a1)) 158 return 1; 159 if (a1 > 0) 160 at26 = at26->at14; 161 else 162 at26 = at26->at10; 163 if (at26 == &at2e) 164 return 0; 165 } while (!at26->at1c); 166 return 1; 167 } 168 169 void Container::Insert(Widget* widget) 170 { 171 dassert(widget != NULL); 172 widget->at10 = at2e.at10; 173 widget->at14 = &at2e; 174 widget->at10->at14 = widget; 175 widget->at14->at10 = widget; 176 widget->at18 = this; 177 } 178 179 void Container::Remove(Widget* widget) 180 { 181 dassert(widget != NULL); 182 widget->at10->at14 = widget->at14; 183 widget->at14->at10 = widget->at10; 184 } 185 186 void Container::Paint(int x, int y, char a3) 187 { 188 UNREFERENCED_PARAMETER(a3); 189 for (Widget* pWidget = at2e.at14; pWidget != &at2e; pWidget = pWidget->at14) 190 { 191 pWidget->Paint(x + pWidget->at0, y + pWidget->at4, at26 == pWidget); 192 } 193 } 194 195 void Container::HandleEvent(GEVENT* event) 196 { 197 if (event->at0 & GEVENT_TYPE_MOUSE_MASK) 198 { 199 event->at6.mouse.at8 -= at0; 200 event->at6.mouse.atc -= at4; 201 if (event->at0 == 1) 202 { 203 at2a = NULL; 204 for (Widget* pWidget = at2e.at10; pWidget != &at2e; pWidget = pWidget->at10) 205 { 206 if (pWidget->Inside(event->at6.mouse.at8, event->at6.mouse.atc)) 207 { 208 at2a = pWidget; 209 if (pWidget->at1c) 210 at26 = pWidget; 211 break; 212 } 213 } 214 } 215 if (at2a) 216 at2a->HandleEvent(event); 217 return; 218 } 219 else if (event->at0 == GEVENT_TYPE_KEYBOARD) 220 { 221 if (event->at6.keyboard.at2.bits.at2 && g_keyAsciiTableShift[event->at6.keyboard.at1]) 222 { 223 for (Widget* pWidget = at2e.at10; pWidget != &at2e; pWidget = pWidget->at10) 224 { 225 if (pWidget->at1f == g_keyAsciiTableShift[event->at6.keyboard.at1] && pWidget->at1c) 226 { 227 at26 = pWidget; 228 at26->HandleEvent(event); 229 return; 230 } 231 } 232 } 233 at26->HandleEvent(event); 234 235 if (event->at0 != GEVENT_TYPE_NONE) 236 { 237 for (Widget* pWidget = at2e.at10; pWidget != &at2e; pWidget = pWidget->at10) 238 { 239 if (pWidget->at1f == g_keyAsciiTableShift[event->at6.keyboard.at1] && pWidget->at1c) 240 { 241 at26 = pWidget; 242 at26->HandleEvent(event); 243 return; 244 } 245 } 246 } 247 } 248 } 249 250 void Container::EndModal(MODAL_RESULT result) 251 { 252 if (at24) 253 { 254 at24 = 0; 255 at25 = result; 256 return; 257 } 258 at18->EndModal(result); 259 } 260 261 void Panel::Paint(int x, int y, char a3) 262 { 263 gColor = gStdColor[20]; 264 gfxFillBox(x, y, x + at8, y + atc); 265 int j = 0; 266 for (int i = klabs(at52); i > 0; i--, j++) 267 { 268 if (at52 > 0) 269 { 270 DrawBevel(x+j,y+j,x+at8-j,y+atc-j, gStdColor[16], gStdColor[24]); 271 } 272 else 273 { 274 DrawBevel(x+j,y+j,x+at8-j,y+atc-j, gStdColor[24], gStdColor[16]); 275 } 276 } 277 j += at56; 278 for (int i = klabs(at5a); i > 0; i--, j++) 279 { 280 if (at5a > 0) 281 { 282 DrawBevel(x+j,y+j,x+at8-j,y+atc-j, gStdColor[16], gStdColor[24]); 283 } 284 else 285 { 286 DrawBevel(x+j,y+j,x+at8-j,y+atc-j, gStdColor[24], gStdColor[16]); 287 } 288 } 289 Container::Paint(x, y, a3); 290 } 291 292 TitleBar::TitleBar(int a1, int a2, int a3, int a4, const char *a5) : Widget(a1, a2, a3, a4) 293 { 294 strcpy(at24, a5); 295 at124 = strlen(a5); 296 } 297 298 void TitleBar::Paint(int x, int y, char a3) 299 { 300 UNREFERENCED_PARAMETER(a3); 301 gColor = gStdColor[1]; 302 gfxFillBox(x, y, x + at8, y + atc); 303 DrawBevel(x, y, x + at8, y + atc, gStdColor[9], gStdColor[30]); 304 CenterLabel(x + at8 / 2, y + atc / 2, at24, gStdColor[15]); 305 } 306 307 void TitleBar::HandleEvent(GEVENT *event) 308 { 309 if (event->at0 & GEVENT_TYPE_MOUSE_MASK) 310 { 311 if (event->at6.mouse.at4 == 0) 312 { 313 if (event->at0 == GEVENT_TYPE_MOUSE_8) 314 { 315 at18->at0 += event->at6.mouse.at10; 316 at18->at4 += event->at6.mouse.at14; 317 event->at0 = GEVENT_TYPE_NONE; 318 } 319 } 320 } 321 } 322 323 Win::Win(int a1, int a2, int a3, int a4, const char* a5) : Panel(a1, a2, a3, a4, 1, 1, -1) 324 { 325 at62 = new TitleBar(3, 3, a3-6, 12, a5); 326 at5e = new Container(3, 15, a3-6, a4-18); 327 Insert(at62); 328 Insert(at5e); 329 at2a = NULL; 330 } 331 332 Button::Button(int a1, int a2, int a3, int a4, MODAL_RESULT a5) : Widget(a1, a2, a3, a4) 333 { 334 at24 = a5; 335 at25 = NULL; 336 at29 = 0; 337 } 338 339 Button::Button(int a1, int a2, int a3, int a4, void (*a5)(Widget*)) : Widget(a1, a2, a3, a4) 340 { 341 at24 = MODAL_RESULT_0; 342 at25 = a5; 343 at29 = 0; 344 } 345 346 void Button::Paint(int x, int y, char a3) 347 { 348 UNREFERENCED_PARAMETER(a3); 349 gColor = gStdColor[0]; 350 gfxHLine(y, x + 1, x + at8 - 2); 351 gfxHLine(y + atc - 1, x + 1, x + at8 - 2); 352 gfxVLine(x, y + 1, y + atc - 2); 353 gfxVLine(x + at8 - 1, y + 1, y + atc - 2); 354 DrawButtonFace(x + 1, y + 1, x + at8 - 1, y + atc - 1, at29); 355 } 356 357 void Button::HandleEvent(GEVENT* event) 358 { 359 if (event->at0 == GEVENT_TYPE_KEYBOARD) 360 { 361 if (event->at6.keyboard.at0 == ' ' || ScanToAsciiShifted(event->at6.keyboard.at1) == at1f) 362 { 363 at29 = !at29; 364 if (at25) 365 at25(this); 366 if (at24) 367 EndModal(at24); 368 event->at0 = GEVENT_TYPE_NONE; 369 } 370 } 371 else if ((event->at0 & GEVENT_TYPE_MOUSE_MASK) && event->at6.mouse.at4 == 0) 372 { 373 switch (event->at0) 374 { 375 case GEVENT_TYPE_MOUSE_1: 376 at29 = 1; 377 at0 = GEVENT_TYPE_NONE; 378 break; 379 case GEVENT_TYPE_MOUSE_8: 380 at29 = Inside(event->at6.mouse.at8, event->at6.mouse.atc); 381 at0 = GEVENT_TYPE_NONE; 382 break; 383 case GEVENT_TYPE_MOUSE_2: 384 at29 = 0; 385 if (Inside(event->at6.mouse.at8, event->at6.mouse.atc)) 386 { 387 if (at25) 388 at25(this); 389 if (at24) 390 EndModal(at24); 391 } 392 at0 = GEVENT_TYPE_NONE; 393 break; 394 default: 395 break; 396 } 397 } 398 } 399 400 TextButton::TextButton(int a1, int a2, int a3, int a4, const char *a5, MODAL_RESULT a6) : Button(a1, a2, a3, a4, a6) 401 { 402 at2a = a5; 403 at1f = GetHotKey(a5); 404 at1c = 1; 405 } 406 407 void TextButton::Paint(int x, int y, char a3) 408 { 409 gColor = gStdColor[0]; 410 gfxHLine(y + 1, x + 2, x + at8 - 3); 411 gfxHLine(y + atc - 2, y + 2, x + at8 - 3); 412 gfxVLine(x + 1, y + 2, y + atc - 3); 413 gfxVLine(x + at8 - 2, y + 2, y + atc - 3); 414 if (a3) 415 { 416 gColor = gStdColor[15]; 417 gfxHLine(y, x + 1, x + at8 - 2); 418 gfxHLine(y + atc - 1, x + 1, x + at8 - 2); 419 gfxVLine(x, y + 1, y + atc - 2); 420 gfxVLine(x + at8 - 1, y + 1, y + atc - 2); 421 gfxPixel(x + 1, y + 1); 422 gfxPixel(x + at8 - 2, y + 1); 423 gfxPixel(x + 1, y + atc - 2); 424 gfxPixel(x + at8 - 2, y + atc - 2); 425 } 426 DrawButtonFace(x + 2, y + 2, x + at8 - 2, y + atc - 2, at29); 427 if (at29) 428 CenterLabel(x + at8 / 2 + 1, y + atc / 2 + 1, at2a, gStdColor[0]); 429 else 430 CenterLabel(x + at8 / 2, y + atc / 2, at2a, gStdColor[0]); 431 } 432 433 void TextButton::HandleEvent(GEVENT* event) 434 { 435 if (event->at0 == GEVENT_TYPE_KEYBOARD && ScanToAsciiShifted(event->at6.keyboard.at1) == at1f) 436 { 437 at29 = !at29; 438 if (at25) 439 at25(this); 440 if (at24) 441 EndModal(at24); 442 event->at0 = GEVENT_TYPE_NONE; 443 } 444 Button::HandleEvent(event); 445 } 446 447 void BitButton::Paint(int x, int y, char a3) 448 { 449 UNREFERENCED_PARAMETER(a3); 450 gColor = gStdColor[0]; 451 gfxHLine(y, x + 1, x + at8 - 2); 452 gfxHLine(y + atc -1, x + 1, x + at8 - 2); 453 gfxVLine(x, y + 1, y + atc - 2); 454 gfxVLine(x + at8 - 1, y + 1, y + atc - 2); 455 DrawButtonFace(x + 1, y + 1, x + at8 - 1, y + atc - 1, at29); 456 457 int bx = x + at8 / 2; 458 int by = y + atc / 2; 459 QBITMAP* pQBM = (QBITMAP*)gGuiRes.Load(bitmap); 460 461 if (at29) 462 gfxDrawBitmap(pQBM, bx - pQBM->at2 / 2 + 1, by - pQBM->at4 / 2 + 1); 463 else 464 gfxDrawBitmap(pQBM, bx - pQBM->at2 / 2, by - pQBM->at4 / 2); 465 } 466 467 EditText::EditText(int a1, int a2, int a3, int a4, const char *a5) : Widget(a1,a2,a3,a4) 468 { 469 at1c = 1; 470 strcpy(at24, a5); 471 at128 = at124 = strlen(a5); 472 at12c = a3 / 8 - 1; 473 } 474 475 void EditText::Paint(int x, int y, char a3) 476 { 477 DrawBevel(x, y, x + at8 - 1, y + atc - 1, gStdColor[24], gStdColor[16]); 478 DrawRect(x + 1, y + 1, x + at8 - 2, y + atc - 2, gStdColor[0]); 479 gColor = gStdColor[a3 ? 15 : 20]; 480 gfxFillBox(x + 2, y + 2, x + at8 - 3, y + atc - 3); 481 gfxDrawText(x + 3, y + atc / 2 - 4, gStdColor[0], at24, pFont); 482 483 if (a3 && IsBlinkOn()) 484 { 485 gColor = gStdColor[0]; 486 y += atc / 2; 487 gfxVLine(x + gfxGetTextNLen(at24, pFont, at128) + 3, y - 4, y + 3); 488 } 489 } 490 491 void EditText::HandleEvent(GEVENT *event) 492 { 493 if (event->at0 & GEVENT_TYPE_MOUSE_MASK) 494 { 495 if (event->at6.mouse.at4 == 0) 496 { 497 switch (event->at0) 498 { 499 case GEVENT_TYPE_MOUSE_1: 500 case GEVENT_TYPE_MOUSE_8: 501 at128 = gfxFindTextPos(at24, pFont, event->at6.mouse.at8 - at0); 502 SetBlinkOn(); 503 event->at0 = GEVENT_TYPE_NONE; 504 break; 505 default: 506 break; 507 } 508 } 509 } 510 else if (event->at0 == GEVENT_TYPE_KEYBOARD) 511 { 512 switch (event->at6.keyboard.at1) 513 { 514 case sc_BackSpace: 515 if (at128 > 0) 516 { 517 memmove(at24+at128-1, at24+at128, at124-at128); 518 at128--; 519 at124--; 520 at24[at124] = 0; 521 } 522 event->at0 = GEVENT_TYPE_NONE; 523 SetBlinkOn(); 524 break; 525 case sc_Delete: 526 if (at128 < at124) 527 { 528 at124--; 529 memmove(at24+at128, at24+at128+1, at124-at128); 530 at24[at124] = 0; 531 } 532 event->at0 = GEVENT_TYPE_NONE; 533 SetBlinkOn(); 534 break; 535 case sc_LeftArrow: 536 if (at128 > 0) 537 at128--; 538 event->at0 = GEVENT_TYPE_NONE; 539 SetBlinkOn(); 540 break; 541 case sc_RightArrow: 542 if (at128 < at124) 543 at128++; 544 event->at0 = GEVENT_TYPE_NONE; 545 SetBlinkOn(); 546 break; 547 case sc_Home: 548 at128 = 0; 549 event->at0 = GEVENT_TYPE_NONE; 550 SetBlinkOn(); 551 break; 552 case sc_End: 553 at128 = at124; 554 event->at0 = GEVENT_TYPE_NONE; 555 SetBlinkOn(); 556 break; 557 default: 558 if (event->at6.keyboard.at0) 559 { 560 if (at124 < at12c) 561 { 562 memmove(at24+at128+1,at24+at128,at124-at128); 563 at24[at128++] = event->at6.keyboard.at0; 564 at124++; 565 at24[at124] = 0; 566 } 567 event->at0 = GEVENT_TYPE_NONE; 568 } 569 SetBlinkOn(); 570 break; 571 } 572 } 573 } 574 575 EditNumber::EditNumber(int a1, int a2, int a3, int a4, int a5) : EditText(a1, a2, a3, a4, "") 576 { 577 at130 = a5; 578 snprintf(at24, 0x100, "%i", a5); 579 at128 = at124 = strlen(at24); 580 } 581 582 void EditNumber::HandleEvent(GEVENT *event) 583 { 584 if (event->at0 == GEVENT_TYPE_KEYBOARD) 585 { 586 switch (event->at6.keyboard.at1) 587 { 588 case sc_Minus: 589 if (at128 == 0 && at24[0] != '-' && at124 < at12c) 590 { 591 memmove(at24+1, at24, at124); 592 at24[at128++] = '-'; 593 at124++; 594 at24[at124] = 0; 595 } 596 event->at0 = GEVENT_TYPE_NONE; 597 break; 598 case sc_BackSpace: 599 break; 600 case sc_Delete: 601 break; 602 case sc_LeftArrow: 603 break; 604 case sc_RightArrow: 605 break; 606 case sc_Home: 607 break; 608 case sc_End: 609 break; 610 default: 611 if (event->at6.keyboard.at0) 612 { 613 if (event->at6.keyboard.at0 >= '0' && event->at6.keyboard.at0 <= '9' && at124 < at12c) 614 { 615 memmove(at24+at128+1,at24+at128,at124-at128); 616 at24[at128++] = event->at6.keyboard.at0; 617 at124++; 618 at24[at124] = 0; 619 } 620 event->at0 = GEVENT_TYPE_NONE; 621 } 622 break; 623 } 624 } 625 EditText::HandleEvent(event); 626 at130 = atoi(at24); 627 } 628 629 void ThumbButton::HandleEvent(GEVENT* event) 630 { 631 if (event->at0 & GEVENT_TYPE_MOUSE_MASK) 632 { 633 if (event->at6.mouse.at4 == 0) 634 { 635 switch (event->at0) 636 { 637 case GEVENT_TYPE_MOUSE_8: 638 at4 = ClipRange(event->at6.mouse.atc-atc/2, 10, at18->atc-10-atc); 639 break; 640 case GEVENT_TYPE_MOUSE_1: 641 at29 = 1; 642 break; 643 case GEVENT_TYPE_MOUSE_2: 644 at29 = 0; 645 break; 646 default: 647 break; 648 } 649 } 650 } 651 } 652 653 void ScrollButton::HandleEvent(GEVENT* event) 654 { 655 if (event->at0 & GEVENT_TYPE_MOUSE_MASK) 656 { 657 if (event->at6.mouse.at4 == 0) 658 { 659 switch (event->at0) 660 { 661 case GEVENT_TYPE_MOUSE_1: 662 at29 = 1; 663 if (at25) 664 at25(this); 665 break; 666 case GEVENT_TYPE_MOUSE_8: 667 at29 = Inside(event->at6.mouse.at8, event->at6.mouse.atc); 668 break; 669 case GEVENT_TYPE_MOUSE_4: 670 if (at29 || at25) 671 at25(this); 672 break; 673 case GEVENT_TYPE_MOUSE_2: 674 at29 = 0; 675 break; 676 default: 677 break; 678 } 679 } 680 } 681 } 682 683 void ScrollLineUp(Widget* widget) 684 { 685 ((ScrollBar*)widget->at18)->ScrollRelative(-1); 686 } 687 688 void ScrollLineDown(Widget* widget) 689 { 690 ((ScrollBar*)widget->at18)->ScrollRelative(1); 691 } 692 693 ScrollBar::ScrollBar(int a1, int a2, int a3, int a4, int a5, int a6) : Container(a1, a2, 13, a3) 694 { 695 at52 = a4; 696 at56 = a5; 697 at6e = a6; 698 699 at5e = new ScrollButton(1, 1, 11, 10, gGuiRes.Lookup("UPARROW", "QBM"), ScrollLineUp); 700 at62 = new ScrollButton(1, a3-11, 11, 10, gGuiRes.Lookup("DNARROW", "QBM"), ScrollLineDown); 701 at6a = new ThumbButton(1, 10, 11, 20); 702 703 Insert(at5e); 704 Insert(at62); 705 Insert(at6a); 706 707 at5a = 0; 708 } 709 710 void ScrollBar::ScrollRelative(int a1) 711 { 712 at6a->at4 = ClipRange(at6a->at4 + a1, 10, atc - 10 - at6a->atc); 713 } 714 715 void ScrollBar::Paint(int x, int y, char a1) 716 { 717 DrawBevel(x, y, x + at8, y + atc, gStdColor[24], gStdColor[16]); 718 DrawRect(x + 1, y + 1, x + at8 - 1, y + atc - 1, gStdColor[0]); 719 gColor = gStdColor[24]; 720 gfxFillBox(x + 2, y + 2, x + at8 - 2, y + atc - 2); 721 722 Container::Paint(x, y, a1); 723 } 724 725 int MouseX, MouseY, MousedX, MousedY; 726 727 GEVENT_TYPE GetEvent(GEVENT* event) 728 { 729 memset(event, 0, sizeof(GEVENT)); 730 731 char key = keyGetScan(); 732 if (key) 733 { 734 if (keystatus[sc_LeftShift]) 735 event->at6.keyboard.at2.bits.at3 = 1; 736 if (keystatus[sc_RightShift]) 737 event->at6.keyboard.at2.bits.at4 = 1; 738 event->at6.keyboard.at2.bits.at0 = event->at6.keyboard.at2.bits.at3 | event->at6.keyboard.at2.bits.at4; 739 if (keystatus[sc_LeftControl]) 740 event->at6.keyboard.at2.bits.at5 = 1; 741 if (keystatus[sc_RightShift]) 742 event->at6.keyboard.at2.bits.at6 = 1; 743 event->at6.keyboard.at2.bits.at1 = event->at6.keyboard.at2.bits.at5 | event->at6.keyboard.at2.bits.at6; 744 if (keystatus[sc_LeftAlt]) 745 event->at6.keyboard.at2.bits.at7 = 1; 746 if (keystatus[sc_RightAlt]) 747 event->at6.keyboard.at2.bits.at8 = 1; 748 event->at6.keyboard.at2.bits.at2 = event->at6.keyboard.at2.bits.at7 | event->at6.keyboard.at2.bits.at8; 749 if (event->at6.keyboard.at2.bits.at2) 750 event->at6.keyboard.at0 = 0; 751 else if (event->at6.keyboard.at2.bits.at1) 752 event->at6.keyboard.at0 = 0; 753 else if (event->at6.keyboard.at2.bits.at0) 754 event->at6.keyboard.at0 = key < 128 ? g_keyAsciiTableShift[key] : 0; 755 else 756 event->at6.keyboard.at0 = key < 128 ? g_keyAsciiTable[key] : 0; 757 event->at0 = GEVENT_TYPE_KEYBOARD; 758 event->at6.keyboard.at1 = key; 759 if (key == sc_Escape) 760 keystatus[sc_Escape] = 0; 761 return event->at0; 762 } 763 764 event->at6.mouse.at10 = MousedX; 765 event->at6.mouse.at14 = MousedY; 766 event->at6.mouse.at8 = MouseX; 767 event->at6.mouse.atc = MouseY; 768 769 static int oldbuttons; 770 static ClockTicks clickTime[5], downTime[5]; 771 int buttons = mouseReadButtons(); 772 773 int delta = buttons & ~oldbuttons; 774 775 for (int i = 0, j = 1; i < 5; i++, j <<= 1) 776 { 777 event->at6.mouse.at4 = i; 778 if (delta & j) 779 { 780 oldbuttons |= j; 781 event->at0 = GEVENT_TYPE_MOUSE_1; 782 if (clickTime[i]+60 < gFrameClock) 783 event->at6.mouse.at18 = 1; 784 clickTime[i] = gFrameClock; 785 downTime[i] = 0; 786 return event->at0; 787 } 788 else if (oldbuttons & j) 789 { 790 if (buttons & j) 791 { 792 downTime[i] += gFrameTicks; 793 if (event->at6.mouse.at10 || event->at6.mouse.at14) 794 { 795 event->at0 = GEVENT_TYPE_MOUSE_8; 796 return event->at0; 797 } 798 else if (downTime[i] > 60) 799 { 800 downTime[i] -= 6; 801 event->at0 = GEVENT_TYPE_MOUSE_4; 802 return event->at0; 803 } 804 } 805 else 806 { 807 oldbuttons &= ~j; 808 event->at0 = GEVENT_TYPE_MOUSE_2; 809 return event->at0; 810 } 811 } 812 } 813 return GEVENT_TYPE_NONE; 814 } 815 816 MODAL_RESULT ShowModal(Container* container) 817 { 818 Container screen(0, 0, xdim, ydim); 819 820 screen.Insert(container); 821 822 container->at0 = (xdim - container->at8) / 2; 823 container->at4 = (ydim - container->atc) / 2; 824 825 int vc = xdim * ydim; 826 827 while (!screen.SetFocus(1)) {} 828 829 DICTNODE* hMouseCursor = gGuiRes.Lookup("MOUSE1", "QBM"); 830 dassert(hMouseCursor != NULL); 831 pMouseCursor = (QBITMAP*)gGuiRes.Lock(hMouseCursor); 832 833 DICTNODE* hFont = gGuiRes.Lookup("FONT1", "QFN"); 834 dassert(hFont != NULL); 835 pFont = (QFONT*)gGuiRes.Lock(hFont); 836 837 char* pFrameBackup = NULL; 838 839 if (videoGetRenderMode() == REND_CLASSIC) 840 { 841 pFrameBackup = (char*)Xmalloc(vc); 842 videoBeginDrawing(); 843 memcpy(pFrameBackup, (void*)frameplace, vc); 844 videoEndDrawing(); 845 } 846 847 MouseX = scale(g_mouseAbs.x, xdim, xres); 848 MouseY = scale(g_mouseAbs.y, ydim, yres); 849 850 container->at24 = 1; 851 while (container->at24) 852 { 853 gFrameTicks = totalclock - gFrameClock; 854 gFrameClock += gFrameTicks; 855 UpdateBlinkClock((int)gFrameTicks); 856 gameHandleEvents(); 857 MUSIC_Update(); 858 859 int nMouseX, nMouseY; 860 861 nMouseX = scale(g_mouseAbs.x, xdim, xres); 862 nMouseY = scale(g_mouseAbs.y, ydim, yres); 863 864 MousedX = nMouseX - MouseX; 865 MousedY = nMouseY - MouseY; 866 867 MouseX = nMouseX; 868 MouseY = nMouseY; 869 870 GEVENT event; 871 GetEvent(&event); 872 if (event.at0 == GEVENT_TYPE_KEYBOARD) 873 { 874 switch (event.at6.keyboard.at1) 875 { 876 case sc_Escape: 877 container->EndModal(MODAL_RESULT_2); 878 continue; 879 case sc_Return: 880 container->EndModal(MODAL_RESULT_1); 881 continue; 882 case sc_Tab: 883 if (event.at6.keyboard.at2.bits.at0) 884 { 885 while (!screen.SetFocus(-1)) {} 886 } 887 else 888 { 889 while (!screen.SetFocus(1)) {} 890 } 891 continue; 892 } 893 } 894 screen.HandleEvent(&event); 895 if (videoGetRenderMode() == REND_CLASSIC) 896 { 897 videoBeginDrawing(); 898 memcpy((void*)frameplace, pFrameBackup, vc); 899 videoEndDrawing(); 900 } 901 screen.Paint(0, 0, 0); 902 DrawMouseCursor(MouseX, MouseY); 903 scrNextPage(); 904 } 905 906 if (videoGetRenderMode() == REND_CLASSIC) 907 { 908 videoBeginDrawing(); 909 memcpy((void*)frameplace, pFrameBackup, vc); 910 videoEndDrawing(); 911 } 912 scrNextPage(); 913 914 gGuiRes.Unlock(hMouseCursor); 915 pMouseCursor = NULL; 916 917 gGuiRes.Unlock(hFont); 918 pFont = NULL; 919 920 Xfree(pFrameBackup); 921 922 screen.Remove(container); 923 924 return container->at25; 925 } 926 927 int GetNumberBox(const char* a1, int a2, int a3) 928 { 929 Win window(0, 0, 168, 40, a1); 930 EditNumber* editnumber = new EditNumber(4, 4, 154, 16, a2); 931 932 window.at5e->Insert(editnumber); 933 934 ShowModal(&window); 935 936 if (window.at25 != MODAL_RESULT_1) 937 return a3; 938 939 return editnumber->at130; 940 } 941 942 void Label::HandleEvent(GEVENT*) 943 { 944 } 945 946 void HeadWidget::HandleEvent(GEVENT*) 947 { 948 } 949 950 void HeadWidget::Paint(int, int, char) 951 { 952 } 953 954 HeadWidget::HeadWidget(void) : Widget(0, 0, 0, 0) 955 { 956 } 957 958 void Widget::EndModal(MODAL_RESULT a1) 959 { 960 at18->EndModal(a1); 961 } 962 963 Widget::~Widget() 964 { 965 } 966 967 Widget::Widget(int a1, int a2, int a3, int a4) 968 { 969 at1c = 0; 970 at1d = 0; 971 at1e = 0; 972 at1f = 0; 973 974 at0 = a1; 975 at4 = a2; 976 at8 = a3; 977 atc = a4; 978 979 at10 = NULL; 980 at14 = NULL; 981 at18 = NULL; 982 } 983 984 Panel::Panel(int a1, int a2, int a3, int a4, int a5, int a6, int a7) : Container(a1, a2, a3, a4) 985 { 986 at52 = a5; 987 at56 = a6; 988 at5a = a7; 989 at1c = 0; 990 } 991 992 BitButton::BitButton(int a1, int a2, int a3, int a4, DICTNODE* _bitmap, void(*a6)(Widget*)) : Button(a1, a2, a3, a4, a6) 993 { 994 bitmap = _bitmap; 995 } 996 997 ThumbButton::ThumbButton(int a1, int a2, int a3, int a4) : Button(a1, a2, a3, a4, MODAL_RESULT_0) 998 { 999 } 1000 1001 ScrollButton::ScrollButton(int a1, int a2, int a3, int a4, DICTNODE* _bitmap, void(*a6)(Widget*)) : BitButton(a1, a2, a3, a4, _bitmap, a6) 1002 { 1003 }