this repo has no description
at main 4900 lines 114 kB view raw
1/* 2 OSGLUSDL.c 3 4 Copyright (C) 2012 Paul C. Pratt, Manuel Alfayate 5 6 You can redistribute this file and/or modify it under the terms 7 of version 2 of the GNU General Public License as published by 8 the Free Software Foundation. You should have received a copy 9 of the license along with this file; see the file COPYING. 10 11 This file is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 license for more details. 15*/ 16 17/* 18 Operating System GLUe for SDL (1.2 and 2.0) library 19 20 All operating system dependent code for the 21 SDL Library should go here. 22 23 This is also the "reference" implementation. General 24 comments about what the platform dependent code 25 does should go here, and not be repeated for each 26 platform. Such comments are labeled with "OSGLUxxx common". 27 28 The SDL port can be used to create a more native port. Once 29 the SDL port runs on a new platform, the source code for 30 Mini vMac and SDL can be merged together. Then any SDL code 31 not used for this platform is removed, then a lot of clean 32 up is done step by step to remove the rest of the SDL code. 33 This technique is particular useful if you are not very 34 familiar with the new platform. It is long but straightforward, 35 and you can learn about the platform as you go. The Cocoa 36 port was created this way, with no previous knowledge of 37 Cocoa or Objective-C. 38 39 The main entry point 'main' is at the end of this file. 40*/ 41 42#include "OSGCOMUI.h" 43#include "OSGCOMUD.h" 44 45#ifdef WantOSGLUSDL 46 47/* --- some simple utilities --- */ 48 49GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount) 50{ 51 (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount); 52} 53 54/* --- control mode and internationalization --- */ 55 56#define NeedCell2PlainAsciiMap 1 57 58#define dbglog_OSGInit (0 && dbglog_HAVE) 59 60#include "INTLCHAR.h" 61 62#ifndef SDL_MAJOR_VERSION 63#define SDL_MAJOR_VERSION 0 64#endif 65 66#ifndef CanGetAppPath 67#if 2 == SDL_MAJOR_VERSION 68#define CanGetAppPath 1 69#else 70#define CanGetAppPath 0 71#endif 72#endif 73 74LOCALVAR char *d_arg = NULL; 75LOCALVAR char *n_arg = NULL; 76 77#if CanGetAppPath 78LOCALVAR char *app_parent = NULL; 79LOCALVAR char *pref_dir = NULL; 80#endif 81 82#ifdef _WIN32 83#define MyPathSep '\\' 84#else 85#define MyPathSep '/' 86#endif 87 88LOCALFUNC tMacErr ChildPath(char *x, char *y, char **r) 89{ 90 tMacErr err = mnvm_miscErr; 91 int nx = strlen(x); 92 int ny = strlen(y); 93 { 94 if ((nx > 0) && (MyPathSep == x[nx - 1])) { 95 --nx; 96 } 97 { 98 int nr = nx + 1 + ny; 99 char *p = malloc(nr + 1); 100 if (p != NULL) { 101 char *p2 = p; 102 (void) memcpy(p2, x, nx); 103 p2 += nx; 104 *p2++ = MyPathSep; 105 (void) memcpy(p2, y, ny); 106 p2 += ny; 107 *p2 = 0; 108 *r = p; 109 err = mnvm_noErr; 110 } 111 } 112 } 113 114 return err; 115} 116 117LOCALPROC MyMayFree(char *p) 118{ 119 if (NULL != p) { 120 free(p); 121 } 122} 123 124/* --- sending debugging info to file --- */ 125 126#if dbglog_HAVE 127 128#ifndef dbglog_ToStdErr 129#define dbglog_ToStdErr 0 130#endif 131#ifndef dbglog_ToSDL_Log 132#define dbglog_ToSDL_Log 0 133#endif 134 135#if ! dbglog_ToStdErr 136LOCALVAR FILE *dbglog_File = NULL; 137#endif 138 139LOCALFUNC blnr dbglog_open0(void) 140{ 141#if dbglog_ToStdErr || dbglog_ToSDL_Log 142 return trueblnr; 143#else 144#if CanGetAppPath 145 if (NULL == app_parent) 146#endif 147 { 148 dbglog_File = fopen("dbglog.txt", "w"); 149 } 150#if CanGetAppPath 151 else { 152 char *t = NULL; 153 154 if (mnvm_noErr == ChildPath(app_parent, "dbglog.txt", &t)) { 155 dbglog_File = fopen(t, "w"); 156 } 157 158 MyMayFree(t); 159 } 160#endif 161 162 return (NULL != dbglog_File); 163#endif 164} 165 166LOCALPROC dbglog_write0(char *s, uimr L) 167{ 168#if dbglog_ToStdErr 169 (void) fwrite(s, 1, L, stderr); 170#elif dbglog_ToSDL_Log 171 char t[256 + 1]; 172 173 if (L > 256) { 174 L = 256; 175 } 176 (void) memcpy(t, s, L); 177 t[L] = 1; 178 179 SDL_Log("%s", t); 180#else 181 if (dbglog_File != NULL) { 182 (void) fwrite(s, 1, L, dbglog_File); 183 } 184#endif 185} 186 187LOCALPROC dbglog_close0(void) 188{ 189#if ! dbglog_ToStdErr 190 if (dbglog_File != NULL) { 191 fclose(dbglog_File); 192 dbglog_File = NULL; 193 } 194#endif 195} 196 197#endif 198 199/* --- information about the environment --- */ 200 201#define WantColorTransValid 0 202 203#include "COMOSGLU.h" 204 205#include "PBUFSTDC.h" 206 207#include "CONTROLM.h" 208 209/* --- text translation --- */ 210 211LOCALPROC NativeStrFromCStr(char *r, char *s) 212{ 213 ui3b ps[ClStrMaxLength]; 214 int i; 215 int L; 216 217 ClStrFromSubstCStr(&L, ps, s); 218 219 for (i = 0; i < L; ++i) { 220 r[i] = Cell2PlainAsciiMap[ps[i]]; 221 } 222 223 r[L] = 0; 224} 225 226/* --- drives --- */ 227 228/* 229 OSGLUxxx common: 230 define NotAfileRef to some value that is different 231 from any valid open file reference. 232*/ 233#define NotAfileRef NULL 234 235#ifndef UseRWops 236#define UseRWops 0 237#endif 238 239#if UseRWops 240#define MyFilePtr SDL_RWops * 241#define MySeek SDL_RWseek 242 /* 243 unlike fseek, SDL_RWseek returns nonzero value on success 244 */ 245#define MySeekSet RW_SEEK_SET 246#define MySeekCur RW_SEEK_CUR 247#define MySeekEnd RW_SEEK_END 248#define MyFileRead(ptr, size, nmemb, stream) \ 249 SDL_RWread(stream, ptr, size, nmemb) 250#define MyFileWrite(ptr, size, nmemb, stream) \ 251 SDL_RWwrite(stream, ptr, size, nmemb) 252#define MyFileTell SDL_RWtell 253#define MyFileClose SDL_RWclose 254#define MyFileOpen SDL_RWFromFile 255#else 256#define MyFilePtr FILE * 257#define MySeek fseek 258#define MySeekSet SEEK_SET 259#define MySeekCur SEEK_CUR 260#define MySeekEnd SEEK_END 261#define MyFileRead fread 262#define MyFileWrite fwrite 263#define MyFileTell ftell 264#define MyFileClose fclose 265#define MyFileOpen fopen 266#define MyFileEof feof 267#endif 268 269LOCALVAR MyFilePtr Drives[NumDrives]; /* open disk image files */ 270 271LOCALPROC InitDrives(void) 272{ 273 /* 274 This isn't really needed, Drives[i] and DriveNames[i] 275 need not have valid values when not vSonyIsInserted[i]. 276 */ 277 tDrive i; 278 279 for (i = 0; i < NumDrives; ++i) { 280 Drives[i] = NotAfileRef; 281 } 282} 283 284GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer, 285 tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count, 286 ui5r *Sony_ActCount) 287{ 288 /* 289 OSGLUxxx common: 290 return 0 if it succeeds, nonzero (a 291 Macintosh style error code, but -1 292 will do) on failure. 293 */ 294 tMacErr err = mnvm_miscErr; 295 MyFilePtr refnum = Drives[Drive_No]; 296 ui5r NewSony_Count = 0; 297 298 if (MySeek(refnum, Sony_Start, MySeekSet) >= 0) { 299 if (IsWrite) { 300 NewSony_Count = MyFileWrite(Buffer, 1, Sony_Count, refnum); 301 } else { 302 NewSony_Count = MyFileRead(Buffer, 1, Sony_Count, refnum); 303 } 304 305 if (NewSony_Count == Sony_Count) { 306 err = mnvm_noErr; 307 } 308 } 309 310 if (nullpr != Sony_ActCount) { 311 *Sony_ActCount = NewSony_Count; 312 } 313 314 return err; /*& figure out what really to return &*/ 315} 316 317GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count) 318{ 319 /* 320 OSGLUxxx common: 321 set Sony_Count to the size of disk image number Drive_No. 322 323 return 0 if it succeeds, nonzero (a 324 Macintosh style error code, but -1 325 will do) on failure. 326 */ 327 tMacErr err = mnvm_miscErr; 328 MyFilePtr refnum = Drives[Drive_No]; 329 long v; 330 331 if (MySeek(refnum, 0, MySeekEnd) >= 0) { 332 v = MyFileTell(refnum); 333 if (v >= 0) { 334 *Sony_Count = v; 335 err = mnvm_noErr; 336 } 337 } 338 339 return err; /*& figure out what really to return &*/ 340} 341 342LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit) 343{ 344 /* 345 OSGLUxxx common: 346 close disk image number Drive_No. 347 348 return 0 if it succeeds, nonzero (a 349 Macintosh style error code, but -1 350 will do) on failure. 351 */ 352 MyFilePtr refnum = Drives[Drive_No]; 353 354 DiskEjectedNotify(Drive_No); 355 356 MyFileClose(refnum); 357 Drives[Drive_No] = NotAfileRef; /* not really needed */ 358 359 return mnvm_noErr; 360} 361 362GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No) 363{ 364 return vSonyEject0(Drive_No, falseblnr); 365} 366 367LOCALPROC UnInitDrives(void) 368{ 369 tDrive i; 370 371 for (i = 0; i < NumDrives; ++i) { 372 if (vSonyIsInserted(i)) { 373 (void) vSonyEject(i); 374 } 375 } 376} 377 378LOCALFUNC blnr Sony_Insert0(MyFilePtr refnum, blnr locked, 379 char *drivepath) 380{ 381 /* 382 OSGLUxxx common: 383 Given reference to open file, mount it as a disk image file. 384 if "locked", then mount it as a locked disk. 385 */ 386 387 tDrive Drive_No; 388 blnr IsOk = falseblnr; 389 390 if (! FirstFreeDisk(&Drive_No)) { 391 MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage, 392 falseblnr); 393 } else { 394 /* printf("Sony_Insert0 %d\n", (int)Drive_No); */ 395 396 { 397 Drives[Drive_No] = refnum; 398 DiskInsertNotify(Drive_No, locked); 399 400 IsOk = trueblnr; 401 } 402 } 403 404 if (! IsOk) { 405 MyFileClose(refnum); 406 } 407 408 return IsOk; 409} 410 411LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail) 412{ 413 blnr locked = falseblnr; 414 /* printf("Sony_Insert1 %s\n", drivepath); */ 415 MyFilePtr refnum = MyFileOpen(drivepath, "rb+"); 416 if (NULL == refnum) { 417 locked = trueblnr; 418 refnum = MyFileOpen(drivepath, "rb"); 419 } 420 if (NULL == refnum) { 421 if (! silentfail) { 422 MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr); 423 } 424 } else { 425 return Sony_Insert0(refnum, locked, drivepath); 426 } 427 return falseblnr; 428} 429 430LOCALFUNC tMacErr LoadMacRomFrom(char *path) 431{ 432 tMacErr err; 433 MyFilePtr ROM_File; 434 int File_Size; 435 436 ROM_File = MyFileOpen(path, "rb"); 437 if (NULL == ROM_File) { 438 err = mnvm_fnfErr; 439 } else { 440 File_Size = MyFileRead(ROM, 1, kROM_Size, ROM_File); 441 if (File_Size != kROM_Size) { 442#ifdef MyFileEof 443 if (MyFileEof(ROM_File)) 444#else 445 if (File_Size > 0) 446#endif 447 { 448 MacMsgOverride(kStrShortROMTitle, 449 kStrShortROMMessage); 450 err = mnvm_eofErr; 451 } else { 452 MacMsgOverride(kStrNoReadROMTitle, 453 kStrNoReadROMMessage); 454 err = mnvm_miscErr; 455 } 456 } else { 457 err = ROM_IsValid(); 458 } 459 MyFileClose(ROM_File); 460 } 461 462 return err; 463} 464 465#if 2 == SDL_MAJOR_VERSION 466 /* otherwise no drag and drop to make use of this */ 467LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail) 468{ 469 blnr v; 470 471 if (! ROM_loaded) { 472 v = (mnvm_noErr == LoadMacRomFrom(drivepath)); 473 } else { 474 v = Sony_Insert1(drivepath, silentfail); 475 } 476 477 return v; 478} 479#endif 480 481LOCALFUNC blnr Sony_Insert2(char *s) 482{ 483 char *d = 484#if CanGetAppPath 485 (NULL == d_arg) ? app_parent : 486#endif 487 d_arg; 488 blnr IsOk = falseblnr; 489 490 if (NULL == d) { 491 IsOk = Sony_Insert1(s, trueblnr); 492 } else 493 { 494 char *t = NULL; 495 496 if (mnvm_noErr == ChildPath(d, s, &t)) { 497 IsOk = Sony_Insert1(t, trueblnr); 498 } 499 500 MyMayFree(t); 501 } 502 503 return IsOk; 504} 505 506LOCALFUNC blnr Sony_InsertIth(int i) 507{ 508 blnr v; 509 510 if ((i > 9) || ! FirstFreeDisk(nullpr)) { 511 v = falseblnr; 512 } else { 513 char s[] = "disk?.dsk"; 514 515 s[4] = '0' + i; 516 517 v = Sony_Insert2(s); 518 } 519 520 return v; 521} 522 523LOCALFUNC blnr LoadInitialImages(void) 524{ 525 if (! AnyDiskInserted()) { 526 int i; 527 528 for (i = 1; Sony_InsertIth(i); ++i) { 529 /* stop on first error (including file not found) */ 530 } 531 } 532 533 return trueblnr; 534} 535 536/* --- ROM --- */ 537 538LOCALVAR char *rom_path = NULL; 539 540#if CanGetAppPath 541LOCALFUNC tMacErr LoadMacRomFromPrefDir(void) 542{ 543 tMacErr err; 544 char *t = NULL; 545 char *t2 = NULL; 546 547 if (NULL == pref_dir) { 548 err = mnvm_fnfErr; 549 } else 550 if (mnvm_noErr != (err = 551 ChildPath(pref_dir, "mnvm_rom", &t))) 552 { 553 /* fail */ 554 } else 555 if (mnvm_noErr != (err = 556 ChildPath(t, RomFileName, &t2))) 557 { 558 /* fail */ 559 } else 560 { 561 err = LoadMacRomFrom(t2); 562 } 563 564 MyMayFree(t2); 565 MyMayFree(t); 566 567 return err; 568} 569#endif 570 571LOCALFUNC tMacErr LoadMacRomFromAppPar(void) 572{ 573 tMacErr err; 574 char *d = 575#if CanGetAppPath 576 (NULL == d_arg) ? app_parent : 577#endif 578 d_arg; 579 580 if (NULL == d) { 581 err = mnvm_fnfErr; 582 } else 583 { 584 char *t = NULL; 585 586 if (mnvm_noErr != (err = 587 ChildPath(d, RomFileName, &t))) 588 { 589 /* fail */ 590 } else 591 { 592 err = LoadMacRomFrom(t); 593 } 594 595 MyMayFree(t); 596 } 597 598 return err; 599} 600 601LOCALFUNC blnr LoadMacRom(void) 602{ 603 tMacErr err; 604 605 if ((NULL == rom_path) 606 || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path)))) 607 if (mnvm_fnfErr == (err = LoadMacRomFromAppPar())) 608#if CanGetAppPath 609 if (mnvm_fnfErr == (err = LoadMacRomFromPrefDir())) 610#endif 611 if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName))) 612 { 613 } 614 615 return trueblnr; /* keep launching Mini vMac, regardless */ 616} 617 618/* --- video out --- */ 619 620#if MayFullScreen && (2 == SDL_MAJOR_VERSION) 621LOCALVAR int hOffset; 622LOCALVAR int vOffset; 623#endif 624 625#if VarFullScreen 626LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0); 627#endif 628 629#if EnableMagnify 630LOCALVAR blnr UseMagnify = (WantInitMagnify != 0); 631#endif 632 633#ifndef UseSDLscaling 634#define UseSDLscaling 0 635#endif 636 637LOCALVAR blnr gBackgroundFlag = falseblnr; 638LOCALVAR blnr gTrueBackgroundFlag = falseblnr; 639LOCALVAR blnr CurSpeedStopped = trueblnr; 640 641#if EnableMagnify && ! UseSDLscaling 642#define MaxScale MyWindowScale 643#else 644#define MaxScale 1 645#endif 646 647 648#if 1 == SDL_MAJOR_VERSION 649LOCALVAR SDL_Surface *my_surface = nullpr; 650#define my_format (my_surface->format) 651#elif 2 == SDL_MAJOR_VERSION 652LOCALVAR SDL_Window *my_main_wind = NULL; 653LOCALVAR SDL_Renderer *my_renderer = NULL; 654LOCALVAR SDL_Texture *my_texture = NULL; 655LOCALVAR SDL_PixelFormat *my_format = NULL; 656#endif 657 658LOCALVAR ui3p ScalingBuff = nullpr; 659 660LOCALVAR ui3p CLUT_final; 661 662#define CLUT_finalsz (256 * 8 * 4 * MaxScale) 663 /* 664 256 possible values of one byte 665 8 pixels per byte maximum (when black and white) 666 4 bytes per destination pixel maximum 667 multiplied by MyWindowScale if EnableMagnify 668 */ 669 670#define ScrnMapr_DoMap UpdateBWDepth3Copy 671#define ScrnMapr_Src GetCurDrawBuff() 672#define ScrnMapr_Dst ScalingBuff 673#define ScrnMapr_SrcDepth 0 674#define ScrnMapr_DstDepth 3 675#define ScrnMapr_Map CLUT_final 676 677#include "SCRNMAPR.h" 678 679#define ScrnMapr_DoMap UpdateBWDepth4Copy 680#define ScrnMapr_Src GetCurDrawBuff() 681#define ScrnMapr_Dst ScalingBuff 682#define ScrnMapr_SrcDepth 0 683#define ScrnMapr_DstDepth 4 684#define ScrnMapr_Map CLUT_final 685 686#include "SCRNMAPR.h" 687 688#define ScrnMapr_DoMap UpdateBWDepth5Copy 689#define ScrnMapr_Src GetCurDrawBuff() 690#define ScrnMapr_Dst ScalingBuff 691#define ScrnMapr_SrcDepth 0 692#define ScrnMapr_DstDepth 5 693#define ScrnMapr_Map CLUT_final 694 695#include "SCRNMAPR.h" 696 697#if EnableMagnify && ! UseSDLscaling 698 699#define ScrnMapr_DoMap UpdateBWDepth3ScaledCopy 700#define ScrnMapr_Src GetCurDrawBuff() 701#define ScrnMapr_Dst ScalingBuff 702#define ScrnMapr_SrcDepth 0 703#define ScrnMapr_DstDepth 3 704#define ScrnMapr_Map CLUT_final 705#define ScrnMapr_Scale MyWindowScale 706 707#include "SCRNMAPR.h" 708 709#define ScrnMapr_DoMap UpdateBWDepth4ScaledCopy 710#define ScrnMapr_Src GetCurDrawBuff() 711#define ScrnMapr_Dst ScalingBuff 712#define ScrnMapr_SrcDepth 0 713#define ScrnMapr_DstDepth 4 714#define ScrnMapr_Map CLUT_final 715#define ScrnMapr_Scale MyWindowScale 716 717#include "SCRNMAPR.h" 718 719#define ScrnMapr_DoMap UpdateBWDepth5ScaledCopy 720#define ScrnMapr_Src GetCurDrawBuff() 721#define ScrnMapr_Dst ScalingBuff 722#define ScrnMapr_SrcDepth 0 723#define ScrnMapr_DstDepth 5 724#define ScrnMapr_Map CLUT_final 725#define ScrnMapr_Scale MyWindowScale 726 727#include "SCRNMAPR.h" 728 729#endif /* EnableMagnify && ! UseSDLscaling */ 730 731 732#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4) 733 734#define ScrnMapr_DoMap UpdateColorDepth3Copy 735#define ScrnMapr_Src GetCurDrawBuff() 736#define ScrnMapr_Dst ScalingBuff 737#define ScrnMapr_SrcDepth vMacScreenDepth 738#define ScrnMapr_DstDepth 3 739#define ScrnMapr_Map CLUT_final 740 741#include "SCRNMAPR.h" 742 743#define ScrnMapr_DoMap UpdateColorDepth4Copy 744#define ScrnMapr_Src GetCurDrawBuff() 745#define ScrnMapr_Dst ScalingBuff 746#define ScrnMapr_SrcDepth vMacScreenDepth 747#define ScrnMapr_DstDepth 4 748#define ScrnMapr_Map CLUT_final 749 750#include "SCRNMAPR.h" 751 752#define ScrnMapr_DoMap UpdateColorDepth5Copy 753#define ScrnMapr_Src GetCurDrawBuff() 754#define ScrnMapr_Dst ScalingBuff 755#define ScrnMapr_SrcDepth vMacScreenDepth 756#define ScrnMapr_DstDepth 5 757#define ScrnMapr_Map CLUT_final 758 759#include "SCRNMAPR.h" 760 761#if EnableMagnify && ! UseSDLscaling 762 763#define ScrnMapr_DoMap UpdateColorDepth3ScaledCopy 764#define ScrnMapr_Src GetCurDrawBuff() 765#define ScrnMapr_Dst ScalingBuff 766#define ScrnMapr_SrcDepth vMacScreenDepth 767#define ScrnMapr_DstDepth 3 768#define ScrnMapr_Map CLUT_final 769#define ScrnMapr_Scale MyWindowScale 770 771#include "SCRNMAPR.h" 772 773#define ScrnMapr_DoMap UpdateColorDepth4ScaledCopy 774#define ScrnMapr_Src GetCurDrawBuff() 775#define ScrnMapr_Dst ScalingBuff 776#define ScrnMapr_SrcDepth vMacScreenDepth 777#define ScrnMapr_DstDepth 4 778#define ScrnMapr_Map CLUT_final 779#define ScrnMapr_Scale MyWindowScale 780 781#include "SCRNMAPR.h" 782 783#define ScrnMapr_DoMap UpdateColorDepth5ScaledCopy 784#define ScrnMapr_Src GetCurDrawBuff() 785#define ScrnMapr_Dst ScalingBuff 786#define ScrnMapr_SrcDepth vMacScreenDepth 787#define ScrnMapr_DstDepth 5 788#define ScrnMapr_Map CLUT_final 789#define ScrnMapr_Scale MyWindowScale 790 791#include "SCRNMAPR.h" 792 793#endif /* EnableMagnify && ! UseSDLscaling */ 794 795#endif 796 797 798LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left, 799 ui4r bottom, ui4r right) 800{ 801#if 0 != SDL_MAJOR_VERSION 802 int i; 803 int j; 804 ui3b *p; 805 Uint32 pixel; 806#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4) 807 Uint32 CLUT_pixel[CLUT_size]; 808#endif 809 Uint32 BWLUT_pixel[2]; 810 ui5r top2; 811 ui5r left2; 812 ui5r bottom2; 813 ui5r right2; 814 void *pixels; 815 int pitch; 816 817#if 2 == SDL_MAJOR_VERSION 818 SDL_Rect src_rect; 819 SDL_Rect dst_rect; 820 int XDest; 821 int YDest; 822 int DestWidth; 823 int DestHeight; 824 825#if VarFullScreen 826 if (UseFullScreen) 827#endif 828#if MayFullScreen 829 { 830 if (top < ViewVStart) { 831 top = ViewVStart; 832 } 833 if (left < ViewHStart) { 834 left = ViewHStart; 835 } 836 if (bottom > ViewVStart + ViewVSize) { 837 bottom = ViewVStart + ViewVSize; 838 } 839 if (right > ViewHStart + ViewHSize) { 840 right = ViewHStart + ViewHSize; 841 } 842 843 if ((top >= bottom) || (left >= right)) { 844 goto label_exit; 845 } 846 } 847#endif 848 849 XDest = left; 850 YDest = top; 851 DestWidth = (right - left); 852 DestHeight = (bottom - top); 853 854#if VarFullScreen 855 if (UseFullScreen) 856#endif 857#if MayFullScreen 858 { 859 XDest -= ViewHStart; 860 YDest -= ViewVStart; 861 } 862#endif 863 864#if EnableMagnify 865 if (UseMagnify) { 866 XDest *= MyWindowScale; 867 YDest *= MyWindowScale; 868 DestWidth *= MyWindowScale; 869 DestHeight *= MyWindowScale; 870 } 871#endif 872 873#if VarFullScreen 874 if (UseFullScreen) 875#endif 876#if MayFullScreen 877 { 878 XDest += hOffset; 879 YDest += vOffset; 880 } 881#endif 882 883#endif /* 2 == SDL_MAJOR_VERSION */ 884 885 top2 = top; 886 left2 = left; 887 bottom2 = bottom; 888 right2 = right; 889 890#if EnableMagnify && ! UseSDLscaling 891 if (UseMagnify) { 892 top2 *= MyWindowScale; 893 left2 *= MyWindowScale; 894 bottom2 *= MyWindowScale; 895 right2 *= MyWindowScale; 896 } 897#endif 898 899#if 1 == SDL_MAJOR_VERSION 900 if (SDL_MUSTLOCK(my_surface)) { 901 if (SDL_LockSurface(my_surface) < 0) { 902 return; 903 } 904 } 905 pixels = my_surface->pixels; 906 pitch = my_surface->pitch; 907 908#elif 2 == SDL_MAJOR_VERSION 909 if (0 != SDL_LockTexture(my_texture, NULL, &pixels, &pitch)) { 910 return; 911 } 912#endif 913 914 { 915 916 int bpp = my_format->BytesPerPixel; 917 ui5r ExpectedPitch = vMacScreenWidth * bpp; 918 919#if EnableMagnify && ! UseSDLscaling 920 if (UseMagnify) { 921 ExpectedPitch *= MyWindowScale; 922 } 923#endif 924 925#if 0 != vMacScreenDepth 926 if (UseColorMode) { 927#if vMacScreenDepth < 4 928 for (i = 0; i < CLUT_size; ++i) { 929 CLUT_pixel[i] = SDL_MapRGB(my_format, 930 CLUT_reds[i] >> 8, 931 CLUT_greens[i] >> 8, 932 CLUT_blues[i] >> 8); 933 } 934#endif 935 } else 936#endif 937 { 938 BWLUT_pixel[1] = SDL_MapRGB(my_format, 0, 0, 0); 939 /* black */ 940 BWLUT_pixel[0] = SDL_MapRGB(my_format, 255, 255, 255); 941 /* white */ 942 } 943 944 if ((0 == ((bpp - 1) & bpp)) /* a power of 2 */ 945 && (pitch == ExpectedPitch) 946#if (vMacScreenDepth > 3) 947 && ! UseColorMode 948#endif 949 ) 950 { 951 int k; 952 Uint32 v; 953#if EnableMagnify && ! UseSDLscaling 954 int a; 955#endif 956 int PixPerByte = 957#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4) 958 UseColorMode ? (1 << (3 - vMacScreenDepth)) : 959#endif 960 8; 961 Uint8 *p4 = (Uint8 *)CLUT_final; 962 963 for (i = 0; i < 256; ++i) { 964 for (k = PixPerByte; --k >= 0; ) { 965 966#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4) 967 if (UseColorMode) { 968 v = CLUT_pixel[ 969#if 3 == vMacScreenDepth 970 i 971#else 972 (i >> (k << vMacScreenDepth)) 973 & (CLUT_size - 1) 974#endif 975 ]; 976 } else 977#endif 978 { 979 v = BWLUT_pixel[(i >> k) & 1]; 980 } 981 982#if EnableMagnify && ! UseSDLscaling 983 for (a = UseMagnify ? MyWindowScale : 1; --a >= 0; ) 984#endif 985 { 986 switch (bpp) { 987 case 1: /* Assuming 8-bpp */ 988 *p4++ = v; 989 break; 990 case 2: /* Probably 15-bpp or 16-bpp */ 991 *(Uint16 *)p4 = v; 992 p4 += 2; 993 break; 994 case 4: /* Probably 32-bpp */ 995 *(Uint32 *)p4 = v; 996 p4 += 4; 997 break; 998 } 999 } 1000 } 1001 } 1002 1003 ScalingBuff = (ui3p)pixels; 1004 1005#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4) 1006 if (UseColorMode) { 1007#if EnableMagnify && ! UseSDLscaling 1008 if (UseMagnify) { 1009 switch (bpp) { 1010 case 1: 1011 UpdateColorDepth3ScaledCopy( 1012 top, left, bottom, right); 1013 break; 1014 case 2: 1015 UpdateColorDepth4ScaledCopy( 1016 top, left, bottom, right); 1017 break; 1018 case 4: 1019 UpdateColorDepth5ScaledCopy( 1020 top, left, bottom, right); 1021 break; 1022 } 1023 } else 1024#endif 1025 { 1026 switch (bpp) { 1027 case 1: 1028 UpdateColorDepth3Copy(top, left, bottom, right); 1029 break; 1030 case 2: 1031 UpdateColorDepth4Copy(top, left, bottom, right); 1032 break; 1033 case 4: 1034 UpdateColorDepth5Copy(top, left, bottom, right); 1035 break; 1036 } 1037 } 1038 } else 1039#endif 1040 { 1041#if EnableMagnify && ! UseSDLscaling 1042 if (UseMagnify) { 1043 switch (bpp) { 1044 case 1: 1045 UpdateBWDepth3ScaledCopy( 1046 top, left, bottom, right); 1047 break; 1048 case 2: 1049 UpdateBWDepth4ScaledCopy( 1050 top, left, bottom, right); 1051 break; 1052 case 4: 1053 UpdateBWDepth5ScaledCopy( 1054 top, left, bottom, right); 1055 break; 1056 } 1057 } else 1058#endif 1059 { 1060 switch (bpp) { 1061 case 1: 1062 UpdateBWDepth3Copy(top, left, bottom, right); 1063 break; 1064 case 2: 1065 UpdateBWDepth4Copy(top, left, bottom, right); 1066 break; 1067 case 4: 1068 UpdateBWDepth5Copy(top, left, bottom, right); 1069 break; 1070 } 1071 } 1072 } 1073 1074 } else { 1075 ui3b *the_data = (ui3b *)GetCurDrawBuff(); 1076 1077 /* adapted from putpixel in SDL documentation */ 1078 1079 for (i = top2; i < bottom2; ++i) { 1080 for (j = left2; j < right2; ++j) { 1081 int i0 = i; 1082 int j0 = j; 1083 Uint8 *bufp = (Uint8 *)pixels 1084 + i * pitch + j * bpp; 1085 1086#if EnableMagnify && ! UseSDLscaling 1087 if (UseMagnify) { 1088 i0 /= MyWindowScale; 1089 j0 /= MyWindowScale; 1090 } 1091#endif 1092 1093#if 0 != vMacScreenDepth 1094 if (UseColorMode) { 1095#if vMacScreenDepth < 4 1096 p = the_data + ((i0 * vMacScreenWidth + j0) 1097 >> (3 - vMacScreenDepth)); 1098 { 1099 ui3r k = (*p >> (((~ j0) 1100 & ((1 << (3 - vMacScreenDepth)) - 1)) 1101 << vMacScreenDepth)) 1102 & (CLUT_size - 1); 1103 pixel = CLUT_pixel[k]; 1104 } 1105#elif 4 == vMacScreenDepth 1106 p = the_data + ((i0 * vMacScreenWidth + j0) << 1); 1107 { 1108 ui4r t0 = do_get_mem_word(p); 1109 pixel = SDL_MapRGB(my_format, 1110 ((t0 & 0x7C00) >> 7) 1111 | ((t0 & 0x7000) >> 12), 1112 ((t0 & 0x03E0) >> 2) 1113 | ((t0 & 0x0380) >> 7), 1114 ((t0 & 0x001F) << 3) 1115 | ((t0 & 0x001C) >> 2)); 1116 } 1117#elif 5 == vMacScreenDepth 1118 p = the_data + ((i0 * vMacScreenWidth + j0) << 2); 1119 pixel = SDL_MapRGB(my_format, 1120 p[1], 1121 p[2], 1122 p[3]); 1123#endif 1124 } else 1125#endif 1126 { 1127 p = the_data + ((i0 * vMacScreenWidth + j0) / 8); 1128 pixel = BWLUT_pixel[(*p >> ((~ j0) & 0x7)) & 1]; 1129 } 1130 1131 switch (bpp) { 1132 case 1: /* Assuming 8-bpp */ 1133 *bufp = pixel; 1134 break; 1135 case 2: /* Probably 15-bpp or 16-bpp */ 1136 *(Uint16 *)bufp = pixel; 1137 break; 1138 case 3: 1139 /* Slow 24-bpp mode, usually not used */ 1140 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { 1141 bufp[0] = (pixel >> 16) & 0xff; 1142 bufp[1] = (pixel >> 8) & 0xff; 1143 bufp[2] = pixel & 0xff; 1144 } else { 1145 bufp[0] = pixel & 0xff; 1146 bufp[1] = (pixel >> 8) & 0xff; 1147 bufp[2] = (pixel >> 16) & 0xff; 1148 } 1149 break; 1150 case 4: /* Probably 32-bpp */ 1151 *(Uint32 *)bufp = pixel; 1152 break; 1153 } 1154 } 1155 } 1156 } 1157 1158 } 1159 1160#if 1 == SDL_MAJOR_VERSION 1161 if (SDL_MUSTLOCK(my_surface)) { 1162 SDL_UnlockSurface(my_surface); 1163 } 1164 1165 SDL_UpdateRect(my_surface, left2, top2, 1166 right2 - left2, bottom2 - top2); 1167#elif 2 == SDL_MAJOR_VERSION 1168 SDL_UnlockTexture(my_texture); 1169 1170 src_rect.x = left2; 1171 src_rect.y = top2; 1172 src_rect.w = right2 - left2; 1173 src_rect.h = bottom2 - top2; 1174 1175 dst_rect.x = XDest; 1176 dst_rect.y = YDest; 1177 dst_rect.w = DestWidth; 1178 dst_rect.h = DestHeight; 1179 1180 /* SDL_RenderClear(my_renderer); */ 1181 SDL_RenderCopy(my_renderer, my_texture, &src_rect, &dst_rect); 1182 SDL_RenderPresent(my_renderer); 1183 1184#if MayFullScreen 1185label_exit: 1186 ; 1187#endif 1188#endif /* 2 == SDL_MAJOR_VERSION */ 1189#endif /* 0 != SDL_MAJOR_VERSION */ 1190} 1191 1192LOCALPROC MyDrawChangesAndClear(void) 1193{ 1194 if (ScreenChangedBottom > ScreenChangedTop) { 1195 HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft, 1196 ScreenChangedBottom, ScreenChangedRight); 1197 ScreenClearChanges(); 1198 } 1199} 1200 1201GLOBALOSGLUPROC DoneWithDrawingForTick(void) 1202{ 1203#if EnableFSMouseMotion 1204 if (HaveMouseMotion) { 1205 AutoScrollScreen(); 1206 } 1207#endif 1208 MyDrawChangesAndClear(); 1209} 1210 1211/* --- mouse --- */ 1212 1213/* cursor hiding */ 1214 1215LOCALVAR blnr HaveCursorHidden = falseblnr; 1216LOCALVAR blnr WantCursorHidden = falseblnr; 1217 1218LOCALPROC ForceShowCursor(void) 1219{ 1220 if (HaveCursorHidden) { 1221 HaveCursorHidden = falseblnr; 1222#if 0 != SDL_MAJOR_VERSION 1223 (void) SDL_ShowCursor(SDL_ENABLE); 1224#endif /* 0 != SDL_MAJOR_VERSION */ 1225 } 1226} 1227 1228/* cursor moving */ 1229 1230/* 1231 OSGLUxxx common: 1232 When "EnableFSMouseMotion" the platform 1233 specific code can get relative mouse 1234 motion, instead of absolute coordinates 1235 on the emulated screen. It should 1236 set HaveMouseMotion to true when 1237 it is doing this (normally when in 1238 full screen mode.) 1239 1240 This can usually be implemented by 1241 hiding the platform specific cursor, 1242 and then keeping it within a box, 1243 moving the cursor back to the center whenever 1244 it leaves the box. This requires the 1245 ability to move the cursor (in MyMoveMouse). 1246*/ 1247 1248#ifndef HaveWorkingWarp 1249#define HaveWorkingWarp 1 1250#endif 1251 1252#if EnableMoveMouse && HaveWorkingWarp 1253LOCALFUNC blnr MyMoveMouse(si4b h, si4b v) 1254{ 1255 /* 1256 OSGLUxxx common: 1257 Move the cursor to the point h, v on the emulated screen. 1258 If detect that this fails return falseblnr, 1259 otherwise return trueblnr. 1260 (On some platforms it is possible to move the curser, 1261 but there is no way to detect failure.) 1262 */ 1263 1264#if VarFullScreen 1265 if (UseFullScreen) 1266#endif 1267#if MayFullScreen 1268 { 1269 h -= ViewHStart; 1270 v -= ViewVStart; 1271 } 1272#endif 1273 1274#if EnableMagnify 1275 if (UseMagnify) { 1276 h *= MyWindowScale; 1277 v *= MyWindowScale; 1278 } 1279#endif 1280 1281#if 2 == SDL_MAJOR_VERSION 1282#if VarFullScreen 1283 if (UseFullScreen) 1284#endif 1285#if MayFullScreen 1286 { 1287 h += hOffset; 1288 v += vOffset; 1289 } 1290#endif 1291#endif /* 2 == SDL_MAJOR_VERSION */ 1292 1293#if 1 == SDL_MAJOR_VERSION 1294 SDL_WarpMouse(h, v); 1295#elif 2 == SDL_MAJOR_VERSION 1296 SDL_WarpMouseInWindow(my_main_wind, h, v); 1297#endif 1298 1299 return trueblnr; 1300} 1301#endif 1302 1303/* cursor state */ 1304 1305LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv) 1306{ 1307 blnr ShouldHaveCursorHidden = trueblnr; 1308 1309#if 2 == SDL_MAJOR_VERSION 1310#if VarFullScreen 1311 if (UseFullScreen) 1312#endif 1313#if MayFullScreen 1314 { 1315 NewMousePosh -= hOffset; 1316 NewMousePosv -= vOffset; 1317 } 1318#endif 1319#endif /* 2 == SDL_MAJOR_VERSION */ 1320 1321#if EnableMagnify 1322 if (UseMagnify) { 1323 NewMousePosh /= MyWindowScale; 1324 NewMousePosv /= MyWindowScale; 1325 } 1326#endif 1327 1328#if VarFullScreen 1329 if (UseFullScreen) 1330#endif 1331#if MayFullScreen 1332 { 1333 NewMousePosh += ViewHStart; 1334 NewMousePosv += ViewVStart; 1335 } 1336#endif 1337 1338#if EnableFSMouseMotion 1339 if (HaveMouseMotion) { 1340 MyMousePositionSetDelta(NewMousePosh - SavedMouseH, 1341 NewMousePosv - SavedMouseV); 1342 SavedMouseH = NewMousePosh; 1343 SavedMouseV = NewMousePosv; 1344 } else 1345#endif 1346 { 1347 if (NewMousePosh < 0) { 1348 NewMousePosh = 0; 1349 ShouldHaveCursorHidden = falseblnr; 1350 } else if (NewMousePosh >= vMacScreenWidth) { 1351 NewMousePosh = vMacScreenWidth - 1; 1352 ShouldHaveCursorHidden = falseblnr; 1353 } 1354 if (NewMousePosv < 0) { 1355 NewMousePosv = 0; 1356 ShouldHaveCursorHidden = falseblnr; 1357 } else if (NewMousePosv >= vMacScreenHeight) { 1358 NewMousePosv = vMacScreenHeight - 1; 1359 ShouldHaveCursorHidden = falseblnr; 1360 } 1361 1362#if VarFullScreen 1363 if (UseFullScreen) 1364#endif 1365#if MayFullScreen 1366 { 1367 ShouldHaveCursorHidden = trueblnr; 1368 } 1369#endif 1370 1371 /* if (ShouldHaveCursorHidden || CurMouseButton) */ 1372 /* 1373 for a game like arkanoid, would like mouse to still 1374 move even when outside window in one direction 1375 */ 1376 MyMousePositionSet(NewMousePosh, NewMousePosv); 1377 } 1378 1379 WantCursorHidden = ShouldHaveCursorHidden; 1380} 1381 1382#if EnableFSMouseMotion && ! HaveWorkingWarp 1383LOCALPROC MousePositionNotifyRelative(int deltah, int deltav) 1384{ 1385 blnr ShouldHaveCursorHidden = trueblnr; 1386 1387#if EnableMagnify 1388 if (UseMagnify) { 1389 /* 1390 This is not really right. If only move one pixel 1391 each time, emulated mouse doesn't move at all. 1392 */ 1393 deltah /= MyWindowScale; 1394 deltav /= MyWindowScale; 1395 } 1396#endif 1397 1398 MyMousePositionSetDelta(deltah, 1399 deltav); 1400 1401 WantCursorHidden = ShouldHaveCursorHidden; 1402} 1403#endif 1404 1405LOCALPROC CheckMouseState(void) 1406{ 1407#if 0 != SDL_MAJOR_VERSION 1408 /* 1409 this doesn't work as desired, doesn't get mouse movements 1410 when outside of our window. 1411 */ 1412 int x; 1413 int y; 1414 1415 (void) SDL_GetMouseState(&x, &y); 1416 MousePositionNotify(x, y); 1417#endif /* 0 != SDL_MAJOR_VERSION */ 1418} 1419 1420/* --- keyboard input --- */ 1421 1422#if 1 == SDL_MAJOR_VERSION 1423LOCALFUNC ui3r SDLKey2MacKeyCode(SDLKey i) 1424{ 1425 ui3r v = MKC_None; 1426 1427 switch (i) { 1428 case SDLK_BACKSPACE: v = MKC_BackSpace; break; 1429 case SDLK_TAB: v = MKC_Tab; break; 1430 case SDLK_CLEAR: v = MKC_Clear; break; 1431 case SDLK_RETURN: v = MKC_Return; break; 1432 case SDLK_PAUSE: v = MKC_Pause; break; 1433 case SDLK_ESCAPE: v = MKC_formac_Escape; break; 1434 case SDLK_SPACE: v = MKC_Space; break; 1435 case SDLK_EXCLAIM: /* ? */ break; 1436 case SDLK_QUOTEDBL: /* ? */ break; 1437 case SDLK_HASH: /* ? */ break; 1438 case SDLK_DOLLAR: /* ? */ break; 1439 case SDLK_AMPERSAND: /* ? */ break; 1440 case SDLK_QUOTE: v = MKC_SingleQuote; break; 1441 case SDLK_LEFTPAREN: /* ? */ break; 1442 case SDLK_RIGHTPAREN: /* ? */ break; 1443 case SDLK_ASTERISK: /* ? */ break; 1444 case SDLK_PLUS: /* ? */ break; 1445 case SDLK_COMMA: v = MKC_Comma; break; 1446 case SDLK_MINUS: v = MKC_Minus; break; 1447 case SDLK_PERIOD: v = MKC_Period; break; 1448 case SDLK_SLASH: v = MKC_formac_Slash; break; 1449 case SDLK_0: v = MKC_0; break; 1450 case SDLK_1: v = MKC_1; break; 1451 case SDLK_2: v = MKC_2; break; 1452 case SDLK_3: v = MKC_3; break; 1453 case SDLK_4: v = MKC_4; break; 1454 case SDLK_5: v = MKC_5; break; 1455 case SDLK_6: v = MKC_6; break; 1456 case SDLK_7: v = MKC_7; break; 1457 case SDLK_8: v = MKC_8; break; 1458 case SDLK_9: v = MKC_9; break; 1459 case SDLK_COLON: /* ? */ break; 1460 case SDLK_SEMICOLON: v = MKC_SemiColon; break; 1461 case SDLK_LESS: /* ? */ break; 1462 case SDLK_EQUALS: v = MKC_Equal; break; 1463 case SDLK_GREATER: /* ? */ break; 1464 case SDLK_QUESTION: /* ? */ break; 1465 case SDLK_AT: /* ? */ break; 1466 1467 case SDLK_LEFTBRACKET: v = MKC_LeftBracket; break; 1468 case SDLK_BACKSLASH: v = MKC_formac_BackSlash; break; 1469 case SDLK_RIGHTBRACKET: v = MKC_RightBracket; break; 1470 case SDLK_CARET: /* ? */ break; 1471 case SDLK_UNDERSCORE: /* ? */ break; 1472 case SDLK_BACKQUOTE: v = MKC_formac_Grave; break; 1473 1474 case SDLK_a: v = MKC_A; break; 1475 case SDLK_b: v = MKC_B; break; 1476 case SDLK_c: v = MKC_C; break; 1477 case SDLK_d: v = MKC_D; break; 1478 case SDLK_e: v = MKC_E; break; 1479 case SDLK_f: v = MKC_F; break; 1480 case SDLK_g: v = MKC_G; break; 1481 case SDLK_h: v = MKC_H; break; 1482 case SDLK_i: v = MKC_I; break; 1483 case SDLK_j: v = MKC_J; break; 1484 case SDLK_k: v = MKC_K; break; 1485 case SDLK_l: v = MKC_L; break; 1486 case SDLK_m: v = MKC_M; break; 1487 case SDLK_n: v = MKC_N; break; 1488 case SDLK_o: v = MKC_O; break; 1489 case SDLK_p: v = MKC_P; break; 1490 case SDLK_q: v = MKC_Q; break; 1491 case SDLK_r: v = MKC_R; break; 1492 case SDLK_s: v = MKC_S; break; 1493 case SDLK_t: v = MKC_T; break; 1494 case SDLK_u: v = MKC_U; break; 1495 case SDLK_v: v = MKC_V; break; 1496 case SDLK_w: v = MKC_W; break; 1497 case SDLK_x: v = MKC_X; break; 1498 case SDLK_y: v = MKC_Y; break; 1499 case SDLK_z: v = MKC_Z; break; 1500 1501 case SDLK_KP0: v = MKC_KP0; break; 1502 case SDLK_KP1: v = MKC_KP1; break; 1503 case SDLK_KP2: v = MKC_KP2; break; 1504 case SDLK_KP3: v = MKC_KP3; break; 1505 case SDLK_KP4: v = MKC_KP4; break; 1506 case SDLK_KP5: v = MKC_KP5; break; 1507 case SDLK_KP6: v = MKC_KP6; break; 1508 case SDLK_KP7: v = MKC_KP7; break; 1509 case SDLK_KP8: v = MKC_KP8; break; 1510 case SDLK_KP9: v = MKC_KP9; break; 1511 1512 case SDLK_KP_PERIOD: v = MKC_Decimal; break; 1513 case SDLK_KP_DIVIDE: v = MKC_KPDevide; break; 1514 case SDLK_KP_MULTIPLY: v = MKC_KPMultiply; break; 1515 case SDLK_KP_MINUS: v = MKC_KPSubtract; break; 1516 case SDLK_KP_PLUS: v = MKC_KPAdd; break; 1517 case SDLK_KP_ENTER: v = MKC_formac_Enter; break; 1518 case SDLK_KP_EQUALS: v = MKC_KPEqual; break; 1519 1520 case SDLK_UP: v = MKC_Up; break; 1521 case SDLK_DOWN: v = MKC_Down; break; 1522 case SDLK_RIGHT: v = MKC_Right; break; 1523 case SDLK_LEFT: v = MKC_Left; break; 1524 case SDLK_INSERT: v = MKC_formac_Help; break; 1525 case SDLK_HOME: v = MKC_formac_Home; break; 1526 case SDLK_END: v = MKC_formac_End; break; 1527 case SDLK_PAGEUP: v = MKC_formac_PageUp; break; 1528 case SDLK_PAGEDOWN: v = MKC_formac_PageDown; break; 1529 1530 case SDLK_F1: v = MKC_formac_F1; break; 1531 case SDLK_F2: v = MKC_formac_F2; break; 1532 case SDLK_F3: v = MKC_formac_F3; break; 1533 case SDLK_F4: v = MKC_formac_F4; break; 1534 case SDLK_F5: v = MKC_formac_F5; break; 1535 case SDLK_F6: v = MKC_F6; break; 1536 case SDLK_F7: v = MKC_F7; break; 1537 case SDLK_F8: v = MKC_F8; break; 1538 case SDLK_F9: v = MKC_F9; break; 1539 case SDLK_F10: v = MKC_F10; break; 1540 case SDLK_F11: v = MKC_F11; break; 1541 case SDLK_F12: v = MKC_F12; break; 1542 1543 case SDLK_F13: /* ? */ break; 1544 case SDLK_F14: /* ? */ break; 1545 case SDLK_F15: /* ? */ break; 1546 1547 case SDLK_NUMLOCK: v = MKC_formac_ForwardDel; break; 1548 case SDLK_CAPSLOCK: v = MKC_formac_CapsLock; break; 1549 case SDLK_SCROLLOCK: v = MKC_ScrollLock; break; 1550 case SDLK_RSHIFT: v = MKC_formac_RShift; break; 1551 case SDLK_LSHIFT: v = MKC_formac_Shift; break; 1552 case SDLK_RCTRL: v = MKC_formac_RControl; break; 1553 case SDLK_LCTRL: v = MKC_formac_Control; break; 1554 case SDLK_RALT: v = MKC_formac_RCommand; break; 1555 case SDLK_LALT: v = MKC_formac_Command; break; 1556 case SDLK_RMETA: v = MKC_formac_RCommand; break; 1557 case SDLK_LMETA: v = MKC_formac_Command; break; 1558 case SDLK_LSUPER: v = MKC_formac_Option; break; 1559 case SDLK_RSUPER: v = MKC_formac_ROption; break; 1560 1561 case SDLK_MODE: /* ? */ break; 1562 case SDLK_COMPOSE: /* ? */ break; 1563 1564 case SDLK_HELP: v = MKC_formac_Help; break; 1565 case SDLK_PRINT: v = MKC_Print; break; 1566 1567 case SDLK_SYSREQ: /* ? */ break; 1568 case SDLK_BREAK: /* ? */ break; 1569 case SDLK_MENU: /* ? */ break; 1570 case SDLK_POWER: /* ? */ break; 1571 case SDLK_EURO: /* ? */ break; 1572 case SDLK_UNDO: /* ? */ break; 1573 1574 default: 1575 break; 1576 } 1577 1578 return v; 1579} 1580#elif 2 == SDL_MAJOR_VERSION 1581LOCALFUNC ui3r SDLScan2MacKeyCode(SDL_Scancode i) 1582{ 1583 ui3r v = MKC_None; 1584 1585 switch (i) { 1586 case SDL_SCANCODE_BACKSPACE: v = MKC_BackSpace; break; 1587 case SDL_SCANCODE_TAB: v = MKC_Tab; break; 1588 case SDL_SCANCODE_CLEAR: v = MKC_Clear; break; 1589 case SDL_SCANCODE_RETURN: v = MKC_Return; break; 1590 case SDL_SCANCODE_PAUSE: v = MKC_Pause; break; 1591 case SDL_SCANCODE_ESCAPE: v = MKC_formac_Escape; break; 1592 case SDL_SCANCODE_SPACE: v = MKC_Space; break; 1593 case SDL_SCANCODE_APOSTROPHE: v = MKC_SingleQuote; break; 1594 case SDL_SCANCODE_COMMA: v = MKC_Comma; break; 1595 case SDL_SCANCODE_MINUS: v = MKC_Minus; break; 1596 case SDL_SCANCODE_PERIOD: v = MKC_Period; break; 1597 case SDL_SCANCODE_SLASH: v = MKC_formac_Slash; break; 1598 case SDL_SCANCODE_0: v = MKC_0; break; 1599 case SDL_SCANCODE_1: v = MKC_1; break; 1600 case SDL_SCANCODE_2: v = MKC_2; break; 1601 case SDL_SCANCODE_3: v = MKC_3; break; 1602 case SDL_SCANCODE_4: v = MKC_4; break; 1603 case SDL_SCANCODE_5: v = MKC_5; break; 1604 case SDL_SCANCODE_6: v = MKC_6; break; 1605 case SDL_SCANCODE_7: v = MKC_7; break; 1606 case SDL_SCANCODE_8: v = MKC_8; break; 1607 case SDL_SCANCODE_9: v = MKC_9; break; 1608 case SDL_SCANCODE_SEMICOLON: v = MKC_SemiColon; break; 1609 case SDL_SCANCODE_EQUALS: v = MKC_Equal; break; 1610 1611 case SDL_SCANCODE_LEFTBRACKET: v = MKC_LeftBracket; break; 1612 case SDL_SCANCODE_BACKSLASH: v = MKC_formac_BackSlash; break; 1613 case SDL_SCANCODE_RIGHTBRACKET: v = MKC_RightBracket; break; 1614 case SDL_SCANCODE_GRAVE: v = MKC_formac_Grave; break; 1615 1616 case SDL_SCANCODE_A: v = MKC_A; break; 1617 case SDL_SCANCODE_B: v = MKC_B; break; 1618 case SDL_SCANCODE_C: v = MKC_C; break; 1619 case SDL_SCANCODE_D: v = MKC_D; break; 1620 case SDL_SCANCODE_E: v = MKC_E; break; 1621 case SDL_SCANCODE_F: v = MKC_F; break; 1622 case SDL_SCANCODE_G: v = MKC_G; break; 1623 case SDL_SCANCODE_H: v = MKC_H; break; 1624 case SDL_SCANCODE_I: v = MKC_I; break; 1625 case SDL_SCANCODE_J: v = MKC_J; break; 1626 case SDL_SCANCODE_K: v = MKC_K; break; 1627 case SDL_SCANCODE_L: v = MKC_L; break; 1628 case SDL_SCANCODE_M: v = MKC_M; break; 1629 case SDL_SCANCODE_N: v = MKC_N; break; 1630 case SDL_SCANCODE_O: v = MKC_O; break; 1631 case SDL_SCANCODE_P: v = MKC_P; break; 1632 case SDL_SCANCODE_Q: v = MKC_Q; break; 1633 case SDL_SCANCODE_R: v = MKC_R; break; 1634 case SDL_SCANCODE_S: v = MKC_S; break; 1635 case SDL_SCANCODE_T: v = MKC_T; break; 1636 case SDL_SCANCODE_U: v = MKC_U; break; 1637 case SDL_SCANCODE_V: v = MKC_V; break; 1638 case SDL_SCANCODE_W: v = MKC_W; break; 1639 case SDL_SCANCODE_X: v = MKC_X; break; 1640 case SDL_SCANCODE_Y: v = MKC_Y; break; 1641 case SDL_SCANCODE_Z: v = MKC_Z; break; 1642 1643 case SDL_SCANCODE_KP_0: v = MKC_KP0; break; 1644 case SDL_SCANCODE_KP_1: v = MKC_KP1; break; 1645 case SDL_SCANCODE_KP_2: v = MKC_KP2; break; 1646 case SDL_SCANCODE_KP_3: v = MKC_KP3; break; 1647 case SDL_SCANCODE_KP_4: v = MKC_KP4; break; 1648 case SDL_SCANCODE_KP_5: v = MKC_KP5; break; 1649 case SDL_SCANCODE_KP_6: v = MKC_KP6; break; 1650 case SDL_SCANCODE_KP_7: v = MKC_KP7; break; 1651 case SDL_SCANCODE_KP_8: v = MKC_KP8; break; 1652 case SDL_SCANCODE_KP_9: v = MKC_KP9; break; 1653 1654 case SDL_SCANCODE_KP_PERIOD: v = MKC_Decimal; break; 1655 case SDL_SCANCODE_KP_DIVIDE: v = MKC_KPDevide; break; 1656 case SDL_SCANCODE_KP_MULTIPLY: v = MKC_KPMultiply; break; 1657 case SDL_SCANCODE_KP_MINUS: v = MKC_KPSubtract; break; 1658 case SDL_SCANCODE_KP_PLUS: v = MKC_KPAdd; break; 1659 case SDL_SCANCODE_KP_ENTER: v = MKC_formac_Enter; break; 1660 case SDL_SCANCODE_KP_EQUALS: v = MKC_KPEqual; break; 1661 1662 case SDL_SCANCODE_UP: v = MKC_Up; break; 1663 case SDL_SCANCODE_DOWN: v = MKC_Down; break; 1664 case SDL_SCANCODE_RIGHT: v = MKC_Right; break; 1665 case SDL_SCANCODE_LEFT: v = MKC_Left; break; 1666 case SDL_SCANCODE_INSERT: v = MKC_formac_Help; break; 1667 case SDL_SCANCODE_HOME: v = MKC_formac_Home; break; 1668 case SDL_SCANCODE_END: v = MKC_formac_End; break; 1669 case SDL_SCANCODE_PAGEUP: v = MKC_formac_PageUp; break; 1670 case SDL_SCANCODE_PAGEDOWN: v = MKC_formac_PageDown; break; 1671 1672 case SDL_SCANCODE_F1: v = MKC_formac_F1; break; 1673 case SDL_SCANCODE_F2: v = MKC_formac_F2; break; 1674 case SDL_SCANCODE_F3: v = MKC_formac_F3; break; 1675 case SDL_SCANCODE_F4: v = MKC_formac_F4; break; 1676 case SDL_SCANCODE_F5: v = MKC_formac_F5; break; 1677 case SDL_SCANCODE_F6: v = MKC_F6; break; 1678 case SDL_SCANCODE_F7: v = MKC_F7; break; 1679 case SDL_SCANCODE_F8: v = MKC_F8; break; 1680 case SDL_SCANCODE_F9: v = MKC_F9; break; 1681 case SDL_SCANCODE_F10: v = MKC_F10; break; 1682 case SDL_SCANCODE_F11: v = MKC_F11; break; 1683 case SDL_SCANCODE_F12: v = MKC_F12; break; 1684 1685 case SDL_SCANCODE_NUMLOCKCLEAR: 1686 v = MKC_formac_ForwardDel; break; 1687 case SDL_SCANCODE_CAPSLOCK: v = MKC_formac_CapsLock; break; 1688 case SDL_SCANCODE_SCROLLLOCK: v = MKC_ScrollLock; break; 1689 case SDL_SCANCODE_RSHIFT: v = MKC_formac_RShift; break; 1690 case SDL_SCANCODE_LSHIFT: v = MKC_formac_Shift; break; 1691 case SDL_SCANCODE_RCTRL: v = MKC_formac_RControl; break; 1692 case SDL_SCANCODE_LCTRL: v = MKC_formac_Control; break; 1693 case SDL_SCANCODE_RALT: v = MKC_formac_ROption; break; 1694 case SDL_SCANCODE_LALT: v = MKC_formac_Option; break; 1695 case SDL_SCANCODE_RGUI: v = MKC_formac_RCommand; break; 1696 case SDL_SCANCODE_LGUI: v = MKC_formac_Command; break; 1697 /* case SDLK_LSUPER: v = MKC_formac_Option; break; */ 1698 /* case SDLK_RSUPER: v = MKC_formac_ROption; break; */ 1699 1700 case SDL_SCANCODE_HELP: v = MKC_formac_Help; break; 1701 case SDL_SCANCODE_PRINTSCREEN: v = MKC_Print; break; 1702 1703 case SDL_SCANCODE_UNDO: v = MKC_formac_F1; break; 1704 case SDL_SCANCODE_CUT: v = MKC_formac_F2; break; 1705 case SDL_SCANCODE_COPY: v = MKC_formac_F3; break; 1706 case SDL_SCANCODE_PASTE: v = MKC_formac_F4; break; 1707 1708 case SDL_SCANCODE_AC_HOME: v = MKC_formac_Home; break; 1709 1710 case SDL_SCANCODE_KP_A: v = MKC_A; break; 1711 case SDL_SCANCODE_KP_B: v = MKC_B; break; 1712 case SDL_SCANCODE_KP_C: v = MKC_C; break; 1713 case SDL_SCANCODE_KP_D: v = MKC_D; break; 1714 case SDL_SCANCODE_KP_E: v = MKC_E; break; 1715 case SDL_SCANCODE_KP_F: v = MKC_F; break; 1716 1717 case SDL_SCANCODE_KP_BACKSPACE: v = MKC_BackSpace; break; 1718 case SDL_SCANCODE_KP_CLEAR: v = MKC_Clear; break; 1719 case SDL_SCANCODE_KP_COMMA: v = MKC_Comma; break; 1720 case SDL_SCANCODE_KP_DECIMAL: v = MKC_Decimal; break; 1721 1722 default: 1723 break; 1724 } 1725 1726 return v; 1727} 1728#endif /* SDL_MAJOR_VERSION */ 1729 1730#if 1 == SDL_MAJOR_VERSION 1731LOCALPROC DoKeyCode(SDL_keysym *r, blnr down) 1732{ 1733 ui3r v = SDLKey2MacKeyCode(r->sym); 1734 if (MKC_None != v) { 1735 Keyboard_UpdateKeyMap2(v, down); 1736 } 1737} 1738#elif 2 == SDL_MAJOR_VERSION 1739LOCALPROC DoKeyCode(SDL_Keysym *r, blnr down) 1740{ 1741 ui3r v = SDLScan2MacKeyCode(r->scancode); 1742 if (MKC_None != v) { 1743 Keyboard_UpdateKeyMap2(v, down); 1744 } 1745} 1746#endif /* SDL_MAJOR_VERSION */ 1747 1748LOCALPROC DisableKeyRepeat(void) 1749{ 1750 /* 1751 OSGLUxxx common: 1752 If possible and useful, disable keyboard autorepeat. 1753 */ 1754} 1755 1756LOCALPROC RestoreKeyRepeat(void) 1757{ 1758 /* 1759 OSGLUxxx common: 1760 Undo any effects of DisableKeyRepeat. 1761 */ 1762} 1763 1764LOCALPROC ReconnectKeyCodes3(void) 1765{ 1766} 1767 1768LOCALPROC DisconnectKeyCodes3(void) 1769{ 1770 DisconnectKeyCodes2(); 1771 MyMouseButtonSet(falseblnr); 1772} 1773 1774/* --- time, date, location --- */ 1775 1776#define HaveWorkingTime 1 1777 1778#define dbglog_TimeStuff (0 && dbglog_HAVE) 1779 1780LOCALVAR ui5b TrueEmulatedTime = 0; 1781 1782#include "DATE2SEC.h" 1783 1784#define TicksPerSecond 1000000 1785 1786LOCALVAR blnr HaveTimeDelta = falseblnr; 1787LOCALVAR ui5b TimeDelta; 1788 1789LOCALVAR ui5b NewMacDateInSeconds; 1790 1791LOCALVAR ui5b LastTimeSec; 1792LOCALVAR ui5b LastTimeUsec; 1793LOCALVAR Uint32 LastTime; 1794LOCALVAR Uint32 NextIntTime; 1795 1796LOCALPROC GetCurrentTicks(void) 1797{ 1798 struct timeval t; 1799 1800 gettimeofday(&t, NULL); 1801 if (! HaveTimeDelta) { 1802 time_t Current_Time; 1803 struct tm *s; 1804 1805 (void) time(&Current_Time); 1806 s = localtime(&Current_Time); 1807 TimeDelta = Date2MacSeconds(s->tm_sec, s->tm_min, s->tm_hour, 1808 s->tm_mday, 1 + s->tm_mon, 1900 + s->tm_year) - t.tv_sec; 1809#if 0 && AutoTimeZone /* how portable is this ? */ 1810 CurMacDelta = ((ui5b)(s->tm_gmtoff) & 0x00FFFFFF) 1811 | ((s->tm_isdst ? 0x80 : 0) << 24); 1812#endif 1813 HaveTimeDelta = trueblnr; 1814 } 1815 1816 NewMacDateInSeconds = t.tv_sec + TimeDelta; 1817 LastTimeSec = (ui5b)t.tv_sec; 1818 LastTimeUsec = (ui5b)t.tv_usec; 1819} 1820 1821#define MyInvTimeStep 16626 /* TicksPerSecond / 60.14742 */ 1822 1823LOCALVAR ui5b NextTimeSec; 1824LOCALVAR ui5b NextTimeUsec; 1825 1826LOCALPROC IncrNextTime(void) 1827{ 1828 NextTimeUsec += MyInvTimeStep; 1829 if (NextTimeUsec >= TicksPerSecond) { 1830 NextTimeUsec -= TicksPerSecond; 1831 NextTimeSec += 1; 1832 } 1833} 1834 1835LOCALPROC InitNextTime(void) 1836{ 1837 NextTimeSec = LastTimeSec; 1838 NextTimeUsec = LastTimeUsec; 1839 IncrNextTime(); 1840} 1841 1842LOCALPROC StartUpTimeAdjust(void) 1843{ 1844 GetCurrentTicks(); 1845 InitNextTime(); 1846} 1847 1848LOCALFUNC si5b GetTimeDiff(void) 1849{ 1850 return ((si5b)(LastTimeSec - NextTimeSec)) * TicksPerSecond 1851 + ((si5b)(LastTimeUsec - NextTimeUsec)); 1852} 1853 1854LOCALPROC UpdateTrueEmulatedTime(void) 1855{ 1856 si5b TimeDiff; 1857 1858 GetCurrentTicks(); 1859 1860 TimeDiff = GetTimeDiff(); 1861 if (TimeDiff >= 0) { 1862 if (TimeDiff > 16 * MyInvTimeStep) { 1863 /* emulation interrupted, forget it */ 1864 ++TrueEmulatedTime; 1865 InitNextTime(); 1866 1867#if dbglog_TimeStuff 1868 dbglog_writelnNum("emulation interrupted", 1869 TrueEmulatedTime); 1870#endif 1871 } else { 1872 do { 1873 ++TrueEmulatedTime; 1874 IncrNextTime(); 1875 TimeDiff -= TicksPerSecond; 1876 } while (TimeDiff >= 0); 1877 } 1878 } else if (TimeDiff < - 16 * MyInvTimeStep) { 1879 /* clock goofed if ever get here, reset */ 1880#if dbglog_TimeStuff 1881 dbglog_writeln("clock set back"); 1882#endif 1883 1884 InitNextTime(); 1885 } 1886} 1887 1888LOCALFUNC blnr CheckDateTime(void) 1889{ 1890 if (CurMacDateInSeconds != NewMacDateInSeconds) { 1891 CurMacDateInSeconds = NewMacDateInSeconds; 1892 return trueblnr; 1893 } else { 1894 return falseblnr; 1895 } 1896} 1897 1898LOCALFUNC blnr InitLocationDat(void) 1899{ 1900 GetCurrentTicks(); 1901 CurMacDateInSeconds = NewMacDateInSeconds; 1902 1903 return trueblnr; 1904} 1905 1906/* --- sound --- */ 1907 1908#if MySoundEnabled 1909 1910#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */ 1911#define kSoundBuffers (1 << kLn2SoundBuffers) 1912#define kSoundBuffMask (kSoundBuffers - 1) 1913 1914#define DesiredMinFilledSoundBuffs 3 1915 /* 1916 if too big then sound lags behind emulation. 1917 if too small then sound will have pauses. 1918 */ 1919 1920#define kLnOneBuffLen 9 1921#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen) 1922#define kOneBuffLen (1UL << kLnOneBuffLen) 1923#define kAllBuffLen (1UL << kLnAllBuffLen) 1924#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3) 1925#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3) 1926#define kOneBuffSz (1UL << kLnOneBuffSz) 1927#define kAllBuffSz (1UL << kLnAllBuffSz) 1928#define kOneBuffMask (kOneBuffLen - 1) 1929#define kAllBuffMask (kAllBuffLen - 1) 1930#define dbhBufferSize (kAllBuffSz + kOneBuffSz) 1931 1932#define dbglog_SoundStuff (0 && dbglog_HAVE) 1933#define dbglog_SoundBuffStats (0 && dbglog_HAVE) 1934 1935LOCALVAR tpSoundSamp TheSoundBuffer = nullpr; 1936volatile static ui4b ThePlayOffset; 1937volatile static ui4b TheFillOffset; 1938volatile static ui4b MinFilledSoundBuffs; 1939#if dbglog_SoundBuffStats 1940LOCALVAR ui4b MaxFilledSoundBuffs; 1941#endif 1942LOCALVAR ui4b TheWriteOffset; 1943 1944LOCALPROC MySound_Init0(void) 1945{ 1946 ThePlayOffset = 0; 1947 TheFillOffset = 0; 1948 TheWriteOffset = 0; 1949} 1950 1951LOCALPROC MySound_Start0(void) 1952{ 1953 /* Reset variables */ 1954 MinFilledSoundBuffs = kSoundBuffers + 1; 1955#if dbglog_SoundBuffStats 1956 MaxFilledSoundBuffs = 0; 1957#endif 1958} 1959 1960GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL) 1961{ 1962 ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset); 1963 ui4b WriteBuffContig = 1964 kOneBuffLen - (TheWriteOffset & kOneBuffMask); 1965 1966 if (WriteBuffContig < n) { 1967 n = WriteBuffContig; 1968 } 1969 if (ToFillLen < n) { 1970 /* overwrite previous buffer */ 1971#if dbglog_SoundStuff 1972 dbglog_writeln("sound buffer over flow"); 1973#endif 1974 TheWriteOffset -= kOneBuffLen; 1975 } 1976 1977 *actL = n; 1978 return TheSoundBuffer + (TheWriteOffset & kAllBuffMask); 1979} 1980 1981#if 4 == kLn2SoundSampSz 1982LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p) 1983{ 1984 int i; 1985 1986 for (i = kOneBuffLen; --i >= 0; ) { 1987 *p++ -= 0x8000; 1988 } 1989} 1990#else 1991#define ConvertSoundBlockToNative(p) 1992#endif 1993 1994LOCALPROC MySound_WroteABlock(void) 1995{ 1996#if (4 == kLn2SoundSampSz) 1997 ui4b PrevWriteOffset = TheWriteOffset - kOneBuffLen; 1998 tpSoundSamp p = TheSoundBuffer + (PrevWriteOffset & kAllBuffMask); 1999#endif 2000 2001#if dbglog_SoundStuff 2002 dbglog_writeln("enter MySound_WroteABlock"); 2003#endif 2004 2005 ConvertSoundBlockToNative(p); 2006 2007 TheFillOffset = TheWriteOffset; 2008 2009#if dbglog_SoundBuffStats 2010 { 2011 ui4b ToPlayLen = TheFillOffset 2012 - ThePlayOffset; 2013 ui4b ToPlayBuffs = ToPlayLen >> kLnOneBuffLen; 2014 2015 if (ToPlayBuffs > MaxFilledSoundBuffs) { 2016 MaxFilledSoundBuffs = ToPlayBuffs; 2017 } 2018 } 2019#endif 2020} 2021 2022LOCALFUNC blnr MySound_EndWrite0(ui4r actL) 2023{ 2024 blnr v; 2025 2026 TheWriteOffset += actL; 2027 2028 if (0 != (TheWriteOffset & kOneBuffMask)) { 2029 v = falseblnr; 2030 } else { 2031 /* just finished a block */ 2032 2033 MySound_WroteABlock(); 2034 2035 v = trueblnr; 2036 } 2037 2038 return v; 2039} 2040 2041LOCALPROC MySound_SecondNotify0(void) 2042{ 2043 if (MinFilledSoundBuffs <= kSoundBuffers) { 2044 if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) { 2045#if dbglog_SoundStuff 2046 dbglog_writeln("MinFilledSoundBuffs too high"); 2047#endif 2048 IncrNextTime(); 2049 } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) { 2050#if dbglog_SoundStuff 2051 dbglog_writeln("MinFilledSoundBuffs too low"); 2052#endif 2053 ++TrueEmulatedTime; 2054 } 2055#if dbglog_SoundBuffStats 2056 dbglog_writelnNum("MinFilledSoundBuffs", 2057 MinFilledSoundBuffs); 2058 dbglog_writelnNum("MaxFilledSoundBuffs", 2059 MaxFilledSoundBuffs); 2060 MaxFilledSoundBuffs = 0; 2061#endif 2062 MinFilledSoundBuffs = kSoundBuffers + 1; 2063 } 2064} 2065 2066typedef ui4r trSoundTemp; 2067 2068#define kCenterTempSound 0x8000 2069 2070#define AudioStepVal 0x0040 2071 2072#if 3 == kLn2SoundSampSz 2073#define ConvertTempSoundSampleFromNative(v) ((v) << 8) 2074#elif 4 == kLn2SoundSampSz 2075#define ConvertTempSoundSampleFromNative(v) ((v) + kCenterSound) 2076#else 2077#error "unsupported kLn2SoundSampSz" 2078#endif 2079 2080#if 3 == kLn2SoundSampSz 2081#define ConvertTempSoundSampleToNative(v) ((v) >> 8) 2082#elif 4 == kLn2SoundSampSz 2083#define ConvertTempSoundSampleToNative(v) ((v) - kCenterSound) 2084#else 2085#error "unsupported kLn2SoundSampSz" 2086#endif 2087 2088LOCALPROC SoundRampTo(trSoundTemp *last_val, trSoundTemp dst_val, 2089 tpSoundSamp *stream, int *len) 2090{ 2091 trSoundTemp diff; 2092 tpSoundSamp p = *stream; 2093 int n = *len; 2094 trSoundTemp v1 = *last_val; 2095 2096 while ((v1 != dst_val) && (0 != n)) { 2097 if (v1 > dst_val) { 2098 diff = v1 - dst_val; 2099 if (diff > AudioStepVal) { 2100 v1 -= AudioStepVal; 2101 } else { 2102 v1 = dst_val; 2103 } 2104 } else { 2105 diff = dst_val - v1; 2106 if (diff > AudioStepVal) { 2107 v1 += AudioStepVal; 2108 } else { 2109 v1 = dst_val; 2110 } 2111 } 2112 2113 --n; 2114 *p++ = ConvertTempSoundSampleToNative(v1); 2115 } 2116 2117 *stream = p; 2118 *len = n; 2119 *last_val = v1; 2120} 2121 2122struct MySoundR { 2123 tpSoundSamp fTheSoundBuffer; 2124 volatile ui4b (*fPlayOffset); 2125 volatile ui4b (*fFillOffset); 2126 volatile ui4b (*fMinFilledSoundBuffs); 2127 2128 volatile trSoundTemp lastv; 2129 2130 blnr wantplaying; 2131 blnr HaveStartedPlaying; 2132}; 2133typedef struct MySoundR MySoundR; 2134 2135#if 0 != SDL_MAJOR_VERSION 2136static void my_audio_callback(void *udata, Uint8 *stream, int len) 2137{ 2138 ui4b ToPlayLen; 2139 ui4b FilledSoundBuffs; 2140 int i; 2141 MySoundR *datp = (MySoundR *)udata; 2142 tpSoundSamp CurSoundBuffer = datp->fTheSoundBuffer; 2143 ui4b CurPlayOffset = *datp->fPlayOffset; 2144 trSoundTemp v0 = datp->lastv; 2145 trSoundTemp v1 = v0; 2146 tpSoundSamp dst = (tpSoundSamp)stream; 2147 2148#if kLn2SoundSampSz > 3 2149 len >>= (kLn2SoundSampSz - 3); 2150#endif 2151 2152#if dbglog_SoundStuff 2153 dbglog_writeln("Enter my_audio_callback"); 2154 dbglog_writelnNum("len", len); 2155#endif 2156 2157label_retry: 2158 ToPlayLen = *datp->fFillOffset - CurPlayOffset; 2159 FilledSoundBuffs = ToPlayLen >> kLnOneBuffLen; 2160 2161 if (! datp->wantplaying) { 2162#if dbglog_SoundStuff 2163 dbglog_writeln("playing end transistion"); 2164#endif 2165 2166 SoundRampTo(&v1, kCenterTempSound, &dst, &len); 2167 2168 ToPlayLen = 0; 2169 } else if (! datp->HaveStartedPlaying) { 2170#if dbglog_SoundStuff 2171 dbglog_writeln("playing start block"); 2172#endif 2173 2174 if ((ToPlayLen >> kLnOneBuffLen) < 8) { 2175 ToPlayLen = 0; 2176 } else { 2177 tpSoundSamp p = datp->fTheSoundBuffer 2178 + (CurPlayOffset & kAllBuffMask); 2179 trSoundTemp v2 = ConvertTempSoundSampleFromNative(*p); 2180 2181#if dbglog_SoundStuff 2182 dbglog_writeln("have enough samples to start"); 2183#endif 2184 2185 SoundRampTo(&v1, v2, &dst, &len); 2186 2187 if (v1 == v2) { 2188#if dbglog_SoundStuff 2189 dbglog_writeln("finished start transition"); 2190#endif 2191 2192 datp->HaveStartedPlaying = trueblnr; 2193 } 2194 } 2195 } 2196 2197 if (0 == len) { 2198 /* done */ 2199 2200 if (FilledSoundBuffs < *datp->fMinFilledSoundBuffs) { 2201 *datp->fMinFilledSoundBuffs = FilledSoundBuffs; 2202 } 2203 } else if (0 == ToPlayLen) { 2204 2205#if dbglog_SoundStuff 2206 dbglog_writeln("under run"); 2207#endif 2208 2209 for (i = 0; i < len; ++i) { 2210 *dst++ = ConvertTempSoundSampleToNative(v1); 2211 } 2212 *datp->fMinFilledSoundBuffs = 0; 2213 } else { 2214 ui4b PlayBuffContig = kAllBuffLen 2215 - (CurPlayOffset & kAllBuffMask); 2216 tpSoundSamp p = CurSoundBuffer 2217 + (CurPlayOffset & kAllBuffMask); 2218 2219 if (ToPlayLen > PlayBuffContig) { 2220 ToPlayLen = PlayBuffContig; 2221 } 2222 if (ToPlayLen > len) { 2223 ToPlayLen = len; 2224 } 2225 2226 for (i = 0; i < ToPlayLen; ++i) { 2227 *dst++ = *p++; 2228 } 2229 v1 = ConvertTempSoundSampleFromNative(p[-1]); 2230 2231 CurPlayOffset += ToPlayLen; 2232 len -= ToPlayLen; 2233 2234 *datp->fPlayOffset = CurPlayOffset; 2235 2236 goto label_retry; 2237 } 2238 2239 datp->lastv = v1; 2240} 2241#endif /* 0 != SDL_MAJOR_VERSION */ 2242 2243LOCALVAR MySoundR cur_audio; 2244 2245LOCALVAR blnr HaveSoundOut = falseblnr; 2246 2247LOCALPROC MySound_Stop(void) 2248{ 2249#if dbglog_SoundStuff 2250 dbglog_writeln("enter MySound_Stop"); 2251#endif 2252 2253 if (cur_audio.wantplaying && HaveSoundOut) { 2254 ui4r retry_limit = 50; /* half of a second */ 2255 2256 cur_audio.wantplaying = falseblnr; 2257 2258label_retry: 2259 if (kCenterTempSound == cur_audio.lastv) { 2260#if dbglog_SoundStuff 2261 dbglog_writeln("reached kCenterTempSound"); 2262#endif 2263 2264 /* done */ 2265 } else if (0 == --retry_limit) { 2266#if dbglog_SoundStuff 2267 dbglog_writeln("retry limit reached"); 2268#endif 2269 /* done */ 2270 } else 2271 { 2272 /* 2273 give time back, particularly important 2274 if got here on a suspend event. 2275 */ 2276 2277#if dbglog_SoundStuff 2278 dbglog_writeln("busy, so sleep"); 2279#endif 2280 2281#if 0 != SDL_MAJOR_VERSION 2282 (void) SDL_Delay(10); 2283#endif 2284 2285 goto label_retry; 2286 } 2287 2288#if 0 != SDL_MAJOR_VERSION 2289 SDL_PauseAudio(1); 2290#endif 2291 } 2292 2293#if dbglog_SoundStuff 2294 dbglog_writeln("leave MySound_Stop"); 2295#endif 2296} 2297 2298LOCALPROC MySound_Start(void) 2299{ 2300 if ((! cur_audio.wantplaying) && HaveSoundOut) { 2301 MySound_Start0(); 2302 cur_audio.lastv = kCenterTempSound; 2303 cur_audio.HaveStartedPlaying = falseblnr; 2304 cur_audio.wantplaying = trueblnr; 2305 2306#if 0 != SDL_MAJOR_VERSION 2307 SDL_PauseAudio(0); 2308#endif 2309 } 2310} 2311 2312LOCALPROC MySound_UnInit(void) 2313{ 2314 if (HaveSoundOut) { 2315#if 0 != SDL_MAJOR_VERSION 2316 SDL_CloseAudio(); 2317#endif 2318 } 2319} 2320 2321#define SOUND_SAMPLERATE 22255 /* = round(7833600 * 2 / 704) */ 2322 2323LOCALFUNC blnr MySound_Init(void) 2324{ 2325#if dbglog_OSGInit 2326 dbglog_writeln("enter MySound_Init"); 2327#endif 2328 2329#if 0 != SDL_MAJOR_VERSION 2330 SDL_AudioSpec desired; 2331#endif 2332 2333 MySound_Init0(); 2334 2335 cur_audio.fTheSoundBuffer = TheSoundBuffer; 2336 cur_audio.fPlayOffset = &ThePlayOffset; 2337 cur_audio.fFillOffset = &TheFillOffset; 2338 cur_audio.fMinFilledSoundBuffs = &MinFilledSoundBuffs; 2339 cur_audio.wantplaying = falseblnr; 2340 2341#if 0 != SDL_MAJOR_VERSION 2342 desired.freq = SOUND_SAMPLERATE; 2343 2344#if 3 == kLn2SoundSampSz 2345 desired.format = AUDIO_U8; 2346#elif 4 == kLn2SoundSampSz 2347 desired.format = AUDIO_S16SYS; 2348#else 2349#error "unsupported audio format" 2350#endif 2351 2352 desired.channels = 1; 2353 desired.samples = 1024; 2354 desired.callback = my_audio_callback; 2355 desired.userdata = (void *)&cur_audio; 2356 2357 /* Open the audio device */ 2358 if (SDL_OpenAudio(&desired, NULL) < 0) { 2359 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); 2360 } else { 2361 HaveSoundOut = trueblnr; 2362 2363 MySound_Start(); 2364 /* 2365 This should be taken care of by LeaveSpeedStopped, 2366 but since takes a while to get going properly, 2367 start early. 2368 */ 2369 } 2370#endif /* 0 != SDL_MAJOR_VERSION */ 2371 2372 return trueblnr; /* keep going, even if no sound */ 2373} 2374 2375GLOBALOSGLUPROC MySound_EndWrite(ui4r actL) 2376{ 2377 if (MySound_EndWrite0(actL)) { 2378 } 2379} 2380 2381LOCALPROC MySound_SecondNotify(void) 2382{ 2383 /* 2384 OSGLUxxx common: 2385 called once a second. 2386 can be used to check if sound output it 2387 lagging or gaining, and if so 2388 adjust emulated time by a tick. 2389 */ 2390 2391 if (HaveSoundOut) { 2392 MySound_SecondNotify0(); 2393 } 2394} 2395 2396#endif /* MySoundEnabled */ 2397 2398/* --- basic dialogs --- */ 2399 2400LOCALPROC CheckSavedMacMsg(void) 2401{ 2402 /* 2403 OSGLUxxx common: 2404 This is currently only used in the 2405 rare case where there is a message 2406 still pending as the program quits. 2407 */ 2408 2409 if (nullpr != SavedBriefMsg) { 2410 char briefMsg0[ClStrMaxLength + 1]; 2411 char longMsg0[ClStrMaxLength + 1]; 2412 2413 NativeStrFromCStr(briefMsg0, SavedBriefMsg); 2414 NativeStrFromCStr(longMsg0, SavedLongMsg); 2415 2416#if 2 == SDL_MAJOR_VERSION 2417 if (0 != SDL_ShowSimpleMessageBox( 2418 SDL_MESSAGEBOX_ERROR, 2419 SavedBriefMsg, 2420 SavedLongMsg, 2421 my_main_wind 2422 )) 2423#endif 2424 { 2425 fprintf(stderr, "%s\n", briefMsg0); 2426 fprintf(stderr, "%s\n", longMsg0); 2427 } 2428 2429 SavedBriefMsg = nullpr; 2430 } 2431} 2432 2433/* --- clipboard --- */ 2434 2435#if IncludeHostTextClipExchange 2436LOCALFUNC uimr MacRoman2UniCodeSize(ui3b *s, uimr L) 2437{ 2438 uimr i; 2439 ui3r x; 2440 uimr n; 2441 uimr v = 0; 2442 2443 for (i = 0; i < L; ++i) { 2444 x = *s++; 2445 if (x < 128) { 2446 n = 1; 2447 } else { 2448 switch (x) { 2449 case 0x80: n = 2; break; 2450 /* LATIN CAPITAL LETTER A WITH DIAERESIS */ 2451 case 0x81: n = 2; break; 2452 /* LATIN CAPITAL LETTER A WITH RING ABOVE */ 2453 case 0x82: n = 2; break; 2454 /* LATIN CAPITAL LETTER C WITH CEDILLA */ 2455 case 0x83: n = 2; break; 2456 /* LATIN CAPITAL LETTER E WITH ACUTE */ 2457 case 0x84: n = 2; break; 2458 /* LATIN CAPITAL LETTER N WITH TILDE */ 2459 case 0x85: n = 2; break; 2460 /* LATIN CAPITAL LETTER O WITH DIAERESIS */ 2461 case 0x86: n = 2; break; 2462 /* LATIN CAPITAL LETTER U WITH DIAERESIS */ 2463 case 0x87: n = 2; break; 2464 /* LATIN SMALL LETTER A WITH ACUTE */ 2465 case 0x88: n = 2; break; 2466 /* LATIN SMALL LETTER A WITH GRAVE */ 2467 case 0x89: n = 2; break; 2468 /* LATIN SMALL LETTER A WITH CIRCUMFLEX */ 2469 case 0x8A: n = 2; break; 2470 /* LATIN SMALL LETTER A WITH DIAERESIS */ 2471 case 0x8B: n = 2; break; 2472 /* LATIN SMALL LETTER A WITH TILDE */ 2473 case 0x8C: n = 2; break; 2474 /* LATIN SMALL LETTER A WITH RING ABOVE */ 2475 case 0x8D: n = 2; break; 2476 /* LATIN SMALL LETTER C WITH CEDILLA */ 2477 case 0x8E: n = 2; break; 2478 /* LATIN SMALL LETTER E WITH ACUTE */ 2479 case 0x8F: n = 2; break; 2480 /* LATIN SMALL LETTER E WITH GRAVE */ 2481 case 0x90: n = 2; break; 2482 /* LATIN SMALL LETTER E WITH CIRCUMFLEX */ 2483 case 0x91: n = 2; break; 2484 /* LATIN SMALL LETTER E WITH DIAERESIS */ 2485 case 0x92: n = 2; break; 2486 /* LATIN SMALL LETTER I WITH ACUTE */ 2487 case 0x93: n = 2; break; 2488 /* LATIN SMALL LETTER I WITH GRAVE */ 2489 case 0x94: n = 2; break; 2490 /* LATIN SMALL LETTER I WITH CIRCUMFLEX */ 2491 case 0x95: n = 2; break; 2492 /* LATIN SMALL LETTER I WITH DIAERESIS */ 2493 case 0x96: n = 2; break; 2494 /* LATIN SMALL LETTER N WITH TILDE */ 2495 case 0x97: n = 2; break; 2496 /* LATIN SMALL LETTER O WITH ACUTE */ 2497 case 0x98: n = 2; break; 2498 /* LATIN SMALL LETTER O WITH GRAVE */ 2499 case 0x99: n = 2; break; 2500 /* LATIN SMALL LETTER O WITH CIRCUMFLEX */ 2501 case 0x9A: n = 2; break; 2502 /* LATIN SMALL LETTER O WITH DIAERESIS */ 2503 case 0x9B: n = 2; break; 2504 /* LATIN SMALL LETTER O WITH TILDE */ 2505 case 0x9C: n = 2; break; 2506 /* LATIN SMALL LETTER U WITH ACUTE */ 2507 case 0x9D: n = 2; break; 2508 /* LATIN SMALL LETTER U WITH GRAVE */ 2509 case 0x9E: n = 2; break; 2510 /* LATIN SMALL LETTER U WITH CIRCUMFLEX */ 2511 case 0x9F: n = 2; break; 2512 /* LATIN SMALL LETTER U WITH DIAERESIS */ 2513 case 0xA0: n = 3; break; 2514 /* DAGGER */ 2515 case 0xA1: n = 2; break; 2516 /* DEGREE SIGN */ 2517 case 0xA2: n = 2; break; 2518 /* CENT SIGN */ 2519 case 0xA3: n = 2; break; 2520 /* POUND SIGN */ 2521 case 0xA4: n = 2; break; 2522 /* SECTION SIGN */ 2523 case 0xA5: n = 3; break; 2524 /* BULLET */ 2525 case 0xA6: n = 2; break; 2526 /* PILCROW SIGN */ 2527 case 0xA7: n = 2; break; 2528 /* LATIN SMALL LETTER SHARP S */ 2529 case 0xA8: n = 2; break; 2530 /* REGISTERED SIGN */ 2531 case 0xA9: n = 2; break; 2532 /* COPYRIGHT SIGN */ 2533 case 0xAA: n = 3; break; 2534 /* TRADE MARK SIGN */ 2535 case 0xAB: n = 2; break; 2536 /* ACUTE ACCENT */ 2537 case 0xAC: n = 2; break; 2538 /* DIAERESIS */ 2539 case 0xAD: n = 3; break; 2540 /* NOT EQUAL TO */ 2541 case 0xAE: n = 2; break; 2542 /* LATIN CAPITAL LETTER AE */ 2543 case 0xAF: n = 2; break; 2544 /* LATIN CAPITAL LETTER O WITH STROKE */ 2545 case 0xB0: n = 3; break; 2546 /* INFINITY */ 2547 case 0xB1: n = 2; break; 2548 /* PLUS-MINUS SIGN */ 2549 case 0xB2: n = 3; break; 2550 /* LESS-THAN OR EQUAL TO */ 2551 case 0xB3: n = 3; break; 2552 /* GREATER-THAN OR EQUAL TO */ 2553 case 0xB4: n = 2; break; 2554 /* YEN SIGN */ 2555 case 0xB5: n = 2; break; 2556 /* MICRO SIGN */ 2557 case 0xB6: n = 3; break; 2558 /* PARTIAL DIFFERENTIAL */ 2559 case 0xB7: n = 3; break; 2560 /* N-ARY SUMMATION */ 2561 case 0xB8: n = 3; break; 2562 /* N-ARY PRODUCT */ 2563 case 0xB9: n = 2; break; 2564 /* GREEK SMALL LETTER PI */ 2565 case 0xBA: n = 3; break; 2566 /* INTEGRAL */ 2567 case 0xBB: n = 2; break; 2568 /* FEMININE ORDINAL INDICATOR */ 2569 case 0xBC: n = 2; break; 2570 /* MASCULINE ORDINAL INDICATOR */ 2571 case 0xBD: n = 2; break; 2572 /* GREEK CAPITAL LETTER OMEGA */ 2573 case 0xBE: n = 2; break; 2574 /* LATIN SMALL LETTER AE */ 2575 case 0xBF: n = 2; break; 2576 /* LATIN SMALL LETTER O WITH STROKE */ 2577 case 0xC0: n = 2; break; 2578 /* INVERTED QUESTION MARK */ 2579 case 0xC1: n = 2; break; 2580 /* INVERTED EXCLAMATION MARK */ 2581 case 0xC2: n = 2; break; 2582 /* NOT SIGN */ 2583 case 0xC3: n = 3; break; 2584 /* SQUARE ROOT */ 2585 case 0xC4: n = 2; break; 2586 /* LATIN SMALL LETTER F WITH HOOK */ 2587 case 0xC5: n = 3; break; 2588 /* ALMOST EQUAL TO */ 2589 case 0xC6: n = 3; break; 2590 /* INCREMENT */ 2591 case 0xC7: n = 2; break; 2592 /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ 2593 case 0xC8: n = 2; break; 2594 /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ 2595 case 0xC9: n = 3; break; 2596 /* HORIZONTAL ELLIPSIS */ 2597 case 0xCA: n = 2; break; 2598 /* NO-BREAK SPACE */ 2599 case 0xCB: n = 2; break; 2600 /* LATIN CAPITAL LETTER A WITH GRAVE */ 2601 case 0xCC: n = 2; break; 2602 /* LATIN CAPITAL LETTER A WITH TILDE */ 2603 case 0xCD: n = 2; break; 2604 /* LATIN CAPITAL LETTER O WITH TILDE */ 2605 case 0xCE: n = 2; break; 2606 /* LATIN CAPITAL LIGATURE OE */ 2607 case 0xCF: n = 2; break; 2608 /* LATIN SMALL LIGATURE OE */ 2609 case 0xD0: n = 3; break; 2610 /* EN DASH */ 2611 case 0xD1: n = 3; break; 2612 /* EM DASH */ 2613 case 0xD2: n = 3; break; 2614 /* LEFT DOUBLE QUOTATION MARK */ 2615 case 0xD3: n = 3; break; 2616 /* RIGHT DOUBLE QUOTATION MARK */ 2617 case 0xD4: n = 3; break; 2618 /* LEFT SINGLE QUOTATION MARK */ 2619 case 0xD5: n = 3; break; 2620 /* RIGHT SINGLE QUOTATION MARK */ 2621 case 0xD6: n = 2; break; 2622 /* DIVISION SIGN */ 2623 case 0xD7: n = 3; break; 2624 /* LOZENGE */ 2625 case 0xD8: n = 2; break; 2626 /* LATIN SMALL LETTER Y WITH DIAERESIS */ 2627 case 0xD9: n = 2; break; 2628 /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ 2629 case 0xDA: n = 3; break; 2630 /* FRACTION SLASH */ 2631 case 0xDB: n = 3; break; 2632 /* EURO SIGN */ 2633 case 0xDC: n = 3; break; 2634 /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ 2635 case 0xDD: n = 3; break; 2636 /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ 2637 case 0xDE: n = 3; break; 2638 /* LATIN SMALL LIGATURE FI */ 2639 case 0xDF: n = 3; break; 2640 /* LATIN SMALL LIGATURE FL */ 2641 case 0xE0: n = 3; break; 2642 /* DOUBLE DAGGER */ 2643 case 0xE1: n = 2; break; 2644 /* MIDDLE DOT */ 2645 case 0xE2: n = 3; break; 2646 /* SINGLE LOW-9 QUOTATION MARK */ 2647 case 0xE3: n = 3; break; 2648 /* DOUBLE LOW-9 QUOTATION MARK */ 2649 case 0xE4: n = 3; break; 2650 /* PER MILLE SIGN */ 2651 case 0xE5: n = 2; break; 2652 /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ 2653 case 0xE6: n = 2; break; 2654 /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ 2655 case 0xE7: n = 2; break; 2656 /* LATIN CAPITAL LETTER A WITH ACUTE */ 2657 case 0xE8: n = 2; break; 2658 /* LATIN CAPITAL LETTER E WITH DIAERESIS */ 2659 case 0xE9: n = 2; break; 2660 /* LATIN CAPITAL LETTER E WITH GRAVE */ 2661 case 0xEA: n = 2; break; 2662 /* LATIN CAPITAL LETTER I WITH ACUTE */ 2663 case 0xEB: n = 2; break; 2664 /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ 2665 case 0xEC: n = 2; break; 2666 /* LATIN CAPITAL LETTER I WITH DIAERESIS */ 2667 case 0xED: n = 2; break; 2668 /* LATIN CAPITAL LETTER I WITH GRAVE */ 2669 case 0xEE: n = 2; break; 2670 /* LATIN CAPITAL LETTER O WITH ACUTE */ 2671 case 0xEF: n = 2; break; 2672 /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ 2673 case 0xF0: n = 3; break; 2674 /* Apple logo */ 2675 case 0xF1: n = 2; break; 2676 /* LATIN CAPITAL LETTER O WITH GRAVE */ 2677 case 0xF2: n = 2; break; 2678 /* LATIN CAPITAL LETTER U WITH ACUTE */ 2679 case 0xF3: n = 2; break; 2680 /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ 2681 case 0xF4: n = 2; break; 2682 /* LATIN CAPITAL LETTER U WITH GRAVE */ 2683 case 0xF5: n = 2; break; 2684 /* LATIN SMALL LETTER DOTLESS I */ 2685 case 0xF6: n = 2; break; 2686 /* MODIFIER LETTER CIRCUMFLEX ACCENT */ 2687 case 0xF7: n = 2; break; 2688 /* SMALL TILDE */ 2689 case 0xF8: n = 2; break; 2690 /* MACRON */ 2691 case 0xF9: n = 2; break; 2692 /* BREVE */ 2693 case 0xFA: n = 2; break; 2694 /* DOT ABOVE */ 2695 case 0xFB: n = 2; break; 2696 /* RING ABOVE */ 2697 case 0xFC: n = 2; break; 2698 /* CEDILLA */ 2699 case 0xFD: n = 2; break; 2700 /* DOUBLE ACUTE ACCENT */ 2701 case 0xFE: n = 2; break; 2702 /* OGONEK */ 2703 case 0xFF: n = 2; break; 2704 /* CARON */ 2705 default: n = 1; break; 2706 /* shouldn't get here */ 2707 } 2708 } 2709 v += n; 2710 } 2711 2712 return v; 2713} 2714#endif 2715 2716#if IncludeHostTextClipExchange 2717LOCALPROC MacRoman2UniCodeData(ui3b *s, uimr L, char *t) 2718{ 2719 uimr i; 2720 ui3r x; 2721 2722 for (i = 0; i < L; ++i) { 2723 x = *s++; 2724 if (x < 128) { 2725 *t++ = x; 2726 } else { 2727 switch (x) { 2728 case 0x80: *t++ = 0xC3; *t++ = 0x84; break; 2729 /* LATIN CAPITAL LETTER A WITH DIAERESIS */ 2730 case 0x81: *t++ = 0xC3; *t++ = 0x85; break; 2731 /* LATIN CAPITAL LETTER A WITH RING ABOVE */ 2732 case 0x82: *t++ = 0xC3; *t++ = 0x87; break; 2733 /* LATIN CAPITAL LETTER C WITH CEDILLA */ 2734 case 0x83: *t++ = 0xC3; *t++ = 0x89; break; 2735 /* LATIN CAPITAL LETTER E WITH ACUTE */ 2736 case 0x84: *t++ = 0xC3; *t++ = 0x91; break; 2737 /* LATIN CAPITAL LETTER N WITH TILDE */ 2738 case 0x85: *t++ = 0xC3; *t++ = 0x96; break; 2739 /* LATIN CAPITAL LETTER O WITH DIAERESIS */ 2740 case 0x86: *t++ = 0xC3; *t++ = 0x9C; break; 2741 /* LATIN CAPITAL LETTER U WITH DIAERESIS */ 2742 case 0x87: *t++ = 0xC3; *t++ = 0xA1; break; 2743 /* LATIN SMALL LETTER A WITH ACUTE */ 2744 case 0x88: *t++ = 0xC3; *t++ = 0xA0; break; 2745 /* LATIN SMALL LETTER A WITH GRAVE */ 2746 case 0x89: *t++ = 0xC3; *t++ = 0xA2; break; 2747 /* LATIN SMALL LETTER A WITH CIRCUMFLEX */ 2748 case 0x8A: *t++ = 0xC3; *t++ = 0xA4; break; 2749 /* LATIN SMALL LETTER A WITH DIAERESIS */ 2750 case 0x8B: *t++ = 0xC3; *t++ = 0xA3; break; 2751 /* LATIN SMALL LETTER A WITH TILDE */ 2752 case 0x8C: *t++ = 0xC3; *t++ = 0xA5; break; 2753 /* LATIN SMALL LETTER A WITH RING ABOVE */ 2754 case 0x8D: *t++ = 0xC3; *t++ = 0xA7; break; 2755 /* LATIN SMALL LETTER C WITH CEDILLA */ 2756 case 0x8E: *t++ = 0xC3; *t++ = 0xA9; break; 2757 /* LATIN SMALL LETTER E WITH ACUTE */ 2758 case 0x8F: *t++ = 0xC3; *t++ = 0xA8; break; 2759 /* LATIN SMALL LETTER E WITH GRAVE */ 2760 case 0x90: *t++ = 0xC3; *t++ = 0xAA; break; 2761 /* LATIN SMALL LETTER E WITH CIRCUMFLEX */ 2762 case 0x91: *t++ = 0xC3; *t++ = 0xAB; break; 2763 /* LATIN SMALL LETTER E WITH DIAERESIS */ 2764 case 0x92: *t++ = 0xC3; *t++ = 0xAD; break; 2765 /* LATIN SMALL LETTER I WITH ACUTE */ 2766 case 0x93: *t++ = 0xC3; *t++ = 0xAC; break; 2767 /* LATIN SMALL LETTER I WITH GRAVE */ 2768 case 0x94: *t++ = 0xC3; *t++ = 0xAE; break; 2769 /* LATIN SMALL LETTER I WITH CIRCUMFLEX */ 2770 case 0x95: *t++ = 0xC3; *t++ = 0xAF; break; 2771 /* LATIN SMALL LETTER I WITH DIAERESIS */ 2772 case 0x96: *t++ = 0xC3; *t++ = 0xB1; break; 2773 /* LATIN SMALL LETTER N WITH TILDE */ 2774 case 0x97: *t++ = 0xC3; *t++ = 0xB3; break; 2775 /* LATIN SMALL LETTER O WITH ACUTE */ 2776 case 0x98: *t++ = 0xC3; *t++ = 0xB2; break; 2777 /* LATIN SMALL LETTER O WITH GRAVE */ 2778 case 0x99: *t++ = 0xC3; *t++ = 0xB4; break; 2779 /* LATIN SMALL LETTER O WITH CIRCUMFLEX */ 2780 case 0x9A: *t++ = 0xC3; *t++ = 0xB6; break; 2781 /* LATIN SMALL LETTER O WITH DIAERESIS */ 2782 case 0x9B: *t++ = 0xC3; *t++ = 0xB5; break; 2783 /* LATIN SMALL LETTER O WITH TILDE */ 2784 case 0x9C: *t++ = 0xC3; *t++ = 0xBA; break; 2785 /* LATIN SMALL LETTER U WITH ACUTE */ 2786 case 0x9D: *t++ = 0xC3; *t++ = 0xB9; break; 2787 /* LATIN SMALL LETTER U WITH GRAVE */ 2788 case 0x9E: *t++ = 0xC3; *t++ = 0xBB; break; 2789 /* LATIN SMALL LETTER U WITH CIRCUMFLEX */ 2790 case 0x9F: *t++ = 0xC3; *t++ = 0xBC; break; 2791 /* LATIN SMALL LETTER U WITH DIAERESIS */ 2792 case 0xA0: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xA0; break; 2793 /* DAGGER */ 2794 case 0xA1: *t++ = 0xC2; *t++ = 0xB0; break; 2795 /* DEGREE SIGN */ 2796 case 0xA2: *t++ = 0xC2; *t++ = 0xA2; break; 2797 /* CENT SIGN */ 2798 case 0xA3: *t++ = 0xC2; *t++ = 0xA3; break; 2799 /* POUND SIGN */ 2800 case 0xA4: *t++ = 0xC2; *t++ = 0xA7; break; 2801 /* SECTION SIGN */ 2802 case 0xA5: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xA2; break; 2803 /* BULLET */ 2804 case 0xA6: *t++ = 0xC2; *t++ = 0xB6; break; 2805 /* PILCROW SIGN */ 2806 case 0xA7: *t++ = 0xC3; *t++ = 0x9F; break; 2807 /* LATIN SMALL LETTER SHARP S */ 2808 case 0xA8: *t++ = 0xC2; *t++ = 0xAE; break; 2809 /* REGISTERED SIGN */ 2810 case 0xA9: *t++ = 0xC2; *t++ = 0xA9; break; 2811 /* COPYRIGHT SIGN */ 2812 case 0xAA: *t++ = 0xE2; *t++ = 0x84; *t++ = 0xA2; break; 2813 /* TRADE MARK SIGN */ 2814 case 0xAB: *t++ = 0xC2; *t++ = 0xB4; break; 2815 /* ACUTE ACCENT */ 2816 case 0xAC: *t++ = 0xC2; *t++ = 0xA8; break; 2817 /* DIAERESIS */ 2818 case 0xAD: *t++ = 0xE2; *t++ = 0x89; *t++ = 0xA0; break; 2819 /* NOT EQUAL TO */ 2820 case 0xAE: *t++ = 0xC3; *t++ = 0x86; break; 2821 /* LATIN CAPITAL LETTER AE */ 2822 case 0xAF: *t++ = 0xC3; *t++ = 0x98; break; 2823 /* LATIN CAPITAL LETTER O WITH STROKE */ 2824 case 0xB0: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x9E; break; 2825 /* INFINITY */ 2826 case 0xB1: *t++ = 0xC2; *t++ = 0xB1; break; 2827 /* PLUS-MINUS SIGN */ 2828 case 0xB2: *t++ = 0xE2; *t++ = 0x89; *t++ = 0xA4; break; 2829 /* LESS-THAN OR EQUAL TO */ 2830 case 0xB3: *t++ = 0xE2; *t++ = 0x89; *t++ = 0xA5; break; 2831 /* GREATER-THAN OR EQUAL TO */ 2832 case 0xB4: *t++ = 0xC2; *t++ = 0xA5; break; 2833 /* YEN SIGN */ 2834 case 0xB5: *t++ = 0xC2; *t++ = 0xB5; break; 2835 /* MICRO SIGN */ 2836 case 0xB6: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x82; break; 2837 /* PARTIAL DIFFERENTIAL */ 2838 case 0xB7: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x91; break; 2839 /* N-ARY SUMMATION */ 2840 case 0xB8: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x8F; break; 2841 /* N-ARY PRODUCT */ 2842 case 0xB9: *t++ = 0xCF; *t++ = 0x80; break; 2843 /* GREEK SMALL LETTER PI */ 2844 case 0xBA: *t++ = 0xE2; *t++ = 0x88; *t++ = 0xAB; break; 2845 /* INTEGRAL */ 2846 case 0xBB: *t++ = 0xC2; *t++ = 0xAA; break; 2847 /* FEMININE ORDINAL INDICATOR */ 2848 case 0xBC: *t++ = 0xC2; *t++ = 0xBA; break; 2849 /* MASCULINE ORDINAL INDICATOR */ 2850 case 0xBD: *t++ = 0xCE; *t++ = 0xA9; break; 2851 /* GREEK CAPITAL LETTER OMEGA */ 2852 case 0xBE: *t++ = 0xC3; *t++ = 0xA6; break; 2853 /* LATIN SMALL LETTER AE */ 2854 case 0xBF: *t++ = 0xC3; *t++ = 0xB8; break; 2855 /* LATIN SMALL LETTER O WITH STROKE */ 2856 case 0xC0: *t++ = 0xC2; *t++ = 0xBF; break; 2857 /* INVERTED QUESTION MARK */ 2858 case 0xC1: *t++ = 0xC2; *t++ = 0xA1; break; 2859 /* INVERTED EXCLAMATION MARK */ 2860 case 0xC2: *t++ = 0xC2; *t++ = 0xAC; break; 2861 /* NOT SIGN */ 2862 case 0xC3: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x9A; break; 2863 /* SQUARE ROOT */ 2864 case 0xC4: *t++ = 0xC6; *t++ = 0x92; break; 2865 /* LATIN SMALL LETTER F WITH HOOK */ 2866 case 0xC5: *t++ = 0xE2; *t++ = 0x89; *t++ = 0x88; break; 2867 /* ALMOST EQUAL TO */ 2868 case 0xC6: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x86; break; 2869 /* INCREMENT */ 2870 case 0xC7: *t++ = 0xC2; *t++ = 0xAB; break; 2871 /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ 2872 case 0xC8: *t++ = 0xC2; *t++ = 0xBB; break; 2873 /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ 2874 case 0xC9: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xA6; break; 2875 /* HORIZONTAL ELLIPSIS */ 2876 case 0xCA: *t++ = 0xC2; *t++ = 0xA0; break; 2877 /* NO-BREAK SPACE */ 2878 case 0xCB: *t++ = 0xC3; *t++ = 0x80; break; 2879 /* LATIN CAPITAL LETTER A WITH GRAVE */ 2880 case 0xCC: *t++ = 0xC3; *t++ = 0x83; break; 2881 /* LATIN CAPITAL LETTER A WITH TILDE */ 2882 case 0xCD: *t++ = 0xC3; *t++ = 0x95; break; 2883 /* LATIN CAPITAL LETTER O WITH TILDE */ 2884 case 0xCE: *t++ = 0xC5; *t++ = 0x92; break; 2885 /* LATIN CAPITAL LIGATURE OE */ 2886 case 0xCF: *t++ = 0xC5; *t++ = 0x93; break; 2887 /* LATIN SMALL LIGATURE OE */ 2888 case 0xD0: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x93; break; 2889 /* EN DASH */ 2890 case 0xD1: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x94; break; 2891 /* EM DASH */ 2892 case 0xD2: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x9C; break; 2893 /* LEFT DOUBLE QUOTATION MARK */ 2894 case 0xD3: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x9D; break; 2895 /* RIGHT DOUBLE QUOTATION MARK */ 2896 case 0xD4: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x98; break; 2897 /* LEFT SINGLE QUOTATION MARK */ 2898 case 0xD5: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x99; break; 2899 /* RIGHT SINGLE QUOTATION MARK */ 2900 case 0xD6: *t++ = 0xC3; *t++ = 0xB7; break; 2901 /* DIVISION SIGN */ 2902 case 0xD7: *t++ = 0xE2; *t++ = 0x97; *t++ = 0x8A; break; 2903 /* LOZENGE */ 2904 case 0xD8: *t++ = 0xC3; *t++ = 0xBF; break; 2905 /* LATIN SMALL LETTER Y WITH DIAERESIS */ 2906 case 0xD9: *t++ = 0xC5; *t++ = 0xB8; break; 2907 /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ 2908 case 0xDA: *t++ = 0xE2; *t++ = 0x81; *t++ = 0x84; break; 2909 /* FRACTION SLASH */ 2910 case 0xDB: *t++ = 0xE2; *t++ = 0x82; *t++ = 0xAC; break; 2911 /* EURO SIGN */ 2912 case 0xDC: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xB9; break; 2913 /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ 2914 case 0xDD: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xBA; break; 2915 /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ 2916 case 0xDE: *t++ = 0xEF; *t++ = 0xAC; *t++ = 0x81; break; 2917 /* LATIN SMALL LIGATURE FI */ 2918 case 0xDF: *t++ = 0xEF; *t++ = 0xAC; *t++ = 0x82; break; 2919 /* LATIN SMALL LIGATURE FL */ 2920 case 0xE0: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xA1; break; 2921 /* DOUBLE DAGGER */ 2922 case 0xE1: *t++ = 0xC2; *t++ = 0xB7; break; 2923 /* MIDDLE DOT */ 2924 case 0xE2: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x9A; break; 2925 /* SINGLE LOW-9 QUOTATION MARK */ 2926 case 0xE3: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x9E; break; 2927 /* DOUBLE LOW-9 QUOTATION MARK */ 2928 case 0xE4: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xB0; break; 2929 /* PER MILLE SIGN */ 2930 case 0xE5: *t++ = 0xC3; *t++ = 0x82; break; 2931 /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ 2932 case 0xE6: *t++ = 0xC3; *t++ = 0x8A; break; 2933 /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ 2934 case 0xE7: *t++ = 0xC3; *t++ = 0x81; break; 2935 /* LATIN CAPITAL LETTER A WITH ACUTE */ 2936 case 0xE8: *t++ = 0xC3; *t++ = 0x8B; break; 2937 /* LATIN CAPITAL LETTER E WITH DIAERESIS */ 2938 case 0xE9: *t++ = 0xC3; *t++ = 0x88; break; 2939 /* LATIN CAPITAL LETTER E WITH GRAVE */ 2940 case 0xEA: *t++ = 0xC3; *t++ = 0x8D; break; 2941 /* LATIN CAPITAL LETTER I WITH ACUTE */ 2942 case 0xEB: *t++ = 0xC3; *t++ = 0x8E; break; 2943 /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ 2944 case 0xEC: *t++ = 0xC3; *t++ = 0x8F; break; 2945 /* LATIN CAPITAL LETTER I WITH DIAERESIS */ 2946 case 0xED: *t++ = 0xC3; *t++ = 0x8C; break; 2947 /* LATIN CAPITAL LETTER I WITH GRAVE */ 2948 case 0xEE: *t++ = 0xC3; *t++ = 0x93; break; 2949 /* LATIN CAPITAL LETTER O WITH ACUTE */ 2950 case 0xEF: *t++ = 0xC3; *t++ = 0x94; break; 2951 /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ 2952 case 0xF0: *t++ = 0xEF; *t++ = 0xA3; *t++ = 0xBF; break; 2953 /* Apple logo */ 2954 case 0xF1: *t++ = 0xC3; *t++ = 0x92; break; 2955 /* LATIN CAPITAL LETTER O WITH GRAVE */ 2956 case 0xF2: *t++ = 0xC3; *t++ = 0x9A; break; 2957 /* LATIN CAPITAL LETTER U WITH ACUTE */ 2958 case 0xF3: *t++ = 0xC3; *t++ = 0x9B; break; 2959 /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ 2960 case 0xF4: *t++ = 0xC3; *t++ = 0x99; break; 2961 /* LATIN CAPITAL LETTER U WITH GRAVE */ 2962 case 0xF5: *t++ = 0xC4; *t++ = 0xB1; break; 2963 /* LATIN SMALL LETTER DOTLESS I */ 2964 case 0xF6: *t++ = 0xCB; *t++ = 0x86; break; 2965 /* MODIFIER LETTER CIRCUMFLEX ACCENT */ 2966 case 0xF7: *t++ = 0xCB; *t++ = 0x9C; break; 2967 /* SMALL TILDE */ 2968 case 0xF8: *t++ = 0xC2; *t++ = 0xAF; break; 2969 /* MACRON */ 2970 case 0xF9: *t++ = 0xCB; *t++ = 0x98; break; 2971 /* BREVE */ 2972 case 0xFA: *t++ = 0xCB; *t++ = 0x99; break; 2973 /* DOT ABOVE */ 2974 case 0xFB: *t++ = 0xCB; *t++ = 0x9A; break; 2975 /* RING ABOVE */ 2976 case 0xFC: *t++ = 0xC2; *t++ = 0xB8; break; 2977 /* CEDILLA */ 2978 case 0xFD: *t++ = 0xCB; *t++ = 0x9D; break; 2979 /* DOUBLE ACUTE ACCENT */ 2980 case 0xFE: *t++ = 0xCB; *t++ = 0x9B; break; 2981 /* OGONEK */ 2982 case 0xFF: *t++ = 0xCB; *t++ = 0x87; break; 2983 /* CARON */ 2984 default: *t++ = '?'; break; 2985 /* shouldn't get here */ 2986 } 2987 } 2988 } 2989} 2990#endif 2991 2992#if IncludeHostTextClipExchange 2993GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i) 2994{ 2995 /* 2996 OSGLUxxx common: 2997 PBuf i is an array of Macintosh 2998 style characters. (using the 2999 MacRoman character set.) 3000 3001 Should export this Buffer to the 3002 native clipboard, performing character 3003 set translation, and eof character translation 3004 as needed. 3005 3006 return 0 if it succeeds, nonzero (a 3007 Macintosh style error code, but -1 3008 will do) on failure. 3009 */ 3010 tMacErr err; 3011 char *p; 3012 ui3p s = PbufDat[i]; 3013 uimr L = PbufSize[i]; 3014 uimr sz = MacRoman2UniCodeSize(s, L); 3015 3016 if (NULL == (p = malloc(sz + 1))) { 3017 err = mnvm_miscErr; 3018 } else { 3019 MacRoman2UniCodeData(s, L, p); 3020 p[sz] = 0; 3021 3022 if (0 != SDL_SetClipboardText(p)) { 3023 err = mnvm_miscErr; 3024 } else { 3025 err = mnvm_noErr; 3026 } 3027 free(p); 3028 } 3029 3030 return err; 3031} 3032#endif 3033 3034#if IncludeHostTextClipExchange 3035LOCALFUNC tMacErr UniCodeStrLength(char *s, uimr *r) 3036{ 3037 tMacErr err; 3038 ui3r t; 3039 ui3r t2; 3040 char *p = s; 3041 uimr L = 0; 3042 3043label_retry: 3044 if (0 == (t = *p++)) { 3045 err = mnvm_noErr; 3046 /* done */ 3047 } else 3048 if (0 == (0x80 & t)) { 3049 /* One-byte code */ 3050 L += 1; 3051 goto label_retry; 3052 } else 3053 if (0 == (0x40 & t)) { 3054 /* continuation code, error */ 3055 err = mnvm_miscErr; 3056 } else 3057 if (0 == (t2 = *p++)) { 3058 err = mnvm_miscErr; 3059 } else 3060 if (0x80 != (0xC0 & t2)) { 3061 /* not a continuation code, error */ 3062 err = mnvm_miscErr; 3063 } else 3064 if (0 == (0x20 & t)) { 3065 /* two bytes */ 3066 L += 2; 3067 goto label_retry; 3068 } else 3069 if (0 == (t2 = *p++)) { 3070 err = mnvm_miscErr; 3071 } else 3072 if (0x80 != (0xC0 & t2)) { 3073 /* not a continuation code, error */ 3074 err = mnvm_miscErr; 3075 } else 3076 if (0 == (0x10 & t)) { 3077 /* three bytes */ 3078 L += 3; 3079 goto label_retry; 3080 } else 3081 if (0 == (t2 = *p++)) { 3082 err = mnvm_miscErr; 3083 } else 3084 if (0x80 != (0xC0 & t2)) { 3085 /* not a continuation code, error */ 3086 err = mnvm_miscErr; 3087 } else 3088 if (0 == (0x08 & t)) { 3089 /* four bytes */ 3090 L += 5; 3091 goto label_retry; 3092 } else 3093 { 3094 err = mnvm_miscErr; 3095 /* longer code not supported yet */ 3096 } 3097 3098 *r = L; 3099 return err; 3100} 3101#endif 3102 3103#if IncludeHostTextClipExchange 3104LOCALFUNC ui3r UniCodePoint2MacRoman(ui5r x) 3105{ 3106/* 3107 adapted from 3108 http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT 3109*/ 3110 ui3r y; 3111 3112 if (x < 128) { 3113 y = x; 3114 } else { 3115 switch (x) { 3116 case 0x00C4: y = 0x80; break; 3117 /* LATIN CAPITAL LETTER A WITH DIAERESIS */ 3118 case 0x00C5: y = 0x81; break; 3119 /* LATIN CAPITAL LETTER A WITH RING ABOVE */ 3120 case 0x00C7: y = 0x82; break; 3121 /* LATIN CAPITAL LETTER C WITH CEDILLA */ 3122 case 0x00C9: y = 0x83; break; 3123 /* LATIN CAPITAL LETTER E WITH ACUTE */ 3124 case 0x00D1: y = 0x84; break; 3125 /* LATIN CAPITAL LETTER N WITH TILDE */ 3126 case 0x00D6: y = 0x85; break; 3127 /* LATIN CAPITAL LETTER O WITH DIAERESIS */ 3128 case 0x00DC: y = 0x86; break; 3129 /* LATIN CAPITAL LETTER U WITH DIAERESIS */ 3130 case 0x00E1: y = 0x87; break; 3131 /* LATIN SMALL LETTER A WITH ACUTE */ 3132 case 0x00E0: y = 0x88; break; 3133 /* LATIN SMALL LETTER A WITH GRAVE */ 3134 case 0x00E2: y = 0x89; break; 3135 /* LATIN SMALL LETTER A WITH CIRCUMFLEX */ 3136 case 0x00E4: y = 0x8A; break; 3137 /* LATIN SMALL LETTER A WITH DIAERESIS */ 3138 case 0x00E3: y = 0x8B; break; 3139 /* LATIN SMALL LETTER A WITH TILDE */ 3140 case 0x00E5: y = 0x8C; break; 3141 /* LATIN SMALL LETTER A WITH RING ABOVE */ 3142 case 0x00E7: y = 0x8D; break; 3143 /* LATIN SMALL LETTER C WITH CEDILLA */ 3144 case 0x00E9: y = 0x8E; break; 3145 /* LATIN SMALL LETTER E WITH ACUTE */ 3146 case 0x00E8: y = 0x8F; break; 3147 /* LATIN SMALL LETTER E WITH GRAVE */ 3148 case 0x00EA: y = 0x90; break; 3149 /* LATIN SMALL LETTER E WITH CIRCUMFLEX */ 3150 case 0x00EB: y = 0x91; break; 3151 /* LATIN SMALL LETTER E WITH DIAERESIS */ 3152 case 0x00ED: y = 0x92; break; 3153 /* LATIN SMALL LETTER I WITH ACUTE */ 3154 case 0x00EC: y = 0x93; break; 3155 /* LATIN SMALL LETTER I WITH GRAVE */ 3156 case 0x00EE: y = 0x94; break; 3157 /* LATIN SMALL LETTER I WITH CIRCUMFLEX */ 3158 case 0x00EF: y = 0x95; break; 3159 /* LATIN SMALL LETTER I WITH DIAERESIS */ 3160 case 0x00F1: y = 0x96; break; 3161 /* LATIN SMALL LETTER N WITH TILDE */ 3162 case 0x00F3: y = 0x97; break; 3163 /* LATIN SMALL LETTER O WITH ACUTE */ 3164 case 0x00F2: y = 0x98; break; 3165 /* LATIN SMALL LETTER O WITH GRAVE */ 3166 case 0x00F4: y = 0x99; break; 3167 /* LATIN SMALL LETTER O WITH CIRCUMFLEX */ 3168 case 0x00F6: y = 0x9A; break; 3169 /* LATIN SMALL LETTER O WITH DIAERESIS */ 3170 case 0x00F5: y = 0x9B; break; 3171 /* LATIN SMALL LETTER O WITH TILDE */ 3172 case 0x00FA: y = 0x9C; break; 3173 /* LATIN SMALL LETTER U WITH ACUTE */ 3174 case 0x00F9: y = 0x9D; break; 3175 /* LATIN SMALL LETTER U WITH GRAVE */ 3176 case 0x00FB: y = 0x9E; break; 3177 /* LATIN SMALL LETTER U WITH CIRCUMFLEX */ 3178 case 0x00FC: y = 0x9F; break; 3179 /* LATIN SMALL LETTER U WITH DIAERESIS */ 3180 case 0x2020: y = 0xA0; break; 3181 /* DAGGER */ 3182 case 0x00B0: y = 0xA1; break; 3183 /* DEGREE SIGN */ 3184 case 0x00A2: y = 0xA2; break; 3185 /* CENT SIGN */ 3186 case 0x00A3: y = 0xA3; break; 3187 /* POUND SIGN */ 3188 case 0x00A7: y = 0xA4; break; 3189 /* SECTION SIGN */ 3190 case 0x2022: y = 0xA5; break; 3191 /* BULLET */ 3192 case 0x00B6: y = 0xA6; break; 3193 /* PILCROW SIGN */ 3194 case 0x00DF: y = 0xA7; break; 3195 /* LATIN SMALL LETTER SHARP S */ 3196 case 0x00AE: y = 0xA8; break; 3197 /* REGISTERED SIGN */ 3198 case 0x00A9: y = 0xA9; break; 3199 /* COPYRIGHT SIGN */ 3200 case 0x2122: y = 0xAA; break; 3201 /* TRADE MARK SIGN */ 3202 case 0x00B4: y = 0xAB; break; 3203 /* ACUTE ACCENT */ 3204 case 0x00A8: y = 0xAC; break; 3205 /* DIAERESIS */ 3206 case 0x2260: y = 0xAD; break; 3207 /* NOT EQUAL TO */ 3208 case 0x00C6: y = 0xAE; break; 3209 /* LATIN CAPITAL LETTER AE */ 3210 case 0x00D8: y = 0xAF; break; 3211 /* LATIN CAPITAL LETTER O WITH STROKE */ 3212 case 0x221E: y = 0xB0; break; 3213 /* INFINITY */ 3214 case 0x00B1: y = 0xB1; break; 3215 /* PLUS-MINUS SIGN */ 3216 case 0x2264: y = 0xB2; break; 3217 /* LESS-THAN OR EQUAL TO */ 3218 case 0x2265: y = 0xB3; break; 3219 /* GREATER-THAN OR EQUAL TO */ 3220 case 0x00A5: y = 0xB4; break; 3221 /* YEN SIGN */ 3222 case 0x00B5: y = 0xB5; break; 3223 /* MICRO SIGN */ 3224 case 0x2202: y = 0xB6; break; 3225 /* PARTIAL DIFFERENTIAL */ 3226 case 0x2211: y = 0xB7; break; 3227 /* N-ARY SUMMATION */ 3228 case 0x220F: y = 0xB8; break; 3229 /* N-ARY PRODUCT */ 3230 case 0x03C0: y = 0xB9; break; 3231 /* GREEK SMALL LETTER PI */ 3232 case 0x222B: y = 0xBA; break; 3233 /* INTEGRAL */ 3234 case 0x00AA: y = 0xBB; break; 3235 /* FEMININE ORDINAL INDICATOR */ 3236 case 0x00BA: y = 0xBC; break; 3237 /* MASCULINE ORDINAL INDICATOR */ 3238 case 0x03A9: y = 0xBD; break; 3239 /* GREEK CAPITAL LETTER OMEGA */ 3240 case 0x00E6: y = 0xBE; break; 3241 /* LATIN SMALL LETTER AE */ 3242 case 0x00F8: y = 0xBF; break; 3243 /* LATIN SMALL LETTER O WITH STROKE */ 3244 case 0x00BF: y = 0xC0; break; 3245 /* INVERTED QUESTION MARK */ 3246 case 0x00A1: y = 0xC1; break; 3247 /* INVERTED EXCLAMATION MARK */ 3248 case 0x00AC: y = 0xC2; break; 3249 /* NOT SIGN */ 3250 case 0x221A: y = 0xC3; break; 3251 /* SQUARE ROOT */ 3252 case 0x0192: y = 0xC4; break; 3253 /* LATIN SMALL LETTER F WITH HOOK */ 3254 case 0x2248: y = 0xC5; break; 3255 /* ALMOST EQUAL TO */ 3256 case 0x2206: y = 0xC6; break; 3257 /* INCREMENT */ 3258 case 0x00AB: y = 0xC7; break; 3259 /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ 3260 case 0x00BB: y = 0xC8; break; 3261 /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ 3262 case 0x2026: y = 0xC9; break; 3263 /* HORIZONTAL ELLIPSIS */ 3264 case 0x00A0: y = 0xCA; break; 3265 /* NO-BREAK SPACE */ 3266 case 0x00C0: y = 0xCB; break; 3267 /* LATIN CAPITAL LETTER A WITH GRAVE */ 3268 case 0x00C3: y = 0xCC; break; 3269 /* LATIN CAPITAL LETTER A WITH TILDE */ 3270 case 0x00D5: y = 0xCD; break; 3271 /* LATIN CAPITAL LETTER O WITH TILDE */ 3272 case 0x0152: y = 0xCE; break; 3273 /* LATIN CAPITAL LIGATURE OE */ 3274 case 0x0153: y = 0xCF; break; 3275 /* LATIN SMALL LIGATURE OE */ 3276 case 0x2013: y = 0xD0; break; 3277 /* EN DASH */ 3278 case 0x2014: y = 0xD1; break; 3279 /* EM DASH */ 3280 case 0x201C: y = 0xD2; break; 3281 /* LEFT DOUBLE QUOTATION MARK */ 3282 case 0x201D: y = 0xD3; break; 3283 /* RIGHT DOUBLE QUOTATION MARK */ 3284 case 0x2018: y = 0xD4; break; 3285 /* LEFT SINGLE QUOTATION MARK */ 3286 case 0x2019: y = 0xD5; break; 3287 /* RIGHT SINGLE QUOTATION MARK */ 3288 case 0x00F7: y = 0xD6; break; 3289 /* DIVISION SIGN */ 3290 case 0x25CA: y = 0xD7; break; 3291 /* LOZENGE */ 3292 case 0x00FF: y = 0xD8; break; 3293 /* LATIN SMALL LETTER Y WITH DIAERESIS */ 3294 case 0x0178: y = 0xD9; break; 3295 /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ 3296 case 0x2044: y = 0xDA; break; 3297 /* FRACTION SLASH */ 3298 case 0x20AC: y = 0xDB; break; 3299 /* EURO SIGN */ 3300 case 0x2039: y = 0xDC; break; 3301 /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ 3302 case 0x203A: y = 0xDD; break; 3303 /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ 3304 case 0xFB01: y = 0xDE; break; 3305 /* LATIN SMALL LIGATURE FI */ 3306 case 0xFB02: y = 0xDF; break; 3307 /* LATIN SMALL LIGATURE FL */ 3308 case 0x2021: y = 0xE0; break; 3309 /* DOUBLE DAGGER */ 3310 case 0x00B7: y = 0xE1; break; 3311 /* MIDDLE DOT */ 3312 case 0x201A: y = 0xE2; break; 3313 /* SINGLE LOW-9 QUOTATION MARK */ 3314 case 0x201E: y = 0xE3; break; 3315 /* DOUBLE LOW-9 QUOTATION MARK */ 3316 case 0x2030: y = 0xE4; break; 3317 /* PER MILLE SIGN */ 3318 case 0x00C2: y = 0xE5; break; 3319 /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ 3320 case 0x00CA: y = 0xE6; break; 3321 /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ 3322 case 0x00C1: y = 0xE7; break; 3323 /* LATIN CAPITAL LETTER A WITH ACUTE */ 3324 case 0x00CB: y = 0xE8; break; 3325 /* LATIN CAPITAL LETTER E WITH DIAERESIS */ 3326 case 0x00C8: y = 0xE9; break; 3327 /* LATIN CAPITAL LETTER E WITH GRAVE */ 3328 case 0x00CD: y = 0xEA; break; 3329 /* LATIN CAPITAL LETTER I WITH ACUTE */ 3330 case 0x00CE: y = 0xEB; break; 3331 /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ 3332 case 0x00CF: y = 0xEC; break; 3333 /* LATIN CAPITAL LETTER I WITH DIAERESIS */ 3334 case 0x00CC: y = 0xED; break; 3335 /* LATIN CAPITAL LETTER I WITH GRAVE */ 3336 case 0x00D3: y = 0xEE; break; 3337 /* LATIN CAPITAL LETTER O WITH ACUTE */ 3338 case 0x00D4: y = 0xEF; break; 3339 /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ 3340 case 0xF8FF: y = 0xF0; break; 3341 /* Apple logo */ 3342 case 0x00D2: y = 0xF1; break; 3343 /* LATIN CAPITAL LETTER O WITH GRAVE */ 3344 case 0x00DA: y = 0xF2; break; 3345 /* LATIN CAPITAL LETTER U WITH ACUTE */ 3346 case 0x00DB: y = 0xF3; break; 3347 /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ 3348 case 0x00D9: y = 0xF4; break; 3349 /* LATIN CAPITAL LETTER U WITH GRAVE */ 3350 case 0x0131: y = 0xF5; break; 3351 /* LATIN SMALL LETTER DOTLESS I */ 3352 case 0x02C6: y = 0xF6; break; 3353 /* MODIFIER LETTER CIRCUMFLEX ACCENT */ 3354 case 0x02DC: y = 0xF7; break; 3355 /* SMALL TILDE */ 3356 case 0x00AF: y = 0xF8; break; 3357 /* MACRON */ 3358 case 0x02D8: y = 0xF9; break; 3359 /* BREVE */ 3360 case 0x02D9: y = 0xFA; break; 3361 /* DOT ABOVE */ 3362 case 0x02DA: y = 0xFB; break; 3363 /* RING ABOVE */ 3364 case 0x00B8: y = 0xFC; break; 3365 /* CEDILLA */ 3366 case 0x02DD: y = 0xFD; break; 3367 /* DOUBLE ACUTE ACCENT */ 3368 case 0x02DB: y = 0xFE; break; 3369 /* OGONEK */ 3370 case 0x02C7: y = 0xFF; break; 3371 /* CARON */ 3372 default: y = '?'; break; 3373 /* unrecognized */ 3374 } 3375 } 3376 3377 return y; 3378} 3379#endif 3380 3381#if IncludeHostTextClipExchange 3382LOCALPROC UniCodeStr2MacRoman(char *s, char *r) 3383{ 3384 tMacErr err; 3385 ui3r t; 3386 ui3r t2; 3387 ui3r t3; 3388 ui3r t4; 3389 ui5r v; 3390 char *p = s; 3391 char *q = r; 3392 3393label_retry: 3394 if (0 == (t = *p++)) { 3395 err = mnvm_noErr; 3396 /* done */ 3397 } else 3398 if (0 == (0x80 & t)) { 3399 *q++ = t; 3400 goto label_retry; 3401 } else 3402 if (0 == (0x40 & t)) { 3403 /* continuation code, error */ 3404 err = mnvm_miscErr; 3405 } else 3406 if (0 == (t2 = *p++)) { 3407 err = mnvm_miscErr; 3408 } else 3409 if (0x80 != (0xC0 & t2)) { 3410 /* not a continuation code, error */ 3411 err = mnvm_miscErr; 3412 } else 3413 if (0 == (0x20 & t)) { 3414 /* two bytes */ 3415 v = t & 0x1F; 3416 v = (v << 6) | (t2 & 0x3F); 3417 *q++ = UniCodePoint2MacRoman(v); 3418 goto label_retry; 3419 } else 3420 if (0 == (t3 = *p++)) { 3421 err = mnvm_miscErr; 3422 } else 3423 if (0x80 != (0xC0 & t3)) { 3424 /* not a continuation code, error */ 3425 err = mnvm_miscErr; 3426 } else 3427 if (0 == (0x10 & t)) { 3428 /* three bytes */ 3429 v = t & 0x0F; 3430 v = (v << 6) | (t3 & 0x3F); 3431 v = (v << 6) | (t2 & 0x3F); 3432 *q++ = UniCodePoint2MacRoman(v); 3433 goto label_retry; 3434 } else 3435 if (0 == (t4 = *p++)) { 3436 err = mnvm_miscErr; 3437 } else 3438 if (0x80 != (0xC0 & t4)) { 3439 /* not a continuation code, error */ 3440 err = mnvm_miscErr; 3441 } else 3442 if (0 == (0x08 & t)) { 3443 /* four bytes */ 3444 v = t & 0x07; 3445 v = (v << 6) | (t4 & 0x3F); 3446 v = (v << 6) | (t3 & 0x3F); 3447 v = (v << 6) | (t2 & 0x3F); 3448 *q++ = UniCodePoint2MacRoman(v); 3449 goto label_retry; 3450 } else 3451 { 3452 err = mnvm_miscErr; 3453 /* longer code not supported yet */ 3454 } 3455} 3456#endif 3457 3458#if IncludeHostTextClipExchange 3459GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r) 3460{ 3461 /* 3462 OSGLUxxx common: 3463 Import the native clipboard as text, 3464 and convert it to Macintosh format, 3465 in a Pbuf. 3466 3467 return 0 if it succeeds, nonzero (a 3468 Macintosh style error code, but -1 3469 will do) on failure. 3470 */ 3471 3472 tMacErr err; 3473 uimr L; 3474 char *s = NULL; 3475 tPbuf t = NotAPbuf; 3476 3477 if (NULL == (s = SDL_GetClipboardText())) { 3478 err = mnvm_miscErr; 3479 } else 3480 if (mnvm_noErr != (err = 3481 UniCodeStrLength(s, &L))) 3482 { 3483 /* fail */ 3484 } else 3485 if (mnvm_noErr != (err = 3486 PbufNew(L, &t))) 3487 { 3488 /* fail */ 3489 } else 3490 { 3491 err = mnvm_noErr; 3492 3493 UniCodeStr2MacRoman(s, PbufDat[t]); 3494 *r = t; 3495 t = NotAPbuf; 3496 } 3497 3498 if (NotAPbuf != t) { 3499 PbufDispose(t); 3500 } 3501 if (NULL != s) { 3502 SDL_free(s); 3503 } 3504 3505 return err; 3506} 3507#endif 3508 3509/* --- event handling for main window --- */ 3510 3511#define UseMotionEvents 1 3512 3513#if UseMotionEvents 3514LOCALVAR blnr CaughtMouse = falseblnr; 3515#endif 3516 3517#if 0 != SDL_MAJOR_VERSION 3518LOCALPROC HandleTheEvent(SDL_Event *event) 3519{ 3520 switch (event->type) { 3521 case SDL_QUIT: 3522 RequestMacOff = trueblnr; 3523 break; 3524#if 1 == SDL_MAJOR_VERSION 3525 case SDL_ACTIVEEVENT: 3526 switch (event->active.state) { 3527 case SDL_APPINPUTFOCUS: 3528 gTrueBackgroundFlag = (0 == event->active.gain); 3529#if 0 && UseMotionEvents 3530 if (! gTrueBackgroundFlag) { 3531 CheckMouseState(); 3532 } 3533#endif 3534 break; 3535 case SDL_APPMOUSEFOCUS: 3536 CaughtMouse = (0 != event->active.gain); 3537 break; 3538 } 3539 break; 3540#endif /* 1 == SDL_MAJOR_VERSION */ 3541#if 2 == SDL_MAJOR_VERSION 3542 case SDL_WINDOWEVENT: 3543 switch (event->window.event) { 3544 case SDL_WINDOWEVENT_FOCUS_GAINED: 3545 gTrueBackgroundFlag = 0; 3546 break; 3547 case SDL_WINDOWEVENT_FOCUS_LOST: 3548 gTrueBackgroundFlag = 1; 3549 break; 3550 case SDL_WINDOWEVENT_ENTER: 3551 CaughtMouse = 1; 3552 break; 3553 case SDL_WINDOWEVENT_LEAVE: 3554 CaughtMouse = 0; 3555 break; 3556 } 3557 break; 3558#endif /* 2 == SDL_MAJOR_VERSION */ 3559 case SDL_MOUSEMOTION: 3560#if EnableFSMouseMotion && ! HaveWorkingWarp 3561 if (HaveMouseMotion) { 3562 MousePositionNotifyRelative( 3563 event->motion.xrel, event->motion.yrel); 3564 } else 3565#endif 3566 { 3567 MousePositionNotify( 3568 event->motion.x, event->motion.y); 3569 } 3570 break; 3571 case SDL_MOUSEBUTTONDOWN: 3572 /* any mouse button, we don't care which */ 3573#if EnableFSMouseMotion && ! HaveWorkingWarp 3574 if (HaveMouseMotion) { 3575 /* ignore position */ 3576 } else 3577#endif 3578 { 3579 MousePositionNotify( 3580 event->button.x, event->button.y); 3581 } 3582 MyMouseButtonSet(trueblnr); 3583 break; 3584 case SDL_MOUSEBUTTONUP: 3585#if EnableFSMouseMotion && ! HaveWorkingWarp 3586 if (HaveMouseMotion) { 3587 /* ignore position */ 3588 } else 3589#endif 3590 { 3591 MousePositionNotify( 3592 event->button.x, event->button.y); 3593 } 3594 MyMouseButtonSet(falseblnr); 3595 break; 3596 case SDL_KEYDOWN: 3597 DoKeyCode(&event->key.keysym, trueblnr); 3598 break; 3599 case SDL_KEYUP: 3600 DoKeyCode(&event->key.keysym, falseblnr); 3601 break; 3602#if 2 == SDL_MAJOR_VERSION 3603 case SDL_MOUSEWHEEL: 3604 if (event->wheel.x < 0) { 3605 Keyboard_UpdateKeyMap2(MKC_Left, trueblnr); 3606 Keyboard_UpdateKeyMap2(MKC_Left, falseblnr); 3607 } else if (event->wheel.x > 0) { 3608 Keyboard_UpdateKeyMap2(MKC_Right, trueblnr); 3609 Keyboard_UpdateKeyMap2(MKC_Right, falseblnr); 3610 } 3611 if (event->wheel.y < 0) { 3612 Keyboard_UpdateKeyMap2(MKC_Down, trueblnr); 3613 Keyboard_UpdateKeyMap2(MKC_Down, falseblnr); 3614 } else if(event->wheel.y > 0) { 3615 Keyboard_UpdateKeyMap2(MKC_Up, trueblnr); 3616 Keyboard_UpdateKeyMap2(MKC_Up, falseblnr); 3617 } 3618 break; 3619 case SDL_DROPFILE: 3620 { 3621 char *s = event->drop.file; 3622 3623 (void) Sony_Insert1a(s, falseblnr); 3624 SDL_RaiseWindow(my_main_wind); 3625 SDL_free(s); 3626 } 3627 break; 3628#endif /* 2 == SDL_MAJOR_VERSION */ 3629#if 0 3630 case Expose: /* SDL doesn't have an expose event */ 3631 int x0 = event->expose.x; 3632 int y0 = event->expose.y; 3633 int x1 = x0 + event->expose.width; 3634 int y1 = y0 + event->expose.height; 3635 3636 if (x0 < 0) { 3637 x0 = 0; 3638 } 3639 if (x1 > vMacScreenWidth) { 3640 x1 = vMacScreenWidth; 3641 } 3642 if (y0 < 0) { 3643 y0 = 0; 3644 } 3645 if (y1 > vMacScreenHeight) { 3646 y1 = vMacScreenHeight; 3647 } 3648 if ((x0 < x1) && (y0 < y1)) { 3649 HaveChangedScreenBuff(y0, x0, y1, x1); 3650 } 3651 break; 3652#endif 3653 } 3654} 3655#endif 3656 3657/* --- main window creation and disposal --- */ 3658 3659LOCALVAR int my_argc; 3660LOCALVAR char **my_argv; 3661 3662LOCALFUNC blnr Screen_Init(void) 3663{ 3664 blnr v = falseblnr; 3665 3666#if dbglog_OSGInit 3667 dbglog_writeln("enter Screen_Init"); 3668#endif 3669 3670 InitKeyCodes(); 3671 3672#if 0 != SDL_MAJOR_VERSION 3673 if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) 3674 { 3675 fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); 3676 } else 3677#endif 3678 { 3679#if 1 == SDL_MAJOR_VERSION 3680 SDL_WM_SetCaption((NULL != n_arg) ? n_arg : kStrAppName, NULL); 3681#endif /* 1 == SDL_MAJOR_VERSION */ 3682 3683 v = trueblnr; 3684 } 3685 3686 return v; 3687} 3688 3689#if MayFullScreen 3690LOCALVAR blnr GrabMachine = falseblnr; 3691#endif 3692 3693#if MayFullScreen 3694LOCALPROC GrabTheMachine(void) 3695{ 3696#if GrabKeysFullScreen 3697#if 1 == SDL_MAJOR_VERSION 3698 (void) SDL_WM_GrabInput(SDL_GRAB_ON); 3699#elif 2 == SDL_MAJOR_VERSION 3700 SDL_SetWindowGrab(my_main_wind, SDL_TRUE); 3701#endif /* SDL_MAJOR_VERSION */ 3702#endif 3703 3704#if EnableFSMouseMotion 3705 3706#if HaveWorkingWarp 3707 /* 3708 if magnification changes, need to reset, 3709 even if HaveMouseMotion already true 3710 */ 3711 if (MyMoveMouse(ViewHStart + (ViewHSize / 2), 3712 ViewVStart + (ViewVSize / 2))) 3713 { 3714 SavedMouseH = ViewHStart + (ViewHSize / 2); 3715 SavedMouseV = ViewVStart + (ViewVSize / 2); 3716 HaveMouseMotion = trueblnr; 3717 } 3718#elif 2 == SDL_MAJOR_VERSION 3719 if (0 == SDL_SetRelativeMouseMode(SDL_ENABLE)) { 3720 HaveMouseMotion = trueblnr; 3721 } 3722#endif 3723 3724#endif /* EnableFSMouseMotion */ 3725} 3726#endif 3727 3728#if MayFullScreen 3729LOCALPROC UngrabMachine(void) 3730{ 3731#if EnableFSMouseMotion 3732 3733 if (HaveMouseMotion) { 3734#if HaveWorkingWarp 3735 (void) MyMoveMouse(CurMouseH, CurMouseV); 3736#elif 2 == SDL_MAJOR_VERSION 3737 SDL_SetRelativeMouseMode(SDL_DISABLE); 3738#endif 3739 3740 HaveMouseMotion = falseblnr; 3741 } 3742 3743#endif /* EnableFSMouseMotion */ 3744 3745#if GrabKeysFullScreen 3746#if 1 == SDL_MAJOR_VERSION 3747 (void) SDL_WM_GrabInput(SDL_GRAB_OFF); 3748#elif 2 == SDL_MAJOR_VERSION 3749 SDL_SetWindowGrab(my_main_wind, SDL_FALSE); 3750#endif 3751#endif 3752} 3753#endif 3754 3755#if EnableFSMouseMotion && HaveWorkingWarp 3756LOCALPROC MyMouseConstrain(void) 3757{ 3758 si4b shiftdh; 3759 si4b shiftdv; 3760 3761 if (SavedMouseH < ViewHStart + (ViewHSize / 4)) { 3762 shiftdh = ViewHSize / 2; 3763 } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) { 3764 shiftdh = - ViewHSize / 2; 3765 } else { 3766 shiftdh = 0; 3767 } 3768 if (SavedMouseV < ViewVStart + (ViewVSize / 4)) { 3769 shiftdv = ViewVSize / 2; 3770 } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) { 3771 shiftdv = - ViewVSize / 2; 3772 } else { 3773 shiftdv = 0; 3774 } 3775 if ((shiftdh != 0) || (shiftdv != 0)) { 3776 SavedMouseH += shiftdh; 3777 SavedMouseV += shiftdv; 3778 if (! MyMoveMouse(SavedMouseH, SavedMouseV)) { 3779 HaveMouseMotion = falseblnr; 3780 } 3781 } 3782} 3783#endif 3784 3785 3786#if 0 == SDL_MAJOR_VERSION 3787 3788LOCALFUNC blnr CreateMainWindow(void) 3789{ 3790#if dbglog_OSGInit 3791 dbglog_writeln("enter CreateMainWindow"); 3792#endif 3793 3794 return trueblnr; 3795} 3796 3797LOCALPROC CloseMainWindow(void) 3798{ 3799} 3800 3801#if EnableRecreateW 3802LOCALFUNC blnr ReCreateMainWindow(void) 3803{ 3804 ForceShowCursor(); /* hide/show cursor api is per window */ 3805 3806#if MayFullScreen 3807 if (GrabMachine) { 3808 GrabMachine = falseblnr; 3809 UngrabMachine(); 3810 } 3811#endif 3812 3813#if EnableMagnify 3814 UseMagnify = WantMagnify; 3815#endif 3816#if VarFullScreen 3817 UseFullScreen = WantFullScreen; 3818#endif 3819 3820 (void) CreateMainWindow(); 3821 3822 if (HaveCursorHidden) { 3823 (void) MyMoveMouse(CurMouseH, CurMouseV); 3824 } 3825 3826 return trueblnr; 3827} 3828#endif 3829 3830#elif 1 == SDL_MAJOR_VERSION 3831 3832LOCALFUNC blnr CreateMainWindow(void) 3833{ 3834 int NewWindowHeight = vMacScreenHeight; 3835 int NewWindowWidth = vMacScreenWidth; 3836 Uint32 flags = SDL_SWSURFACE; 3837 blnr v = falseblnr; 3838 3839#if EnableMagnify && 1 3840 if (UseMagnify) { 3841 NewWindowHeight *= MyWindowScale; 3842 NewWindowWidth *= MyWindowScale; 3843 } 3844#endif 3845 3846#if VarFullScreen 3847 if (UseFullScreen) 3848#endif 3849#if MayFullScreen 3850 { 3851 flags |= SDL_FULLSCREEN; 3852 } 3853#endif 3854 3855 ViewHStart = 0; 3856 ViewVStart = 0; 3857 ViewHSize = vMacScreenWidth; 3858 ViewVSize = vMacScreenHeight; 3859 3860 my_surface = SDL_SetVideoMode(NewWindowWidth, NewWindowHeight, 3861#if 0 != vMacScreenDepth 3862 32, 3863#else 3864 /* 32 */ /* 24 */ /* 16 */ 8, 3865#endif 3866 flags); 3867 if (NULL == my_surface) { 3868 fprintf(stderr, "SDL_SetVideoMode fails: %s\n", 3869 SDL_GetError()); 3870 } else { 3871#if 0 != vMacScreenDepth 3872 ColorModeWorks = trueblnr; 3873#endif 3874 v = trueblnr; 3875 } 3876 3877 return v; 3878} 3879 3880LOCALPROC CloseMainWindow(void) 3881{ 3882} 3883 3884#if EnableRecreateW 3885LOCALFUNC blnr ReCreateMainWindow(void) 3886{ 3887 ForceShowCursor(); /* hide/show cursor api is per window */ 3888 3889#if MayFullScreen 3890 if (GrabMachine) { 3891 GrabMachine = falseblnr; 3892 UngrabMachine(); 3893 } 3894#endif 3895 3896#if EnableMagnify 3897 UseMagnify = WantMagnify; 3898#endif 3899#if VarFullScreen 3900 UseFullScreen = WantFullScreen; 3901#endif 3902 3903 (void) CreateMainWindow(); 3904 3905 if (HaveCursorHidden) { 3906 (void) MyMoveMouse(CurMouseH, CurMouseV); 3907 } 3908 3909 return trueblnr; 3910} 3911#endif 3912 3913#elif 2 == SDL_MAJOR_VERSION 3914 3915enum { 3916 kMagStateNormal, 3917#if EnableMagnify 3918 kMagStateMagnifgy, 3919#endif 3920 kNumMagStates 3921}; 3922 3923#define kMagStateAuto kNumMagStates 3924 3925#if MayNotFullScreen 3926LOCALVAR int CurWinIndx; 3927LOCALVAR blnr HavePositionWins[kNumMagStates]; 3928LOCALVAR int WinPositionsX[kNumMagStates]; 3929LOCALVAR int WinPositionsY[kNumMagStates]; 3930#endif 3931 3932LOCALFUNC blnr CreateMainWindow(void) 3933{ 3934 /* 3935 OSGLUxxx common: 3936 Set up somewhere for us to draw the emulated screen and 3937 receive mouse input. i.e. usually a window, as is the case 3938 for this port. 3939 3940 The window should not be resizeable. 3941 3942 Should look at the current value of UseMagnify and 3943 UseFullScreen. 3944 */ 3945 3946 int NewWindowX; 3947 int NewWindowY; 3948 int NewWindowHeight = vMacScreenHeight; 3949 int NewWindowWidth = vMacScreenWidth; 3950 Uint32 flags = 0 /* SDL_WINDOW_HIDDEN */; 3951 blnr v = falseblnr; 3952 3953#if EnableMagnify && 1 3954 if (UseMagnify) { 3955 NewWindowHeight *= MyWindowScale; 3956 NewWindowWidth *= MyWindowScale; 3957 } 3958#endif 3959 3960#if VarFullScreen 3961 if (UseFullScreen) 3962#endif 3963#if MayFullScreen 3964 { 3965 /* 3966 We don't want physical screen mode to be changed in modern 3967 displays, so we pass this _DESKTOP flag. 3968 */ 3969 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; 3970 3971 NewWindowX = SDL_WINDOWPOS_UNDEFINED; 3972 NewWindowY = SDL_WINDOWPOS_UNDEFINED; 3973 } 3974#endif 3975#if VarFullScreen 3976 else 3977#endif 3978#if MayNotFullScreen 3979 { 3980 int WinIndx; 3981 3982#if EnableMagnify 3983 if (UseMagnify) { 3984 WinIndx = kMagStateMagnifgy; 3985 } else 3986#endif 3987 { 3988 WinIndx = kMagStateNormal; 3989 } 3990 3991 if (! HavePositionWins[WinIndx]) { 3992 NewWindowX = SDL_WINDOWPOS_CENTERED; 3993 NewWindowY = SDL_WINDOWPOS_CENTERED; 3994 } else { 3995 NewWindowX = WinPositionsX[WinIndx]; 3996 NewWindowY = WinPositionsY[WinIndx]; 3997 } 3998 3999 CurWinIndx = WinIndx; 4000 } 4001#endif 4002 4003#if 0 4004 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); 4005#endif 4006 4007 if (NULL == (my_main_wind = SDL_CreateWindow( 4008 (NULL != n_arg) ? n_arg : kStrAppName, 4009 NewWindowX, NewWindowY, 4010 NewWindowWidth, NewWindowHeight, 4011 flags))) 4012 { 4013 fprintf(stderr, "SDL_CreateWindow fails: %s\n", 4014 SDL_GetError()); 4015 } else 4016 if (NULL == (my_renderer = SDL_CreateRenderer( 4017 my_main_wind, -1, 4018 0 /* SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC */ 4019 /* 4020 SDL_RENDERER_ACCELERATED not needed 4021 "no flags gives priority to available 4022 SDL_RENDERER_ACCELERATED renderers" 4023 */ 4024 /* would rather not require vsync */ 4025 ))) 4026 { 4027 fprintf(stderr, "SDL_CreateRenderer fails: %s\n", 4028 SDL_GetError()); 4029 } else 4030 if (NULL == (my_texture = SDL_CreateTexture( 4031 my_renderer, 4032 SDL_PIXELFORMAT_ARGB8888, 4033 SDL_TEXTUREACCESS_STREAMING, 4034#if UseSDLscaling 4035 vMacScreenWidth, vMacScreenHeight 4036#else 4037 NewWindowWidth, NewWindowHeight 4038#endif 4039 ))) 4040 { 4041 fprintf(stderr, "SDL_CreateTexture fails: %s\n", 4042 SDL_GetError()); 4043 } else 4044 if (NULL == (my_format = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888))) 4045 { 4046 fprintf(stderr, "SDL_AllocFormat fails: %s\n", 4047 SDL_GetError()); 4048 } else 4049 { 4050 /* SDL_ShowWindow(my_main_wind); */ 4051 4052 SDL_RenderClear(my_renderer); 4053 4054#if 0 4055 SDL_DisplayMode info; 4056 4057 if (0 != SDL_GetCurrentDisplayMode(0, &info)) { 4058 fprintf(stderr, "SDL_GetCurrentDisplayMode fails: %s\n", 4059 SDL_GetError()); 4060 4061 return falseblnr; 4062 } 4063#endif 4064 4065#if VarFullScreen 4066 if (UseFullScreen) 4067#endif 4068#if MayFullScreen 4069 { 4070 int wr; 4071 int hr; 4072 4073 SDL_GL_GetDrawableSize(my_main_wind, &wr, &hr); 4074 4075 ViewHSize = wr; 4076 ViewVSize = hr; 4077#if EnableMagnify 4078 if (UseMagnify) { 4079 ViewHSize /= MyWindowScale; 4080 ViewVSize /= MyWindowScale; 4081 } 4082#endif 4083 if (ViewHSize >= vMacScreenWidth) { 4084 ViewHStart = 0; 4085 ViewHSize = vMacScreenWidth; 4086 } else { 4087 ViewHSize &= ~ 1; 4088 } 4089 if (ViewVSize >= vMacScreenHeight) { 4090 ViewVStart = 0; 4091 ViewVSize = vMacScreenHeight; 4092 } else { 4093 ViewVSize &= ~ 1; 4094 } 4095 4096 if (wr > NewWindowWidth) { 4097 hOffset = (wr - NewWindowWidth) / 2; 4098 } else { 4099 hOffset = 0; 4100 } 4101 if (hr > NewWindowHeight) { 4102 vOffset = (hr - NewWindowHeight) / 2; 4103 } else { 4104 vOffset = 0; 4105 } 4106 } 4107#endif 4108 4109#if 0 != vMacScreenDepth 4110 ColorModeWorks = trueblnr; 4111#endif 4112 4113 v = trueblnr; 4114 } 4115 4116 return v; 4117} 4118 4119LOCALPROC CloseMainWindow(void) 4120{ 4121 /* 4122 OSGLUxxx common: 4123 Dispose of anything set up by CreateMainWindow. 4124 */ 4125 4126 if (NULL != my_format) { 4127 SDL_FreeFormat(my_format); 4128 my_format = NULL; 4129 } 4130 4131 if (NULL != my_texture) { 4132 SDL_DestroyTexture(my_texture); 4133 my_texture = NULL; 4134 } 4135 4136 if (NULL != my_renderer) { 4137 SDL_DestroyRenderer(my_renderer); 4138 my_renderer = NULL; 4139 } 4140 4141 if (NULL != my_main_wind) { 4142 SDL_DestroyWindow(my_main_wind); 4143 my_main_wind = NULL; 4144 } 4145} 4146 4147#if EnableRecreateW 4148LOCALPROC ZapMyWState(void) 4149{ 4150 my_main_wind = NULL; 4151 my_renderer = NULL; 4152 my_texture = NULL; 4153 my_format = NULL; 4154} 4155#endif 4156 4157#if EnableRecreateW 4158struct MyWState { 4159#if MayFullScreen 4160 ui4r f_ViewHSize; 4161 ui4r f_ViewVSize; 4162 ui4r f_ViewHStart; 4163 ui4r f_ViewVStart; 4164 int f_hOffset; 4165 int f_vOffset; 4166#endif 4167#if VarFullScreen 4168 blnr f_UseFullScreen; 4169#endif 4170#if EnableMagnify 4171 blnr f_UseMagnify; 4172#endif 4173#if MayNotFullScreen 4174 int f_CurWinIndx; 4175#endif 4176 SDL_Window *f_my_main_wind; 4177 SDL_Renderer *f_my_renderer; 4178 SDL_Texture *f_my_texture; 4179 SDL_PixelFormat *f_my_format; 4180}; 4181typedef struct MyWState MyWState; 4182#endif 4183 4184#if EnableRecreateW 4185LOCALPROC GetMyWState(MyWState *r) 4186{ 4187#if MayFullScreen 4188 r->f_ViewHSize = ViewHSize; 4189 r->f_ViewVSize = ViewVSize; 4190 r->f_ViewHStart = ViewHStart; 4191 r->f_ViewVStart = ViewVStart; 4192 r->f_hOffset = hOffset; 4193 r->f_vOffset = vOffset; 4194#endif 4195#if VarFullScreen 4196 r->f_UseFullScreen = UseFullScreen; 4197#endif 4198#if EnableMagnify 4199 r->f_UseMagnify = UseMagnify; 4200#endif 4201#if MayNotFullScreen 4202 r->f_CurWinIndx = CurWinIndx; 4203#endif 4204 r->f_my_main_wind = my_main_wind; 4205 r->f_my_renderer = my_renderer; 4206 r->f_my_texture = my_texture; 4207 r->f_my_format = my_format; 4208} 4209#endif 4210 4211#if EnableRecreateW 4212LOCALPROC SetMyWState(MyWState *r) 4213{ 4214#if MayFullScreen 4215 ViewHSize = r->f_ViewHSize; 4216 ViewVSize = r->f_ViewVSize; 4217 ViewHStart = r->f_ViewHStart; 4218 ViewVStart = r->f_ViewVStart; 4219 hOffset = r->f_hOffset; 4220 vOffset = r->f_vOffset; 4221#endif 4222#if VarFullScreen 4223 UseFullScreen = r->f_UseFullScreen; 4224#endif 4225#if EnableMagnify 4226 UseMagnify = r->f_UseMagnify; 4227#endif 4228#if MayNotFullScreen 4229 CurWinIndx = r->f_CurWinIndx; 4230#endif 4231 my_main_wind = r->f_my_main_wind; 4232 my_renderer = r->f_my_renderer; 4233 my_texture = r->f_my_texture; 4234 my_format = r->f_my_format; 4235} 4236#endif 4237 4238#if VarFullScreen && EnableMagnify 4239enum { 4240 kWinStateWindowed, 4241#if EnableMagnify 4242 kWinStateFullScreen, 4243#endif 4244 kNumWinStates 4245}; 4246#endif 4247 4248#if VarFullScreen && EnableMagnify 4249LOCALVAR int WinMagStates[kNumWinStates]; 4250#endif 4251 4252#if EnableRecreateW 4253LOCALFUNC blnr ReCreateMainWindow(void) 4254{ 4255 /* 4256 OSGLUxxx common: 4257 Like CreateMainWindow (which it calls), except may be 4258 called when already have window, without CloseMainWindow 4259 being called first. (Usually with different 4260 values of WantMagnify and WantFullScreen than 4261 on the previous call.) 4262 4263 If there is existing window, and fail to create 4264 the new one, then existing window must be left alone, 4265 in valid state. (and return falseblnr. otherwise, 4266 if succeed, return trueblnr) 4267 4268 i.e. can allocate the new one before disposing 4269 of the old one. 4270 */ 4271 4272 MyWState old_state; 4273 MyWState new_state; 4274#if HaveWorkingWarp 4275 blnr HadCursorHidden = HaveCursorHidden; 4276#endif 4277#if VarFullScreen && EnableMagnify 4278 int OldWinState = 4279 UseFullScreen ? kWinStateFullScreen : kWinStateWindowed; 4280 int OldMagState = 4281 UseMagnify ? kMagStateMagnifgy : kMagStateNormal; 4282 4283 WinMagStates[OldWinState] = 4284 OldMagState; 4285#endif 4286 4287#if VarFullScreen 4288 if (! UseFullScreen) 4289#endif 4290#if MayNotFullScreen 4291 { 4292 SDL_GetWindowPosition(my_main_wind, 4293 &WinPositionsX[CurWinIndx], 4294 &WinPositionsY[CurWinIndx]); 4295 HavePositionWins[CurWinIndx] = trueblnr; 4296 } 4297#endif 4298 4299 ForceShowCursor(); /* hide/show cursor api is per window */ 4300 4301#if MayFullScreen 4302 if (GrabMachine) { 4303 GrabMachine = falseblnr; 4304 UngrabMachine(); 4305 } 4306#endif 4307 4308 GetMyWState(&old_state); 4309 4310 ZapMyWState(); 4311 4312#if EnableMagnify 4313 UseMagnify = WantMagnify; 4314#endif 4315#if VarFullScreen 4316 UseFullScreen = WantFullScreen; 4317#endif 4318 4319 if (! CreateMainWindow()) { 4320 CloseMainWindow(); 4321 SetMyWState(&old_state); 4322 4323 /* avoid retry */ 4324#if VarFullScreen 4325 WantFullScreen = UseFullScreen; 4326#endif 4327#if EnableMagnify 4328 WantMagnify = UseMagnify; 4329#endif 4330 4331 } else { 4332 GetMyWState(&new_state); 4333 SetMyWState(&old_state); 4334 CloseMainWindow(); 4335 SetMyWState(&new_state); 4336 4337#if HaveWorkingWarp 4338 if (HadCursorHidden) { 4339 (void) MyMoveMouse(CurMouseH, CurMouseV); 4340 } 4341#endif 4342 } 4343 4344 return trueblnr; 4345} 4346#endif 4347 4348#endif /* SDL_MAJOR_VERSION */ 4349 4350 4351LOCALPROC ZapWinStateVars(void) 4352{ 4353#if 2 == SDL_MAJOR_VERSION 4354#if MayNotFullScreen 4355 { 4356 int i; 4357 4358 for (i = 0; i < kNumMagStates; ++i) { 4359 HavePositionWins[i] = falseblnr; 4360 } 4361 } 4362#endif 4363#if VarFullScreen && EnableMagnify 4364 { 4365 int i; 4366 4367 for (i = 0; i < kNumWinStates; ++i) { 4368 WinMagStates[i] = kMagStateAuto; 4369 } 4370 } 4371#endif 4372#endif /* 2 == SDL_MAJOR_VERSION */ 4373} 4374 4375#if VarFullScreen 4376LOCALPROC ToggleWantFullScreen(void) 4377{ 4378 WantFullScreen = ! WantFullScreen; 4379 4380#if EnableMagnify && (2 == SDL_MAJOR_VERSION) 4381 { 4382 int OldWinState = 4383 UseFullScreen ? kWinStateFullScreen : kWinStateWindowed; 4384 int OldMagState = 4385 UseMagnify ? kMagStateMagnifgy : kMagStateNormal; 4386 int NewWinState = 4387 WantFullScreen ? kWinStateFullScreen : kWinStateWindowed; 4388 int NewMagState = WinMagStates[NewWinState]; 4389 4390 WinMagStates[OldWinState] = OldMagState; 4391 if (kMagStateAuto != NewMagState) { 4392 WantMagnify = (kMagStateMagnifgy == NewMagState); 4393 } else { 4394 WantMagnify = falseblnr; 4395 if (WantFullScreen) { 4396 SDL_Rect r; 4397 4398 if (0 == SDL_GetDisplayBounds(0, &r)) { 4399 if ((r.w >= vMacScreenWidth * MyWindowScale) 4400 && (r.h >= vMacScreenHeight * MyWindowScale) 4401 ) 4402 { 4403 WantMagnify = trueblnr; 4404 } 4405 } 4406 } 4407 } 4408 } 4409#endif 4410} 4411#endif 4412 4413/* --- SavedTasks --- */ 4414 4415LOCALPROC LeaveBackground(void) 4416{ 4417 ReconnectKeyCodes3(); 4418 DisableKeyRepeat(); 4419} 4420 4421LOCALPROC EnterBackground(void) 4422{ 4423 RestoreKeyRepeat(); 4424 DisconnectKeyCodes3(); 4425 4426 ForceShowCursor(); 4427} 4428 4429LOCALPROC LeaveSpeedStopped(void) 4430{ 4431#if MySoundEnabled 4432 MySound_Start(); 4433#endif 4434 4435 StartUpTimeAdjust(); 4436} 4437 4438LOCALPROC EnterSpeedStopped(void) 4439{ 4440#if MySoundEnabled 4441 MySound_Stop(); 4442#endif 4443} 4444 4445LOCALPROC CheckForSavedTasks(void) 4446{ 4447 if (MyEvtQNeedRecover) { 4448 MyEvtQNeedRecover = falseblnr; 4449 4450 /* attempt cleanup, MyEvtQNeedRecover may get set again */ 4451 MyEvtQTryRecoverFromFull(); 4452 } 4453 4454#if EnableFSMouseMotion && HaveWorkingWarp 4455 if (HaveMouseMotion) { 4456 MyMouseConstrain(); 4457 } 4458#endif 4459 4460 if (RequestMacOff) { 4461 RequestMacOff = falseblnr; 4462 if (AnyDiskInserted()) { 4463 MacMsgOverride(kStrQuitWarningTitle, 4464 kStrQuitWarningMessage); 4465 } else { 4466 ForceMacOff = trueblnr; 4467 } 4468 } 4469 4470 if (ForceMacOff) { 4471 return; 4472 } 4473 4474 if (gTrueBackgroundFlag != gBackgroundFlag) { 4475 gBackgroundFlag = gTrueBackgroundFlag; 4476 if (gTrueBackgroundFlag) { 4477 EnterBackground(); 4478 } else { 4479 LeaveBackground(); 4480 } 4481 } 4482 4483 if (CurSpeedStopped != (SpeedStopped || 4484 (gBackgroundFlag && ! RunInBackground 4485#if EnableAutoSlow && 0 4486 && (QuietSubTicks >= 4092) 4487#endif 4488 ))) 4489 { 4490 CurSpeedStopped = ! CurSpeedStopped; 4491 if (CurSpeedStopped) { 4492 EnterSpeedStopped(); 4493 } else { 4494 LeaveSpeedStopped(); 4495 } 4496 } 4497 4498 if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) { 4499 MacMsgDisplayOn(); 4500 } 4501 4502#if EnableRecreateW 4503 if (0 4504#if EnableMagnify 4505 || (UseMagnify != WantMagnify) 4506#endif 4507#if VarFullScreen 4508 || (UseFullScreen != WantFullScreen) 4509#endif 4510 ) 4511 { 4512 (void) ReCreateMainWindow(); 4513 } 4514#endif 4515 4516#if MayFullScreen 4517 if (GrabMachine != ( 4518#if VarFullScreen 4519 UseFullScreen && 4520#endif 4521 ! (gTrueBackgroundFlag || CurSpeedStopped))) 4522 { 4523 GrabMachine = ! GrabMachine; 4524 if (GrabMachine) { 4525 GrabTheMachine(); 4526 } else { 4527 UngrabMachine(); 4528 } 4529 } 4530#endif 4531 4532 if (NeedWholeScreenDraw) { 4533 NeedWholeScreenDraw = falseblnr; 4534 ScreenChangedAll(); 4535 } 4536 4537#if NeedRequestIthDisk 4538 if (0 != RequestIthDisk) { 4539 Sony_InsertIth(RequestIthDisk); 4540 RequestIthDisk = 0; 4541 } 4542#endif 4543 4544 if (HaveCursorHidden != (WantCursorHidden 4545 && ! (gTrueBackgroundFlag || CurSpeedStopped))) 4546 { 4547 HaveCursorHidden = ! HaveCursorHidden; 4548#if 0 != SDL_MAJOR_VERSION 4549 (void) SDL_ShowCursor( 4550 HaveCursorHidden ? SDL_DISABLE : SDL_ENABLE); 4551#endif 4552 } 4553} 4554 4555/* --- command line parsing --- */ 4556 4557LOCALFUNC blnr ScanCommandLine(void) 4558{ 4559 char *pa; 4560 int i = 1; 4561 4562#if dbglog_OSGInit 4563 dbglog_writeln("enter ScanCommandLine"); /*^*/ 4564#endif 4565 4566label_retry: 4567 if (i < my_argc) { 4568 pa = my_argv[i++]; 4569 if ('-' == pa[0]) { 4570 if ((0 == strcmp(pa, "--rom")) 4571 || (0 == strcmp(pa, "-r"))) 4572 { 4573 if (i < my_argc) { 4574 rom_path = my_argv[i++]; 4575 goto label_retry; 4576 } 4577 } else 4578 if (0 == strcmp(pa, "-n")) 4579 { 4580 if (i < my_argc) { 4581 n_arg = my_argv[i++]; 4582 goto label_retry; 4583 } 4584 } else 4585 if (0 == strcmp(pa, "-d")) 4586 { 4587 if (i < my_argc) { 4588 d_arg = my_argv[i++]; 4589 goto label_retry; 4590 } 4591 } else 4592 if (('p' == pa[1]) && ('s' == pa[2]) && ('n' == pa[3])) 4593 { 4594 /* seen in OS X. ignore */ 4595 goto label_retry; 4596 } else 4597 { 4598 MacMsg(kStrBadArgTitle, kStrBadArgMessage, falseblnr); 4599#if dbglog_HAVE 4600 dbglog_writeln("bad command line argument"); 4601 dbglog_writeln(pa); 4602#endif 4603 } 4604 } else { 4605 (void) Sony_Insert1(pa, falseblnr); 4606 goto label_retry; 4607 } 4608 } 4609 4610 return trueblnr; 4611} 4612 4613/* --- main program flow --- */ 4614 4615LOCALPROC WaitForTheNextEvent(void) 4616{ 4617#if 0 != SDL_MAJOR_VERSION 4618 SDL_Event event; 4619 4620 if (SDL_WaitEvent(&event)) { 4621 HandleTheEvent(&event); 4622 } 4623#endif 4624} 4625 4626LOCALPROC CheckForSystemEvents(void) 4627{ 4628 /* 4629 OSGLUxxx common: 4630 Handle any events that are waiting for us. 4631 Return immediately when no more events 4632 are waiting, don't wait for more. 4633 */ 4634 4635#if 0 != SDL_MAJOR_VERSION 4636 SDL_Event event; 4637 int i = 10; 4638 4639 while ((--i >= 0) && SDL_PollEvent(&event)) { 4640 HandleTheEvent(&event); 4641 } 4642#endif 4643} 4644 4645/* 4646 OSGLUxxx common: 4647 In general, attempt to emulate one Macintosh tick (1/60.14742 4648 seconds) for every tick of real time. When done emulating 4649 one tick, wait for one tick of real time to elapse, by 4650 calling WaitForNextTick. 4651 4652 But, Mini vMac can run the emulation at greater than 1x speed, up to 4653 and including running as fast as possible, by emulating extra cycles 4654 at the end of the emulated tick. In this case, the extra emulation 4655 should continue only as long as the current real time tick is not 4656 over - until ExtraTimeNotOver returns false. 4657*/ 4658 4659GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void) 4660{ 4661 UpdateTrueEmulatedTime(); 4662 return TrueEmulatedTime == OnTrueTime; 4663} 4664 4665GLOBALOSGLUPROC WaitForNextTick(void) 4666{ 4667label_retry: 4668 CheckForSystemEvents(); 4669 CheckForSavedTasks(); 4670 4671 if (ForceMacOff) { 4672 return; 4673 } 4674 4675 if (CurSpeedStopped) { 4676 DoneWithDrawingForTick(); 4677 WaitForTheNextEvent(); 4678 goto label_retry; 4679 } 4680 4681#if ! HaveWorkingTime 4682 ++TrueEmulatedTime; 4683#endif 4684 4685 if (ExtraTimeNotOver()) { 4686#if 0 != SDL_MAJOR_VERSION 4687 (void) SDL_Delay(NextIntTime - LastTime); 4688#endif 4689 goto label_retry; 4690 } 4691 4692 if (CheckDateTime()) { 4693#if MySoundEnabled 4694 MySound_SecondNotify(); 4695#endif 4696#if EnableDemoMsg 4697 DemoModeSecondNotify(); 4698#endif 4699 } 4700 4701 if ((! gBackgroundFlag) 4702#if UseMotionEvents 4703 && (! CaughtMouse) 4704#endif 4705 ) 4706 { 4707 CheckMouseState(); 4708 } 4709 4710 OnTrueTime = TrueEmulatedTime; 4711 4712#if dbglog_TimeStuff 4713 dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime); 4714#endif 4715} 4716 4717/* --- platform independent code can be thought of as going here --- */ 4718 4719#include "PROGMAIN.h" 4720 4721LOCALPROC ZapOSGLUVars(void) 4722{ 4723 /* 4724 OSGLUxxx common: 4725 Set initial values of variables for 4726 platform dependent code, where not 4727 done using c initializers. (such 4728 as for arrays.) 4729 */ 4730 4731 InitDrives(); 4732 ZapWinStateVars(); 4733} 4734 4735LOCALPROC ReserveAllocAll(void) 4736{ 4737#if dbglog_HAVE 4738 dbglog_ReserveAlloc(); 4739#endif 4740 ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr); 4741 4742 ReserveAllocOneBlock(&screencomparebuff, 4743 vMacScreenNumBytes, 5, trueblnr); 4744#if UseControlKeys 4745 ReserveAllocOneBlock(&CntrlDisplayBuff, 4746 vMacScreenNumBytes, 5, falseblnr); 4747#endif 4748 4749 ReserveAllocOneBlock(&CLUT_final, CLUT_finalsz, 5, falseblnr); 4750#if MySoundEnabled 4751 ReserveAllocOneBlock((ui3p *)&TheSoundBuffer, 4752 dbhBufferSize, 5, falseblnr); 4753#endif 4754 4755 EmulationReserveAlloc(); 4756} 4757 4758LOCALFUNC blnr AllocMyMemory(void) 4759{ 4760 uimr n; 4761 blnr IsOk = falseblnr; 4762 4763 ReserveAllocOffset = 0; 4764 ReserveAllocBigBlock = nullpr; 4765 ReserveAllocAll(); 4766 n = ReserveAllocOffset; 4767 ReserveAllocBigBlock = (ui3p)calloc(1, n); 4768 if (NULL == ReserveAllocBigBlock) { 4769 MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr); 4770 } else { 4771 ReserveAllocOffset = 0; 4772 ReserveAllocAll(); 4773 if (n != ReserveAllocOffset) { 4774 /* oops, program error */ 4775 } else { 4776 IsOk = trueblnr; 4777 } 4778 } 4779 4780 return IsOk; 4781} 4782 4783LOCALPROC UnallocMyMemory(void) 4784{ 4785 if (nullpr != ReserveAllocBigBlock) { 4786 free((char *)ReserveAllocBigBlock); 4787 } 4788} 4789 4790#if CanGetAppPath 4791LOCALFUNC blnr InitWhereAmI(void) 4792{ 4793 app_parent = SDL_GetBasePath(); 4794 4795 pref_dir = SDL_GetPrefPath("gryphel", "minivmac"); 4796 4797 return trueblnr; /* keep going regardless */ 4798} 4799#endif 4800 4801#if CanGetAppPath 4802LOCALPROC UninitWhereAmI(void) 4803{ 4804 SDL_free(pref_dir); 4805 4806 SDL_free(app_parent); 4807} 4808#endif 4809 4810LOCALFUNC blnr InitOSGLU(void) 4811{ 4812 /* 4813 OSGLUxxx common: 4814 Run all the initializations needed for the program. 4815 */ 4816 4817 if (AllocMyMemory()) 4818#if CanGetAppPath 4819 if (InitWhereAmI()) 4820#endif 4821#if dbglog_HAVE 4822 if (dbglog_open()) 4823#endif 4824 if (ScanCommandLine()) 4825 if (LoadMacRom()) 4826 if (LoadInitialImages()) 4827 if (InitLocationDat()) 4828#if MySoundEnabled 4829 if (MySound_Init()) 4830#endif 4831 if (Screen_Init()) 4832 if (CreateMainWindow()) 4833 if (WaitForRom()) 4834 { 4835 return trueblnr; 4836 } 4837 return falseblnr; 4838} 4839 4840LOCALPROC UnInitOSGLU(void) 4841{ 4842 /* 4843 OSGLUxxx common: 4844 Do all clean ups needed before the program quits. 4845 */ 4846 4847 if (MacMsgDisplayed) { 4848 MacMsgDisplayOff(); 4849 } 4850 4851 RestoreKeyRepeat(); 4852#if MayFullScreen 4853 UngrabMachine(); 4854#endif 4855#if MySoundEnabled 4856 MySound_Stop(); 4857#endif 4858#if MySoundEnabled 4859 MySound_UnInit(); 4860#endif 4861#if IncludePbufs 4862 UnInitPbufs(); 4863#endif 4864 UnInitDrives(); 4865 4866 ForceShowCursor(); 4867 4868#if dbglog_HAVE 4869 dbglog_close(); 4870#endif 4871 4872#if CanGetAppPath 4873 UninitWhereAmI(); 4874#endif 4875 UnallocMyMemory(); 4876 4877 CheckSavedMacMsg(); 4878 4879 CloseMainWindow(); 4880 4881#if 0 != SDL_MAJOR_VERSION 4882 SDL_Quit(); 4883#endif 4884} 4885 4886int main(int argc, char **argv) 4887{ 4888 my_argc = argc; 4889 my_argv = argv; 4890 4891 ZapOSGLUVars(); 4892 if (InitOSGLU()) { 4893 ProgramMain(); 4894 } 4895 UnInitOSGLU(); 4896 4897 return 0; 4898} 4899 4900#endif /* WantOSGLUSDL */