this repo has no description
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 */