diff --git a/src/Makefile b/src/Makefile index b9b60cc..ffca2e0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -61,8 +61,11 @@ gsportmac: $(OBJECTS) compile_time.o arch/mac/makedmg.sh .. GSportDmg GSport GSport 7 # Linux for X builds: +gsportx: CCOPTS += -DX_RENDER -DX_RENDER_SCALE=2 -DBORDER_WIDTH=8 +gsportx: EXTRA_LIBS += -lXrender gsportx: $(OBJECTS) compile_time.o - $(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(XLIBS) $(EXTRA_LIBS) -lX11 + $(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) \ + $(XLIBS) $(EXTRA_LIBS) -lX11 echo $(OBJECTS) mv gsportx .. cp -f ../config.template ../config.txt diff --git a/src/defc.h b/src/defc.h index 9283d7e..a28fd13 100644 --- a/src/defc.h +++ b/src/defc.h @@ -1,35 +1,35 @@ /* GSport - an Apple //gs Emulator Copyright (C) 2010 by GSport contributors - + Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "defcomm.h" -// OG redirect printf to console -#ifdef ACTIVEGS -#include -extern "C" int outputInfo(const char* format,...); -extern "C" int fOutputInfo(FILE*,const char* format,...); -#define printf outputInfo -#define fprintf fOutputInfo -#endif - +// OG redirect printf to console +#ifdef ACTIVEGS +#include +extern "C" int outputInfo(const char* format,...); +extern "C" int fOutputInfo(FILE*,const char* format,...); +#define printf outputInfo +#define fprintf fOutputInfo +#endif + #define STRUCT(a) typedef struct _ ## a a; struct _ ## a typedef unsigned char byte; @@ -58,12 +58,18 @@ void U_STACK_TRACE(); #define DRECIP_DCYCS_IN_16MS (1.0 / (DCYCS_IN_16MS)) #ifdef GSPORT_LITTLE_ENDIAN +#ifdef __GNUC__ +# define BIGEND(a) __builtin_bswap32(a) +# define GET_BE_WORD16(a) __builtin_bswap16(a) +# define GET_BE_WORD32(a) (BIGEND(a)) +#else # define BIGEND(a) ((((a) >> 24) & 0xff) + \ (((a) >> 8) & 0xff00) + \ (((a) << 8) & 0xff0000) + \ (((a) << 24) & 0xff000000)) # define GET_BE_WORD16(a) ((((a) >> 8) & 0xff) + (((a) << 8) & 0xff00)) # define GET_BE_WORD32(a) (BIGEND(a)) +#endif #else # define BIGEND(a) (a) # define GET_BE_WORD16(a) (a) @@ -83,45 +89,45 @@ void U_STACK_TRACE(); #endif #include -#include -#include - -#include -#include -#include - -#ifndef UNDER_CE // OG CE SPecific +#include +#include + +#include +#include +#include + +#ifndef UNDER_CE // OG CE SPecific #include #include #include #include -// OG Adding support for open -#ifdef WIN32 -#include -#endif - -#else -extern int errno; -extern int open(const char* name,int,...); -extern int read(int,char*,int); -extern int close(int); -extern int write( int fd, const void *buffer, unsigned int count ); -extern int lseek(int,int,int); -struct stat { int st_size; }; -extern int stat(const char* name, struct stat*); -extern int fstat(int, struct stat*); -#define O_RDWR 1 -#define O_BINARY 2 -#define O_RDONLY 4 -#define O_WRONLY 8 -#define O_CREAT 16 -#define O_TRUNC 32 -#define EAGAIN 11 -#define EINTR 4 - -#endif - - +// OG Adding support for open +#ifdef WIN32 +#include +#endif + +#else +extern int errno; +extern int open(const char* name,int,...); +extern int read(int,char*,int); +extern int close(int); +extern int write( int fd, const void *buffer, unsigned int count ); +extern int lseek(int,int,int); +struct stat { int st_size; }; +extern int stat(const char* name, struct stat*); +extern int fstat(int, struct stat*); +#define O_RDWR 1 +#define O_BINARY 2 +#define O_RDONLY 4 +#define O_WRONLY 8 +#define O_CREAT 16 +#define O_TRUNC 32 +#define EAGAIN 11 +#define EINTR 4 + +#endif + + #ifdef HPUX # include /* for GET_ITIMER */ #endif @@ -184,6 +190,7 @@ STRUCT(Engine_reg) { STRUCT(Kimage) { void *dev_handle; void *dev_handle2; + void *dev_handle3; /* for xrender ! */ byte *data_ptr; int width_req; int width_act; @@ -361,10 +368,10 @@ STRUCT(Emustate_word32list) { #include "iwm.h" #include "protos.h" -// OG Added define for joystick -#define JOYSTICK_TYPE_KEYPAD 0 -#define JOYSTICK_TYPE_MOUSE 1 -#define JOYSTICK_TYPE_NATIVE_1 2 -#define JOYSTICK_TYPE_NATIVE_2 3 -#define JOYSTICK_TYPE_NONE 4 // OG Added Joystick None -#define NB_JOYSTICK_TYPE 5 +// OG Added define for joystick +#define JOYSTICK_TYPE_KEYPAD 0 +#define JOYSTICK_TYPE_MOUSE 1 +#define JOYSTICK_TYPE_NATIVE_1 2 +#define JOYSTICK_TYPE_NATIVE_2 3 +#define JOYSTICK_TYPE_NONE 4 // OG Added Joystick None +#define NB_JOYSTICK_TYPE 5 diff --git a/src/defcomm.h b/src/defcomm.h index 8e16e5e..4724058 100644 --- a/src/defcomm.h +++ b/src/defcomm.h @@ -146,7 +146,9 @@ #define ALL_STAT_FLASH_STATE (1 << (BIT_ALL_STAT_FLASH_STATE)) #define ALL_STAT_A2VID_PALETTE (0xf << (BIT_ALL_STAT_A2VID_PALETTE)) +#ifndef BORDER_WIDTH #define BORDER_WIDTH 32 +#endif //#define EFF_BORDER_WIDTH (BORDER_WIDTH + (640-560)) @@ -155,8 +157,8 @@ /* BASE_MARGIN_BOTTOM+MARGIN_TOP must equal 62. There are 262 scan lines */ /* at 60Hz (15.7KHz line rate) and so we just make 62 border lines */ -#define BASE_MARGIN_TOP 32 -#define BASE_MARGIN_BOTTOM 30 +#define BASE_MARGIN_TOP BORDER_WIDTH +#define BASE_MARGIN_BOTTOM (BORDER_WIDTH-2) #define BASE_MARGIN_LEFT BORDER_WIDTH #define BASE_MARGIN_RIGHT BORDER_WIDTH diff --git a/src/prodos.h b/src/prodos.h index 9702546..741a73f 100755 --- a/src/prodos.h +++ b/src/prodos.h @@ -19,25 +19,31 @@ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifdef __linux__ +#define PACKED __attribute__((packed)) +#else +#define PACKED +#endif + typedef struct l2byte_st L2byte; struct l2byte_st { byte low; byte hi; -}; +} PACKED; typedef struct l3byte_st L3byte; struct l3byte_st { byte low; byte hi; byte higher; -}; +} PACKED; typedef L2byte Block; typedef struct pro_time_st Pro_time; struct pro_time_st { byte times[4]; -}; +} PACKED; typedef struct file_entry_st File_entry; struct file_entry_st { @@ -63,7 +69,7 @@ struct file_entry_st { Pro_time last_mod; /* 0x25 */ Block header_pointer; -}; +} PACKED; STRUCT(Vol_hdr) { /* 0x4 */ @@ -86,14 +92,14 @@ STRUCT(Vol_hdr) { Block bit_map; /* 0x29 */ L2byte total_blocks; -}; +} PACKED; typedef struct directory_st Directory; struct directory_st { Block prev_blk; Block next_blk; File_entry file_entries[13]; -}; +} PACKED; STRUCT(ProDisk) { int fd; diff --git a/src/xdriver.c b/src/xdriver.c index f31a316..ec2a83c 100644 --- a/src/xdriver.c +++ b/src/xdriver.c @@ -21,7 +21,14 @@ # if !defined(__CYGWIN__) && !defined(__POWERPC__) /* No shared memory on Cygwin */ + +#ifndef X_RENDER +/* Enabled in the Makefile: Required to enable scaling */ +/* # define X_RENDER */ +#endif + # define X_SHARED_MEM + #endif /* CYGWIN */ #include @@ -37,6 +44,10 @@ # include #endif +#ifdef X_RENDER +#include +#endif + int XShmQueryExtension(Display *display); #include "defc.h" @@ -90,6 +101,18 @@ int g_use_shmem = 1; int g_use_shmem = 0; #endif +#ifdef X_RENDER +#ifndef X_RENDER_SCALE +# define X_RENDER_SCALE 1 +#endif +int g_use_xrender = 1; +unsigned int g_xscreen_scale = X_RENDER_SCALE; +Picture g_xrender_win; +Picture g_xrender_a2_screen; +Pixmap g_xrender_a2_pix; +GC g_xrender_gc; +#endif + extern Kimage g_mainwin_kimage; extern int Max_color_size; @@ -307,7 +330,7 @@ show_xcolor_array() for(i = 0; i < 256; i++) { printf("%02x: %08x\n", i, g_palette_8to1624[i]); - + #if 0 printf("%02x: %04x %04x %04x, %02x %x\n", i, xcolor_array[i].red, xcolor_array[i].green, @@ -397,6 +420,7 @@ dev_video_init() int cnt; int font_height; int base_height; + int base_width = X_A2_WINDOW_WIDTH; int screen_num; char *myTextString[1]; word32 lores_col; @@ -523,11 +547,30 @@ dev_video_init() create_win_list |= CWColormap | CWBorderPixel | CWBackPixel; base_height = X_A2_WINDOW_HEIGHT; + +#ifdef X_RENDER + if (g_use_xrender) { + int dummy = 0; + ret = XRenderQueryExtension(g_display, &dummy, &dummy); + if(ret == 0) { + printf("XRenderQueryExtension ret: %d\n", ret); + printf("not using XRender memory\n"); + g_use_xrender = 0; + } else { + printf("Will use XRender for X\n"); + // g_use_shmem = 0; // not necessary + } + } + if (g_use_xrender) { + base_width *= g_xscreen_scale; + base_height *= g_xscreen_scale; + } +#endif if (g_win_status_debug) base_height += MAX_STATUS_LINES * 13; g_a2_win = XCreateWindow(g_display, RootWindow(g_display, screen_num), - 0, 0, BASE_WINDOW_WIDTH, base_height, + 0, 0, base_width, base_height, 0, g_screen_depth, InputOutput, g_vis, create_win_list, &win_attr); @@ -535,6 +578,36 @@ dev_video_init() XFlush(g_display); +#ifdef X_RENDER + if (g_use_xrender) { + XWindowAttributes attrs; + XGetWindowAttributes(g_display, g_a2_win, &attrs); + + XRenderPictFormat* format = XRenderFindVisualFormat(g_display, attrs.visual); + + g_xrender_win = XRenderCreatePicture(g_display, g_a2_win, + format, 0, NULL); + /* Also create the backbuffer we transfer to, we don't + * 'draw' in the window itself */ + Pixmap pix = XCreatePixmap(g_display, + g_a2_win, X_A2_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT, 24); + g_xrender_gc = XCreateGC(g_display, pix, 0, NULL); + g_xrender_a2_screen = XRenderCreatePicture( + g_display, pix, + XRenderFindStandardFormat(g_display, PictStandardRGB24), + 0, NULL); + if (g_xscreen_scale != 1) { + XTransform t = {}; + t.matrix[0][0] = XDoubleToFixed(1); + t.matrix[1][1] = XDoubleToFixed(1); + t.matrix[2][2] = XDoubleToFixed(g_xscreen_scale); + + XRenderSetPictureTransform(g_display, g_xrender_a2_screen, &t); + } + g_xrender_a2_pix = pix; + } +#endif + /* Check for XShm */ #ifdef X_SHARED_MEM if(g_use_shmem) { @@ -582,11 +655,11 @@ dev_video_init() XStringListToTextProperty(myTextString, 1, &my_winText); my_winSizeHints.flags = PSize | PMinSize | PMaxSize; - my_winSizeHints.width = BASE_WINDOW_WIDTH; + my_winSizeHints.width = base_width; my_winSizeHints.height = base_height; - my_winSizeHints.min_width = BASE_WINDOW_WIDTH; + my_winSizeHints.min_width = base_width; my_winSizeHints.min_height = base_height; - my_winSizeHints.max_width = BASE_WINDOW_WIDTH; + my_winSizeHints.max_width = base_width; my_winSizeHints.max_height = base_height; my_winClassHint.res_name = "GSport"; my_winClassHint.res_class = "GSport"; @@ -746,7 +819,10 @@ x_set_mask_and_shift(word32 x_mask, word32 *mask_ptr, int *shift_left_ptr, int i; /* Shift until we find first set bit in mask, then remember mask,shift*/ - +#ifdef __GCC__ + shift = x_mask? ffs(x_mask) - 1 : 0; + x_mask >>= shift; +#else shift = 0; for(i = 0; i < 32; i++) { if(x_mask & 1) { @@ -756,6 +832,7 @@ x_set_mask_and_shift(word32 x_mask, word32 *mask_ptr, int *shift_left_ptr, x_mask = x_mask >> 1; shift++; } +#endif *mask_ptr = x_mask; *shift_left_ptr = shift; /* Now, calculate shift_right_ptr */ @@ -924,21 +1001,27 @@ get_ximage(Kimage *kimage_ptr) } -void +void x_toggle_status_lines() { XSizeHints my_winSizeHints; XClassHint my_winClassHint; int base_height = X_A2_WINDOW_HEIGHT; + int base_width = X_A2_WINDOW_WIDTH; + +#ifdef X_RENDER + base_height *= g_xscreen_scale; + base_width *= g_xscreen_scale; +#endif if ((g_win_status_debug = !g_win_status_debug)) base_height += MAX_STATUS_LINES * 13; //printf("Resize returns %d\n", XResizeWindow(g_display, g_a2_win, BASE_WINDOW_WIDTH, base_height)); my_winSizeHints.flags = PSize | PMinSize | PMaxSize; - my_winSizeHints.width = BASE_WINDOW_WIDTH; + my_winSizeHints.width = base_width; my_winSizeHints.height = base_height; - my_winSizeHints.min_width = BASE_WINDOW_WIDTH; + my_winSizeHints.min_width = base_width; my_winSizeHints.min_height = base_height; - my_winSizeHints.max_width = BASE_WINDOW_WIDTH; + my_winSizeHints.max_width = base_width; my_winSizeHints.max_height = base_height; my_winClassHint.res_name = "GSport"; my_winClassHint.res_class = "GSport"; @@ -956,8 +1039,14 @@ x_redraw_status_lines() int line; int height; int margin; + int base = X_A2_WINDOW_HEIGHT; word32 white, black; +#ifdef X_RENDER + if (g_use_xrender) { + base *= g_xscreen_scale; + } +#endif if (g_win_status_debug) { height = g_text_FontSt->ascent + g_text_FontSt->descent; @@ -979,10 +1068,10 @@ x_redraw_status_lines() continue; } XDrawImageString(g_display, g_a2_win, g_a2_winGC, 0, - X_A2_WINDOW_HEIGHT + height*line + margin, + base + height*line + margin, buf, strlen(buf)); } - + XFlush(g_display); } } @@ -996,6 +1085,27 @@ x_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy, xim = (XImage *)kimage_ptr->dev_handle; +#ifdef X_RENDER + if (g_use_xrender) { +#ifdef X_SHARED_MEM + if(g_use_shmem) { + XShmPutImage(g_display, g_xrender_a2_pix, g_xrender_gc, xim, + srcx, srcy, destx, desty, width, height, False); + } else +#endif + /* transfer to server */ + XPutImage(g_display, g_xrender_a2_pix, g_xrender_gc, xim, + srcx, srcy, destx, desty, width, height); + /* accerated copy + scale to window */ + XRenderComposite(g_display, PictOpSrc, + g_xrender_a2_screen, None, g_xrender_win, + 0, 0, 0, 0, 0, 0, + X_A2_WINDOW_WIDTH * g_xscreen_scale, + X_A2_WINDOW_HEIGHT * g_xscreen_scale); + return; + } +#endif + #ifdef X_SHARED_MEM if(g_use_shmem) { XShmPutImage(g_display, g_a2_win, g_a2_winGC, xim, @@ -1024,9 +1134,19 @@ int x_update_mouse(int raw_x, int raw_y, int button_states, int buttons_valid) { int x, y; +#ifdef X_RENDER + if (g_use_xrender) { + int ml = BASE_MARGIN_LEFT * g_xscreen_scale; + int mt = BASE_MARGIN_TOP * g_xscreen_scale; - x = raw_x - BASE_MARGIN_LEFT; - y = raw_y - BASE_MARGIN_TOP; + x = (raw_x - ml) / g_xscreen_scale; + y = (raw_y - mt) / g_xscreen_scale; + } else +#endif + { + x = raw_x - BASE_MARGIN_LEFT; + y = raw_y - BASE_MARGIN_TOP; + } if(g_warp_pointer && (x == A2_WINDOW_WIDTH/2) && (y == A2_WINDOW_HEIGHT/2) && (buttons_valid == 0) ) {