home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
Emulation
/
Atari800
/
atari_x11.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-02-12
|
76KB
|
3,538 lines
#include <stdio.h>
#include <stdlib.h>
#ifdef VMS
#include <stat.h>
#else
#include <sys/stat.h>
#endif
#include <sys/time.h>
#include <unistd.h>
/*
* Note: For SHM version check if image_data or the pixmap is needed
* Check if rect, nrects, points and npoints are needed.
* scanline_ptr.
*/
static char *rcsid = "$Id: atari_x11.c,v 1.42 1997/09/30 jhs,david Exp $";
#ifdef XVIEW
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
#include <xview/canvas.h>
#include <xview/notice.h>
#include <xview/file_chsr.h>
#endif
#ifdef MOTIF
#include <Xm/MainW.h>
#include <Xm/DrawingA.h>
#include <Xm/MessageB.h>
#include <Xm/FileSB.h>
#include <Xm/RowColumn.h>
#include <Xm/ToggleBG.h>
static XtAppContext app;
static Widget toplevel;
static Widget main_w;
static Widget drawing_area;
static Widget fsel_b;
static Widget fsel_d;
static Widget fsel_r;
static Widget rbox_d;
static Widget rbox_r;
static Widget togg_d1, togg_d2, togg_d3, togg_d4;
static Widget togg_d5, togg_d6, togg_d7, togg_d8;
static Widget togg_8k, togg_16k, togg_oss, togg_32k, togg_5200;
static Widget eject_menu;
static Widget disable_menu;
static Widget system_menu;
static int motif_disk_sel = 1;
static int motif_rom_sel = 1;
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#ifndef VMS
#include "config.h"
#endif
#include "atari.h"
#include "colours.h"
#include "monitor.h"
#include "sio.h"
#include "nas.h"
#include "platform.h"
#include "rt-config.h"
#include "mem.h"
static struct timeval tp;
static struct timezone tzp;
static double basetime;
/*
static int nframes = 0;
*/
#ifdef SHM
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
static XShmSegmentInfo shminfo;
static XImage *image;
extern char *atari_screen;
extern int colour_translation_table[256];
#endif
#ifdef LINUX_JOYSTICK
#include <linux/joystick.h>
#include <fcntl.h>
static int js0;
static int js1;
static int js0_centre_x;
static int js0_centre_y;
static int js1_centre_x;
static int js1_centre_y;
static struct JS_DATA_TYPE js_data;
#endif
#define FALSE 0
#define TRUE 1
typedef enum
{
Small,
Large,
Huge
} WindowSize;
static WindowSize windowsize = Large;
enum
{
MONITOR_NOTHING,
MONITOR_FPS,
MONITOR_SIO
} x11_monitor = MONITOR_NOTHING;
static int x11bug = FALSE;
static int private_cmap = FALSE; /* If TRUE, allocate own cmap,
otherwise cmap == defcmap */
static Colormap defcmap; /* Default of Screen */
static Colormap cmap; /* The cmap we actually use */
static int window_width;
static int window_height;
static Display *display;
static Screen *screen;
static Window window;
#ifndef SHM
static Pixmap pixmap;
#endif
static Visual *visual;
static GC gc;
static GC gc_colour[256];
static int colours[256];
/*static XComposeStatus keyboard_status;*/
#ifdef XVIEW
static Frame frame;
static Panel panel;
static Canvas canvas;
static Menu system_menu;
static Menu coldstart_menu;
static Menu consol_menu;
static Menu options_menu;
static Frame chooser;
static Frame controllers_frame;
static Panel controllers_panel;
static Panel_item keypad_item;
static Panel_item mouse_item;
#ifdef LINUX_JOYSTICK
static Panel_item js0_item;
static Panel_item js1_item;
#endif
static Frame performance_frame;
static Panel performance_panel;
static Panel_item refresh_slider;
#endif
static int NUMLOCKMASK = Mod2Mask; /* preliminary */
/* Should try to find out with XGetModifierMapping */
#define IsShifted(event) (!!((event)->xkey.state & ShiftMask))
#define SHIFT(event) (IsShifted(event) ? AKEY_SHFT : 0)
#define CONTROL(event) (((event)->xkey.state & ControlMask) ? AKEY_CTRL : 0)
#define IsNumlocked(event) (!!((event)->xkey.state & NUMLOCKMASK))
static int SHIFTPRESSED =0;
static int KEYPRESSED =0;
static int XTERNAUTOREPEAT=1; /* At program-start, is autorepeat set? */
static int XCURRENTAUTOREPEAT=1; /* is autorepeat currently set? */
static int paused=0;
static UBYTE *image_data;
static int modified;
static int keypad_mode = -1; /* Joystick */
static int keypad_trig = 1; /* Keypad Trigger Position */
/* static int keypad_stick = 0x0f; * Keypad Joystick Position, now function */
/* These are the specific keys currently pressed */
/* The scheme is from xkobo, which has great keypad control */
static int keypad_dl =0;
static int keypad_d =0;
static int keypad_dr =0;
static int keypad_l =0;
static int keypad_r =0;
static int keypad_ul =0;
static int keypad_u =0;
static int keypad_ur =0;
static int keypad_changed=1; /* one of the values above has changed */
static int mouse_mode = -1; /* Joystick, Paddle and Light Pen */
static int mouse_stick; /* Mouse Joystick Position */
static int js0_mode = -1;
static int js1_mode = -1;
static int last_colour = -1;
#define NPOINTS (4096/4)
#define NRECTS (4096/4)
/*
static int nrects = 0;
*/
static int npoints = 0;
static XPoint points[NPOINTS];
static XRectangle rectangles[NRECTS];
static int keyboard_consol;
static int menu_consol;
static int screen_dump = 0;
/*
==========================================
Import a few variables from atari_custom.c
==========================================
*/
extern int refresh_rate;
int GetKeyCode (XEvent *event)
{
KeySym keysym = NoSymbol;
int keycode = AKEY_NONE;
/* OLD, and slow:
char buffer[128];
XLookupString ((XKeyEvent*)event, buffer, 128,
&keysym, &keyboard_status); */
switch (event->type)
{
case Expose :
#ifndef SHM
XCopyArea (display, pixmap, window, gc,
0, 0,
window_width, window_height,
0, 0);
#endif
break;
case KeyPress :
keysym = XLookupKeysym((XKeyEvent*)event, IsShifted(event));
switch (keysym)
{
case XK_Shift_L :
case XK_Shift_R :
/* not quite correct to use Shift here, I SHOULD
look up the XModMap. But then I couldnt do
a switch - case. */
SHIFTPRESSED=1; /* Pokey register */
break;
case XK_Control_L :
case XK_Control_R :
break;
case XK_Caps_Lock :
if (IsShifted(event))
keycode = CONTROL(event) | AKEY_CAPSLOCK;
else
keycode = CONTROL(event) | AKEY_CAPSTOGGLE;
break;
case XK_Shift_Lock :
if (x11bug)
printf ("XK_Shift_Lock\n");
break;
case XK_Alt_L :
case XK_Alt_R :
keycode = AKEY_ATARI;
break;
case XK_F1 :
keycode = AKEY_UI;
break;
case XK_F2 :
keyboard_consol &= 0x03;
keycode = AKEY_NONE;
break;
case XK_F3 :
keyboard_consol &= 0x05;
keycode = AKEY_NONE;
break;
case XK_F4 :
keyboard_consol &= 0x6;
keycode = AKEY_NONE;
break;
case XK_F5 :
keycode = AKEY_WARMSTART;
break;
case XK_L5 :
keycode = AKEY_COLDSTART;
break;
case XK_F6 :
keycode = AKEY_PIL;
break;
case XK_F7 :
keycode = AKEY_BREAK;
break;
case XK_L8 :
screen_dump = (1 - screen_dump);
keycode = AKEY_NONE;
break;
case XK_F8 :
screen_dump = 2;
keycode = AKEY_NONE;
break;
case XK_F9 :
keycode = AKEY_EXIT;
break;
case XK_F10 :
keycode = AKEY_NONE;
break;
case XK_Pause:
keycode = AKEY_NONE;
if (!paused)
paused = 2; /* waiting for TWO Pause releases */
break;
case XK_Home :
keycode = 0x76;
break;
case XK_Insert :
if (IsShifted(event))
keycode = AKEY_INSERT_LINE;
else
keycode = AKEY_INSERT_CHAR;
break;
case XK_BackSpace :
if (CONTROL(event))
keycode = AKEY_DELETE_CHAR;
else if (IsShifted(event))
keycode = AKEY_DELETE_LINE;
else
keycode = AKEY_BACKSPACE;
break;
case XK_Delete :
if (CONTROL(event))
keycode = AKEY_DELETE_CHAR;
else if (IsShifted(event))
keycode = AKEY_DELETE_LINE;
else
keycode = AKEY_BACKSPACE;
break;
case XK_Left :
keycode = AKEY_LEFT;
/* keypad_stick = STICK_LEFT; */
break;
case XK_Up :
keycode = AKEY_UP;
/* keypad_stick = STICK_FORWARD; */
break;
case XK_Right :
keycode = AKEY_RIGHT;
/* keypad_stick = STICK_RIGHT; */
break;
case XK_Down :
keycode = AKEY_DOWN;
/* keypad_stick = STICK_BACK; */
break;
case XK_Escape :
keycode = AKEY_ESCAPE;
break;
case XK_Tab :
if (CONTROL(event))
keycode = AKEY_CLRTAB;
else if (IsShifted(event))
keycode = AKEY_SETTAB;
else
keycode = AKEY_TAB;
break;
case XK_exclam :
keycode = AKEY_EXCLAMATION;
break;
case XK_quotedbl :
keycode = AKEY_DBLQUOTE;
break;
case XK_numbersign :
keycode = AKEY_HASH;
break;
case XK_dollar :
keycode = AKEY_DOLLAR;
break;
case XK_percent :
keycode = AKEY_PERCENT;
break;
case XK_ampersand :
keycode = AKEY_AMPERSAND;
break;
case XK_quoteright :
keycode = AKEY_QUOTE;
break;
case XK_at :
keycode = AKEY_AT;
break;
case XK_parenleft :
keycode = AKEY_PARENLEFT;
break;
case XK_parenright :
keycode = AKEY_PARENRIGHT;
break;
case XK_less :
keycode = AKEY_LESS;
break;
case XK_greater :
keycode = AKEY_GREATER;
break;
case XK_equal :
keycode = AKEY_EQUAL;
break;
case XK_question :
keycode = AKEY_QUESTION;
break;
case XK_minus :
keycode = AKEY_MINUS;
break;
case XK_plus :
keycode = AKEY_PLUS;
break;
case XK_asterisk :
keycode = AKEY_ASTERISK;
break;
case XK_slash :
keycode = AKEY_SLASH;
break;
case XK_colon :
keycode = AKEY_COLON;
break;
case XK_semicolon :
keycode = AKEY_SEMICOLON;
break;
case XK_comma :
keycode = AKEY_COMMA;
break;
case XK_period :
keycode = AKEY_FULLSTOP;
break;
case XK_underscore :
keycode = AKEY_UNDERSCORE;
break;
case XK_bracketleft :
keycode = AKEY_BRACKETLEFT;
break;
case XK_bracketright :
keycode = AKEY_BRACKETRIGHT;
break;
case XK_asciicircum :
keycode = AKEY_CIRCUMFLEX;
break;
case XK_backslash :
keycode = AKEY_BACKSLASH;
break;
case XK_bar :
keycode = AKEY_BAR;
break;
case XK_space :
keycode = AKEY_SPACE;
/* keypad_trig = 0; */
break;
case XK_Return :
keycode = AKEY_RETURN;
/* keypad_stick = STICK_CENTRE; */
break;
case XK_0 :
keycode = CONTROL(event) | AKEY_0;
break;
case XK_1 :
keycode = CONTROL(event) | AKEY_1;
break;
case XK_2 :
keycode = CONTROL(event) | AKEY_2;
break;
case XK_3 :
keycode = CONTROL(event) | AKEY_3;
break;
case XK_4 :
keycode = CONTROL(event) | AKEY_4;
break;
case XK_5 :
keycode = CONTROL(event) | AKEY_5;
break;
case XK_6 :
keycode = CONTROL(event) | AKEY_6;
break;
case XK_7 :
keycode = CONTROL(event) | AKEY_7;
break;
case XK_8 :
keycode = CONTROL(event) | AKEY_8;
break;
case XK_9 :
keycode = CONTROL(event) | AKEY_9;
break;
case XK_A : case XK_a :
keycode = SHIFT(event) | CONTROL(event) | AKEY_a;
break;
case XK_B : case XK_b :
keycode = SHIFT(event) | CONTROL(event) | AKEY_b;
break;
case XK_C : case XK_c :
keycode = SHIFT(event) | CONTROL(event) | AKEY_c;
break;
case XK_D : case XK_d :
keycode = SHIFT(event) | CONTROL(event) | AKEY_d;
break;
case XK_E : case XK_e :
keycode = SHIFT(event) | CONTROL(event) | AKEY_e;
break;
case XK_F : case XK_f :
keycode = SHIFT(event) | CONTROL(event) | AKEY_f;
break;
case XK_G : case XK_g :
keycode = SHIFT(event) | CONTROL(event) | AKEY_g;
break;
case XK_H : case XK_h :
keycode = SHIFT(event) | CONTROL(event) | AKEY_h;
break;
case XK_I : case XK_i :
keycode = SHIFT(event) | CONTROL(event) | AKEY_i;
break;
case XK_J : case XK_j :
keycode = SHIFT(event) | CONTROL(event) | AKEY_j;
break;
case XK_K : case XK_k :
keycode = SHIFT(event) | CONTROL(event) | AKEY_k;
break;
case XK_L : case XK_l :
keycode = SHIFT(event) | CONTROL(event) | AKEY_l;
break;
case XK_M : case XK_m :
keycode = SHIFT(event) | CONTROL(event) | AKEY_m;
break;
case XK_N : case XK_n :
keycode = SHIFT(event) | CONTROL(event) | AKEY_n;
break;
case XK_O : case XK_o :
keycode = SHIFT(event) | CONTROL(event) | AKEY_o;
break;
case XK_P : case XK_p :
keycode = SHIFT(event) | CONTROL(event) | AKEY_p;
break;
case XK_Q : case XK_q :
keycode = SHIFT(event) | CONTROL(event) | AKEY_q;
break;
case XK_R : case XK_r :
keycode = SHIFT(event) | CONTROL(event) | AKEY_r;
break;
case XK_S : case XK_s :
keycode = SHIFT(event) | CONTROL(event) | AKEY_s;
break;
case XK_T : case XK_t :
keycode = SHIFT(event) | CONTROL(event) | AKEY_t;
break;
case XK_U : case XK_u :
keycode = SHIFT(event) | CONTROL(event) | AKEY_u;
break;
case XK_V : case XK_v :
keycode = SHIFT(event) | CONTROL(event) | AKEY_v;
break;
case XK_W : case XK_w :
keycode = SHIFT(event) | CONTROL(event) | AKEY_w;
break;
case XK_X : case XK_x :
keycode = SHIFT(event) | CONTROL(event) | AKEY_x;
break;
case XK_Y : case XK_y :
keycode = SHIFT(event) | CONTROL(event) | AKEY_y;
break;
case XK_Z : case XK_z :
keycode = SHIFT(event) | CONTROL(event) | AKEY_z;
break;
case XK_KP_0 :
case XK_KP_Insert :
keypad_trig = 0;
break;
case XK_KP_1 :
case XK_KP_End :
keypad_dl = 1;
keypad_changed =1;
break;
case XK_KP_2 :
case XK_KP_Down:
keypad_d = 1;
keypad_changed =1;
break;
case XK_KP_3 :
case XK_KP_Next:
keypad_dr = 1;
keypad_changed =1;
break;
case XK_KP_4 :
case XK_KP_Left:
keypad_l = 1;
keypad_changed =1;
break;
case XK_KP_5 :
case XK_KP_Begin: /* Center joystick */
keypad_dl = keypad_d = keypad_dr = keypad_l =0;
keypad_r = keypad_ul = keypad_u = keypad_ur =0;
keypad_changed =1;
break;
case XK_KP_6 :
case XK_KP_Right:
keypad_r = 1;
keypad_changed =1;
break;
case XK_KP_7 :
case XK_KP_Home:
keypad_ul = 1;
keypad_changed =1;
break;
case XK_KP_8 :
case XK_KP_Up:
keypad_u = 1;
keypad_changed =1;
break;
case XK_KP_9 :
case XK_KP_Prior:
keypad_ur = 1;
keypad_changed =1;
break;
default :
if (x11bug)
printf ("Pressed Keysym = %x\n", (int)keysym);
break;
}
if (keycode > AKEY_NONE)
KEYPRESSED=1; /* Pokey Register */
break;
case KeyRelease :
keysym = XLookupKeysym((XKeyEvent*)event, 0);
switch (keysym)
{
case XK_Shift_L :
case XK_Shift_R :
SHIFTPRESSED=0;
break;
case XK_Control_L :
case XK_Control_R :
break;
case XK_Shift_Lock :
if (x11bug)
printf ("XK_Shift_Lock\n");
break;
case XK_Pause:
if (paused > 0) /* safety! */
paused--;
break;
case XK_F1:
case XK_F5:
case XK_F6:
case XK_F7:
case XK_L8:
case XK_F8:
case XK_F9:
case XK_F10:
break;
case XK_F2 :
case XK_F3 :
case XK_F4 :
keyboard_consol = 0x07;
break;
case XK_KP_0 :
case XK_KP_Insert :
keypad_trig = 1;
break;
case XK_KP_1 :
case XK_KP_End :
keypad_dl = 0;
keypad_changed =1;
break;
case XK_KP_2 :
case XK_KP_Down:
keypad_d = 0;
keypad_changed =1;
break;
case XK_KP_3 :
case XK_KP_Next:
keypad_dr = 0;
keypad_changed =1;
break;
case XK_KP_4 :
case XK_KP_Left:
keypad_l = 0;
keypad_changed =1;
break;
case XK_KP_6 :
case XK_KP_Right:
keypad_r = 0;
keypad_changed =1;
break;
case XK_KP_7 :
case XK_KP_Home:
keypad_ul = 0;
keypad_changed =1;
break;
case XK_KP_8 :
case XK_KP_Up:
keypad_u = 0;
keypad_changed =1;
break;
case XK_KP_9 :
case XK_KP_Prior:
keypad_ur = 0;
keypad_changed =1;
break;
case XK_KP_5 :
case XK_KP_Begin:
default :
KEYPRESSED=0;
break;
}
break;
}
return keycode;
}
static int xview_keycode = AKEY_NONE;
#ifdef XVIEW
void event_proc (Xv_Window window, Event *event, Notify_arg arg)
{
int keycode;
keycode = GetKeyCode (event->ie_xevent);
if (keycode != AKEY_NONE)
xview_keycode = keycode;
}
static int auto_reboot;
int disk_change (char *a, char *full_filename, char *filename)
{
int diskno;
int status;
diskno = 1;
if (!auto_reboot)
diskno = notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Insert Disk into which drive?",
NULL,
NOTICE_BUTTON, "1", 1,
NOTICE_BUTTON, "2", 2,
NOTICE_BUTTON, "3", 3,
NOTICE_BUTTON, "4", 4,
NOTICE_BUTTON, "5", 5,
NOTICE_BUTTON, "6", 6,
NOTICE_BUTTON, "7", 7,
NOTICE_BUTTON, "8", 8,
NULL);
if ((diskno < 1) || (diskno > 8))
{
printf ("Invalid diskno: %d\n", diskno);
exit (1);
}
SIO_Dismount(diskno);
if (!SIO_Mount (diskno,full_filename))
status = XV_ERROR;
else
{
if (auto_reboot)
Coldstart ();
status = XV_OK;
}
return status;
}
boot_callback ()
{
auto_reboot = TRUE;
xv_set (chooser,
FRAME_LABEL, "Disk Selector",
FILE_CHOOSER_DIRECTORY, atari_disk_dir,
FILE_CHOOSER_NOTIFY_FUNC, disk_change,
XV_SHOW, TRUE,
NULL);
}
insert_callback ()
{
auto_reboot = FALSE;
xv_set (chooser,
FRAME_LABEL, "Disk Selector",
FILE_CHOOSER_DIRECTORY, atari_disk_dir,
FILE_CHOOSER_NOTIFY_FUNC, disk_change,
XV_SHOW, TRUE,
NULL);
}
eject_callback ()
{
int diskno;
diskno = notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Eject Disk from drive?",
NULL,
NOTICE_BUTTON, "1", 1,
NOTICE_BUTTON, "2", 2,
NOTICE_BUTTON, "3", 3,
NOTICE_BUTTON, "4", 4,
NOTICE_BUTTON, "5", 5,
NOTICE_BUTTON, "6", 6,
NOTICE_BUTTON, "7", 7,
NOTICE_BUTTON, "8", 8,
NULL);
if ((diskno < 1) || (diskno > 8))
{
printf ("Invalid diskno: %d\n", diskno);
exit (1);
}
SIO_Dismount(diskno);
}
disable_callback ()
{
int diskno;
diskno = notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Drive to Disable?",
NULL,
NOTICE_BUTTON, "1", 1,
NOTICE_BUTTON, "2", 2,
NOTICE_BUTTON, "3", 3,
NOTICE_BUTTON, "4", 4,
NOTICE_BUTTON, "5", 5,
NOTICE_BUTTON, "6", 6,
NOTICE_BUTTON, "7", 7,
NOTICE_BUTTON, "8", 8,
NULL);
if ((diskno < 1) || (diskno > 8))
{
printf ("Invalid driveno: %d\n", diskno);
exit (1);
}
SIO_DisableDrive(diskno);
}
int rom_change (char *a, char *full_filename, char *filename)
{
struct stat buf;
int status = XV_ERROR;
int yesno;
stat (full_filename, &buf);
switch (buf.st_size)
{
case 0x2000 :
Remove_ROM ();
if (Insert_8K_ROM(full_filename,0))
{
Coldstart ();
status = XV_OK;
}
break;
case 0x4000 :
yesno = notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
filename,
"Is this an OSS Supercartridge?",
NULL,
NOTICE_BUTTON_YES, "No",
NOTICE_BUTTON_NO, "Yes",
NULL);
if (yesno == NOTICE_YES)
{
Remove_ROM ();
if (Insert_16K_ROM(full_filename,0))
{
Coldstart ();
status = XV_OK;
}
}
else
{
Remove_ROM ();
if (Insert_OSS_ROM(full_filename,0))
{
Coldstart ();
status = XV_OK;
}
}
break;
case 0x8000 :
Remove_ROM ();
if (machine == Atari5200)
{
if (Insert_32K_5200ROM(full_filename,0))
{
Coldstart ();
status = XV_OK;
}
}
else
{
if (Insert_DB_ROM(full_filename,0))
{
Coldstart ();
status = XV_OK;
}
}
break;
default :
break;
}
return status;
}
insert_rom_callback ()
{
xv_set (chooser,
FRAME_LABEL, "ROM Selector",
FILE_CHOOSER_DIRECTORY, atari_rom_dir,
FILE_CHOOSER_NOTIFY_FUNC, rom_change,
XV_SHOW, TRUE,
NULL);
}
remove_rom_callback ()
{
Remove_ROM ();
Coldstart ();
}
enable_pill_callback ()
{
EnablePILL ();
Coldstart ();
}
exit_callback ()
{
exit (1);
}
option_callback ()
{
menu_consol &= 0x03;
}
select_callback ()
{
menu_consol &= 0x05;
}
start_callback ()
{
menu_consol &= 0x6;
}
help_callback ()
{
xview_keycode = AKEY_HELP;
}
break_callback ()
{
xview_keycode = AKEY_BREAK;
}
reset_callback ()
{
Warmstart ();
}
coldstart_callback ()
{
Coldstart ();
}
coldstart_osa_callback ()
{
int status;
status = Initialise_AtariOSA ();
if (status)
{
Menu_item menuitem;
menuitem = xv_get (consol_menu,
MENU_NTH_ITEM, 4);
xv_set (menuitem,
MENU_INACTIVE, TRUE,
NULL);
}
else
{
notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Sorry, OS/A ROM Unavailable",
NULL,
NOTICE_BUTTON, "Cancel", 1,
NULL);
}
}
coldstart_osb_callback ()
{
int status;
status = Initialise_AtariOSB ();
if (status)
{
Menu_item menuitem;
menuitem = xv_get (consol_menu,
MENU_NTH_ITEM, 4);
xv_set (menuitem,
MENU_INACTIVE, TRUE,
NULL);
}
else
{
notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Sorry, OS/B ROM Unavailable",
NULL,
NOTICE_BUTTON, "Cancel", 1,
NULL);
}
}
coldstart_xl_callback ()
{
int status;
status = Initialise_AtariXL ();
if (status)
{
Menu_item menuitem;
menuitem = xv_get (consol_menu,
MENU_NTH_ITEM, 4);
xv_set (menuitem,
MENU_INACTIVE, FALSE,
NULL);
}
else
{
notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Sorry, XL/XE ROM Unavailable",
NULL,
NOTICE_BUTTON, "Cancel", 1,
NULL);
}
}
coldstart_xe_callback ()
{
int status;
status = Initialise_AtariXE ();
if (status)
{
Menu_item menuitem;
menuitem = xv_get (consol_menu,
MENU_NTH_ITEM, 4);
xv_set (menuitem,
MENU_INACTIVE, FALSE,
NULL);
}
else
{
notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Sorry, XL/XE ROM Unavailable",
NULL,
NOTICE_BUTTON, "Cancel", 1,
NULL);
}
}
coldstart_5200_callback ()
{
int status;
status = Initialise_Atari5200 ();
if (status)
{
Menu_item menuitem;
menuitem = xv_get (consol_menu,
MENU_NTH_ITEM, 4);
xv_set (menuitem,
MENU_INACTIVE, FALSE,
NULL);
}
else
{
notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Sorry, 5200 ROM Unavailable",
NULL,
NOTICE_BUTTON, "Cancel", 1,
NULL);
}
}
controllers_ok_callback ()
{
xv_set (controllers_frame,
XV_SHOW, FALSE,
NULL);
}
controllers_callback ()
{
xv_set (controllers_frame,
XV_SHOW, TRUE,
NULL);
}
void sorry_message ()
{
notice_prompt (panel, NULL,
NOTICE_MESSAGE_STRINGS,
"Sorry, controller already assign",
"to another device",
NULL,
NOTICE_BUTTON, "Cancel", 1,
NULL);
}
keypad_callback ()
{
int new_mode;
new_mode = xv_get (keypad_item, PANEL_VALUE);
if ((new_mode != mouse_mode) &&
(new_mode != js0_mode) &&
(new_mode != js1_mode))
{
keypad_mode = new_mode;
}
else
{
sorry_message ();
xv_set (keypad_item,
PANEL_VALUE, keypad_mode,
NULL);
}
}
mouse_callback ()
{
int new_mode;
new_mode = xv_get (mouse_item, PANEL_VALUE);
if ((new_mode != keypad_mode) &&
(new_mode != js0_mode) &&
(new_mode != js1_mode))
{
mouse_mode = new_mode;
}
else
{
sorry_message ();
xv_set (mouse_item,
PANEL_VALUE, mouse_mode,
NULL);
}
}
#ifdef LINUX_JOYSTICK
js0_callback ()
{
int new_mode;
new_mode = xv_get (js0_item, PANEL_VALUE);
if ((new_mode != keypad_mode) &&
(new_mode != mouse_mode) &&
(new_mode != js1_mode))
{
js0_mode = new_mode;
}
else
{
sorry_message ();
xv_set (js0_item,
PANEL_VALUE, js0_mode,
NULL);
}
}
js1_callback ()
{
int new_mode;
new_mode = xv_get (js1_item, PANEL_VALUE);
if ((new_mode != keypad_mode) &&
(new_mode != mouse_mode) &&
(new_mode != js0_mode))
{
js1_mode = new_mode;
}
else
{
sorry_message ();
xv_set (js1_item,
PANEL_VALUE, js1_mode,
NULL);
}
}
#endif
performance_ok_callback ()
{
xv_set (performance_frame,
XV_SHOW, FALSE,
NULL);
}
performance_callback ()
{
xv_set (performance_frame,
XV_SHOW, TRUE,
NULL);
}
refresh_callback (Panel_item item, int value, Event *event)
{
refresh_rate = value;
}
#endif
void Atari_WhatIs (int mode)
{
switch (mode)
{
case 0 :
printf ("Joystick 0");
break;
case 1 :
printf ("Joystick 1");
break;
case 2 :
printf ("Joystick 2");
break;
case 3 :
printf ("Joystick 3");
break;
default :
printf ("not available");
break;
}
}
#ifdef MOTIF
void motif_boot_disk (Widget fs, XtPointer client_data,
XtPointer cbs)
{
char *filename;
if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
XmSTRING_DEFAULT_CHARSET, &filename))
{
if (*filename)
{
SIO_Dismount(1);
if (SIO_Mount (1, filename))
Coldstart ();
}
XtFree (filename);
}
XtUnmanageChild (fs);
XtPopdown (XtParent(fs));
}
void motif_select_disk (Widget toggle, XtPointer client_data, XtPointer cbs)
{
motif_disk_sel = (int) client_data;
}
void motif_insert_disk (Widget fs, XtPointer client_data, XtPointer cbs)
{
char *filename;
if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
XmSTRING_DEFAULT_CHARSET, &filename))
{
if (*filename)
{
SIO_Dismount(motif_disk_sel);
SIO_Mount (motif_disk_sel, filename);
}
XtFree (filename);
}
XtUnmanageChild (fs);
XtPopdown (XtParent(fs));
}
void motif_select_rom (Widget toggle, XtPointer client_data, XtPointer cbs)
{
motif_rom_sel = (int) client_data;
}
void motif_insert_rom (Widget fs, XtPointer client_data, XtPointer cbs)
{
char *filename;
int ret;
if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
XmSTRING_DEFAULT_CHARSET, &filename))
{
if (*filename)
{
Remove_ROM ();
switch (motif_rom_sel)
{
case 1:
ret = Insert_8K_ROM(filename,0);
break;
case 2:
ret = Insert_16K_ROM(filename,0);
break;
case 3:
ret = Insert_OSS_ROM(filename,0);
break;
case 4:
ret = Insert_DB_ROM(filename,0);
break;
case 5:
ret = Insert_32K_5200ROM(filename,0);
break;
default:
ret = 0;
break;
}
if (ret)
{
Coldstart ();
}
}
XtFree (filename);
}
XtUnmanageChild (fs);
XtPopdown (XtParent(fs));
}
void motif_fs_cancel (Widget fs, XtPointer client_data, XtPointer call_data)
{
XtUnmanageChild (fs);
XtPopdown (XtParent(fs));
}
void motif_eject_cback (Widget button, XtPointer client_data, XtPointer cbs)
{
SIO_Dismount(((int) client_data) + 1);
}
void motif_disable_cback (Widget button, XtPointer client_data, XtPointer cbs)
{
SIO_DisableDrive(((int) client_data) + 1);
}
void update_fsel(Widget fsel)
{
XmString dirmask;
XtVaGetValues(fsel, XmNdirMask, &dirmask, NULL);
XmFileSelectionDoSearch(fsel, dirmask);
}
void motif_system_cback (Widget w, XtPointer item_no, XtPointer cbs)
{
XmString t;
int status;
char *errmsg = NULL;
switch ((int) item_no)
{
case 0 :
update_fsel(fsel_b);
XtManageChild (fsel_b);
XtPopup (XtParent(fsel_b), XtGrabNone);
break;
case 1 :
/* insert disk */
update_fsel(fsel_d);
XtManageChild (fsel_d);
XtPopup (XtParent(fsel_d), XtGrabNone);
break;
case 2 :
/* eject disk */
/* handled by pullright menu */
break;
case 3 :
/* disable drive */
/* handled by pullright menu */
break;
case 4 :
/* insert rom */
update_fsel(fsel_r);
XtManageChild (fsel_r);
XtPopup (XtParent(fsel_r), XtGrabNone);
break;
case 5 :
Remove_ROM ();
Coldstart ();
break;
case 6 :
EnablePILL ();
Coldstart ();
break;
case 7 :
status = Initialise_AtariOSA (NULL,NULL);
if (status == 0)
errmsg = "Sorry, OS/A ROM Unavailable";
break;
case 8 :
status = Initialise_AtariOSB (NULL,NULL);
if (status == 0)
errmsg = "Sorry, OS/B ROM Unavailable";
break;
case 9 :
status = Initialise_AtariXL (NULL,NULL);
if (status == 0)
errmsg = "Sorry, XL/XE ROM Unavailable";
break;
case 10 :
status = Initialise_AtariXE (NULL,NULL);
if (status == 0)
errmsg = "Sorry, XL/XE ROM Unavailable";
break;
case 11 :
status = Initialise_Atari5200 (NULL,NULL);
if (status == 0)
errmsg = "Sorry, 5200 ROM Unavailable";
break;
case 12 :
exit (0);
}
if (errmsg)
{
static Widget dialog = NULL;
if (!dialog)
{
Arg arg[1];
dialog = XmCreateErrorDialog (main_w, "message", arg, 0);
XtVaSetValues (dialog,
XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
NULL);
XtUnmanageChild (XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON));
XtUnmanageChild (XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
}
t = XmStringCreateSimple (errmsg);
XtVaSetValues (dialog,
XmNmessageString, t,
NULL);
XmStringFree (t);
XtManageChild (dialog);
}
}
void motif_consol_cback (Widget w, XtPointer item_no, XtPointer cbs)
{
switch ((int) item_no)
{
case 0 :
menu_consol &= 0x03; /* Option Pressed */
break;
case 1 :
menu_consol &= 0x05; /* Select Pressed */
break;
case 2 :
menu_consol &= 0x06; /* Start Pressed */
break;
case 3 :
xview_keycode = AKEY_HELP;
break;
case 4 :
xview_keycode = AKEY_BREAK;
break;
case 5 :
Warmstart ();
break;
case 6 :
Coldstart ();
break;
}
}
void motif_keypress (Widget w, XtPointer client_data, XEvent *event,
Boolean *continue_to_dispatch)
{
int keycode;
keycode = GetKeyCode (event);
if (keycode != AKEY_NONE)
xview_keycode = keycode;
}
void motif_exposure (Widget w, XtPointer client_data, XEvent *event,
Boolean *continue_to_dispatch)
{
modified = TRUE;
}
void motif_enter (Widget w, XtPointer client_data, XEvent *event, Boolean *ctd)
{
if (XCURRENTAUTOREPEAT == AutoRepeatModeOn)
{
XAutoRepeatOff(display);
XCURRENTAUTOREPEAT=AutoRepeatModeOff;
}
if (private_cmap)
XInstallColormap(display, cmap);
}
void motif_leave (Widget w, XtPointer client_data, XEvent *event, Boolean *ctd)
{
if (XTERNAUTOREPEAT == AutoRepeatModeOn)
{
XAutoRepeatOn(display);
XCURRENTAUTOREPEAT=AutoRepeatModeOn;
}
if (private_cmap)
{
XUninstallColormap(display,cmap);
/* XInstallColormap(display,defcmap); */
}
}
#endif
void Atari_Destruct(void)
{
if (display && XTERNAUTOREPEAT != XCURRENTAUTOREPEAT)
XAutoRepeatOn(display);
}
void Atari_Initialise (int *argc, char *argv[])
{
#ifndef XVIEW
#ifndef MOTIF
XSetWindowAttributes xswda;
#endif
#endif
XGCValues xgcvl;
int missing_colors=0;
int depth;
int i, j;
int mode = 0;
#ifdef XVIEW
int ypos;
xv_init (XV_INIT_ARGC_PTR_ARGV, argc, argv, NULL);
#endif
atexit(Atari_Destruct);
#ifdef MOTIF
toplevel = XtVaAppInitialize (&app, "Atari800",
NULL, 0,
argc, argv, NULL,
XtNtitle, ATARI_TITLE,
NULL);
#endif
gettimeofday (&tp, &tzp);
basetime = tp.tv_sec + (tp.tv_usec / 1000000.0);
for (i=j=1;i<*argc;i++)
{
if (strcmp(argv[i],"-small") == 0)
windowsize = Small;
else if (strcmp(argv[i],"-large") == 0)
windowsize = Large;
else if (strcmp(argv[i],"-huge") == 0)
windowsize = Huge;
else if (strcmp(argv[i],"-x11bug") == 0)
x11bug = TRUE;
else if (strcmp(argv[i],"-fps") == 0)
x11_monitor = MONITOR_FPS;
else if (strcmp(argv[i],"-sio") == 0)
x11_monitor = MONITOR_SIO;
else if (strcmp(argv[i],"-private_cmap") == 0)
private_cmap = TRUE;
else if (strcmp(argv[i],"-keypad") == 0)
{
if (keypad_mode == -1)
keypad_mode = mode++;
}
else
{
if (strcmp(argv[i],"-help") == 0)
{
printf ("\t-small Small window (%dx%d)\n",
ATARI_WIDTH, ATARI_HEIGHT);
printf ("\t-large Large window (%dx%d)\n",
ATARI_WIDTH*2, ATARI_HEIGHT*2);
printf ("\t-huge Huge window (%dx%d)\n",
ATARI_WIDTH*3, ATARI_HEIGHT*3);
printf ("\t-x11bug Enable debug code in atari_x11.c\n");
}
argv[j++] = argv[i];
}
}
*argc = j;
#ifdef NAS
NAS_Initialise (argc, argv);
#endif
#ifdef VOXWARE
Voxware_Initialise (argc, argv);
#endif
#ifdef SHM
if (windowsize != Small)
{
printf ("X Shared memory version only supports small window\n");
windowsize = Small;
}
#endif
switch (windowsize)
{
case Small :
window_width = ATARI_WIDTH;
window_height = ATARI_HEIGHT;
break;
case Large :
window_width = ATARI_WIDTH * 2;
window_height = ATARI_HEIGHT * 2;
break;
case Huge :
window_width = ATARI_WIDTH * 3;
window_height = ATARI_HEIGHT * 3;
break;
}
#ifdef LINUX_JOYSTICK
js0 = open ("/dev/js0", O_RDONLY, 0777);
if (js0 != -1)
{
int status;
status = read (js0, &js_data, JS_RETURN);
if (status != JS_RETURN)
{
perror ("/dev/js0");
exit (1);
}
js0_centre_x = js_data.x;
js0_centre_y = js_data.y;
if (x11bug)
printf ("Joystick 0: centre_x = %d, centry_y = %d\n",
js0_centre_x, js0_centre_y);
js0_mode = mode++;
}
js1 = open ("/dev/js1", O_RDONLY, 0777);
if (js1 != -1)
{
int status;
status = read (js1, &js_data, JS_RETURN);
if (status != JS_RETURN)
{
perror ("/dev/js1");
exit (1);
}
js1_centre_x = js_data.x;
js1_centre_y = js_data.y;
if (x11bug)
printf ("Joystick 1: centre_x = %d, centry_y = %d\n",
js1_centre_x, js1_centre_y);
js1_mode = mode++;
}
#endif
mouse_mode = mode++;
if (keypad_mode == -1)
keypad_mode = mode++;
#ifdef XVIEW
frame = (Frame)xv_create ((Xv_opaque)NULL, FRAME,
FRAME_LABEL, ATARI_TITLE,
FRAME_SHOW_RESIZE_CORNER, FALSE,
XV_WIDTH, window_width,
XV_HEIGHT, window_height + 27,
FRAME_SHOW_FOOTER, TRUE,
XV_SHOW, TRUE,
NULL);
panel = (Panel)xv_create (frame, PANEL,
XV_HEIGHT, 25,
XV_SHOW, TRUE,
NULL);
system_menu = xv_create ((Xv_opaque)NULL, MENU,
MENU_ITEM,
MENU_STRING, "Boot Disk",
MENU_NOTIFY_PROC, boot_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Insert Disk",
MENU_NOTIFY_PROC, insert_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Eject Disk",
MENU_NOTIFY_PROC, eject_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Disable Drive",
MENU_NOTIFY_PROC, disable_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Insert Cartridge",
MENU_NOTIFY_PROC, insert_rom_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Remove Cartridge",
MENU_NOTIFY_PROC, remove_rom_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Enable PILL",
MENU_NOTIFY_PROC, enable_pill_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Atari 800 OS/A",
MENU_NOTIFY_PROC, coldstart_osa_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Atari 800 OS/B",
MENU_NOTIFY_PROC, coldstart_osb_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Atari 800XL",
MENU_NOTIFY_PROC, coldstart_xl_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Atari 130XE",
MENU_NOTIFY_PROC, coldstart_xe_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Atari 5200",
MENU_NOTIFY_PROC, coldstart_5200_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Exit",
MENU_NOTIFY_PROC, exit_callback,
NULL,
NULL);
xv_create (panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "System",
PANEL_ITEM_MENU, system_menu,
NULL);
consol_menu = (Menu)xv_create ((Xv_opaque)NULL, MENU,
MENU_ITEM,
MENU_STRING, "Option",
MENU_NOTIFY_PROC, option_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Select",
MENU_NOTIFY_PROC, select_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Start",
MENU_NOTIFY_PROC, start_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Help",
MENU_NOTIFY_PROC, help_callback,
MENU_INACTIVE, (machine == Atari),
NULL,
MENU_ITEM,
MENU_STRING, "Break",
MENU_NOTIFY_PROC, break_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Reset",
MENU_NOTIFY_PROC, reset_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Coldstart",
MENU_NOTIFY_PROC, coldstart_callback,
NULL,
NULL);
xv_create (panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Console",
PANEL_ITEM_MENU, consol_menu,
NULL);
options_menu = (Menu)xv_create ((Xv_opaque)NULL, MENU,
MENU_ITEM,
MENU_STRING, "Controllers",
MENU_NOTIFY_PROC, controllers_callback,
NULL,
MENU_ITEM,
MENU_STRING, "Performance",
MENU_NOTIFY_PROC, performance_callback,
NULL,
NULL);
xv_create (panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Options",
PANEL_ITEM_MENU, options_menu,
NULL);
canvas = (Canvas)xv_create (frame, CANVAS,
CANVAS_WIDTH, window_width,
CANVAS_HEIGHT, window_height,
NULL);
/*
=====================================
Create Controller Configuration Frame
=====================================
*/
controllers_frame = (Frame)xv_create (frame, FRAME_CMD,
FRAME_LABEL, "Controller Configuration",
XV_WIDTH, 300,
XV_HEIGHT, 150,
NULL);
controllers_panel = (Panel)xv_get (controllers_frame, FRAME_CMD_PANEL,
NULL);
ypos = 10;
keypad_item = (Panel_item)xv_create (controllers_panel, PANEL_CHOICE_STACK,
PANEL_VALUE_X, 150,
PANEL_VALUE_Y, ypos,
PANEL_LAYOUT, PANEL_HORIZONTAL,
PANEL_LABEL_STRING, "Numeric Keypad",
PANEL_CHOICE_STRINGS,
"Joystick 1",
"Joystick 2",
"Joystick 3",
"Joystick 4",
NULL,
PANEL_VALUE, keypad_mode,
PANEL_NOTIFY_PROC, keypad_callback,
NULL);
ypos += 25;
mouse_item = (Panel_item)xv_create (controllers_panel, PANEL_CHOICE_STACK,
PANEL_VALUE_X, 150,
PANEL_VALUE_Y, ypos,
PANEL_LAYOUT, PANEL_HORIZONTAL,
PANEL_LABEL_STRING, "Mouse",
PANEL_CHOICE_STRINGS,
"Joystick 1",
"Joystick 2",
"Joystick 3",
"Joystick 4",
"Paddle 1",
"Paddle 2",
"Paddle 3",
"Paddle 4",
"Paddle 5",
"Paddle 6",
"Paddle 7",
"Paddle 8",
"Light Pen",
NULL,
PANEL_VALUE, mouse_mode,
PANEL_NOTIFY_PROC, mouse_callback,
NULL);
ypos += 25;
#ifdef LINUX_JOYSTICK
if (js0 != -1)
{
js0_item = (Panel_item)xv_create (controllers_panel, PANEL_CHOICE_STACK,
PANEL_VALUE_X, 150,
PANEL_VALUE_Y, ypos,
PANEL_LAYOUT, PANEL_HORIZONTAL,
PANEL_LABEL_STRING, "/dev/js0",
PANEL_CHOICE_STRINGS,
"Joystick 1",
"Joystick 2",
"Joystick 3",
"Joystick 4",
NULL,
PANEL_VALUE, js0_mode,
PANEL_NOTIFY_PROC, js0_callback,
NULL);
ypos += 25;
}
if (js1 != -1)
{
js1_item = (Panel_item)xv_create (controllers_panel, PANEL_CHOICE_STACK,
PANEL_VALUE_X, 150,
PANEL_VALUE_Y, ypos,
PANEL_LAYOUT, PANEL_HORIZONTAL,
PANEL_LABEL_STRING, "/dev/js1",
PANEL_CHOICE_STRINGS,
"Joystick 1",
"Joystick 2",
"Joystick 3",
"Joystick 4",
NULL,
PANEL_VALUE, js1_mode,
PANEL_NOTIFY_PROC, js1_callback,
NULL);
ypos += 25;
}
#endif
xv_create (controllers_panel, PANEL_BUTTON,
XV_X, 130,
XV_Y, 125,
PANEL_LABEL_STRING, "OK",
PANEL_NOTIFY_PROC, controllers_ok_callback,
NULL);
/*
======================================
Create Performance Configuration Frame
======================================
*/
performance_frame = (Frame)xv_create (frame, FRAME_CMD,
FRAME_LABEL, "Performance Configuration",
XV_WIDTH, 400,
XV_HEIGHT, 100,
NULL);
performance_panel = (Panel)xv_get (performance_frame, FRAME_CMD_PANEL,
NULL);
ypos = 10;
refresh_slider = (Panel_item)xv_create (performance_panel, PANEL_SLIDER,
PANEL_VALUE_X, 155,
PANEL_VALUE_Y, ypos,
PANEL_LAYOUT, PANEL_HORIZONTAL,
PANEL_LABEL_STRING, "Screen Refresh Rate",
PANEL_VALUE, refresh_rate,
PANEL_MIN_VALUE, 1,
PANEL_MAX_VALUE, 32,
PANEL_SLIDER_WIDTH, 100,
PANEL_TICKS, 32,
PANEL_NOTIFY_PROC, refresh_callback,
NULL);
ypos += 25;
xv_create (performance_panel, PANEL_BUTTON,
XV_X, 180,
XV_Y, 75,
PANEL_LABEL_STRING, "OK",
PANEL_NOTIFY_PROC, performance_ok_callback,
NULL);
/*
====================
Get X Window Objects
====================
*/
display = (Display*)xv_get(frame, XV_DISPLAY);
if (!display)
{
printf ("Failed to open display\n");
exit (1);
}
screen = XDefaultScreenOfDisplay (display);
if (!screen)
{
printf ("Unable to get screen\n");
exit (1);
}
visual = XDefaultVisualOfScreen (screen);
if (!visual)
{
printf ("Unable to get visual\n");
exit (1);
}
window = (Window)xv_get(canvas_paint_window(canvas), XV_XID);
depth = XDefaultDepthOfScreen (screen);
defcmap = XDefaultColormapOfScreen(screen);
if (private_cmap)
{
cmap = XCreateColormap (display,
window,
visual,
AllocNone);
XSetWindowColormap(display, window, cmap);
XInstallColormap(display, cmap);
}
else
cmap = defcmap;
chooser = (Frame)xv_create (frame, FILE_CHOOSER,
FILE_CHOOSER_TYPE, FILE_CHOOSER_OPEN,
NULL);
xv_set (canvas_paint_window(canvas),
WIN_EVENT_PROC, event_proc,
WIN_CONSUME_EVENTS, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS, NULL,
NULL);
#endif
#ifdef MOTIF
{
Widget menubar;
XmString s_system;
XmString s_boot_disk;
XmString s_insert_disk;
XmString s_eject_disk;
XmString s_disable_drive;
XmString s_insert_cart;
XmString s_remove_cart;
XmString s_enable_pill;
XmString s_osa;
XmString s_osb;
XmString s_osxl;
XmString s_osxe;
XmString s_os5200;
XmString s_exit;
XmString s_console;
XmString s_option;
XmString s_select;
XmString s_start;
XmString s_help;
XmString s_break;
XmString s_warmstart;
XmString s_coldstart;
XmString s_label;
XmString s_d1, s_d2, s_d3, s_d4;
XmString s_d5, s_d6, s_d7, s_d8;
char *tmpstr;
XmString xmtmpstr;
Arg args[8];
int n;
main_w = XtVaCreateManagedWidget ("main_window",
xmMainWindowWidgetClass, toplevel,
NULL);
s_system = XmStringCreateSimple ("System");
s_boot_disk = XmStringCreateSimple ("Boot Disk...");
s_insert_disk = XmStringCreateSimple ("Insert Disk...");
s_eject_disk = XmStringCreateSimple ("Eject Disk");
s_disable_drive = XmStringCreateSimple ("Disable Drive");
s_insert_cart = XmStringCreateSimple ("Insert Cartridge...");
s_remove_cart = XmStringCreateSimple ("Remove Cartridge");
s_enable_pill = XmStringCreateSimple ("Enable PILL");
s_osa = XmStringCreateSimple ("Atari 800 OS/A");
s_osb = XmStringCreateSimple ("Atari 800 OS/B");
s_osxl = XmStringCreateSimple ("Atari 800XL");
s_osxe = XmStringCreateSimple ("Atari 130XE");
s_os5200 = XmStringCreateSimple ("Atari 5200");
s_exit = XmStringCreateSimple ("Exit");
s_console = XmStringCreateSimple ("Console");
s_option = XmStringCreateSimple ("Option");
s_select = XmStringCreateSimple ("Select");
s_start = XmStringCreateSimple ("Start");
s_help = XmStringCreateSimple ("Help");
s_break = XmStringCreateSimple ("Break");
s_warmstart = XmStringCreateSimple ("Warmstart");
s_coldstart = XmStringCreateSimple ("Coldstart");
;
menubar = XmVaCreateSimpleMenuBar (main_w, "menubar",
XmVaCASCADEBUTTON, s_system, 'S',
XmVaCASCADEBUTTON, s_console, 'C',
NULL);
system_menu =
XmVaCreateSimplePulldownMenu (menubar, "system_menu", 0, motif_system_cback,
XmVaPUSHBUTTON, s_boot_disk, 'o', NULL, NULL,
XmVaPUSHBUTTON, s_insert_disk, 'I', NULL, NULL,
XmVaCASCADEBUTTON, s_eject_disk, 'j',
XmVaCASCADEBUTTON, s_disable_drive, 'D',
XmVaSEPARATOR,
XmVaPUSHBUTTON, s_insert_cart, 'n', NULL, NULL,
XmVaPUSHBUTTON, s_remove_cart, 'R', NULL, NULL,
XmVaPUSHBUTTON, s_enable_pill, 'P', NULL, NULL,
XmVaSEPARATOR,
XmVaPUSHBUTTON, s_osa, 'A', NULL, NULL,
XmVaPUSHBUTTON, s_osb, 'B', NULL, NULL,
XmVaPUSHBUTTON, s_osxl, 'L', NULL, NULL,
XmVaPUSHBUTTON, s_osxe, 'E', NULL, NULL,
XmVaPUSHBUTTON, s_os5200, '5', NULL, NULL,
XmVaSEPARATOR,
XmVaPUSHBUTTON, s_exit, 'x', NULL, NULL,
NULL);
XmVaCreateSimplePulldownMenu (menubar, "console_menu", 1, motif_consol_cback,
XmVaPUSHBUTTON, s_option, 'O', NULL, NULL,
XmVaPUSHBUTTON, s_select, 't', NULL, NULL,
XmVaPUSHBUTTON, s_start, 'S', NULL, NULL,
XmVaSEPARATOR,
XmVaPUSHBUTTON, s_help, 'H', NULL, NULL,
XmVaPUSHBUTTON, s_break, 'B', NULL, NULL,
XmVaSEPARATOR,
XmVaPUSHBUTTON, s_warmstart, 'W', NULL, NULL,
XmVaPUSHBUTTON, s_coldstart, 'C', NULL, NULL,
NULL);
XmStringFree (s_system);
XmStringFree (s_boot_disk);
XmStringFree (s_insert_disk);
XmStringFree (s_eject_disk);
XmStringFree (s_disable_drive);
XmStringFree (s_insert_cart);
XmStringFree (s_remove_cart);
XmStringFree (s_enable_pill);
XmStringFree (s_osa);
XmStringFree (s_osb);
XmStringFree (s_osxl);
XmStringFree (s_osxe);
XmStringFree (s_os5200);
XmStringFree (s_exit);
XmStringFree (s_console);
XmStringFree (s_option);
XmStringFree (s_select);
XmStringFree (s_start);
XmStringFree (s_help);
XmStringFree (s_break);
XmStringFree (s_warmstart);
XmStringFree (s_coldstart);
XtManageChild (menubar);
fsel_b = XmCreateFileSelectionDialog (toplevel, "boot_disk", NULL, 0);
XtAddCallback (fsel_b, XmNokCallback, motif_boot_disk, NULL);
XtAddCallback (fsel_b, XmNcancelCallback, motif_fs_cancel, NULL);
fsel_d = XmCreateFileSelectionDialog (toplevel, "load_disk", NULL, 0);
XtAddCallback (fsel_d, XmNokCallback, motif_insert_disk, NULL);
XtAddCallback (fsel_d, XmNcancelCallback, motif_fs_cancel, NULL);
n = 0;
XtSetArg(args[n], XmNradioBehavior, True); n++;
XtSetArg(args[n], XmNradioAlwaysOne, True); n++;
XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
rbox_d = XmCreateWorkArea(fsel_d, "rbox_d", args, n);
XtManageChild(rbox_d);
s_label = XmStringCreateSimple("D1:");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
XtSetArg(args[n], XmNset, True); n++;
togg_d1 = XmCreateToggleButtonGadget(rbox_d, "togg_d1", args, n);
XtManageChild(togg_d1);
XmStringFree(s_label);
XtAddCallback (togg_d1, XmNarmCallback, motif_select_disk, (XtPointer) 1);
s_label = XmStringCreateSimple("D2:");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_d2 = XmCreateToggleButtonGadget(rbox_d, "togg_d2", args, n);
XtManageChild(togg_d2);
XmStringFree(s_label);
XtAddCallback (togg_d2, XmNarmCallback, motif_select_disk, (XtPointer) 2);
s_label = XmStringCreateSimple("D3:");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_d3 = XmCreateToggleButtonGadget(rbox_d, "togg_d3", args, n);
XtManageChild(togg_d3);
XmStringFree(s_label);
XtAddCallback (togg_d3, XmNarmCallback, motif_select_disk, (XtPointer) 3);
s_label = XmStringCreateSimple("D4:");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_d4 = XmCreateToggleButtonGadget(rbox_d, "togg_d4", args, n);
XtManageChild(togg_d4);
XmStringFree(s_label);
XtAddCallback (togg_d4, XmNarmCallback, motif_select_disk, (XtPointer) 4);
s_label = XmStringCreateSimple("D5:");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_d5 = XmCreateToggleButtonGadget(rbox_d, "togg_d5", args, n);
XtManageChild(togg_d5);
XmStringFree(s_label);
XtAddCallback (togg_d5, XmNarmCallback, motif_select_disk, (XtPointer) 5);
s_label = XmStringCreateSimple("D6:");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_d6 = XmCreateToggleButtonGadget(rbox_d, "togg_d6", args, n);
XtManageChild(togg_d6);
XmStringFree(s_label);
XtAddCallback (togg_d6, XmNarmCallback, motif_select_disk, (XtPointer) 6);
s_label = XmStringCreateSimple("D7:");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_d7 = XmCreateToggleButtonGadget(rbox_d, "togg_d7", args, n);
XtManageChild(togg_d7);
XmStringFree(s_label);
XtAddCallback (togg_d7, XmNarmCallback, motif_select_disk, (XtPointer) 7);
s_label = XmStringCreateSimple("D8:");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_d8 = XmCreateToggleButtonGadget(rbox_d, "togg_d8", args, n);
XtManageChild(togg_d8);
XmStringFree(s_label);
XtAddCallback (togg_d8, XmNarmCallback, motif_select_disk, (XtPointer) 8);
fsel_r = XmCreateFileSelectionDialog (toplevel, "load_rom", NULL, 0);
XtAddCallback (fsel_r, XmNokCallback, motif_insert_rom, NULL);
XtAddCallback (fsel_r, XmNcancelCallback, motif_fs_cancel, NULL);
n = 0;
XtSetArg(args[n], XmNradioBehavior, True); n++;
XtSetArg(args[n], XmNradioAlwaysOne, True); n++;
rbox_r = XmCreateWorkArea(fsel_r, "rbox_r", args, n);
XtManageChild(rbox_r);
s_label = XmStringCreateSimple("8K");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
XtSetArg(args[n], XmNset, True); n++;
togg_8k = XmCreateToggleButtonGadget(rbox_r, "togg_8k", args, n);
XtManageChild(togg_8k);
XmStringFree(s_label);
XtAddCallback (togg_8k, XmNarmCallback, motif_select_rom, (XtPointer) 1);
s_label = XmStringCreateSimple("16K");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_16k = XmCreateToggleButtonGadget(rbox_r, "togg_16k", args, n);
XtManageChild(togg_16k);
XmStringFree(s_label);
XtAddCallback (togg_16k, XmNarmCallback, motif_select_rom, (XtPointer) 2);
s_label = XmStringCreateSimple("OSS 16K Bank Switched");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_oss = XmCreateToggleButtonGadget(rbox_r, "togg_oss", args, n);
XtManageChild(togg_oss);
XmStringFree(s_label);
XtAddCallback (togg_oss, XmNarmCallback, motif_select_rom, (XtPointer) 3);
s_label = XmStringCreateSimple("DB 32K Bank Switched");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_32k = XmCreateToggleButtonGadget(rbox_r, "togg_32k", args, n);
XtManageChild(togg_32k);
XmStringFree(s_label);
XtAddCallback (togg_32k, XmNarmCallback, motif_select_rom, (XtPointer) 4);
s_label = XmStringCreateSimple("5200 32K");
n = 0;
XtSetArg(args[n], XmNlabelString, s_label); n++;
togg_5200 = XmCreateToggleButtonGadget(rbox_r, "togg_5200", args, n);
XtManageChild(togg_5200);
XmStringFree(s_label);
XtAddCallback (togg_5200, XmNarmCallback, motif_select_rom, (XtPointer) 5);
tmpstr = (char *) XtMalloc(strlen(atari_disk_dir + 3));
strcpy(tmpstr, atari_disk_dir);
strcat(tmpstr, "/*");
xmtmpstr = XmStringCreateSimple(tmpstr);
XmFileSelectionDoSearch(fsel_b, xmtmpstr);
XmFileSelectionDoSearch(fsel_d, xmtmpstr);
XmStringFree(xmtmpstr);
XtFree(tmpstr);
tmpstr = (char *) XtMalloc(strlen(atari_rom_dir + 3));
strcpy(tmpstr, atari_rom_dir);
strcat(tmpstr, "/*");
xmtmpstr = XmStringCreateSimple(tmpstr);
XmFileSelectionDoSearch(fsel_r, xmtmpstr);
XmStringFree(xmtmpstr);
XtFree(tmpstr);
s_d1 = XmStringCreateSimple("D1:");
s_d2 = XmStringCreateSimple("D2:");
s_d3 = XmStringCreateSimple("D3:");
s_d4 = XmStringCreateSimple("D4:");
s_d5 = XmStringCreateSimple("D5:");
s_d6 = XmStringCreateSimple("D6:");
s_d7 = XmStringCreateSimple("D7:");
s_d8 = XmStringCreateSimple("D8:");
eject_menu = XmVaCreateSimplePulldownMenu(system_menu,
"eject_disk", 2,
motif_eject_cback,
XmVaPUSHBUTTON, s_d1, '1', NULL, NULL,
XmVaPUSHBUTTON, s_d2, '2', NULL, NULL,
XmVaPUSHBUTTON, s_d3, '3', NULL, NULL,
XmVaPUSHBUTTON, s_d4, '4', NULL, NULL,
XmVaPUSHBUTTON, s_d5, '5', NULL, NULL,
XmVaPUSHBUTTON, s_d6, '6', NULL, NULL,
XmVaPUSHBUTTON, s_d7, '7', NULL, NULL,
XmVaPUSHBUTTON, s_d8, '8', NULL, NULL,
NULL);
disable_menu = XmVaCreateSimplePulldownMenu(system_menu,
"disable_disk", 3,
motif_disable_cback,
XmVaPUSHBUTTON, s_d1, '1', NULL, NULL,
XmVaPUSHBUTTON, s_d2, '2', NULL, NULL,
XmVaPUSHBUTTON, s_d3, '3', NULL, NULL,
XmVaPUSHBUTTON, s_d4, '4', NULL, NULL,
XmVaPUSHBUTTON, s_d5, '5', NULL, NULL,
XmVaPUSHBUTTON, s_d6, '6', NULL, NULL,
XmVaPUSHBUTTON, s_d7, '7', NULL, NULL,
XmVaPUSHBUTTON, s_d8, '8', NULL, NULL,
NULL);
XmStringFree(s_d1);
XmStringFree(s_d2);
XmStringFree(s_d3);
XmStringFree(s_d4);
XmStringFree(s_d5);
XmStringFree(s_d6);
XmStringFree(s_d7);
XmStringFree(s_d8);
drawing_area = XtVaCreateManagedWidget ("Canvas",
xmDrawingAreaWidgetClass, main_w,
XmNunitType, XmPIXELS,
XmNheight, window_height,
XmNwidth, window_width,
XmNresizePolicy, XmNONE,
NULL);
{
XKeyboardState state;
XGetKeyboardControl(XtDisplay(drawing_area), &state);
XCURRENTAUTOREPEAT=XTERNAUTOREPEAT=state.global_auto_repeat;
}
XtAddEventHandler (drawing_area,
KeyPressMask | KeyReleaseMask,
False,
motif_keypress, NULL);
XtAddEventHandler (drawing_area,
ExposureMask,
False,
motif_exposure, NULL);
XtAddEventHandler (drawing_area,
EnterWindowMask,
False,
motif_enter, NULL);
XtAddEventHandler (drawing_area,
LeaveWindowMask,
False,
motif_leave, NULL);
XtRealizeWidget (toplevel);
}
display = XtDisplay (drawing_area);
window = XtWindow (drawing_area);
screen = XDefaultScreenOfDisplay (display);
if (!screen)
{
printf ("Unable to get screen\n");
exit (1);
}
visual = XDefaultVisualOfScreen (screen);
if (!visual)
{
printf ("Unable to get visual\n");
exit (1);
}
depth = XDefaultDepthOfScreen (screen);
defcmap = XDefaultColormapOfScreen(screen);
if (private_cmap)
{
cmap = XCreateColormap (display,
window,
visual,
AllocNone);
XSetWindowColormap(display, window, cmap);
XInstallColormap(display, cmap);
}
else
cmap = defcmap;
#endif
#ifndef MOTIF
#ifndef XVIEW
display = XOpenDisplay (NULL);
if (!display)
{
printf ("Failed to open display\n");
exit (1);
}
screen = XDefaultScreenOfDisplay (display);
if (!screen)
{
printf ("Unable to get screen\n");
exit (1);
}
visual = XDefaultVisualOfScreen (screen);
if (!visual)
{
printf ("Unable to get visual\n");
exit (1);
}
depth = XDefaultDepthOfScreen (screen);
defcmap = XDefaultColormapOfScreen(screen);
if (private_cmap)
{
cmap = XCreateColormap (display,
XRootWindowOfScreen(screen),
visual,
AllocNone);
XInstallColormap(display, cmap);
}
else
cmap = XDefaultColormapOfScreen(screen);
xswda.event_mask = KeyPressMask | KeyReleaseMask | ExposureMask;
xswda.colormap = cmap;
window = XCreateWindow (display,
XRootWindowOfScreen(screen),
50, 50,
window_width, window_height, 3, depth,
InputOutput, visual,
CWEventMask | CWBackPixel | CWColormap,
&xswda);
XStoreName (display, window, ATARI_TITLE);
#endif
#endif
#ifdef SHM
{
int major;
int minor;
Bool pixmaps;
Status status;
status = XShmQueryVersion (display, &major, &minor, &pixmaps);
if (!status)
{
printf ("X Shared Memory extensions not available\n");
exit (1);
}
printf ("Using X11 Shared Memory Extensions\n");
image = XShmCreateImage (display, visual, depth, ZPixmap,
NULL, &shminfo, window_width, window_height);
shminfo.shmid = shmget (IPC_PRIVATE,
(ATARI_HEIGHT+16) * ATARI_WIDTH,
IPC_CREAT | 0777);
shminfo.shmaddr = image->data = atari_screen = shmat (shminfo.shmid, 0, 0);
shminfo.readOnly = False;
XShmAttach (display, &shminfo);
#ifndef NOSYNC
XSync (display, False);
#endif
shmctl (shminfo.shmid, IPC_RMID, 0);
}
#else
pixmap = XCreatePixmap (display, window,
window_width, window_height, depth);
#endif
/* ALLOCATE COLORS
- 1st: Allocate 128 colors to fill every second spot in the color
grid. Actually, that's 120, since hue 1 == hue 15
I NEED AT LEAST THAT MUCH
*/
for (i=0;i<256;i+=2)
{
XColor colour;
int rgb = colortable[i];
int status;
colour.red = (rgb & 0x00ff0000) >> 8;
colour.green = (rgb & 0x0000ff00);
colour.blue = (rgb & 0x000000ff) << 8;
status = XAllocColor (display,
cmap,
&colour);
if (status)
colours[i] = colour.pixel;
else
{
printf("Failed to get at least 120 different colors.\n"
"Try -private_cmap.\n");
exit(1);
}
}
/*
- 2nd: Allocate all the rest of hue 0 (b/w) and hue 1 (brown)
THESE ARE USED MOST OFTEN. BUT I DON'T REALLY NEED THEM.
*/
for (i=1; i<32; i+=2)
{
XColor colour;
int rgb = colortable[i];
int status;
colour.red = (rgb & 0x00ff0000) >> 8;
colour.green = (rgb & 0x0000ff00);
colour.blue = (rgb & 0x000000ff) << 8;
status = XAllocColor (display,
cmap,
&colour);
if (status)
colours[i]=colour.pixel;
else
{
colours[i]=colours[i-1];
missing_colors++;
}
}
/*
- 3rd: Try to allocate all the rest (odd) colors. Darkest Colors
first, since they are the most discernible.
*/
for (i=1; i<16; i+=2)
{
int hue;
for (hue=2; hue<16; hue++)
{
XColor colour;
int rgb = colortable[hue*16 +i];
int status;
colour.red = (rgb & 0x00ff0000) >> 8;
colour.green = (rgb & 0x0000ff00);
colour.blue = (rgb & 0x000000ff) << 8;
status = XAllocColor (display,
cmap,
&colour);
if (status)
colours[hue*16 + i] = colour.pixel;
else
{
colours[hue*16 + i] = colours[hue*16 +i -1];
missing_colors++;
}
}
}
/*
BTW: Contrary to public (and my prior) belief, the Atari had only
225 colors, NOT 255. Hue 1 == Hue 15. And Brightness 7 ==
Brightness 8.
*/
if (missing_colors)
printf("Missed %d of 225 colors. Winging it.\n"
"Try -private_cmap.\n",missing_colors);
#ifdef SHM
for(i=0;i<256;i++)
colour_translation_table[i] = colours[i];
#endif
for (i=0;i<256;i++)
{
xgcvl.background = colours[0];
xgcvl.foreground = colours[i];
gc_colour[i] = XCreateGC (display, window,
GCForeground | GCBackground,
&xgcvl);
}
xgcvl.background = colours[0];
xgcvl.foreground = colours[0];
gc = XCreateGC (display, window,
GCForeground | GCBackground,
&xgcvl);
#ifndef SHM
XFillRectangle (display, pixmap, gc, 0, 0,
window_width, window_height);
#endif
XMapWindow (display, window);
/* ============================
Find NUMLOCKMASK
============================
This is not currently needed, but it's interesting code, and could be
used later on. Essentially, we find the mask that tells us whether or
not the numlock key is lit (which is transmitted with each KeyPress Event).
*/
{
int symperkey;
int keys_min, keys_max;
KeySym *keysym;
XModifierKeymap *modkm;
KeyCode numlock =0x7e; /* default for NUMLOCK on my system */
XDisplayKeycodes(display, &keys_min, &keys_max);
keysym=XGetKeyboardMapping(display, keys_min, keys_max +1 -keys_min, &symperkey);
if (keysym)
{
int icode, isym;
for (icode=keys_min; icode <= keys_max; icode++)
for (isym=0; isym<symperkey; isym++)
if (keysym[(icode -keys_min) * symperkey + isym] == XK_Num_Lock)
numlock=icode;
}
XFree(keysym);
keysym=NULL;
modkm=XGetModifierMapping(display);
if (modkm)
{
int imod, icode;
for (imod=0; imod<8; imod++)
for (icode=0; icode<modkm->max_keypermod; icode++)
if ((modkm->modifiermap)[imod * modkm->max_keypermod + icode] == numlock)
NUMLOCKMASK=(1<<imod);
}
XFreeModifiermap(modkm);
modkm=NULL;
}
#ifndef NOSYNC
XSync (display, False);
#endif
/*
============================
Storage for Atari 800 Screen
============================
*/
image_data = (UBYTE*) malloc (ATARI_WIDTH * ATARI_HEIGHT);
if (!image_data)
{
printf ("Failed to allocate space for image\n");
exit (1);
}
/* Preparation for Atari_Scanline_Flush() */
switch(windowsize)
{
case Large:
for(i=0; i<NPOINTS; i++)
{
rectangles[i].width = 2;
rectangles[i].height = 2;
}
break;
case Huge:
for(i=0; i<NPOINTS; i++)
{
rectangles[i].width = 3;
rectangles[i].height = 3;
}
break;
default:
break;
}
keyboard_consol = 7;
menu_consol = 7;
if (x11bug)
{
printf ("Initial X11 controller configuration\n");
printf ("------------------------------------\n\n");
printf ("Keypad is "); Atari_WhatIs (keypad_mode); printf ("\n");
printf ("Mouse is "); Atari_WhatIs (mouse_mode); printf ("\n");
printf ("/dev/js0 is "); Atari_WhatIs (js0_mode); printf ("\n");
printf ("/dev/js1 is "); Atari_WhatIs (js1_mode); printf ("\n");
}
}
int Atari_Exit (int run_monitor)
{
int restart;
if (run_monitor)
{
#ifdef MOTIF
/* Don't know these, just using them to call motif_*() */
Widget w;
XtPointer client_data;
XEvent event;
Boolean ctd;
motif_leave(w, client_data, &event, &ctd);
#endif
restart = monitor();
#ifdef MOTIF
if (restart)
motif_enter(w, client_data, &event, &ctd);
#endif
}
else
restart = FALSE;
if (!restart)
{
if (XTERNAUTOREPEAT != XCURRENTAUTOREPEAT)
XAutoRepeatOn(display);
free (image_data);
XSync (display, True);
if (private_cmap)
{
XUninstallColormap(display,cmap);
XFreeColormap (display, cmap);
}
#ifdef SHM
XDestroyImage (image);
#else
XFreePixmap (display, pixmap);
#endif
XUnmapWindow (display, window);
XDestroyWindow (display, window);
XCloseDisplay (display);
display=NULL;
#ifdef LINUX_JOYSTICK
if (js0 != -1)
close (js0);
if (js1 != -1)
close (js1);
#endif
#ifdef NAS
NAS_Exit ();
#endif
#ifdef VOXWARE
Voxware_Exit ();
#endif
}
return restart;
}
#ifndef SHM
void Atari_ScanLine_Flush(void)
{
if (npoints)
{
switch(windowsize)
{
case Small:
XDrawPoints (display, pixmap, gc_colour[last_colour],
points, npoints, CoordModeOrigin);
break;
case Large:
case Huge:
XFillRectangles (display, pixmap, gc_colour[last_colour],
rectangles, npoints);
break;
}
npoints = 0;
modified = TRUE;
}
last_colour = -1;
}
#endif
void ScreenDump ()
{
char *tmp_file_name=tempnam(NULL, "asd");
char command[1028];
static int frame_num = 0;
unsigned char *ip;
FILE *tf;
if (!tmp_file_name)
return; /* error */
tf=fopen(tmp_file_name, "w");
if (!tf)
return; /* error */
/* Write a ppm file */
fprintf(tf, "P6\n%u %d\n255\n", ATARI_WIDTH, ATARI_HEIGHT);
for (ip=image_data; ip< image_data + ATARI_WIDTH * ATARI_HEIGHT; ip++)
fprintf(tf, "%c%c%c", (colortable[*ip] & 0xff0000) >> 16,
(colortable[*ip] & 0xff00) >> 8, colortable[*ip] &0xff);
fclose(tf);
sprintf (command, "/bin/sh -pc 'ppmtogif %s > %d.gif 2>/dev/null'", tmp_file_name, frame_num++);
system (command);
unlink(tmp_file_name);
free(tmp_file_name);
}
void RebuildScreen(register UBYTE *screen)
{
UBYTE *scanline_ptr = image_data;
register int xpos;
register int ypos;
register UBYTE colour;
for (ypos=0;ypos<ATARI_HEIGHT;ypos++) {
for (xpos=0;xpos<ATARI_WIDTH;xpos++) {
colour = *screen++;
if (colour != *scanline_ptr)
{
if ((npoints >= NPOINTS) || (colour != last_colour)) {
Atari_ScanLine_Flush();
last_colour = colour;
}
switch(windowsize) {
case Small:
points[npoints].x = xpos;
points[npoints].y = ypos;
break;
case Large:
rectangles[npoints].x = xpos << 1;
rectangles[npoints].y = ypos << 1;
break;
case Huge:
rectangles[npoints].x = xpos + xpos + xpos;
rectangles[npoints].y = ypos + ypos + ypos;
break;
}
npoints++;
*scanline_ptr++ = colour;
}
else
{
scanline_ptr++;
}
}
screen+=ATARI_EXTRA;
}
Atari_ScanLine_Flush ();
if (modified) {
XCopyArea (display, pixmap, window, gc, 0, 0,
window_width, window_height, 0, 0);
}
modified = FALSE;
}
void Atari_DisplayScreen (UBYTE *screen)
{
#ifndef NOSTATUS
static char status_line[64];
int update_status_line;
#endif
#ifdef SHM
XShmPutImage (display, window, gc, image, 0, 0, 0, 0,
window_width, window_height, 0);
XSync(display, FALSE);
#else
RebuildScreen(screen);
#endif
#ifndef NOSTATUS
switch (x11_monitor)
{
case MONITOR_SIO :
if (sio_status[0] != '\0')
{
#ifdef XVIEW
strcpy (status_line, sio_status);
#else
sprintf (status_line, "%s - %s",
ATARI_TITLE, sio_status);
#endif
sio_status[0] = '\0';
update_status_line = TRUE;
}
else
{
update_status_line = FALSE;
}
break;
case MONITOR_FPS :
{
double curtime;
gettimeofday (&tp, &tzp);
curtime = tp.tv_sec + (tp.tv_usec / 1000000.0);
nframes++;
if ((curtime - basetime) >= 2.0)
{
#ifdef XVIEW
sprintf (status_line, "%.2f FPS",
(double)nframes / (curtime - basetime));
#else
sprintf (status_line, " %s - %.2f FPS",
ATARI_TITLE, (double)nframes / (curtime - basetime));
#endif
nframes = 0;
basetime = curtime;
}
}
update_status_line = TRUE;
break;
default :
update_status_line = FALSE;
break;
}
if (update_status_line)
{
#ifdef XVIEW
xv_set (frame,
FRAME_LEFT_FOOTER, status_line,
NULL);
#else
#ifdef MOTIF
XtVaSetValues(toplevel,
XtNtitle, status_line,
NULL);
#else
XStoreName (display, window, status_line);
#endif
#endif
}
#endif
/* * this now moved to Atari_Keyboard () *
#ifdef XVIEW
notify_dispatch ();
XFlush (display);
#endif
#ifdef MOTIF
while (XtAppPending(app))
{
static XEvent event;
XtAppNextEvent (app, &event);
XtDispatchEvent (&event);
}
#endif
*/
#ifdef NAS
NAS_UpdateSound ();
#endif
#ifdef VOXWARE
Voxware_UpdateSound ();
#endif
if (screen_dump)
{
ScreenDump ();
if (screen_dump == 2)
screen_dump = 0;
}
}
int Atari_Keyboard (void)
{
int keycode = AKEY_NONE;
/* About XSync:
man XSync: ... Client applications seldom need to call XSync. ...
In fact, calling XSync() does slow it down on some systems,
especially if they were slow to begin with.
However, it DOES speed things up on MY system, which is already
fast. It has something to do with how long the connection between
caller and receiver is (so you should only do this if your DISPLAY
is the local machine...)
*/
#ifndef NOSYNC
XSync(display,False);
#endif
do /* PAUSE loop */
{
#ifndef SHM
if (modified)
XCopyArea (display, pixmap, window, gc, 0, 0,
window_width, window_height, 0, 0);
#endif
modified=FALSE;
#ifdef XVIEW
notify_dispatch ();
XFlush (display);
keycode = xview_keycode;
xview_keycode = AKEY_NONE;
#else
#ifdef MOTIF
while (XtAppPending(app))
{
static XEvent event;
XtAppNextEvent (app, &event);
XtDispatchEvent (&event);
}
keycode = xview_keycode;
xview_keycode = AKEY_NONE;
#else
while (XEventsQueued (display, QueuedAlready) > 0) /* QueuedAfterFlush */
{
XEvent event;
XNextEvent (display, &event);
keycode = GetKeyCode (&event);
}
#endif
#endif
} while (paused);
return keycode;
}
void mouse_joystick (int mode)
{
Window root_return;
Window child_return;
int root_x_return;
int root_y_return;
int win_x_return;
int win_y_return;
unsigned int mask_return;
mouse_stick = 0x0f;
XQueryPointer (display, window, &root_return, &child_return,
&root_x_return, &root_y_return,
&win_x_return, &win_y_return,
&mask_return);
if (mode < 5)
{
int center_x;
int center_y;
int threshold;
if (windowsize == Small)
{
center_x = ATARI_WIDTH / 2;
center_y = ATARI_HEIGHT / 2;
threshold = 32;
}
else if (windowsize == Large)
{
center_x = (ATARI_WIDTH * 2) / 2;
center_y = (ATARI_HEIGHT * 2) / 2;
threshold = 64;
}
else
{
center_x = (ATARI_WIDTH * 3) / 2;
center_y = (ATARI_HEIGHT * 3) / 2;
threshold = 96;
}
if (win_x_return < (center_x - threshold))
mouse_stick &= 0xfb;
if (win_x_return > (center_x + threshold))
mouse_stick &= 0xf7;
if (win_y_return < (center_y - threshold))
mouse_stick &= 0xfe;
if (win_y_return > (center_y + threshold))
mouse_stick &= 0xfd;
}
else
{
if (mask_return)
mouse_stick &= 0xfb;
}
}
#ifdef LINUX_JOYSTICK
void read_joystick (int js, int centre_x, int centre_y)
{
const int threshold = 50;
int status;
mouse_stick = 0x0f;
status = read (js, &js_data, JS_RETURN);
if (status != JS_RETURN)
{
perror ("/dev/js");
exit (1);
}
if (js_data.x < (centre_x - threshold))
mouse_stick &= 0xfb;
if (js_data.x > (centre_x + threshold))
mouse_stick &= 0xf7;
if (js_data.y < (centre_y - threshold))
mouse_stick &= 0xfe;
if (js_data.y > (centre_y + threshold))
mouse_stick &= 0xfd;
}
#endif
/* The scheme is from xkobo, which has great keypad control */
unsigned char keypad_stick()
{
static unsigned char stick=STICK_CENTRE;
if (keypad_changed)
{
int lr;
int ud;
keypad_changed=0;
lr=keypad_l +keypad_ul +keypad_dl -keypad_r -keypad_ur -keypad_dr;
ud=keypad_u +keypad_ul +keypad_ur -keypad_d -keypad_dl -keypad_dr;
if (!lr)
{
if (!ud) stick= STICK_CENTRE;
else if (ud > 0) stick= STICK_FORWARD;
else stick= STICK_BACK;
}
else if (lr > 0)
{
if (!ud) stick= STICK_LEFT;
else if (ud > 0) stick= STICK_UL;
else stick= STICK_LL;
}
else
{
if (!ud) stick= STICK_RIGHT;
else if (ud > 0) stick= STICK_UR;
else stick= STICK_LR;
}
}
return stick;
}
int Atari_PORT (int num)
{
int nibble_0 = 0x0f;
int nibble_1 = 0x0f;
if (num == 0)
{
if (keypad_mode == 0)
nibble_0 = keypad_stick();
else if (keypad_mode == 1)
nibble_1 = keypad_stick();
if (mouse_mode == 0)
{
mouse_joystick (mouse_mode);
nibble_0 = mouse_stick;
}
else if (mouse_mode == 1)
{
mouse_joystick (mouse_mode);
nibble_1 = mouse_stick;
}
#ifdef LINUX_JOYSTICK
if (js0_mode == 0)
{
read_joystick (js0, js0_centre_x, js0_centre_y);
nibble_0 = mouse_stick;
}
else if (js0_mode == 1)
{
read_joystick (js0, js0_centre_x, js0_centre_y);
nibble_1 = mouse_stick;
}
if (js1_mode == 0)
{
read_joystick (js1, js1_centre_x, js1_centre_y);
nibble_0 = mouse_stick;
}
else if (js1_mode == 1)
{
read_joystick (js1, js1_centre_x, js1_centre_y);
nibble_1 = mouse_stick;
}
#endif
}
else
{
if (keypad_mode == 2)
nibble_0 = keypad_stick();
else if (keypad_mode == 3)
nibble_1 = keypad_stick();
if (mouse_mode == 2)
{
mouse_joystick (mouse_mode);
nibble_0 = mouse_stick;
}
else if (mouse_mode == 3)
{
mouse_joystick (mouse_mode);
nibble_1 = mouse_stick;
}
#ifdef LINUX_JOYSTICK
if (js0_mode == 2)
{
read_joystick (js0, js0_centre_x, js0_centre_y);
nibble_0 = mouse_stick;
}
else if (js0_mode == 3)
{
read_joystick (js0, js0_centre_x, js0_centre_y);
nibble_1 = mouse_stick;
}
if (js1_mode == 2)
{
read_joystick (js1, js1_centre_x, js1_centre_y);
nibble_0 = mouse_stick;
}
else if (js1_mode == 3)
{
read_joystick (js1, js1_centre_x, js1_centre_y);
nibble_1 = mouse_stick;
}
#endif
}
return (nibble_1 << 4) | nibble_0;
}
int Atari_TRIG (int num)
{
int trig = 1; /* Trigger not pressed */
if (num == keypad_mode)
{
trig = keypad_trig;
}
if (num == mouse_mode)
{
Window root_return;
Window child_return;
int root_x_return;
int root_y_return;
int win_x_return;
int win_y_return;
unsigned int mask_return;
if (XQueryPointer (display, window, &root_return, &child_return,
&root_x_return, &root_y_return,
&win_x_return, &win_y_return,
&mask_return))
{
if (mask_return)
trig = 0;
}
}
#ifdef LINUX_JOYSTICK
if (num == js0_mode)
{
int status;
status = read (js0, &js_data, JS_RETURN);
if (status != JS_RETURN)
{
perror ("/dev/js0");
exit (1);
}
if (js_data.buttons & 0x01)
trig = 0;
else
trig = 1;
if (js_data.buttons & 0x02)
xview_keycode = AKEY_SPACE;
}
if (num == js1_mode)
{
int status;
status = read (js1, &js_data, JS_RETURN);
if (status != JS_RETURN)
{
perror ("/dev/js1");
exit (1);
}
trig = (js_data.buttons & 0x0f) ? 0 : 1;
}
#endif
return trig;
}
int Atari_POT (int num)
{
int pot;
if (num == (mouse_mode - 4))
{
Window root_return;
Window child_return;
int root_x_return;
int root_y_return;
int win_x_return;
int win_y_return;
unsigned int mask_return;
if (XQueryPointer (display, window, &root_return,
&child_return, &root_x_return, &root_y_return,
&win_x_return, &win_y_return, &mask_return))
{
switch (windowsize)
{
case Small:
pot = ((float)((ATARI_WIDTH) - win_x_return) /
(float)(ATARI_WIDTH)) * 228;
break;
case Large:
pot = ((float)((ATARI_WIDTH * 2) - win_x_return) /
(float)(ATARI_WIDTH * 2)) * 228;
break;
default:
pot = ((float)((ATARI_WIDTH * 3) - win_x_return) /
(float)(ATARI_WIDTH * 3)) * 228;
break;
}
}
else
{
pot = 228;
}
}
else
{
pot = 228;
}
return pot;
}
int Atari_CONSOL (void)
{
int temp;
if (menu_consol != 7)
{
temp = menu_consol;
menu_consol = 0x07;
}
else
{
temp = keyboard_consol;
}
return temp;
}
UBYTE Atari_Keyboard_State(void)
{
return ~((SHIFTPRESSED<<3) | (KEYPRESSED<<2));
}
#define USE_LED 3 /* Use 1..32. 3 might be SCROLL_LOCK */
void Atari_Set_LED(int on)
{
XKeyboardControl control={0, 0, 0, 0,
1<<(USE_LED-1), (on ? LedModeOn : LedModeOff),
0, 0};
XChangeKeyboardControl(display, KBLed | KBLedMode, &control);
}