mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-24 11:30:52 +00:00
Merge remote-tracking branch 'zydeco/rootless' into zydeco_rootless
This commit is contained in:
commit
2f66b83bae
@ -245,7 +245,8 @@ static void Blit_Copy_Raw(uint8 * dest, const uint8 * source, uint32 length)
|
||||
(dst = (((src) >> 24) & UVAL64(0x000000ff000000ff)) | \
|
||||
(((src) >> 8) & UVAL64(0x0000ff000000ff00)) | \
|
||||
(((src) & UVAL64(0x0000ff000000ff00)) << 8) | \
|
||||
(((src) & UVAL64(0x000000ff000000ff)) << 24))
|
||||
(((src) & UVAL64(0x000000ff000000ff)) << 24) | \
|
||||
(UVAL64(0xff000000ff000000)))
|
||||
|
||||
#define FB_DEPTH 24
|
||||
#include "video_blit.h"
|
||||
|
@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
28EFB21E2364DB4F00988A5B /* video_rootless.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28EFB21C2364DB4F00988A5B /* video_rootless.cpp */; };
|
||||
28EFB222236CE16F00988A5B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28EFB221236CE16F00988A5B /* QuartzCore.framework */; };
|
||||
752F26F91F240E51001032B4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 752F26F81F240E51001032B4 /* Foundation.framework */; };
|
||||
752F26FB1F240E69001032B4 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 752F26FA1F240E69001032B4 /* IOKit.framework */; };
|
||||
752F27011F242BAF001032B4 /* prefs_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 752F27001F242BAF001032B4 /* prefs_sdl.cpp */; };
|
||||
@ -165,6 +167,8 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
28EFB21C2364DB4F00988A5B /* video_rootless.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = video_rootless.cpp; sourceTree = "<group>"; };
|
||||
28EFB221236CE16F00988A5B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
752F26F81F240E51001032B4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
752F26FA1F240E69001032B4 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
752F27001F242BAF001032B4 /* prefs_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prefs_sdl.cpp; sourceTree = "<group>"; };
|
||||
@ -399,6 +403,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
28EFB222236CE16F00988A5B /* QuartzCore.framework in Frameworks */,
|
||||
E413D93620D260DA00E437D8 /* SDL2.framework in Frameworks */,
|
||||
756C1B391F25306A00620917 /* AppKit.framework in Frameworks */,
|
||||
752F26FB1F240E69001032B4 /* IOKit.framework in Frameworks */,
|
||||
@ -461,6 +466,7 @@
|
||||
752F26F71F240E51001032B4 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
28EFB221236CE16F00988A5B /* QuartzCore.framework */,
|
||||
E413D93520D260DA00E437D8 /* SDL2.framework */,
|
||||
756C1B381F25306A00620917 /* AppKit.framework */,
|
||||
752F26FA1F240E69001032B4 /* IOKit.framework */,
|
||||
@ -607,6 +613,7 @@
|
||||
75CBCF761F5DB65E00830063 /* video_sdl.cpp */,
|
||||
75CBCF741F5DB3AD00830063 /* video_sdl2.cpp */,
|
||||
752F27021F242F51001032B4 /* xpram_sdl.cpp */,
|
||||
28EFB21C2364DB4F00988A5B /* video_rootless.cpp */,
|
||||
);
|
||||
name = SDL;
|
||||
path = ../SDL;
|
||||
@ -1016,6 +1023,7 @@
|
||||
752F27011F242BAF001032B4 /* prefs_sdl.cpp in Sources */,
|
||||
7539E2971F23C5FD006B2DF2 /* newcpu.cpp in Sources */,
|
||||
7539E12A1F23B25A006B2DF2 /* vm_alloc.cpp in Sources */,
|
||||
28EFB21E2364DB4F00988A5B /* video_rootless.cpp in Sources */,
|
||||
E413D93220D260BC00E437D8 /* if.c in Sources */,
|
||||
753253331F5368370024025B /* cpustbl_nf.cpp in Sources */,
|
||||
7539E16C1F23B25A006B2DF2 /* main.cpp in Sources */,
|
||||
|
@ -816,5 +816,6 @@
|
||||
/* #undef uintmax_t */
|
||||
|
||||
#define FPU_IEEE
|
||||
#define VIDEO_ROOTLESS
|
||||
|
||||
#endif
|
||||
|
@ -19,9 +19,12 @@
|
||||
*/
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
#include <objc/runtime.h>
|
||||
#include "sysdeps.h"
|
||||
#include "utils_macosx.h"
|
||||
#include <SDL.h>
|
||||
#include <vector>
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
#include <SDL_syswm.h>
|
||||
@ -52,6 +55,79 @@ void disable_SDL2_macosx_menu_bar_keyboard_shortcuts() {
|
||||
}
|
||||
}
|
||||
|
||||
void make_window_transparent(SDL_Window * window)
|
||||
{
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
extern int native_menubar_size;
|
||||
native_menubar_size = (int)[[NSApp mainMenu] menuBarHeight];
|
||||
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
if (!SDL_GetWindowWMInfo(window, &wmInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGColorRef clearColor = [NSColor clearColor].CGColor;
|
||||
NSWindow *cocoaWindow = wmInfo.info.cocoa.window;
|
||||
NSView *sdlView = cocoaWindow.contentView;
|
||||
sdlView.layer.backgroundColor = [NSColor clearColor].CGColor;
|
||||
if (SDL_GetWindowData(window, "observing") == NULL) {
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserverForName:NSWindowDidBecomeKeyNotification object:cocoaWindow queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
|
||||
NSWindow *window = (NSWindow*)note.object;
|
||||
window.level = NSMainMenuWindowLevel+1;
|
||||
}];
|
||||
[nc addObserverForName:NSWindowDidResignKeyNotification object:cocoaWindow queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
|
||||
NSWindow *window = (NSWindow*)note.object;
|
||||
// hack for window to be sent behind new key window
|
||||
[window setIsVisible:NO];
|
||||
[window setLevel:NSNormalWindowLevel];
|
||||
[window setIsVisible:YES];
|
||||
}];
|
||||
SDL_SetWindowData(window, "observing", nc);
|
||||
}
|
||||
if (SDL_GetWindowData(window, "maskLayer") == NULL) {
|
||||
CALayer *maskLayer = [CAShapeLayer layer];
|
||||
sdlView.layer.mask = maskLayer;
|
||||
SDL_SetWindowData(window, "maskLayer", maskLayer);
|
||||
}
|
||||
cocoaWindow.backgroundColor = [NSColor clearColor];
|
||||
cocoaWindow.hasShadow = NO;
|
||||
cocoaWindow.opaque = NO;
|
||||
if (cocoaWindow.isKeyWindow) {
|
||||
cocoaWindow.level = NSMainMenuWindowLevel+1;
|
||||
}
|
||||
|
||||
// make metal layer transparent
|
||||
for (NSView *view in sdlView.subviews) {
|
||||
if ([view.className isEqualToString:@"SDL_cocoametalview"]) {
|
||||
view.layer.opaque = NO;
|
||||
view.layer.backgroundColor = clearColor;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// make OpenGL surface transparent
|
||||
GLint zero = 0;
|
||||
[[NSOpenGLContext currentContext] setValues:&zero forParameter:NSOpenGLCPSurfaceOpacity];
|
||||
}
|
||||
|
||||
void update_window_mask_rects(SDL_Window * window, int h, const std::vector<SDL_Rect> &rects)
|
||||
{
|
||||
CAShapeLayer *maskLayer = (CAShapeLayer*)SDL_GetWindowData(window, "maskLayer");
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
for(auto it = rects.begin(); it != rects.end(); ++it) {
|
||||
SDL_Rect rect = *it;
|
||||
CGPathAddRect(path, NULL, CGRectMake(rect.x, rect.y, rect.w, rect.h));
|
||||
}
|
||||
maskLayer.path = path;
|
||||
maskLayer.affineTransform = CGAffineTransformScale(CGAffineTransformMakeTranslation(0, h), 1.0, -1.0);
|
||||
CGPathRelease(path);
|
||||
}
|
||||
|
||||
bool is_fullscreen_osx(SDL_Window * window)
|
||||
{
|
||||
if (!window) {
|
||||
|
517
BasiliskII/src/SDL/video_rootless.cpp
Normal file
517
BasiliskII/src/SDL/video_rootless.cpp
Normal file
@ -0,0 +1,517 @@
|
||||
//
|
||||
// video_rootless.cpp
|
||||
// BasiliskII
|
||||
//
|
||||
// Created by Jesús A. Álvarez on 26/10/2019.
|
||||
//
|
||||
|
||||
#include <SDL.h>
|
||||
#include "sysdeps.h"
|
||||
#include "cpu_emulation.h"
|
||||
#include "main.h"
|
||||
#include "macos_util.h"
|
||||
#include "prefs.h"
|
||||
#include "emul_op.h"
|
||||
#include <vector>
|
||||
|
||||
extern void make_window_transparent(SDL_Window * window);
|
||||
extern void update_sdl_video(SDL_Surface *s, int numrects, SDL_Rect *rects);
|
||||
int native_menubar_size = 0;
|
||||
|
||||
/*
|
||||
* Rootless mode support
|
||||
*/
|
||||
|
||||
static const uint8 rootless_proc[] = {
|
||||
// PEntryFromProcessSerialNumber(GetNextProcess(d0:d1))
|
||||
// returns next PSN in d0:d1, PEntryPtr in d2
|
||||
0x2F, 0x01, // move.l d1,-(sp) ; psn low
|
||||
0x2F, 0x00, // move.l d0,-(sp) ; psn high
|
||||
0x55, 0x4F, // suba.w #2,sp ; result
|
||||
0x48, 0x6F, 0x00, 0x02, // pea 2(sp) ; ptr(psn)
|
||||
0x3F, 0x3C, 0x00, 0x38, // move.w #$38,-(sp) ; GetNextProcess
|
||||
0xA8, 0x8F, // _OSDispatch ; get psn of first process
|
||||
0x30, 0x1F, // move.w (sp)+,d0 ; result
|
||||
|
||||
0x59, 0x4F, // subq #4,sp ; result
|
||||
0x48, 0x6F, 0x00, 0x04, // pea 4(sp) ; ptr(psn)
|
||||
0x3F, 0x3C, 0x00, 0x4F, // move.w #$4F,-(sp) ; _PEntryFromProcessSerialNumber
|
||||
0xA8, 0x8F, // _OSDispatch ; get PEntry
|
||||
0x24, 0x1F, // move.l (sp)+, d2 ; pEntry
|
||||
0x20, 0x1F, // move.l (sp)+, d0 ; psn high
|
||||
0x22, 0x1F, // move.l (sp)+, d1 ; psn low
|
||||
0x4E, 0x75, // rts
|
||||
|
||||
// a0 = GetResource(d0, d1)
|
||||
#define GETRESOURCE 38 // offset to this function
|
||||
0x59, 0x4F, // subq #4,sp ; result
|
||||
0x2F, 0x00, // move.l d0,-(sp) ; type
|
||||
0x3F, 0x01, // move.w d1,-(sp) ; size
|
||||
0xA9, 0xA0, // _GetResource
|
||||
0x20, 0x57, // movea.l (sp),a0 ; result to a0
|
||||
0x59, 0x4F, // subq #4, sp ; result
|
||||
0x2F, 0x08, // move.l a0,-(sp) ; handle
|
||||
0xA9, 0xA5, // _SizeRsrc
|
||||
0x20, 0x1F, // move.l (sp)+,d0 ; size
|
||||
0x20, 0x5F, // movea.l (sp)+,a0 ; handle
|
||||
0x4E, 0x75, // rts
|
||||
|
||||
#define PAINTRGNPATCH (GETRESOURCE + 22)
|
||||
M68K_EMUL_OP_PAINTRGN >> 8,
|
||||
M68K_EMUL_OP_PAINTRGN & 0xff,
|
||||
0x2F, 0x3C, 0, 0, 0, 0, // move.l address, -(sp)
|
||||
0x4E, 0x75, // rts
|
||||
|
||||
#define DRAGGRAYRGNPATCH (PAINTRGNPATCH + 10)
|
||||
M68K_EMUL_OP_DRAGGRAYRGN >> 8,
|
||||
M68K_EMUL_OP_DRAGGRAYRGN & 0xff,
|
||||
0x2F, 0x3C, 0, 0, 0, 0, // move.l address, -(sp)
|
||||
0x4E, 0x75, // rts
|
||||
};
|
||||
|
||||
static uint32 rootless_proc_ptr = 0;
|
||||
static uint32 low_mem_map = 0;
|
||||
static bool dragging_region = false;
|
||||
static uint32 drag_region_ptr = 0;
|
||||
|
||||
static void MyPatchTrap(int trap, uint32 ptr) {
|
||||
M68kRegisters r;
|
||||
r.d[0] = trap;
|
||||
Execute68kTrap(0xa746, &r); // GetToolTrapAddress()
|
||||
WriteMacInt32(ptr + 4, r.a[0]);
|
||||
r.d[0] = trap;
|
||||
r.a[0] = ptr;
|
||||
Execute68kTrap(0xa647, &r); // SetToolTrap()
|
||||
}
|
||||
|
||||
int16 InstallRootlessProc() {
|
||||
// Rootless mode support
|
||||
M68kRegisters r;
|
||||
if (strncmp(PrefsFindString("screen"), "rootless", 8) == 0) {
|
||||
printf("Installing rootless support\n");
|
||||
r.d[0] = sizeof(rootless_proc);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
if (r.a[0] == 0) {
|
||||
return memFullErr;
|
||||
}
|
||||
rootless_proc_ptr = r.a[0];
|
||||
Host2Mac_memcpy(rootless_proc_ptr, rootless_proc, sizeof(rootless_proc));
|
||||
low_mem_map = 0;
|
||||
printf("Installed at 0x%x\n", rootless_proc_ptr);
|
||||
|
||||
// Install patches to detect dragging regions
|
||||
MyPatchTrap(0xa8d3, rootless_proc_ptr + PAINTRGNPATCH);
|
||||
MyPatchTrap(0xa905, rootless_proc_ptr + DRAGGRAYRGNPATCH);
|
||||
} else {
|
||||
rootless_proc_ptr = 0;
|
||||
low_mem_map = 0;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static struct {
|
||||
uint8_t *pixels;
|
||||
uint8_t *cursorMask;
|
||||
int w,h;
|
||||
} display_mask = {
|
||||
.pixels = NULL,
|
||||
.cursorMask = NULL,
|
||||
.w = 0,
|
||||
.h = 0
|
||||
};
|
||||
|
||||
void MaskRect(int16 top, int16 left, int16 bottom, int16 right, bool in) {
|
||||
if (top == bottom || left == right) return;
|
||||
if (top < 0) top = 0;
|
||||
if (left < 0) left = 0;
|
||||
if (bottom > display_mask.h) bottom = display_mask.h;
|
||||
if (right > display_mask.w) right = display_mask.w;
|
||||
|
||||
uint8_t *line = display_mask.pixels + display_mask.w * top + left;
|
||||
for (int y = top; y < bottom; y++) {
|
||||
memset(line, in ? 0xff : 0x00, right - left);
|
||||
line += display_mask.w;
|
||||
}
|
||||
}
|
||||
|
||||
void PrintRegion(uint32 regionPtr) {
|
||||
int16 size = ReadMacInt16(regionPtr);
|
||||
int16 top = ReadMacInt16(regionPtr + 2);
|
||||
int16 left = ReadMacInt16(regionPtr + 4);
|
||||
int16 bottom = ReadMacInt16(regionPtr + 6);
|
||||
int16 right = ReadMacInt16(regionPtr + 8);
|
||||
printf("Region (%d: %d,%d %dx%d):\n", size, left, top, (right-left), (bottom-top));
|
||||
for(int i=0; i < size; i++) {
|
||||
printf("%02x", ReadMacInt8(regionPtr + i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void MaskRegion(uint32 regionPtr, bool in) {
|
||||
// https://www.info-mac.org/viewtopic.php?t=17328
|
||||
uint16 size = ReadMacInt16(regionPtr);
|
||||
int16 top = ReadMacInt16(regionPtr + 2);
|
||||
int16 left = ReadMacInt16(regionPtr + 4);
|
||||
int16 bottom = ReadMacInt16(regionPtr + 6);
|
||||
int16 right = ReadMacInt16(regionPtr + 8);
|
||||
if (bottom > display_mask.h) bottom = display_mask.h;
|
||||
if (right > display_mask.w) right = display_mask.w;
|
||||
|
||||
if (size == 10) {
|
||||
MaskRect(top, left, bottom, right, in);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *scanline = display_mask.pixels + top * display_mask.w;
|
||||
uint8_t *curLine = (uint8*)alloca(display_mask.w);
|
||||
memset(curLine, 0, display_mask.w);
|
||||
|
||||
uint32 ptr = regionPtr + 10;
|
||||
for (int16 y = top; y < bottom; y++) {
|
||||
uint16 nextLine = ReadMacInt16(ptr);
|
||||
if (nextLine == y) {
|
||||
// apply changes to current line
|
||||
ptr += 2;
|
||||
for(;;) {
|
||||
uint16 begin = ReadMacInt16(ptr);
|
||||
ptr += 2;
|
||||
if (begin == 0x7fff) break;
|
||||
uint16 end = ReadMacInt16(ptr);
|
||||
ptr += 2;
|
||||
if (end > display_mask.w) {
|
||||
end = display_mask.w;
|
||||
}
|
||||
for (int i=begin; i < end; i++) {
|
||||
curLine[i] ^= 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// blit current line
|
||||
if (in) {
|
||||
for (int x = left; x < right; x++) {
|
||||
scanline[x] |= curLine[x];
|
||||
}
|
||||
} else {
|
||||
for (int x = left; x < right; x++) {
|
||||
scanline[x] |= ~curLine[x];
|
||||
}
|
||||
}
|
||||
|
||||
scanline += display_mask.w;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Rect GetRegionBounds(uint32 regionPtr) {
|
||||
int16 top = ReadMacInt16(regionPtr + 2);
|
||||
int16 left = ReadMacInt16(regionPtr + 4);
|
||||
int16 bottom = ReadMacInt16(regionPtr + 6);
|
||||
int16 right = ReadMacInt16(regionPtr + 8);
|
||||
return (SDL_Rect){.x = left, .y = top, .w = right-left, .h = bottom-top};
|
||||
}
|
||||
|
||||
uint32 GetLowMemOffset(uint32 addr) {
|
||||
if (low_mem_map == 0) {
|
||||
abort();
|
||||
}
|
||||
|
||||
uint32 offset = 0;
|
||||
uint32 ptr = low_mem_map;
|
||||
for(;;) {
|
||||
uint16 size = ReadMacInt16(ptr);
|
||||
if (size == 0) break;
|
||||
uint32 lo = ReadMacInt32(ptr+2);
|
||||
ptr += 6;
|
||||
if (addr < lo) {
|
||||
return UINT32_MAX;
|
||||
} else if (addr < (lo+size)) {
|
||||
return offset + (addr-lo);
|
||||
}
|
||||
offset += size;
|
||||
}
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
static uint32 GetResource(uint32 type, int16 id, int32* size) {
|
||||
M68kRegisters r;
|
||||
r.d[0] = type;
|
||||
r.d[1] = id;
|
||||
Execute68k(rootless_proc_ptr + GETRESOURCE, &r);
|
||||
if (size) {
|
||||
*size = r.d[0];
|
||||
}
|
||||
return r.a[0];
|
||||
}
|
||||
|
||||
static SDL_Rect MaskMenu(uint32 mbEntry) {
|
||||
int16 menuTop = ReadMacInt16(mbEntry);
|
||||
int16 menuLeft = ReadMacInt16(mbEntry + 2);
|
||||
int16 menuBottom = ReadMacInt16(mbEntry + 4);
|
||||
int16 menuRight = ReadMacInt16(mbEntry + 6);
|
||||
MaskRect(menuTop-1, menuLeft-1, menuBottom+1, menuRight+1, true);
|
||||
// shadow
|
||||
MaskRect(menuBottom+1, menuLeft+1, menuBottom+2, menuRight+1, true);
|
||||
MaskRect(menuTop+2, menuRight+1, menuBottom+2, menuRight+2, true);
|
||||
return (SDL_Rect){.x = menuLeft-1, .y = menuTop-1, .w = menuRight - menuLeft + 3, .h = menuBottom - menuTop + 3};
|
||||
}
|
||||
|
||||
uint16 menuEntries[16];
|
||||
uint16 *lastMenuEntry = menuEntries;
|
||||
uint16 menuBarHeight;
|
||||
bool inMenuSelect = false;
|
||||
|
||||
static SDL_Rect MaskMenuBar() {
|
||||
if (native_menubar_size && ReadMacInt16(0x0BAA) == 20) {
|
||||
// Embiggen menubar
|
||||
WriteMacInt16(0xBAA, native_menubar_size);
|
||||
}
|
||||
if (!inMenuSelect) {
|
||||
menuBarHeight = ReadMacInt16(0x0BAA);
|
||||
}
|
||||
MaskRect(0, 0, menuBarHeight, display_mask.w, true);
|
||||
return (SDL_Rect){.x = 0, .y = 0, .w = display_mask.w, .h = menuBarHeight};
|
||||
}
|
||||
|
||||
static void MaskMenus(uint32 expandMem, uint32 lowMemPtr, std::vector<SDL_Rect> &rects) {
|
||||
uint32 mbSaveLoc = ReadMacInt32(ReadMacInt32(lowMemPtr + GetLowMemOffset(0x0B5C)));
|
||||
if (mbSaveLoc == 0) {
|
||||
// no menu yet
|
||||
inMenuSelect = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16 mbEntryOffset = ReadMacInt16(mbSaveLoc);
|
||||
if (mbEntryOffset == 0) {
|
||||
inMenuSelect = false;
|
||||
return;
|
||||
} else if (lastMenuEntry == menuEntries && *lastMenuEntry == 0) {
|
||||
// first menu
|
||||
*lastMenuEntry = mbEntryOffset;
|
||||
} else if (mbEntryOffset > *lastMenuEntry && lastMenuEntry < &menuEntries[16]) {
|
||||
// added menu
|
||||
*(++lastMenuEntry) = mbEntryOffset;
|
||||
} else if (mbEntryOffset < *lastMenuEntry) {
|
||||
// removed menu
|
||||
lastMenuEntry--;
|
||||
}
|
||||
|
||||
inMenuSelect = true;
|
||||
|
||||
// mask all menus
|
||||
for (uint16 *entry = menuEntries; entry <= lastMenuEntry; entry++) {
|
||||
rects.push_back(MaskMenu(mbSaveLoc + *entry));
|
||||
}
|
||||
}
|
||||
|
||||
static void MaskBits(int16 x, int16 y, uint16 bits) {
|
||||
uint16 testBit = 0x8000;
|
||||
for(int i=0; i < 16; i++, testBit >>= 1) {
|
||||
if (x < 0 || y < 0 || y >= display_mask.h) continue;
|
||||
display_mask.pixels[x + (y * display_mask.w) + i] |= (bits & testBit) ? 0xff : 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
bool cursor_point_opaque() {
|
||||
if (display_mask.pixels == NULL) {
|
||||
return true;
|
||||
}
|
||||
int32 my = ReadMacInt16(0x0828);
|
||||
int32 mx = ReadMacInt16(0x082a);
|
||||
return display_mask.cursorMask[mx + my * display_mask.w];
|
||||
}
|
||||
|
||||
static SDL_Rect MaskCursor() {
|
||||
int32 y = ReadMacInt16(0x0830);
|
||||
int32 x = ReadMacInt16(0x0832);
|
||||
// cursor data
|
||||
uint16 *TheCrsr = (uint16*)Mac2HostAddr(0x0844);
|
||||
// hotspot
|
||||
uint16 hx = ntohs(TheCrsr[32]);
|
||||
uint16 hy = ntohs(TheCrsr[33]);
|
||||
|
||||
// apply mask
|
||||
for (int i=0; i < 16; i++) {
|
||||
MaskBits(x-hx, y+i-hy, ntohs(TheCrsr[16+i]));
|
||||
}
|
||||
return (SDL_Rect){.x=x-hx, .y=y-hy, .w=16, .h=16};
|
||||
}
|
||||
|
||||
bool IsLayer(uint32 windowPtr) {
|
||||
return ReadMacInt16(windowPtr + 0x4A) == 0xDEAD;
|
||||
}
|
||||
|
||||
void WalkLayerHierarchy(uint32 layerPtr, int level, std::vector<SDL_Rect> &mask_rects) {
|
||||
if (layerPtr == 0) return;
|
||||
int kind = ReadMacInt16(layerPtr + 0x6C);
|
||||
int visible = ReadMacInt8(layerPtr + 0x6E);
|
||||
bool isLayer = IsLayer(layerPtr);
|
||||
uint32 strucRgnHandle = ReadMacInt32(layerPtr + 0x72);
|
||||
int x = 0,y = 0,w = 0,h = 0;
|
||||
if (strucRgnHandle) {
|
||||
uint32 regionPtr = ReadMacInt32(strucRgnHandle);
|
||||
y = ReadMacInt16(regionPtr + 2);
|
||||
x = ReadMacInt16(regionPtr + 4);
|
||||
h = ReadMacInt16(regionPtr + 6) - y;
|
||||
w = ReadMacInt16(regionPtr + 8) - x;
|
||||
if (visible && w && h && !isLayer) {
|
||||
mask_rects.push_back(GetRegionBounds(regionPtr));
|
||||
}
|
||||
}
|
||||
//printf("%*s%s 0x%x, kind=%d, visible=%d, %d,%d %dx%d\n", 2*level, "", IsLayer(layerPtr) ? "Layer" : "Window", layerPtr, kind, visible, x,y,w,h);
|
||||
|
||||
if (IsLayer(layerPtr)) {
|
||||
uint32 subWindows = ReadMacInt32(layerPtr + 0x94);
|
||||
WalkLayerHierarchy(subWindows, level+1, mask_rects);
|
||||
}
|
||||
|
||||
uint32 nextWindow = ReadMacInt32(layerPtr + 0x90);
|
||||
if (nextWindow) WalkLayerHierarchy(nextWindow, level, mask_rects);
|
||||
}
|
||||
|
||||
void update_display_mask(SDL_Window *window, int w, int h) {
|
||||
if (rootless_proc_ptr == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for process manager
|
||||
uint32 expandMem = ReadMacInt32(0x02B6);
|
||||
uint16 emProcessMgrExists = ReadMacInt16(expandMem + 0x0128);
|
||||
if (!emProcessMgrExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Read lowmem mapping
|
||||
if (low_mem_map == 0) {
|
||||
uint32 handle = GetResource('lmem', -16458, NULL);
|
||||
low_mem_map = ReadMacInt32(handle);
|
||||
printf("low_mem_map at 0x%x\n", low_mem_map);
|
||||
}
|
||||
|
||||
std::vector<SDL_Rect> mask_rects;
|
||||
|
||||
if (display_mask.w != w || display_mask.h != h) {
|
||||
// new mask
|
||||
free(display_mask.pixels);
|
||||
display_mask.pixels = (uint8_t*)calloc(2, w*h);
|
||||
display_mask.w = w;
|
||||
display_mask.h = h;
|
||||
display_mask.cursorMask = &display_mask.pixels[display_mask.w * display_mask.h];
|
||||
|
||||
// update whole screen
|
||||
make_window_transparent(window);
|
||||
SDL_Rect rect = {.x = 0, .y = 0, .w = w, .h = h};
|
||||
update_sdl_video(NULL, 1, &rect);
|
||||
mask_rects.push_back(rect);
|
||||
memset(display_mask.pixels, 0xff, 2 * display_mask.w * display_mask.h);
|
||||
} else {
|
||||
// clear all
|
||||
memset(display_mask.pixels, 0, display_mask.w * display_mask.h);
|
||||
|
||||
// show non-desktop
|
||||
uint32 deskPort = ReadMacInt32(0x9E2);
|
||||
uint32 deskPortVisRgn = ReadMacInt32(ReadMacInt32(deskPort + 0x18));
|
||||
MaskRegion(deskPortVisRgn, false);
|
||||
}
|
||||
|
||||
bool has_front_process = false;
|
||||
|
||||
M68kRegisters r;
|
||||
uint32 rootLayerPtr = 0;
|
||||
for(r.d[0] = 0, r.d[1] = 0;;) {
|
||||
Execute68k(rootless_proc_ptr, &r);
|
||||
uint32_t pEntryPtr = r.d[2];
|
||||
if (r.d[2] == 0) break;
|
||||
|
||||
uint16 state = ReadMacInt16(pEntryPtr);
|
||||
if (state == 4) {
|
||||
has_front_process = true;
|
||||
uint32 lowMemPtr = ReadMacInt32(ReadMacInt32(pEntryPtr + 0x9E));
|
||||
if (lowMemPtr) {
|
||||
MaskMenus(expandMem, lowMemPtr, mask_rects);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 layerPtr = ReadMacInt32(pEntryPtr + 0x70);
|
||||
uint16 layerTxSize = ReadMacInt16(layerPtr + 0x4A);
|
||||
if (layerTxSize != 0xDEAD) {
|
||||
// not a layer
|
||||
continue;
|
||||
}
|
||||
|
||||
// find root layer
|
||||
if (rootLayerPtr == 0) {
|
||||
rootLayerPtr = ReadMacInt32(layerPtr + 0x82); // parent layer
|
||||
while (ReadMacInt32(rootLayerPtr + 0x82)) {
|
||||
rootLayerPtr = ReadMacInt32(rootLayerPtr + 0x82);
|
||||
}
|
||||
WalkLayerHierarchy(rootLayerPtr, 0, mask_rects);
|
||||
}
|
||||
}
|
||||
|
||||
// Menu Bar
|
||||
mask_rects.push_back(MaskMenuBar());
|
||||
|
||||
// Drag region
|
||||
int8 mouseState = ReadMacInt8(0x0172);
|
||||
if (dragging_region && mouseState) {
|
||||
dragging_region = false;
|
||||
drag_region_ptr = 0;
|
||||
} else if (dragging_region && !mouseState && drag_region_ptr) {
|
||||
MaskRegion(drag_region_ptr, true);
|
||||
mask_rects.push_back(GetRegionBounds(drag_region_ptr));
|
||||
}
|
||||
|
||||
// Copy over cursor mask
|
||||
memcpy(display_mask.cursorMask, display_mask.pixels, display_mask.w * display_mask.h);
|
||||
|
||||
// Cursor
|
||||
if (cursor_point_opaque()) {
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
mask_rects.push_back(MaskCursor());
|
||||
} else {
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
}
|
||||
|
||||
extern void update_window_mask_rects(SDL_Window * window, int h, const std::vector<SDL_Rect> &rects);
|
||||
update_window_mask_rects(window, display_mask.h, mask_rects);
|
||||
}
|
||||
|
||||
void apply_display_mask(SDL_Surface * host_surface, SDL_Rect update_rect) {
|
||||
if (display_mask.pixels == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (host_surface->format->format != SDL_PIXELFORMAT_ARGB8888) {
|
||||
printf("Invalid host surface\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t * srcPixels = (uint32_t*)((uint8_t *)host_surface->pixels +
|
||||
update_rect.y * host_surface->pitch +
|
||||
update_rect.x * 4);
|
||||
|
||||
uint8_t * srcMask = display_mask.pixels + update_rect.y * display_mask.w + update_rect.x;
|
||||
for (int y = update_rect.y; y < update_rect.y+update_rect.h; y++) {
|
||||
uint32_t * pixel = srcPixels;
|
||||
uint8_t * mask = srcMask;
|
||||
for (int x = update_rect.x; x < update_rect.x+update_rect.w; x++) {
|
||||
if (*mask == 0) {
|
||||
*pixel = 0;
|
||||
}
|
||||
pixel++;
|
||||
mask++;
|
||||
}
|
||||
srcPixels += host_surface->pitch / 4;
|
||||
srcMask += display_mask.w;
|
||||
}
|
||||
}
|
||||
|
||||
void check_drag_region(M68kRegisters *r, uint16 opcode) {
|
||||
if (opcode == M68K_EMUL_OP_DRAGGRAYRGN) {
|
||||
dragging_region = true;
|
||||
drag_region_ptr = 0;
|
||||
} else if (opcode == M68K_EMUL_OP_PAINTRGN && dragging_region) {
|
||||
uint32 regionHandle = ReadMacInt32(r->a[7]+4);
|
||||
drag_region_ptr = ReadMacInt32(regionHandle);
|
||||
}
|
||||
}
|
@ -65,6 +65,12 @@
|
||||
#include "video_blit.h"
|
||||
#include "vm_alloc.h"
|
||||
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
extern void update_display_mask(SDL_Window * window, int w, int h);
|
||||
extern void apply_display_mask(SDL_Surface * host_surface, SDL_Rect update_rect);
|
||||
extern bool cursor_point_opaque(void);
|
||||
#endif
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
@ -82,7 +88,8 @@ extern int display_type; // See enum above
|
||||
#else
|
||||
enum {
|
||||
DISPLAY_WINDOW, // windowed display
|
||||
DISPLAY_SCREEN // fullscreen display
|
||||
DISPLAY_SCREEN, // fullscreen display
|
||||
DISPLAY_ROOTLESS // fullscreen with transparent desktop
|
||||
};
|
||||
static int display_type = DISPLAY_WINDOW; // See enum above
|
||||
#endif
|
||||
@ -737,6 +744,11 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags
|
||||
window_flags |= SDL_WINDOW_RESIZABLE;
|
||||
*/
|
||||
if (!sdl_window) {
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
if (display_type == DISPLAY_ROOTLESS) {
|
||||
window_flags |= SDL_WINDOW_BORDERLESS;
|
||||
}
|
||||
#endif
|
||||
sdl_window = SDL_CreateWindow(
|
||||
"Basilisk II",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
@ -894,6 +906,11 @@ static int present_sdl_video()
|
||||
}
|
||||
UNLOCK_PALETTE; // passed potential deadlock, can unlock palette
|
||||
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
// Apply mask
|
||||
apply_display_mask(host_surface, sdl_update_video_rect);
|
||||
#endif
|
||||
|
||||
// Update the host OS' texture
|
||||
void * srcPixels = (void *)((uint8_t *)host_surface->pixels +
|
||||
sdl_update_video_rect.y * host_surface->pitch +
|
||||
@ -1369,6 +1386,13 @@ bool VideoInit(bool classic)
|
||||
display_type = DISPLAY_WINDOW;
|
||||
else if (sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2)
|
||||
display_type = DISPLAY_SCREEN;
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
else if (strncmp(mode_str, "rootless", 8) == 0) {
|
||||
display_type = DISPLAY_ROOTLESS;
|
||||
default_width = sdl_display_width();
|
||||
default_height = sdl_display_height();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (default_width <= 0)
|
||||
default_width = sdl_display_width();
|
||||
@ -1458,6 +1482,17 @@ bool VideoInit(bool classic)
|
||||
for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++)
|
||||
add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d);
|
||||
}
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
} else if (display_type == DISPLAY_ROOTLESS) {
|
||||
for (int i = 0; video_modes[i].w != 0; i++) {
|
||||
const int w = video_modes[i].w;
|
||||
const int h = video_modes[i].h;
|
||||
if (i > 0 && (w >= default_width || h >= default_height))
|
||||
continue;
|
||||
for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++)
|
||||
add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (VideoModes.empty()) {
|
||||
@ -1697,6 +1732,9 @@ void VideoInterrupt(void)
|
||||
if (toggle_fullscreen)
|
||||
do_toggle_fullscreen();
|
||||
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
update_display_mask(sdl_window, host_surface->w, host_surface->h);
|
||||
#endif
|
||||
present_sdl_video();
|
||||
|
||||
// Temporarily give up frame buffer lock (this is the point where
|
||||
@ -1931,132 +1969,31 @@ static bool is_hotkey_down(SDL_Keysym const & ks)
|
||||
|
||||
static int kc_decode(SDL_Keysym const & ks, bool key_down)
|
||||
{
|
||||
static int8_t usb_to_adb_scancode[] = {
|
||||
-1, -1, -1, -1, 0, 11, 8, 2, 14, 3, 5, 4, 34, 38, 40, 37,
|
||||
46, 45, 31, 35, 12, 15, 1, 17, 32, 9, 13, 7, 16, 6, 18, 19,
|
||||
20, 21, 23, 22, 26, 28, 25, 29, 36, 53, 51, 48, 49, 27, 24, 33,
|
||||
30, 42, 42, 41, 39, 10, 43, 47, 44, 57, 122, 120, 99, 118, 96, 97,
|
||||
98, 100, 101, 109, 103, 111, 105, 107, 113, 114, 115, 116, 117, 119, 121, 60,
|
||||
59, 61, 62, 71, 75, 67, 78, 69, 76, 83, 84, 85, 86, 87, 88, 89,
|
||||
91, 92, 82, 65, 50, 55, 126, 81, 105, 107, 113, 106, 64, 79, 80, 90,
|
||||
-1, -1, -1, -1, -1, 114, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74,
|
||||
72, 73, -1, -1, -1, 95, -1, 94, -1, 93, -1, -1, -1, -1, -1, -1,
|
||||
104, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
54, 56, 58, 55, 54, 56, 58, 55, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
switch (ks.sym) {
|
||||
case SDLK_a: return 0x00;
|
||||
case SDLK_b: return 0x0b;
|
||||
case SDLK_c: return 0x08;
|
||||
case SDLK_d: return 0x02;
|
||||
case SDLK_e: return 0x0e;
|
||||
case SDLK_f: return 0x03;
|
||||
case SDLK_g: return 0x05;
|
||||
case SDLK_h: return 0x04;
|
||||
case SDLK_i: return 0x22;
|
||||
case SDLK_j: return 0x26;
|
||||
case SDLK_k: return 0x28;
|
||||
case SDLK_l: return 0x25;
|
||||
case SDLK_m: return 0x2e;
|
||||
case SDLK_n: return 0x2d;
|
||||
case SDLK_o: return 0x1f;
|
||||
case SDLK_p: return 0x23;
|
||||
case SDLK_q: return 0x0c;
|
||||
case SDLK_r: return 0x0f;
|
||||
case SDLK_s: return 0x01;
|
||||
case SDLK_t: return 0x11;
|
||||
case SDLK_u: return 0x20;
|
||||
case SDLK_v: return 0x09;
|
||||
case SDLK_w: return 0x0d;
|
||||
case SDLK_x: return 0x07;
|
||||
case SDLK_y: return 0x10;
|
||||
case SDLK_z: return 0x06;
|
||||
|
||||
case SDLK_1: case SDLK_EXCLAIM: return 0x12;
|
||||
case SDLK_2: case SDLK_AT: return 0x13;
|
||||
case SDLK_3: case SDLK_HASH: return 0x14;
|
||||
case SDLK_4: case SDLK_DOLLAR: return 0x15;
|
||||
case SDLK_5: return 0x17;
|
||||
case SDLK_6: return 0x16;
|
||||
case SDLK_7: return 0x1a;
|
||||
case SDLK_8: return 0x1c;
|
||||
case SDLK_9: return 0x19;
|
||||
case SDLK_0: return 0x1d;
|
||||
|
||||
case SDLK_BACKQUOTE: case 167: return 0x32;
|
||||
case SDLK_MINUS: case SDLK_UNDERSCORE: return 0x1b;
|
||||
case SDLK_EQUALS: case SDLK_PLUS: return 0x18;
|
||||
case SDLK_LEFTBRACKET: return 0x21;
|
||||
case SDLK_RIGHTBRACKET: return 0x1e;
|
||||
case SDLK_BACKSLASH: return 0x2a;
|
||||
case SDLK_SEMICOLON: case SDLK_COLON: return 0x29;
|
||||
case SDLK_QUOTE: case SDLK_QUOTEDBL: return 0x27;
|
||||
case SDLK_COMMA: case SDLK_LESS: return 0x2b;
|
||||
case SDLK_PERIOD: case SDLK_GREATER: return 0x2f;
|
||||
case SDLK_SLASH: case SDLK_QUESTION: return 0x2c;
|
||||
|
||||
case SDLK_TAB: if (is_hotkey_down(ks)) {if (!key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case SDLK_RETURN: if (is_hotkey_down(ks)) {if (!key_down) toggle_fullscreen = true; return -2;} else return 0x24;
|
||||
case SDLK_SPACE: return 0x31;
|
||||
case SDLK_BACKSPACE: return 0x33;
|
||||
|
||||
case SDLK_DELETE: return 0x75;
|
||||
case SDLK_INSERT: return 0x72;
|
||||
case SDLK_HOME: case SDLK_HELP: return 0x73;
|
||||
case SDLK_END: return 0x77;
|
||||
case SDLK_PAGEUP: return 0x74;
|
||||
case SDLK_PAGEDOWN: return 0x79;
|
||||
|
||||
case SDLK_LCTRL: return 0x36;
|
||||
case SDLK_RCTRL: return 0x36;
|
||||
case SDLK_LSHIFT: return 0x38;
|
||||
case SDLK_RSHIFT: return 0x38;
|
||||
#ifdef __APPLE__
|
||||
case SDLK_LALT: return 0x3a;
|
||||
case SDLK_RALT: return 0x3a;
|
||||
case SDLK_LGUI: return 0x37;
|
||||
case SDLK_RGUI: return 0x37;
|
||||
#else
|
||||
case SDLK_LALT: return 0x37;
|
||||
case SDLK_RALT: return 0x37;
|
||||
case SDLK_LGUI: return 0x3a;
|
||||
case SDLK_RGUI: return 0x3a;
|
||||
#endif
|
||||
case SDLK_MENU: return 0x32;
|
||||
case SDLK_CAPSLOCK: return 0x39;
|
||||
case SDLK_NUMLOCKCLEAR: return 0x47;
|
||||
|
||||
case SDLK_UP: return 0x3e;
|
||||
case SDLK_DOWN: return 0x3d;
|
||||
case SDLK_LEFT: return 0x3b;
|
||||
case SDLK_RIGHT: return 0x3c;
|
||||
|
||||
case SDLK_ESCAPE: if (is_hotkey_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
|
||||
case SDLK_F1: if (is_hotkey_down(ks)) {if (!key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case SDLK_F2: return 0x78;
|
||||
case SDLK_F3: return 0x63;
|
||||
case SDLK_F4: return 0x76;
|
||||
case SDLK_F5: return 0x60;
|
||||
case SDLK_F6: return 0x61;
|
||||
case SDLK_F7: return 0x62;
|
||||
case SDLK_F8: return 0x64;
|
||||
case SDLK_F9: return 0x65;
|
||||
case SDLK_F10: return 0x6d;
|
||||
case SDLK_F11: return 0x67;
|
||||
case SDLK_F12: return 0x6f;
|
||||
|
||||
case SDLK_PRINTSCREEN: return 0x69;
|
||||
case SDLK_SCROLLLOCK: return 0x6b;
|
||||
case SDLK_PAUSE: return 0x71;
|
||||
|
||||
case SDLK_KP_0: return 0x52;
|
||||
case SDLK_KP_1: return 0x53;
|
||||
case SDLK_KP_2: return 0x54;
|
||||
case SDLK_KP_3: return 0x55;
|
||||
case SDLK_KP_4: return 0x56;
|
||||
case SDLK_KP_5: return 0x57;
|
||||
case SDLK_KP_6: return 0x58;
|
||||
case SDLK_KP_7: return 0x59;
|
||||
case SDLK_KP_8: return 0x5b;
|
||||
case SDLK_KP_9: return 0x5c;
|
||||
case SDLK_KP_PERIOD: return 0x41;
|
||||
case SDLK_KP_PLUS: return 0x45;
|
||||
case SDLK_KP_MINUS: return 0x4e;
|
||||
case SDLK_KP_MULTIPLY: return 0x43;
|
||||
case SDLK_KP_DIVIDE: return 0x4b;
|
||||
case SDLK_KP_ENTER: return 0x4c;
|
||||
case SDLK_KP_EQUALS: return 0x51;
|
||||
default: return usb_to_adb_scancode[ks.scancode];
|
||||
}
|
||||
D(bug("Unhandled SDL keysym: %d\n", ks.sym));
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int event2keycode(SDL_KeyboardEvent const &ev, bool key_down)
|
||||
@ -2162,6 +2099,11 @@ static void handle_events(void)
|
||||
|
||||
// Mouse button
|
||||
case SDL_MOUSEBUTTONDOWN: {
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
if (!cursor_point_opaque()) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
unsigned int button = event.button.button;
|
||||
if (button == SDL_BUTTON_LEFT)
|
||||
ADBMouseDown(0);
|
||||
|
@ -581,6 +581,16 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
case M68K_EMUL_OP_PAINTRGN:
|
||||
case M68K_EMUL_OP_DRAGGRAYRGN: {
|
||||
// Patched traps for tracking dragged outlines
|
||||
extern void check_drag_region(M68kRegisters *r, uint16 opcode);
|
||||
check_drag_region(r, opcode);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
printf("FATAL: EMUL_OP called with bogus opcode %08x\n", opcode);
|
||||
printf("d0 %08x d1 %08x d2 %08x d3 %08x\n"
|
||||
|
@ -90,7 +90,9 @@ enum {
|
||||
M68K_EMUL_OP_SOUNDIN_CLOSE,
|
||||
M68K_EMUL_OP_DEBUGUTIL,
|
||||
M68K_EMUL_OP_IDLE_TIME,
|
||||
M68K_EMUL_OP_SUSPEND,
|
||||
M68K_EMUL_OP_SUSPEND, // 0x7138
|
||||
M68K_EMUL_OP_PAINTRGN,
|
||||
M68K_EMUL_OP_DRAGGRAYRGN,
|
||||
M68K_EMUL_OP_MAX // highest number
|
||||
};
|
||||
|
||||
|
@ -482,6 +482,12 @@ int16 monitor_desc::driver_open(void)
|
||||
|
||||
// Init color palette (solid gray)
|
||||
set_gray_palette();
|
||||
|
||||
// Enable rootless video
|
||||
#ifdef VIDEO_ROOTLESS
|
||||
extern int16 InstallRootlessProc(void);
|
||||
return InstallRootlessProc();
|
||||
#endif
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user