apple2ix/src/interface.c
2013-06-11 00:08:15 -07:00

1230 lines
31 KiB
C

/*
* Apple // emulator for Linux: Configuration Interface
*
* Copyright 1994 Alexander Jean-Claude Bottema
* Copyright 1995 Stephen Lee
* Copyright 1997, 1998 Aaron Culliney
* Copyright 1998, 1999, 2000 Michael Deutschmann
*
* This software package is subject to the GNU General Public License
* version 2 or later (your choice) as published by the Free Software
* Foundation.
*
* THERE ARE NO WARRANTIES WHATSOEVER.
*
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <dirent.h>
#include <termios.h>
#include <errno.h>
#include "interface.h"
#include "keys.h"
#include "disk.h"
#include "misc.h"
#include "video.h"
#include "cpu.h"
#include "prefs.h"
static struct stat statbuf;
static int altdrive;
/*#define undoc_supported 1*/
/*#else*/
/*#define undoc_supported 0*/
#ifdef APPLE_IIE
#define iie_supported 1
#else
#define iie_supported 0
#endif
static void pad_string(char *s, char c, int len) {
char *p;
for (p = s; ((*p != '\0') && (p-s < len-1)); p++);
while (p-s < len-1) {
*p++ = c;
}
*p = '\0';
}
/* in keys.c */
//extern void c_mouse_close();
/* from joystick.c */
#ifdef PC_JOYSTICK
extern int c_open_joystick();
extern void c_calculate_joystick_parms();
extern void c_close_joystick();
extern void c_calibrate_joystick();
extern long js_timelimit;
#endif
/* -------------------------------------------------------------------------
c_load_interface_font()
------------------------------------------------------------------------- */
void c_load_interface_font()
{
/* Only codes 0x20 -- 0x8A are actually used. But I feel safer
* explicitly initializing all of them.
*/
video_loadfont_int(0x00,0x40,ucase_glyphs);
video_loadfont_int(0x40,0x20,ucase_glyphs);
video_loadfont_int(0x60,0x20,lcase_glyphs);
video_loadfont_int(0x80,0x40,ucase_glyphs);
video_loadfont_int(0xC0,0x20,ucase_glyphs);
video_loadfont_int(0xE0,0x20,lcase_glyphs);
video_loadfont_int(0x80,11,interface_glyphs);
}
/* -------------------------------------------------------------------------
c_interface_print()
------------------------------------------------------------------------- */
void c_interface_print( int x, int y, int cs, unsigned char *s )
{
int i;
for (i = x; *s; i++, s++)
video_plotchar( i, y, cs, *s );
}
/* -------------------------------------------------------------------------
c_interface_redo_bottom()
------------------------------------------------------------------------- */
void c_interface_redo_bottom() {
c_interface_print( 1, 21, 2,
" Use arrow keys (or Return) to modify "
);
c_interface_print( 1, 22, 2,
" parameters. (Press ESC to exit menu) "
);
}
/* -------------------------------------------------------------------------
c_interface_redo_diskette_bottom()
------------------------------------------------------------------------- */
void c_interface_redo_diskette_bottom() {
c_interface_print( 1, 21, 2,
" Move: Arrows, PGUP, PGDN, HOME, END. "
);
c_interface_print( 1, 22, 2,
" Return and 'w' select, ESC cancels. "
);
}
/* -------------------------------------------------------------------------
c_interface_translate_screen()
------------------------------------------------------------------------- */
#define IsGraphic(c) ((c) == '|' || ((c) >= 0x80 && (c) <= 0x8A))
#define IsInside(x,y) ((x) >= 0 && (x) <= 39 && (y) >= 0 && (y) <= 23)
void c_interface_translate_screen( unsigned char screen[24][41] )
{
static char map[11][3][4] ={ { "...",
".||",
".|." },
{ "...",
"||.",
".|." },
{ ".|.",
".||",
"..." },
{ ".|.",
"||.",
"..." },
{ ".|.",
".|.",
".|." },
{ "...",
"|||",
"..." },
{ ".|.",
".||",
".|." },
{ ".|.",
"||.",
".|." },
{ "...",
"|||",
".|." },
{ ".|.",
"|||",
"..." },
{ ".|.",
"|||",
".|." } };
int x, y, i, j, k;
for (y = 0; y < 24; y++)
for (x = 0; x < 40; x++)
{
if (screen[ y ][ x ] == '|')
{
int flag = 0;
for (k = 10; !flag && k >= 0; flag ? : k--)
{
flag = 1;
for (i = y - 1; flag && i <= y + 1; i++)
for (j = x - 1; flag && j <= x + 1; j++)
if (IsInside(j, i))
if (!(IsGraphic( screen[ i ][ j ])) &&
(map[k][ i - y + 1 ][ j - x + 1 ] == '|'))
flag = 0;
else;
else
if (map[k][ i - y + 1 ][ j - x + 1 ] == '|')
flag = 0;
}
if (flag)
screen[ y ][ x ] = 0x80 + k;
}
}
}
int c_interface_cut_name(char *name)
{
char *p = name + strlen(name) - 1;
int is_gz = 0;
if (p >= name && *p == 'z')
{
p--;
if (p >= name && *p == 'g')
{
p--;
if (p >= name && *p == '.') {
*p-- = '\0';
is_gz = 1;
}
}
}
return is_gz;
}
void c_interface_cut_gz(char *name)
{
char *p = name + strlen(name) - 1;
p--;
p--;
*p = '\0';
}
#define GZ_EXT ".gz"
#define GZ_EXT_LEN 3
#define DISK_EXT ".dsk"
#define DISK_EXT2 ".nib"
#define DISK_EXT_LEN 4
/* does name end with ".gz" ? */
int c_interface_is_gz(const char *name)
{
size_t len = strlen( name );
if (len > GZ_EXT_LEN) { /* shouldn't have a file called ".gz"... */
/*name += len - GZ_EXT_LEN;*/
return ((strcmp(name+len-GZ_EXT_LEN, GZ_EXT) == 0) ? 1 : 0);
}
return 0;
}
/* does name end with ".nib{.gz}" */
int c_interface_is_nibblized(const char *name)
{
size_t len = strlen( name );
if (c_interface_is_gz(name))
len -= GZ_EXT_LEN;
if (!strncmp(name + len - DISK_EXT_LEN, DISK_EXT2, DISK_EXT_LEN))
return 1;
return 0;
}
int c_interface_disk_select(const struct dirent *e)
{
static char cmp[ DISKSIZE ];
size_t len;
const char *p;
strncpy( cmp, disk_path, DISKSIZE );
strncat( cmp, "/", DISKSIZE );
strncat( cmp, e -> d_name, DISKSIZE );
/* don't show disk in alternate drive */
if (!strcmp(cmp, disk6.disk[altdrive].file_name))
return 0;
/* show directories except '.' and '..' at toplevel. */
stat(cmp, &statbuf);
if (S_ISDIR(statbuf.st_mode) && strcmp(".", e->d_name) &&
!(!strcmp("..", e->d_name) && !strcmp(disk_path, "/")))
return 1;
p = e->d_name;
len = strlen(p);
if (len > GZ_EXT_LEN && (!strcmp(p + len - GZ_EXT_LEN, GZ_EXT))) {
len -= GZ_EXT_LEN;
}
/* true if .dsk or .nib extension */
if (!strncmp(p + len - DISK_EXT_LEN, DISK_EXT, DISK_EXT_LEN))
return 1;
if (!strncmp(p + len - DISK_EXT_LEN, DISK_EXT2, DISK_EXT_LEN))
return 1;
return 0;
}
/* -------------------------------------------------------------------------
c_interface_exit()
------------------------------------------------------------------------- */
void c_interface_exit()
{
video_setpage(!!(softswitches & SS_SCREEN));
video_redraw();
}
/* -------------------------------------------------------------------------
c_interface_select_diskette()
------------------------------------------------------------------------- */
void c_interface_select_diskette( int drive )
{
static unsigned char screen[24][41] =
{ "||||||||||||||||||||||||||||||||||||||||",
"| Insert diskette into Drive _, Slot 6 |",
"||||||||||||||||||||||||||||||||||||||||",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"||||||||||||||||||||||||||||||||||||||||",
"| Move: Arrows, PGUP, PGDN, HOME, END. |",
"| Return and 'w' select, ESC cancels. |",
"||||||||||||||||||||||||||||||||||||||||" };
struct dirent **namelist;
int i, entries;
pid_t pid;
static int curpos=0;
int ch;
screen[ 1 ][ 29 ] = (drive == 0) ? 'A' : 'B';
video_setpage( 0 );
c_interface_translate_screen( screen );
NEXTDIR:
for (i = 0; i < 24; i++)
c_interface_print( 0, i, 2, screen[ i ] );
altdrive = (drive == 0) ? 1 : 0;
if (!strcmp("", disk_path))
sprintf(disk_path, "/");
/* set to users privilege level for directory access */
entries = scandir(disk_path, &namelist,
c_interface_disk_select, alphasort);
if (entries <= 0) {
/* 1/17/97 NOTE: scandir (libc5.3.12) seems to freak on broken
symlinks. so you won't be able to read from some
legitimate directories... */
c_interface_print( 6, 11, 0, "Problem reading directory!" );
sprintf(disk_path, "/");
usleep(1500000);
c_interface_exit();
return;
}
if (curpos >= entries)
curpos = entries - 1;
for (;;) {
for (i = 0; i < 17; i++) {
int ent_no = curpos - 8 + i, slen;
int in_drive = 0;
strcpy( temp, " " );
if (ent_no >= 0 && ent_no < entries) {
snprintf(temp, TEMPSIZE, "%s/%s",
disk_path, namelist[ent_no]->d_name);
if (!strcmp(temp, disk6.disk[drive].file_name))
in_drive = 1;
stat(temp, &statbuf);
if (S_ISDIR(statbuf.st_mode))
snprintf(temp, TEMPSIZE, " %s/",
namelist[ ent_no ] -> d_name );
else
snprintf(temp, TEMPSIZE, " %s",
namelist[ ent_no ] -> d_name );
if (c_interface_cut_name(temp)) {
strncat(temp, " <gz>", TEMPSIZE);
}
/* write protected disk in drive? */
else if ((in_drive) && (disk6.disk[drive].protected))
strncat(temp, (drive == 0) ? " <r1>" : " <r2>", TEMPSIZE);
else if (in_drive)
strncat(temp, (drive == 0) ? " <rw1>" : " <rw2>", TEMPSIZE);
}
slen = strlen( temp );
while (slen < 38)
temp[ slen++ ] = ' ';
temp[ 38 ] = '\0';
c_interface_print(1, i + 3, ent_no == curpos, temp);
}
do
{
ch = c_mygetch(1);
}
while (ch == -1);
if (ch == kUP) /* Arrow up */
if (curpos > 0)
curpos--;
else;
else if (ch == kDOWN) /* Arrow down */
if (curpos < entries - 1)
curpos++;
else;
else if (ch == kPGDN) /* Page down */
{
curpos += 16;
if (curpos > entries - 1)
curpos = entries - 1;
}
else if (ch == kPGUP) /* Page up */
{
curpos -= 16;
if (curpos < 0)
curpos = 0;
}
else if (ch == kHOME) /* Home */
curpos = 0;
else if (ch == kEND) /* End */
curpos = entries - 1;
else if (ch == kESC) /* ESC */
{
for (i = 0; i < entries; i++)
free(namelist[ i ]);
free(namelist);
c_interface_exit();
return;
}
else if ((ch == 13) || (toupper(ch) == 'W')) /* Return */
{
int len, cmpr = 0;
snprintf(temp, TEMPSIZE, "%s/%s",
disk_path, namelist[ curpos ] -> d_name );
len = strlen(disk_path);
/* handle disk currently in the drive */
if (!strcmp(temp, disk6.disk[drive].file_name)) {
/* reopen disk, forcing write enabled */
if (toupper(ch) == 'W') {
if (c_new_diskette_6(
drive,
temp,
disk6.disk[drive].compressed,
disk6.disk[drive].nibblized, 0))
{
c_interface_print( 1, 21, 0,
" Disk is read and write protected. " );
c_interface_print( 1, 22, 0,
" " );
usleep(1500000);
c_mygetch(1);
c_interface_redo_diskette_bottom();
continue;
}
for (i = 0; i < entries; i++)
free(namelist[ i ]); /* clean up */
free(namelist);
c_interface_exit(); /* resume emulation */
return;
}
/* eject the disk and start over */
c_eject_6(drive);
for (i = 0; i < entries; i++)
free(namelist[ i ]); /* clean up */
free(namelist);
goto NEXTDIR; /* I'm lazy */
}
/* read another directory */
stat(temp, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
if (toupper(ch) == 'W') continue;/* can't protect this */
if ((disk_path[len-1]) == '/') disk_path[--len] = '\0';
if (!strcmp("..", namelist[curpos]->d_name)) {
while (--len && (disk_path[len] != '/'))
disk_path[len] = '\0';
}
else if (strcmp(".", namelist[curpos]->d_name))
snprintf(disk_path + len, DISKSIZE-len, "/%s",
namelist[curpos]->d_name);
for (i = 0; i < entries; i++)
free(namelist[ i ]); /* clean up */
free(namelist);
goto NEXTDIR; /* I'm lazy */
}
/* uncompress the gziped disk */
if (c_interface_is_gz(temp))
{
if ((pid = fork())) { /* parent process */
c_interface_print( 1, 21, 0,
" Uncompressing... " );
c_interface_print( 1, 22, 0,
" " );
if (waitpid(pid, NULL, 0) == -1) {
c_interface_print( 1, 21, 0,
" Problem gunzip'ing " );
c_interface_print( 1, 22, 0,
" " );
usleep(1500000);
c_mygetch(1);
c_interface_redo_diskette_bottom();
continue;
}
} else if (!pid) { /* child process */
/* privileged mode - gzip in place */
if (execl("/bin/gzip", "/bin/gzip",
"-d", temp, NULL) == -1)
{
snprintf(temp, TEMPSIZE, "%s", sys_errlist[errno]);
perror("\tproblem");
c_interface_print( 1, 21, 0,
" Problem exec'ing /bin/gzip -d " );
c_interface_print( 1, 22, 0, temp);
usleep(1500000);
exit(-1);
}
} else {
snprintf(temp, TEMPSIZE, "%s", sys_errlist[errno]);
c_interface_print( 1, 21, 0,
" Cannot fork! " );
c_interface_print( 1, 22, 0, temp);
usleep(1500000);
c_mygetch(1);
c_interface_redo_diskette_bottom();
continue;
}
c_interface_cut_gz( temp );
cmpr = 1;
}
/* gzip the last disk */
if (disk6.disk[drive].compressed) {
/* gzip the last disk if it was compressed_6 */
if ((pid = fork())) { /* parent process */
/* privileged mode - gzip in place */
c_interface_print( 1, 21, 0,
" Compressing old diskette... " );
c_interface_print( 1, 22, 0,
" " );
if (waitpid(pid, NULL, 0) == -1) {
c_interface_print( 1, 21, 0,
" Problem gzip'ing " );
c_interface_print( 1, 22, 0,
" " );
usleep(1500000);
c_mygetch(1);
c_interface_redo_diskette_bottom();
continue;
}
} else if (!pid) { /* child process */
/* privileged mode - gzip in place */
if (execl("/bin/gzip", "/bin/gzip",
disk6.disk[drive].file_name, NULL) == -1)
{
c_interface_print( 1, 21, 0,
" Problem exec'ing /bin/gzip " );
c_interface_print( 1, 22, 0, temp);
usleep(1500000);
exit(-1);
}
} else {
snprintf(temp, TEMPSIZE, "%s", sys_errlist[errno]);
c_interface_print( 1, 21, 0,
" Cannot fork! " );
c_interface_print( 1, 22, 0, temp);
usleep(1500000);
c_mygetch(1);
c_interface_redo_diskette_bottom();
continue;
}
}
/* now try to change the disk */
if (c_new_diskette_6(
drive, temp, cmpr, c_interface_is_nibblized(temp),
(toupper(ch) != 'W')))
{
c_interface_print( 1, 21, 0,
" Disk is read and write protected. " );
c_interface_print( 1, 22, 0,
" " );
usleep(1500000);
c_mygetch(1);
c_interface_redo_diskette_bottom();
continue;
}
for (i = 0; i < entries; i++)
free(namelist[ i ]); /* clean up */
free(namelist);
c_interface_exit(); /* resume emulation */
return;
}
}
}
/* -------------------------------------------------------------------------
c_interface_parameters()
------------------------------------------------------------------------- */
#define NUM_OPTIONS 14
#define SAVE_SETTINGS 12
#define QUIT_EMULATOR 13
#define PATH_OPTION 1
#define CALIBRATE_OPTION 6
void c_interface_parameters()
{
static unsigned char screen[24][41] =
{ "||||||||||||||||||||||||||||||||||||||||",
"| Apple II Emulator for Linux |",
"| Originally by |",
"| Alexander Jean-Claude Bottema |",
"||||||||||||||||||||||||||||||||||||||||",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"| |",
"||||||||||||||||||||||||||||||||||||||||",
"| F1 F2: Slot6 Drive A, Drive B |",
"| F4 : Pause Emulation |",
"| F5 : Keyboard Layout |",
"| F9 : Toggle Max Speed |",
"| F10 : This Menu |",
"||||||||||||||||||||||||||||||||||||||||",
"| Use arrow keys (or Return) to modify |",
"| parameters. (Press ESC to exit menu) |",
"||||||||||||||||||||||||||||||||||||||||" };
static char *options[NUM_OPTIONS] =
{ " Speed : ", /* 0 */
" Path : ",
" Mode : ",
" Color : ",
" Sound : ",
" Joystick : ", /* 5 */
" Calibrate ",
" JS Range : ",
" Origin X : ",
" Origin Y : ",
" JS Sens. : ", /* 10 */
" JS Sample: ",
" Save ",
" Quit " };
int i;
int ch;
static int option = 0;
static int cur_y = 0, cur_off = 0, cur_x = 0, cur_pos = 0;
int current_mode = apple_mode;
if (!iie_supported && (current_mode == 2))
current_mode = apple_mode = 0;
/* reset the x position, so we don't lose our cursor if path changes */
cur_x = 0;
video_setpage( 0 );
c_interface_translate_screen( screen );
for (i = 0; i < 24; i++)
c_interface_print( 0, i, 2,screen[ i ] );
for (;;) {
for (i = 0; i < 9; i++) {
cur_off = option - 8;
if (cur_off < 0) cur_off = 0;
c_interface_print( 1, 5 + i, cur_y == i, options[ i + cur_off ] );
switch (i + cur_off)
{
case 0:
snprintf(temp, TEMPSIZE, "%03d",
MAX_APPLE_DELAY + 1 - cpu65_delay);
break;
case 1:
strncpy(temp, disk_path + cur_pos, 24);
temp[24] = '\0';
break;
case 2:
#ifdef APPLE_IIE
sprintf(temp, "%s", (apple_mode == 0) ? "][+ " :
(apple_mode == 1) ? "][+ undocumented" :
"//e ");
#else
sprintf(temp, "%s", (apple_mode == 0) ? "][+ " :
"][+ undocumented");
#endif
break;
case 3:
sprintf(temp, "%s", (color_mode == 0) ? "Black/White " :
(color_mode == 1) ? "Lazy Color " :
(color_mode == 2) ? "Color " :
(color_mode == 3) ? "Lazy Interp." :
"Interpolated");
break;
case 4:
sprintf(temp, "%s", (sound_mode == 0) ? "Off " :
"PC speaker");
break;
case 5:
sprintf(temp, "%s", (joy_mode == JOY_KYBD) ? "Linear " :
(joy_mode == JOY_DIGITAL) ? "Digital " :
(joy_mode == JOY_PCJOY) ? "PC Joystick" :
"Off ");
break;
case 6: /* calibrate joystick */
strcpy( temp, "" );
break;
case 7:
sprintf(temp, "%02x", joy_range);
break;
case 8:
sprintf(temp, "%02x", joy_center_x);
break;
case 9:
sprintf(temp, "%02x", joy_center_y);
break;
case 10:
sprintf(temp, "%03d%%", joy_step );
break;
case 11:
#ifdef PC_JOYSTICK
sprintf(temp, "%ld", js_timelimit);
#else
sprintf(temp, "%s", "");
#endif
break;
case SAVE_SETTINGS: /* save settings */
strcpy( temp, "" );
break;
case QUIT_EMULATOR: /* quit emulator */
strcpy( temp, "" );
break;
default:
break;
}
pad_string(temp, ' ', 26);
if (i+cur_off != 1)
c_interface_print(14, 5 + i, 0, temp);
else {
int j;
for (j = 0; j < 24; j++)
if (cur_x != j)
{
if (temp[ j ] == '\0')
{
video_plotchar( 14 + j, 5+i, 0, ' ' );
j++;
break;
}
else
video_plotchar( 14 + j, 5+i, 0, temp[ j ] );
}
else
{
if (temp[ j ] == '\0')
{
video_plotchar( 14 + j, 5+i, option==1,' ' );
j++;
break;
}
else
video_plotchar( 14 + j, 5+i, option==1,
temp[ j ]);
}
for (; j < 24; j++)
video_plotchar( 14 + j, 5+i, 0, ' ' );
}
}
do
{
ch = c_mygetch(1);
}
while (ch == -1);
if (ch == kUP) { /* Arrow up */
if (option > 8) {
option--; /* only dec option */
} else if (option > 0) {
option--; /* dec option */
cur_y--; /* and dec y position */
} else {
option = NUM_OPTIONS-1; /* wrap to last option */
cur_y = 8; /* wrap to last y position */
}
}
else if (ch == kDOWN) { /* Arrow down */
if (cur_y < 8) {
option++; /* inc option */
cur_y++; /* and inc y position */
} else if (option < NUM_OPTIONS-1) {
option++; /* only inc option */
} else {
cur_y = option = 0; /* wrap both to first */
}
}
else if (ch == kLEFT) { /* Arrow left */
switch (option) {
case 0: /* inc speed */
if (cpu65_delay < MAX_APPLE_DELAY)
cpu65_delay++;
break;
case 1: /* path */
if (cur_x > 0)
cur_x--;
else
if (cur_pos > 0)
cur_pos--;
break;
case 2: /* apple mode */
apple_mode--;
if (apple_mode < 0)
apple_mode = 2;
if ((apple_mode == 2) && !iie_supported)
apple_mode = 1;
break;
case 3: /* color mode */
if (color_mode == 0)
color_mode = 4;
else
--color_mode;
break;
case 4: /* sound mode */
if (sound_mode == 0)
sound_mode = 1;
else
--sound_mode;
break;
case 5: /* joystick mode */
#ifdef PC_JOYSTICK
if (joy_mode == 0)
joy_mode = 3;
#else
if (joy_mode == 0)
joy_mode = 2;
#endif
else
--joy_mode;
break;
case 6: /* calibrate */
break;
case 7: /* range */
if (joy_range > 10) {
--joy_range;
joy_center_x = joy_range/2;
joy_center_y = joy_range/2;
}
break;
case 8: /* origin x */
if (joy_center_x > 0)
joy_center_x--;
break;
case 9: /* origin y */
if (joy_center_y > 0)
joy_center_y--;
break;
case 10: /* sensitivity */
if (joy_step > 1)
joy_step--;
break;
case 11:
#ifdef PC_JOYSTICK
if (js_timelimit > 2) /* joystick sample rate */
--js_timelimit;
#endif
break;
case SAVE_SETTINGS: /* save settings */
case QUIT_EMULATOR: /* quit emulator */
break;
}
}
else if (ch == kRIGHT) { /* Arrow right */
switch (option) {
case 0: /* dec speed */
if (cpu65_delay > 1)
cpu65_delay--;
break;
case 1: /* path */
if (cur_x < 23)
{
if (disk_path[cur_pos + cur_x] != '\0')
cur_x++;
}
else
if (disk_path[cur_pos + cur_x] != '\0')
cur_pos++;
break;
case 2: /* apple mode */
apple_mode++;
if (apple_mode > 2)
apple_mode = 0;
if ((apple_mode == 2) && !iie_supported)
apple_mode = 0;
break;
case 3: /* color mode */
color_mode++;
if (color_mode > 4)
color_mode = 0;
break;
case 4: /* sound mode */
sound_mode++;
if (sound_mode > 1)
sound_mode = 0;
break;
case 5: /* joystick mode */
#ifdef PC_JOYSTICK
if (joy_mode == 3)
joy_mode = 0;
#else
if (joy_mode == 2)
joy_mode = 0;
#endif
else
++joy_mode;
break;
case 6: /* calibrate */
break;
case 7: /* range */
if (joy_range < 256) {
++joy_range;
joy_center_x = joy_range/2;
joy_center_y = joy_range/2;
}
break;
case 8: /* origin x */
if (joy_center_x < joy_range-1)
joy_center_x++;
break;
case 9: /* origin y */
if (joy_center_y < joy_range-1)
joy_center_y++;
break;
case 10: /* sensitivity */
if (joy_step < 100)
joy_step++;
break;
case 11: /* joystick sample rate */
#ifdef PC_JOYSTICK
js_timelimit++;
#endif
break;
case SAVE_SETTINGS: /* save settings */
case QUIT_EMULATOR: /* quit emulator */
break;
}
}
else if (ch == kESC) { /* exit menu */
c_initialize_sound();
video_set(0); /* redo colors */
#ifdef PC_JOYSTICK
if (joy_mode == JOY_PCJOY) {
c_close_joystick(); /* close the joystick */
c_open_joystick(); /* reopen the joystick */
half_joy_range = joy_range/2;
c_calculate_joystick_parms();
} else {
c_close_joystick();
}
#endif
/* reboot machine if different */
if (current_mode != apple_mode)
cpu65_interrupt(RebootSig);
c_interface_exit();
return;
}
else {
/* got a normal character setting path */
if (ch >= ' ' && ch < 127 && option == PATH_OPTION) {
int i;
strncpy(temp, disk_path, TEMPSIZE);
for (i = strlen(temp); i >= cur_pos + cur_x; i--)
temp[ i + 1 ] = temp[ i ];
temp[ cur_pos + cur_x ] = ch;
strncpy(disk_path, temp, DISKSIZE);
if (cur_x < 23)
cur_x++;
else
if (disk_path[cur_pos + cur_x] != '\0')
cur_pos++;
}
/* Backspace or delete setting path */
if ((ch == 127 || ch == 8) && (cur_pos + cur_x - 1 >= 0) &&
(option == 1))
{
int i;
for (i = cur_pos + cur_x - 1; disk_path[ i ] != '\0'; i++)
disk_path[ i ] = disk_path[ i + 1 ];
if (cur_x > 0)
cur_x--;
else
if (cur_pos > 0)
cur_pos--;
}
#ifdef PC_JOYSTICK
/* calibrate joystick */
if ((ch == 13) && (option == CALIBRATE_OPTION)) {
c_calibrate_joystick();
}
#endif
/* save settings */
if ((ch == 13) && (option == SAVE_SETTINGS)) {
save_settings();
}
/* quit apple II simulator */
if (ch == 13 && option == QUIT_EMULATOR) {
int ch;
c_interface_print(
1, 22, 0, " Are you sure? (Y/N) " );
while ((ch = c_mygetch(1)) == -1) ;
ch = toupper(ch);
if (ch == 'Y')
{
c_eject_6( 0 );
c_eject_6( 1 );
#ifdef PC_JOYSTICK
c_close_joystick();
#endif
printf("Linux! ...and there were much rejoicing! "
"oyeeeeh...\n");
video_shutdown();
exit( 0 );
}
c_interface_print( 0, 22, 2, screen[ 22 ] );
}
}
}
}
#if 0
/* -------------------------------------------------------------------------
c_interface_words() - this is not valid anymore.
if anyone has his email, let the maintainer know!
------------------------------------------------------------------------- */
void c_interface_words()
{
static unsigned char screen[24][41] =
{ "||||||||||||||||||||||||||||||||||||||||",
"| Apple II+ Emulator Version 0.01 |",
"||||||||||||||||||||||||||||||||||||||||",
"| If you have problems with your |",
"| keyboard concerning the mapping of |",
"| various keys, please let me know. |",
"| I use a Swedish keyboard for myself |",
"| and the scancodes may differ from US |",
"| keyboards (or other countries as |",
"| well). Currently, my email address |",
"| is: d91a1bo@meryl.csd.uu.se. This |",
"| address is valid at least one more |",
"| year, i.e. as long as I am Computer |",
"| Science student at the University |",
"| of Uppsala. \"...and there were much |",
"| rejoicing! oyeeeeeh\" |",
"| |",
"| |",
"| |",
"| |",
"| / Alexander Oct 9 1994 |",
"||||||||||||||||||||||||||||||||||||||||",
"| (Press any key to exit) |",
"||||||||||||||||||||||||||||||||||||||||" };
int i;
video_setpage( 0 );
c_interface_translate_screen( screen );
for (i = 0; i < 24; i++)
c_interface_print( 0, i, 2, screen[ i ] );
while (c_mygetch(1) == -1) { }
c_interface_exit();
}
#endif /* if 0 */
/* -------------------------------------------------------------------------
c_interface_keyboard_layout()
------------------------------------------------------------------------- */
void c_interface_keyboard_layout()
{
static unsigned char screen1[24][41] =
{ "||||||||||||||||||||||||||||||||||||||||",
"| Apple II+ US Keyboard Layout |",
"||||||||||||||||||||||||||||||||||||||||",
"| |",
"| 1! 2\" 3# 4$ 5% 6& 7' 8( 9) 0 :* -= |",
"| Q W E R T Y U I O P@ CR |",
"| A S D F G H J K L ;+ <- ->|",
"| Z X C V B N^ M ,< .> /? |",
"| Where <- -> are the left and right |",
"| arrow keys respectively. |",
"| |",
"| Joystick emulation on numeric keypad |",
"| 7 8 9 for various directions. |",
"| 4 6 Press 5 to center linear |",
"| 1 2 3 joystick. |",
"| |",
"| Ctrl-PrintScrn/SysRq is REBOOT. |",
"| Ctrl-Pause/Break is RESET. |",
"| Pause/Break alone pauses emulation. |",
"| Alt Left and Alt Right are Apple |",
"| Keys (Joystick buttons 0 & 1). |",
"||||||||||||||||||||||||||||||||||||||||",
"| (Press any key to exit) |",
"||||||||||||||||||||||||||||||||||||||||" };
#ifdef APPLE_IIE
static unsigned char screen2[24][41] =
{ "||||||||||||||||||||||||||||||||||||||||",
"| Apple //e US Keyboard Layout |",
"||||||||||||||||||||||||||||||||||||||||",
"| |",
"|1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ dl|",
"| Q W E R T Y U I O P [{ ]} \\| |",
"|cp A S D F G H J K L ;: '\" CR |",
"|sh Z X C V B N M ,< .> /? sh |",
"|ctrl |",
"| |",
"| Where dl is DEL, cp is CAPS, CR is |",
"| RETURN, sh is SHIFT, ctrl is CONTROL.|",
"| Arrow keys are as is. |",
"| Joystick emulation is same as the |",
"| ][+. |",
"| |",
"| Ctrl-PrintScrn/SysRq is REBOOT. |",
"| Ctrl-Pause/Break is RESET. |",
"| Pause/Break alone pauses emulation. |",
"| Alt Left and Alt Right are Apple |",
"| Keys (Joystick buttons 0 & 1). |",
"||||||||||||||||||||||||||||||||||||||||",
"| (Press any key to exit) |",
"||||||||||||||||||||||||||||||||||||||||" };
#endif
int i;
video_setpage( 0 );
#ifdef APPLE_IIE
if (apple_mode == 2) {
c_interface_translate_screen(screen2);
for (i = 0; i < 24; i++)
c_interface_print( 0, i, 2, screen2[ i ] );
} else
#endif
{
c_interface_translate_screen(screen1);
for (i = 0; i < 24; i++)
c_interface_print( 0, i, 2, screen1[ i ] );
}
while (c_mygetch(1) == -1) { }
c_interface_exit();
}