diff options
author | Bardur Arantsson <bardur@scientician.net> | 2010-01-11 23:46:27 +0100 |
---|---|---|
committer | Bardur Arantsson <bardur@scientician.net> | 2010-01-11 23:46:28 +0100 |
commit | d829c88460b4d60ecc3a9f339dd57113c764cf80 (patch) | |
tree | 70857f09a01b3570c9c53960d49797007983a7dd /src | |
parent | bdfb7e6170baeceb3b79bcd8dad3b15f1a90051f (diff) |
Remove obsolete platforms/frontends.
Removed platforms/systems:
- OS/2
- RiscOS
- SVGALib
- IBM DOS
- VM/ESA (Vax)
- Amiga
- Acorn
- Dummy
- VMS
- Macintosh (non-Carbon)
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/config.h | 8 | ||||
-rw-r--r-- | src/externs.h | 4 | ||||
-rw-r--r-- | src/files.c | 9 | ||||
-rw-r--r-- | src/h-config.h | 46 | ||||
-rw-r--r-- | src/h-define.h | 34 | ||||
-rw-r--r-- | src/h-system.h | 11 | ||||
-rw-r--r-- | src/init2.c | 36 | ||||
-rw-r--r-- | src/loadsave.c | 12 | ||||
-rw-r--r-- | src/main-ami.c | 3250 | ||||
-rw-r--r-- | src/main-dmy.c | 315 | ||||
-rw-r--r-- | src/main-dos.c | 2417 | ||||
-rw-r--r-- | src/main-emx.c | 1268 | ||||
-rw-r--r-- | src/main-gcu.c | 12 | ||||
-rw-r--r-- | src/main-ibm.c | 1594 | ||||
-rw-r--r-- | src/main-lsl.c | 598 | ||||
-rw-r--r-- | src/main-mac.c | 5504 | ||||
-rw-r--r-- | src/main-ros.c | 8670 | ||||
-rw-r--r-- | src/main-sdl-iso.c | 14 | ||||
-rw-r--r-- | src/main-vme.c | 1198 | ||||
-rw-r--r-- | src/main.c | 150 | ||||
-rw-r--r-- | src/makefile.ami | 110 | ||||
-rw-r--r-- | src/makefile.dos | 169 | ||||
-rw-r--r-- | src/makefile.emx | 205 | ||||
-rw-r--r-- | src/makefile.gdb | 155 | ||||
-rw-r--r-- | src/makefile.ibm | 165 | ||||
-rw-r--r-- | src/makefile.lsl | 42 | ||||
-rw-r--r-- | src/makefile.my | 519 | ||||
-rw-r--r-- | src/makefile.ros | 159 | ||||
-rw-r--r-- | src/makefile.wat | 71 | ||||
-rw-r--r-- | src/object1.c | 6 | ||||
-rw-r--r-- | src/script.c | 21 | ||||
-rw-r--r-- | src/store.c | 5 | ||||
-rw-r--r-- | src/util.c | 33 |
34 files changed, 24 insertions, 26788 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 58d5c0e3..68c6a92b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,7 +24,7 @@ TOLUA_FILE(dungeon w_dun.c) # tome executable INCLUDE_DIRECTORIES(lua) -ADD_EXECUTABLE(tome main-gcu.c main-x11.c main-xaw.c main-sdl.c main-dmy.c +ADD_EXECUTABLE(tome main-gcu.c main-x11.c main-xaw.c main-sdl.c z-rand.c z-util.c z-form.c z-virt.c z-term.c z-sock.c variable.c tables.c plots.c util.c cave.c dungeon.c melee1.c melee2.c modules.c diff --git a/src/config.h b/src/config.h index d626062a..23b3c1e4 100644 --- a/src/config.h +++ b/src/config.h @@ -37,7 +37,7 @@ * The old "USE_NCU" option has been replaced with "USE_GCU". * * Several other such options are available for non-unix machines, - * such as "MACINTOSH", "WINDOWS", "USE_IBM", "USE_EMX". + * such as "MACINTOSH", "WINDOWS". * * You may also need to specify the "system", using defines such as * "SOLARIS" (for Solaris), etc, see "h-config.h" for more info. @@ -73,7 +73,7 @@ * Currently used whenever available, if you get a warning about * "nodelay()" undefined, then make sure to undefine this. */ -#if defined(SYS_V) || defined(AMIGA) +#if defined(SYS_V) # define USE_GETCH #endif @@ -430,7 +430,7 @@ * player's name, it will then save the savefile elsewhere. Note that * this also gives a method of "bypassing" the "VERIFY_TIMESTAMP" code. */ -#if defined(MACINTOSH) || defined(WINDOWS) || defined(AMIGA) +#if defined(MACINTOSH) || defined(WINDOWS) /* #define SAVEFILE_MUTABLE */ #endif @@ -467,7 +467,7 @@ /* * Hack -- Special "ancient machine" versions */ -#if defined(USE_286) || defined(ANGBAND_LITE_MAC) +#if defined(ANGBAND_LITE_MAC) # ifndef ANGBAND_LITE # define ANGBAND_LITE # endif diff --git a/src/externs.h b/src/externs.h index 1777cf34..9021d291 100644 --- a/src/externs.h +++ b/src/externs.h @@ -1762,10 +1762,10 @@ extern u32b _ftype; /* extern int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, ...); */ #endif -#if !defined(WINDOWS) && !defined(MACINTOSH) && !defined(ACORN) +#if !defined(WINDOWS) && !defined(MACINTOSH) /* files.c */ extern bool chg_to_txt(cptr base, cptr newname); -#endif /* !WINDOWS && !MACINTOSH && !ACORN */ +#endif /* !WINDOWS && !MACINTOSH */ #ifdef ALLOW_REPEAT /* TNB */ diff --git a/src/files.c b/src/files.c index c3166f4a..792393e7 100644 --- a/src/files.c +++ b/src/files.c @@ -4606,7 +4606,7 @@ void html_screenshot(cptr name) * Because this is dead code and hardly anyone but DG needs it. * IMHO this should never been included in the game code -- pelpel */ -#if !defined(WINDOWS) && !defined(MACINTOSH) && !defined(ACORN) +#if !defined(WINDOWS) && !defined(MACINTOSH) #define KEY_NUM 9 static int keys_tab[KEY_NUM] = @@ -4744,7 +4744,7 @@ bool chg_to_txt(cptr base, cptr newname) return (TRUE); } -#endif /* !WINDOWS && !MACINTOSH && !ACORN */ +#endif /* !WINDOWS && !MACINTOSH */ /* * Peruse the On-Line-Help @@ -4781,11 +4781,6 @@ void process_player_base() (void)sprintf(temp, "%s", player_base); #endif -#ifdef VM - /* Hack -- support "flat directory" usage on VM/ESA */ - (void)sprintf(temp, "%s.sv", player_base); -#endif /* VM */ - /* Build the filename */ path_build(savefile, 1024, ANGBAND_DIR_SAVE, temp); } diff --git a/src/h-config.h b/src/h-config.h index 97120cd1..da68959d 100644 --- a/src/h-config.h +++ b/src/h-config.h @@ -32,24 +32,6 @@ /* #define WINDOWS */ #endif -#ifdef USE_IBM - - /* - * OPTION: Compile on an IBM (automatic) - */ - #ifndef MSDOS - #define MSDOS - #endif - - - /* Use the new SVGA code */ - #ifndef USE_IBM_SVGA - #define USE_IBM_SVGA - #endif - - -#endif - /* * OPTION: Compile on a SYS III version of UNIX */ @@ -130,15 +112,6 @@ #endif /* - * Extract the "ACORN" flag from the compiler - */ -#ifdef __riscos -# ifndef ACORN -# define ACORN -# endif -#endif - -/* * Extract the "SGI" flag from the compiler */ #ifdef sgi @@ -181,8 +154,7 @@ * or for the "Atari" platform which is Unix-like, apparently */ #if !defined(MACINTOSH) && !defined(WINDOWS) && \ - !defined(MSDOS) && !defined(USE_EMX) && \ - !defined(AMIGA) && !defined(ACORN) && !defined(VM) + !defined(MSDOS) && !defined(USE_EMX) # define SET_UID #endif @@ -210,8 +182,6 @@ * for various other systems. Note that any system that uses the * "period" as a separator (i.e. ACORN) will have to pretend that * it uses the slash, and do its own mapping of period <-> slash. - * Note that the VM system uses a "flat" directory, and thus uses - * the empty string for "PATH_SEP". */ #undef PATH_SEP #define PATH_SEP "/" @@ -227,18 +197,10 @@ # undef PATH_SEP # define PATH_SEP "\\" #endif -#ifdef AMIGA -# undef PATH_SEP -# define PATH_SEP "/" -#endif #ifdef __GO32__ # undef PATH_SEP # define PATH_SEP "/" #endif -#ifdef VM -# undef PATH_SEP -# define PATH_SEP "" -#endif /* @@ -298,10 +260,4 @@ # endif #endif -#ifdef USE_IBM - #ifndef HAS_USLEEP - #define HAS_USLEEP /* Set for gcc (djgpp-v2), TY */ - #endif -#endif - #endif diff --git a/src/h-define.h b/src/h-define.h index 777a5b8d..cb36b189 100644 --- a/src/h-define.h +++ b/src/h-define.h @@ -21,16 +21,6 @@ /* - * Hack -- assist "main-acn.c" XXX XXX XXX - */ -#ifdef ACORN -# define O_RDONLY 0 -# define O_WRONLY 1 -# define O_RDWR 2 -#endif - - -/* * Hack -- force definitions -- see fd_seek() */ #ifndef SEEK_SET @@ -105,28 +95,16 @@ /* - * Hack -- allow use of "ASCII" and "EBCDIC" for "indexes", "digits", - * and "Control-Characters". - * * Note that all "index" values must be "lowercase letters", while * all "digits" must be "digits". Control characters can be made * from any legal characters. XXX XXX XXX */ -#ifdef VM -# define A2I(X) alphatoindex(X) -# define I2A(X) indextoalpha(X) -# define D2I(X) ((X) - '0') -# define I2D(X) ((X) + '0') -# define KTRL(X) ((X) & 0x1F) -# define ESCAPE '\033' -#else -# define A2I(X) ((X) - 'a') -# define I2A(X) ((X) + 'a') -# define D2I(X) ((X) - '0') -# define I2D(X) ((X) + '0') -# define KTRL(X) ((X) & 0x1F) -# define ESCAPE '\033' -#endif +#define A2I(X) ((X) - 'a') +#define I2A(X) ((X) + 'a') +#define D2I(X) ((X) - '0') +#define I2D(X) ((X) + '0') +#define KTRL(X) ((X) & 0x1F) +#define ESCAPE '\033' #endif diff --git a/src/h-system.h b/src/h-system.h index 2d28e45d..465c3170 100644 --- a/src/h-system.h +++ b/src/h-system.h @@ -11,9 +11,6 @@ * * This file is a big hack to make other files less of a hack. * This file has been rebuilt -- it may need a little more work. - * - * It is (very) unlikely that VMS will work without help, primarily - * because VMS does not use the "ASCII" character set. */ @@ -58,8 +55,8 @@ # include <io.h> #endif -#if !defined(MACINTOSH) && !defined(AMIGA) && \ - !defined(ACORN) && !defined(VM) && !defined(__MWERKS__) +#if !defined(MACINTOSH) && \ + !defined(__MWERKS__) # if defined(__TURBOC__) || defined(__WATCOMC__) # include <mem.h> # else @@ -68,7 +65,7 @@ #endif -#if !defined(NeXT) && !defined(__MWERKS__) && !defined(ACORN) +#if !defined(NeXT) && !defined(__MWERKS__) # include <fcntl.h> #endif @@ -125,7 +122,7 @@ extern char *strrchr(); -#if !defined(linux) && !defined(__MWERKS__) && !defined(ACORN) +#if !defined(linux) && !defined(__MWERKS__) extern long atol(); #endif diff --git a/src/init2.c b/src/init2.c index 2d78b24e..7a66d09a 100644 --- a/src/init2.c +++ b/src/init2.c @@ -5,10 +5,10 @@ #include "angband.h" -#if !defined(MACINTOSH) && !defined(RISCOS) && defined(CHECK_MODIFICATION_TIME) +#if !defined(MACINTOSH) && defined(CHECK_MODIFICATION_TIME) #include <sys/types.h> #include <sys/stat.h> -#endif /* !MACINTOSH && !RISCOS && CHECK_MODIFICATION_TIME */ +#endif /* !MACINTOSH && CHECK_MODIFICATION_TIME */ /* @@ -130,33 +130,6 @@ void init_file_paths(char *path) -#ifdef VM - - /*** Use "flat" paths with VM/ESA ***/ - - /* Use "blank" path names */ - ANGBAND_DIR_APEX = string_make(""); - ANGBAND_DIR_BONE = string_make(""); - ANGBAND_DIR_CORE = string_make(""); - ANGBAND_DIR_DNGN = string_make(""); - ANGBAND_DIR_DATA = string_make(""); - ANGBAND_DIR_EDIT = string_make(""); - ANGBAND_DIR_FILE = string_make(""); - ANGBAND_DIR_HELP = string_make(""); - ANGBAND_DIR_INFO = string_make(""); - ANGBAND_DIR_MODULES = string_make(""); - ANGBAND_DIR_NOTE = string_make(""); - ANGBAND_DIR_PATCH = string_make(""); - ANGBAND_DIR_SAVE = string_make(""); - ANGBAND_DIR_SCPT = string_make(""); - ANGBAND_DIR_PREF = string_make(""); - ANGBAND_DIR_USER = string_make(""); - ANGBAND_DIR_XTRA = string_make(""); - ANGBAND_DIR_CMOV = string_make(""); - -#else /* VM */ - - /*** Build the sub-directory names ***/ /* Build a path name */ @@ -268,9 +241,6 @@ void init_file_paths(char *path) strcpy(tail, "xtra"); ANGBAND_DIR_XTRA = string_make(path); -#endif /* VM */ - - #ifdef NeXT /* Allow "fat binary" usage with NeXT */ @@ -350,7 +320,7 @@ static cptr err_str[9] = #endif /* ALLOW_TEMPLATES */ -#if !defined(RISCOS) && defined(CHECK_MODIFICATION_TIME) +#if defined(CHECK_MODIFICATION_TIME) static errr check_modification_date(int fd, cptr template_file) { diff --git a/src/loadsave.c b/src/loadsave.c index 6f355226..835d1e57 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -967,12 +967,6 @@ bool save_player(void) strcpy(safe, savefile); strcat(safe, ".new"); -#ifdef VM - /* Hack -- support "flat directory" usage on VM/ESA */ - strcpy(safe, savefile); - strcat(safe, "n"); -#endif /* VM */ - /* Grab permission */ if (savefile_setuid) safe_setuid_grab(); @@ -991,12 +985,6 @@ bool save_player(void) strcpy(temp, savefile); strcat(temp, ".old"); -#ifdef VM - /* Hack -- support "flat directory" usage on VM/ESA */ - strcpy(temp, savefile); - strcat(temp, "o"); -#endif /* VM */ - /* Grab permission */ if (savefile_setuid) safe_setuid_grab(); diff --git a/src/main-ami.c b/src/main-ami.c deleted file mode 100644 index da267b53..00000000 --- a/src/main-ami.c +++ /dev/null @@ -1,3250 +0,0 @@ -/* - - File: main-ami.c - - Version: 2.7.9v6 (09.May.96) - - Purpose: Amiga module for Angband with graphics and sound - - Author: Lars Haugseth - Email: larshau@ifi.uio.no - WWW: http://www.ifi.uio.no/~larshau - -*/ - -#define VERSION "Angband 2.7.9v6" - -///{ "includes" - -#include "angband.h" -#include "sound-ami.h" -#include <exec/memory.h> -#include <intuition/intuitionbase.h> -#include <intuition/intuition.h> -#include <intuition/screens.h> -#include <devices/inputevent.h> -#include <graphics/gfxbase.h> -#include <graphics/modeid.h> -#include <graphics/scale.h> -#include <graphics/text.h> -#include <libraries/asl.h> -#include <libraries/gadtools.h> -#include <proto/asl.h> -#include <proto/exec.h> -#include <proto/diskfont.h> -#include <proto/dos.h> -#include <proto/intuition.h> -#include <proto/graphics.h> -#include <proto/keymap.h> -#include <proto/gadtools.h> - -///} -///{ "macros" - -/* Pen number convertion */ -#define PEN( p ) ( penconv[ p ] ) - -/* Graphics pen number convertion */ -#define GPEN( p ) ( use_pub ? pubpens[ p ] : p ) - -/* Failure */ -#define FAIL( str ) return ( amiga_fail( str )) - -/* Message */ -#define MSG( x, y, txt ) amiga_text( x, y, strlen( txt ), 1, txt ); - -/* Char and attr under cursor */ -#define CUR_A ( td->t.scr->a[ td->cursor_ypos ][ td->cursor_xpos ] ) -#define CUR_C ( td->t.scr->c[ td->cursor_ypos ][ td->cursor_xpos ] ) - -///} -///{ "defines" - -/* Color to use for cursor */ -#define CURSOR_PEN 4 - -/* Size of graphical tile */ -#define TILEW 8 -#define TILEH 8 - -/* Size of tile image */ -#define GFXW 256 -#define GFXH 256 -#define GFXB 32 - -/* Size of tombstone image */ -#define TOMW 512 -#define TOMH 168 -#define TOMB 64 - -/* Filename of tile image */ -#define MGFX "Angband:xtra/gfx/tiles.raw" - -/* Filename of tombstone image */ -#define MTOM "Angband:xtra/gfx/tomb.raw" - -/* Filename of preferences file */ -#define WPRF "Angband:user/settings.prf" - -///} -///{ "globals" - -/* DisplayID specified with option -m */ -char modestr[ 256 ] = ""; - -/* Font specified with option -f */ -char fontstr[ 32 ] = ""; - -/* Library bases */ -struct Library *DiskfontBase = NULL; -struct Library *KeymapBase = NULL; -struct Library *GadToolsBase = NULL; - -/* Term data structure */ -typedef struct term_data -{ - term t; /* Term structure */ - cptr name; /* Name string */ - - BYTE use; /* Use this window */ - - BYTE cols; /* Number of columns */ - BYTE rows; /* Number of rows */ - - UWORD wx; /* Window x-pos */ - UWORD wy; /* Window y-pos */ - UWORD ww; /* Window width */ - UWORD wh; /* Window height */ - - BYTE fw; /* Font width */ - BYTE fh; /* Font height */ - BYTE fb; /* Font baseline */ - - struct TextFont *font; /* Font pointers */ - - BYTE ownf; /* Font is owned by this term */ - - struct Window *win; /* Window pointer */ - struct RastPort *wrp; /* RastPort of window */ - struct RastPort *rp; /* RastPort of screen or window */ - - struct BitMap *gfxbm; - struct BitMap *mapbm; - struct BitMap *mskbm; - - int gfx_w; - int gfx_h; - - int map_w; - int map_h; - int map_x; - int map_y; - - int mpt_w; - int mpt_h; - - int cursor_xpos; - int cursor_ypos; - int cursor_visible; - int cursor_lit; - int cursor_frame; - int cursor_map; - - int notitle; - int avoidbar; -} -term_data; - -/* Term data for all windows */ -static term_data screen; -static term_data mirror; -static term_data recall; -static term_data choice; - -/* Window names */ -static char screen_name[] = "Main"; -static char choice_name[] = "Choice"; -static char recall_name[] = "Recall"; -static char mirror_name[] = "Mirror"; - -/* Screen pointers */ -static struct Screen *amiscr = NULL; -static struct Screen *pubscr = NULL; - -/* Visual info for gadtools menus */ -static APTR *visinfo; - -/* TextAttr for screen font */ -static struct TextAttr ScrAttr, *scrattr = &ScrAttr; - -/* Screen DisplayID */ -static ULONG scr_m = 0; - -/* Last term for cursor */ -static term_data *term_curs = NULL; - -/* Temporary string */ -static char tmpstr[ 256 ]; - -/* Iconify status of windows */ -static int iconified = FALSE; - -/* Use intuition menus? */ -static int use_menus = TRUE; - -/* Use mouseblanking? */ -static int blankmouse = FALSE; - -/* Window input event */ -static struct InputEvent ie; - -/* KickStart 3.0+ present */ -static int v39 = FALSE; - -/* Use a public screen */ -static int use_pub = FALSE; - -/* Public screen lock */ -static int publock = FALSE; - -/* Use a backdrop main window */ -static int backdrop = FALSE; - -/* Use 32 colors on custom screen */ -static int deep = FALSE; - -/* Invisible pointer for blanking */ -static __chip UWORD blankpointer[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* Pointer visibility status */ -static int pointer_visible = TRUE; - -/* Convert textual pens to screen pens */ -static UWORD penconv[ 16 ] = -{ - 0, 1, 2, 4, 11, 15, 9, 6, 3, 1, 13, 4, 11, 15, 8, 5 -}; - -/* Public screen obtained pens */ -static LONG pubpens[ 32 ] = -{ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 -}; - -/* Default color palette, 16 for graphics, 16 for text */ -static ULONG default_colors[ 32 ] = -{ - 0x000000, 0xf0e0d0, 0x808080, 0x505050, - 0xe0b000, 0xc0a070, 0x806040, 0x403020, - 0x00a0f0, 0x0000f0, 0x000070, 0xf00000, - 0x800000, 0x9000b0, 0x006010, 0x60f040, - - 0x000000, 0xffffff, 0xc7c7c7, 0xff9200, - 0xff0000, 0x00cd00, 0x0000fe, 0xc86400, - 0x8a8a8a, 0xe0e0e0, 0xa500ff, 0xfffd00, - 0xff00bc, 0x00ff00, 0x00c8ff, 0xffcc80 -}; - -/* Palette, 32 bits per gun */ -static ULONG palette32[ 32 * 3 + 2 ]; - -/* Palette, 4 bits per gun */ -static UWORD palette4[ 32 ]; - -/* Version string */ -static char ver[] = "$VER: " VERSION " (" __DATE__ ")"; - -///} -///{ "sound" - -#define NSAMPLES 25 - -struct AmiSound -{ - char *Name; - int Volume; - int Channel; - int Rate; - int Repeats; - int Memory; - struct SoundInfo *Address; -}; - -static struct AmiSound sound_data[ NSAMPLES ] = -{ - { "intro.8svx", 64, 0, 0, 1, 0, NULL }, /* Intro */ - { "hit.8svx", 64, 0, 0, 1, 1, NULL }, /* Hit */ - { "miss.8svx", 64, 3, 0, 1, 1, NULL }, /* Miss */ - { "flee.8svx", 64, 1, 0, 1, 1, NULL }, /* Flee */ - { "drop.8svx", 64, 2, 0, 1, 1, NULL }, /* Drop */ - { "kill.8svx", 64, 1, 0, 1, 1, NULL }, /* Kill */ - { "study.8svx", 64, 2, 0, 1, 1, NULL }, /* Level */ - { "death.8svx", 64, 0, 0, 1, 0, NULL }, /* Death */ - { "study.8svx", 64, 2, 0, 1, 1, NULL }, /* Study */ - { "teleport.8svx", 64, 3, 0, 1, 1, NULL }, /* Teleport */ - { "shoot.8svx", 64, 0, 0, 1, 1, NULL }, /* Shoot */ - { "quaff.8svx", 64, 1, 0, 1, 1, NULL }, /* Quaff */ - { "zap.8svx", 64, 3, 0, 1, 1, NULL }, /* Zap */ - { "walk.8svx", 64, 0, 0, 1, 1, NULL }, /* Walk */ - { "tpother.8svx", 64, 3, 0, 1, 1, NULL }, /* Teleport Other */ - { "hitwall.8svx", 64, 3, 0, 1, 1, NULL }, /* Hit Wall */ - { "eat.8svx", 64, 3, 0, 1, 1, NULL }, /* Eat */ - { "store1.8svx", 64, 0, 0, 1, 0, NULL }, /* Shopkeeper furious */ - { "store2.8svx", 64, 0, 0, 1, 0, NULL }, /* Shopkeeper angry */ - { "store3.8svx", 64, 0, 0, 1, 0, NULL }, /* Shopkeeper glad */ - { "store4.8svx", 64, 0, 0, 1, 0, NULL }, /* Shopkeeper happy */ - { "dig.8svx", 64, 0, 0, 1, 1, NULL }, /* Dig */ - { "opendoor.8svx", 64, 0, 0, 1, 1, NULL }, /* Open door */ - { "closedoor.8svx", 64, 0, 0, 1, 1, NULL }, /* Close door */ - { "tplevel.8svx", 64, 0, 0, 1, 0, NULL }, /* Teleport level */ -}; - -static int channel_last[ 4 ] = { -1, -1, -1, -1 }; - -static int has_sound = FALSE; - -///} -///{ "menus" - -#define MENUMAX 256 - -/* Menu userdata indexes */ -#define MNU_SCALEDMAP 1001 - -/* Special offset indexes */ -#define MNU_KEYCOM 2001 -#define MNU_CKEYCOM 3001 -#define MNU_OPTION 4001 -#define MNU_HELP 5001 - -/* Macro for menu userdata keycodes and help */ -#define MKC( c ) (void *)( MNU_KEYCOM + c ) -#define MCC( c ) (void *)( MNU_CKEYCOM + c ) -#define MHL( c ) (void *)( MNU_HELP + c ) - -struct Menu *menu = NULL; - -/* Menu items that comes before the options */ -struct NewMenu pre_item[] = -{ - { NM_TITLE, "Options", 0, 0, 0, 0}, - { 255, 0, 0, 0, 0, 0 } -}; - -/* Option menu items, titles of submenus */ -struct NewMenu opt_item[] = -{ - { NM_ITEM, "User Interface", 0, 0, 0, 0 }, - { NM_ITEM, "Disturbance", 0, 0, 0, 0 }, - { NM_ITEM, "Inventory", 0, 0, 0, 0 }, - { NM_ITEM, "Game-Play", 0, 0, 0, 0 }, - { NM_ITEM, "Efficiency", 0, 0, 0, 0 }, - { NM_ITEM, "Special", 0, 0, 0, 0 }, - { NM_ITEM, "Cheating", 0, 0, 0, 0 }, - { 255, 0, 0, 0, 0, 0 } -}; - -/* Menu items that comes after the options */ -struct NewMenu post_item[] = -{ - /* - { NM_ITEM, "Hitpoint Warning", 0, 0, 0, 0 }, - { NM_SUB, "90%", 0, CHECKIT, ~1, 0 }, - { NM_SUB, "80%", 0, CHECKIT, ~2, 0 }, - { NM_SUB, "70%", 0, CHECKIT, ~4, 0 }, - { NM_SUB, "60%", 0, CHECKIT, ~8, 0 }, - { NM_SUB, "50%", 0, CHECKIT, ~16, 0 }, - { NM_SUB, "40%", 0, CHECKIT, ~32, 0 }, - { NM_SUB, "30%", 0, CHECKIT, ~64, 0 }, - { NM_SUB, "20%", 0, CHECKIT, ~128, 0 }, - { NM_SUB, "10%", 0, CHECKIT, ~256, 0 }, - { NM_SUB, "Off", 0, CHECKIT, ~512, 0 }, - */ - - { NM_TITLE, "Cmd1", 0, 0, 0, 0 }, - { NM_ITEM, "a Aim a wand", 0, 0, 0, MKC('a') }, - { NM_ITEM, "b Browse a book", 0, 0, 0, MKC('b') }, - { NM_ITEM, "c Close a door", 0, 0, 0, MKC('c') }, - { NM_ITEM, "d Drop an item", 0, 0, 0, MKC('d') }, - { NM_ITEM, "e Equipment list", 0, 0, 0, MKC('e') }, - { NM_ITEM, "f Fire an item", 0, 0, 0, MKC('f') }, - { NM_ITEM, "g Stay still", 0, 0, 0, MKC('g') }, - { NM_ITEM, "i Inventory list", 0, 0, 0, MKC('i') }, - { NM_ITEM, "j Jam a door", 0, 0, 0, MKC('j') }, - { NM_ITEM, "k Destroy an item", 0, 0, 0, MKC('k') }, - { NM_ITEM, "l Look around", 0, 0, 0, MKC('l') }, - - { NM_TITLE, "Cmd2", 0, 0, 0, 0 }, - { NM_ITEM, "m Cast a spell", 0, 0, 0, MKC('m') }, - { NM_ITEM, "o Open a door or chest", 0, 0, 0, MKC('o') }, - { NM_ITEM, "p Pray a prayer", 0, 0, 0, MKC('p') }, - { NM_ITEM, "q Quaff a potion", 0, 0, 0, MKC('q') }, - { NM_ITEM, "r Read a scroll", 0, 0, 0, MKC('r') }, - { NM_ITEM, "s Search for traps/doors", 0, 0, 0, MKC('s') }, - { NM_ITEM, "t Take off equipment", 0, 0, 0, MKC('t') }, - { NM_ITEM, "u Use a staff", 0, 0, 0, MKC('u') }, - { NM_ITEM, "v Throw an item", 0, 0, 0, MKC('v') }, - { NM_ITEM, "w Wear/wield equipment", 0, 0, 0, MKC('w') }, - { NM_ITEM, "z Zap a rod", 0, 0, 0, MKC('z') }, - - { NM_TITLE, "Cmd3", 0, 0, 0, 0 }, - { NM_ITEM, "A Activate an artifact", 0, 0, 0, MKC('A') }, - { NM_ITEM, "B Bash a door", 0, 0, 0, MKC('B') }, - { NM_ITEM, "C Character description", 0, 0, 0, MKC('C') }, - { NM_ITEM, "D Disarm a trap", 0, 0, 0, MKC('D') }, - { NM_ITEM, "E Eat some food", 0, 0, 0, MKC('E') }, - { NM_ITEM, "F Fuel your lantern/torch", 0, 0, 0, MKC('F') }, - { NM_ITEM, "G Gain new spells/prayers", 0, 0, 0, MKC('G') }, - { NM_ITEM, "I Observe an item", 0, 0, 0, MKC('I') }, - { NM_ITEM, "L Locate player on map", 0, 0, 0, MKC('L') }, - { NM_ITEM, "M Full dungeon map", 0, 0, 0, MKC('M') }, - { NM_ITEM, "Q Quit (commit suicide)", 0, 0, 0, MKC('Q') }, - { NM_ITEM, "R Rest for a period", 0, 0, 0, MKC('R') }, - { NM_ITEM, "S Toggle search mode", 0, 0, 0, MKC('S') }, - { NM_ITEM, "T Dig a tunnel", 0, 0, 0, MKC('T') }, - { NM_ITEM, "V Version info", 0, 0, 0, MKC('V') }, - - { NM_TITLE, "Cmd4", 0, 0, 0, 0 }, - { NM_ITEM, "@ Interact with macros", 0, 0, 0, MKC('@') }, - { NM_ITEM, "% Interact with visuals", 0, 0, 0, MKC('%') }, - { NM_ITEM, "& Interact with colors", 0, 0, 0, MKC('&') }, - { NM_ITEM, "* Target monster or location", 0, 0, 0, MKC('*') }, - { NM_ITEM, "( Load screen dump", 0, 0, 0, MKC('(') }, - { NM_ITEM, ") Dump screen dump", 0, 0, 0, MKC(')') }, - { NM_ITEM, "{ Inscribe an object", 0, 0, 0, MKC('{') }, - { NM_ITEM, "} Uninscribe an object", 0, 0, 0, MKC('}') }, - { NM_ITEM, "- Walk (flip pickup)", 0, 0, 0, MKC('-') }, - - { NM_TITLE, "Cmd5", 0, 0, 0, 0 }, - { NM_ITEM, "+ Dig tunnel", 0, 0, 0, MKC('+') }, - { NM_ITEM, "= Set options", 0, 0, 0, MKC('=') }, - { NM_ITEM, "; Walk (with pickup)", 0, 0, 0, MKC(';') }, - { NM_ITEM, ": Take notes", 0, 0, 0, MKC(':') }, - { NM_ITEM, "\" Enter a user pref command", 0, 0, 0, MKC('\"') }, - { NM_ITEM, ", Stay still (with pickup)", 0, 0, 0, MKC(',') }, - { NM_ITEM, "< Go up staircase", 0, 0, 0, MKC('<') }, - { NM_ITEM, ". Run", 0, 0, 0, MKC('.') }, - { NM_ITEM, "> Go down staircase", 0, 0, 0, MKC('>') }, - { NM_ITEM, "/ Identify symbol", 0, 0, 0, MKC('/') }, - { NM_ITEM, "| Check uniques", 0, 0, 0, MKC('|') }, - { NM_ITEM, "~ Check artifacts", 0, 0, 0, MKC('~') }, - { NM_ITEM, "? Help", 0, 0, 0, MKC('?') }, - - { NM_TITLE, "Cmd6", 0, 0, 0, 0 }, - { NM_ITEM, "^f Repeat level feeling", 0, 0, 0, MCC('f') }, - { NM_ITEM, "^k Quit", 0, 0, 0, MCC('k') }, - { NM_ITEM, "^p Show previous messages", 0, 0, 0, MCC('p') }, - { NM_ITEM, "^r Redraw the screen", 0, 0, 0, MCC('r') }, - { NM_ITEM, "^s Save and don't quit", 0, 0, 0, MCC('s') }, - { NM_ITEM, "^x Save and quit", 0, 0, 0, MCC('x') }, - { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 }, - { NM_ITEM, "Draw dungeon map", "m", 0, 0, (void *)MNU_SCALEDMAP }, - - { NM_TITLE, "Help", 0, 0, 0, 0 }, - { NM_ITEM, "General Information", 0, 0, 0, MHL('1') }, - { NM_ITEM, "Creating a Character", 0, 0, 0, MHL('2') }, - { NM_ITEM, "Exploring the Dungeon", 0, 0, 0, MHL('3') }, - { NM_ITEM, "Attacking Monsters", 0, 0, 0, MHL('4') }, - { NM_ITEM, "List of Commands", 0, 0, 0, MHL('5') }, - { NM_ITEM, "List of Options", 0, 0, 0, MHL('6') }, - { NM_ITEM, "Version Information", 0, 0, 0, MHL('7') }, - - { NM_END, NULL, 0, 0, 0, 0 }, - { 255, 0, 0, 0, 0, 0 } -}; - -/* Menu array */ -struct NewMenu newmenu[ MENUMAX ]; - -///} -///{ "protos" - -extern void map_info( int y, int x, byte *ap, char *cp ); -extern void center_string( char *buf, cptr str ); -errr init_ami( void ); -static void init_term( term_data *td ); -static term *link_term( term_data *td ); -static void free_term( term_data *td ); -static char *stripstr( char *src, char *dst ); -void request_font( char *str ); -void request_mode( char *str ); -int read_prefs( void ); -static void amiga_open( term *t ); -static void amiga_nuke( term *t ); -static errr amiga_curs( int x, int y ); -static errr amiga_wipe( int x, int y, int n ); -static errr amiga_clear( void ); -static errr amiga_pict( int x, int y, byte a, char c ); -static errr amiga_text( int x, int y, int n, byte a, cptr s ); -static errr amiga_xtra( int n, int v ); -static errr amiga_flush( int v ); -static errr amiga_event( int v ); -static errr amiga_react( int v ); -static errr amiga_fail( char *msg ); -static void cursor_on( term_data *td ); -static void cursor_off( term_data *td ); -void amiga_tomp( void ); -void tomb_str( int y, char *str ); -int load_gfx( void ); -int conv_gfx( void ); -int size_gfx( term_data *td ); -void scale_bitmap( struct BitMap *srcbm, int srcw, int srch, struct BitMap *dstbm, int dstw, int dsth ); -void remap_bitmap( struct BitMap *srcbm, struct BitMap *dstbm, long *pens, int width, int height ); -static void put_gfx( struct RastPort *rp, int x, int y, int chr, int col ); -static void put_gfx_map( term_data *td, int x, int y, int c, int a ); -static void cursor_anim( void ); -void load_palette( void ); -static void amiga_map( void ); -int init_sound( void ); -void free_sound( void ); -static void play_sound( int v ); -struct BitMap *alloc_bitmap( int width, int height, int depth, ULONG flags, struct BitMap *friend ); -void free_bitmap( struct BitMap *bitmap ); -int depth_of_bitmap( struct BitMap *bm ); -int create_menus( void ); -void update_menus( void ); -void handle_menupick( int mnum ); -void handle_rawkey( UWORD code, UWORD qual, APTR addr ); - -///} - -///{ "init_ami()" - Initialize all Amiga spesific stuff - -errr init_ami( void ) -{ - char *s; - int i; - LONG pen; - struct DimensionInfo diminfo; - int pw, ph, maxw, maxh, th, barh; - - /* XXX XXX XXX */ - use_sound = arg_sound; - use_graphics = arg_graphics; - - /* Term data pointers */ - term_data *ts = &screen; - term_data *tc = &choice; - term_data *tr = &recall; - term_data *tm = &mirror; - - /* Clear the term data */ - init_term( ts ); - init_term( tc ); - init_term( tr ); - init_term( tm ); - - /* Always use the main term */ - ts->use = TRUE; - - /* We *must* have kickstart 37 or later */ - if ( IntuitionBase->LibNode.lib_Version < 37 ) - FAIL( "Sorry, this program requires KickStart 2.04 or later." ); - - /* Check if we have kickstart 39 or later */ - v39 = ( IntuitionBase->LibNode.lib_Version >= 39 ); - - /* Open diskfont.library */ - if (( DiskfontBase = OpenLibrary( "diskfont.library", 0 )) == NULL ) - FAIL( "Unable to open diskfont.library." ); - - /* Read preferences file */ - read_prefs(); - - /* Initialize keyboard stuff */ - ie.ie_NextEvent = NULL; - ie.ie_Class = IECLASS_RAWKEY; - ie.ie_SubClass = 0; - if (( KeymapBase = OpenLibrary( "keymap.library", 36 )) == NULL ) - FAIL( "Unable to open keymap.library v36+." ); - - /* Open gadtools.library */ - if ( use_menus ) - { - if (( GadToolsBase = OpenLibrary( "gadtools.library", 36 )) == NULL ) - { - use_menus = FALSE; - } - } - - /* Initialize color palette */ - for ( i = 0; i < 32; i++ ) - { - /* If undefined, use default palette */ - if ( color_table[ i ][ 0 ] == 0 && - color_table[ i ][ 1 ] == 0 && - color_table[ i ][ 2 ] == 0 && - color_table[ i ][ 3 ] == 0 ) - { - color_table[ i ][ 0 ] = 1; - color_table[ i ][ 1 ] = ( default_colors[ i ] & 0xff0000 ) >> 16; - color_table[ i ][ 2 ] = ( default_colors[ i ] & 0x00ff00 ) >> 8; - color_table[ i ][ 3 ] = ( default_colors[ i ] & 0x0000ff ); - } - } - - /* Search for prefered screenmode or public screen */ - if ( strlen( modestr ) > 0 ) - { - /* Convert string to long */ - scr_m = strtol( modestr, &s, 0 ); - - /* It was not a number, so treat it as a public screen name */ - if ( scr_m == 0 ) - { - /* We need kickstart 3.0+ to use a public screen */ - if ( !v39 ) - { - FAIL( "Public screen can only be used on kickstart 3.0 or later." ); - } - - /* Try to lock the named public screen if it isn't already */ - if ( !pubscr ) - { - pubscr = LockPubScreen( modestr ); - } - - /* Failed */ - if ( !pubscr ) - { - sprintf( tmpstr, "Unable to get a lock on screen '%s'.", modestr ); - FAIL( tmpstr ); - } - - /* We got a lock now */ - publock = TRUE; - - scr_m = -1; - - use_pub = TRUE; - - /* Don't blank mouse on public screen */ - blankmouse = FALSE; - - /* Find suitable pens to use on public screen */ - for ( i = 0; i < 32; i++ ) - { - pen = ObtainBestPen( pubscr->ViewPort.ColorMap, - color_table[ i ][ 1 ] << 24, - color_table[ i ][ 2 ] << 24, - color_table[ i ][ 3 ] << 24, - OBP_Precision, PRECISION_EXACT ); - if ( pen == -1 ) - { - FAIL( "Unable to obtain suitable pens to use on public screen. "); - } - - pubpens[ i ] = pen; - } - - for ( i = 0; i < 16; i++ ) penconv[ i ] = (UWORD) pubpens[ i + 16 ]; - } - - /* Use specified screenmode if available */ - else - { - /* Check if requested mode is available */ - if ( ModeNotAvailable( scr_m )) scr_m = 0; - } - } - - if ( !use_pub ) - { - /* Extra windows not allowed on custom screen */ - tc->use = tr->use = tm->use = FALSE; - } - - /* Calculate window dimensions */ - ts->ww = ts->fw * ts->cols; ts->wh = ts->fh * ts->rows; - tc->ww = tc->fw * tc->cols; tc->wh = tc->fh * tc->rows; - tr->ww = tr->fw * tr->cols; tr->wh = tr->fh * tr->rows; - tm->ww = tm->fw * tm->cols; tm->wh = tm->fh * tm->rows; - - /* Find a nice screenmode */ - if ( scr_m == 0 && v39 ) - { - scr_m = BestModeID( - BIDTAG_NominalWidth, ts->ww, - BIDTAG_NominalHeight, ts->wh, - BIDTAG_DesiredWidth, ts->ww, - BIDTAG_DesiredHeight, ts->wh, - BIDTAG_Depth, 4, - TAG_END ); - } - - /* Use default screenmode if we don't have any */ - if ( scr_m == 0 || scr_m == INVALID_ID ) - { - scr_m = ( DEFAULT_MONITOR_ID | HIRES_KEY ); - } - - /* Open custom screen */ - if ( !use_pub ) - { - /* Use 32 colors with graphics */ - if ( use_graphics ) - { - /* Get dimension data for screenmode */ - if ( GetDisplayInfoData( NULL, (UBYTE *) &diminfo, sizeof( struct DimensionInfo ), DTAG_DIMS, scr_m )) - { - /* Check if we support deep screens */ - if ( diminfo.MaxDepth > 4 ) - { - /* Use 32 colors */ - deep = TRUE; - - /* Use colors 16..31 for text */ - for ( i = 0; i < 16; i++ ) penconv[ i ] = i + 16; - } - } - } - - /* Use only 16 colors with no graphics */ - if ( !use_graphics ) - { - /* Use 16 colors */ - deep = FALSE; - - /* Use colors 0..15 for text */ - for ( i = 0; i < 16; i++ ) penconv[ i ] = i; - } - - if (( amiscr = OpenScreenTags( NULL, - SA_Width, ts->ww, - SA_Height, ts->wh, - SA_Depth, deep ? 5 : 4, - SA_DisplayID, scr_m, - SA_Font, scrattr, - SA_Type, CUSTOMSCREEN, - SA_Title, "Angband Screen", - SA_ShowTitle, FALSE, - SA_Quiet, TRUE, - SA_Behind, TRUE, - SA_AutoScroll, TRUE, - SA_Overscan, OSCAN_TEXT, - v39 ? SA_Interleaved : TAG_IGNORE, TRUE, - TAG_END )) == NULL) - { - FAIL( "Unable to open screen." ); - } - - /* Initialize screen rastport */ - ts->rp = &amiscr->RastPort; - SetRast( ts->rp, PEN( 0 )); - SetAPen( ts->rp, 1 ); - SetBPen( ts->rp, 0 ); - SetDrMd( ts->rp, JAM2 ); - SetFont( ts->rp, ts->font ); - - /* Always use backdrop window on custom screen */ - backdrop = TRUE; - } - - /* We are using a public screen */ - else - { - /* Size of public screen */ - pw = pubscr->Width; - ph = pubscr->Height; - - /* Height difference between a window with or without a title bar */ - th = pubscr->Font->ta_YSize + 1; - - /* Find width of widest window */ - maxw = ts->ww; - maxw = tc->ww > maxw ? tc->ww : maxw; - maxw = tr->ww > maxw ? tr->ww : maxw; - maxw = tm->ww > maxw ? tm->ww : maxw; - maxw += pubscr->WBorLeft + pubscr->WBorRight; - - /* Find height of tallest window */ - maxh = ts->wh + ts->notitle ? 0 : th; - maxh = ( tc->wh + tc->notitle ? 0 : th ) > maxh ? ( tc->wh + tc->notitle ? 0 : th ) : maxh; - maxh = ( tr->wh + tr->notitle ? 0 : th ) > maxh ? ( tr->wh + tr->notitle ? 0 : th ) : maxh; - maxh = ( tm->wh + tm->notitle ? 0 : th ) > maxh ? ( tm->wh + tm->notitle ? 0 : th ) : maxh; - maxh += pubscr->WBorTop + pubscr->WBorBottom; - - /* Check if the public screen is large enough */ - if ( pw < maxw || ph < maxh ) - { - sprintf( tmpstr, "Public screen is too small for window (%d x %d).", maxw, maxh ); - FAIL( tmpstr ); - } - - /* Use backdrop window if pubscreen is quiet */ - backdrop = ( pubscr->Flags & SCREENQUIET ) ? TRUE : FALSE; - - /* Calculate screen bar height */ - barh = pubscr->BarHeight + 1; - - /* Check if windows are to be positioned at the right or bottom */ - if ( ts->wx == -1 ) ts->wx = pw - 1; - if ( ts->wy == -1 ) ts->wy = ph - 1; - if ( tc->wx == -1 ) tc->wx = pw - 1; - if ( tc->wy == -1 ) tc->wy = ph - 1; - if ( tr->wx == -1 ) tr->wx = pw - 1; - if ( tr->wy == -1 ) tr->wy = ph - 1; - if ( tm->wx == -1 ) tm->wx = pw - 1; - if ( tm->wy == -1 ) tm->wy = ph - 1; - - /* Position windows below screen bar if requested */ - if ( ts->wy == -2 ) ts->wy = barh; - if ( tc->wy == -2 ) tc->wy = barh; - if ( tr->wy == -2 ) tr->wy = barh; - if ( tm->wy == -2 ) tm->wy = barh; - } - - /* Get visual info for GadTools */ - if ( use_menus ) - { - if (( visinfo = GetVisualInfo( use_pub ? pubscr : amiscr, TAG_END )) == NULL ) - { - use_menus = FALSE; - } - } - - /* Open window, backdrop if on custom screen */ - if (( ts->win = OpenWindowTags( NULL, - WA_Left, ts->wx, - WA_Top, ts->wy, - WA_InnerWidth, ts->ww, - WA_InnerHeight, ts->wh, - use_pub ? WA_PubScreen : WA_CustomScreen, use_pub ? pubscr : amiscr, - WA_Backdrop, backdrop, - WA_Borderless, backdrop, - WA_GimmeZeroZero, !backdrop, - WA_DragBar, !backdrop && !ts->notitle, - WA_DepthGadget, !backdrop && !ts->notitle, - WA_NewLookMenus, TRUE, - backdrop ? TAG_IGNORE : WA_ScreenTitle, VERSION, - ( backdrop || ts->notitle ) ? TAG_IGNORE : WA_Title, ts->name, - WA_Activate, TRUE, - WA_RMBTrap, !use_menus, - WA_ReportMouse, TRUE, - WA_IDCMP, IDCMP_RAWKEY | IDCMP_INTUITICKS | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_MENUPICK | IDCMP_MENUVERIFY, - TAG_END )) == NULL ) - { - FAIL("Unable to open window."); - } - - /* Unlock public screen */ - if ( publock ) - { - UnlockPubScreen( NULL, pubscr ); - publock = FALSE; - } - - /* Initialize main rastport */ - ts->wrp = ts->win->RPort; - SetRast( ts->wrp, PEN( 0 )); - SetAPen( ts->wrp, 1 ); - SetBPen( ts->wrp, 0 ); - SetDrMd( ts->wrp, JAM2 ); - SetFont( ts->wrp, ts->font ); - - /* Never use screen's rastport on public screen */ - if ( use_pub ) - { - ts->rp = ts->wrp; - } - - /* Use mirror window? */ - if ( tm->use ) - { - /* Open mirror window */ - if (( tm->win = OpenWindowTags( NULL, - WA_Left, tm->wx, - WA_Top, tm->wy, - WA_InnerWidth, tm->ww, - WA_InnerHeight, tm->wh, - WA_PubScreen, pubscr, - WA_GimmeZeroZero, TRUE, - WA_DragBar, !tm->notitle, - WA_DepthGadget, !tm->notitle, - WA_NewLookMenus, TRUE, - WA_ScreenTitle, VERSION, - tm->notitle ? TAG_IGNORE : WA_Title, tm->name, - WA_ReportMouse, TRUE, - TAG_END )) == NULL ) - { - FAIL("Unable to open recall window."); - } - - /* Initialize mirror rastport */ - tm->rp = tm->wrp = tm->win->RPort; - SetRast( tm->rp, PEN( 0 )); - SetAPen( tm->rp, 1 ); - SetBPen( tm->rp, 0 ); - SetDrMd( tm->rp, JAM2 ); - SetFont( tm->rp, tm->font ); - } - - /* Use recall window? */ - if ( tr->use ) - { - /* Open recall window */ - if (( tr->win = OpenWindowTags( NULL, - WA_Left, tr->wx, - WA_Top, tr->wy, - WA_InnerWidth, tr->ww, - WA_InnerHeight, tr->wh, - WA_PubScreen, pubscr, - WA_GimmeZeroZero, TRUE, - WA_DragBar, !tr->notitle, - WA_DepthGadget, !tr->notitle, - WA_NewLookMenus, TRUE, - WA_ScreenTitle, VERSION, - tr->notitle ? TAG_IGNORE : WA_Title, tr->name, - WA_ReportMouse, TRUE, - TAG_END )) == NULL ) - { - FAIL("Unable to open recall window."); - } - - /* Initialize recall rastport */ - tr->rp = tr->wrp = tr->win->RPort; - SetRast( tr->rp, PEN( 0 )); - SetAPen( tr->rp, 1 ); - SetBPen( tr->rp, 0 ); - SetDrMd( tr->rp, JAM2 ); - SetFont( tr->rp, tr->font ); - } - - /* Use choice window? */ - if ( tc->use ) - { - /* Open choice window */ - if (( tc->win = OpenWindowTags( NULL, - WA_Left, tc->wx, - WA_Top, tc->wy, - WA_InnerWidth, tc->ww, - WA_InnerHeight, tc->wh, - WA_PubScreen, pubscr, - WA_GimmeZeroZero, TRUE, - WA_DragBar, !tc->notitle, - WA_DepthGadget, !tc->notitle, - WA_NewLookMenus, TRUE, - WA_ScreenTitle, VERSION, - tc->notitle ? TAG_IGNORE : WA_Title, tc->name, - WA_ReportMouse, TRUE, - TAG_END )) == NULL ) - { - FAIL("Unable to open recall window."); - } - - /* Initialize choice rastport */ - tc->rp = tc->wrp = tc->win->RPort; - SetRast( tc->rp, PEN( 0 )); - SetAPen( tc->rp, 1 ); - SetBPen( tc->rp, 0 ); - SetDrMd( tc->rp, JAM2 ); - SetFont( tc->rp, tc->font ); - } - - /* Create palette for screen */ - load_palette(); - - /* Link terms with the metaterm */ - if ( tc->use ) term_choice = link_term( tc ); - if ( tr->use ) term_recall = link_term( tr ); - if ( tm->use ) term_mirror = link_term( tm ); - if ( ts->use ) term_screen = link_term( ts ); - - /* Bring main window to front */ - if ( !backdrop ) WindowToFront( ts->win ); - - /* Bring screen to front */ - ScreenToFront( use_pub ? pubscr : amiscr ); - - /* Load and convert graphics */ - if ( use_graphics ) - { - MSG( 0, 0, "Loading graphics" ); - if ( !load_gfx() ) FAIL( NULL ); - - /* Check if conversion is necessary */ - if ( use_pub || ( depth_of_bitmap( ts->rp->BitMap ) != depth_of_bitmap( ts->gfxbm ))) - { - MSG( 0, 1, "Remapping graphics" ); - if ( !conv_gfx() ) FAIL( "Out of memory while remapping graphics." ); - } - - /* Scale the graphics to fit font sizes */ - if ( tm->use ) if ( !size_gfx( tm ) ) FAIL( "Out of memory while scaling graphics." ); - if ( tr->use ) if ( !size_gfx( tr ) ) FAIL( "Out of memory while scaling graphics." ); - if ( tc->use ) if ( !size_gfx( tc ) ) FAIL( "Out of memory while scaling graphics." ); - if ( ts->use ) if ( !size_gfx( ts ) ) FAIL( "Out of memory while scaling graphics." ); - - /* Use graphics */ - use_graphics = TRUE; - } - - /* Load sound effects */ - if ( use_sound ) - { - MSG( 0, 2, "Loading sound effects" ); - init_sound(); - } - - /* Success */ - return ( 0 ); -} -///} -///{ "init_term()" - -static void init_term( term_data *td ) -{ - /* Set term name */ - if ( td == &screen ) td->name = screen_name; - if ( td == &choice ) td->name = choice_name; - if ( td == &recall ) td->name = recall_name; - if ( td == &mirror ) td->name = mirror_name; - - /* Term off */ - td->use = FALSE; - - /* Term size */ - td->cols = 80; - td->rows = 24; - - /* Term dimension */ - td->wx = 0; - td->wy = 0; - td->ww = 0; - td->wh = 0; - - /* System default font */ - td->font = GfxBase->DefaultFont; - td->ownf = FALSE; - td->fw = td->font->tf_XSize; - td->fh = td->font->tf_YSize; - td->fb = td->font->tf_Baseline; - - /* No window or rastports */ - td->win = NULL; - td->wrp = NULL; - td->rp = NULL; - - /* No bitmaps */ - td->gfxbm = NULL; - td->mskbm = NULL; - td->mapbm = NULL; - - /* Cursor status */ - td->cursor_xpos = 0; - td->cursor_ypos = 0; - td->cursor_visible = FALSE; - td->cursor_lit = FALSE; - td->cursor_frame = 0; - td->cursor_map = FALSE; - - /* Use window title */ - td->notitle = FALSE; -} - -///} -///{ "link_term()" - -static term *link_term( term_data *td ) -{ - term *t; - - /* Term pointer */ - t = &td->t; - - /* Initialize the term */ - term_init( t, td->cols, td->rows, 256 ); - - /* Hooks */ - t->init_hook = amiga_open; - t->nuke_hook = amiga_nuke; - t->text_hook = amiga_text; - t->pict_hook = amiga_pict; - t->wipe_hook = amiga_wipe; - t->curs_hook = amiga_curs; - t->xtra_hook = amiga_xtra; - - /* We are emulating a hardware cursor */ - t->soft_cursor = FALSE; - - /* Draw graphical tiles one by one */ - t->always_text = FALSE; - t->always_pict = FALSE; - t->higher_pict = TRUE; - - /* Misc. efficiency flags */ - t->never_bored = TRUE; - t->never_frosh = TRUE; - - /* Erase with "white space" */ - t->attr_blank = TERM_WHITE; - t->char_blank = ' '; - - /* Remember where we come from */ - t->data = (vptr) td; - - /* Activate it */ - Term_activate( t ); - - /* Return pointer to the term */ - return ( t ); -} - -///} -///{ "free_term()" - -static void free_term( term_data *td ) -{ - /* Do we own the font? */ - if ( td->ownf && td->font ) CloseFont( td->font ); - - /* Is the window opened? */ - if ( td->win ) CloseWindow( td->win ); - - /* Free bitmaps */ - if ( td->gfxbm ) free_bitmap( td->gfxbm ); - if ( td->mskbm ) free_bitmap( td->mskbm ); - if ( td->mapbm ) free_bitmap( td->mapbm ); -} - -///} -///{ "stripstr()" - -static char *stripstr( char *src, char *dst ) -{ - int len; - - /* Ignore leading spaces */ - while ( *src == ' ' ) src++; - - /* Copy string */ - for ( len = 0; *src != 0; len++ ) *dst++ = *src++; - *dst = 0; - - /* Remove trailing spaces */ - for ( dst--; *dst == ' ' && len; len-- ) *dst-- = 0; - - /* Return pointer to destination */ - return ( dst ); -} - -///} -///{ "yesno()" - -static int yesno( char *str ) -{ - char tmp[ 256 ]; - char *s; - - /* Strip spaces around string */ - stripstr( str, tmp); - - /* Make lowercase */ - for ( s = tmp; *s != 0; s++ ) *s = tolower( *s ); - - return ( !strcmp( tmp, "y" ) || !strcmp( tmp, "yes" ) || !strcmp( tmp, "true" ) || !strcmp( tmp, "on" )); -} - -///} -///{ "request_font()" - -void request_font( char *str ) -{ - struct Library *AslBase = NULL; - struct FontRequester *req = NULL; - - /* Blank string as default */ - *str = 0; - - /* Open asl.library */ - if ( AslBase = OpenLibrary ( "asl.library", 37 )) - { - /* Allocate screenmode requester */ - if ( req = AllocAslRequestTags( ASL_FontRequest, TAG_DONE )) - { - /* Open screenmode requester */ - if ( AslRequestTags( req, ASLFO_FixedWidthOnly, TRUE, TAG_DONE )) - { - /* Store font name and size */ - sprintf( str, "%s/%d", req->fo_Attr.ta_Name, req->fo_Attr.ta_YSize ); - } - /* Free requester */ - FreeAslRequest( req ); - } - /* Close asl.library */ - CloseLibrary( AslBase ); - } -} - -///} -///{ "request_mode()" - -void request_mode( char *str ) -{ - struct Library *AslBase = NULL; - struct ScreenModeRequester *req = NULL; - - /* Blank string as default */ - *str = 0; - - /* Open asl.library */ - if ( AslBase = OpenLibrary ( "asl.library", 37 )) - { - /* Allocate screenmode requester */ - if ( req = AllocAslRequestTags( ASL_ScreenModeRequest, TAG_DONE )) - { - /* Open screenmode requester */ - if ( AslRequestTags( req, TAG_DONE )) - { - /* Store font name and size */ - sprintf( str, "0x%X", req->sm_DisplayID ); - } - /* Free requester */ - FreeAslRequest( req ); - } - /* Close asl.library */ - CloseLibrary( AslBase ); - } -} - -///} -///{ "read_prefs()" - -int read_prefs( void ) -{ - BPTR file; - char line[ 256 ]; - char fname[ 256 ]; - char *tmp, *s; - int len; - int fsize; - int val; - struct TextAttr attr; - term_data *td; - - /* Open config file */ - if (( file = Open( WPRF, MODE_OLDFILE )) == NULL ) - { - fprintf( stderr, "\nUnable to open file '%s'.\n", WPRF ); - return ( FALSE ); - } - - /* Read next line from file */ - while ( FGets( file, line, 256 )) - { - /* Cut off comments */ - if ( tmp = strchr( line, ';' )) * tmp = 0; - - /* Length of line */ - len = strlen( line ); - - /* Cut off trailing newline and blanks */ - for ( tmp = line + len - 1; len > 0 && ( *tmp == '\n' || *tmp == ' ' ); len-- ) *tmp-- = 0; - - /* Ignore blank lines */ - if ( len == 0 ) continue; - - /* Extract term */ - if ( strncmp( line, "MAIN.", 5 ) == 0 ) td = &screen; - else if ( strncmp( line, "CHOICE.", 7 ) == 0 ) td = &choice; - else if ( strncmp( line, "RECALL.", 7 ) == 0 ) td = &recall; - else if ( strncmp( line, "MIRROR.", 7 ) == 0 ) td = &mirror; - else if ( strncmp( line, "SCREEN.", 7 ) != 0 && - strncmp( line, "ANGBAND.", 8 ) != 0 ) - { - printf( "PREFS: Error in line '%s'\n", line ); - continue; - } - - /* Find start of option */ - tmp = strchr( line, '.' ) + 1; - - /* Ignore blank options */ - if ( *tmp == 0 ) continue; - - /* Option 'use' - Use this term */ - if ( !strncmp( tmp, "use", 3 )) - { - td->use = yesno( tmp + 3 ); - } - - /* Option 'cols' - Set number of columns for term */ - else if ( !strncmp( tmp, "cols", 4 ) && sscanf( tmp + 4, "%d", &val )) td->cols = val; - - /* Option 'rows' - Set number of rows for term */ - else if ( !strncmp( tmp, "rows", 4 ) && sscanf( tmp + 4, "%d", &val )) td->rows = val; - - /* Option 'xpos' - Set horizontal position for window */ - else if ( !strncmp( tmp, "xpos", 4 ) && sscanf( tmp + 4, "%d", &val )) td->wx = val; - - /* Option 'ypos' - Set vertical position for window */ - else if ( !strncmp( tmp, "ypos", 4 ) && sscanf( tmp + 4, "%d", &val )) td->wy = val; - - /* Option 'name' - Set window title */ - else if ( !strncmp( tmp, "title", 5 )) - { - /* Get parameter */ - stripstr( tmp + 5, fname ); - - /* Make a copy of the title */ - if ( strlen( fname ) > 0 ) - { - td->name = strdup( fname ); - } - - /* Don't use a title bar on this window */ - else - { - td->notitle = TRUE; - } - - continue; - } - - /* Option 'font' - Set font for this window */ - else if ( !strncmp( tmp, "font", 4 )) - { - /* Get value */ - stripstr( tmp + 4, fname ); - - /* Ask for font? */ - if ( !strcmp( fname, "?" )) - { - /* Open font requester */ - request_font( fname ); - } - - /* No font specification given */ - if ( strlen( fname ) == 0 ) - { - /* Main window */ - if ( td == &screen ) - { - /* System default font */ - td->font = GfxBase->DefaultFont; - - /* Use default font as screen font */ - scrattr = NULL; - } - - /* Extra window */ - else - { - /* Copy main window's font */ - td->font = screen.font; - } - - /* Set font dimensions */ - td->fw = td->font->tf_XSize; - td->fh = td->font->tf_YSize; - td->fb = td->font->tf_Baseline; - - /* This font is not opened by us */ - td->ownf = FALSE; - - /* Next line */ - continue; - } - - /* Get name and size */ - else - { - /* Find font name/size delimiter */ - if (( s = strchr( fname, '/' )) == NULL ) - { - printf( "\nPREFS: Illegal font specification: '%s'.\n", fname ); - continue; - } - - /* End fontname here */ - *s++ = 0; - - /* Convert size string to integer */ - fsize = atoi( s ); - - /* Make sure the font name ends with .font */ - if ( !strstr( fname, ".font" )) strcat( fname, ".font" ); - } - - /* Set font attributes */ - attr.ta_Name = fname; - attr.ta_YSize = fsize; - attr.ta_Style = FS_NORMAL; - attr.ta_Flags = ( !strcmp( fname, "topaz.font" ) && ( fsize == 8 || fsize == 9 )) ? - FPF_ROMFONT : FPF_DISKFONT; - - /* Open font from disk */ - if ( td->font = OpenDiskFont( &attr )) - { - /* We own this font */ - td->ownf = TRUE; - - /* Set font dimensions */ - td->fw = td->font->tf_XSize; - td->fh = td->font->tf_YSize; - td->fb = td->font->tf_Baseline; - - /* Copy font attr to screen font */ - if ( td == &screen ) - { - scrattr->ta_Name = strdup( fname ); - scrattr->ta_YSize = fsize; - scrattr->ta_Style = FS_NORMAL; - scrattr->ta_Flags = attr.ta_Flags; - } - } - - /* The font could not be opened */ - else - { - /* Fallback to default font */ - td->font = GfxBase->DefaultFont; - - /* Use default font as screen font */ - scrattr = NULL; - - /* Output error message */ - printf( "\nUnable to open font '%s/%d'.\n", fname, fsize ); - } - } - - /* Option .name - Set public screen name. KS 3.0+ required */ - else if ( !strncmp( tmp, "name", 4 ) && v39 ) - { - /* Copy name */ - stripstr( tmp + 4, modestr ); - } - - /* Option .mode - Set custom screen mode */ - else if ( !strncmp( tmp, "mode", 4 )) - { - /* If a public screen was also specified, check if it exist */ - if ( strlen( modestr ) > 0 ) - { - /* Don't lock it twice */ - if ( pubscr ) continue; - - /* Try to lock the named public screen */ - if ( pubscr = LockPubScreen( modestr )) - { - /* We got a lock now */ - publock = TRUE; - - /* Screen exist. Skip this option */ - continue; - } - } - - /* Get parameter */ - stripstr( tmp + 4, modestr ); - - /* Ask for mode? */ - if ( !strcmp( modestr, "?" )) - { - /* Open screenmode requester */ - request_mode( modestr ); - } - } - - /* Option .blankmouse - Use mouseblanking */ - else if ( !strncmp( tmp, "blankmouse", 10 )) - { - blankmouse = yesno( tmp + 10 ); - } - - /* Option .blankmouse - Use intuition menus */ - else if ( !strncmp( tmp, "menus", 5 )) - { - use_menus = yesno( tmp + 5 ); - } - - else if ( !strncmp( tmp, "sound", 5 )) - { - use_sound = yesno( tmp + 5 ); - } - - else if ( !strncmp( tmp, "gfx", 3 )) - { - use_graphics = yesno( tmp + 5 ); - } - - /* Unknown option */ - else - { - /* Output error message */ - printf ( "\nPREFS: Unknown option '%s'.\n", tmp ); - } - } - - /* Close the file */ - Close( file ); -} - -///} -///{ "amiga_nuke()" - Free all allocated resources - -static void amiga_nuke( term *t ) -{ - if ( t == term_screen ) - { - amiga_fail( NULL ); - /* Flush the output */ - fflush( stdout ); - } -} - -///} -///{ "amiga_open()" - Initialize terminal - -static void amiga_open( term *t ) -{ - /* Nothing to do here */ -} - -///} -///{ "amiga_curs()" - Move the cursor to a new location - -static errr amiga_curs( int x, int y ) -{ - term_data *td = term_curs; - - if ( td->cursor_visible ) - { - cursor_off( td ); - } - - td->cursor_xpos = x; - td->cursor_ypos = y; - td->cursor_frame = 0; - - if ( td->cursor_visible ) - { - cursor_on( td ); - } - - return ( 0 ); -} - -///} -///{ "amiga_wipe()" - Erase a part of a line - -static errr amiga_wipe( int x, int y, int n ) -{ - term_data *td = (term_data*)(Term->data); - - if (( n > 0 ) && !iconified ) - { - /* Erase rectangular area on screen */ - SetAPen( td->rp, PEN( 0 ) ); - RectFill( td->rp, x * td->fw, y * td->fh, ( x + n ) * td->fw - 1, ( y + 1 ) * td->fh - 1 ); - } - - return ( 0 ); -} - -///} -///{ "amiga_clear()" - Clear whole window - -static errr amiga_clear( void ) -{ - term_data *td = (term_data*)(Term->data); - - /* Fill window with background color */ - SetRast( td->rp, PEN( 0 )); - - return ( 0 ); -} - -///} -///{ "amiga_pict()" - Place one tile on the screen - -static errr amiga_pict( int x, int y, byte a, char c ) -{ - term_data *td = (term_data*)(Term->data); - char s[2]; - - /* Graphical tile */ - if ( a & 0x80 ) - { - put_gfx( td->rp, x, y, c & 0x7f, a & 0x7f ); - } - - /* Textual character */ - else - { - s[0] = c; - s[1] = 0; - SetAPen( td->rp, PEN( a & 0x0f )); - SetBPen( td->rp, PEN( 0 )); - Move( td->rp, x * td->fw, y * td->fh + td->fb ); - Text( td->rp, (char *) s, 1 ); - } - - return ( 0 ); -} - -///} -///{ "amiga_text()" - Place some text on the screen using an attribute - -static errr amiga_text( int x, int y, int n, byte a, cptr s ) -{ - term_data *td = (term_data*)(Term->data); - int i; - - if ( x >= 0 && y >= 0 && n > 0 && !iconified ) - { - /* Draw gfx one char at a time */ - if (( a & 0xc0 )) - { - for ( i = 0; i < n; i++ ) put_gfx( td->rp, x + i, y, s[ i ] & 0x7f, a & 0x7f ); - } - - /* Draw the string on screen */ - else - { - SetAPen( td->rp, PEN( a&0x0f )); - SetBPen( td->rp, PEN( 0 )); - Move( td->rp, x * td->fw, y * td->fh + td->fb ); - Text( td->rp, (char *) s, n ); - } - } - - return ( 0 ); -} - -///} -///{ "amiga_xtra()" - Handle a "special request" - -static errr amiga_xtra( int n, int v ) -{ - term_data *td = (term_data*)(Term->data); - - /* Analyze the request */ - switch ( n ) - { - /* Wait for event */ - case TERM_XTRA_EVENT: - - return ( amiga_event( v )); - - - /* Flush input */ - case TERM_XTRA_FLUSH: - - return ( amiga_flush( v )); - - - /* Make a noise */ - case TERM_XTRA_CLEAR: - - return ( amiga_clear()); - - - /* Change cursor visibility */ - case TERM_XTRA_SHAPE: - - /* Cursor on */ - if ( v ) - { - cursor_on( td ); - td->cursor_visible = TRUE; - } - /* Cursor off */ - else - { - cursor_off( td ); - td->cursor_visible = FALSE; - } - return ( 0 ); - - - /* Flash screen */ - case TERM_XTRA_NOISE: - - DisplayBeep( use_pub ? pubscr : amiscr ); - return ( 0 ); - - - /* Play a sound */ - case TERM_XTRA_SOUND: - - if ( has_sound ) - { - play_sound( v ); - } - return ( 0 ); - - - /* React on global changes */ - case TERM_XTRA_REACT: - - return ( amiga_react( v )); - - - case TERM_XTRA_LEVEL: - - term_curs = td; - return ( 0 ); - - case TERM_XTRA_DELAY: - - if (v >= 20) Delay(v / 20); - return (0); - - /* Unknown request type */ - default: - - return ( 1 ); - - } - - /* Shouldn't be able to get here */ - return ( 1 ); -} - -///} -///{ "amiga_flush()" - Flush input buffer - -static errr amiga_flush( int v ) -{ - struct IntuiMessage *imsg; - - /* Ignore all messages at the port */ - while ( imsg = (struct IntuiMessage *) GetMsg( screen.win->UserPort )) - { - ReplyMsg(( struct Message *) imsg ); - } - - return ( 1 ); -} - -///} -///{ "amiga_event()" - Wait for an event, and handle it. - -static errr amiga_event( int v ) -{ - struct IntuiMessage *imsg; - ULONG iclass; - UWORD icode; - UWORD iqual; - APTR iaddr; - - /* Check for messages to the window */ - if (( imsg = (struct IntuiMessage *) GetMsg( screen.win->UserPort )) == NULL ) - { - /* If we don't want blocking, return */ - if ( !v ) - { - return ( 0 ); - } - - /* No messages, so wait for one */ - Wait( 1 << screen.win->UserPort->mp_SigBit ); - - /* Get the new message */ - imsg = (struct IntuiMessage *) GetMsg( screen.win->UserPort ); - } - - /* Handle message */ - if ( imsg ) - { - /* Get message attributes */ - iclass = imsg->Class; - icode = imsg->Code; - iqual = imsg->Qualifier; - iaddr = imsg->IAddress; - - /* Update menus before displaying */ - if ( iclass == IDCMP_MENUVERIFY && icode == MENUHOT && use_menus ) - { - update_menus(); - } - - /* Reply the message */ - ReplyMsg(( struct Message *) imsg ); - - /* Do we have a keypress? */ - if ( iclass == IDCMP_RAWKEY ) - { - handle_rawkey( icode, iqual, iaddr ); - return ( 0 ); - } - - /* Mouse event - Make pointer visible */ - if ( iclass == IDCMP_MOUSEMOVE || - iclass == IDCMP_MOUSEBUTTONS || - iclass == IDCMP_MENUVERIFY ) - { - if ( blankmouse && !pointer_visible ) - { - ClearPointer( screen.win ); - pointer_visible = TRUE; - } - - return ( 0 ); - } - - /* Time for some cursor anim? */ - if ( iclass == IDCMP_INTUITICKS ) - { - cursor_anim(); - return ( 0 ); - } - - /* Menu item picked? */ - if ( iclass == IDCMP_MENUPICK ) - { - handle_menupick( icode ); - } - - /* Unknown message class */ - return ( 1 ); - } - - /* No events */ - return ( 1 ); -} - -///} -///{ "amiga_react()" - -static errr amiga_react( int v ) -{ - /* Apply color palette, in case it has changed */ - load_palette(); - - /* Create menus if we don't have any */ - if ( !menu && use_menus ) - { - create_menus(); - } - - return ( 0 ); -} - -///} -///{ "amiga_tomb()" - -int amiga_tomb( void ) -{ - cptr p; - char tmp[160]; - time_t ct = time((time_t)0); - BPTR file; - - char *pp; - int plane, row, error = FALSE; - struct BitMap *filebm, *scalbm, *convbm; - long stdpens[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; - int depth; - BYTE *src, *dst; - int byt; - - int tw = screen.fw * 64; - int th = screen.fh * 21; - - /* Allocate bitmap for tomb graphics file */ - if (( filebm = alloc_bitmap( 512, 168, 4, BMF_CLEAR, screen.rp->BitMap )) == NULL ) - { - return ( FALSE ); - } - - /* Open tomb file */ - if (( file = Open( MTOM, MODE_OLDFILE )) == NULL ) - { - free_bitmap( filebm ); - return ( FALSE ); - } - - /* Read file into bitmap */ - for ( plane = 0; plane < 4 && !error; plane++ ) - { - pp = filebm->Planes[ plane ]; - for ( row = 0; row < 168 && !error; row++ ) - { - error = ( Read( file, pp, 64 ) != 64 ); - pp += filebm->BytesPerRow; - } - } - - /* Close tomb file */ - Close( file ); - - /* Get depth of display */ - depth = depth_of_bitmap( screen.rp->BitMap ); - - /* Remapping needed? */ - if ( depth != 4 || use_pub ) - { - /* Allocate bitmap for remapped image */ - if (( convbm = alloc_bitmap( 512, 168, depth, BMF_CLEAR, screen.rp->BitMap )) == NULL ) - { - free_bitmap( filebm ); - return ( FALSE ); - } - - /* Simple remapping from 4 to 5 planes? */ - if ( depth == 5 && !use_pub ) - { - for ( plane = 0; plane < 4; plane++ ) - { - src = filebm->Planes[ plane ]; - dst = convbm->Planes[ plane ]; - for ( row = 0; row < 168; row++ ) - { - for ( byt = 0; byt < 64; byt++ ) - { - dst[ byt ] = src[ byt ]; - } - src += filebm->BytesPerRow; - dst += convbm->BytesPerRow; - } - } - } - - /* Complex remapping */ - else - { - /* Remap old bitmap into new bitmap */ - remap_bitmap( filebm, convbm, use_pub ? pubpens : stdpens, 512, 168 ); - } - - /* Free original bitmap */ - free_bitmap( filebm ); - } - - /* No remapping needed */ - else - { - convbm = filebm; - } - - /* Allocate bitmap for scaled graphics */ - if (( scalbm = alloc_bitmap( tw, th, depth, BMF_CLEAR, screen.rp->BitMap )) == NULL ) - { - free_bitmap( convbm ); - return ( FALSE ); - } - - /* Scale the tomb bitmap */ - scale_bitmap( convbm, 512, 168, scalbm, tw, th ); - - /* Free old bitmap */ - free_bitmap( convbm ); - - /* Copy the tomb graphics to the screen, centered */ - BltBitMapRastPort( scalbm, 0, 0, screen.rp, ( screen.ww - tw ) / 2, 0, tw, th, 0xc0 ); - - /* Free bitmap */ - free_bitmap( scalbm ); - - /* King or Queen */ - if (total_winner || (p_ptr->lev > PY_MAX_LEVEL)) - { - p = "Magnificent"; - } - - /* Normal */ - else - { - p = player_title[p_ptr->pclass][(p_ptr->lev - 1) / 5]; - } - - tomb_str( 3, " R.I.P." ); - - tomb_str( 5, player_name ); - - tomb_str( 6, "the" ); - - tomb_str( 7, (char *)p ); - - tomb_str( 9, (char *)cp_ptr->title ); - - sprintf( tmp, "Level: %d", (int)p_ptr->lev ); - tomb_str( 10, tmp ); - - sprintf( tmp, "Exp: %ld", (long)p_ptr->exp ); - tomb_str( 11, tmp ); - - sprintf( tmp, "AU: %ld", (long)p_ptr->au ); - tomb_str( 12, tmp ); - - sprintf( tmp, "Killed on Level %d", dun_level ); - tomb_str( 13, tmp ); - - sprintf( tmp, "by %s", died_from ); - tomb_str( 14, tmp ); - - sprintf( tmp, "%-.24s", ctime(&ct)); - tomb_str( 16, tmp ); - - return ( TRUE ); -} - -///} -///{ "tomb_str()" - -void tomb_str( int y, char *str ) -{ - term_data *td = &screen; - int l = strlen( str ); - int xp = ( 39 * td->fw ) - (( l + 1 ) * td->fw ) / 2; - - SetDrMd( td->rp, JAM1 ); - - SetAPen( td->rp, PEN( 1 )); - Move( td->rp, xp + 1, y * td->fh + td->fb + 1 ); - Text( td->rp, str, l ); - - SetAPen( td->rp, PEN( 0 )); - Move( td->rp, xp, y * td->fh + td->fb ); - Text( td->rp, str, l ); - - SetDrMd( td->rp, JAM2 ); -} - -///} -///{ "handle_rawkey()" - -void handle_rawkey( UWORD code, UWORD qual, APTR addr ) -{ - char buf[ 80 ]; - int i; - int len; - UWORD q; - - /* Use a blank mouse-pointer on this window */ - if ( blankmouse && pointer_visible ) - { - SetPointer( screen.win, blankpointer, 2, 16, 0, 0 ); - pointer_visible = FALSE; - } - - /* Numeric keypad pressed with qualifier? */ - if (( qual & IEQUALIFIER_NUMERICPAD ) && ( qual & 0xff )) - { - /* Direction key? (1,2,3,4,6,7,8,9) */ - if (( code >= 0x1d && code <= 0x1f ) || - ( code == 0x2d || code == 0x2f ) || - ( code >= 0x3d && code <= 0x3f )) - { - /* Shift/Ctrl/Alt/Amiga keys */ - q = qual & 0xff; - - /* Shift + Direction */ - if ( q == IEQUALIFIER_LSHIFT || q == IEQUALIFIER_RSHIFT ) - { - /* Fake a keypress 'run' */ - Term_keypress( '.' ); - - /* Remove shift key from event */ - qual &= ~( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT ); - } - - /* Alt + Direction */ - else if ( q == IEQUALIFIER_LALT || q == IEQUALIFIER_RALT ) - { - /* Fake a keypress 'tunnel' */ - Term_keypress( 'T' ); - - /* Remove alt key from event */ - qual &= ~( IEQUALIFIER_LALT | IEQUALIFIER_RALT ); - } - - /* Ctrl + Direction */ - else if ( q == IEQUALIFIER_CONTROL ) - { - /* Fake a keypress 'open' */ - Term_keypress( 'o' ); - - /* Remove ctrl key from event */ - qual &= ~IEQUALIFIER_CONTROL; - } - } - } - - /* Convert raw keycode to ANSI sequence */ - ie.ie_Code = code; - ie.ie_Qualifier = qual; - ie.ie_EventAddress = (APTR *) * ((ULONG *) addr ); - len = MapRawKey( &ie, buf, 80, NULL ); - - /* Send ANSI sequence to meta-terminal */ - for ( i = 0; i < len; i++ ) - { - if ( !iconified ) - { - Term_keypress( (unsigned char) buf[ i ]); - } - } -} - -///} -///{ "handle_menupick()" - -void handle_menupick( int mnum ) -{ - struct MenuItem *item; - ULONG ud; - int i; - - /* Be sure to handle all selections */ - while ( mnum != MENUNULL ) - { - /* Find address of menuitem */ - item = ItemAddress( menu, mnum ); - - /* Find userdata of menuitem */ - ud = (ULONG) GTMENUITEM_USERDATA( item ); - - /* Is this a help item? */ - if ( ud >= MNU_HELP ) - { - /* Send keypresses */ - Term_keypress( '\\' ); - Term_keypress( '?' ); - Term_keypress( ud - MNU_HELP ); - } - - /* Is this an option item? */ - else if ( ud >= MNU_OPTION ) - { - /* Option index */ - i = ud - MNU_OPTION; - - /* Set option according to checkmark status */ - *options[ i ].o_var = item->Flags & CHECKED ? TRUE : FALSE; - - /* Fake a dummy keypress to cause update */ - Term_keypress( ' ' ); - } - - /* Control key shortcuts */ - else if ( ud >= MNU_CKEYCOM ) - { - /* Send keycode */ - Term_keypress( '\\' ); - Term_keypress( '^' ); - Term_keypress( ud - MNU_CKEYCOM ); - } - - /* Key shortcuts */ - else if ( ud >= MNU_KEYCOM ) - { - /* Key code */ - i = ud - MNU_KEYCOM; - - /* Some functions need underlying keymap */ - if ( i != 't' && i != 'w' && i != 'T' ) - { - Term_keypress( '\\' ); - } - - /* Send keycode */ - Term_keypress( i ); - } - - /* Scaled down Map of the dungeon */ - else if ( ud == MNU_SCALEDMAP ) - { - /* Draw the map */ - amiga_map(); - } - - /* Find next menunumber */ - mnum = item->NextSelect; - } -} - -///} -///{ "cursor_on()" - -static void cursor_on( term_data *td ) -{ - int x0, y0, x1, y1; - - if ( !td->cursor_lit && !iconified ) - { - td->cursor_frame = 0; - - /* Hack - Don't draw cursor at (0,0) */ - if ( td->cursor_xpos == 0 && td->cursor_ypos == 0 ) return; - - /* Draw an outlined cursor */ - if ( CUR_A & 0xf0 && use_graphics ) - { - x0 = td->cursor_xpos * td->fw; - y0 = td->cursor_ypos * td->fh; - x1 = x0 + td->fw - 1; - y1 = y0 + td->fh - 1; - SetAPen( td->wrp, PEN( CURSOR_PEN )); - Move( td->wrp, x0, y0 ); - Draw( td->wrp, x1, y0 ); - Draw( td->wrp, x1, y1 ); - Draw( td->wrp, x0, y1 ); - Draw( td->wrp, x0, y0 ); - } - - /* Draw a filled cursor */ - else - { - SetAPen( td->wrp, PEN( CUR_A & 0x0f )); - SetBPen( td->wrp, PEN( CURSOR_PEN )); - Move( td->wrp, td->fw * td->cursor_xpos, td->fh * td->cursor_ypos + td->fb ); - Text( td->wrp, &CUR_C, 1 ); - } - - td->cursor_lit = TRUE; - } -} - -///} -///{ "cursor_off()" - -static void cursor_off( term_data *td ) -{ - if ( td->cursor_lit && !iconified ) - { - /* Restore graphics under cursor */ - if ( CUR_A & 0xf0 && use_graphics ) - { - put_gfx( td->wrp, td->cursor_xpos, td->cursor_ypos, CUR_C, CUR_A ); - } - - /* Restore char/attr under cursor */ - else - { - SetAPen( td->wrp, PEN( CUR_A & 0x0f )); - SetBPen( td->wrp, PEN( 0 )); - Move( td->wrp, td->fw * td->cursor_xpos, td->fh * td->cursor_ypos + td->fb ); - Text( td->wrp, &CUR_C, 1 ); - } - td->cursor_lit = FALSE; - } -} - -///} -///{ "cursor_anim()" - -static void cursor_anim( void ) -{ - term_data *td = term_curs; - int x0, y0, x1, y1, i = p_ptr->px, j = p_ptr->py; - byte tc, ta; - - if ( !term_curs ) return; - - td->cursor_frame = ++(td->cursor_frame) % 8; - - /* Small cursor on map */ - if ( td->cursor_map ) - { - if ( td->cursor_frame & 2 ) - { - SetAPen( td->wrp, PEN( CURSOR_PEN )); - RectFill( td->wrp, - td->map_x + i * td->mpt_w, - td->map_y + j * td->mpt_h, - td->map_x + ( i + 1) * td->mpt_w - 1, - td->map_y + ( j + 1 ) * td->mpt_h - 1 - ); - } - else - { - ta = (( p_ptr->pclass * 10 + p_ptr->prace) >> 5 ) + 12; - tc = (( p_ptr->pclass * 10 + p_ptr->prace) & 0x1f ); - put_gfx_map( td, i, j, tc, ta ); - } - } - - else if ( td->cursor_visible && !iconified ) - { - /* Hack - Don't draw cursor at (0,0) */ - if ( td->cursor_xpos == 0 && td->cursor_ypos == 0 ) return; - - /* Draw an outlined cursor */ - if ( CUR_A & 0x80 && use_graphics ) - { - /* First draw the tile under cursor */ - put_gfx( td->wrp, td->cursor_xpos, td->cursor_ypos, CUR_C, CUR_A ); - - if ( td->cursor_frame < 4 ) - { - x0 = td->cursor_xpos * td->fw; - y0 = td->cursor_ypos * td->fh; - x1 = x0 + td->fw - 1; - y1 = y0 + td->fh - 1; - SetAPen( td->wrp, PEN( CURSOR_PEN )); - Move( td->wrp, x0, y0 ); - Draw( td->wrp, x1, y0 ); - Draw( td->wrp, x1, y1 ); - Draw( td->wrp, x0, y1 ); - Draw( td->wrp, x0, y0 ); - } - } - - /* Draw a filled cursor */ - else - { - SetAPen( td->wrp, PEN( CUR_A & 0x0f )); - SetBPen( td->wrp, ( td->cursor_frame < 4 ) ? PEN( CURSOR_PEN ) : PEN( 0 )); - Move( td->wrp, td->fw * td->cursor_xpos, td->fh * td->cursor_ypos + td->fb ); - Text( td->wrp, &CUR_C, 1 ); - } - } -} - -///} -///{ "load_gfx()" - -int load_gfx( void ) -{ - term_data *ts = &screen; - BPTR file; - char *p; - int plane, row, error = FALSE; - - /* Allocate bitmaps */ - if (( ts->gfxbm = alloc_bitmap( GFXW, GFXH, 4, BMF_CLEAR, ts->rp->BitMap )) == NULL ) return ( FALSE ); - if (( ts->mskbm = alloc_bitmap( GFXW, GFXH, 1, BMF_CLEAR, ts->rp->BitMap )) == NULL ) return ( FALSE ); - - /* Open file */ - if (( file = Open( MGFX, MODE_OLDFILE )) == NULL ) - { - MSG( 0, 0, "Unable to open graphics file" ); - Delay( 100 ); - return ( FALSE ); - } - - /* Read file into bitmap */ - for ( plane = 0; plane < 4 && !error; plane++ ) - { - p = ts->gfxbm->Planes[ plane ]; - for ( row = 0; row < GFXH && !error; row++ ) - { - error = ( Read( file, p, GFXB ) != GFXB ); - p += ts->gfxbm->BytesPerRow; - } - } - - /* Read mask data into bitmap */ - p = ts->mskbm->Planes[ 0 ]; - for ( row = 0; row < GFXH && !error; row++ ) - { - error = ( Read( file, p, GFXB ) != GFXB ); - p += ts->mskbm->BytesPerRow; - } - - /* Close file */ - Close( file ); - - /* Did we get any errors while reading? */ - if ( error ) - { - MSG( 0, 0, "Error while reading graphics file" ); - Delay( 100 ); - return ( FALSE ); - } - - /* Success */ - return ( TRUE ); -} -///} -///{ "conv_gfx()" - -int conv_gfx( void ) -{ - term_data *ts = &screen; - struct BitMap *tmpbm; - struct BitMap *sbm = ts->rp->BitMap; - long stdpens[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; - long mskpens[] = { 0, -1 }; - int depth; - BYTE *src, *dst; - int plane, row, byt; - - /* Get depth of display */ - depth = depth_of_bitmap( sbm ); - - /* We don't want 16 or 24 bit displays (yet) */ - if ( depth > 8 ) - { - MSG( 0, 1, "Sorry, max. 8 bit display supported." ); - Delay( 100 ); - return ( FALSE ); - } - - /* Allocate new bitmap with screen's depth */ - if (( tmpbm = alloc_bitmap( GFXW, GFXH, depth, BMF_CLEAR, sbm )) == NULL ) - { - MSG( 0, 1, "Unable to allocate temporary bitmap." ); - Delay( 100 ); - return ( FALSE ); - } - - /* Simple remapping from 4 to 5 planes? */ - if ( depth == 5 && !use_pub ) - { - for ( plane = 0; plane < 4; plane++ ) - { - src = ts->gfxbm->Planes[ plane ]; - dst = tmpbm->Planes[ plane ]; - for ( row = 0; row < GFXH; row++ ) - { - for ( byt = 0; byt < GFXB; byt++ ) - { - dst[ byt ] = src[ byt ]; - } - src += ts->gfxbm->BytesPerRow; - dst += tmpbm->BytesPerRow; - } - } - } - - /* Complex remapping */ - else - { - /* Remap old bitmat into new bitmap */ - remap_bitmap( ts->gfxbm, tmpbm, use_pub ? pubpens : stdpens, GFXW, GFXH ); - } - - /* Free old bitmap */ - free_bitmap( ts->gfxbm ); - ts->gfxbm = tmpbm; - - /* Allocate new bitmap with screen's depth */ - if (( tmpbm = alloc_bitmap( GFXW, GFXH, depth, BMF_CLEAR, sbm )) == NULL ) - { - MSG( 0, 1, "Unable to allocate temporary bitmap." ); - Delay( 100 ); - return ( FALSE ); - } - - /* Simple remapping from 4 to 5 planes? */ - if ( depth == 5 && !use_pub ) - { - for ( plane = 0; plane < 4; plane++ ) - { - src = ts->mskbm->Planes[ 0 ]; - dst = tmpbm->Planes[ plane ]; - for ( row = 0; row < GFXH; row++ ) - { - for ( byt = 0; byt < GFXB; byt++ ) - { - dst[ byt ] = src[ byt ]; - } - src += ts->mskbm->BytesPerRow; - dst += tmpbm->BytesPerRow; - } - } - } - - /* Complex remapping */ - else - { - /* Remap old bitmap into new bitmap */ - remap_bitmap( ts->mskbm, tmpbm, mskpens, GFXW, GFXH ); - } - - /* Free old bitmap */ - free_bitmap( ts->mskbm ); - ts->mskbm = tmpbm; - - /* Done */ - return ( TRUE ); -} - -///} -///{ "size_gfx()" - -int size_gfx( term_data *td ) -{ - term_data *ts = &screen; - int depth; - struct BitMap *sbm = td->rp->BitMap; - struct BitMap *tmpbm; - - /* Calculate tile bitmap dimensions */ - td->gfx_w = 32 * td->fw; - td->gfx_h = 32 * td->fh; - - /* Calculate map bitmap dimensions */ - td->mpt_w = td->ww / MAX_WID; - td->mpt_h = td->wh / MAX_HGT; - td->map_w = td->mpt_w * 32; - td->map_h = td->mpt_h * 32; - - /* Scale tile graphics into map size */ - depth = depth_of_bitmap( ts->gfxbm ); - if (( td->mapbm = alloc_bitmap( td->map_w, td->map_h, depth, BMF_CLEAR, sbm )) == NULL ) return ( FALSE ); - scale_bitmap( ts->gfxbm, GFXW, GFXH, td->mapbm, td->map_w, td->map_h ); - - /* Scale tile graphics */ - depth = depth_of_bitmap( ts->gfxbm ); - if (( tmpbm = alloc_bitmap( td->gfx_w, td->gfx_h, depth, BMF_CLEAR, sbm )) == NULL ) return ( FALSE ); - scale_bitmap( ts->gfxbm, GFXW, GFXH, tmpbm, td->gfx_w, td->gfx_h ); - if ( td->gfxbm ) free_bitmap( td->gfxbm ); - td->gfxbm = tmpbm; - - /* Scale tile mask */ - depth = depth_of_bitmap( ts->mskbm ); - if (( tmpbm = alloc_bitmap( td->gfx_w, td->gfx_h, depth, BMF_CLEAR, sbm )) == NULL ) return ( FALSE ); - scale_bitmap( ts->mskbm, GFXW, GFXH, tmpbm, td->gfx_w, td->gfx_h ); - if ( td->mskbm ) free_bitmap( td->mskbm ); - td->mskbm = tmpbm; - - /* Success */ - return ( TRUE ); -} - -///} -///{ "put_gfx()" - -static void put_gfx( struct RastPort *rp, int x, int y, int chr, int col ) -{ - term_data *td = (term_data*)(Term->data); - int fw = td->fw; - int fh = td->fh; - int x0 = x * fw; - int y0 = y * fh; - int x1 = x0 + fw - 1; - int y1 = y0 + fh - 1; - int a = col & 0x1f; - int c = chr & 0x1f; - - /* Just a black tile */ - if ( a == 0 && c == 0 ) - { - SetAPen( rp, PEN( 0 )); - RectFill( rp, x0, y0, x1, y1 ); - return; - } - - /* Player - Remap for race and class */ - if ( a == 12 && c == 0 ) - { - a = (( p_ptr->pclass * 10 + p_ptr->prace) >> 5 ) + 12; - c = (( p_ptr->pclass * 10 + p_ptr->prace) & 0x1f ); - } - - /* Draw tile through mask */ - if ( col & 0x40 ) - { - SetAPen( rp, PEN(0) ); - RectFill( rp, x0, y0, x1, y1 ); - BltMaskBitMapRastPort( td->gfxbm, c * fw, a * fh, rp, x0, y0, fw, fh, (ABC | ANBC | ABNC), td->mskbm->Planes[ 0 ] ); - } - - /* Draw full tile */ - else - { - BltBitMapRastPort( td->gfxbm, c * fw, a * fh, rp, x0, y0, fw, fh, 0xc0 ); - } -} - -///} -///{ "amiga_fail()" - -static int amiga_fail( char *msg ) -{ - int i; - - /* Print error message */ - if ( msg ) - { - fprintf( stderr, "%s\n", msg ); - } - - /* Free sound memory */ - free_sound(); - - /* Unlock public screen */ - if ( publock ) - { - UnlockPubScreen( NULL, pubscr ); - publock = FALSE; - } - - /* Remove menu from window */ - if ( menu && screen.win ) - { - ClearMenuStrip( screen.win ); - } - - /* Free menus */ - if ( menu ) - { - FreeMenus( menu ); - menu = NULL; - } - - /* Free term resources */ - free_term( &mirror ); - free_term( &recall ); - free_term( &choice ); - free_term( &screen ); - - /* Free obtained pens */ - if ( pubscr ) - { - for ( i = 0; i < 32; i++) - { - if ( pubpens[ i ] != -1 ) - { - ReleasePen( pubscr->ViewPort.ColorMap, pubpens[ i ]); - } - } - } - - /* Free visual info */ - if ( visinfo ) - { - FreeVisualInfo( visinfo ); - visinfo = NULL; - } - - /* Close intuition screen */ - if ( amiscr ) - { - CloseScreen( amiscr ); - amiscr = NULL; - } - - /* Close gadtools.library */ - if ( GadToolsBase ) - { - CloseLibrary( GadToolsBase ); - GadToolsBase = NULL; - } - - /* Close keymap.library */ - if ( KeymapBase ) - { - CloseLibrary( KeymapBase ); - KeymapBase = NULL; - } - - /* Close keymap.library */ - if ( DiskfontBase ) - { - CloseLibrary( DiskfontBase ); - DiskfontBase = NULL; - } - - // Return failure - return ( -1); -} - -///} -///{ "amiga_map()" - -static void amiga_map( void ) -{ - term_data *td = &screen; // (term_data*)(Term->data); - int i, j; - byte ta, tc; - - /* Only in graphics mode */ - if ( !use_graphics ) return; - - /* Turn off cursor */ - if ( td->cursor_visible ) cursor_off( td ); - - /* Save screen */ - Term_save(); - - /* Clear screen */ - Term_clear(); - Term_fresh(); - - /* Calculate offset values */ - td->map_x = (( td->fw * 80 ) - ( td->mpt_w * cur_wid )) / 2; - td->map_y = (( td->fh * 24 ) - ( td->mpt_h * cur_hgt )) / 2; - - /* Draw all "interesting" features */ - for ( i = 0; i < cur_wid; i++ ) - { - for ( j = 0; j < cur_hgt; j++ ) - { - /* Get frame tile */ - if ( i == 0 || i == cur_wid - 1 || j == 0 || j == cur_hgt - 1 ) - { - ta = f_info[ 63 ].z_attr; - tc = f_info[ 63 ].z_char; - } - - /* Get tile from cave table */ - else - { - map_info( j, i, &ta, (char *) &tc ); - } - - /* Ignore non-graphics */ - if ( ta & 0x80 ) - { - ta &= 0x1f; - tc &= 0x1f; - - /* Player XXX XXX XXX */ - if ( ta == 12 && tc == 0 ) - { - ta = (( p_ptr->pclass * 10 + p_ptr->prace ) >> 5 ) + 12; - tc = (( p_ptr->pclass * 10 + p_ptr->prace ) & 0x1f ); - } - - /* Put the graphics to the screen */ - put_gfx_map( td, i, j, tc, ta ); - } - } - } - - /* Draw a small cursor now */ - td->cursor_map = TRUE; - - /* Wait for a keypress, flush key buffer */ - Term_inkey( &tc, TRUE, TRUE ); - Term_flush(); - - /* Normal cursor again */ - td->cursor_map = FALSE; - - /* Restore screen */ - Term_clear(); - Term_fresh(); - Term_load(); - Term_fresh(); - - /* Turn cursor back on */ - if ( td->cursor_visible ) cursor_on( td ); -} - -///} -///{ "load_palette()" - -void load_palette( void ) -{ - int i; - int n; - - if ( amiscr == NULL ) return; - - n = deep ? 32 : 16; - - if ( v39 ) - { - palette32[ 0 ] = n << 16; - palette32[ n * 3 + 1 ] = 0; - for ( i = 0; i < n; i++ ) - { - palette32[ i * 3 + 1 ] = color_table[ use_graphics ? i : i + 16 ][ 1 ] << 24; - palette32[ i * 3 + 2 ] = color_table[ use_graphics ? i : i + 16 ][ 2 ] << 24; - palette32[ i * 3 + 3 ] = color_table[ use_graphics ? i : i + 16 ][ 3 ] << 24; - } - LoadRGB32( &amiscr->ViewPort, palette32 ); - } - else - { - for ( i = 0; i < n; i++ ) - { - palette4[ i ] = ( color_table[ use_graphics ? i : i + 16 ][ 1 ] >> 4 ) << 8; - palette4[ i ] |= ( color_table[ use_graphics ? i : i + 16 ][ 2 ] >> 4 ) << 4; - palette4[ i ] |= ( color_table[ use_graphics ? i : i + 16 ][ 3 ] >> 4 ); - } - LoadRGB4( &amiscr->ViewPort, palette4, n ); - } -} - -///} -///{ "create_menus()" - -int create_menus( void ) -{ - option_type *opt; - struct NewMenu *item = newmenu; - int nmsize = sizeof ( struct NewMenu ); - int page = -1; - int pg = 0; - int i, o; - - /* Copy all pre-items into array */ - for ( i = 0; pre_item[ i ].nm_Type != 255; i++ ) - { - memcpy( item++, &pre_item[ i ], nmsize ); - } - - /* Find next option */ - for ( opt = options, o = 0; opt->o_desc; opt++, o++ ) - { - /* Cheating options are skipped */ - if ( opt->o_page > 6 ) continue; - - /* New page of options? */ - if ( page != opt->o_page ) - { - page = opt->o_page; - - /* Copy option header */ - memcpy( item++, &opt_item[ pg++ ], nmsize ); - } - - /* Insert fields for this option */ - item->nm_Type = NM_SUB; - item->nm_CommKey = 0; - item->nm_MutualExclude = 0; - - /* Use option description as menu text */ - item->nm_Label = (STRPTR) opt->o_desc; - - /* Insert option index into userdata field */ - item->nm_UserData = (void *)( MNU_OPTION + o ); - - /* Use checkmark on this item */ - item->nm_Flags = CHECKIT | MENUTOGGLE; - - /* Done with this item */ - item++; - } - - /* Copy all post-items into array */ - for ( i = 0; post_item[ i ].nm_Type != 255; i++ ) - { - memcpy( item++, &post_item[ i ], nmsize ); - } - - /* Actually create the menu structures */ - menu = CreateMenus( newmenu, NULL ); - - if ( menu ) - { - /* Layout menus */ - if ( LayoutMenus( menu, visinfo, v39 ? GTMN_NewLookMenus : TAG_IGNORE, TRUE, TAG_END )) - { - /* Attach menu to window */ - SetMenuStrip( screen.win , menu ); - } - - /* Free menus */ - else - { - FreeMenus( menu ); - menu = NULL; - } - } - - /* Success */ - return ( menu != NULL ); -} - -///} -///{ "update_menus()" - -void update_menus( void ) -{ - struct MenuItem *father, *item; - int i; - - /* Require a window and a menu */ - if ( !screen.win || !menu ) return; - - /* Detach the menu from the window */ - // ClearMenuStrip( screen.win ); - - /* Initial menuitem and subitem for options */ - father = menu->FirstItem; - item = father->SubItem; - - /* Find next option */ - for ( i = 0; item && options[ i ].o_desc; i++ ) - { - /* Did we find it? */ - if ( item ) - { - /* Option is set, add a checkmark */ - if ( *(options[ i ].o_var )) - { - item->Flags |= CHECKED; - } - - /* Option is not set, remove checkmark */ - else - { - item->Flags &= ~CHECKED; - } - } - - /* Menuitem not found */ - else - { - fprintf( stderr, "ERROR: menuitem #%d not found.\n", i ); - return; - } - - /* Find next menuitem */ - if ((item = item->NextItem ) == NULL ) - { - /* New set */ - father = father->NextItem; - if ( father ) - { - item = father->SubItem; - } - } - } - - /* Enable/Disable the amiga map according to use_graphics */ - if ( item = ItemAddress( menu, FULLMENUNUM( 6, 7, 0 ))) - { - item->Flags = use_graphics ? item->Flags | ITEMENABLED : item->Flags & ~ITEMENABLED; - } - - /* Attach menu to window again */ - // ResetMenuStrip( screen.win, menu ); -} - -///} -///{ "init_sound()" - - -int init_sound( void ) -{ - int i; - char tmp[256]; - char buf[256]; - struct AmiSound *snd; - - /* Load samples */ - for ( i = 0; i < NSAMPLES; i++ ) - { - /* Pointer to sound data */ - snd = &sound_data[ i ]; - - /* Should this sample be loaded into memory? */ - if ( snd->Memory ) - { - /* Construct filename */ - path_build(buf, 255, ANGBAND_DIR_XTRA, "sound"); - - /* Construct filename */ - path_build(tmp, 255, buf, snd->Name ); - - /* Load the sample into memory */ - snd->Address = (struct SoundInfo *) PrepareSound( tmp ); - } - } - - /* Success */ - has_sound = TRUE; - use_sound = TRUE; - - return ( TRUE ); -} - -///} -///{ "free_sound()" - -void free_sound( void ) -{ - int i; - - /* Stop all channels */ - StopSound( LEFT0 ); - StopSound( LEFT1 ); - StopSound( RIGHT0 ); - StopSound( RIGHT1 ); - - /* Remove all sounds from memory */ - for ( i = 0; i < NSAMPLES; i++ ) - { - if ( sound_data[ i ].Address ) - { - /* Remove the sound from memory */ - RemoveSound( sound_data[ i ].Address ); - - /* Clear address field */ - sound_data[ i ].Address = NULL; - } - } - - /* Done */ - has_sound = FALSE; - use_sound = FALSE; -} - -///} -///{ "play_sound()" - -static void play_sound( int v ) -{ - struct AmiSound *snd; - struct AmiSound *old_snd; - int rate; - int channel; - int old; - char buf[256]; - char tmp[256]; - - if ( has_sound ) - { - /* Pointer to sound data */ - snd = &sound_data[ v ]; - - /* Channel number */ - channel = snd->Channel; - - /* Last sample played on channel */ - old = channel_last[ channel ]; - - /* Sample Rate */ - rate = snd->Rate; - - /* Random rate on some sounds */ - if ( v == SOUND_HIT || v == SOUND_MISS ) - { - rate = rate - 50 + rand_int( 150 ); - } - - /* Pointer to old sound data */ - old_snd = old >= 0 ? &sound_data[ old ] : NULL; - - /* Stop sound currently playing on this channel */ - StopSound( channel ); - - /* Free old sample if required */ - if ( !old_snd->Memory && old_snd->Address && old != v ) - { - /* Remove it from memory */ - RemoveSound( old_snd->Address ); - - /* Clear address field */ - old_snd->Address = NULL; - } - - /* Load new sample into memory if required */ - if ( !snd->Memory && snd->Address == NULL ) - { - /* Construct filename */ - path_build(buf, 255, ANGBAND_DIR_XTRA, "sound"); - - /* Construct filename */ - path_build(tmp, 255, buf, snd->Name ); - - /* Load the sample into memory */ - snd->Address = (struct SoundInfo *) PrepareSound( tmp ); - } - - /* Make sure the sample is loaded into memory */ - if ( snd->Address ) - { - /* Start playing the sound */ - PlaySound( snd->Address, snd->Volume, channel, rate, snd->Repeats ); - } - - /* Store sample number */ - channel_last[ channel ] = v; - } -} - -///} -///{ put_gfx_map() - -static void put_gfx_map( term_data *td, int x, int y, int c, int a ) -{ - BltBitMapRastPort( - td->mapbm, - c * td->mpt_w, - a * td->mpt_h, - td->wrp, - td->map_x + x * td->mpt_w, - td->map_y + y * td->mpt_h, - td->mpt_w, - td->mpt_h, - 0xc0 - ); -} - -///} -///{ "alloc_bitmap()" - -struct BitMap *alloc_bitmap( int width, int height, int depth, ULONG flags, struct BitMap *friend ) -{ - int p; - struct BitMap *bitmap; - unsigned char *bp; - - /* Kickstart 39+ */ - if ( v39 ) return ( AllocBitMap( width, height, depth, flags, friend )); - - /* Kickstart 38- */ - else - { - /* Allocate bitmap structure */ - if (( bitmap = AllocMem( sizeof( struct BitMap ), MEMF_PUBLIC | MEMF_CLEAR ))) - { - InitBitMap( bitmap, depth, width, height ); - /* Allocate bitplanes */ - for ( p = 0; p < depth; p++ ) - { - bp = AllocRaster( width, height ); - if ( !bp ) break; - bitmap->Planes[ p ] = bp; - } - - /* Out of memory */ - if ( p != depth ) - { - /* Free bitplanes */ - while ( --p >= 0 ) - { - FreeRaster( bitmap->Planes[ p ], width, height ); - } - /* Free bitmap structure */ - FreeMem( bitmap, sizeof( struct BitMap )); - bitmap = NULL; - } - } - return ( bitmap ); - } -} - -///} -///{ "free_bitmap()" - -void free_bitmap( struct BitMap *bitmap ) -{ - int p; - - /* Check for NULL */ - if ( !bitmap ) return; - - /* Kickstart 39+ */ - if ( v39 ) FreeBitMap( bitmap ); - - /* Kickstart 38- */ - else - { - /* Free bitplanes */ - for ( p = 0; p < bitmap->Depth; p++ ) - { - FreeRaster( bitmap->Planes[ p ], bitmap->BytesPerRow * 8, bitmap->Rows ); - } - /* Free bitmap structure */ - FreeMem( bitmap, sizeof( struct BitMap )); - } -} - -///} -///{ scale_bitmap() - -void scale_bitmap( struct BitMap *srcbm, int srcw, int srch, struct BitMap *dstbm, int dstw, int dsth ) -{ - struct BitScaleArgs bsa; - - /* Scale bitmap */ - bsa.bsa_SrcBitMap = srcbm; - bsa.bsa_DestBitMap = dstbm; - bsa.bsa_SrcX = 0; - bsa.bsa_SrcY = 0; - bsa.bsa_SrcWidth = srcw; - bsa.bsa_SrcHeight = srch; - bsa.bsa_DestX = 0; - bsa.bsa_DestY = 0; - bsa.bsa_XSrcFactor = srcw; - bsa.bsa_YSrcFactor = srch; - bsa.bsa_XDestFactor = dstw; - bsa.bsa_YDestFactor = dsth; - bsa.bsa_Flags = 0; - BitMapScale( &bsa ); -} - -///} -///{ "remap_bitmap()" - -void remap_bitmap( struct BitMap *srcbm, struct BitMap *dstbm, long *pens, int width, int height ) -{ - int x, y, p, c, ox, lpr, sd, dd; - int bm[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; - UBYTE *sp[ 4 ]; - UBYTE *dp[ 8 ]; - ULONG ls[ 4 ]; - ULONG ld[ 8 ]; - ULONG mask; - - /* Source bitplanes */ - sd = depth_of_bitmap( srcbm ); - for ( p = 0; p < sd; p++ ) - { - sp[ p ] = srcbm->Planes[ p ]; - } - - /* Destination bitplanes */ - dd = depth_of_bitmap( dstbm ); - for ( p = 0; p < dd; p++ ) - { - dp[ p ] = dstbm->Planes[ p ]; - } - - /* Number of longwords per row */ - lpr = width / 32; - - /* Convert graphics */ - for ( y = 0; y < height; y++ ) - { - ox = 0; - for ( x = 0 ; x < lpr; x++ ) - { - /* Read source longwords */ - for ( p = 0; p < sd; p++ ) ls[ p ] = *(ULONG *)( sp[ p ] + ox); - - /* Clear destination longwords */ - for ( p = 0; p < dd; ld[ p++ ] = 0 ); - - /* Remap */ - for ( mask = 0x80000000; mask != 0; mask >>= 1) - { - /* Find color index */ - for ( p = c = 0; p < sd; p++ ) if ( ls[ p ] & mask ) c |= bm[ p ]; - - /* Remap */ - c = pens[ c ]; - - /* Update destination longwords */ - for ( p = 0; p < dd; p++ ) if ( c & bm[ p ] ) ld[ p ] |= mask; - } - - /* Write destination longwords */ - for ( p = 0; p < dd; p++ ) *(ULONG *)( dp[ p ] + ox ) = ld[ p ]; - - /* Update offset */ - ox += 4; - } - - /* Update pointers to get to next line */ - for ( p = 0; p < sd; sp[ p++ ] += srcbm->BytesPerRow ); - for ( p = 0; p < dd; dp[ p++ ] += dstbm->BytesPerRow ); - } -} - -///} -///{ "depth_of_bitmap()" - -int depth_of_bitmap( struct BitMap *bm ) -{ - int depth; - - if ( v39 ) - { - depth = GetBitMapAttr( bm, BMA_DEPTH ); - } - else - { - depth = bm->Depth; - } - - return ( depth ); -} - -///} - diff --git a/src/main-dmy.c b/src/main-dmy.c deleted file mode 100644 index 6f144fdd..00000000 --- a/src/main-dmy.c +++ /dev/null @@ -1,315 +0,0 @@ -/* File: main-dmy.c */ - -/* - * Copyright (c) 1997 Ben Harrison, and others - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. - */ - -#ifdef USE_DMY - -/* - * This file helps ToME run on nothing. - */ - - -#include "angband.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <dirent.h> -#include <limits.h> - -/* /me pffts Solaris */ -#ifndef NAME_MAX -#define NAME_MAX _POSIX_NAME_MAX -#endif - -/* - * Information about a term - */ -typedef struct term_data term_data; - -struct term_data -{ - term t; /* All term info */ -}; - -/* Max number of windows on screen */ -#define MAX_TERM_DATA 4 - -/* Information about our windows */ -static term_data data[MAX_TERM_DATA]; - - -/* - * Hack -- Number of initialized "term" structures - */ -static int active = 0; - - - - -/* - * Suspend/Resume - */ -static errr Term_xtra_dummy_alive(int v) -{ - int x, y; - - - /* Suspend */ - if (!v) - {} - - /* Resume */ - else - {} - - /* Success */ - return (0); -} - - - -/* - * Init the "net" system - */ -static void Term_init_dummy(term *t) -{ - term_data *td = (term_data *)(t->data); - - /* Count init's, handle first */ - if (active++ != 0) return; -} - - -/* - * Nuke the "net" system - */ -static void Term_nuke_dummy(term *t) -{ - int x, y; - term_data *td = (term_data *)(t->data); -} - - - - -/* - * Process events (with optional wait) - */ -static errr Term_xtra_dummy_event(int v) -{ - /* Success */ - Term_keypress('\r'); - return (0); -} - -/* - * React to changes - */ -static errr Term_xtra_dummy_react(void) -{ - /* Success */ - return (0); -} - - -/* - * Handle a "special request" - */ -static errr Term_xtra_dummy(int n, int v) -{ - term_data *td = (term_data *)(Term->data); - char buf[2]; - - /* Analyze the request */ - switch (n) - { - /* Clear screen */ - case TERM_XTRA_CLEAR: - return (0); - - /* Make a noise */ - case TERM_XTRA_NOISE: - return (0); - - /* Flush the Curses buffer */ - case TERM_XTRA_FRESH: - return (0); - - /* Suspend/Resume curses */ - case TERM_XTRA_ALIVE: - return (Term_xtra_dummy_alive(v)); - - /* Process events */ - case TERM_XTRA_EVENT: - return (Term_xtra_dummy_event(v)); - - /* Flush events */ - case TERM_XTRA_FLUSH: - while (!Term_xtra_dummy_event(FALSE)); - return (0); - - /* Delay */ - case TERM_XTRA_DELAY: - return (0); - - /* React to events */ - case TERM_XTRA_REACT: - Term_xtra_dummy_react(); - return (0); - - /* Subdirectory scan */ - case TERM_XTRA_SCANSUBDIR: - { - DIR *directory; - struct dirent *entry; - - scansubdir_max = 0; - - directory = opendir(scansubdir_dir); - if (!directory) - return 1; - - while ((entry = readdir(directory))) - { - char file[PATH_MAX + NAME_MAX + 2]; - struct stat filedata; - - file[PATH_MAX + NAME_MAX] = 0; - strncpy(file, scansubdir_dir, PATH_MAX); - strncat(file, "/", 2); - strncat(file, entry->d_name, NAME_MAX); - if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode))) - { - string_free(scansubdir_result[scansubdir_max]); - scansubdir_result[scansubdir_max] = string_make(entry->d_name); - ++scansubdir_max; - } - } - - closedir(directory); - return 0; - } - } - - /* Unknown */ - return (1); -} - - -/* - * Actually MOVE the hardware cursor - */ -static errr Term_curs_dummy(int x, int y) -{ - term_data *td = (term_data *)(Term->data); - - /* Literally move the cursor */ - // DGDGDGD - - /* Success */ - return (0); -} - - -/* - * Erase a grid of space - * Hack -- try to be "semi-efficient". - */ -static errr Term_wipe_dummy(int x, int y, int n) -{ - /* Success */ - return (0); -} - -/* - * Place some text on the screen using an attribute - */ -static errr Term_text_dummy(int x, int y, int n, byte a, cptr s) -{ - /* Success */ - return (0); -} - - -/* - * Create a window for the given "term_data" argument. - * - * Assumes legal arguments. - */ -static errr term_data_init_dummy(term_data *td, int rows, int cols) -{ - term *t = &td->t; - - /* Initialize the term */ - term_init(t, cols, rows, 256); - - /* Erase with "white space" */ - t->attr_blank = TERM_WHITE; - t->char_blank = ' '; - - /* Set some hooks */ - t->init_hook = Term_init_dummy; - t->nuke_hook = Term_nuke_dummy; - - /* Set some more hooks */ - t->text_hook = Term_text_dummy; - t->wipe_hook = Term_wipe_dummy; - t->curs_hook = Term_curs_dummy; - t->xtra_hook = Term_xtra_dummy; - - /* Save the data */ - t->data = td; - - /* Activate it */ - Term_activate(t); - - /* Success */ - return (0); -} - - -static void hook_quit(cptr str) -{ - /* Unused */ - (void)str; -} - -/* - * Prepare "curses" for use by the file "z-term.c" - * - * Installs the "hook" functions defined above, and then activates - * the main screen "term", which clears the screen and such things. - * - * Someone should really check the semantics of "initscr()" - */ -errr init_dummy(int argc, char **argv) -{ - int num_term = MAX_TERM_DATA, next_win = 0; - - /* Activate hooks */ - quit_aux = hook_quit; - core_aux = hook_quit; - - /* Create a term */ - term_data_init_dummy(&data[0], 25, 80); - - /* Remember the term */ - angband_term[0] = &data[0].t; - - /* Activate the "Angband" window screen */ - Term_activate(&data[0].t); - - /* Remember the active screen */ - term_screen = &data[0].t; - - /* Success */ - return (0); -} -#endif diff --git a/src/main-dos.c b/src/main-dos.c deleted file mode 100644 index 0a93cdc8..00000000 --- a/src/main-dos.c +++ /dev/null @@ -1,2417 +0,0 @@ -/* File: main-dos.c */ - -/* - * Copyright (c) 1997 Ben Harrison, Robert Ruehlmann, and others - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. - */ - - -/* - * This file helps Angband work with DOS computers. - * - * Adapted from "main-ibm.c". - * - * Author: Robert Ruehlmann (rr9@angband.org). - * See "http://thangorodrim.angband.org/". - * - * Initial framework (and some code) by Ben Harrison (benh@phial.com). - * - * This file requires the (free) DJGPP compiler (based on "gcc"). - * See "http://www.delorie.com/djgpp/". - * - * This file uses the (free) "Allegro" library (SVGA graphics library). - * See "http://www.talula.demon.co.uk/allegro/". - * - * To compile this file, use "Makefile.dos", which defines "USE_DOS". - * - * See also "main-ibm.c" and "main-win.c". - * - * - * The "lib/user/pref.prf" file contains macro definitions and possible - * alternative color set definitions. - * - * The "lib/user/font.prf" contains attr/char mappings for use with the - * special fonts in the "lib/xtra/font/" directory. - * - * The "lib/user/graf.prf" contains attr/char mappings for use with the - * special bitmaps in the "lib/xtra/graf/" directory. - * - * - * Both "shift" keys are treated as "identical", and all the modifier keys - * (control, shift, alt) are ignored when used with "normal" keys, unless - * they modify the underlying "ascii" value of the key. You must use the - * new "user pref files" to be able to interact with the keypad and such. - * - * Note that "Term_xtra_dos_react()" allows runtime color, graphics, - * screen resolution, and sound modification. - * - * - * The sound code uses *.wav files placed in the "lib/xtra/sound" folder. - * Every sound-event can have several samples assigned to it and a random - * one will be played when the event occures. Look at the - * "lib/xtra/sound/sound.cfg" configuration file for more informations. - * - * The background music uses midi-files (and mod files) from the - * "lib/xtra/music" folder. - * - * - * Comment by Ben Harrison (benh@phial.com): - * - * On my Windows NT box, modes "VESA1" and "VESA2B" seem to work, but - * result in the game running with no visible output. Mode "VESA2L" - * clears the screen and then fails silently. All other modes fail - * instantly. To recover from such "invisible" modes, you can try - * typing escape, plus control-x, plus escape. XXX XXX XXX - * - * Comment by Eric Stevens (tome@eastevens.com): - * - * This file has been modified to work with Allegro 4.0.3 that comes with - * DJGPP 2.0.3. This modification allows ToME to use the .dat font files - * provided with the Angband release for DOS. - * - */ - -#include "angband.h" - - -#ifdef USE_DOS - -#include <allegro.h> - -#ifdef USE_MOD_FILES -#include <jgmod.h> -#endif /* USE_MOD_FILES */ - -#include "load_gif.c" - - -#include <bios.h> -#include <dos.h> -#include <keys.h> -#include <unistd.h> -#include <dir.h> - -/* - * ZAngband remapping for race and class in the enhanced bitmap - */ -/* #define PLAYER_REMAP */ - - -/* - * Index of the first standard Angband color. - * - * All colors below this index are defined by - * the palette of the tiles-bitmap. - */ -#define COLOR_OFFSET 240 - - -/* - * Maximum number of terminals - */ -#define MAX_TERM_DATA 8 - - -/* - * Forward declare - */ -typedef struct term_data term_data; - - -/* - * Extra "term" data - */ -struct term_data -{ - term t; - - int number; - - int x; - int y; - - int cols; - int rows; - - int tile_wid; - int tile_hgt; - - int font_wid; - int font_hgt; - - FONT *font; - -#ifdef USE_GRAPHICS - - BITMAP *tiles; - -#endif /* USE_GRAPHICS */ - -#ifdef USE_BACKGROUND - - int window_type; - -#endif /* USE_BACKGROUND */ - -}; - -/* - * The current screen resolution - */ -static int resolution; - -#ifdef USE_BACKGROUND - -/* - * The background images - */ -BITMAP *background[17]; - -#endif /* USE_BACKGROUND */ - - -/* - * An array of term_data's - */ -static term_data data[MAX_TERM_DATA]; - - -#ifdef USE_GRAPHICS - -/* - * Are graphics already initialized ? - */ -static bool graphics_initialized = FALSE; - -#endif /* USE_GRAPHICS */ - - -/* - * Small bitmap for the cursor - */ -static BITMAP *cursor; - - -#ifdef USE_SOUND - -/* - * Is the sound already initialized ? - */ -static bool sound_initialized = FALSE; - -# ifdef USE_MOD_FILES -/* - * Is the mod-file support already initialized ? - */ -static bool mod_file_initialized = FALSE; - -# endif /* USE_MOD_FILES */ - -/* - * Volume settings - */ -static int digi_volume; -static int midi_volume; - -/* - * The currently playing song - */ -static MIDI *midi_song = NULL; - -# ifdef USE_MOD_FILES - -static JGMOD *mod_song = NULL; - -# endif /* USE_MOD_FILES */ - -static int current_song; - -/* - * The number of available songs - */ -static int song_number; - -/* - * The maximum number of available songs - */ -#define MAX_SONGS 255 - -static char music_files[MAX_SONGS][16]; - -/* - * The maximum number of samples per sound-event - */ -#define SAMPLE_MAX 10 - -/* - * An array of sound files - */ -static SAMPLE* samples[SOUND_MAX][SAMPLE_MAX]; - -/* - * The number of available samples for every event - */ -static int sample_count[SOUND_MAX]; - -#endif /* USE_SOUND */ - - -/* - * Extra paths - */ -static char xtra_font_dir[1024]; -static char xtra_graf_dir[1024]; -static char xtra_sound_dir[1024]; -static char xtra_music_dir[1024]; - - -/* - * List of the available videomodes to reduce executable size - */ - /* -DECLARE_GFX_DRIVER_LIS -( - GFX_DRIVER_VBEAF - GFX_DRIVER_VESA2L - GFX_DRIVER_VESA2B - GFX_DRIVER_ATI - GFX_DRIVER_MACH64 - GFX_DRIVER_CIRRUS64 - GFX_DRIVER_CIRRUS54 - GFX_DRIVER_PARADISE - GFX_DRIVER_S3 - GFX_DRIVER_TRIDENT - GFX_DRIVER_ET3000 - GFX_DRIVER_ET4000 - GFX_DRIVER_VIDEO7 - GFX_DRIVER_VESA1 -) -*/ - -/* - * Declare the videomode list - */ -//DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8) - - -/* - * Keypress input modifier flags (hard-coded by DOS) - */ -#define K_RSHIFT 0 /* Right shift key down */ -#define K_LSHIFT 1 /* Left shift key down */ -#define K_CTRL 2 /* Ctrl key down */ -#define K_ALT 3 /* Alt key down */ -#define K_SCROLL 4 /* Scroll lock on */ -#define K_NUM 5 /* Num lock on */ -#define K_CAPS 6 /* Caps lock on */ -#define K_INSERT 7 /* Insert on */ - - -/* - * Prototypes - */ -static errr Term_xtra_dos_event(int v); -static void Term_xtra_dos_react(void); -static void Term_xtra_dos_clear(void); -static errr Term_xtra_dos(int n, int v); -static errr Term_user_dos(int n); -static errr Term_curs_dos(int x, int y); -static errr Term_wipe_dos(int x, int y, int n); -static errr Term_text_dos(int x, int y, int n, byte a, const char *cp); -static void Term_init_dos(term *t); -static void Term_nuke_dos(term *t); -static void term_data_link(term_data *td); -static void dos_dump_screen(void); -static void dos_quit_hook(cptr str); -static bool init_windows(void); -errr init_dos(void); -#ifdef USE_SOUND -static bool init_sound(void); -static errr Term_xtra_dos_sound(int v); -static void play_song(void); -#endif /* USE_SOUND */ -#ifdef USE_GRAPHICS -static bool init_graphics(void); -# ifdef USE_TRANSPARENCY -# ifdef USE_EGO_GRAPHICS -static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp, - const byte *tap, const char *tcp, const byte *eap, const char *ecp); -# else /* USE_EGO_GRAPHICS */ -static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp, - const byte *tap, const char *tcp); -# endif /* USE_EGO_GRAPHICS */ -# else /* USE_TRANSPARENCY */ -static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp); -# endif /* USE_TRANSPARENCY */ -#endif /* USE_GRAPHICS */ - - -/* - * Process an event (check for a keypress) - * - * The keypress processing code is often the most system dependant part - * of Angband, since sometimes even the choice of compiler is important. - * - * For this file, we divide all keypresses into two categories, first, the - * "normal" keys, including all keys required to play Angband, and second, - * the "special" keys, such as keypad keys, function keys, and various keys - * used in combination with various modifier keys. - * - * To simplify this file, we use Angband's "macro processing" ability, in - * combination with the "lib/user/pref.prf" file, to handle most of the - * "special" keys, instead of attempting to fully analyze them here. This - * file only has to determine when a "special" key has been pressed, and - * translate it into a simple string which signals the use of a "special" - * key, the set of modifiers used, if any, and the hardware scan code of - * the actual key which was pressed. To simplify life for the user, we - * treat both "shift" keys as identical modifiers. - * - * The final encoding is "^_MMMxSS\r", where "MMM" encodes the modifiers - * ("C" for control, "S" for shift, "A" for alt, or any ordered combination), - * and "SS" encodes the keypress (as the two "digit" hexadecimal encoding of - * the scan code of the key that was pressed), and the "^_" and "x" and "\r" - * delimit the encoding for recognition by the macro processing code. - * - * Some important facts about scan codes follow. All "normal" keys use - * scan codes from 1-58. The "function" keys use 59-68 (and 133-134). - * The "keypad" keys use 69-83. Escape uses 1. Enter uses 28. Control - * uses 29. Left Shift uses 42. Right Shift uses 54. PrtScrn uses 55. - * Alt uses 56. Space uses 57. CapsLock uses 58. NumLock uses 69. - * ScrollLock uses 70. The "keypad" keys which use scan codes 71-83 - * are ordered KP7,KP8,KP9,KP-,KP4,KP5,KP6,KP+,KP1,KP2,KP3,INS,DEL. - * - * Using "bioskey(0x10)" instead of "bioskey(0)" apparently provides more - * information, including better access to the keypad keys in combination - * with various modifiers, but only works on "PC's after 6/1/86", and there - * is no way to determine if the function is provided on a machine. I have - * been told that without it you cannot detect, for example, control-left. - * The basic scan code + ascii value pairs returned by the keypad follow, - * with values in parentheses only available to "bioskey(0x10)". - * - * / * - + 1 2 3 4 - * Norm: 352f 372a 4a2d 4e2b 4f00 5000 5100 4b00 - * Shft: 352f 372a 4a2d 4e2b 4f31 5032 5133 4b34 - * Ctrl: (9500) (9600) (8e00) (9000) 7500 (9100) 7600 7300 - * - * 5 6 7 8 9 0 . Enter - * Norm: (4c00) 4d00 4700 4800 4900 5200 5300 (e00d) - * Shft: 4c35 4d36 4737 4838 4939 5230 532e (e00d) - * Ctrl: (8f00) 7400 7700 (8d00) 8400 (9200) (9300) (e00a) - * - * See "lib/user/pref-win.prf" for the "standard" macros for various keys. - * - * Certain "bizarre" keypad keys (such as "enter") return a "scan code" - * of "0xE0", and a "usable" ascii value. These keys should be treated - * like the normal keys, see below. XXX XXX XXX Note that these "special" - * keys could be prefixed with an optional "ctrl-^" which would allow them - * to be used in macros without hurting their use in normal situations. - * - * This function also appears in "main-ibm.c". XXX XXX XXX - * - * Addition for the DOS version: Dump-screen function with the - * "Ctrl-Print" key saves a bitmap with the screen contents to - * "lib/user/dump.bmp". - */ -static errr Term_xtra_dos_event(int v) -{ - int i, k, s; - - bool mc = FALSE; - bool ms = FALSE; - bool ma = FALSE; - - /* Hack -- Check for a keypress */ - if (!v && !bioskey(1)) return (1); - - /* Wait for a keypress */ - k = bioskey(0x10); - - /* Access the "modifiers" */ - i = bioskey(2); - - /* Extract the "scan code" */ - s = ((k >> 8) & 0xFF); - - /* Extract the "ascii value" */ - k = (k & 0xFF); - - /* Process "normal" keys */ - if ((s <= 58) || (s == 0xE0)) - { - /* Enqueue it */ - if (k) Term_keypress(k); - - /* Success */ - return (0); - } - - /* Extract the modifier flags */ - if (i & (1 << K_CTRL)) mc = TRUE; - if (i & (1 << K_LSHIFT)) ms = TRUE; - if (i & (1 << K_RSHIFT)) ms = TRUE; - if (i & (1 << K_ALT)) ma = TRUE; - - /* Dump the screen with "Ctrl-Print" */ - if ((s == 0x72) && mc) - { - /* Dump the screen */ - dos_dump_screen(); - - /* Success */ - return (0); - } - - /* Begin a "macro trigger" */ - Term_keypress(31); - - /* Hack -- Send the modifiers */ - if (mc) Term_keypress('C'); - if (ms) Term_keypress('S'); - if (ma) Term_keypress('A'); - - /* Introduce the hexidecimal scan code */ - Term_keypress('x'); - - /* Encode the hexidecimal scan code */ - Term_keypress(hexsym[s / 16]); - Term_keypress(hexsym[s % 16]); - - /* End the "macro trigger" */ - Term_keypress(13); - - /* Success */ - return (0); -} - - -#ifdef SUPPORT_GAMMA - -/* - * When set to TRUE, indicates that we can use gamma_table - */ -static bool gamma_table_ready = FALSE; - - -/* - * Build gamma correction table if requested and applicable - */ -static void setup_gamma_table(void) -{ - static u16b old_gamma_val = 0; - - /* (Re)build the table only when gamma value changes */ - if (gamma_val == old_gamma_val) return; - - /* Temporarily inactivate the table */ - gamma_table_ready = FALSE; - - /* Validate gamma_val */ - if ((gamma_val <= 0) || (gamma_val >= 256)) - { - /* Reset */ - old_gamma_val = gamma_val = 0; - - /* Leave it inactive */ - return; - } - - /* (Re)build the table */ - build_gamma_table(gamma_val); - - /* Remember gamma_val */ - old_gamma_val = gamma_val; - - /* Activate the table */ - gamma_table_ready = TRUE; -} - -#endif /* SUPPORT_GAMMA */ - - -/* - * React to global changes in the colors, graphics, and sound settings. - */ -static void Term_xtra_dos_react(void) -{ - int i; - -#ifdef USE_SPECIAL_BACKGROUND - - int j; - - term_data *td; - -#endif /* USE_SPECIAL_BACKGROUND */ - - -#ifdef SUPPORT_GAMMA - - /* Setup gamma_table */ - setup_gamma_table(); - -#endif /* SUPPORT_GAMMA */ - - /* - * Set the Angband colors - */ - for (i = 0; i < 16; i++) - { - byte rv, gv, bv; - RGB colour; - - /* Extract desired values */ - rv = angband_color_table[i][1]; - gv = angband_color_table[i][2]; - bv = angband_color_table[i][3]; - -#ifdef SUPPORT_GAMMA - - /* Hack - Gamma correction */ - if (gamma_table_ready) - { - rv = gamma_table[rv]; - gv = gamma_table[gv]; - bv = gamma_table[bv]; - } - -#endif /* SUPPORT_GAMMA */ - - /* 8 bit to 6 bit conversion */ - colour.r = rv >> 2; - colour.g = gv >> 2; - colour.b = bv >> 2; - - set_color(COLOR_OFFSET + i, &colour); - } - -#ifdef USE_GRAPHICS - - /* - * Handle "arg_graphics" - */ - if (use_graphics != arg_graphics) - { - /* Initialize (if needed) */ - if (arg_graphics && !init_graphics()) - { - /* Warning */ - plog("Cannot initialize graphics!"); - - /* Cannot enable */ - arg_graphics = FALSE; - } - - /* Change setting */ - use_graphics = arg_graphics; - } - -#endif /* USE_GRAPHICS */ - -#ifdef USE_SOUND - - /* - * Handle "arg_sound" - */ - if (use_sound != arg_sound) - { - /* Clear the old song */ - if (midi_song) destroy_midi(midi_song); - midi_song = NULL; -#ifdef USE_MOD_FILES - if (mod_file_initialized) - { - stop_mod(); - if (mod_song) destroy_mod(mod_song); - mod_song = NULL; - } -#endif /* USE_MOD_FILES */ - - /* Initialize (if needed) */ - if (arg_sound && !init_sound()) - { - /* Warning */ - plog("Cannot initialize sound!"); - - /* Cannot enable */ - arg_sound = FALSE; - } - - /* Change setting */ - use_sound = arg_sound; - } - -#endif /* USE_SOUND */ - -#ifdef USE_SPECIAL_BACKGROUND - - /* - * Initialize the window backgrounds - */ - for (i = 0; i < 8; i++) - { - td = &data[i]; - - /* Window flags */ - for (j = 0; j < 16; j++) - { - if (op_ptr->window_flag[i] & (1L << j)) - { - if (background[j + 1]) - { - td->window_type = j + 1; - } - else - { - td->window_type = 0; - } - } - } - } -#endif /* USE_SPECIAL_BACKGROUND */ -} - - -/* - * Clear a terminal - * - * Fills the terminal area with black color or with - * the background image - */ -static void Term_xtra_dos_clear(void) -{ - term_data *td = (term_data*)(Term->data); - -#ifdef USE_BACKGROUND - int bgrnd; -#endif /* USE_BACKGROUND */ - - int x1, y1; - int w1, h1; - - /* Location */ - x1 = td->x; - y1 = td->y; - - /* Size */ - w1 = td->tile_wid * td->cols; - h1 = td->tile_hgt * td->rows; - -#ifdef USE_BACKGROUND - - bgrnd = td->window_type; - - if (background[bgrnd]) - { - /* Draw the background */ - stretch_blit(background[bgrnd], screen, - 0, 0, background[bgrnd]->w, background[bgrnd]->h, - x1, y1, w1, h1); - } - else - -#endif /* USE_BACKGROUND */ - - { - /* Draw the Term black */ - rectfill(screen, - x1, y1, x1 + w1 - 1, y1 + h1 - 1, - COLOR_OFFSET + TERM_DARK); - } -} - - -/* - * Handle a "special request" - * - * The given parameters are "valid". - */ -static errr Term_xtra_dos(int n, int v) -{ - /* Analyze the request */ - switch (n) - { - /* Make a "bell" noise */ - case TERM_XTRA_NOISE: - { - /* Make a bell noise */ - (void)write(1, "\007", 1); - - /* Success */ - return (0); - } - - /* Clear the screen */ - case TERM_XTRA_CLEAR: - { - /* Clear the screen */ - Term_xtra_dos_clear(); - - /* Success */ - return (0); - } - - /* Process events */ - case TERM_XTRA_EVENT: - { - irc_poll(); - - /* Process one event */ - return (Term_xtra_dos_event(v)); - } - - /* Flush events */ - case TERM_XTRA_FLUSH: - { - /* Strip events */ - while (!Term_xtra_dos_event(FALSE)); - - /* Success */ - return (0); - } - - /* Do something useful if bored */ - case TERM_XTRA_BORED: - { - irc_poll(); - -#ifdef USE_SOUND - /* - * Check for end of song and start a new one - */ - if (!use_sound) return (0); - -#ifdef USE_MOD_FILES - if (song_number && ((midi_pos == -1) && !is_mod_playing())) -#else /* USE_MOD_FILES */ -if (song_number && (midi_pos == -1)) -#endif /* USE_MOD_FILES */ - { - if (song_number > 1) - { - /* Get a *new* song at random */ - while (1) - { - n = randint(song_number); - if (n != current_song) break; - } - current_song = n; - } - else - { - /* We only have one song, so loop it */ - current_song = 1; - } - - /* Play the song */ - play_song(); - } - -#endif /* USE_SOUND */ - - /* Success */ - return (0); - } - - /* React to global changes */ - case TERM_XTRA_REACT: - { - /* Change the colors */ - Term_xtra_dos_react(); - - /* Success */ - return (0); - } - - /* Delay for some milliseconds */ - case TERM_XTRA_DELAY: - { - irc_poll(); - - /* Delay if needed */ - if (v > 0) delay(v); - - /* Success */ - return (0); - } - -#ifdef USE_SOUND - - /* Make a sound */ - case TERM_XTRA_SOUND: - { - return (Term_xtra_dos_sound(v)); - } - -#endif /* USE_SOUND */ - - /* - * Scans for subdirectories in a directory "scansubdir_dir" - * and place teh result in "scansubdir_result/scansubdir_max" - */ - case TERM_XTRA_SCANSUBDIR: - { - struct ffblk f; - int done; - - done = findfirst(format("%s\\*", scansubdir_dir), &f, FA_DIREC); - - scansubdir_max = 0; - while ((!done) && (scansubdir_max < 255)) - { - if ((f.ff_attrib & FA_DIREC) && (strcmp(f.ff_name, ".")) && (strcmp(f.ff_name, ".."))) - { - string_free(scansubdir_result[scansubdir_max]); - scansubdir_result[scansubdir_max] = string_make(f.ff_name); - scansubdir_max++; - } - - done = findnext(&f); - } - - return 0; - } - - } - - /* Unknown request */ - return (1); -} - - -/* - * Do a "user action" on the current "term" - */ -static errr Term_user_dos(int n) -{ - int k; - - char status[4]; - - char section[80]; - - /* Interact */ - while (1) - { - /* Clear screen */ - Term_clear(); - - /* Print date and time of compilation */ - prt(format("Compiled: %s %s\n", __TIME__, __DATE__), 1, 45); - - /* Why are we here */ - prt("DOS options", 2, 0); - - /* Give some choices */ -#ifdef USE_SOUND - prt("(V) Sound Volume", 4, 5); - prt("(M) Music Volume", 5, 5); -#endif /* USE_SOUND */ - -#ifdef USE_GRAPHICS - - if (arg_graphics) - { - strcpy(status, "On"); - } - else - { - strcpy(status, "Off"); - } - prt(format("(G) Graphics : %s", status), 7, 5); - -#endif /* USE_GRAPHICS */ - -#ifdef USE_SOUND - - if (arg_sound) - { - strcpy(status, "On"); - } - else - { - strcpy(status, "Off"); - } - prt(format("(S) Sound/Music : %s", status), 8, 5); - -#endif /* USE_SOUND */ - - prt("(R) Screen resolution", 12, 5); - - prt("(W) Save current options", 14, 5); - - /* Prompt */ - prt("Command: ", 18, 0); - - /* Get command */ - k = inkey(); - - /* Exit */ - if (k == ESCAPE) break; - - /* Analyze */ - switch (k) - { -#ifdef USE_SOUND - /* Sound Volume */ - case 'V': - case 'v': - { - /* Prompt */ - prt("Command: Sound Volume", 18, 0); - - /* Get a new value */ - while (1) - { - prt(format("Current Volume: %d", digi_volume), 22, 0); - prt("Change Volume (+, - or ESC to accept): ", 20, 0); - k = inkey(); - if (k == ESCAPE) break; - switch (k) - { - case '+': - { - digi_volume++; - if (digi_volume > 255) digi_volume = 255; - break; - } - case '-': - { - digi_volume--; - if (digi_volume < 0) digi_volume = 0; - break; - } - /* Unknown option */ - default: - { - break; - } - } - set_volume(digi_volume, -1); - } - break; - } - - /* Music Volume */ - case 'M': - case 'm': - { - /* Prompt */ - prt("Command: Music Volume", 18, 0); - - /* Get a new value */ - while (1) - { - prt(format("Current Volume: %d", midi_volume), 22, 0); - prt("Change Volume (+, - or ESC to accept): ", 20, 0); - k = inkey(); - if (k == ESCAPE) break; - switch (k) - { - case '+': - { - midi_volume++; - if (midi_volume > 255) midi_volume = 255; - break; - } - case '-': - { - midi_volume--; - if (midi_volume < 0) midi_volume = 0; - break; - } - /* Unknown option */ - default: - { - break; - } - } - set_volume( -1, midi_volume); - } - break; - } - -#endif /*USE_SOUND */ - -#ifdef USE_GRAPHICS - - /* Switch graphics on/off */ - case 'G': - case 'g': - { - /* Toggle "arg_graphics" */ - arg_graphics = !arg_graphics; - - /* React to changes */ - Term_xtra_dos_react(); - - /* Reset visuals */ -#ifdef ANGBAND_2_8_1 - reset_visuals(); -#else /* ANGBAND_2_8_1 */ - reset_visuals(TRUE); -#endif /* ANGBAND_2_8_1 */ - break; - } - -#endif /* USE_GRAPHICS */ - -#ifdef USE_SOUND - - /* Sound/Music On/Off */ - case 'S': - case 's': - { - /* Toggle "arg_sound" */ - arg_sound = !arg_sound; - - /* React to changes */ - Term_xtra_dos_react(); - - break; - } - -#endif /* USE_SOUND */ - - /* Screen Resolution */ - case 'R': - case 'r': - { - int h, w, i = 1; - char *descr; - - /* Clear screen */ - Term_clear(); - - /* Prompt */ - prt("Command: Screen Resolution", 1, 0); - prt("Restart Angband to get the new screenmode.", 3, 0); - - /* Get a list of the available presets */ - while (1) - { - /* Section name */ - sprintf(section, "Mode-%d", i); - - /* Get new values or end the list */ - if (!(w = get_config_int(section, "screen_wid", 0)) || (i == 16)) break; - h = get_config_int(section, "screen_hgt", 0); - - /* Get a extra description of the resolution */ - descr = get_config_string(section, "Description", ""); - - /* Print it */ - prt(format("(%d) %d x %d %s", i, w, h, descr), 4 + i, 0); - - /* Next */ - i++; - } - - /* Get a new resolution */ - prt(format("Screen Resolution : %d", resolution), 20, 0); - k = inkey(); - if (k == ESCAPE) break; - if (isdigit(k)) resolution = D2I(k); - - /* Check for min, max value */ - if ((resolution < 1) || (resolution >= i)) resolution = 1; - - /* Save the resolution */ - set_config_int("Angband", "Resolution", resolution); - - /* Return */ - break; - } - - - /* Save current option */ - case 'W': - case 'w': - { - prt("Saving current options", 18, 0); - -#ifdef USE_SOUND - set_config_int("sound", "digi_volume", digi_volume); - set_config_int("sound", "midi_volume", midi_volume); -#endif /* USE_SOUND */ - set_config_int("Angband", "Graphics", arg_graphics); - set_config_int("Angband", "Sound", arg_sound); - - break; - } - - /* Unknown option */ - default: - { - break; - } - } - - /* Flush messages */ - msg_print(NULL); - } - - /* Redraw it */ - Term_key_push(KTRL('R')); - - /* Unknown */ - return (0); -} - - -/* - * Move the cursor - * - * The given parameters are "valid". - */ -static errr Term_curs_dos(int x, int y) -{ - term_data *td = (term_data*)(Term->data); - - int x1, y1; - - /* Location */ - x1 = x * td->tile_wid + td->x; - y1 = y * td->tile_hgt + td->y; - - /* Draw the cursor */ - draw_sprite(screen, cursor, x1, y1); - - /* Success */ - return (0); -} - - -/* - * Erase a block of the screen - * - * The given parameters are "valid". - */ -static errr Term_wipe_dos(int x, int y, int n) -{ - term_data *td = (term_data*)(Term->data); - -#ifdef USE_BACKGROUND - int bgrnd; -#endif /* USE_BACKGROUND */ - - int x1, y1; - int w1, h1; - - /* Location */ - x1 = x * td->tile_wid + td->x; - y1 = y * td->tile_hgt + td->y; - - /* Size */ - w1 = n * td->tile_wid; - h1 = td->tile_hgt; - -#ifdef USE_BACKGROUND - - bgrnd = td->window_type; - - if (background[bgrnd]) - { - int source_x = x * background[bgrnd]->w / td->cols; - int source_y = y * background[bgrnd]->h / td->rows; - int source_w = n * background[bgrnd]->w / td->cols; - int source_h = background[bgrnd]->h / td->rows; - - /* Draw the background */ - stretch_blit(background[bgrnd], screen, - source_x, source_y, source_w, source_h, - x1, y1, w1, h1); - } - else - -#endif /* USE_BACKGROUND */ - - { - /* Draw a black block */ - rectfill(screen, x1, y1, x1 + w1 - 1, y1 + h1 - 1, - COLOR_OFFSET + TERM_DARK); - } - - /* Success */ - return (0); -} - - -/* - * Place some text on the screen using an attribute - * - * The given parameters are "valid". Be careful with "a". - * - * The string "cp" has length "n" and is NOT null-terminated. - */ -static errr Term_text_dos(int x, int y, int n, byte a, const char *cp) -{ - term_data *td = (term_data*)(Term->data); - - int i; - - int x1, y1; - - char text[257]; - - /* Location */ - x1 = x * td->tile_wid + td->x; - y1 = y * td->tile_hgt + td->y; - - /* Erase old contents */ - Term_wipe_dos(x, y, n); - -#ifdef USE_SPECIAL_BACKGROUND - - /* Show text in black in the message window */ - if (op_ptr->window_flag[td->number] & (PW_MESSAGE)) a = 0; - -#endif /* USE_SPECIAL_BACKGROUND */ - - /* No stretch needed */ - if (td->font_wid == td->tile_wid) - { - /* Copy the string */ - for (i = 0; i < n; ++i) text[i] = cp[i]; - - /* Terminate */ - text[i] = '\0'; - - /* Dump the text */ - textout(screen, td->font, text, x1, y1, - COLOR_OFFSET + (a & 0x0F)); - } - - /* Stretch needed */ - else - { - /* Pre-Terminate */ - text[1] = '\0'; - - /* Write the chars to the screen */ - for (i = 0; i < n; ++i) - { - /* Build a one character string */ - text[0] = cp[i]; - - /* Dump some text */ - textout(screen, td->font, text, x1, y1, - COLOR_OFFSET + (a & 0x0F)); - - /* Advance */ - x1 += td->tile_wid; - } - } - - /* Success */ - return (0); -} - - -#ifdef USE_GRAPHICS - -/* - * Place some attr/char pairs on the screen - * - * The given parameters are "valid". - * - * To prevent crashes, we must not only remove the high bits of the - * "ap[i]" and "cp[i]" values, but we must map the resulting value - * onto the legal bitmap size, which is normally 32x32. XXX XXX XXX - */ -#ifdef USE_TRANSPARENCY -# ifdef USE_EGO_GRAPHICS -static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp, - const byte *tap, const char *tcp, const byte *eap, const char *ecp) -# else /* USE_EGO_GRAPHICS */ -static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp, - const byte *tap, const char *tcp) -# endif /* USE_EGO_GRAPHICS */ -#else /* USE_TRANSPARENCY */ -static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp) -#endif /* USE_TRANSPARENCY */ -{ - term_data *td = (term_data*)(Term->data); - - int i; - - int w, h; - - int x1, y1; - int x2, y2; - -# ifdef USE_TRANSPARENCY - - int x3, y3; - -# ifdef USE_EGO_GRAPHICS - - int x4, y4; - bool has_overlay; - -# endif /* USE_EGO_GRAPHICS */ - -# endif /* USE_TRANSPARENCY */ - - /* Size */ - w = td->tile_wid; - h = td->tile_hgt; - - /* Location (window) */ - x1 = x * w + td->x; - y1 = y * h + td->y; - - /* Dump the tiles */ - for (i = 0; i < n; i++) - { - /* Location (bitmap) */ - x2 = (cp[i] & 0x7F) * w; - y2 = (ap[i] & 0x7F) * h; - -# ifdef USE_TRANSPARENCY - x3 = (tcp[i] & 0x7F) * w; - y3 = (tap[i] & 0x7F) * h; - -# ifdef EGO_GRAPHICS - x4 = (ecp[i] & 0x7F) * w; - y4 = (eap[i] & 0x7F) * h; - has_overlay = (ecp[i] && eap[i]); - -# endif /* EGO_GRAPHICS */ - - /* Blit the tile to the screen */ - blit(td->tiles, screen, x3, y3, x1, y1, w, h); - - /* Blit the tile to the screen */ - masked_blit(td->tiles, screen, x2, y2, x1, y1, w, h); - -# ifdef EGO_GRAPHICS - - /* Blit the overlay to the screen */ - if (has_overlay) - masked_blit(td->tiles, screen, x4, y4, x1, y1, w, h); - -# endif /* EGO_GRAPHICS */ - -# else /* USE_TRANSPARENCY */ - - /* Blit the tile to the screen */ - blit(td->tiles, screen, x2, y2, x1, y1, w, h); - -# endif /* USE_TRANSPARENCY */ - - /* Advance (window) */ - x1 += w; - } - - /* Success */ - return (0); -} - -#endif /* USE_GRAPHICS */ - - -/* - * Init a Term - */ -static void Term_init_dos(term *t) -{ - /* XXX Nothing */ -} - - -/* - * Nuke a Term - */ -static void Term_nuke_dos(term *t) -{ - term_data *td = (term_data*)(t->data); - - /* Free the terminal font */ - if (td->font) destroy_font(td->font); - -#ifdef USE_GRAPHICS - - /* Free the terminal bitmap */ - if (td->tiles) destroy_bitmap(td->tiles); - -#endif /* USE_GRAPHICS */ -} - - - -/* - * Instantiate a "term_data" structure - */ -static void term_data_link(term_data *td) -{ - term *t = &td->t; - - /* Initialize the term */ - term_init(t, td->cols, td->rows, 255); - - /* Use a "software" cursor */ - t->soft_cursor = TRUE; - - /* Ignore the "TERM_XTRA_BORED" action */ - t->never_bored = FALSE; - - /* Ignore the "TERM_XTRA_FROSH" action */ - t->never_frosh = TRUE; - - /* Erase with "white space" */ - t->attr_blank = TERM_WHITE; - t->char_blank = ' '; - - /* Prepare the init/nuke hooks */ - t->init_hook = Term_init_dos; - t->nuke_hook = Term_nuke_dos; - - /* Prepare the template hooks */ - t->xtra_hook = Term_xtra_dos; - t->curs_hook = Term_curs_dos; - t->wipe_hook = Term_wipe_dos; - t->user_hook = Term_user_dos; - t->text_hook = Term_text_dos; - -#ifdef USE_GRAPHICS - - /* Prepare the graphics hook */ - t->pict_hook = Term_pict_dos; - - /* Use "Term_pict" for "graphic" data */ - t->higher_pict = TRUE; - -#endif /* USE_GRAPHICS */ - - /* Remember where we came from */ - t->data = (vptr)(td); -} - - -/* - * Shut down visual system, then fall back into standard "quit()" - */ -static void dos_quit_hook(cptr str) -{ - int i; - - /* Destroy sub-windows */ - for (i = MAX_TERM_DATA - 1; i >= 1; i--) - { - /* Unused */ - if (!angband_term[i]) continue; - - /* Nuke it */ - term_nuke(angband_term[i]); - } - - - /* Free all resources */ - if (cursor) destroy_bitmap(cursor); - -#ifdef USE_BACKGROUND - - /* Free the background bitmaps */ - for (i = 0; i < 17; i++) - { - if (background[i]) destroy_bitmap(background[i]); - } - -#endif /* USE_BACKGROUND */ - - -#ifdef USE_SOUND - - if (sound_initialized) - { - /* Destroy samples */ - for (i = 1; i < SOUND_MAX; i++) - { - int j; - - for (j = 0; j < sample_count[i]; j++) - { - if (samples[i][j]) destroy_sample(samples[i][j]); - } - } - } - - /* Clear the old song */ - if (midi_song) destroy_midi(midi_song); - midi_song = NULL; -# ifdef USE_MOD_FILES - if (mod_file_initialized) - { - stop_mod(); - if (mod_song) destroy_mod(mod_song); - mod_song = NULL; - } -# endif /* USE_MOD_FILES */ - -#endif /* USE_SOUND */ - - /* Shut down Allegro */ - allegro_exit(); -} - - -/* - * Dump the screen to "lib/user/dump.bmp" - */ -static void dos_dump_screen(void) -{ - /* Bitmap and palette of the screen */ - BITMAP *bmp; - PALETTE pal; - - /* Filename */ - char filename[1024]; - - /* Get bitmap and palette of the screen */ - bmp = create_sub_bitmap(screen, 0, 0, SCREEN_W, SCREEN_H); - get_palette(pal); - - /* Build the filename for the screen-dump */ - path_build(filename, 1024, ANGBAND_DIR_USER, "dump.bmp"); - - /* Save it */ - save_bmp(filename, bmp, pal); - - /* Free up the memory */ - if (bmp) destroy_bitmap(bmp); - - /* Success message */ - msg_print("Screen dump saved."); - msg_print(NULL); -} - - -/* - * GRX font file reader by Mark Wodrich. - * - * GRX FNT files consist of the header data (see struct below). If the font - * is proportional, followed by a table of widths per character (unsigned - * shorts). Then, the data for each character follows. 1 bit/pixel is used, - * with each line of the character stored in contiguous bytes. High bit of - * first byte is leftmost pixel of line. - * - * Note that GRX FNT files can have a variable number of characters, so you - * must verify that any "necessary" characters exist before using them. - * - * The GRX FNT files were developed by ???. - */ - - -/* - * Magic value - */ -#define FONTMAGIC 0x19590214L - - -/* - * Forward declare - */ -typedef struct FNTfile_header FNTfile_header; - - -/* - * .FNT file header - */ -struct FNTfile_header -{ - unsigned long magic; - unsigned long bmpsize; - unsigned short width; - unsigned short height; - unsigned short minchar; - unsigned short maxchar; - unsigned short isfixed; - unsigned short reserved; - unsigned short baseline; - unsigned short undwidth; - char fname[16]; - char family[16]; -}; - - -/* - * A "bitmap" is simply an array of bytes - */ -typedef byte *GRX_BITMAP; - - -/* - * Temporary space to store font bitmap - */ -#define GRX_TMP_SIZE 4096 - - -/* - * ??? - */ -void convert_grx_bitmap(int width, int height, GRX_BITMAP src, GRX_BITMAP dest) -{ - unsigned short x, y, bytes_per_line; - unsigned char bitpos, bitset; - - bytes_per_line = (width + 7) >> 3; - - for (y = 0; y < height; y++) - { - for (x = 0; x < width; x++) - { - bitpos = 7 - (x & 7); - bitset = !!(src[(bytes_per_line * y) + (x >> 3)] & (1 << bitpos)); - dest[y*width + x] = bitset; - } - } -} - - -/* - * ??? - */ -GRX_BITMAP *load_grx_bmps(PACKFILE *f, FNTfile_header *hdr, - int numchar, unsigned short *wtable) -{ - int t, width, bmp_size; - GRX_BITMAP temp; - GRX_BITMAP *bmp; - - /* alloc array of bitmap pointers */ - bmp = malloc(sizeof(GRX_BITMAP) * numchar); - - /* assume it's fixed width for now */ - width = hdr->width; - - /* temporary working area to store FNT bitmap */ - temp = malloc(GRX_TMP_SIZE); - - for (t = 0; t < numchar; t++) - { - /* if prop. get character width */ - if (!hdr->isfixed) width = wtable[t]; - - /* work out how many bytes to read */ - bmp_size = ((width + 7) >> 3) * hdr->height; - - /* oops, out of space! */ - if (bmp_size > GRX_TMP_SIZE) - { - free(temp); - for (t--; t >= 0; t--) free(bmp[t]); - free(bmp); - return NULL; - } - - /* alloc space for converted bitmap */ - bmp[t] = malloc(width * hdr->height); - - /* read data */ - pack_fread(temp, bmp_size, f); - - /* convert to 1 byte/pixel */ - convert_grx_bitmap(width, hdr->height, temp, bmp[t]); - } - - free(temp); - return bmp; -} - - -/* - * ??? - */ - -FONT* import_grx_font(char *fname)
- { - return NULL; - } - -//FONT *import_grx_font(char *fname) -//{ -// PACKFILE *f; -// -// /* GRX font header */ -// FNTfile_header hdr; -// -// /* number of characters in the font */ -// int numchar; -// -// /* table of widths for each character */ -// unsigned short *wtable = NULL; -// -// /* array of font bitmaps */ -// GRX_BITMAP *bmp; -// -// /* the Allegro font */ -// FONT *font = NULL; -// -// FONT_PROP *font_prop; -// int c, c2, start, width; -// -// -// f = pack_fopen(fname, F_READ); -// -// if (!f) return NULL; -// -// /* read the header structure */ -// pack_fread(&hdr, sizeof(hdr), f); -// -// /* check magic number */ -// if (hdr.magic != FONTMAGIC) -// { -// pack_fclose(f); -// return NULL; -// } -// -// numchar = hdr.maxchar - hdr.minchar + 1; -// -// /* proportional font */ -// if (!hdr.isfixed) -// { -// wtable = malloc(sizeof(unsigned short) * numchar); -// pack_fread(wtable, sizeof(unsigned short) * numchar, f); -// } -// -// bmp = load_grx_bmps(f, &hdr, numchar, wtable); -// -// if (!bmp) goto get_out; -// -// if (pack_ferror(f)) goto get_out; -// -// font = malloc(sizeof(FONT)); -// font->height = -1; -// font->dat.dat_prop = font_prop = malloc(sizeof(FONT_PROP)); -// -// start = 32 - hdr.minchar; -// width = hdr.width; -// -// for (c = 0; c < FONT_SIZE; c++) -// { -// c2 = c + start; -// -// if ((c2 >= 0) && (c2 < numchar)) -// { -// if (!hdr.isfixed) width = wtable[c2]; -// -// font_prop->dat[c] = create_bitmap_ex(8, width, hdr.height); -// memcpy(font_prop->dat[c]->dat, bmp[c2], width*hdr.height); -// } -// else -// { -// font_prop->dat[c] = create_bitmap_ex(8, 8, hdr.height); -// clear(font_prop->dat[c]); -// } -// } -// -//get_out: -// -// pack_fclose(f); -// -// if (wtable) free(wtable); -// -// if (bmp) -// { -// for (c = 0; c < numchar; c++) free(bmp[c]); -// -// free(bmp); -// } -// -// return font; -//} - - -/* - * Initialize the terminal windows - */ -static bool init_windows(void) -{ - int i, num_windows; - - term_data *td; - - char section[80]; - - char filename[1024]; - - char buf[128]; - - /* Section name */ - sprintf(section, "Mode-%d", resolution); - - /* Get number of windows */ - num_windows = get_config_int(section, "num_windows", 1); - - /* Paranoia */ - if (num_windows > 8) num_windows = 8; - - /* Init the terms */ - for (i = 0; i < num_windows; i++) - { - td = &data[i]; - WIPE(td, term_data); - - /* Section name */ - sprintf(section, "Term-%d-%d", resolution, i); - - /* Term number */ - td->number = i; - - /* Coordinates of left top corner */ - td->x = get_config_int(section, "x", 0); - td->y = get_config_int(section, "y", 0); - - /* Rows and cols of term */ - td->rows = get_config_int(section, "rows", 24); - td->cols = get_config_int(section, "cols", 80); - - /* Tile size */ - td->tile_wid = get_config_int(section, "tile_wid", 8); - td->tile_hgt = get_config_int(section, "tile_hgt", 13); - - /* Font size */ - td->font_wid = get_config_int(section, "tile_wid", 8); - td->font_hgt = get_config_int(section, "tile_hgt", 13); - - /* Get font filename */ - strcpy(buf, get_config_string(section, "font_file", "xm8x13.fnt")); - - /* Build the name of the font file */ - path_build(filename, 1024, xtra_font_dir, buf); - - /* Load a "*.fnt" file */ - if (suffix(filename, ".fnt")) - { - /* Load the font file */ - if (!(td->font = import_grx_font(filename))) - { - quit_fmt("Error reading font file '%s'", filename); - } - } - - /* Load a "*.dat" file */ - else if (suffix(filename, ".dat")) - { - DATAFILE *fontdata; - - /* Load the font file */ - if (!(fontdata = load_datafile(filename))) - { - quit_fmt("Error reading font file '%s'", filename); - } - - /* Save the font data */ - td->font = fontdata[1].dat; - - /* Unload the font file */ - unload_datafile_object(fontdata); - } - - /* Oops */ - else - { - quit_fmt("Unknown suffix in font file '%s'", filename); - } - - /* Link the term */ - term_data_link(td); - angband_term[i] = &td->t; - } - - /* Success */ - return 0; -} - - -#ifdef USE_BACKGROUND - -/* - * Initialize the window backgrounds - */ -static void init_background(void) -{ - int i; - - char filename[1024]; - - char buf[128]; - - PALLETE background_pallete; - - /* Get the backgrounds */ - for (i = 0; i < 16; i++) - { - /* Get background filename */ - strcpy(buf, get_config_string("Background", format("Background-%d", i), "")); - - /* Build the filename for the background-bitmap */ - path_build(filename, 1024, xtra_graf_dir, buf); - - /* Try to open the bitmap file */ - background[i] = load_bitmap(filename, background_pallete); - } - -#ifndef USE_SPECIAL_BACKGROUND - /* - * Set the palette for the background - */ - if (background[0]) - { - set_palette_range(background_pallete, 0, COLOR_OFFSET - 1, 0); - } -#endif /* USE_SPECIAL_BACKGROUND */ -} - -#endif /* USE_BACKGROUND */ - - -#ifdef USE_GRAPHICS - -/* - * Initialize graphics - */ -static bool init_graphics(void) -{ - char filename[1024]; - char section[80]; - char name_tiles[128]; - - /* Large bitmap for the tiles */ - BITMAP *tiles = NULL; - PALLETE tiles_pallete; - - /* Size of each bitmap tile */ - int bitmap_wid; - int bitmap_hgt; - - int num_windows; - - if (!graphics_initialized) - { - /* Section name */ - sprintf(section, "Mode-%d", resolution); - - /* Get bitmap tile size */ - bitmap_wid = get_config_int(section, "bitmap_wid", 8); - bitmap_hgt = get_config_int(section, "bitmap_hgt", 8); - - /* Get bitmap filename */ - strcpy(name_tiles, get_config_string(section, "bitmap_file", "8x8.bmp")); - - /* Get number of windows */ - num_windows = get_config_int(section, "num_windows", 1); - - /* Build the name of the bitmap file */ - path_build(filename, 1024, xtra_graf_dir, name_tiles); - - /* Open the bitmap file */ - if ((tiles = load_bitmap(filename, tiles_pallete)) != NULL) - { - int i; - - /* - * Set the graphics mode to "new" if Adam Bolt's - * new 16x16 tiles are used. - */ - ANGBAND_GRAF = get_config_string(section, "graf-mode", "old"); - - /* Select the bitmap pallete */ - set_palette_range(tiles_pallete, 0, COLOR_OFFSET - 1, 0); - - /* Prepare the graphics */ - for (i = 0; i < num_windows; i++) - { - term_data *td; - - int col, row; - int cols, rows; - int width, height; - int src_x, src_y; - int tgt_x, tgt_y; - - td = &data[i]; - - cols = tiles->w / bitmap_wid; - rows = tiles->h / bitmap_hgt; - - width = td->tile_wid * cols; - height = td->tile_hgt * rows; - - /* Initialize the tile graphics */ - td->tiles = create_bitmap(width, height); - - for (row = 0; row < rows; ++row) - { - src_y = row * bitmap_hgt; - tgt_y = row * td->tile_hgt; - - for (col = 0; col < cols; ++col) - { - src_x = col * bitmap_wid; - tgt_x = col * td->tile_wid; - - stretch_blit(tiles, td->tiles, - src_x, src_y, - bitmap_wid, bitmap_hgt, - tgt_x, tgt_y, - td->tile_wid, td->tile_hgt); - } - } - } - - /* Free the old tiles bitmap */ - if (tiles) destroy_bitmap(tiles); - - graphics_initialized = TRUE; - - /* Success */ - return (TRUE); - } - - /* Failure */ - return (FALSE); - } - - /* Success */ - return (TRUE); -} - -#endif /* USE_GRAPHICS */ - -#ifdef USE_SOUND - -/* - * Initialize sound - * We try to get a list of the available sound-files from "lib/xtra/sound/sound.cfg" - * and then preload the samples. Every Angband-sound-event can have several samples - * assigned. Angband will randomly select which is played. This makes it easy to - * create "sound-packs", just copy wav-files into the "lib/xtra/sound/" folder and - * add the filenames to "sound.cfg" in the same folder. - */ -static bool init_sound(void) -{ - int i, j, done; - - char section[128]; - char filename[1024]; - char **argv; - - struct ffblk f; - - if (sound_initialized) return (TRUE); - - /* Initialize Allegro sound */ - if (!install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL)) - { -#ifdef USE_MOD_FILES - /* - * Try to enable support for MOD-, and S3M-files - * The parameter for install_mod() is the number - * of channels reserved for the MOD/S3M-file. - */ - if (install_mod(16) > 0) mod_file_initialized = TRUE; -#endif /* USE_MOD_FILES */ - - /* Access the new sample */ - path_build(filename, 1024, xtra_sound_dir, "sound.cfg"); - - /* Read config info from "lib/xtra/sound/sound.cfg" */ - override_config_file(filename); - - /* Sound section */ - strcpy(section, "Sound"); - - /* Prepare the sounds */ - for (i = 1; i < SOUND_MAX + 1; i++) - { - /* Get the sample names */ - argv = get_config_argv(section, angband_sound_name[i], &sample_count[i]); - - /* Limit the number of samples */ - if (sample_count[i] > SAMPLE_MAX) sample_count[i] = SAMPLE_MAX; - - for (j = 0; j < sample_count[i]; j++) - { - /* Access the new sample */ - path_build(filename, 1024, xtra_sound_dir, argv[j]); - - /* Load the sample */ - samples[i][j] = load_sample(filename); - } - } - - /* - * Get a list of music files - */ -#ifdef USE_MOD_FILES - if (mod_file_initialized) - { - done = findfirst(format("%s/*.*", xtra_music_dir), &f, FA_ARCH | FA_RDONLY); - } - else -#endif /* USE_MOD_FILES */ - done = findfirst(format("%s/*.mid", xtra_music_dir), &f, FA_ARCH | FA_RDONLY); - - - while (!done && (song_number <= MAX_SONGS)) - { - /* Add music files */ - { - strcpy(music_files[song_number], f.ff_name); - song_number++; - } - - done = findnext(&f); - } - - /* Use "angdos.cfg" */ - override_config_file("angdos.cfg"); - - /* Sound section */ - strcpy(section, "Sound"); - - /* Get the volume setting */ - digi_volume = get_config_int(section, "digi_volume", 255); - midi_volume = get_config_int(section, "midi_volume", 255); - - /* Set the volume */ - set_volume(digi_volume, midi_volume); - - /* Success */ - return (TRUE); - } - - /* Init failed */ - return (FALSE); -} - - -/* - * Make a sound - */ -static errr Term_xtra_dos_sound(int v) -{ - int n; - - /* Sound disabled */ - if (!use_sound) return (1); - - /* Illegal sound */ - if ((v < 0) || (v >= SOUND_MAX)) return (1); - - /* Get a random sample from the available ones */ - n = rand_int(sample_count[v]); - - /* Play the sound, catch errors */ - if (samples[v][n]) - { - return (play_sample(samples[v][n], 255, 128, 1000, 0) == 0); - } - - /* Oops */ - return (1); -} - - -/* - * Play a song-file - */ -static void play_song(void) -{ - char filename[256]; - - /* Clear the old song */ - if (midi_song) destroy_midi(midi_song); - midi_song = NULL; -#ifdef USE_MOD_FILES - if (mod_file_initialized) - { - stop_mod(); - if (mod_song) destroy_mod(mod_song); - mod_song = NULL; - } -#endif /* USE_MOD_FILES */ - - /* Access the new song */ - path_build(filename, 1024, xtra_music_dir, music_files[current_song - 1]); - - /* Load and play the new song */ - if ((midi_song = load_midi(filename))) play_midi(midi_song, 0); -#ifdef USE_MOD_FILES - else if (mod_file_initialized) - { - if ((mod_song = load_mod(filename))) play_mod(mod_song, FALSE); - } -#endif /* USE_MOD_FILES */ -} - -#endif /* USE_SOUND */ - - -/* - * Attempt to initialize this file - * - * Hack -- we assume that "blank space" should be "white space" - * (and not "black space" which might make more sense). - * - * Note the use of "((x << 2) | (x >> 4))" to "expand" a 6 bit value - * into an 8 bit value, without losing much precision, by using the 2 - * most significant bits as the least significant bits in the new value. - * - * We should attempt to "share" bitmaps (and fonts) between windows - * with the same "tile" size. XXX XXX XXX - */ -errr init_dos(void) -{ - term_data *td; - - char section[80]; - - int screen_wid; - int screen_hgt; - - /* Initialize the Allegro library (never fails) */ - (void)allegro_init(); - - /* Install timer support for music and sound */ - install_timer(); - - /* Enable the gif-loading function */ - register_bitmap_file_type("GIF", load_gif , NULL); - - /* Read config info from filename */ - set_config_file("angdos.cfg"); - - /* Main section */ - strcpy(section, "Angband"); - - /* Get screen size */ - resolution = get_config_int(section, "Resolution", 1); - - /* Section name */ - sprintf(section, "Mode-%d", resolution); - - /* Get the screen dimensions */ - screen_wid = get_config_int(section, "screen_wid", 640); - screen_hgt = get_config_int(section, "screen_hgt", 480); - - /* Set the color depth */ - set_color_depth(8); - - /* Auto-detect, and instantiate, the appropriate graphics mode */ - if ((set_gfx_mode(GFX_AUTODETECT, screen_wid, screen_hgt, 0, 0)) < 0) - { - /* - * Requested graphics mode is not available - * We retry with the basic 640x480 mode - */ - resolution = 1; - - if ((set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0)) < 0) - { - char error_text[1024]; - - /* Save the Allegro error description */ - strcpy(error_text, allegro_error); - - /* Shut down Allegro */ - allegro_exit(); - - /* Print the error description */ - plog_fmt("Error selecting screen mode: %s", error_text); - - /* Failure */ - return ( -1); - } - } - - /* Hook in "z-util.c" hook */ - quit_aux = dos_quit_hook; - - /* Build the "graf" path */ - path_build(xtra_graf_dir, 1024, ANGBAND_DIR_XTRA, "graf"); - - /* Build the "font" path */ - path_build(xtra_font_dir, 1024, ANGBAND_DIR_XTRA, "font"); - - /* Build the "sound" path */ - path_build(xtra_sound_dir, 1024, ANGBAND_DIR_XTRA, "sound"); - - /* Build the "music" path */ - path_build(xtra_music_dir, 1024, ANGBAND_DIR_XTRA, "music"); - - /* Initialize the windows */ - init_windows(); - -#ifdef USE_SOUND - - /* Look for the sound preferences in "angdos.cfg" */ - if (!arg_sound) - { - arg_sound = get_config_int("Angband", "Sound", TRUE); - } - -#endif /* USE_SOUND */ - -#ifdef USE_GRAPHICS - - /* Look for the graphic preferences in "angdos.cfg" */ - if (!arg_graphics) - { - arg_graphics = get_config_int("Angband", "Graphics", TRUE); - } - -#endif /* USE_GRAPHICS */ - - /* Initialize the "complex" RNG for the midi-shuffle function */ - Rand_quick = FALSE; - Rand_state_init(time(NULL)); - - /* Set the Angband colors/graphics/sound mode */ - Term_xtra_dos_react(); - -#ifdef USE_BACKGROUND - - /* Initialize the background graphics */ - init_background(); - -#endif /* USE_BACKGROUND */ - - /* Clear the screen */ - clear_to_color(screen, COLOR_OFFSET + TERM_DARK); - - /* Main screen */ - td = &data[0]; - - /* Build a cursor bitmap */ - cursor = create_bitmap(td->tile_wid, td->tile_hgt); - - /* Erase the cursor sprite */ - clear(cursor); - - /* Draw the cursor sprite (yellow rectangle) */ - rect(cursor, 0, 0, td->tile_wid - 1, td->tile_hgt - 1, - COLOR_OFFSET + TERM_YELLOW); - - /* Activate the main term */ - Term_activate(angband_term[0]); - - /* Place the cursor */ - Term_curs_dos(0, 0); - -#ifdef USE_BACKGROUND - - /* Use transparent text */ - text_mode( -1); - -#endif /* USE_BACKGROUND */ - - /* Success */ - return 0; -} - -#endif /* USE_DOS */ diff --git a/src/main-emx.c b/src/main-emx.c deleted file mode 100644 index 6d048e79..00000000 --- a/src/main-emx.c +++ /dev/null @@ -1,1268 +0,0 @@ -/* File: main-emx.c */ - -/* - * Copyright (c) 1997 Ben Harrison, Ekkehard Kraemer, and others - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. - */ - -/* Purpose: Support for OS/2 EMX Angband */ - -/* Author: ekraemer@pluto.camelot.de (Ekkehard Kraemer) */ - -/* Current maintainer: silasd@psyber.com (Silas Dunsmore) */ -/* Unless somebody else wants it.... */ - -#ifdef USE_EMX - -/* - * === Instructions for using Angband 2.7.X with OS/2 === - * - * The patches (file "main-emx.c") to compile Angband 2.7.X under OS/2 - * were written by ekraemer@pluto.camelot.de (Ekkehard Kraemer). - * - * TO COMPILE: - * - * - untar the archive into /angband (or /games/angband or whatever) - * - change directory to /angband/src - * - run "dmake -B -r -f makefile.emx" (not gmake or make) - * - * TO INSTALL: - * - * - change directory to /angband/src - * - run "dmake -B -r -f makefile.emx install" (not gmake or make) - * - copy your old savefile into ./lib/save and your old pref.prf into ./lib/user - * - start /angband/angband.exe for one single window - * - start /angband/startwnd.cmd for multiple windows - * - * TO REMOVE TEMPORARY FILES: - * - * - run 'dmake -B -r -f makefile.emx clean' - * - * - * I use EMX 0.9b, but every EMX compiler since 0.8g or so should work - * fine. EMX is available at ftp-os2.cdrom.com ("Hobbes"), as is dmake. - * - * dmake: ftp://ftp-os2.cdrom.com/all/program/dmake38X.zip - * EMX: ftp://ftp-os2.cdrom.com/2_x/unix/emx???/ (most probably) - * - * Old savefiles must be renamed to follow the new "savefile" naming - * conventions. Either rename the savefile to "PLAYER", or start the - * program with the "-uName" flag. See "main.c" for details. The - * savefiles are stores in "./lib/save" if you forgot the old names... - * - * Changes - * ======= - * - * When By Version What - * ------------------------------------------------------------------- - * - * 18.11.95 EK 2.7.8 Added window/pipe code - * Introduced __EMX__CLIENT__ hack - * - * 15.12.95 EK 2.7.9 Updated for 2.7.9 - * beta Added third view - * Added number of line support in aclient - * - * 25.12.95 EK 2.7.9 Added 'install' target - * non-beta Updated installation hints - * Uploaded binary to export.andrew.cmu.edu - * - * 25.01.96 EK 2.7.9 Updated for 2.7.9v3 - * v3 Removed (improved) keyboard hack - * Introduced pref-emx.prf - * Phew... Makefile.emx grows! (patches, export) - * Uploaded binary to export.andrew.cmu.edu - * - * 26.01.96 EK Added files.uue target - * - * 22.02.96 EK Added PM support - * - * 2.03.96 EK 2.7.9 Uploaded binaries to export.andrew.cmu.edu - * v4 - * - * 9.03.96 EK 2.7.9 Adjustable background color (PM) - * v5 Added map window - - * 3 Dec 97 SWD 282 Brought key-handling, macros in sync with DOS. - * Hacked on sub-window code -- it compiles, but - * doesn't link. - * - * 23 Jan 98 SWD 282 Hacked more on sub-windows. Now links, with - * warnings. Seems to work. - * - * 01 Nov 98 AGA 2.8.3 Adjusted for 2.8.3 sources, typos corrected - * - * 01 Nov 98 AGA Z214b Corrections for ZAngband 2.1.4 beta - * - */ - -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/kbdscan.h> -#include <io.h> -#define INCL_KBD 1 -#include <os2.h> -#include <sys/video.h> - -#include "angband.h" - - -/* - * Maximum windows - */ -#define MAX_TERM_DATA 8 - - -/* - * Keypress input modifier flags (copied from main-ibm.c) - * - * SWD: these could be changed to the definitions in <os2.h>, which are - * direct bitmasks instead of shift-counts. - */ -#define K_RSHIFT 0 /* Right shift key down */ -#define K_LSHIFT 1 /* Left shift key down */ -#define K_CTRL 2 /* Ctrl key down */ -#define K_ALT 3 /* Alt key down */ -#define K_SCROLL 4 /* Scroll lock on */ -#define K_NUM 5 /* Num lock on */ -#define K_CAPS 6 /* Caps lock on */ -#define K_INSERT 7 /* Insert on */ - - -/* - * Prototypes! - */ -static errr Term_curs_emx(int x, int y); -static errr Term_wipe_emx(int x, int y, int n); -static errr Term_text_emx(int x, int y, int n, unsigned char a, cptr s); -static void Term_init_emx(term *t); -static void Term_nuke_emx(term *t); - -#ifndef EMXPM - -/* - * termPipe* is sometimes cast to term* and vice versa, - * so "term t;" must be the first line - */ - -typedef struct -{ - term t; - FILE *out; /* used by the ..._pipe_emx stuff */ -} -termPipe; - -/* - * Communication between server and client - */ - -enum -{ - PIP_INIT, - PIP_NUKE, - PIP_XTRA, - PIP_CURS, - PIP_WIPE, - PIP_TEXT, -}; - - -/* - * Current cursor "size" - */ -static int curs_start = 0; -static int curs_end = 0; - -/* - * Angband color conversion table - * - * Note that "Light Green"/"Yellow"/"Red" are used for - * "good"/"fair"/"awful" stats and conditions. - * - * But "brown"/"light brown"/"orange" are really only used - * for "objects" (such as doors and spellbooks), and these - * values can in fact be re-defined. - * - * Future versions of Angband will probably allow the - * "use" of more that 16 colors, so "extra" entries can be - * made at the end of this table in preparation. - */ -static int colors[16] = -{ - F_BLACK, /* Black */ - F_WHITE | INTENSITY, /* White */ - F_WHITE, /* XXX Gray */ - F_RED | INTENSITY, /* Orange */ - F_RED, /* Red */ - F_GREEN, /* Green */ - F_BLUE, /* Blue */ - F_BROWN, /* Brown */ - F_BLACK | INTENSITY, /* Dark-grey */ - F_WHITE, /* XXX Light gray */ - F_MAGENTA, /* Purple */ - F_YELLOW | INTENSITY, /* Yellow */ - F_RED | INTENSITY, /* Light Red */ - F_GREEN | INTENSITY, /* Light Green */ - F_BLUE | INTENSITY, /* Light Blue */ - F_BROWN | INTENSITY /* Light brown */ -}; - -/* - * Display a cursor, on top of a given attr/char - */ -static errr Term_curs_emx(int x, int y) -{ - v_gotoxy(x, y); - v_ctype(curs_start, curs_end); - - return (0); -} - -/* - * Erase a grid of space (as if spaces were printed) - */ -static errr Term_wipe_emx(int x, int y, int n) -{ - v_gotoxy(x, y); - v_putn(' ', n); - - return (0); -} - -/* - * Draw some text, wiping behind it first - */ -static errr Term_text_emx(int x, int y, int n, unsigned char a, cptr s) -{ - /* Convert the color and put the text */ - v_attrib(colors[a & 0x0F]); - v_gotoxy(x, y); - v_putm(s, n); - - return (0); -} - -/* - * EMX initialization - */ -static void Term_init_emx(term *t) -{ - struct _KBDINFO kbdinfo; /* see structure description ?somewhere? */ - - v_init(); - v_getctype(&curs_start, &curs_end); - /* hide cursor (?) XXX XXX XXX */ - v_clear(); - - /* the documentation I (SWD) have implies, in passing, that setting */ - /* "binary mode" on the keyboard device will prevent the O/S from */ - /* acting on keys such as ^S (pause) and ^P (printer echo). */ - - /* note also that "KbdSetStatus is ignored for a Vio-windowed application." */ - /* so there may well be problems with running this in a window. Damnit. */ - - /* this is kind of a nasty structure, as you can't just flip a bit */ - /* to change binary/ASCII mode, or echo on/off mode... nor can you */ - /* clear the whole thing -- certain bits need to be preserved. */ - - KbdGetStatus(&kbdinfo, (HKBD)0); - kbdinfo.fsMask &= ~ (KEYBOARD_ECHO_ON | /* clear lowest four bits */ - KEYBOARD_ECHO_OFF | KEYBOARD_BINARY_MODE | KEYBOARD_ASCII_MODE); - kbdinfo.fsMask |= (KEYBOARD_BINARY_MODE); /* set bit two */ - KbdSetStatus(&kbdinfo, (HKBD)0); - -#if 1 /* turn off for debug */ - signal(SIGHUP, SIG_IGN); - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - /* signal(SIGILL,SIG_IGN); */ - /* signal(SIGTRAP,SIG_IGN); */ - /* signal(SIGABRT,SIG_IGN); */ - /* signal(SIGEMT,SIG_IGN); */ - /* signal(SIGFPE,SIG_IGN); */ - /* signal(SIGBUS,SIG_IGN); */ - /* signal(SIGSEGV,SIG_IGN); */ - /* signal(SIGSYS,SIG_IGN); */ - signal(SIGPIPE, SIG_IGN); - signal(SIGALRM, SIG_IGN); - /* signal(SIGTERM,SIG_IGN); */ - signal(SIGUSR1, SIG_IGN); - signal(SIGUSR2, SIG_IGN); - signal(SIGCHLD, SIG_IGN); - signal(SIGBREAK, SIG_IGN); -#endif - -} - -/* - * EMX shutdown - */ -static void Term_nuke_emx(term *t) -{ - /* Move the cursor to bottom of screen */ - v_gotoxy(0, 23); - - /* Restore the cursor (not necessary) */ - v_ctype(curs_start, curs_end); - - /* Set attribute to gray on black */ - v_attrib(F_WHITE); - - /* Clear the screen */ - v_clear(); -} - - -#ifndef __EMX__CLIENT__ - -/* - * Oh no, more prototypes! - */ -static errr CheckEvents(int returnImmediately); -static errr Term_xtra_pipe_emx(int n, int v); -static errr Term_curs_pipe_emx(int x, int y); -static errr Term_wipe_pipe_emx(int x, int y, int n); -static errr Term_text_pipe_emx(int x, int y, int n, unsigned char a, cptr s); -static void Term_init_pipe_emx(term *t); -static void Term_nuke_pipe_emx(term *t); -static FILE *initPipe(const char *name); -static void initPipeTerm(termPipe *pipe, const char *name, term **term); - -/* - * Main initialization function - */ -errr init_emx(void); - -/* - * The screens - */ -static termPipe term_screen_aga[MAX_TERM_DATA]; - - -/* - * Check for events -- called by "Term_scan_emx()" - * - * Note -- this is probably NOT the most efficient way - * to "wait" for a keypress (TERM_XTRA_EVENT). - * - * - * This code was ripped from "main-ibm.c" -- consult it to - * figure out what's going on. - * - * See "main-ibm.c" for more information about "macro encoding". - * - * - * The following documentation was cut&pasted from - * the OS/2 Programming Reference, PRCP.INF - * <ftp://hobbes.nmsu.edu/pub/os2/dev/16-bit/inf16bit.zip> -------------------------------------------------------------------------------- - - - This call returns a character data record from the keyboard. - - KbdCharIn (CharData, IOWait, KbdHandle) - - CharData (PKBDKEYINFO) - output - Address of the character data structure: - - asciicharcode (UCHAR) - ASCII character code. The scan code received from the keyboard is - translated to the ASCII character code. - - scancode (UCHAR) - Code received from the keyboard. The scan code received from the - keyboard is translated to the ASCII character code. - - status (UCHAR) - State of the keystroke event: - - Bit Description - - 7-6 00 = Undefined - - 01 = Final character, interim character flag off - - 10 = Interim character - - 11 = Final character, interim character flag on. - - 5 1 = Immediate conversion requested. - - 4-2 Reserved. - - 1 0 = Scan code is a character. - - 1 = Scan code is not a character; is an extended key code - from the keyboard. - - 0 1 = Shift status returned without character. - - reserved (UCHAR) - NLS shift status. Reserved, set to zero. - - shiftkeystat (USHORT) - Shift key status. - - Bit Description - 15 SysReq key down - 14 CapsLock key down - 13 NumLock key down - 12 ScrollLock key down - 11 Right Alt key down - 10 Right Ctrl key down - 9 Left Alt key down - 8 Left Ctrl key down - 7 Insert on - 6 CapsLock on - 5 NumLock on - 4 ScrollLock on - 3 Either Alt key down - 2 Either Ctrl key down - 1 Left Shift key down - 0 Right Shift key down - - time (ULONG) - Time stamp indicating when a key was pressed. It is specified in - milliseconds from the time the system was started. - - IOWait (USHORT) - input - Wait if a character is not available. - - Value Definition - 0 Requestor waits for a character if one is not available. - 1 Requestor gets an immediate return if no character is - available. - - KbdHandle (HKBD) - input - Default keyboard or the logical keyboard. - - rc (USHORT) - return - Return code descriptions are: - - 0 NO_ERROR - 375 ERROR_KBD_INVALID_IOWAIT - 439 ERROR_KBD_INVALID_HANDLE - 445 ERROR_KBD_FOCUS_REQUIRED - 447 ERROR_KBD_KEYBOARD_BUSY - 464 ERROR_KBD_DETACHED - 504 ERROR_KBD_EXTENDED_SG - - Remarks - - On an enhanced keyboard, the secondary enter key returns the normal - character 0DH and a scan code of E0H. - - Double-byte character codes (DBCS) require two function calls to obtain - the entire code. - - If shift report is set with KbdSetStatus, the CharData record returned - reflects changed shift information only. - - Extended ASCII codes are identified with the status byte, bit 1 on and the - ASCII character code being either 00H or E0H. Both conditions must be - satisfied for the character to be an extended keystroke. For extended - ASCII codes, the scan code byte returned is the second code (extended - code). Usually the extended ASCII code is the scan code of the primary - key that was pressed. - - A thread in the foreground session that repeatedly polls the keyboard - with KbdCharIn (with no wait), can prevent all regular priority class - threads from executing. If polling must be used and a minimal amount of - other processing is being performed, the thread should periodically yield to - the CPU by issuing a DosSleep call for an interval of at least 5 - milliseconds. - - - Family API Considerations - - Some options operate differently in the DOS mode than in the OS /2 mode. - Therefore, the following restrictions apply to KbdCharIn when coding in - the DOS mode: - - o The CharData structure includes everything except the time stamp. - o Interim character is not supported - o Status can be 0 or 40H - o KbdHandle is ignored. - - -------------------------------------------------------------------------------- - - - typedef struct _KBDKEYINFO { / * kbci * / - UCHAR chChar; / * ASCII character code * / - UCHAR chScan; / * Scan Code * / - UCHAR fbStatus; / * State of the character * / - UCHAR bNlsShift; / * Reserved (set to zero) * / - USHORT fsState; / * State of the shift keys * / - ULONG time; / * Time stamp of keystroke (ms since ipl) * / - }KBDKEYINFO; - - #define INCL_KBD - - USHORT rc = KbdCharIn(CharData, IOWait, KbdHandle); - - PKBDKEYINFO CharData; / * Buffer for data * / - USHORT IOWait; / * Indicate if wait * / - HKBD KbdHandle; / * Keyboard handle * / - - USHORT rc; / * return code * / - - -------------------------------------------------------------------------------- - * - */ -static errr CheckEvents(int returnImmediately) -{ - int i, k, s; - - bool mc = FALSE; - bool ms = FALSE; - bool ma = FALSE; - - /* start OS/2 specific section */ - - struct _KBDKEYINFO keyinfo; /* see structure description above */ - - /* Check (and possibly wait) for a keypress */ - /* see function description above */ - KbdCharIn( &keyinfo, returnImmediately, (HKBD)0 ); - -#if 0 - printf("AC:%x SC:%x ST:%x R1:%x SH:%x TI:%ld\n", /* OS/2 debug */ - keyinfo.chChar, - keyinfo.chScan, - keyinfo.fbStatus, - keyinfo.bNlsShift, - keyinfo.fsState, - keyinfo.time ); -#endif - - /* If there wasn't a key, leave now. */ - if ((keyinfo.fbStatus & 0xC0) == 0) return (1); - - - /* by a set of lucky coincidences, the data maps directly over. */ - k = keyinfo.chChar; - s = keyinfo.chScan; - i = (keyinfo.fsState & 0xFF); - - /* end OS/2 specific section */ - - - /* Process "normal" keys */ - if ( k != 0 && ((s <= 58) || (s == 0xE0)) ) /* Tweak: allow for ALT-keys */ - { - /* Enqueue it */ - Term_keypress(k); - - /* Success */ - return (0); - } - - /* Extract the modifier flags */ - if (i & (1 << K_CTRL)) mc = TRUE; - if (i & (1 << K_LSHIFT)) ms = TRUE; - if (i & (1 << K_RSHIFT)) ms = TRUE; - if (i & (1 << K_ALT)) ma = TRUE; - - - /* Begin a "macro trigger" */ - Term_keypress(31); - - /* Hack -- Send the modifiers */ - if (mc) Term_keypress('C'); - if (ms) Term_keypress('S'); - if (ma) Term_keypress('A'); - - /* Introduce the hexidecimal scan code */ - Term_keypress('x'); - - /* Encode the hexidecimal scan code */ - Term_keypress(hexsym[s / 16]); - Term_keypress(hexsym[s % 16]); - - /* End the "macro trigger" */ - Term_keypress(13); - - /* Success */ - return (0); -} - - - -/* - * Do a special thing (beep, flush, etc) - */ -static errr Term_xtra_emx(int n, int v) -{ - switch (n) - { - case TERM_XTRA_SHAPE: - if (v) - { - v_ctype(curs_start, curs_end); - } - else - { - v_hidecursor(); - } - return (0); - - case TERM_XTRA_NOISE: - DosBeep(440, 50); - return (0); - - case TERM_XTRA_FLUSH: - while (!CheckEvents(TRUE)); - return 0; - - case TERM_XTRA_EVENT: - - /* Process an event */ - return (CheckEvents(!v)); - - /* Success */ - return (0); - - case TERM_XTRA_CLEAR: - v_clear(); - return (0); - } - - return (1); -} - -static errr Term_xtra_pipe_emx(int n, int v) -{ - termPipe *tp = (termPipe*)Term; - - switch (n) - { - case TERM_XTRA_NOISE: - DosBeep(440, 50); - return (0); - - case TERM_XTRA_SHAPE: - return (0); - - case TERM_XTRA_EVENT: - return (CheckEvents(FALSE)); - - case TERM_XTRA_CLEAR: - - if (!tp->out) return -1; - - fputc(PIP_XTRA, tp->out); - fwrite(&n, sizeof(n), 1, tp->out); - fwrite(&v, sizeof(v), 1, tp->out); - fflush(tp->out); - - return (0); - } - - return (1); -} - -static errr Term_curs_pipe_emx(int x, int y) -{ - termPipe *tp = (termPipe*)Term; - - if (!tp->out) return -1; - - fputc(PIP_CURS, tp->out); - fwrite(&x, sizeof(x), 1, tp->out); - fwrite(&y, sizeof(y), 1, tp->out); - fflush(tp->out); - - return (0); -} - - -static errr Term_wipe_pipe_emx(int x, int y, int n) -{ - termPipe *tp = (termPipe*)Term; - - if (!tp->out) return -1; - - fputc(PIP_WIPE, tp->out); - fwrite(&x, sizeof(x), 1, tp->out); - fwrite(&y, sizeof(y), 1, tp->out); - fwrite(&n, sizeof(n), 1, tp->out); - fflush(tp->out); - - return (0); -} - - -static errr Term_text_pipe_emx(int x, int y, int n, unsigned char a, cptr s) -{ - termPipe *tp = (termPipe*)Term; - - if (!tp->out) return -1; - - fputc(PIP_TEXT, tp->out); - fwrite(&x, sizeof(x), 1, tp->out); - fwrite(&y, sizeof(y), 1, tp->out); - fwrite(&n, sizeof(n), 1, tp->out); - fwrite(&a, sizeof(a), 1, tp->out); - fwrite(s, n, 1, tp->out); - fflush(tp->out); - - return (0); -} - - -static void Term_init_pipe_emx(term *t) -{ - termPipe *tp = (termPipe*)t; - - if (tp->out) - { - fputc(PIP_INIT, tp->out); - fflush(tp->out); - } -} - - -static void Term_nuke_pipe_emx(term *t) -{ - termPipe *tp = (termPipe*)t; - - if (tp->out) - { - fputc(PIP_NUKE, tp->out); /* Terminate client */ - fflush(tp->out); - fclose(tp->out); /* Close Pipe */ - tp->out = NULL; /* Paranoia */ - } -} - -static void initPipeTerm(termPipe *pipe, const char *name, term **termTarget) -{ - term *t; - - t = &pipe->t; - - if ((pipe->out = initPipe(name)) != NULL) - { - /* Initialize the term */ - term_init(t, 80, 24, 1); - - /* Special hooks */ - t->init_hook = Term_init_pipe_emx; - t->nuke_hook = Term_nuke_pipe_emx; - - /* Add the hooks */ - t->text_hook = Term_text_pipe_emx; - t->wipe_hook = Term_wipe_pipe_emx; - t->curs_hook = Term_curs_pipe_emx; - t->xtra_hook = Term_xtra_pipe_emx; - - /* Save it */ - *termTarget = t; - - /* Activate it */ - Term_activate(t); - } -} - -/* - * Prepare "term.c" to use "USE_EMX" built-in video library - */ -errr init_emx(void) -{ - int i; - - term *t; - - /* Initialize the pipe windows */ - for (i = MAX_TERM_DATA - 1; i > 0; --i) - { - const char *name = angband_term_name[i]; - initPipeTerm(&term_screen_aga[i], name, &angband_term[i]); - } - - /* Initialize main window */ - t = &term_screen_aga[0].t; - - /* Initialize the term -- big key buffer */ - term_init(t, 80, 24, 1024); - - /* Special hooks */ - t->init_hook = Term_init_emx; - t->nuke_hook = Term_nuke_emx; - - /* Add the hooks */ - t->text_hook = Term_text_emx; - t->wipe_hook = Term_wipe_emx; - t->curs_hook = Term_curs_emx; - t->xtra_hook = Term_xtra_emx; - - /* Save it */ - angband_term[0] = t; - - /* Activate it */ - Term_activate(t); - - /* Success */ - return (0); -} - -static FILE *initPipe(const char *name) -{ - char buf[256]; - FILE *fi; - - sprintf(buf, "\\pipe\\angband\\%s", name); /* Name of pipe */ - fi = fopen(buf, "wb"); /* Look for server */ - return fi; -} - -#else /* __EMX__CLIENT__ */ - -int main(int argc, char **argv) -{ - int c, end = 0, lines = 25; - int x, y, h, n, v; - - FILE *in = NULL; - char a; - char buf[160]; - HPIPE pipe; - APIRET rc; - char *target; - - /* Check command line */ - if (argc != 2 && argc != 3) - { - printf("Usage: %s Mirror|Recall|Choice|Term-4|...|Term-7 [number of lines]\n" - "Start this before angband.exe\n", argv[0]); - exit(1); - } - - if (argc == 3) lines = atoi(argv[2]); - if (lines <= 0) lines = 25; - - printf("Looking for Angband... press ^C to abort\n"); - - target = strdup(argv[1]); - for (c = 0; c < strlen(target); c++) target[c] = tolower(target[c]); - - sprintf(buf, "\\pipe\\angband\\%s", target); - - do - { - rc = DosCreateNPipe((PSZ)buf, /* Create pipe */ - &pipe, - NP_ACCESS_INBOUND, - NP_WAIT | NP_TYPE_BYTE | NP_READMODE_BYTE | 1, - 1, /* No output buffer */ - 1, /* No input buffer */ - -1); - - if (rc) /* Pipe not created */ - { - printf("DosCreateNPipe: rc=%ld, pipe=%ld\n", (long)rc, (long)pipe); - break; - } - - do - { - rc = DosConnectNPipe(pipe); /* Wait for angband to connect */ - if (!rc) break; - _sleep2(500); /* Sleep for 0.5s */ - } - while (_read_kbd(0, 0, 0) == -1); /* Until key pressed */ - - if (rc) break; - - h = _imphandle(pipe); /* Register handle with io */ - setmode(h, O_BINARY); /* Make it binary */ - in = fdopen(h, "rb"); /* Register handle with stdio */ - - } - while (0); /* We don't need no stinking exception handling <g> */ - - if (!in) - { - printf("Sorry, the pipe connection to Angband could not be established.\n"); - exit(1); - } - - printf("Connected.\n"); - - sprintf(buf, "mode co80,%d", lines); - system(buf); - - /* Infinite loop */ - while (!end) - { - /* Get command */ - c = fgetc(in); - - switch (c) - { - case PIP_XTRA: - if (!fread(&n, sizeof(x), 1, in) || - !fread(&v, sizeof(y), 1, in)) - abort(); - - /* This hack prevents another hack */ - switch (n) - { - case TERM_XTRA_CLEAR: - v_clear(); - break; - - default: - printf("Sorry, angband.exe and aclient.exe don't fit together.\n"); - exit(1); - } - - break; - - case PIP_CURS: - if (!fread(&x, sizeof(x), 1, in) || - !fread(&y, sizeof(y), 1, in)) - abort(); - Term_curs_emx(x, y); - break; - - case PIP_WIPE: - if (!fread(&x, sizeof(x), 1, in) || - !fread(&y, sizeof(y), 1, in) || - !fread(&n, sizeof(n), 1, in)) - abort(); - Term_wipe_emx(x, y, n); - break; - - case PIP_TEXT: - if (!fread(&x, sizeof(x), 1, in) || - !fread(&y, sizeof(y), 1, in) || - !fread(&n, sizeof(n), 1, in) || - !fread(&a, sizeof(a), 1, in) || (n > 160) || - !fread(buf, n, 1, in)) - abort(); - Term_text_emx(x, y, n, a, buf); - break; - - case PIP_INIT: - Term_init_emx(NULL); - break; - - case PIP_NUKE: - case EOF: - default: - Term_nuke_emx(NULL); - end = 1; - break; - } - } - - return 0; -} - -#endif /* __EMX__CLIENT__ */ - -#else /* EMXPM */ - -void emx_endPM(const char *reason); -int emx_options(char **ANGBAND_DIR_USER, - char **ANGBAND_DIR_SAVE, - char **ANGBAND_DIR_INFO, - char *arg_force_roguelike, - char *arg_force_original, - char *arg_fiddle, - char *arg_wizard, - char player_name[32]); - -void emx_init_window(void **instance, void *main_instance, int n); - -errr emx_curs(void *instance, int x, int y); -errr emx_wipe(void *instance, int x, int y, int n); -errr emx_text(void *instance, int x, int y, int n, unsigned char a, cptr s); -void emx_init(void *instance); -void emx_nuke(void *instance); -int emx_read_kbd(void *instance, int wait); -void emx_clear(void *instance); -void emx_hidecursor(void *instance); -void emx_showcursor(void *instance); - -/* -* termWindow* is sometimes cast to term* and vice versa, -* so "term t;" must be the first line -*/ - -typedef struct -{ - term t; - void *instance; /* Pointer to window */ -} -termWindow; - -/* -* Display a cursor, on top of a given attr/char -*/ -static errr Term_curs_emx(int x, int y) -{ - return emx_curs(((termWindow*)Term)->instance, x, y); -} - -/* -* Erase a grid of space (as if spaces were printed) -*/ -static errr Term_wipe_emx(int x, int y, int n) -{ - return emx_wipe(((termWindow*)Term)->instance, x, y, n); -} - -/* -* Draw some text, wiping behind it first -*/ -static errr Term_text_emx(int x, int y, int n, unsigned char a, cptr s) -{ - return emx_text(((termWindow*)Term)->instance, x, y, n, a, s); -} - -/* -* EMX initialization -*/ -static void Term_init_emx(term *t) -{ - return emx_init(((termWindow*)t)->instance); -} - -/* -* EMX shutdown -*/ -static void Term_nuke_emx(term *t) -{} - -/* -* Oh no, more prototypes! -*/ -static errr CheckEvents(int returnImmediately); - -/* -* Main initialization function -*/ -errr init_emx(void); - -/* -* The screens -*/ -static termWindow term_screen_aga[MAX_TERM_DATA]; - -/* -* Check for events -- called by "Term_scan_emx()" -*/ -static errr CheckEvents(int returnImmediately) -{ - /* Get key - Macro triggers are generated by emx_read_kbd() */ - int k = emx_read_kbd(((termWindow*)Term)->instance, returnImmediately ? 0 : 1); - - /* Nothing ready */ - if (k < 0) return (1); - - /* Enqueue the key */ - Term_keypress(k); - - /* Success */ - return (0); -} - -/* -* Do a special thing (beep, flush, etc) -*/ -static errr Term_xtra_emx(int n, int v) -{ - void *instance = ((termWindow*)Term)->instance; - - switch (n) - { - case TERM_XTRA_SHAPE: - if (v) - { - emx_showcursor(instance); - } - else - { - emx_hidecursor(instance); - } - return (0); - - case TERM_XTRA_NOISE: - DosBeep(440, 50); - return (0); - - case TERM_XTRA_FLUSH: - while (!CheckEvents(TRUE)); - return 0; - - case TERM_XTRA_EVENT: - return (CheckEvents(!v)); - - case TERM_XTRA_CLEAR: - emx_clear(instance); - return (0); - - case TERM_XTRA_DELAY: - if (v > 0) _sleep2(v); - return (0); - } - - return (1); -} - -void emx_init_term(termWindow *t, void *main_instance, term **angTerm, int n) -{ - term *te = (term*)t; - - /* Initialize window */ - emx_init_window(&t->instance, main_instance, n); - - *angTerm = te; - - /* Initialize the term -- big key buffer */ - term_init(te, 80, 24, 1024); - - /* Special hooks */ - te->init_hook = Term_init_emx; - te->nuke_hook = Term_nuke_emx; - - /* Add the hooks */ - te->text_hook = Term_text_emx; - te->wipe_hook = Term_wipe_emx; - te->curs_hook = Term_curs_emx; - te->xtra_hook = Term_xtra_emx; -} - -/* -* Prepare "term.c" to use "USE_EMX" built-in faked video library -*/ -errr init_emx(void) -{ - int i; - - /* Initialize the windows */ - emx_init_term(&term_screen_aga[0], NULL, &angband_term[0], 0); - - for (i = 1; i < MAX_TERM_DATA; ++i) - { - emx_init_term(&term_screen_aga[i], term_screen_aga[0].instance, &angband_term[i], i); - } - - /* Activate main window */ - Term_activate(angband_term[0]); - - /* Success */ - return (0); -} - -static void init_stuff(void) -{ - char path[1024]; - cptr tail; - - /* Get the environment variable */ - tail = getenv("ANGBAND_PATH"); - - /* Use the angband_path, or a default */ - strcpy(path, tail ? tail : DEFAULT_PATH); - - /* Hack -- Add a path separator (only if needed) */ - if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP); - - /* Initialize */ - init_file_paths(path); -} - -static void quit_hook(cptr s) -{ - int i; - - for (i = MAX_TERM_DATA - 1; i >= 0; --i) - { - /* Shut down the term windows */ - if (angband_term[i]) - { - term_nuke(angband_term[i]); - emx_nuke(((termWindow*)angband_term[i])->instance); - } - } - - /* Shut down window system - doesn't return */ - emx_endPM(s); -} - - -void angbandThread(void *arg) -{ - bool new_game = FALSE; - - int show_score = 0; - - char player_name_aga[32]; - - /* Save the "program name" */ - argv0 = (char*)arg; - - /* Use the "main-emx.c" support */ - init_emx(); - ANGBAND_SYS = "ibm"; - - /* Get the file paths */ - init_stuff(); - - if (!emx_options((char**)&ANGBAND_DIR_USER, - (char**)&ANGBAND_DIR_SAVE, - (char**)&ANGBAND_DIR_INFO, - &arg_force_roguelike, - &arg_force_original, - &arg_fiddle, - &arg_wizard, - player_name_aga)) quit(NULL); - - /* XXX XXX XXX (?) */ - strcpy(player_name, player_name_aga); - - /* Process the player name */ - process_player_name(TRUE); - - /* Tell "quit()" to call "Term_nuke()" */ - quit_aux = quit_hook; - - /* If requested, display scores and quit */ - if (show_score > 0) display_scores(0, show_score); - - /* Catch nasty signals */ - signals_init(); - - /* Initialize */ - init_angband(); - - /* Wait for response */ - pause_line(23); - - /* Play the game */ - play_game(new_game); - - /* Quit */ - quit(NULL); -} - -#endif /* EMXPM */ - -#endif /* USE_EMX */ - -/* - * Local Variables: - * comment-column: 45 - * End: - * - */ - diff --git a/src/main-gcu.c b/src/main-gcu.c index 365fe4d7..fa86da80 100644 --- a/src/main-gcu.c +++ b/src/main-gcu.c @@ -96,18 +96,6 @@ #endif /* - * Hack -- Amiga uses "fake curses" and cannot do any of this stuff - */ -#if defined(AMIGA) -# undef USE_TPOSIX -# undef USE_TERMIO -# undef USE_TCHARS -#endif - - - - -/* * POSIX stuff */ #ifdef USE_TPOSIX diff --git a/src/main-ibm.c b/src/main-ibm.c deleted file mode 100644 index 6201649c..00000000 --- a/src/main-ibm.c +++ /dev/null @@ -1,1594 +0,0 @@ -/* File: main-ibm.c */ - -/* - * Copyright (c) 1997 Ben Harrison, and others - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. - */ - -/* Purpose: Visual Display Support for "term.c", for the IBM */ - -/* - * Original code by "Billy Tanksley (wtanksle@ucsd.edu)" - * Use "Makefile.ibm" to compile Angband using this file. - * - * Support for DJGPP v2 by "Scott Egashira (egashira@u.washington.edu)" - * - * Extensive modifications by "Ben Harrison (benh@phial.com)", - * including "collation" of the Watcom C/C++ and DOS-286 patches. - * - * Watcom C/C++ changes by "David Boeren (akemi@netcom.com)" - * Use "Makefile.wat" to compile this file with Watcom C/C++, and - * be sure to define "USE_IBM" and "USE_WAT". - * - * DOS-286 (conio.h) changes by (Roland Jay Roberts (jay@map.com) - * Use "Makefile.286" (not ready) to compile this file for DOS-286, - * and be sure to define "USE_IBM", "USE_WAT", and "USE_286". Also, - * depending on your compiler, you may need to define "USE_CONIO". - * - * True color palette support by "Mike Marcelais (michmarc@microsoft.com)", - * with interface to the "color_table" array by Ben Harrison. - * - * Both "shift" keys are treated as "identical", and all the modifier keys - * (control, shift, alt) are ignored when used with "normal" keys, unless - * they modify the underlying "ascii" value of the key. You must use the - * new "user pref files" to be able to interact with the keypad and such. - * - * The "lib/user/pref-ibm.prf" file contains macro definitions and possible - * alternative color set definitions. The "lib/user/font-ibm.prf" contains - * attr/char mappings for walls and floors and such. - * - * Note the "Term_user_ibm()" function hook, which could allow the user - * to interact with the "main-ibm.c" visual system. Currently this hook - * is unused, but, for example, it could allow the user to toggle "sound" - * or "graphics" modes, or to select the number of screen rows, with the - * extra screen rows being used for the mirror window. - */ - - -#include "angband.h" - - -#ifdef USE_IBM - - -/* - * Use a "virtual" screen to "buffer" screen writes. - */ -#define USE_VIRTUAL - -#ifdef USE_DOSSOCK -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <netdb.h> -#endif - -#include <bios.h> -#include <dos.h> -#include <dir.h> - -#ifdef USE_WAT - -# include <conio.h> - -# ifdef USE_CONIO -# else /* USE_CONIO */ - -# include <graph.h> - -# define bioskey(C) _bios_keybrd(C) - -# endif /* USE_CONIO */ - -# ifndef USE_286 -# define int86(a, b, c) int386(a, b, c) -# endif - -# define inportb(x) inp(x) -# define outportb(x, y) outp(x, y) - -#else /* USE_WAT */ - -# if __DJGPP__ > 1 - -# include <pc.h> -# include <osfcn.h> - -# else /* __DJGPP__ > 1 */ -# ifdef __DJGPP__ -# error "Upgrade to version 2.0 of DJGPP" -# endif /* __DJGPP__ */ -# endif /* __DJGPP__ > 1 */ - -#endif /* USE_WAT */ - - -#ifdef USE_CONIO - -# include <conio.h> - -/* - * Hack -- write directly to video card - */ -extern int directvideo = 1; - -/* - * Hack -- no virtual screen - */ -# undef USE_VIRTUAL - -#endif /* USE_CONIO */ - - -/* - * Keypress input modifier flags (hard-coded by DOS) - */ -#define K_RSHIFT 0 /* Right shift key down */ -#define K_LSHIFT 1 /* Left shift key down */ -#define K_CTRL 2 /* Ctrl key down */ -#define K_ALT 3 /* Alt key down */ -#define K_SCROLL 4 /* Scroll lock on */ -#define K_NUM 5 /* Num lock on */ -#define K_CAPS 6 /* Caps lock on */ -#define K_INSERT 7 /* Insert on */ - - -/* - * Foreground color bits (hard-coded by DOS) - */ -#define VID_BLACK 0x00 -#define VID_BLUE 0x01 -#define VID_GREEN 0x02 -#define VID_CYAN 0x03 -#define VID_RED 0x04 -#define VID_MAGENTA 0x05 -#define VID_YELLOW 0x06 -#define VID_WHITE 0x07 - -/* - * Bright text (hard-coded by DOS) - */ -#define VID_BRIGHT 0x08 - -/* - * Background color bits (hard-coded by DOS) - */ -#define VUD_BLACK 0x00 -#define VUD_BLUE 0x10 -#define VUD_GREEN 0x20 -#define VUD_CYAN 0x30 -#define VUD_RED 0x40 -#define VUD_MAGENTA 0x50 -#define VUD_YELLOW 0x60 -#define VUD_WHITE 0x70 - -/* - * Blinking text (hard-coded by DOS) - */ -#define VUD_BRIGHT 0x80 - - -/* - * Screen Size - */ -static int rows = 25; -static int cols = 80; - - -/* - * Physical Screen - */ -#ifdef USE_286 -# define PhysicalScreen ((byte *)MK_FP(0xB800, 0x0000)) -#else -# define PhysicalScreen ((byte *)(0xB800 << 4)) -#endif - - -#ifdef USE_VIRTUAL - -/* - * Virtual Screen Contents - */ -static byte *VirtualScreen; - -#else - -/* -* Physical screen access -*/ -#define VirtualScreen PhysicalScreen - -#endif - - -/* - * Hack -- the cursor "visibility" - */ -static int saved_cur_v; -static int saved_cur_high; -static int saved_cur_low; - - -#ifdef USE_CONIO -#else /* USE_CONIO */ - -/* -* This array is used for "wiping" the screen -*/ -static byte wiper[160]; - -#endif /* USE_CONIO */ - - -/* - * The main screen (currently the only screen) - */ -static term term_screen_body; - - -/* - * Choose between the "complex" and "simple" color methods - */ -static byte use_color_complex = FALSE; - - -/* - * The "complex" color set - */ -static long ibm_color_complex[16]; - - -/* - * The "simple" color set - * - * This table is used by the "color" code to instantiate the "approximate" - * Angband colors using the only colors available on crappy monitors. - * - * The entries below are taken from the "color bits" defined above. - * - * Note that values from 16 to 255 are extremely ugly. - * - * The values below came from various sources, if you do not like them, - * get a better monitor, or edit "pref-ibm.prf" to use different codes. - * - * Note that many of the choices below suck, but so do crappy monitors. - */ -static byte ibm_color_simple[16] = -{ - VID_BLACK, /* Dark */ - VID_WHITE, /* White */ - VID_CYAN, /* Slate XXX */ - VID_RED | VID_BRIGHT, /* Orange XXX */ - VID_RED, /* Red */ - VID_GREEN, /* Green */ - VID_BLUE, /* Blue */ - VID_YELLOW, /* Umber XXX */ - VID_BLACK | VID_BRIGHT, /* Light Dark */ - VID_CYAN | VID_BRIGHT, /* Light Slate XXX */ - VID_MAGENTA, /* Violet */ - VID_YELLOW | VID_BRIGHT, /* Yellow */ - VID_MAGENTA | VID_BRIGHT, /* Light Red XXX */ - VID_GREEN | VID_BRIGHT, /* Light Green */ - VID_BLUE | VID_BRIGHT, /* Light Blue */ - VID_YELLOW /* Light Umber XXX */ -}; - - - -/* - * Activate the "ibm_color_complex" palette information. - * - * Code by Mike Marcelais, with help from "The programmer's guide - * to the EGA and VGA video cards" [Farraro]. - * - * On VGA cards, colors go through a double-indirection when looking - * up the `real' color when in 16 color mode. The color value in the - * attribute is looked up in the EGA color registers. Then that value - * is looked up in the VGA color registers. Then the color is displayed. - * This is done for compatability. However, the EGA registers are - * initialized by default to 0..5, 14, 7, 38..3F and not 0..F which means - * that unless these are reset, the VGA setpalette function will not - * update the correct palette register! - * - * DJGPP's GrSetColor() does _not_ set the EGA palette list, only the - * VGA color list. - * - * Note that the "traditional" method, using "int86(0x10)", is very slow - * when called in protected mode, so we use a faster method using video - * ports instead. - * - * On Watcom machines, we could simply use the special "_remapallpalette()" - * function, which not only sets both palette lists (see below) but also - * checks for legality of the monitor mode, but, if we are doing bitmapped - * graphics, that function forgets to set the EGA registers for some reason. - */ -static void activate_color_complex(void) -{ - int i; - printf("%c%c%c%c", 8, 8, 8, 8); - -#if 1 - - /* Edit the EGA palette */ - inportb(0x3da); - - /* Edit the colors */ - for (i = 0; i < 16; i++) - { - /* Set color "i" */ - outportb(0x3c0, i); - - /* To value "i" */ - outportb(0x3c0, i); - } - - /* Use that EGA palette */ - outportb(0x3c0, 0x20); - - /* Edit VGA palette, starting at color zero */ - outportb(0x3c8, 0); - - /* Send the colors */ - for (i = 0; i < 16; i++) - { - /* Send the red, green, blue components */ - outportb(0x3c9, ((ibm_color_complex[i]) & 0xFF)); - outportb(0x3c9, ((ibm_color_complex[i] >> 8) & 0xFF)); - outportb(0x3c9, ((ibm_color_complex[i] >> 16) & 0xFF)); - } - -#else /* 1 */ - - /* Set the colors */ - for (i = 0; i < 16; i++) - { - union REGS r; - - /* Set EGA color */ - r.h.ah = 0x10; - r.h.al = 0x00; - - /* Set color "i" */ - r.h.bl = i; - - /* To value "i" */ - r.h.bh = i; - - /* Do it */ - int86(0x10, &r, &r); - - /* Set VGA color */ - r.h.ah = 0x10; - r.h.al = 0x10; - - /* Set color "i" */ - r.h.bh = 0x00; - r.h.bl = i; - - /* Use this "green" value */ - r.h.ch = ((ibm_color_complex[i] >> 8) & 0xFF); - - /* Use this "blue" value */ - r.h.cl = ((ibm_color_complex[i] >> 16) & 0xFF); - - /* Use this "red" value */ - r.h.dh = ((ibm_color_complex[i]) & 0xFF); - - /* Do it */ - int86(0x10, &r, &r); - } - -#endif /* 1 */ - -} - - -#ifdef SUPPORT_GAMMA - -/* - * When set to TRUE, indicates that we can use gamma_table - */ -static bool gamma_table_ready = FALSE; - - -/* - * Build gamma correction table if requested and applicable - */ -static void setup_gamma_table(void) -{ - static u16b old_gamma_val = 0; - - /* (Re)build the table only when gamma value changes */ - if (gamma_val == old_gamma_val) return; - - /* Temporarily inactivate the table */ - gamma_table_ready = FALSE; - - /* Validate gamma_val */ - if ((gamma_val <= 0) || (gamma_val >= 256)) - { - /* Reset */ - old_gamma_val = gamma_val = 0; - - /* Leave it inactive */ - return; - } - - /* (Re)build the table */ - build_gamma_table(gamma_val); - - /* Remember gamma_val */ - old_gamma_val = gamma_val; - - /* Activate the table */ - gamma_table_ready = TRUE; -} - -#endif /* SUPPORT_GAMMA */ - - -/* - * Note the use of "(x >> 2)" to convert an 8 bit value to a 6 bit value - * without losing much precision. - */ -static int Term_xtra_ibm_react(void) -{ - int i; - - /* Complex method */ - if (use_color_complex) - { - long rv, gv, bv, code; - - bool change = FALSE; - -#ifdef SUPPORT_GAMMA - - /* Build gamma_table */ - setup_gamma_table(); - -#endif /* SUPPORT_GAMMA */ - - /* Save the default colors */ - for (i = 0; i < 16; i++) - { - /* Extract desired values */ - rv = angband_color_table[i][1]; - gv = angband_color_table[i][2]; - bv = angband_color_table[i][3]; - -#ifdef SUPPORT_GAMMA - - /* Hack - Gamma correction */ - if (gamma_table_ready) - { - rv = gamma_table[rv]; - gv = gamma_table[gv]; - bv = gamma_table[bv]; - } - -#endif /* SUPPORT_GAMMA */ - - /* 8 bit to 6 bit conversion */ - rv = rv >> 2; - gv = gv >> 2; - bv = bv >> 2; - - /* Extract a full color code */ - code = ((rv) | (gv << 8) | (bv << 16)); - - /* Activate changes */ - if (ibm_color_complex[i] != code) - { - /* Note the change */ - change = TRUE; - - /* Apply the desired color */ - ibm_color_complex[i] = code; - } - } - - /* Activate the palette if needed */ - if (change) activate_color_complex(); - } - - /* Simple method */ - else - { - /* Save the default colors */ - for (i = 0; i < 16; i++) - { - /* Simply accept the desired colors */ - ibm_color_simple[i] = angband_color_table[i][0]; - } - } - - /* Success */ - return (0); -} - - - -/* - * Hack -- set the cursor "visibility" - */ -static void curs_set(int v) -{ - /* If needed */ - if (saved_cur_v != v) - { - union REGS r; - - /* Set cursor */ - r.h.ah = 1; - - /* Visible */ - if (v) - { - /* Use the saved values */ - r.h.ch = saved_cur_high; - r.h.cl = saved_cur_low; - } - - /* Invisible */ - else - { - /* Make it invisible */ - r.h.ch = 0x20; - r.h.cl = 0x00; - } - - /* Make the call */ - int86(0x10, &r, &r); - - /* Save the cursor state */ - saved_cur_v = v; - } -} - - - -/* - * Process an event (check for a keypress) - * - * The keypress processing code is often the most system dependant part - * of Angband, since sometimes even the choice of compiler is important. - * - * For the IBM, we divide all keypresses into two categories, first, the - * "normal" keys, including all keys required to play Angband, and second, - * the "special" keys, such as keypad keys, function keys, and various keys - * used in combination with various modifier keys. - * - * To simplify this file, we use Angband's "macro processing" ability, in - * combination with a specialized "pref-ibm.prf" file, to handle most of the - * "special" keys, instead of attempting to fully analyze them here. This - * file only has to determine when a "special" key has been pressed, and - * translate it into a simple string which signals the use of a "special" - * key, the set of modifiers used, if any, and the hardware scan code of - * the actual key which was pressed. To simplify life for the user, we - * treat both "shift" keys as identical modifiers. - * - * The final encoding is "^_MMMxSS\r", where "MMM" encodes the modifiers - * ("C" for control, "S" for shift, "A" for alt, or any ordered combination), - * and "SS" encodes the keypress (as the two "digit" hexadecimal encoding of - * the scan code of the key that was pressed), and the "^_" and "x" and "\r" - * delimit the encoding for recognition by the macro processing code. - * - * Some important facts about scan codes follow. All "normal" keys use - * scan codes from 1-58. The "function" keys use 59-68 (and 133-134). - * The "keypad" keys use 69-83. Escape uses 1. Enter uses 28. Control - * uses 29. Left Shift uses 42. Right Shift uses 54. PrtScrn uses 55. - * Alt uses 56. Space uses 57. CapsLock uses 58. NumLock uses 69. - * ScrollLock uses 70. The "keypad" keys which use scan codes 71-83 - * are ordered KP7,KP8,KP9,KP-,KP4,KP5,KP6,KP+,KP1,KP2,KP3,INS,DEL. - * - * Using "bioskey(0x10)" instead of "bioskey(0)" apparently provides more - * information, including better access to the keypad keys in combination - * with various modifiers, but only works on "PC's after 6/1/86", and there - * is no way to determine if the function is provided on a machine. I have - * been told that without it you cannot detect, for example, control-left. - * The basic scan code + ascii value pairs returned by the keypad follow, - * with values in parentheses only available to "bioskey(0x10)". - * - * / * - + 1 2 3 4 - * Norm: 352f 372a 4a2d 4e2b 4f00 5000 5100 4b00 - * Shft: 352f 372a 4a2d 4e2b 4f31 5032 5133 4b34 - * Ctrl: (9500) (9600) (8e00) (9000) 7500 (9100) 7600 7300 - * - * 5 6 7 8 9 0 . Enter - * Norm: (4c00) 4d00 4700 4800 4900 5200 5300 (e00d) - * Shft: 4c35 4d36 4737 4838 4939 5230 532e (e00d) - * Ctrl: (8f00) 7400 7700 (8d00) 8400 (9200) (9300) (e00a) - * - * See "pref-ibm.prf" for the "standard" macros for various keys. - * - * Certain "bizarre" keypad keys (such as "enter") return a "scan code" - * of "0xE0", and a "usable" ascii value. These keys should be treated - * like the normal keys, see below. XXX XXX XXX Note that these "special" - * keys could be prefixed with an optional "ctrl-^" which would allow them - * to be used in macros without hurting their use in normal situations. - */ -static errr Term_xtra_ibm_event(int v) -{ - int i, k, s; - - bool mc = FALSE; - bool ms = FALSE; - bool ma = FALSE; - - - /* Hack -- Check for a keypress */ - if (!v && !bioskey(1)) return (1); - - /* Wait for a keypress */ - k = bioskey(0x10); - - /* Access the "modifiers" */ - i = bioskey(2); - - /* Extract the "scan code" */ - s = ((k >> 8) & 0xFF); - - /* Extract the "ascii value" */ - k = (k & 0xFF); - - /* Process "normal" keys */ - if ((s <= 58) || (s == 0xE0)) - { - /* Enqueue it */ - if (k) Term_keypress(k); - - /* Success */ - return (0); - } - - /* Extract the modifier flags */ - if (i & (1 << K_CTRL)) mc = TRUE; - if (i & (1 << K_LSHIFT)) ms = TRUE; - if (i & (1 << K_RSHIFT)) ms = TRUE; - if (i & (1 << K_ALT)) ma = TRUE; - - - /* Begin a "macro trigger" */ - Term_keypress(31); - - /* Hack -- Send the modifiers */ - if (mc) Term_keypress('C'); - if (ms) Term_keypress('S'); - if (ma) Term_keypress('A'); - - /* Introduce the hexidecimal scan code */ - Term_keypress('x'); - - /* Encode the hexidecimal scan code */ - Term_keypress(hexsym[s / 16]); - Term_keypress(hexsym[s % 16]); - - /* End the "macro trigger" */ - Term_keypress(13); - - /* Success */ - return (0); -} - - -/* - * Handle a "special request" - * - * The given parameters are "valid". - */ -static errr Term_xtra_ibm(int n, int v) -{ - int i; - - /* Analyze the request */ - switch (n) - { - /* Make a "bell" noise */ - case TERM_XTRA_NOISE: - { - /* Make a bell noise */ - (void)write(1, "\007", 1); - - /* Success */ - return (0); - } - - /* Set the cursor shape */ - case TERM_XTRA_SHAPE: - { - /* Set cursor shape */ - curs_set(v); - - /* Success */ - return (0); - } - - /* Flush one line of output */ - case TERM_XTRA_FROSH: - { - -#ifdef USE_VIRTUAL - -# ifdef USE_WAT - - /* Copy the virtual screen to the physical screen */ - memcpy(PhysicalScreen + (v*160), VirtualScreen + (v*160), 160); - -# else /* USE_WAT */ - - /* Apply the virtual screen to the physical screen */ - ScreenUpdateLine(VirtualScreen + ((v*cols) << 1), v); - -# endif /* USE_WAT */ - -#endif /* USE_VIRTUAL */ - - /* Success */ - return (0); - } - - /* Clear the screen */ - case TERM_XTRA_CLEAR: - { - -#ifdef USE_CONIO - - /* Clear the screen */ - clrscr(); - -#else /* USE_CONIO */ - - /* Clear each line (virtual or physical) */ - for (i = 0; i < rows; i++) - { - /* Clear the line */ - memcpy((VirtualScreen + ((i*cols) << 1)), wiper, (cols << 1)); - } - -# ifdef USE_VIRTUAL - -# ifdef USE_WAT - - /* Copy the virtual screen to the physical screen */ - memcpy(PhysicalScreen, VirtualScreen, 25*80*2); - -# else /* USE_WAT */ - - /* Erase the physical screen */ - ScreenClear(); - -# endif /* USE_WAT */ - -# endif /* USE_VIRTUAL */ - -#endif /* USE_CONIO */ - - /* Success */ - return (0); - } - - /* Process events */ - case TERM_XTRA_EVENT: - { - irc_poll(); - - /* Process one event */ - return (Term_xtra_ibm_event(v)); - } - - /* Flush events */ - case TERM_XTRA_FLUSH: - { - /* Strip events */ - while (!Term_xtra_ibm_event(FALSE)) /* loop */; - - /* Success */ - return (0); - } - - /* React to global changes */ - case TERM_XTRA_REACT: - { - /* React to "color_table" changes */ - return (Term_xtra_ibm_react()); - } - - /* Delay for some milliseconds */ - case TERM_XTRA_DELAY: - { - /* Delay if needed */ - if (v > 0) delay(v); - - /* Success */ - return (0); - } - - /* - * Scans for subdirectories in a directory "scansubdir_dir" - * and place teh result in "scansubdir_result/scansubdir_max" - */ - case TERM_XTRA_SCANSUBDIR: - { - struct ffblk f; - int done; - - done = findfirst(format("%s\\*", scansubdir_dir), &f, FA_DIREC); - - scansubdir_max = 0; - while ((!done) && (scansubdir_max < 255)) - { - if ((f.ff_attrib & FA_DIREC) && (strcmp(f.ff_name, ".")) && (strcmp(f.ff_name, ".."))) - { - string_free(scansubdir_result[scansubdir_max]); - scansubdir_result[scansubdir_max] = string_make(f.ff_name); - scansubdir_max++; - } - - done = findnext(&f); - } - - return 0; - } - } - - /* Unknown request */ - return (1); -} - - - -/* - * Move the cursor - * - * The given parameters are "valid". - */ -static errr Term_curs_ibm(int x, int y) -{ - -#ifdef USE_WAT - -# ifdef USE_CONIO - - /* Place the cursor */ - gotoxy(x + 1, y + 1); - -# else /* USE_CONIO */ - - union REGS r; - - r.h.ah = 2; - r.h.bh = 0; - r.h.dl = x; - r.h.dh = y; - - /* Place the cursor */ - int86(0x10, &r, &r); - -# endif /* USE_CONIO */ - -#else /* USE_WAT */ - - /* Move the cursor */ - ScreenSetCursor(y, x); - -#endif /* USE_WAT */ - - /* Success */ - return (0); -} - - -/* - * Erase a block of the screen - * - * The given parameters are "valid". - */ -static errr Term_wipe_ibm(int x, int y, int n) -{ - -#ifdef USE_CONIO - - /* Wipe the region */ - window(x + 1, y + 1, x + n, y + 1); - clrscr(); - window(1, 1, cols, rows); - -#else /* USE_CONIO */ - - /* Wipe part of the virtual (or physical) screen */ - memcpy(VirtualScreen + ((cols*y + x) << 1), wiper, n << 1); - -#endif /* USE_CONIO */ - - /* Success */ - return (0); -} - - -/* - * Place some text on the screen using an attribute - * - * The given parameters are "valid". Be careful with "a". - * - * The string "cp" has length "n" and is NOT null-terminated. - */ -static errr Term_text_ibm(int x, int y, int n, byte a, const char *cp) -{ - register int i; - register byte attr; - register byte *dest; - - - /* Handle "complex" color */ - if (use_color_complex) - { - /* Extract a color index */ - attr = (a & 0x0F); - } - - /* Handle "simple" color */ - else - { - /* Extract a color value */ - attr = ibm_color_simple[a & 0x0F]; - } - -#ifdef USE_CONIO - - /* Place the cursor */ - gotoxy(x + 1, y + 1); - - /* Set the attribute */ - textattr(attr); - - /* Dump the text */ - for (i = 0; i < n; i++) putch(cp[i]); - -#else /* USE_CONIO */ - - /* Access the virtual (or physical) screen */ - dest = VirtualScreen + (((cols * y) + x) << 1); - - /* Save the data */ - for (i = 0; i < n; i++) - { - /* Apply */ - *dest++ = cp[i]; - *dest++ = attr; - } - -#endif /* USE_CONIO */ - - /* Success */ - return (0); -} - - -/* - * Place some attr/char pairs on the screen - * - * The given parameters are "valid". - */ -#ifdef USE_TRANSPARENCY -static errr Term_pict_ibm(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp) -#else /* USE_TRANSPARENCY */ -static errr Term_pict_ibm(int x, int y, int n, const byte *ap, const char *cp) -#endif /* USE_TRANSPARENCY */ -{ - register int i; - register byte attr; - register byte *dest; - - -#ifdef USE_CONIO - - /* Place the cursor */ - gotoxy(x + 1, y + 1); - - /* Dump the text */ - for (i = 0; i < n; i++) - { - /* Handle "complex" color */ - if (use_color_complex) - { - /* Extract a color index */ - attr = (ap[i] & 0x0F); - } - - /* Handle "simple" color */ - else - { - /* Extract a color value */ - attr = ibm_color_simple[ap[i] & 0x0F]; - } - - /* Set the attribute */ - textattr(attr); - - /* Dump the char */ - putch(cp[i]); - } - -#else /* USE_CONIO */ - - /* Access the virtual (or physical) screen */ - dest = VirtualScreen + (((cols * y) + x) << 1); - - /* Save the data */ - for (i = 0; i < n; i++) - { - /* Handle "complex" color */ - if (use_color_complex) - { - /* Extract a color index */ - attr = (ap[i] & 0x0F); - } - - /* Handle "simple" color */ - else - { - /* Extract a color value */ - attr = ibm_color_simple[ap[i] & 0x0F]; - } - - /* Apply */ - *dest++ = cp[i]; - *dest++ = attr; - } - -#endif /* USE_CONIO */ - - /* Success */ - return (0); -} - - -/* - * Init a Term - */ -static void Term_init_ibm(term *t) -{ - /* XXX Nothing */ -} - - -/* - * Nuke a Term - */ -static void Term_nuke_ibm(term *t) -{ - -#ifdef USE_WAT - - /* Nothing */ - -#else /* USE_WAT */ - - union REGS r; - -#endif /* USE_WAT */ - - /* Move the cursor to the bottom of the screen */ - Term_curs_ibm(0, rows - 1); - -#ifdef USE_WAT - - /* Restore the original video mode */ - _setvideomode(_DEFAULTMODE); - -#else /* USE_WAT */ - - /* Restore the original video mode */ - r.h.ah = 0x00; - r.h.al = 0x03; - int86(0x10, &r, &r); - -#endif /* USE_WAT */ - - /* Make the cursor visible */ - curs_set(1); -} - - - -#ifdef USE_GRAPHICS - -#ifdef USE_286 - -/* - * In 286 mode we don't need to worry about translating from a 32bit - * pointer to a 16 bit pointer so we just call the interrupt function - * - * Note the use of "intr()" instead of "int86()" so we can pass - * segment registers. - */ -void enable_graphic_font(void *font) -{ - union REGPACK regs = - {0}; - - regs.h.ah = 0x11; /* Text font function */ - regs.h.bh = 0x10; /* Size of a character -- 16 bytes */ - regs.h.cl = 0xFF; /* Last character in font */ - regs.x.es = FP_SEG(font); /* Pointer to font */ - regs.x.bp = FP_OFF(font); - intr(0x10, ®s); -} - -#else /* USE_286 */ - -#ifdef USE_WAT - -/* -* This structure is used by the DMPI function to hold registers when -* doing a real mode interrupt call. (Stolen from the DJGPP <dpmi.h> - * header file). -*/ - -typedef union -{ - struct - { - unsigned long edi; - unsigned long esi; - unsigned long ebp; - unsigned long res; - unsigned long ebx; - unsigned long edx; - unsigned long ecx; - unsigned long eax; - } - d; - struct - { - unsigned short di, di_hi; - unsigned short si, si_hi; - unsigned short bp, bp_hi; - unsigned short res, res_hi; - unsigned short bx, bx_hi; - unsigned short dx, dx_hi; - unsigned short cx, cx_hi; - unsigned short ax, ax_hi; - unsigned short flags; - unsigned short es; - unsigned short ds; - unsigned short fs; - unsigned short gs; - unsigned short ip; - unsigned short cs; - unsigned short sp; - unsigned short ss; - } - x; - struct - { - unsigned char edi[4]; - unsigned char esi[4]; - unsigned char ebp[4]; - unsigned char res[4]; - unsigned char bl, bh, ebx_b2, ebx_b3; - unsigned char dl, dh, edx_b2, edx_b3; - unsigned char cl, ch, ecx_b2, ecx_b3; - unsigned char al, ah, eax_b2, eax_b3; - } - h; -} __dpmi_regs; - -unsigned __dpmi_allocate_dos_memory(int size, unsigned *selector) -{ - union REGPACK regs = - {0}; - - regs.w.ax = 0x100; /* DPMI function -- allocate low memory */ - regs.w.bx = size; /* Number of Paragraphs to allocate */ - intr(0x31, ®s); /* DPMI interface */ - - *selector = regs.w.dx; - return (regs.w.ax); -} - -void __dpmi_free_dos_memory(unsigned sel) -{ - union REGPACK regs = - {0}; - - regs.w.ax = 0x101; /* DPMI function -- free low memory */ - regs.x.edx = sel; /* PM selector for memory block */ - intr(0x31, ®s); /* DPMI interface */ -} - -void __dpmi_int(int intno, __dpmi_regs *dblock) -{ - union REGPACK regs = - {0}; - - regs.w.ax = 0x300; /* DPMI function -- real mode interrupt */ - regs.h.bl = intno; /* interrupt 0x10 */ - regs.x.edi = FP_OFF(dblock); /* Pointer to dblock (offset and segment) */ - regs.x.es = FP_SEG(dblock); - intr(0x31, ®s); /* DPMI interface */ -} - -unsigned short __dpmi_sel = 0x0000; -#define _farsetsel(x) __dpmi_sel=(x) -extern void _farnspokeb(unsigned long offset, unsigned char value); -#pragma aux _farnspokeb = \ -"push fs" \ -"mov fs,__dpmi_sel" \ -"mov fs:[eax],bl" \ -"pop fs" \ -parm [eax] [bl]; - -#else /* USE_WAT */ - -#include <dpmi.h> -#include <go32.h> -#include <sys/farptr.h> - -#endif /* USE_WAT */ - - -/* -* Since you cannot send 32bit pointers to a 16bit interrupt handler -* and the video BIOS wants a (16bit) pointer to the font, we have -* to allocate a block of dos memory, copy the font into it, then -* translate a 32bit pointer into a 16bit pointer to that block. -* -* DPMI - Dos Protected Mode Interface provides functions that let -* us do that. -*/ -void enable_graphic_font(const char *font) -{ - __dpmi_regs dblock = {{0}}; - - unsigned seg, sel, i; - - /* - * Allocate a block of memory 4096 bytes big in `low memory' so a real - * mode interrupt can access it. Real mode pointer is returned as seg:0 - * Protected mode pointer is sel:0. - */ - seg = __dpmi_allocate_dos_memory(256, &sel); - - /* Copy the information into low memory buffer, by copying one byte at - * a time. According to the info in <sys/farptr.h>, the functions - * _farsetsel() and _farnspokeb() will optimise away completely - */ - _farsetsel(sel); /* Set the selector to write to */ - for (i = 0; i < 4096; i++) - { - _farnspokeb(i, *font++); /* Copy 1 byte into low (far) memory */ - } - - /* - * Now we use DPMI as a jumper to call the real mode interrupt. This - * is needed because loading `es' while in protected mode with a real - * mode pointer will cause an Protection Fault and calling the interrupt - * directly using the protected mode pointer will result in garbage - * being received by the interrupt routine - */ - dblock.d.eax = 0x1100; /* BIOS function -- set font */ - dblock.d.ebx = 0x1000; /* bh = size of a letter; bl = 0 (reserved) */ - dblock.d.ecx = 0x00FF; /* Last character in font */ - dblock.x.es = seg; /* Pointer to font segment */ - dblock.d.ebp = 0x0000; /* Pointer to font offset */ - - __dpmi_int(0x10, &dblock); - - /* We're done with the low memory, free it */ - __dpmi_free_dos_memory(sel); -} - -#endif /* USE_286 */ - -#endif /* ALLOW_GRAPH */ - -#ifdef USE_DOSSOCK -void *zsock_connect(char *hos, short port) -{ - struct hostent *host; - struct sockaddr_in sin; - int *client; - - MAKE(client, int); - *client = socket(AF_INET, SOCK_STREAM, 0); - - host = gethostbyname(hos); - - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr; - sin.sin_port = htons(port); - - if (connect(*client, (struct sockaddr*)&sin, sizeof sin) == -1) - { - /* could not connect to server */ - return NULL; - } - - return client; -} - -bool zsock_can_read(void *client) -{ - struct timeval t; - fd_set rd; - int *c = client; - - FD_ZERO(&rd); - FD_SET(*c, &rd); - t.tv_sec = 0; - t.tv_usec = 0; - select(*c + 1, &rd, NULL, NULL, &t); - if (FD_ISSET(*c, &rd)) return TRUE; - else return (FALSE); -} - -bool zsock_wait(void *client) -{ - struct timeval t; - fd_set rd; - int *c = client; - - t.tv_sec = 30; - t.tv_usec = 0; - - FD_ZERO(&rd); - FD_SET(*c, &rd); - select(*c + 1, &rd, NULL, NULL, &t); - if (FD_ISSET(*c, &rd)) return TRUE; - else return (FALSE); -} - -void zsock_disconnect(void *client) -{ - close(*(int*)client); - FREE(client, int); -} - -void zsock_send(void *sock, char *str) -{ - send(*(int*)sock, str, strlen(str), 0); -} - -void zsock_recv(void *sock, char *str, int len) -{ - char c; - int l = 0; - - while ((l < len) && zsock_can_read(sock)) - { - if (!recv(*(int*)sock, &c, 1, 0)) - { - irc_disconnect(); - break; - } - if (c == '\r') continue; - if (c == '\n') break; - str[l++] = c; - } - str[l] = '\0'; -} -#endif - - -/* - * Initialize the IBM "visual module" - * - * Hack -- we assume that "blank space" should be "white space" - * (and not "black space" which might make more sense). - * - * Note the use of "((x << 2) | (x >> 4))" to "expand" a 6 bit value - * into an 8 bit value, without losing much precision, by using the 2 - * most significant bits as the least significant bits in the new value. - */ -errr init_ibm(void) -{ - int i; - int mode; - - term *t = &term_screen_body; - - union REGS r; - - /* Check for "Windows" */ - if (getenv("windir")) - { - r.h.ah = 0x16; /* Windows API Call -- Set device focus */ - r.h.al = 0x8B; /* Causes Dos boxes to become fullscreen */ - r.h.bh = r.h.bl = 0x00; /* 0x0000 = current Dos box */ - int86(0x2F, &r, &r); /* Call the Windows API */ - } - - /* Initialize "color_table" */ - for (i = 0; i < 16; i++) - { - long rv, gv, bv; - - /* Extract desired values */ - rv = angband_color_table[i][1] >> 2; - gv = angband_color_table[i][2] >> 2; - bv = angband_color_table[i][3] >> 2; - - /* Extract the "complex" codes */ - ibm_color_complex[i] = ((rv) | (gv << 8) | (bv << 16)); - - /* Save the "simple" codes */ - angband_color_table[i][0] = ibm_color_simple[i]; - } - -#ifdef USE_WAT - - /* Set the video mode */ - if (_setvideomode(_VRES16COLOR)) - { - mode = 0x13; - } - - /* Wimpy monitor */ - else - { - mode = 0x03; - } - - /* Force 25 line mode */ - _setvideomode(_TEXTC80); - _settextrows(25); - -#else /* USE_WAT */ - - /* Set video mode */ - r.h.ah = 0x00; - r.h.al = 0x13; /* VGA only mode */ - int86(0x10, &r, &r); - - /* Get video mode */ - r.h.ah = 0x0F; - int86(0x10, &r, &r); - mode = r.h.al; - - /* Set video mode */ - r.h.ah = 0x00; - r.h.al = 0x03; /* Color text mode */ - int86(0x10, &r, &r); - -#endif /* USE_WAT */ - - /* Check video mode */ - if (mode == 0x13) - { - /* Remember the mode */ - use_color_complex = TRUE; - - /* Instantiate the color set */ - activate_color_complex(); - } - -#ifdef USE_GRAPHICS - - /* Try to activate bitmap graphics */ - if (arg_graphics && use_color_complex) - { - FILE *f; - - char buf[4096]; - - /* Build the filename */ - path_build(buf, 1024, ANGBAND_DIR_XTRA, "angband.fnt"); - - /* Open the file */ - f = fopen(buf, "rb"); - - /* Okay */ - if (f) - { - /* Load the bitmap data */ - if (fread(buf, 1, 4096, f) != 4096) - { - quit("Corrupt 'angband.fnt' file"); - } - - /* Close the file */ - fclose(f); - - /* Enable graphics */ - enable_graphic_font(buf); - - /* Enable colors (again) */ - activate_color_complex(); - - /* Use graphics */ - use_graphics = TRUE; - } - } - -#endif - -#ifdef USE_CONIO -#else /* USE_CONIO */ - - /* Build a "wiper line" */ - for (i = 0; i < 80; i++) - { - /* Space */ - wiper[2*i] = ' '; - - /* Black */ - wiper[2*i + 1] = TERM_WHITE; - } - -#endif /* USE_CONIO */ - - -#ifdef USE_VIRTUAL - - /* Make the virtual screen */ - C_MAKE(VirtualScreen, rows * cols * 2, byte); - -#endif /* USE_VIRTUAL */ - - - /* Erase the screen */ - Term_xtra_ibm(TERM_XTRA_CLEAR, 0); - - - /* Place the cursor */ - Term_curs_ibm(0, 0); - - - /* Access the "default" cursor info */ - r.h.ah = 3; - r.h.bh = 0; - - /* Make the call */ - int86(0x10, &r, &r); - - /* Extract the standard cursor info */ - saved_cur_v = 1; - saved_cur_high = r.h.ch; - saved_cur_low = r.h.cl; - - - /* Initialize the term */ - term_init(t, 80, 24, 256); - -#ifdef USE_CONIO -#else /* USE_CONIO */ - - /* Always use "Term_pict()" */ - t->always_pict = TRUE; - -#endif /* USE_CONIO */ - - /* Use "white space" to erase */ - t->attr_blank = TERM_WHITE; - t->char_blank = ' '; - - /* Prepare the init/nuke hooks */ - t->init_hook = Term_init_ibm; - t->nuke_hook = Term_nuke_ibm; - - /* Connect the hooks */ - t->xtra_hook = Term_xtra_ibm; - t->curs_hook = Term_curs_ibm; - t->wipe_hook = Term_wipe_ibm; - t->text_hook = Term_text_ibm; - t->pict_hook = Term_pict_ibm; - - /* Save it */ - term_screen = t; - - /* Activate it */ - Term_activate(term_screen); - - /* Success */ - return 0; -} - - -#endif /* USE_IBM */ diff --git a/src/main-lsl.c b/src/main-lsl.c deleted file mode 100644 index d24ede3f..00000000 --- a/src/main-lsl.c +++ /dev/null @@ -1,598 +0,0 @@ -/* - * File: main-lsl.c - * Purpose: Support for Linux-SVGALIB Angband - * Original Author: Jon Taylor (taylorj@gaia.ecs.csus.edu) - * Update by: Dennis Payne (dulsi@identicalsoftware.com) - * Version: 1.4.0, 12/05/99 - * - * Large amounts of code rewritten by Steven Fuerst. 20/04/2001 - * - * It now uses a hacked-up version of the X11 bmp-loading code. - * (Preparing to use 256 colour 16x16 mode) - */ - -#include "angband.h" - -#ifdef USE_LSL - -/* Standard C header files */ -#include <stdio.h> -#include <stdlib.h> - -/* SVGAlib header files */ -#include <vga.h> -#include <vgagl.h> -#include <vgakeyboard.h> -#include <zlib.h> - -#define COLOR_OFFSET 240 - -/* Hack - Define font/graphics cell width and height */ -#define CHAR_W 8 -#define CHAR_H 13 - -/* Global palette */ -static byte *pal = NULL; - -#ifdef USE_GRAPHICS - -/* - * The Win32 "BITMAPFILEHEADER" type. - */ -typedef struct BITMAPFILEHEADER -{ - u16b bfType; - u32b bfSize; - u16b bfReserved1; - u16b bfReserved2; - u32b bfOffBits; -} -BITMAPFILEHEADER; - - -/* - * The Win32 "BITMAPINFOHEADER" type. - */ -typedef struct BITMAPINFOHEADER -{ - u32b biSize; - u32b biWidth; - u32b biHeight; - u16b biPlanes; - u16b biBitCount; - u32b biCompresion; - u32b biSizeImage; - u32b biXPelsPerMeter; - u32b biYPelsPerMeter; - u32b biClrUsed; - u32b biClrImportand; -} -BITMAPINFOHEADER; - -/* - * The Win32 "RGBQUAD" type. - */ -typedef struct RGBQUAD -{ - unsigned char b, g, r; - unsigned char filler; -} -RGBQUAD; - - -/*** Helper functions for system independent file loading. ***/ - -static byte get_byte(FILE *fff) -{ - /* Get a character, and return it */ - return (getc(fff) & 0xFF); -} - -static void rd_byte(FILE *fff, byte *ip) -{ - *ip = get_byte(fff); -} - -static void rd_u16b(FILE *fff, u16b *ip) -{ - (*ip) = get_byte(fff); - (*ip) |= ((u16b)(get_byte(fff)) << 8); -} - -static void rd_u32b(FILE *fff, u32b *ip) -{ - (*ip) = get_byte(fff); - (*ip) |= ((u32b)(get_byte(fff)) << 8); - (*ip) |= ((u32b)(get_byte(fff)) << 16); - (*ip) |= ((u32b)(get_byte(fff)) << 24); -} - - -/* - * Read a Win32 BMP file. - * - * Assumes that the bitmap has a size such that no padding is needed in - * various places. Currently only handles bitmaps with 3 to 256 colors. - */ -static byte *ReadBMP(char *Name, int *bw, int *bh) -{ - FILE *f; - - BITMAPFILEHEADER fileheader; - BITMAPINFOHEADER infoheader; - - byte *Data; - - int ncol; - - int total; - - int i; - - u16b x, y; - - /* Open the BMP file */ - f = fopen(Name, "r"); - - /* No such file */ - if (!f) - { - quit ("No bitmap to load!"); - } - - /* Read the "BITMAPFILEHEADER" */ - rd_u16b(f, &(fileheader.bfType)); - rd_u32b(f, &(fileheader.bfSize)); - rd_u16b(f, &(fileheader.bfReserved1)); - rd_u16b(f, &(fileheader.bfReserved2)); - rd_u32b(f, &(fileheader.bfOffBits)); - - /* Read the "BITMAPINFOHEADER" */ - rd_u32b(f, &(infoheader.biSize)); - rd_u32b(f, &(infoheader.biWidth)); - rd_u32b(f, &(infoheader.biHeight)); - rd_u16b(f, &(infoheader.biPlanes)); - rd_u16b(f, &(infoheader.biBitCount)); - rd_u32b(f, &(infoheader.biCompresion)); - rd_u32b(f, &(infoheader.biSizeImage)); - rd_u32b(f, &(infoheader.biXPelsPerMeter)); - rd_u32b(f, &(infoheader.biYPelsPerMeter)); - rd_u32b(f, &(infoheader.biClrUsed)); - rd_u32b(f, &(infoheader.biClrImportand)); - - /* Verify the header */ - if (feof(f) || - (fileheader.bfType != 19778) || - (infoheader.biSize != 40)) - { - quit_fmt("Incorrect BMP file format %s", Name); - } - - /* The two headers above occupy 54 bytes total */ - /* The "bfOffBits" field says where the data starts */ - /* The "biClrUsed" field does not seem to be reliable */ - /* Compute number of colors recorded */ - ncol = (fileheader.bfOffBits - 54) / 4; - - for (i = 0; i < ncol; i++) - { - RGBQUAD clrg; - - /* Read an "RGBQUAD" */ - rd_byte(f, &(clrg.b)); - rd_byte(f, &(clrg.g)); - rd_byte(f, &(clrg.r)); - rd_byte(f, &(clrg.filler)); - - /* Analyze the color */ - pal[i * 3] = clrg.b; - pal[i * 3 + 1] = clrg.g; - pal[i * 3 + 2] = clrg.r; - } - - /* Look for illegal bitdepths. */ - if ((infoheader.biBitCount == 1) || (infoheader.biBitCount == 24)) - { - quit_fmt("Illegal biBitCount %d in %s", - infoheader.biBitCount, Name); - } - - /* Determine total bytes needed for image */ - total = infoheader.biWidth * (infoheader.biHeight + 2); - - /* Allocate image memory */ - C_MAKE(Data, total, byte); - - for (y = 0; y < infoheader.biHeight; y++) - { - int y2 = infoheader.biHeight - y - 1; - - for (x = 0; x < infoheader.biWidth; x++) - { - int ch = getc(f); - - /* Verify not at end of file XXX XXX */ - if (feof(f)) quit_fmt("Unexpected end of file in %s", Name); - - if (infoheader.biBitCount == 8) - { - Data[x + y2 * infoheader.biWidth] = ch; - } - else if (infoheader.biBitCount == 4) - { - Data[x + y2 * infoheader.biWidth] = ch / 16; - x++; - Data[x + y2 * infoheader.biWidth] = ch % 16; - } - } - } - - fclose(f); - - /* Save the size for later */ - *bw = infoheader.biWidth; - *bh = infoheader.biHeight; - - return (Data); -} - -#endif /* USE_GRAPHICS */ - - -/* The main "term" structure */ -static term term_screen_body; - -/* The visible and virtual screens */ -GraphicsContext *screen; -GraphicsContext *buffer; - -/* The font data */ -static void *font; - -/* Initialize the screen font */ -static void initfont(void) -{ - gzFile fontfile; - void *temp; - long junk; - - if (!(fontfile = gzopen("/usr/lib/kbd/consolefonts/lat1-12.psf.gz", "r"))) - { - /* Try uncompressed */ - if (!(fontfile = gzopen("/usr/lib/kbd/consolefonts/lat1-12.psf", "r"))) - { - printf ("Error: could not open font file. Aborting....\n"); - exit(1); - } - } - - /* Junk the 4-byte header */ - gzread(fontfile, &junk, 4); - - /* Initialize font */ - - /* - * Read in 13 bytes per character, and there are 256 characters - * in the font. This means we need to load 13x256 = 3328 bytes. - */ - C_MAKE(temp, 256 * 13, byte); - gzread(fontfile, temp, 256 * 13); - - /* - * I don't understand this code - SF - * (Is it converting from 8x13 -> 8x12?) - * - * I assume 15 is a colour... - */ - font = malloc(256 * 8 * 12 * BYTESPERPIXEL); - gl_expandfont(8, 12, 15, temp, font); - gl_setfont(8, 12, font); - - /* Cleanup */ - C_FREE(temp, 256 * 13, byte); - gzclose(fontfile); -} - -/* Initialize palette values for colors 0-15 */ -static void setpal(void) -{ - int i; - gl_setpalette(pal); - for (i = 0; i < 16; i++) - { - gl_setpalettecolor(COLOR_OFFSET + i, - angband_color_table[i][1] >> 2, - angband_color_table[i][2] >> 2, - angband_color_table[i][3] >> 2); - } -} - -/* - * Check for "events" - * If block, then busy-loop waiting for event, else check once and exit. - */ -static errr CheckEvents(int block) -{ - int k = 0; - - if (block) - { - k = vga_getkey(); - if (k < 1) return (1); - } - else - { - k = vga_getch(); - } - - Term_keypress(k); - return (0); -} - - -/* - * Low-level graphics routine (assumes valid input) - * Do a "special thing" - */ -static errr term_xtra_svgalib(int n, int v) -{ - switch (n) - { - case TERM_XTRA_EVENT: - { - /* Process some pending events */ - if (v) return (CheckEvents (FALSE)); - while (!CheckEvents (TRUE)); - return 0; - } - - case TERM_XTRA_FLUSH: - { - /* Flush all pending events */ - /* Should discard all key presses but unimplemented */ - return 0; - } - - case TERM_XTRA_CLEAR: - { - /* Clear the entire window */ - gl_fillbox (0, 0, 80 * CHAR_W, 25 * CHAR_H, 0); - return 0; - } - - case TERM_XTRA_DELAY: - { - /* Delay for some milliseconds */ - usleep(1000 * v); - return 0; - } - } - return 1; -} - -/* - * Low-level graphics routine (assumes valid input) - * Draws a "cursor" at (x,y) - */ -static errr term_curs_svgalib(int x, int y) -{ - gl_fillbox(x * CHAR_W, y * CHAR_H, CHAR_W, CHAR_H, 15); - return (0); -} - -/* - * Low-level graphics routine (assumes valid input) - * Erases a rectangular block of characters from (x,y) to (x+w,y+h) - */ -static errr term_wipe_svgalib(int x, int y, int n) -{ - gl_fillbox(x * CHAR_W, y * CHAR_H, n * CHAR_W, CHAR_H, 0); - return (0); -} - -/* - * Low-level graphics routine (assumes valid input) - * Draw n chars at location (x,y) with value s and attribute a - */ -static errr term_text_svgalib(int x, int y, int n, byte a, cptr s) -{ - /* Clear the area */ - term_wipe_svgalib(x, y, n); - - /* Draw the coloured text */ - gl_colorfont(8, 12, COLOR_OFFSET + (a & 0x0F), font); - gl_writen(x * CHAR_W, y * CHAR_H, n, (char *) s); - return (0); -} - -/* - * Low-level graphics routine (assumes valid input) - * Draw n chars at location (x,y) with value s and attribute a - */ - -#ifdef USE_GRAPHICS - -# ifdef USE_TRANSPARENCY -static errr term_pict_svgalib(int x, int y, int n, - const byte *ap, const char *cp, const byte *tap, const char *tcp) -# else /* USE_TRANSPARENCY */ -static errr term_pict_svgalib(int x, int y, int n, - const byte *ap, const char *cp) -# endif /* USE_TRANSPARENCY */ -{ - int i; - int x2, y2; - - -# ifdef USE_TRANSPARENCY - /* Hack - Ignore unused transparency data for now */ - (void) tap; - (void) tcp; -# endif /* USE_TRANSPARENCY */ - - for (i = 0; i < n; i++) - { - x2 = (cp[i] & 0x7F) * CHAR_W; - y2 = (ap[i] & 0x7F) * CHAR_H; - - gl_copyboxfromcontext(buffer, x2, y2, CHAR_W, CHAR_H, - (x + i) * CHAR_W, y * CHAR_H); - } - return (0); -} - -static void term_load_bitmap(void) -{ - char path[1024]; - - byte *temp = NULL; - - int bw, bh; - - /* Build the "graf" path */ - path_build(path, 1024, ANGBAND_DIR_XTRA, "graf"); - - sprintf (path, "%s/8x13.bmp", path); - - /* See if the file exists */ - if (fd_close(fd_open(path, O_RDONLY))) - { - printf ("Unable to load bitmap data file %s, bailing out....\n", path); - exit ( -1); - } - - temp = ReadBMP(path, &bw, &bh); - - /* Blit bitmap into buffer */ - gl_putbox(0, 0, bw, bh, temp); - - FREE(temp, byte); - - return; -} - -#endif /* USE_GRAPHICS */ - -/* - * Term hook - * Initialize a new term - */ -static void term_init_svgalib(term *t) -{ - int vgamode; - - /* Only one term */ - (void) t; - - vga_init(); - - /* The palette is 256x3 bytes big (RGB). */ - C_MAKE(pal, 768, byte); - -#ifdef USE_GRAPHICS - - /* Hardwire this mode in for now */ - vgamode = G1024x768x256; - - /* Set up the bitmap buffer context */ - gl_setcontextvgavirtual(vgamode); - buffer = gl_allocatecontext(); - gl_getcontext(buffer); - - /* Load bitmap into virtual screen */ - term_load_bitmap(); - -#endif /* USE_GRAPHICS */ - - /* Hardwire this mode in for now */ - vgamode = G640x480x256; - - /* Set up the physical screen context */ - if (vga_setmode(vgamode) < 0) - { - quit("Graphics mode not available!"); - } - - gl_setcontextvga(vgamode); - screen = gl_allocatecontext(); - gl_getcontext(screen); - - /* Is this needed? */ - gl_enablepageflipping(screen); - - /* Set up palette colors */ - setpal(); - - /* Load the character font data */ - initfont(); - - /* Color 0 isn't transparent */ - gl_setwritemode(WRITEMODE_OVERWRITE); -} - -/* - * Term hook - * Nuke an old term - */ -static void term_nuke_svgalib(term *t) -{ - /* Only one term */ - (void) t; - - vga_setmode(TEXT); -} - -/* - * Hook SVGAlib routines into term.c - */ -errr init_lsl(void) -{ - term *t = &term_screen_body; - -#ifdef USE_GRAPHICS - - if (arg_graphics) - { - use_graphics = TRUE; - } - -#endif /* USE_GRAPHICS */ - - /* Initialize the term */ - term_init(t, 80, 24, 1024); - - /* The cursor is done via software and needs erasing */ - t->soft_cursor = TRUE; - - t->attr_blank = TERM_DARK; - t->char_blank = ' '; - - /* Add hooks */ - t->init_hook = term_init_svgalib; - t->nuke_hook = term_nuke_svgalib; - t->text_hook = term_text_svgalib; - -#ifdef USE_GRAPHICS - - if (use_graphics) - { - t->pict_hook = term_pict_svgalib; - t->higher_pict = TRUE; - } - -#endif /* USE_GRAPHICS */ - - t->wipe_hook = term_wipe_svgalib; - t->curs_hook = term_curs_svgalib; - t->xtra_hook = term_xtra_svgalib; - - /* Save the term */ - term_screen = t; - - /* Activate it */ - Term_activate(term_screen); - - return (0); -} - -#endif /* USE_LSL */ diff --git a/src/main-mac.c b/src/main-mac.c deleted file mode 100644 index 2de64abd..00000000 --- a/src/main-mac.c +++ /dev/null @@ -1,5504 +0,0 @@ -/* File: main-mac.c */ - -/* - * Copyright (c) 1997 Ben Harrison, Keith Randall, and others - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. - */ - - -/* - * This file helps Angband work with Macintosh computers. - * - * To use this file, use an appropriate "Makefile" or "Project File", which - * should define "MACINTOSH". - * - * The official compilation uses the CodeWarrior Pro compiler. - * - * If you are never going to use "graphics" (especially if you are not - * compiling support for graphics anyway) then you can delete the "pict" - * resource with id "1001" with no dangerous side effects. - * - * - * By default, this file assumes that you will be using a 68020 or better - * machine, running System 7 and Color Quickdraw. In fact, the game will - * refuse to run unless these features are available. This allows the use - * of a variety of interesting features such as graphics and sound. - * - * To create a version which can be used on 68000 machines, or on machines - * which are not running System 7 or Color Quickdraw, simply activate the - * "ANGBAND_LITE_MAC" compilation flag in the proper header file. This - * will disable all "modern" features used in this file, including support - * for multiple sub-windows, color, graphics, and sound. - * - * When compiling with the "ANGBAND_LITE_MAC" flag, the "ANGBAND_LITE" - * flag will be automatically defined, which will disable many of the - * advanced features of the game itself, reducing the total memory usage. - * - * - * Note that the "preference" file is now a simple text file called - * "Angband Preferences", which contains a version stamp, so that - * obsolete preference files can be ignored. This should probably - * be replaced with a "structured" preference file of some kind. - * - * Note that "init1.c", "init2.c", "load1.c", "load2.c", and "birth.c" - * should probably be "unloaded" as soon as they are no longer needed, - * to save space, but I do not know how to do this. XXX XXX XXX - * - * Stange bug -- The first "ClipRect()" call crashes if the user closes - * all the windows, switches to another application, switches back, and - * re-opens the main window, for example, using "command-a". XXX XXX XXX - * - * - * Initial framework (and most code) by Ben Harrison (benh@phial.com). - * - * Some code adapted from "MacAngband 2.6.1" by Keith Randall - * - * Initial PowerMac port by Maarten Hazewinkel (mmhazewi@cs.ruu.nl). - * - * Most "USE_SFL_CODE" code provided by Steve Linberg (slinberg@crocker.com). - * - * Most of the graphics code is adapted from an extremely minimal subset of - * the "Sprite World II" package, an amazing (and free) animation package. - * - * - * Important Resources in the resource file: - * - * FREF 130 = ANGBAND_CREATOR / 'APPL' (application) - * FREF 129 = ANGBAND_CREATOR / 'SAVE' (save file) - * FREF 130 = ANGBAND_CREATOR / 'TEXT' (bone file, generic text file) - * FREF 131 = ANGBAND_CREATOR / 'DATA' (binary image file, score file) - * - * DLOG 128 = "About Angband..." - * - * ALRT 128 = unused (?) - * ALRT 129 = "Warning..." - * ALRT 130 = "Are you sure you want to quit without saving?" - * - * DITL 128 = body for DLOG 128 - * DITL 129 = body for ALRT 129 - * DITL 130 = body for ALRT 130 - * - * ICON 128 = "warning" icon - * - * MENU 128 = apple (about, -, ...) - * MENU 129 = File (new, open, close, save, -, score, exit, quit) - * In T.o.M.E. - * MENU 129 = File (close, save, -, score, exit, quit) - * MENU 130 = Edit (undo, -, cut, copy, paste, clear) - * MENU 131 = Font (bold, wide, -) - * MENU 132 = Size () - * MENU 133 = Windows () - * MENU 134 = Special (Sound, Graphics, TileWidth, TileHeight, -, Fiddle, Wizard) - * Graphics have following submenu attached: - * MENU 144 = Graphics (None, 8x8, 16x16) - * TileWidth and TileHeight submenus are filled in by this program - * MENU 145 = TileWidth () - * MENU 146 = TileHeight () - * - * PICT 1001 = Graphics tile set (8x8) - * PICT 1002 = Graphics tile set (16x16 images) - * - * Note: You can no longer use the exit menu unless you build the programme - * with an appropriate compile-time option. - * - * - * File name patterns: - * all 'APEX' files have a filename of the form "*:apex:*" (?) - * all 'BONE' files have a filename of the form "*:bone:*" (?) - * all 'DATA' files have a filename of the form "*:data:*" - * all 'SAVE' files have a filename of the form "*:save:*" - * all 'USER' files have a filename of the form "*:user:*" (?) - * - * Perhaps we should attempt to set the "_ftype" flag inside this file, - * to avoid nasty file type information being spread all through the - * rest of the code. (?) This might require adding hooks into the - * "fd_open()" and "my_fopen()" functions in "util.c". XXX XXX XXX - * - * - * Reasons for each header file: - * - * angband.h = Angband header file - * - * Types.h = (included anyway) - * Gestalt.h = gestalt code - * QuickDraw.h = (included anyway) - * OSUtils.h = (included anyway) - * Files.h = file code - * Fonts.h = font code - * Menus.h = menu code - * Dialogs.h = dialog code - * Windows.h = (included anyway) - * Palettes.h = palette code - * StandardFile.h = file dialog box - * DiskInit.h = disk initialization - * ToolUtils.h = HiWord() / LoWord() - * Desk.h = OpenDeskAcc() - * Devices.h = OpenDeskAcc() - * Events.h = event code - * Resources.h = resource code - * Controls.h = button code - * SegLoad.h = ExitToShell(), AppFile, etc - * Memory.h = SetApplLimit(), NewPtr(), etc - * QDOffscreen.h = GWorld code - * Sound.h = Sound code - * - * For backwards compatibility: - * Use GestaltEqu.h instead of Gestalt.h - * Add Desk.h to include simply includes Menus.h, Devices.h, Events.h - */ - - -#include "angband.h" - - -#ifdef MACINTOSH - -/* - * Variant-dependent features: - * - * #define ALLOW_BIG_SCREEN (V, Ey, O, T.o.M.E. and Z. - * Dr's big screen needs more work. New S one needs some thought) - * #define ANG281_RESET_VISUALS (Cth, Gum, T.o.M.E., Z) - * #define SAVEFILE_SCREEN (T.o.M.E.) - * #define USE_DOUBLE_TILES ("bigtile" patch, V and T.o.M.E. - * T requires #define TOME in addition to this) - * #define ZANG_AUTO_SAVE (O and Z) - * #define HAS_SCORE_MENU (V and T.o.M.E.) - * #define ANGBAND_PREFERENCES "_your_variant_name_ Preferences" - * #define ANGBAND_CREATOR four letter code for your variant, if any. - * or use the default one. - * - * In [Z], please replace inkey_flag with p_ptr->inkey_flag as well. - */ - -/* Some porting examples */ -#ifdef ANGBAND30X -# define USE_DOUBLE_TILES -# define ALLOW_BIG_SCREEN -# define HAS_SCORE_MENU -# define NEW_ZVIRT_HOOKS -/* I can't ditch this, yet, because there are many variants */ -# define USE_TRANSPARENCY -#endif /* ANGBAND30X */ - -#ifdef TOME -# define USE_DOUBLE_TILES -# define SAVEFILE_SCREEN -# define ANG281_RESET_VISUALS -# define ALLOW_BIG_SCREEN -# define HAS_SCORE_MENU -# define ANGBAND_CREATOR 'PrnA' -# define ANGBAND_PREFERENCES "T.o.M.E. Preferences" -#endif /* TOME */ - -/* Default creator signature */ -# ifndef ANGBAND_CREATOR -# define ANGBAND_CREATOR 'A271' -# endif - -/* Default preferences file name */ -# ifndef ANGBAND_PREFERENCES -# define ANGBAND_PREFERENCES "Angband Preferences" -# endif - - -/* - * To cope with pref file related problems - * - * Please note that some variants don't set them to "real" version number - * and uses other defines for that purpose. - * - * This is *very* important for Classic ports, because wrong pref file formats - * can crash the system. - */ -#ifndef PREF_VER_MAJOR -# define PREF_VER_MAJOR VERSION_MAJOR -#endif -#ifndef PREF_VER_MINOR -# define PREF_VER_MINOR VERSION_MINOR -#endif -#ifndef PREF_VER_PATCH -# define PREF_VER_PATCH VERSION_PATCH -#endif -#ifndef PREF_VER_EXTRA -# define PREF_VER_EXTRA VERSION_EXTRA -#endif - - -#include <Types.h> -#include <Gestalt.h> -#include <QuickDraw.h> -#include <Files.h> -#include <Fonts.h> -#include <Menus.h> -#include <Dialogs.h> -#include <Windows.h> -#include <Palettes.h> -#include <StandardFile.h> -#include <DiskInit.h> -#include <ToolUtils.h> -#include <Devices.h> -#include <Events.h> -#include <Resources.h> -#include <Controls.h> -#include <SegLoad.h> -#include <Memory.h> -#include <QDOffscreen.h> -#include <Sound.h> - - -/* - * Use "malloc()" instead of "NewPtr()" - */ -/* #define USE_MALLOC */ - - -#if defined(powerc) || defined(__powerc) - -/* - * Disable "LITE" version - */ -# undef ANGBAND_LITE_MAC - -#endif - - -#ifndef ANGBAND_LITE_MAC - -/* - * Activate some special code - */ -# define USE_SFL_CODE - -#endif /* ANGBAND_LITE_MAC */ - - - -#ifdef USE_SFL_CODE - -/* - * Include the necessary header files - */ -#include <AppleEvents.h> -#include <EPPC.h> -#include <Folders.h> - -#endif - - -#ifdef ANGBAND_LITE_MAC - -/* - * Everything in drawn as white on black - */ - -#else /* ANGBAND_LITE_MAC */ - -/* -* Information about each of the 256 available colors -*/ -static RGBColor color_info[256]; - -#endif /* ANGBAND_LITE_MAC */ - - -/* - * Forward declare - */ -typedef struct term_data term_data; - -/* - * Extra "term" data - */ -struct term_data -{ - term *t; - - Rect r; - - WindowPtr w; - -#ifdef ANGBAND_LITE_MAC - - /* Nothing */ - -#else /* ANGBAND_LITE_MAC */ - - short padding; - - short pixelDepth; - - GWorldPtr theGWorld; - - GDHandle theGDH; - - GDHandle mainSWGDH; - -#endif /* ANGBAND_LITE_MAC */ - - Str15 title; - - s16b oops; - - s16b keys; - - s16b last; - - s16b mapped; - - s16b rows; - s16b cols; - - s16b font_id; - s16b font_size; - s16b font_face; - s16b font_mono; - - s16b font_o_x; - s16b font_o_y; - s16b font_wid; - s16b font_hgt; - - s16b tile_o_x; - s16b tile_o_y; - s16b tile_wid; - s16b tile_hgt; - - s16b size_wid; - s16b size_hgt; - - s16b size_ow1; - s16b size_oh1; - s16b size_ow2; - s16b size_oh2; -}; - - - - -#ifdef MAC_MPW - -/* - * MPW 68K compiler cannot process ToME's variable.c correctly... - * but support for it is here, for your reference. I have tried - * this with SC and MrC to compile Vanilla successfully. - */ -QDGlobals qd; - -/* - * File type assigner - declare them in externs.h as well. - * - * You still have to call - * fsetfileinfo(buf, _fcreator, _ftype); - * in fd_make() and my_fopen() to assign creator and type - * to a file. - */ -u32b _ftype; -u32b _fcreator; - -/* - * Since MPW's C library doesn't have stat or fstat, you have to - * disable CHECK_MODIFICATION_TIME in config.h - * - * Another source code change required for MPW compilation is - * to #define MACINTOSH and #undef __STDC__ - * This can be done conveniently in h-system.h - * - * You may have to cast some pointers to non-offending types e.g. (void *). - * This typically occurs when passing a const pointer to a library - * function whose prototype doesn't have const in corresponding - * parameter. - */ - -#endif /* MAC_MPW */ - - -/* - * Forward declare -- see below - */ -static bool CheckEvents(bool wait); - - -/* - * Hack -- location of the main directory - */ -static short app_vol; -static long app_dir; - - -/* - * Delay handling of double-clicked savefiles - */ -Boolean open_when_ready = FALSE; - -/* - * Delay handling of pre-emptive "quit" event - */ -Boolean quit_when_ready = FALSE; - - -/* - * Hack -- game in progress - */ -static int game_in_progress = 0; - - -/* - * Only do "SetPort()" when needed - */ -static WindowPtr active = NULL; - - -/* - * Maximum number of terms - */ -#define MAX_TERM_DATA 8 - - -/* - * An array of term_data's - */ -static term_data data[MAX_TERM_DATA]; - - - -/* - * Note when "open"/"new" become valid - */ -static bool initialized = FALSE; - - - -#ifdef ALLOW_NO_SAVE_QUITS - -/* - * CodeWarrior uses Universal Procedure Pointers - */ -static ModalFilterUPP ynfilterUPP; - -#endif /* ALLOW_NO_SAVE_QUITS */ - - - -#ifdef USE_SFL_CODE - -/* - * Apple Event Hooks - */ -AEEventHandlerUPP AEH_Start_UPP; -AEEventHandlerUPP AEH_Quit_UPP; -AEEventHandlerUPP AEH_Print_UPP; -AEEventHandlerUPP AEH_Open_UPP; - -#endif - - - -/* - * Convert a C string to a pascal string in place - * - * This function may be defined elsewhere, but since it is so - * small, it is not worth finding the proper function name for - * all the different platforms. - */ -static void ctopstr(StringPtr src) -{ - int i; - byte len; - - /* Hack -- pointer */ - char *s = (char*)(src); - - len = strlen(s); - - /* Hack -- convert the string */ - for (i = len; i > 1; i--) s[i] = s[i - 1]; - - /* Hack -- terminate the string */ - s[0] = len; -} - - -/* - * Convert refnum+vrefnum+fname into a full file name - * Store this filename in 'buf' (make sure it is long enough) - * Note that 'fname' looks to be a "pascal" string - */ -static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname) -{ - DirInfo pb; - Str255 name; - int err; - int i, j; - - char res[1000]; - - i = 999; - - res[i] = 0; - i--; - for (j = 1; j <= fname[0]; j++) - { - res[i - fname[0] + j] = fname[j]; - } - i -= fname[0]; - - pb.ioCompletion = NULL; - pb.ioNamePtr = name; - pb.ioVRefNum = vrefnum; - pb.ioDrParID = refnum; - pb.ioFDirIndex = -1; - - while (1) - { - pb.ioDrDirID = pb.ioDrParID; - err = PBGetCatInfoSync((CInfoPBPtr) & pb); - res[i] = ':'; - i--; - for (j = 1; j <= name[0]; j++) - { - res[i - name[0] + j] = name[j]; - } - i -= name[0]; - - if (pb.ioDrDirID == fsRtDirID) break; - } - - /* Extract the result */ - for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i]; - buf[j] = 0; -} - - -#if 0 - -/* - * XXX XXX XXX Allow the system to ask us for a filename - */ -static bool askfor_file(char *buf, int len) -{ - SFReply reply; - Str255 dflt; - Point topleft; - short vrefnum; - long drefnum, junk; - - /* Default file name */ - strnfmt((char*)dflt + 1, 255, "%s's description", buf); - dflt[0] = strlen((char*)dflt + 1); - - /* Ask for a file name */ - topleft.h = (qd.screenBits.bounds.left + qd.screenBits.bounds.right) / 2 - 344 / 2; - topleft.v = (2 * qd.screenBits.bounds.top + qd.screenBits.bounds.bottom) / 3 - 188 / 2; - SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply); - /* StandardPutFile("\pSelect a filename:", dflt, &reply); */ - - /* Process */ - if (reply.good) - { - int fc; - - /* Get info */ - GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk); - - /* Extract the name */ - refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName); - - /* Success */ - return (TRUE); - } - - /* Failure */ - return (FALSE); -} - -#endif - - - -/* - * Center a rectangle inside another rectangle - */ -static void center_rect(Rect *r, Rect *s) -{ - int centerx = (s->left + s->right) / 2; - int centery = (2 * s->top + s->bottom) / 3; - int dx = centerx - (r->right - r->left) / 2 - r->left; - int dy = centery - (r->bottom - r->top) / 2 - r->top; - r->left += dx; - r->right += dx; - r->top += dy; - r->bottom += dy; -} - - -/* - * Convert a pascal string in place - * - * This function may be defined elsewhere, but since it is so - * small, it is not worth finding the proper function name for - * all the different platforms. - */ -static void ptocstr(StringPtr src) -{ - int i; - - /* Hack -- pointer */ - char *s = (char*)(src); - - /* Hack -- convert the string */ - for (i = s[0]; i; i--, s++) s[0] = s[1]; - - /* Hack -- terminate the string */ - s[0] = '\0'; -} - - -#if defined(USE_SFL_CODE) - - -/* - * The following three routines (pstrcat, pstrinsert, and PathNameFromDirID) - * were taken from the Think Reference section called "Getting a Full Pathname" - * (under the File Manager section). We need PathNameFromDirID to get the - * full pathname of the opened savefile, making no assumptions about where it - * is. - * - * I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully - * nice. - */ -static void pstrcat(StringPtr dst, StringPtr src) -{ - /* copy string in */ - BlockMove(src + 1, dst + *dst + 1, *src); - - /* adjust length byte */ - *dst += *src; -} - -/* - * pstrinsert - insert string 'src' at beginning of string 'dst' - */ -static void pstrinsert(StringPtr dst, StringPtr src) -{ - /* make room for new string */ - BlockMove(dst + 1, dst + *src + 1, *dst); - - /* copy new string in */ - BlockMove(src + 1, dst + 1, *src); - - /* adjust length byte */ - *dst += *src; -} - -static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName) -{ - CInfoPBRec block; - Str255 directoryName; - OSErr err; - - fullPathName[0] = '\0'; - - block.dirInfo.ioDrParID = dirID; - block.dirInfo.ioNamePtr = directoryName; - - while (1) - { - block.dirInfo.ioVRefNum = vRefNum; - block.dirInfo.ioFDirIndex = -1; - block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID; - err = PBGetCatInfoSync(&block); - pstrcat(directoryName, (StringPtr)"\p:"); - pstrinsert(fullPathName, directoryName); - if (block.dirInfo.ioDrDirID == 2) break; - } -} - -#endif - - - -/* - * Activate a given window, if necessary - */ -static void activate(WindowPtr w) -{ - /* Activate */ - if (active != w) - { - /* Activate */ - if (w) SetPort(w); - - /* Remember */ - active = w; - } -} - - -/* - * Display a warning message - */ -static void mac_warning(cptr warning) -{ - Str255 text; - int len, i; - - /* Limit of 250 chars */ - len = strlen(warning); - if (len > 250) len = 250; - - /* Make a "Pascal" string */ - text[0] = len; - for (i = 0; i < len; i++) text[i + 1] = warning[i]; - - /* Prepare the dialog box values */ - ParamText(text, "\p", "\p", "\p"); - - /* Display the Alert, wait for Okay */ - Alert(129, 0L); -} - - - -/*** Some generic functions ***/ - - -#ifdef ANGBAND_LITE_MAC - -/* - * Hack -- activate a color (0 to 255) - */ -#define term_data_color(TD,A) /* Nothing */ - -#else /* ANGBAND_LITE_MAC */ - -/* -* Hack -- activate a color (0 to 255) -*/ -static void term_data_color(term_data *td, int a) -{ - /* Activate the color */ - if (td->last != a) - { - /* Activate the color */ - RGBForeColor(&color_info[a]); - - /* Memorize color */ - td->last = a; - } -} - -#endif /* ANGBAND_LITE_MAC */ - - -/* - * Hack -- Apply and Verify the "font" info - * - * This should usually be followed by "term_data_check_size()" - * - * XXX XXX To force (re)initialisation of td->tile_wid and td->tile_hgt - * you have to reset them to zero before this function is called. - * XXX XXX This is automatic when the program starts because the term_data - * array is WIPE'd by term_data_hack, but isn't in the other cases, i.e. - * font, font style and size changes. - */ -static void term_data_check_font(term_data *td) -{ - int i; - - FontInfo info; - - WindowPtr old = active; - - - /* Activate */ - activate(td->w); - - /* Instantiate font */ - TextFont(td->font_id); - TextSize(td->font_size); - TextFace(td->font_face); - - /* Extract the font info */ - GetFontInfo(&info); - - /* Assume monospaced */ - td->font_mono = TRUE; - - /* Extract the font sizing values XXX XXX XXX */ - td->font_wid = CharWidth('@'); /* info.widMax; */ - td->font_hgt = info.ascent + info.descent; - td->font_o_x = 0; - td->font_o_y = info.ascent; - - /* Check important characters */ - for (i = 33; i < 127; i++) - { - /* Hack -- notice non-mono-space */ - if (td->font_wid != CharWidth(i)) td->font_mono = FALSE; - - /* Hack -- collect largest width */ - if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i); - } - - /* Set default offsets */ - td->tile_o_x = td->font_o_x; - td->tile_o_y = td->font_o_y; - - /* Set default tile size */ - if (td->tile_wid == 0) td->tile_wid = td->font_wid; - if (td->tile_hgt == 0) td->tile_hgt = td->font_hgt; - - /* Re-activate the old window */ - activate(old); -} - - -/* - * Hack -- Apply and Verify the "size" info - */ -static void term_data_check_size(term_data *td) -{ - /* Minimal window size for the Angband window */ - if (td == &data[0]) - { -#ifdef ALLOW_BIG_SCREEN - - /* Enforce minimal size */ - if (td->cols < 80) td->cols = 80; - if (td->rows < 24) td->rows = 24; - -#else - - /* Enforce the traditional size */ - if (td->cols != 80) td->cols = 80; - if (td->rows != 24) td->rows = 24; - -#endif /* ALLOW_BIG_SCREEN */ - } - - /* Allow small windows for the rest */ - else - { - if (td->cols < 1) td->cols = 1; - if (td->rows < 1) td->rows = 1; - } - - /* Enforce maximal sizes */ - if (td->cols > 255) td->cols = 255; - if (td->rows > 255) td->rows = 255; - - /* Minimal tile size */ - if (td->tile_wid < td->font_wid) td->tile_wid = td->font_wid; - if (td->tile_hgt < td->font_hgt) td->tile_hgt = td->font_hgt; - - /* Default tile offsets */ - td->tile_o_x = (td->tile_wid - td->font_wid) / 2; - td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2; - - /* Minimal tile offsets */ - if (td->tile_o_x < 0) td->tile_o_x = 0; - if (td->tile_o_y < 0) td->tile_o_y = 0; - - /* Apply font offsets */ - td->tile_o_x += td->font_o_x; - td->tile_o_y += td->font_o_y; - - /* Calculate full window size */ - td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2; - td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2; - - /* Verify the top */ - if (td->r.top > qd.screenBits.bounds.bottom - td->size_hgt) - { - td->r.top = qd.screenBits.bounds.bottom - td->size_hgt; - } - - /* Verify the top */ - if (td->r.top < qd.screenBits.bounds.top + 30) - { - td->r.top = qd.screenBits.bounds.top + 30; - } - - /* Verify the left */ - if (td->r.left > qd.screenBits.bounds.right - td->size_wid) - { - td->r.left = qd.screenBits.bounds.right - td->size_wid; - } - - /* Verify the left */ - if (td->r.left < qd.screenBits.bounds.left) - { - td->r.left = qd.screenBits.bounds.left; - } - - /* Calculate bottom right corner */ - td->r.right = td->r.left + td->size_wid; - td->r.bottom = td->r.top + td->size_hgt; - - /* Assume no graphics */ - td->t->higher_pict = FALSE; - td->t->always_pict = FALSE; - -#ifdef ANGBAND_LITE_MAC - - /* No graphics */ - -#else /* ANGBAND_LITE_MAC */ - - /* Handle graphics */ - if (use_graphics) - { - /* Use higher_pict whenever possible */ - if (td->font_mono) td->t->higher_pict = TRUE; - - /* Use always_pict only when necessary */ - else td->t->always_pict = TRUE; - } - -#endif /* ANGBAND_LITE_MAC */ - - /* Fake mono-space */ - if (!td->font_mono || - (td->font_wid != td->tile_wid) || - (td->font_hgt != td->tile_hgt)) - { - /* Handle fake monospace -- this is SLOW */ - if (td->t->higher_pict) td->t->higher_pict = FALSE; - td->t->always_pict = TRUE; - } -} - - -/* - * Hack -- resize a term_data - * - * This should normally be followed by "term_data_resize()" - */ -static void term_data_resize(term_data *td) -{ - /* Actually resize the window */ - SizeWindow(td->w, td->size_wid, td->size_hgt, 0); -} - - - -/* - * Hack -- redraw a term_data - * - * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR" - */ -static void term_data_redraw(term_data *td) -{ - term *old = Term; - - /* Activate the term */ - Term_activate(td->t); - - /* Redraw the contents */ - Term_redraw(); - - /* Flush the output */ - Term_fresh(); - - /* Restore the old term */ - Term_activate(old); - - /* No need to redraw */ - ValidRect(&td->w->portRect); -} - - - - -#ifdef ANGBAND_LITE_MAC - -/* No graphics */ - -#else /* ANGBAND_LITE_MAC */ - - -/* -* Graphics support -*/ - -/* Set by Term_xtra_mac_react */ -static int pictID; /* PICT id of image tiles */ - -static int grafWidth; /* Width of a tile in pixels */ -static int grafHeight; /* Height of a tile in pixels */ - -/* Calculated by PICT loading code */ -static int pictCols; /* Number of columns in tiles */ -static int pictRows; /* Number of rows in tiles */ - -/* Available graphics modes */ -#define GRAF_MODE_NONE 0 /* plain ASCII */ -#define GRAF_MODE_8X8 1 /* 8x8 tiles, no transparency effect */ -#define GRAF_MODE_16X16 2 /* 16x16 tiles, transparency effect */ -/* This doesn't work... */ -#define GRAF_MODE_32X32 3 /* 32x32 tiles, transparency effect */ - -static int graf_mode = GRAF_MODE_NONE; /* current graphics mode */ -static int graf_mode_req = GRAF_MODE_NONE; /* requested graphics mode */ - -#define TR_NONE 0 /* No transparency effect */ -#define TR_OVER 1 /* Overwriting with transparent black pixels */ -static int transparency_mode = TR_NONE; - - -/* -* Forward Declare -*/ -typedef struct FrameRec FrameRec; - -/* -* Frame -* -* - GWorld for the frame image -* - Handle to pix map (saved for unlocking/locking) -* - Pointer to color pix map (valid only while locked) -*/ -struct FrameRec -{ - GWorldPtr framePort; - PixMapHandle framePixHndl; - PixMapPtr framePix; -}; - - -/* -* The global picture data -*/ -static FrameRec *frameP = NULL; - - -/* -* Lock a frame -*/ -static void BenSWLockFrame(FrameRec *srcFrameP) -{ - PixMapHandle pixMapH; - - pixMapH = GetGWorldPixMap(srcFrameP->framePort); - (void)LockPixels(pixMapH); - HLockHi((Handle)pixMapH); - srcFrameP->framePixHndl = pixMapH; - srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH); -} - - -/* -* Unlock a frame -*/ -static void BenSWUnlockFrame(FrameRec *srcFrameP) -{ - if (srcFrameP->framePort != NULL) - { - HUnlock((Handle)srcFrameP->framePixHndl); - UnlockPixels(srcFrameP->framePixHndl); - } - - srcFrameP->framePix = NULL; -} - - - -static OSErr BenSWCreateGWorldFromPict( - GWorldPtr *pictGWorld, PicHandle pictH) -{ - OSErr err; - GWorldPtr saveGWorld; - GDHandle saveGDevice; - GWorldPtr tempGWorld; - Rect pictRect; - short depth; - GDHandle theGDH; - - tempGWorld = NULL; - - /* Reset */ - *pictGWorld = NULL; - - /* Get depth */ - depth = data[0].pixelDepth; - - /* Get GDH */ - theGDH = data[0].theGDH; - - /* Obtain size rectangle */ - pictRect = (**pictH).picFrame; - OffsetRect(&pictRect, -pictRect.left, -pictRect.top); - - /* Calculate and set numbers of rows and columns */ - pictRows = pictRect.bottom / grafHeight; - pictCols = pictRect.right / grafWidth; - - /* Create a GWorld */ - err = NewGWorld(&tempGWorld, depth, &pictRect, nil, theGDH, noNewDevice); - - /* Error */ - if (err != noErr) return (err); - - /* Save pointer */ - *pictGWorld = tempGWorld; - - /* Save GWorld */ - GetGWorld(&saveGWorld, &saveGDevice); - - /* Activate */ - SetGWorld(tempGWorld, nil); - - /* Dump the pict into the GWorld */ - (void)LockPixels(GetGWorldPixMap(tempGWorld)); - EraseRect(&pictRect); - DrawPicture(pictH, &pictRect); - UnlockPixels(GetGWorldPixMap(tempGWorld)); - - /* Restore GWorld */ - SetGWorld(saveGWorld, saveGDevice); - - /* Success */ - return (0); -} - - -/* -* Init the global "frameP" -*/ -static OSErr globe_init(void) -{ - OSErr err; - - GWorldPtr tempPictGWorldP; - - PicHandle newPictH; - - - /* Use window XXX XXX XXX */ - SetPort(data[0].w); - - - /* Get the pict resource */ - newPictH = GetPicture(pictID); - - /* Error */ - if (newPictH == NULL) return ( -1); - - /* Create GWorld */ - err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH); - - /* Release resource */ - ReleaseResource((Handle)newPictH); - - /* Error */ - if (err != noErr) return (err); - - /* Create the frame */ - frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec)); - - /* Error */ - if (frameP == NULL) return ( -1); - - /* Save GWorld */ - frameP->framePort = tempPictGWorldP; - - /* Lock it */ - BenSWLockFrame(frameP); - - /* Success */ - return (noErr); -} - - -/* -* Nuke the global "frameP" -*/ -static errr globe_nuke(void) -{ - /* Dispose */ - if (frameP) - { - /* Unlock */ - BenSWUnlockFrame(frameP); - - /* Dispose of the GWorld */ - DisposeGWorld(frameP->framePort); - - /* Dispose of the memory */ - DisposePtr((Ptr)frameP); - - /* Forget */ - frameP = NULL; - } - - /* Flush events */ - FlushEvents(everyEvent, 0); - - /* Success */ - return (0); -} - - -#endif /* ANGBAND_LITE_MAC */ - - - - -#ifdef USE_ASYNC_SOUND - -/* - * Asynchronous sound player - completely revised (beta) - */ - -/* - * Number of channels in the channel pool - */ -#define MAX_CHANNELS 4 - -/* - * A pool of sound channels - */ -static SndChannelPtr channels[MAX_CHANNELS]; - -/* - * Status of the channel pool - */ -static Boolean channel_initialised = FALSE; - -/* - * Data handles containing sound samples - */ -static SndListHandle samples[SOUND_MAX]; - -/* - * Reference counts of sound samples - */ -static SInt16 sample_refs[SOUND_MAX]; - -#define SOUND_VOLUME_MIN 0 /* Default minimum sound volume */ -#define SOUND_VOLUME_MAX 255 /* Default maximum sound volume */ -#define VOLUME_MIN 0 /* Minimum sound volume in % */ -#define VOLUME_MAX 100 /* Maximum sound volume in % */ -#define VOLUME_INC 5 /* Increment sound volume in % */ - -/* I'm just too lazy to write a panel for this XXX XXX */ -static int sound_volume = SOUND_VOLUME_MAX; - -/* - * Return a handle of 'snd ' resource given Angband sound event number, - * or NULL if it isn't found. - * - * Globals referenced: angband_sound_name[] (variable.c) - */ -static SndListHandle find_sound(int num) -{ - Str255 sound; - - /* Get the proper sound name */ - strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[num]); - sound[0] = strlen((char*)sound + 1); - - /* Obtain resource XXX XXX XXX */ - return ((SndListHandle)GetNamedResource('snd ', sound)); -} - - -/* - * Clean up sound support - to be called when the game exits. - * - * Globals referenced: channels[], samples[], sample_refs[]. - */ -static void cleanup_sound(void) -{ - int i; - - /* No need to clean it up */ - if (!channel_initialised) return; - - /* Dispose channels */ - for (i = 0; i < MAX_CHANNELS; i++) - { - /* Drain sound commands and free the channel */ - SndDisposeChannel(channels[i], TRUE); - } - - /* Free sound data */ - for (i = 1; i < SOUND_MAX; i++) - { - /* Still locked */ - if ((sample_refs[i] > 0) && (samples[i] != NULL)) - { - /* Unlock it */ - HUnlock((Handle)samples[i]); - } - - /* Release it */ - if (samples[i]) ReleaseResource((Handle)samples[i]); - } -} - - -/* - * Play sound effects asynchronously -- pelpel - * - * I don't believe those who first started using the previous implementations - * imagined this is *much* more complicated as it may seem. Anyway, - * introduced round-robin scheduling of channels and made it much more - * paranoid about HLock/HUnlock. - * - * XXX XXX de-refcounting, HUnlock and ReleaseResource should be done - * using channel's callback procedures, which set global flags, and - * a procedure hooked into CheckEvents does housekeeping. On the other - * hand, this lazy reclaiming strategy keeps things simple (no interrupt - * time code) and provides a sort of cache for sound data. - * - * Globals referenced: channel_initialised, channels[], samples[], - * sample_refs[]. - * Globals updated: ditto. - */ -static void play_sound(int num, int vol) -{ - OSErr err; - int i; - int prev_num; - SndListHandle h; - SndChannelPtr chan; - SCStatus status; - - static int next_chan; - static SInt16 channel_occupants[MAX_CHANNELS]; - static SndCommand volume_cmd, quiet_cmd; - - - /* Initialise sound channels */ - if (!channel_initialised) - { - for (i = 0; i < MAX_CHANNELS; i++) - { - /* Paranoia - Clear occupant table */ - /* channel_occupants[i] = 0; */ - - /* Create sound channel for all sounds to play from */ - err = SndNewChannel(&channels[i], sampledSynth, initMono, 0L); - - /* Error */ - if (err != noErr) - { - /* Free channels */ - while (--i >= 0) - { - SndDisposeChannel(channels[i], TRUE); - } - - /* Notify error */ - plog("Cannot initialise sound channels!"); - - /* Cancel request */ - use_sound = arg_sound = FALSE; - - /* Failure */ - return; - } - } - - /* First channel to use */ - next_chan = 0; - - /* Prepare volume command */ - volume_cmd.cmd = volumeCmd; - volume_cmd.param1 = 0; - volume_cmd.param2 = 0; - - /* Prepare quiet command */ - quiet_cmd.cmd = quietCmd; - quiet_cmd.param1 = 0; - quiet_cmd.param2 = 0; - - /* Initialisation complete */ - channel_initialised = TRUE; - } - - /* Paranoia */ - if ((num <= 0) || (num >= SOUND_MAX)) return; - - /* Prepare volume command */ - volume_cmd.param2 = (SInt16)((vol << 4) | vol); - - /* Channel to use (round robin) */ - chan = channels[next_chan]; - - /* See if the resource is already in use */ - if (sample_refs[num] > 0) - { - /* Resource in use */ - h = samples[num]; - - /* Increase the refcount */ - sample_refs[num]++; - } - - /* Sound is not currently in use */ - else - { - /* Get handle for the sound */ - h = find_sound(num); - - /* Sample not available */ - if (h == NULL) return; - - /* Load resource */ - LoadResource((Handle)h); - - /* Lock the handle */ - HLock((Handle)h); - - /* Remember it */ - samples[num] = h; - - /* Initialise refcount */ - sample_refs[num] = 1; - } - - /* Poll the channel */ - err = SndChannelStatus(chan, sizeof(SCStatus), &status); - - /* It isn't available */ - if ((err != noErr) || status.scChannelBusy) - { - /* Shut it down */ - SndDoImmediate(chan, &quiet_cmd); - } - - /* Previously played sound on this channel */ - prev_num = channel_occupants[next_chan]; - - /* Process previously played sound */ - if (prev_num != 0) - { - /* Decrease refcount */ - sample_refs[prev_num]--; - - /* We can free it now */ - if (sample_refs[prev_num] <= 0) - { - /* Unlock */ - HUnlock((Handle)samples[prev_num]); - - /* Release */ - ReleaseResource((Handle)samples[prev_num]); - - /* Forget handle */ - samples[prev_num] = NULL; - - /* Paranoia */ - sample_refs[prev_num] = 0; - } - } - - /* Remember this sound as the current occupant of the channel */ - channel_occupants[next_chan] = num; - - /* Set up volume for channel */ - SndDoImmediate(chan, &volume_cmd); - - /* Play new sound asynchronously */ - SndPlay(chan, h, TRUE); - - /* Schedule next channel (round robin) */ - next_chan++; - if (next_chan >= MAX_CHANNELS) next_chan = 0; -} - -#endif /* USE_ASYNC_SOUND */ - - -/*** Support for the "z-term.c" package ***/ - - -/* - * Initialize a new Term - * - * Note also the "window type" called "noGrowDocProc", which might be more - * appropriate for the main "screen" window. - * - * Note the use of "srcCopy" mode for optimized screen writes. - */ -static void Term_init_mac(term *t) -{ - term_data *td = (term_data*)(t->data); - - static RGBColor black = {0x0000, 0x0000, 0x0000}; - static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF}; - -#ifdef ANGBAND_LITE_MAC - - /* Make the window */ - td->w = NewWindow(0, &td->r, td->title, 0, noGrowDocProc, (WindowPtr) - 1, 1, 0L); - -#else /* ANGBAND_LITE_MAC */ - - /* Make the window */ - td->w = NewCWindow(0, &td->r, td->title, 0, documentProc, (WindowPtr) - 1, 1, 0L); - -#endif /* ANGBAND_LITE_MAC */ - - /* Activate the window */ - activate(td->w); - - /* Erase behind words */ - TextMode(srcCopy); - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize the window */ - term_data_resize(td); - -#ifdef ANGBAND_LITE_MAC - - /* Prepare the colors (base colors) */ - BackColor(blackColor); - ForeColor(whiteColor); - -#else /* ANGBAND_LITE_MAC */ - - /* Prepare the colors (real colors) */ - RGBBackColor(&black); - RGBForeColor(&white); - - /* Block */ - { - Rect tempRect; - Rect globalRect; - GDHandle mainGDH; - GDHandle currentGDH; - GWorldPtr windowGWorld; - PixMapHandle basePixMap; - - /* Obtain the rect */ - tempRect = td->w->portRect; - - /* Obtain the global rect */ - globalRect = tempRect; - LocalToGlobal((Point*)&globalRect.top); - LocalToGlobal((Point*)&globalRect.bottom); - - /* Obtain the proper GDH */ - mainGDH = GetMaxDevice(&globalRect); - - /* Extract GWorld and GDH */ - GetGWorld(&windowGWorld, ¤tGDH); - - /* Obtain base pixmap */ - basePixMap = (**mainGDH).gdPMap; - - /* Save pixel depth */ - td->pixelDepth = (**basePixMap).pixelSize; - - /* Save Window GWorld */ - td->theGWorld = windowGWorld; - - /* Save Window GDH */ - td->theGDH = currentGDH; - - /* Save main GDH */ - td->mainSWGDH = mainGDH; - } - -#endif /* ANGBAND_LITE_MAC */ - - /* Clip to the window */ - ClipRect(&td->w->portRect); - - /* Erase the window */ - EraseRect(&td->w->portRect); - - /* Invalidate the window */ - InvalRect(&td->w->portRect); - - /* Display the window if needed */ - if (td->mapped) ShowWindow(td->w); - - /* Hack -- set "mapped" flag */ - t->mapped_flag = td->mapped; - - /* Forget color */ - td->last = -1; -} - - - -/* - * Nuke an old Term - */ -static void Term_nuke_mac(term *t) -{ - -#pragma unused (t) - - /* XXX */ -} - - - -/* - * Unused - */ -static errr Term_user_mac(int n) -{ - -#pragma unused (n) - - /* Success */ - return (0); -} - - - -/* - * React to changes - */ -static errr Term_xtra_mac_react(void) -{ - term_data *td = (term_data*)(Term->data); - - int i; - - -#ifdef ANGBAND_LITE_MAC - - /* Nothing */ - -#else /* ANGBAND_LITE_MAC */ - - /* Reset color */ - td->last = -1; - - /* Update colors */ - for (i = 0; i < 256; i++) - { - u16b rv, gv, bv; - - /* Extract the R,G,B data */ - rv = angband_color_table[i][1]; - gv = angband_color_table[i][2]; - bv = angband_color_table[i][3]; - - /* Save the actual color */ - color_info[i].red = (rv | (rv << 8)); - color_info[i].green = (gv | (gv << 8)); - color_info[i].blue = (bv | (bv << 8)); - } - - /* Handle sound */ - if (use_sound != arg_sound) - { - /* Apply request */ - use_sound = arg_sound; - } - - /* Handle graphics */ - if (graf_mode_req != graf_mode) - { - /* dispose old GWorld's if present */ - globe_nuke(); - - /* Setup parameters according to request */ - switch (graf_mode_req) - { - /* ASCII - no graphics whatsoever */ - case GRAF_MODE_NONE: - { -#ifndef ZANGBAND - use_graphics = arg_graphics = FALSE; -#else -use_graphics = arg_graphics = GRAPHICS_NONE; -#endif /* !ZANGBAND */ - transparency_mode = TR_NONE; - break; - } - - /* - * 8x8 tiles (PICT id 1001) - * no transparency effect - * "old" graphics definitions - */ - case GRAF_MODE_8X8: - { -#ifndef ZANGBAND - use_graphics = arg_graphics = TRUE; - ANGBAND_GRAF = "old"; -#else - use_graphics = arg_graphics = GRAPHICS_ORIGINAL; -#endif /* !ZANGBAND */ - pictID = 1001; - transparency_mode = TR_NONE; - grafWidth = grafHeight = 8; - break; - } - - /* - * 16x16 tiles (images: PICT id 1002) - * with transparency effect - * "new" graphics definitions - */ - case GRAF_MODE_16X16: - { -#ifndef ZANGBAND - use_graphics = arg_graphics = TRUE; - ANGBAND_GRAF = "new"; -#else - use_graphics = arg_graphics = GRAPHICS_ADAM_BOLT; -#endif /* !ZANGBAND */ - pictID = 1002; - transparency_mode = TR_OVER; - grafWidth = grafHeight = 16; - break; - } - -#if 0 /* Good Lord! It doesn't work... Is it too large? */ - - /* - * 32x32 tiles (images: PICT id 1004) - * no transparency effect - * "david" graphics definitions - */ - case GRAF_MODE_32X32: - { - use_graphics = arg_graphics = TRUE; - ANGBAND_GRAF = "david"; - pictID = 1004; - transparency_mode = TR_OVER; - grafWidth = grafHeight = 32; - break; - } - -#endif /* sigh */ - } - - /* load tiles and setup GWorlds if tiles are requested */ - if ((graf_mode_req != GRAF_MODE_NONE) && (globe_init() != 0)) - { - /* Oops */ - plog("Cannot initialize graphics!"); - - /* reject request */ - graf_mode_req = GRAF_MODE_NONE; - - /* reset graphics flags */ - use_graphics = arg_graphics = FALSE; - - /* reset transparency mode */ - transparency_mode = TR_NONE; - } - - /* update current graphics mode */ - graf_mode = graf_mode_req; - - /* Apply and Verify */ - term_data_check_size(td); - - /* Resize the window */ - term_data_resize(td); - - /* Reset visuals */ -#ifndef ANG281_RESET_VISUALS - reset_visuals(TRUE); -#else -reset_visuals(); -#endif /* !ANG281_RESET_VISUALS */ - } - -#endif /* ANGBAND_LITE_MAC */ - - /* Success */ - return (0); -} - - -/* - * Do a "special thing" - */ -static errr Term_xtra_mac(int n, int v) -{ - term_data *td = (term_data*)(Term->data); - - Rect r; - - /* Analyze */ - switch (n) - { - /* Make a noise */ - case TERM_XTRA_NOISE: - { - /* Make a noise */ - SysBeep(1); - - /* Success */ - return (0); - } - -#ifdef ANGBAND_LITE_MAC - - /* Nothing */ - -#else /* ANGBAND_LITE_MAC */ - - /* Make a sound */ - case TERM_XTRA_SOUND: - { -#ifndef USE_ASYNC_SOUND - - /* - * This may not be your choice, but much safer and much less - * resource hungry. Existing implementations can quite easily - * crash, by starting asynchronous playing and immediately - * unlocking and releasing the sound data just started playing... - * -- pelpel - */ - Handle handle; - Str255 sound; - - /* Get the proper sound name */ - strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[v]); - sound[0] = strlen((char*)sound + 1); - - /* Obtain resource XXX XXX XXX */ - handle = GetNamedResource('snd ', sound); - - /* Oops -- it is a failure, but we return 0 anyway */ - if (handle == NULL) return (0); - - /* Load and Lock */ - LoadResource(handle); - HLock(handle); - - /* Play sound (wait for completion) */ - SndPlay(nil, (SndListHandle)handle, false); - - /* Unlock and release */ - HUnlock(handle); - ReleaseResource(handle); - -#else /* !USE_ASYNC_SOUND */ - - /* If you really want async player, please try this one */ - play_sound(v, sound_volume); - -#endif /* !USE_ASYNC_SOUND */ - - /* Success */ - return (0); - } - -#endif /* ANGBAND_LITE_MAC */ - - /* Process random events */ - case TERM_XTRA_BORED: - { - /* Process an event */ - (void)CheckEvents(FALSE); - - /* Success */ - return (0); - } - - /* Process pending events */ - case TERM_XTRA_EVENT: - { - /* Process an event */ - (void)CheckEvents(v); - - /* Success */ - return (0); - } - - /* Flush all pending events (if any) */ - case TERM_XTRA_FLUSH: - { - /* Hack -- flush all events */ - while (CheckEvents(TRUE)) /* loop */; - - /* Success */ - return (0); - } - - /* Hack -- Change the "soft level" */ - case TERM_XTRA_LEVEL: - { - /* Activate if requested */ - if (v) activate(td->w); - - /* Success */ - return (0); - } - - /* Clear the screen */ - case TERM_XTRA_CLEAR: - { - /* No clipping XXX XXX XXX */ - ClipRect(&td->w->portRect); - - /* Erase the window */ - EraseRect(&td->w->portRect); - - /* Set the color */ - term_data_color(td, TERM_WHITE); - - /* Frame the window in white */ - MoveTo(0, 0); - LineTo(0, td->size_hgt - 1); - LineTo(td->size_wid - 1, td->size_hgt - 1); - LineTo(td->size_wid - 1, 0); - - /* Clip to the new size */ - r.left = td->w->portRect.left + td->size_ow1; - r.top = td->w->portRect.top + td->size_oh1; - r.right = td->w->portRect.right - td->size_ow2; - r.bottom = td->w->portRect.bottom - td->size_oh2; - ClipRect(&r); - - /* Success */ - return (0); - } - - /* React to changes */ - case TERM_XTRA_REACT: - { - /* React to changes */ - return (Term_xtra_mac_react()); - } - - /* Delay (milliseconds) */ - case TERM_XTRA_DELAY: - { - /* If needed */ - if (v > 0) - { - long m = TickCount() + (v * 60L) / 1000; - - /* Wait for it */ - while (TickCount() < m) /* loop */; - } - - /* Success */ - return (0); - } - - /* Rename main window */ - case TERM_XTRA_RENAME_MAIN_WIN: - { - char *s = strdup(angband_term_name[0]); - - ctopstr((StringPtr)s); - SetWTitle(data[0].w, (StringPtr)s); - - free(s); - return (0); - } - } - - /* Oops */ - return (1); -} - - - -/* - * Low level graphics (Assumes valid input). - * Draw a "cursor" at (x,y), using a "yellow box". - * We are allowed to use "Term_what()" to determine - * the current screen contents (for inverting, etc). - */ -static errr Term_curs_mac(int x, int y) -{ - Rect r; - - term_data *td = (term_data*)(Term->data); - - /* Set the color */ - term_data_color(td, TERM_YELLOW); - - /* Frame the grid */ - r.left = x * td->tile_wid + td->size_ow1; - r.right = r.left + td->tile_wid; - r.top = y * td->tile_hgt + td->size_oh1; - r.bottom = r.top + td->tile_hgt; - -#ifdef USE_DOUBLE_TILES - - /* Mogami's double width tile patch */ - if (use_bigtile && - (x + 1 < Term->wid) && - (Term->old->a[y][x + 1] == 255)) - { - r.right += td->tile_wid; - } - -#endif /* USE_DOUBLE_TILES */ - - FrameRect(&r); - - /* Success */ - return (0); -} - - -/* - * Low level graphics (Assumes valid input) - * - * Erase "n" characters starting at (x,y) - */ -static errr Term_wipe_mac(int x, int y, int n) -{ - Rect r; - - term_data *td = (term_data*)(Term->data); - - /* Erase the block of characters */ - r.left = x * td->tile_wid + td->size_ow1; - r.right = r.left + n * td->tile_wid; - r.top = y * td->tile_hgt + td->size_oh1; - r.bottom = r.top + td->tile_hgt; - EraseRect(&r); - - /* Success */ - return (0); -} - - -/* - * Low level graphics. Assumes valid input. - * - * Draw several ("n") chars, with an attr, at a given location. - */ -static errr Term_text_mac(int x, int y, int n, byte a, const char *cp) -{ - int xp, yp; - - term_data *td = (term_data*)(Term->data); - - /* Set the color */ - term_data_color(td, a); - - /* Starting pixel */ - xp = x * td->tile_wid + td->tile_o_x + td->size_ow1; - yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1; - - /* Move to the correct location */ - MoveTo(xp, yp); - - /* Draw the character */ - if (n == 1) DrawChar(*cp); - - /* Draw the string */ - else DrawText(cp, 0, n); - - /* Success */ - return (0); -} - - -/* - * Low level graphics (Assumes valid input) - * - * Erase "n" characters starting at (x,y) - */ -#ifdef USE_TRANSPARENCY -# ifdef USE_EGO_GRAPHICS -static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp, - const byte *tap, const char *tcp, - const byte *eap, const char *ecp) -# else /* USE_EGO_GRAPHICS */ -static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp, - const byte *tap, const char *tcp) -# endif /* USE_EGO_GRAPHICS */ -#else /* USE_TRANSPARENCY */ -static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp) -#endif /* USE_TRANSPARENCY */ -{ - int i; - Rect dst_r; - static RGBColor black = {0x0000, 0x0000, 0x0000}; - static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF}; - term_data *td = (term_data*)(Term->data); - - /* Destination rectangle */ - dst_r.left = x * td->tile_wid + td->size_ow1; -#ifndef USE_DOUBLE_TILES - dst_r.right = dst_r.left + td->tile_wid; -#endif /* !USE_DOUBLE_TILES */ - dst_r.top = y * td->tile_hgt + td->size_oh1; - dst_r.bottom = dst_r.top + td->tile_hgt; - - /* Scan the input */ - for (i = 0; i < n; i++) - { - byte a = *ap++; - char c = *cp++; - -#ifdef USE_TRANSPARENCY - byte ta = *tap++; - char tc = *tcp++; -# ifdef USE_EGO_GRAPHICS - byte ea = *eap++; - char ec = *ecp++; - bool has_overlay = (ea && ec); -# endif /* USE_EGO_GRAPHICS */ -#endif /* USE_TRANSPARENCY */ - -#ifdef USE_DOUBLE_TILES - - /* Second byte of bigtile */ - if (use_bigtile && (a == 255)) - { - /* Advance */ - dst_r.left += td->tile_wid; - - /* Ignore it */ - continue; - } - - /* Prepare right side of rectangle */ - dst_r.right = dst_r.left + td->tile_wid; - -#endif /* USE_DOUBLE_TILES */ - -#ifdef ANGBAND_LITE_MAC - - /* Nothing */ - -#else /* ANGBAND_LITE_MAC */ - - /* Graphics -- if Available and Needed */ - if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80)) - { -#ifdef USE_TRANSPARENCY - int t_col, t_row; - Rect terrain_r; -# ifdef USE_EGO_GRAPHICS - int e_col, e_row; - Rect ego_r; -# endif /* USE_EGO_GRAPHICS */ -#endif /* USE_TRANSPARENCY */ - - int col, row; - Rect src_r; - - /* Row and Col */ - row = ((byte)a & 0x7F) % pictRows; - col = ((byte)c & 0x7F) % pictCols; - - /* Source rectangle */ - src_r.left = col * grafWidth; - src_r.top = row * grafHeight; - src_r.right = src_r.left + grafWidth; - src_r.bottom = src_r.top + grafHeight; - -#ifdef USE_TRANSPARENCY - - /* Terrain Row and Col */ - t_row = ((byte)ta & 0x7F) % pictRows; - t_col = ((byte)tc & 0x7F) % pictCols; - - /* Terrain Source rectangle */ - terrain_r.left = t_col * grafWidth; - terrain_r.top = t_row * grafHeight; - terrain_r.right = terrain_r.left + grafWidth; - terrain_r.bottom = terrain_r.top + grafHeight; - -# ifdef USE_EGO_GRAPHICS - - /* If and only if there's overlay */ - if (has_overlay) - { - /* Overlay Row and Col */ - e_row = ((byte)ea & 0x7F) % pictRows; - e_col = ((byte)ec & 0x7F) % pictCols; - - /* Overlay Source rectangle */ - ego_r.left = e_col * grafWidth; - ego_r.top = e_row * grafHeight; - ego_r.right = ego_r.left + grafWidth; - ego_r.bottom = ego_r.top + grafHeight; - } - -# endif /* USE_EGO_GRAPHICS */ - -#endif /* USE_TRANSPARENCY */ - - /* Hardwire CopyBits */ - RGBBackColor(&white); - RGBForeColor(&black); - -#ifdef USE_DOUBLE_TILES - - /* Double width tiles */ - if (use_bigtile) dst_r.right += td->tile_wid; - -#endif /* USE_DOUBLE_TILES */ - -#ifdef USE_TRANSPARENCY - - /* Transparency effect */ - switch (transparency_mode) - { - /* No transparency effect */ - case TR_NONE: - default: - { - /* Draw the picture */ - CopyBits((BitMap*)frameP->framePix, - &(td->w->portBits), - &src_r, &dst_r, srcCopy, NULL); - - break; - } - - /* Overwriting with transparent black pixels */ - case TR_OVER: - { - /* Draw the terrain */ - CopyBits((BitMap*)frameP->framePix, - &(td->w->portBits), - &terrain_r, &dst_r, srcCopy, NULL); - - /* Make black pixels transparent */ - RGBBackColor(&black); - - /* Draw mon/obj if there's one */ - if ((row != t_row) || (col != t_col)) - CopyBits((BitMap*)frameP->framePix, - &(td->w->portBits), - &src_r, &dst_r, transparent, NULL); - -# ifdef USE_EGO_GRAPHICS - - /* Draw overlay if there's one */ - if (has_overlay) - CopyBits((BitMap*)frameP->framePix, - &(td->w->portBits), - &ego_r, &dst_r, transparent, NULL); - -# endif /* USE_EGO_GRAPHICS */ - - break; - } - } - -#else /* USE_TRANSPARENCY */ - -/* Draw the picture */ - CopyBits((BitMap*)frameP->framePix, - &(td->w->portBits), - &src_r, &dst_r, srcCopy, NULL); - -#endif /* USE_TRANSPARENCY */ - - /* Restore colors */ - RGBBackColor(&black); - RGBForeColor(&white); - - /* Forget color */ - td->last = -1; - } - -#endif /* ANGBAND_LITE_MAC */ - - /* Normal */ - else - { - int xp, yp; - - /* Erase */ - EraseRect(&dst_r); - - /* Set the color */ - term_data_color(td, a); - - /* Starting pixel */ - xp = dst_r.left + td->tile_o_x; - yp = dst_r.top + td->tile_o_y; - - /* Move to the correct location */ - MoveTo(xp, yp); - - /* Draw the character */ - DrawChar(c); - } - - /* Advance */ - dst_r.left += td->tile_wid; -#ifndef USE_DOUBLE_TILES - dst_r.right += td->tile_wid; -#endif /* USE_DOUBLE_TILES */ - } - - /* Success */ - return (0); -} - - - - - -/* - * Create and initialize window number "i" - */ -static void term_data_link(int i) -{ - term *old = Term; - - term_data *td = &data[i]; - - /* Only once */ - if (td->t) return; - - /* Require mapped */ - if (!td->mapped) return; - - /* Allocate */ - MAKE(td->t, term); - - /* Initialize the term */ - term_init(td->t, td->cols, td->rows, td->keys); - - /* Use a "software" cursor */ - td->t->soft_cursor = TRUE; - - /* Erase with "white space" */ - td->t->attr_blank = TERM_WHITE; - td->t->char_blank = ' '; - - /* Prepare the init/nuke hooks */ - td->t->init_hook = Term_init_mac; - td->t->nuke_hook = Term_nuke_mac; - - /* Prepare the function hooks */ - td->t->user_hook = Term_user_mac; - td->t->xtra_hook = Term_xtra_mac; - td->t->wipe_hook = Term_wipe_mac; - td->t->curs_hook = Term_curs_mac; - td->t->text_hook = Term_text_mac; - td->t->pict_hook = Term_pict_mac; - - /* Link the local structure */ - td->t->data = (void *)(td); - - /* Activate it */ - Term_activate(td->t); - - /* Global pointer */ - angband_term[i] = td->t; - - /* Activate old */ - Term_activate(old); -} - - - - -/* - * Set the "current working directory" (also known as the "default" - * volume/directory) to the location of the current application. - * - * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl) - * - * This function does not appear to work correctly with System 6. - */ -static void SetupAppDir(void) -{ - FCBPBRec fcbBlock; - OSErr err = noErr; - char errString[100]; - - /* Get the location of the Angband executable */ - fcbBlock.ioCompletion = NULL; - fcbBlock.ioNamePtr = NULL; - fcbBlock.ioVRefNum = 0; - fcbBlock.ioRefNum = CurResFile(); - fcbBlock.ioFCBIndx = 0; - err = PBGetFCBInfoSync(&fcbBlock); - if (err != noErr) - { - strnfmt(errString, 100, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err); - mac_warning(errString); - ExitToShell(); - } - - /* Extract the Vol and Dir */ - app_vol = fcbBlock.ioFCBVRefNum; - app_dir = fcbBlock.ioFCBParID; - - /* Set the current working directory to that location */ - err = HSetVol(NULL, app_vol, app_dir); - if (err != noErr) - { - strnfmt(errString, 100, "Fatal HSetVol Error #%d.\r Exiting.", err); - mac_warning(errString); - ExitToShell(); - } -} - - - - -/* - * Global "preference" file pointer - */ -static FILE *fff; - -/* - * Read a "short" from the file - */ -static int getshort(void) -{ - int x = 0; - char buf[256]; - if (0 == my_fgets(fff, buf, 256)) x = atoi(buf); - return (x); -} - -/* - * Dump a "short" to the file - */ -static void putshort(int x) -{ - fprintf(fff, "%d\n", x); -} - - - -/* - * Write the "preference" data to the current "file" - */ -static void save_prefs(void) -{ - int i; - - term_data *td; - - - /*** The current version ***/ - - putshort(PREF_VER_MAJOR); - putshort(PREF_VER_MINOR); - putshort(PREF_VER_PATCH); - putshort(PREF_VER_EXTRA); - - /* Gfx settings */ - putshort(arg_sound); - putshort(graf_mode); -#ifdef USE_DOUBLE_TILES - putshort(use_bigtile); -#endif /* USE_DOUBLE_TILES */ - - /* Dump */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Access */ - td = &data[i]; - - putshort(td->mapped); - - putshort(td->font_id); - putshort(td->font_size); - putshort(td->font_face); - - putshort(td->tile_wid); - putshort(td->tile_hgt); - - putshort(td->cols); - putshort(td->rows); - - putshort(td->r.left); - putshort(td->r.top); - } -} - - -/* - * Load the preferences from the current "file" - * - * XXX XXX XXX Being able to undefine various windows is - * slightly bizarre, and may cause problems. - */ -static void load_prefs(void) -{ - int i; - - int old_major, old_minor, old_patch, old_extra; - - term_data *td; - - - /*** Version information ***/ - - /* Preferences version */ - old_major = getshort(); - old_minor = getshort(); - old_patch = getshort(); - old_extra = getshort(); - - /* Hack -- Verify or ignore */ - if ((old_major != PREF_VER_MAJOR) || - (old_minor != PREF_VER_MINOR) || - (old_patch != PREF_VER_PATCH) || - (old_extra != PREF_VER_EXTRA)) - { - /* Message */ - mac_warning("Ignoring old preferences."); - - /* Ignore */ - return; - } - - /* Gfx mode */ - arg_sound = getshort(); - graf_mode_req = getshort(); -#ifdef USE_DOUBLE_TILES - use_bigtile = getshort(); -#endif /* USE_DOUBLE_TILES */ - - /* Windows */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Access */ - td = &data[i]; - - td->mapped = getshort(); - - td->font_id = getshort(); - td->font_size = getshort(); - td->font_face = getshort(); - - td->tile_wid = getshort(); - td->tile_hgt = getshort(); - - td->cols = getshort(); - td->rows = getshort(); - - td->r.left = getshort(); - td->r.top = getshort(); - - /* Done */ - if (feof(fff)) break; - } -} - - - - -/* - * Hack -- default data for a window - */ -static void term_data_hack(term_data *td) -{ - short fid; - - /* Default to Monaco font */ - GetFNum("\pmonaco", &fid); - - /* Wipe it */ - WIPE(td, term_data); - - /* No color */ - td->last = -1; - - /* Default borders */ - td->size_ow1 = 2; - td->size_ow2 = 2; - td->size_oh2 = 2; - - /* Start hidden */ - td->mapped = FALSE; - - /* Default font */ - td->font_id = fid; - - /* Default font size */ - td->font_size = 12; - - /* Default font face */ - td->font_face = 0; - - /* Default size */ - td->rows = 24; - td->cols = 80; - - /* Default position */ - td->r.left = 10; - td->r.top = 40; - - /* Minimal keys */ - td->keys = 16; -} - - -/* - * Read the preference file, Create the windows. - * - * We attempt to use "FindFolder()" to track down the preference file, - * but if this fails, for any reason, we will try the "SysEnvirons()" - * method, which may work better with System 6. - */ -static void init_windows(void) -{ - int i, b = 0; - - term_data *td; - - bool oops; - - - /*** Default values ***/ - - /* Initialize (backwards) */ - for (i = MAX_TERM_DATA; i-- > 0; ) - { - int n; - - cptr s; - - /* Obtain */ - td = &data[i]; - - /* Defaults */ - term_data_hack(td); - - /* Obtain title */ - s = angband_term_name[i]; - - /* Get length */ - n = strlen(s); - - /* Maximal length */ - if (n > 15) n = 15; - - /* Copy the title */ - strncpy((char*)(td->title) + 1, s, n); - - /* Save the length */ - td->title[0] = n; - - /* Tile the windows */ - td->r.left += (b * 30); - td->r.top += (b * 30); - - /* Tile */ - b++; - } - - - /*** Load preferences ***/ - - /* Assume failure */ - oops = TRUE; - - /* Assume failure */ - fff = NULL; - -#ifdef USE_SFL_CODE - - /* Block */ - if (TRUE) - { - OSErr err; - short vref; - long dirID; - char foo[128]; - - /* Find the folder */ - err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, - &vref, &dirID); - - /* Success */ - if (!err) - { - /* Extract a path name */ - PathNameFromDirID(dirID, vref, (StringPtr)foo); - - /* Convert the string */ - ptocstr((StringPtr)foo); - - /* Append the preference file name */ - strcat(foo, ANGBAND_PREFERENCES); - - /* Open the preference file */ - fff = fopen(foo, "r"); - - /* Success */ - oops = FALSE; - } - } - -#endif /* USE_SFL_CODE */ - -#if 0 /* SysEnvirons? SetVol? I'd say no */ - - /* Oops */ - if (oops) - { - SysEnvRec env; - short savev; - long saved; - - /* Save */ - HGetVol(0, &savev, &saved); - - /* Go to the "system" folder */ - SysEnvirons(curSysEnvVers, &env); - SetVol(0, env.sysVRefNum); - - /* Open the file */ - fff = fopen(":Preferences:" ANGBAND_PREFERENCES, "r"); - if (!fff) fff = fopen(":" ANGBAND_PREFERENCES, "r"); - - /* Restore */ - HSetVol(0, savev, saved); - } - -#endif /* relic */ - - /* Load preferences */ - if (fff) - { - /* Load a real preference file */ - load_prefs(); - - /* Close the file */ - my_fclose(fff); - } - - - /*** Instantiate ***/ - - /* Main window */ - td = &data[0]; - - /* Many keys */ - td->keys = 1024; - - /* Start visible */ - td->mapped = TRUE; - - /* Link (backwards, for stacking order) */ - for (i = MAX_TERM_DATA; i-- > 0; ) - { - term_data_link(i); - } - - /* Main window */ - td = &data[0]; - - /* Main window */ - Term_activate(td->t); -} - - -/* - * Exit the program - */ -static void save_pref_file(void) -{ - bool oops; - - - /* Assume failure */ - oops = TRUE; - - /* Assume failure */ - fff = NULL; - - /* Text file */ - _ftype = 'TEXT'; - - -#ifdef USE_SFL_CODE - - /* Block */ - if (TRUE) - { - OSErr err; - short vref; - long dirID; - char foo[128]; - - /* Find the folder */ - err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, - &vref, &dirID); - - /* Success */ - if (!err) - { - /* Extract a path name */ - PathNameFromDirID(dirID, vref, (StringPtr)foo); - - /* Convert the string */ - ptocstr((StringPtr)foo); - - /* Append the preference file name */ - strcat(foo, ANGBAND_PREFERENCES); - - /* Open the preference file */ - fff = fopen(foo, "w"); - - /* Success */ - oops = FALSE; - } - } - -#endif /* USE_SFL_CODE */ - -#if 0 /* I don't believe we need SysEnvirons any longer */ - - /* Oops */ - if (oops) - { - SysEnvRec env; - short savev; - long saved; - - /* Save */ - HGetVol(0, &savev, &saved); - - /* Go to "system" folder */ - SysEnvirons(curSysEnvVers, &env); - SetVol(0, env.sysVRefNum); - - /* Open the preference file */ - fff = fopen(":Preferences:" ANGBAND_PREFERENCES, "w"); - if (!fff) fff = fopen(":" ANGBAND_PREFERENCES, "w"); - - /* Restore */ - HSetVol(0, savev, saved); - } - -#endif /* relic */ - - /* Save preferences */ - if (fff) - { - /* Write the preferences */ - save_prefs(); - - /* Close it */ - my_fclose(fff); - } -} - - - -#ifdef ALLOW_NO_SAVE_QUITS - -/* - * A simple "Yes/No" filter to parse "key press" events in dialog windows - */ -static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip) -{ - /* Parse key press events */ - if (event->what == keyDown) - { - int i = 0; - char c; - - /* Extract the pressed key */ - c = (event->message & charCodeMask); - - /* Accept "no" and <return> and <enter> */ - if ((c == 'n') || (c == 'N') || (c == 13) || (c == 3)) i = 1; - - /* Accept "yes" */ - else if ((c == 'y') || (c == 'Y')) i = 2; - - /* Handle "yes" or "no" */ - if (i) - { - short type; - ControlHandle control; - Rect r; - - /* Get the button */ - GetDialogItem(dialog, i, &type, (Handle*)&control, &r); - - /* Blink button for 1/10 second */ - HiliteControl(control, 1); - Term_xtra_mac(TERM_XTRA_DELAY, 100); - HiliteControl(control, 0); - - /* Result */ - *ip = i; - return (1); - } - } - - /* Ignore */ - return (0); -} - -#endif /* ALLOW_NO_SAVE_QUITS */ - - - -#ifndef SAVEFILE_SCREEN - -/* - * Handle menu: "File" + "New" - */ -static void do_menu_file_new(void) -{ - /* Hack */ - HiliteMenu(0); - - /* Game is in progress */ - game_in_progress = 1; - - /* Flush input */ - Term_flush(); - - /* Play a game */ - play_game(TRUE); - - /* Hack -- quit */ - quit(NULL); -} - -/* - * Handle menu: "File" + "Open" - */ -static void do_menu_file_open(bool all) -{ - int err; - short vrefnum; - long drefnum; - long junk; - DirInfo pb; - SFTypeList types; - SFReply reply; - Point topleft; - - - /* XXX XXX XXX */ - - /* vrefnum = GetSFCurVol(); */ - vrefnum = -*((short*)0x214); - - /* drefnum = GetSFCurDir(); */ - drefnum = *((long*)0x398); - - /* Descend into "lib" folder */ - pb.ioCompletion = NULL; - pb.ioNamePtr = "\plib"; - pb.ioVRefNum = vrefnum; - pb.ioDrDirID = drefnum; - pb.ioFDirIndex = 0; - - /* Check for errors */ - err = PBGetCatInfoSync((CInfoPBPtr) & pb); - - /* Success */ - if ((err == noErr) && (pb.ioFlAttrib & 0x10)) - { - /* Descend into "lib/save" folder */ - pb.ioCompletion = NULL; - pb.ioNamePtr = "\psave"; - pb.ioVRefNum = vrefnum; - pb.ioDrDirID = pb.ioDrDirID; - pb.ioFDirIndex = 0; - - /* Check for errors */ - err = PBGetCatInfoSync((CInfoPBPtr) & pb); - - /* Success */ - if ((err == noErr) && (pb.ioFlAttrib & 0x10)) - { - /* SetSFCurDir(pb.ioDrDirID); */ - *((long*)0x398) = pb.ioDrDirID; - } - } - - /* Window location */ - topleft.h = (qd.screenBits.bounds.left + qd.screenBits.bounds.right) / 2 - 344 / 2; - topleft.v = (2 * qd.screenBits.bounds.top + qd.screenBits.bounds.bottom) / 3 - 188 / 2; - - /* Allow "all" files */ - if (all) - { - /* Get any file */ - SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply); - } - - /* Allow "save" files */ - else - { - /* Legal types */ - types[0] = 'SAVE'; - - /* Get a file */ - SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply); - } - - /* Allow cancel */ - if (!reply.good) return; - - /* Extract textual file name for save file */ - GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk); - refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName); - - /* Hack */ - HiliteMenu(0); - - /* Game is in progress */ - game_in_progress = 1; - - /* Flush input */ - flush(); - - /* Play a game */ - play_game(FALSE); - - /* Hack -- quit */ - quit(NULL); -} - -#endif /* !SAVEFILE_SCREEN */ - - -/* - * Handle the "open_when_ready" flag - */ -static void handle_open_when_ready(void) -{ - /* Check the flag XXX XXX XXX make a function for this */ - if (open_when_ready && initialized && !game_in_progress) - { - /* Forget */ - open_when_ready = FALSE; - - /* Game is in progress */ - game_in_progress = 1; - - /* Wait for it */ - pause_line(23); - - /* Flush input */ - flush(); - -#ifdef SAVEFILE_SCREEN - - /* User double-clicked savefile; no savefile screen */ - no_begin_screen = TRUE; - -#endif /* SAVEFILE_SCREEN */ - - /* Play a game */ - play_game(FALSE); - - /* Quit */ - quit(NULL); - } -} - - - -/* - * The standard menus are: - * - * Apple (128) = { About, -, ... } - * File (129) = { New,Open,Import,Close,Save,-,Score,Exit,Quit } - * In ToME, this becomes - * File (129) = { Close,Save,-,Score,Exit,Quit } - * Edit (130) = { Cut, Copy, Paste, Clear } (?) - * Font (131) = { Bold, Extend, -, Monaco, ..., -, ... } - * Size (132) = { ... } - * Window (133) = { Angband, Term-1/Mirror, Term-2/Recall, Term-3/Choice, - * Term-4, Term-5, Term-6, Term-7 } - * Special (134) = { Sound, Graphics, TileWidth, TileHeight, -, - * Fiddle, Wizard } - */ - -/* Apple menu */ -#define MENU_APPLE 128 -#define ITEM_ABOUT 1 - -/* File menu */ -#define MENU_FILE 129 -#ifndef SAVEFILE_SCREEN -# define ITEM_NEW 1 -# define ITEM_OPEN 2 -# define ITEM_IMPORT 3 -# define ITEM_CLOSE 4 -# define ITEM_SAVE 5 -# ifdef HAS_SCORE_MENU -# define ITEM_SCORE 7 -# define ITEM_EXIT 8 -# define ITEM_QUIT 9 -# else -# define ITEM_EXIT 7 -# define ITEM_QUIT 8 -# endif /* HAS_SCORE_MENU */ -#else /* !SAVEFILE_SCREEN - in-game savefile menu */ -# define ITEM_CLOSE 1 -# define ITEM_SAVE 2 -# ifdef HAS_SCORE_MENU -# define ITEM_SCORE 4 -# define ITEM_EXIT 5 -# define ITEM_QUIT 6 -# else -# define ITEM_EXIT 4 -# define ITEM_QUIT 5 -# endif /* HAS_SCORE_MENU */ -#endif /* !SAVEFILE_SCREEN */ - -/* Edit menu */ -#define MENU_EDIT 130 -#define ITEM_UNDO 1 -#define ITEM_CUT 3 -#define ITEM_COPY 4 -#define ITEM_PASTE 5 -#define ITEM_CLEAR 6 - -/* Font menu */ -#define MENU_FONT 131 -#define ITEM_BOLD 1 -#define ITEM_WIDE 2 - -/* Size menu */ -#define MENU_SIZE 132 - -/* Windows menu */ -#define MENU_WINDOWS 133 - -/* Special menu */ -#define MENU_SPECIAL 134 -#define ITEM_SOUND 1 -#define ITEM_GRAPH 2 -#define ITEM_TILEWIDTH 3 -#define ITEM_TILEHEIGHT 4 -#define ITEM_FIDDLE 6 -#define ITEM_WIZARD 7 - -/* Graphics submenu */ -#define SUBMENU_GRAPH 144 -#define ITEM_NONE 1 -#define ITEM_8X8 2 -#define ITEM_16X16 3 -#define ITEM_BIGTILE 5 - -/* TileWidth submenu */ -#define SUBMENU_TILEWIDTH 145 - -/* TileHeight submenu */ -#define SUBMENU_TILEHEIGHT 146 - - -/* - * Initialize the menus - */ -static void init_menubar(void) -{ - int i, n; - - Rect r; - - WindowPtr tmpw; - - MenuHandle m; - - Handle mbar; - - - /* Load menubar from resources */ - mbar = GetNewMBar(128); - - /* Whoops! */ - if (mbar == nil) quit("Cannot find menubar('MBAR') id 128!"); - - /* Insert them into the current menu list */ - SetMenuBar(mbar); - - /* Free handle */ - DisposeHandle(mbar); - - - /* Apple menu (id 128) */ - m = GetMenuHandle(MENU_APPLE); - - /* Add the DA's to the "apple" menu */ - AppendResMenu(m, 'DRVR'); - - - /* File menu (id 129) - we don't have to do anything */ - - - /* Edit menu (id 130) - we don't have to do anything */ - - - /* - * Font menu (id 131) - append names of mono-spaced fonts - * followed by all available ones - */ - m = GetMenuHandle(MENU_FONT); - - /* Fake window */ - r.left = r.right = r.top = r.bottom = 0; - - /* Make the fake window so that we can retrive font info */ - tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0); - - /* Activate the "fake" window */ - SetPort(tmpw); - - /* Default mode */ - TextMode(0); - - /* Default size */ - TextSize(12); - - /* Add the fonts to the menu */ - AppendResMenu(m, 'FONT'); - - /* Size of menu */ - n = CountMItems(m); - - /* Scan the menu */ - for (i = n; i >= 4; i--) - { - Str255 tmpName; - short fontNum; - - /* Acquire the font name */ - GetMenuItemText(m, i, tmpName); - - /* Acquire the font index */ - GetFNum(tmpName, &fontNum); - - /* Apply the font index */ - TextFont(fontNum); - - /* Remove non-mono-spaced fonts */ - if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0)) - { - /* Delete the menu item */ - DeleteMenuItem(m, i); - } - } - - /* Destroy the old window */ - DisposeWindow(tmpw); - - /* Add a separator */ - AppendMenu(m, "\p-"); - - /* Add the fonts to the menu */ - AppendResMenu(m, 'FONT'); - - - /* Size menu (id 132) */ - m = GetMenuHandle(MENU_SIZE); - - /* Add some sizes (stagger choices) */ - for (i = 8; i <= 32; i += ((i / 16) + 1)) - { - Str15 buf; - - /* Textual size */ - strnfmt((char*)buf + 1, 15, "%d", i); - buf[0] = strlen((char*)buf + 1); - - /* Add the item */ - AppendMenu(m, buf); - } - - - /* Windows menu (id 133) */ - m = GetMenuHandle(MENU_WINDOWS); - - /* Default choices */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - Str15 buf; - - /* Describe the item */ - strnfmt((char*)buf + 1, 15, "%.15s", angband_term_name[i]); - buf[0] = strlen((char*)buf + 1); - - /* Add the item */ - AppendMenu(m, buf); - - /* Command-Key shortcuts */ - if (i < 8) SetItemCmd(m, i + 1, I2D(i)); - } - - - /* Special menu (id 134) */ - - /* Get graphics (sub)menu (id 144) */ - m = GetMenu(SUBMENU_GRAPH); - - /* Insert it as a submenu */ - InsertMenu(m, hierMenu); - - - /* Get TileWidth (sub)menu (id 145) */ - m = GetMenu(SUBMENU_TILEWIDTH); - - /* Add some sizes */ - for (i = 4; i <= 32; i++) - { - Str15 buf; - - /* Textual size */ - strnfmt((char*)buf + 1, 15, "%d", i); - buf[0] = strlen((char*)buf + 1); - - /* Append item */ - AppendMenu(m, buf); - } - - /* Insert it as a submenu */ - InsertMenu(m, hierMenu); - - /* Get TileHeight (sub)menu (id 146) */ - m = GetMenu(SUBMENU_TILEHEIGHT); - - /* Add some sizes */ - for (i = 4; i <= 32; i++) - { - Str15 buf; - - /* Textual size */ - strnfmt((char*)buf + 1, 15, "%d", i); - buf[0] = strlen((char*)buf + 1); - - /* Append item */ - AppendMenu(m, buf); - } - - /* Insert it as a submenu */ - InsertMenu(m, hierMenu); - - - /* Update the menu bar */ - DrawMenuBar(); -} - - -/* - * Prepare the menus - * - * It is very important that the player not be allowed to "save" the game - * unless the "inkey_flag" variable is set, indicating that the game is - * waiting for a new command. XXX XXX XXX - */ -static void setup_menus(void) -{ - int i, n; - - short value; - - Str255 s; - - MenuHandle m; - - term_data *td = NULL; - - - /* Relevant "term_data" */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Unused */ - if (!data[i].t) continue; - - /* Notice the matching window */ - if (data[i].w == FrontWindow()) td = &data[i]; - } - - - /* File menu */ - m = GetMenuHandle(MENU_FILE); - - /* Get menu size */ - n = CountMItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableItem(m, i); - CheckItem(m, i, FALSE); - } - -#ifndef SAVEFILE_SCREEN - - /* Enable "new"/"open..."/"import..." */ - if (initialized && !game_in_progress) - { - EnableItem(m, ITEM_NEW); - EnableItem(m, ITEM_OPEN); - EnableItem(m, ITEM_IMPORT); - } - -#endif /* !SAVEFILE_SCREEN */ - - /* Enable "close" */ - if (initialized) - { - EnableItem(m, ITEM_CLOSE); - } - - /* Enable "save" */ - if (initialized && character_generated && inkey_flag) - { - EnableItem(m, ITEM_SAVE); - } - -#ifdef HAS_SCORE_MENU - - /* Enable "score" */ - if (initialized && character_generated && !character_icky) - { - EnableItem(m, ITEM_SCORE); - } - -#endif /* HAS_SCORE_MENU */ - -#ifdef ALLOW_NO_SAVE_QUITS - - /* Enable "exit" */ - if (TRUE) - { - EnableItem(m, ITEM_EXIT); - } - -#endif /* ALLOW_NO_SAVE_QUITS */ - - /* Enable "quit" */ - if (!initialized || !character_generated || inkey_flag) - { - EnableItem(m, ITEM_QUIT); - } - - - /* Edit menu */ - m = GetMenuHandle(MENU_EDIT); - - /* Get menu size */ - n = CountMItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableItem(m, i); - CheckItem(m, i, FALSE); - } - - /* Enable "edit" options if "needed" */ - if (!td) - { - EnableItem(m, ITEM_UNDO); - EnableItem(m, ITEM_CUT); - EnableItem(m, ITEM_COPY); - EnableItem(m, ITEM_PASTE); - EnableItem(m, ITEM_CLEAR); - } - - - /* Font menu */ - m = GetMenuHandle(MENU_FONT); - - /* Get menu size */ - n = CountMItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableItem(m, i); - CheckItem(m, i, FALSE); - } - - /* Hack -- look cute XXX XXX */ - /* SetItemStyle(m, ITEM_BOLD, bold); */ - - /* Hack -- look cute XXX XXX */ - /* SetItemStyle(m, ITEM_WIDE, extend); */ - - /* Active window */ - if (initialized && td) - { - /* Enable "bold" */ - EnableItem(m, ITEM_BOLD); - - /* Enable "extend" */ - EnableItem(m, ITEM_WIDE); - - /* Check the appropriate "bold-ness" */ - if (td->font_face & bold) CheckItem(m, ITEM_BOLD, TRUE); - - /* Check the appropriate "wide-ness" */ - if (td->font_face & extend) CheckItem(m, ITEM_WIDE, TRUE); - - /* Analyze fonts */ - for (i = 4; i <= n; i++) - { - /* Enable it */ - EnableItem(m, i); - - /* Analyze font */ - GetMenuItemText(m, i, s); - GetFNum(s, &value); - - /* Check active font */ - if (td->font_id == value) CheckItem(m, i, TRUE); - } - } - - - /* Size menu */ - m = GetMenuHandle(MENU_SIZE); - - /* Get menu size */ - n = CountMItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableItem(m, i); - CheckItem(m, i, FALSE); - } - - /* Active window */ - if (initialized && td) - { - /* Analyze sizes */ - for (i = 1; i <= n; i++) - { - /* Analyze size */ - GetMenuItemText(m, i, s); - s[s[0] + 1] = '\0'; - value = atoi((char*)(s + 1)); - - /* Enable the "real" sizes */ - if (RealFont(td->font_id, value)) EnableItem(m, i); - - /* Check the current size */ - if (td->font_size == value) CheckItem(m, i, TRUE); - } - } - - - /* Windows menu */ - m = GetMenuHandle(MENU_WINDOWS); - - /* Get menu size */ - n = CountMItems(m); - - /* Check active windows */ - for (i = 1; i <= n; i++) - { - /* Check if needed */ - CheckItem(m, i, data[i - 1].mapped); - } - - - /* Special menu */ - m = GetMenuHandle(MENU_SPECIAL); - - /* Get menu size */ - n = CountMItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableItem(m, i); - - /* XXX Oh no, this removes submenu... */ - if ((i != ITEM_GRAPH) && - (i != ITEM_TILEWIDTH) && - (i != ITEM_TILEHEIGHT)) CheckItem(m, i, FALSE); - } - - /* Item "Sound" */ - EnableItem(m, ITEM_SOUND); - CheckItem(m, ITEM_SOUND, arg_sound); - - /* Item "Graphics" */ - EnableItem(m, ITEM_GRAPH); - - /* Item "TileWidth" */ - EnableItem(m, ITEM_TILEWIDTH); - - /* Item "TileHeight" */ - EnableItem(m, ITEM_TILEHEIGHT); - - /* Item "Fiddle" */ - EnableItem(m, ITEM_FIDDLE); - CheckItem(m, ITEM_FIDDLE, arg_fiddle); - - /* Item "Wizard" */ - EnableItem(m, ITEM_WIZARD); - CheckItem(m, ITEM_WIZARD, arg_wizard); - - /* Graphics submenu */ - m = GetMenuHandle(SUBMENU_GRAPH); - - /* Get menu size */ - n = CountMItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableItem(m, i); - CheckItem(m, i, FALSE); - } - - /* Item "None" */ - EnableItem(m, ITEM_NONE); - CheckItem(m, ITEM_NONE, (graf_mode == GRAF_MODE_NONE)); - - /* Item "8x8" */ - EnableItem(m, ITEM_8X8); - CheckItem(m, ITEM_8X8, (graf_mode == GRAF_MODE_8X8)); - - /* Item "16x16" */ - EnableItem(m, ITEM_16X16); - CheckItem(m, ITEM_16X16, (graf_mode == GRAF_MODE_16X16)); - -#ifdef USE_DOUBLE_TILES - - /* Item "Bigtile" */ - if (inkey_flag) EnableItem(m, ITEM_BIGTILE); - CheckItem(m, ITEM_BIGTILE, use_bigtile); - -#endif /* USE_DOUBLE_TILES */ - - - /* TIleWidth submenu */ - m = GetMenuHandle(SUBMENU_TILEWIDTH); - - /* Get menu size */ - n = CountMItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableItem(m, i); - CheckItem(m, i, FALSE); - } - - /* Active window */ - if (initialized && td) - { - /* Analyze sizes */ - for (i = 1; i <= n; i++) - { - /* Analyze size */ - GetMenuItemText(m, i, s); - s[s[0] + 1] = '\0'; - value = atoi((char*)(s + 1)); - - /* Enable */ - if (value >= td->font_wid) EnableItem(m, i); - - /* Check the current size */ - if (td->tile_wid == value) CheckItem(m, i, TRUE); - } - } - - - /* TileHeight submenu */ - m = GetMenuHandle(SUBMENU_TILEHEIGHT); - - /* Get menu size */ - n = CountMItems(m); - - /* Reset menu */ - for (i = 1; i <= n; i++) - { - /* Reset */ - DisableItem(m, i); - CheckItem(m, i, FALSE); - } - - /* Active window */ - if (initialized && td) - { - /* Analyze sizes */ - for (i = 1; i <= n; i++) - { - /* Analyze size */ - GetMenuItemText(m, i, s); - s[s[0] + 1] = '\0'; - value = atoi((char*)(s + 1)); - - /* Enable */ - if (value >= td->font_hgt) EnableItem(m, i); - - /* Check the current size */ - if (td->tile_hgt == value) CheckItem(m, i, TRUE); - } - } -} - - -/* - * Process a menu selection (see above) - * - * Hack -- assume that invalid menu selections are disabled above, - * which I have been informed may not be reliable. XXX XXX XXX - */ -static void menu(long mc) -{ - int i; - - int menuid, selection; - - static unsigned char s[1000]; - - short fid; - - term_data *td = NULL; - - WindowPtr old_win; - - - /* Analyze the menu command */ - menuid = HiWord(mc); - selection = LoWord(mc); - - - /* Find the window */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Skip dead windows */ - if (!data[i].t) continue; - - /* Notice matches */ - if (data[i].w == FrontWindow()) td = &data[i]; - } - - - /* Branch on the menu */ - switch (menuid) - { - /* Apple Menu */ - case MENU_APPLE: - { - /* About Angband... */ - if (selection == ITEM_ABOUT) - { - DialogPtr dialog; - Rect r; - short item_hit; - - dialog = GetNewDialog(128, 0, (WindowPtr) - 1); - - r = dialog->portRect; - center_rect(&r, &qd.screenBits.bounds); - MoveWindow(dialog, r.left, r.top, 1); - ShowWindow(dialog); - ModalDialog(0, &item_hit); - DisposeDialog(dialog); - break; - } - - /* Desk accessory */ - GetMenuItemText(GetMenuHandle(MENU_APPLE), selection, s); - OpenDeskAcc(s); - break; - } - - - /* File Menu */ - case MENU_FILE: - { - switch (selection) - { -#ifndef SAVEFILE_SCREEN - - /* New */ - case ITEM_NEW: - { - do_menu_file_new(); - break; - } - - /* Open... */ - case ITEM_OPEN: - { - do_menu_file_open(FALSE); - break; - } - - /* Import... */ - case ITEM_IMPORT: - { - do_menu_file_open(TRUE); - break; - } - -#endif /* !SAVEFILE_SCREEN */ - - /* Close */ - case ITEM_CLOSE: - { - /* No window */ - if (!td) break; - - /* Not Mapped */ - td->mapped = FALSE; - - /* Not Mapped */ - td->t->mapped_flag = FALSE; - - /* Hide the window */ - HideWindow(td->w); - - break; - } - - /* Save */ - case ITEM_SAVE: - { - /* Hack -- Forget messages */ - msg_flag = FALSE; - - /* Hack -- Save the game */ -#ifndef ZANG_AUTO_SAVE - do_cmd_save_game(); -#else -do_cmd_save_game(FALSE); -#endif /* !ZANG_AUTO_SAVE */ - - break; - } - -#ifdef HAS_SCORE_MENU - - /* Show score */ - case ITEM_SCORE: - { - char buf[1024]; - - /* Paranoia */ - if (!initialized || character_icky || - !game_in_progress || !character_generated) - { - /* Can't happen but just in case */ - plog("You may not do that right now."); - - break; - } - - /* Build the pathname of the score file */ - path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, - "scores.raw"); - - /* Hack - open the score file for reading */ - highscore_fd = fd_open(buf, O_RDONLY); - - /* Paranoia - No score file */ - if (highscore_fd < 0) - { - msg_print("Score file is not available."); - - break; - } - - /* Mega-Hack - prevent various functions XXX XXX XXX */ - initialized = FALSE; - - /* Save screen */ - screen_save(); - - /* Clear screen */ - Term_clear(); - - /* Prepare scores */ - if (game_in_progress && character_generated) - { - predict_score(); - } - -#if 0 /* I don't like this - pelpel */ - - /* Mega-Hack - No current player XXX XXX XXX XXX */ - else - { - display_scores_aux(0, MAX_HISCORES, -1, NULL); - } - -#endif - - /* Close the high score file */ - (void)fd_close(highscore_fd); - - /* Forget the fd */ - highscore_fd = -1; - - /* Restore screen */ - screen_load(); - - /* Hack - Flush it */ - Term_fresh(); - - /* Mega-Hack - We are ready again */ - initialized = TRUE; - - /* Done */ - break; - } - -#endif /* HAS_SCORE_MENU */ - -#ifdef ALLOW_NO_SAVE_QUITS - - /* Exit (without save) */ - case ITEM_EXIT: - { - /* Allow user to cancel "dangerous" exit */ - if (game_in_progress && character_generated) - { - AlertTHndl alert; - short item_hit; - - /* Get the "alert" info */ - alert = (AlertTHndl)GetResource('ALRT', 130); - - /* Center the "alert" rectangle */ - center_rect(&(*alert)->boundsRect, - &qd.screenBits.bounds); - - /* Display the Alert, get "No" or "Yes" */ - item_hit = Alert(130, ynfilterUPP); - - /* Require "yes" button */ - if (item_hit != 2) break; - } - - /* Quit */ - quit(NULL); - break; - } - -#endif /* ALLOW_NO_SAVE_QUITS */ - - /* Quit (with save) */ - case ITEM_QUIT: - { - /* Save the game (if necessary) */ - if (game_in_progress && character_generated) - { - /* Hack -- Forget messages */ - msg_flag = FALSE; - - /* Save the game */ -#ifndef ZANG_AUTO_SAVE - do_cmd_save_game(); -#else - do_cmd_save_game(FALSE); -#endif /* !ZANG_AUTO_SAVE */ - } - - /* Quit */ - quit(NULL); - break; - } - } - - break; - } - - - /* Edit menu */ - case MENU_EDIT: - { - /* Unused */ - break; - } - - - /* Font menu */ - case MENU_FONT: - { - /* Require a window */ - if (!td) break; - - /* Memorize old */ - old_win = active; - - /* Activate */ - activate(td->w); - - /* Toggle the "bold" setting */ - if (selection == ITEM_BOLD) - { - /* Toggle the setting */ - if (td->font_face & bold) - { - td->font_face &= ~bold; - } - else - { - td->font_face |= bold; - } - - /* Hack - clear tile size info XXX XXX */ - td->tile_wid = td->tile_hgt = 0; - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - break; - } - - /* Toggle the "wide" setting */ - if (selection == ITEM_WIDE) - { - /* Toggle the setting */ - if (td->font_face & extend) - { - td->font_face &= ~extend; - } - else - { - td->font_face |= extend; - } - - /* Hack - clear tile size info XXX XXX */ - td->tile_wid = td->tile_hgt = 0; - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - break; - } - - /* Get a new font name */ - GetMenuItemText(GetMenuHandle(MENU_FONT), selection, s); - GetFNum(s, &fid); - - /* Save the new font id */ - td->font_id = fid; - - /* Current size is bad for new font */ - if (!RealFont(td->font_id, td->font_size)) - { - /* Find similar size */ - for (i = 1; i <= 32; i++) - { - /* Adjust smaller */ - if (td->font_size - i >= 8) - { - if (RealFont(td->font_id, td->font_size - i)) - { - td->font_size -= i; - break; - } - } - - /* Adjust larger */ - if (td->font_size + i <= 128) - { - if (RealFont(td->font_id, td->font_size + i)) - { - td->font_size += i; - break; - } - } - } - } - - /* Hack - clear tile size info XXX XXX */ - td->tile_wid = td->tile_hgt = 0; - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore the window */ - activate(old_win); - - break; - } - - /* Size menu */ - case MENU_SIZE: - { - if (!td) break; - - /* Save old */ - old_win = active; - - /* Activate */ - activate(td->w); - - GetMenuItemText(GetMenuHandle(MENU_SIZE), selection, s); - s[s[0] + 1] = 0; - td->font_size = atoi((char*)(s + 1)); - - /* Hack - clear tile size info XXX XXX */ - td->tile_wid = td->tile_hgt = 0; - - /* Apply and Verify */ - term_data_check_font(td); - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore */ - activate(old_win); - - break; - } - - /* Window menu */ - case MENU_WINDOWS: - { - /* Parse */ - i = selection - 1; - - /* Check legality of choice */ - if ((i < 0) || (i >= MAX_TERM_DATA)) break; - - /* Obtain the window */ - td = &data[i]; - - /* Mapped */ - td->mapped = TRUE; - - /* Link */ - term_data_link(i); - - /* Mapped (?) */ - td->t->mapped_flag = TRUE; - - /* Show the window */ - ShowWindow(td->w); - - /* Bring to the front */ - SelectWindow(td->w); - - break; - } - - /* Special menu */ - case MENU_SPECIAL: - { - switch (selection) - { - case ITEM_SOUND: - { - /* Toggle arg_sound */ - arg_sound = !arg_sound; - - /* React to changes */ - Term_xtra(TERM_XTRA_REACT, 0); - - break; - } - - case ITEM_FIDDLE: - { - arg_fiddle = !arg_fiddle; - break; - } - - case ITEM_WIZARD: - { - arg_wizard = !arg_wizard; - break; - } - } - - break; - } - - - /* Graphics submenu */ - case SUBMENU_GRAPH: - { - switch (selection) - { - case ITEM_NONE: - { - graf_mode_req = GRAF_MODE_NONE; - - break; - } - - case ITEM_8X8: - { - graf_mode_req = GRAF_MODE_8X8; - - break; - } - - case ITEM_16X16: - { - graf_mode_req = GRAF_MODE_16X16; - - break; - } - -#ifdef USE_DOUBLE_TILES - - case ITEM_BIGTILE: - { - term *old = Term; - term_data *td = &data[0]; - - /* Toggle "arg_bigtile" */ - use_bigtile = !use_bigtile; -# ifdef TOME - arg_bigtile = use_bigtile; -# endif /* TOME */ - - /* Activate */ - Term_activate(td->t); - - /* Resize the term */ - Term_resize(td->cols, td->rows); - - /* Activate old */ - Term_activate(old); - - break; - } - -#endif /* USE_DOUBLE_TILES */ - - } - - /* Hack -- Force redraw */ - Term_key_push(KTRL('R')); - - break; - } - - - /* TileWidth submenu */ - case SUBMENU_TILEWIDTH: - { - if (!td) break; - - /* Save old */ - old_win = active; - - /* Activate */ - activate(td->w); - - GetMenuItemText(GetMenuHandle(SUBMENU_TILEWIDTH), selection, s); - s[s[0] + 1] = 0; - td->tile_wid = atoi((char*)(s + 1)); - - /* Apply and Verify */ - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore */ - activate(old_win); - - break; - } - - - /* TileHeight submenu */ - case SUBMENU_TILEHEIGHT: - { - if (!td) break; - - /* Save old */ - old_win = active; - - /* Activate */ - activate(td->w); - - GetMenuItemText(GetMenuHandle(SUBMENU_TILEHEIGHT), selection, s); - s[s[0] + 1] = 0; - td->tile_hgt = atoi((char*)(s + 1)); - - /* Apply and Verify */ - term_data_check_size(td); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore */ - activate(old_win); - - break; - } - } - - - /* Clean the menu */ - HiliteMenu(0); -} - - -#ifdef USE_SFL_CODE - - -/* - * Check for extra required parameters -- From "Maarten Hazewinkel" - */ -static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent) -{ - OSErr aeError; - DescType returnedType; - Size actualSize; - - aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard, - &returnedType, NULL, 0, &actualSize); - - if (aeError == errAEDescNotFound) return (noErr); - - if (aeError == noErr) return (errAEParamMissed); - - return (aeError); -} - - -/* - * Apple Event Handler -- Open Application - */ -static OSErr AEH_Start(const AppleEvent *theAppleEvent, - AppleEvent *reply, long handlerRefCon) -{ -#pragma unused(reply, handlerRefCon) - - return (CheckRequiredAEParams(theAppleEvent)); -} - - -/* - * Apple Event Handler -- Quit Application - */ -static OSErr AEH_Quit(const AppleEvent *theAppleEvent, - AppleEvent *reply, long handlerRefCon) -{ -#pragma unused(reply, handlerRefCon) - - /* Quit later */ - quit_when_ready = TRUE; - - /* Check arguments */ - return (CheckRequiredAEParams(theAppleEvent)); -} - - -/* - * Apple Event Handler -- Print Documents - */ -static OSErr AEH_Print(const AppleEvent *theAppleEvent, - AppleEvent *reply, long handlerRefCon) -{ -#pragma unused(theAppleEvent, reply, handlerRefCon) - - return (errAEEventNotHandled); -} - - -/* - * Apple Event Handler by Steve Linberg (slinberg@crocker.com). - * - * The old method of opening savefiles from the finder does not work - * on the Power Macintosh, because CountAppFiles and GetAppFiles, - * used to return information about the selected document files when - * an application is launched, are part of the Segment Loader, which - * is not present in the RISC OS due to the new memory architecture. - * - * The "correct" way to do this is with AppleEvents. The following - * code is modeled on the "Getting Files Selected from the Finder" - * snippet from Think Reference 2.0. (The prior sentence could read - * "shamelessly swiped & hacked") - */ -static OSErr AEH_Open(AppleEvent *theAppleEvent, - AppleEvent* reply, long handlerRefCon) -{ -#pragma unused(reply, handlerRefCon) - - FSSpec myFSS; - AEDescList docList; - OSErr err; - Size actualSize; - AEKeyword keywd; - DescType returnedType; - char msg[128]; - FInfo myFileInfo; - - /* Put the direct parameter (a descriptor list) into a docList */ - err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList); - if (err) return err; - - /* - * We ignore the validity check, because we trust the FInder, and we only - * allow one savefile to be opened, so we ignore the depth of the list. - */ - - err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd, - &returnedType, (Ptr) & myFSS, sizeof(myFSS), &actualSize); - if (err) return err; - - /* Only needed to check savefile type below */ - err = FSpGetFInfo(&myFSS, &myFileInfo); - if (err) - { - strnfmt(msg, 128, "Argh! FSpGetFInfo failed with code %d", err); - mac_warning(msg); - return err; - } - - /* Ignore non 'SAVE' files */ - if (myFileInfo.fdType != 'SAVE') return noErr; - - /* XXX XXX XXX Extract a file name */ - PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile); - pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name); - - /* Convert the string */ - ptocstr((StringPtr)savefile); - - /* Delay actual open */ - open_when_ready = TRUE; - - /* Dispose */ - err = AEDisposeDesc(&docList); - - /* Success */ - return noErr; -} - - -#endif - - - -/* - * Macintosh modifiers (event.modifier & ccc): - * cmdKey, optionKey, shiftKey, alphaLock, controlKey - * - * - * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra): - * - * Return:36 - * Delete:51 - * - * Period:65 - * Star:67 - * Plus:69 - * Clear:71 - * Slash:75 - * Enter:76 - * Minus:78 - * Equal:81 - * 0-7:82-89 - * 8-9:91-92 - * - * backslash/vertical bar (Japanese keyboard):93 - * - * F5: 96 - * F6: 97 - * F7: 98 - * F3:99 - * F8:100 - * F10:101 - * F11:103 - * F13:105 - * F14:107 - * F9:109 - * F12:111 - * F15:113 - * Help:114 - * Home:115 - * PgUp:116 - * Del:117 - * F4: 118 - * End:119 - * F2:120 - * PgDn:121 - * F1:122 - * Lt:123 - * Rt:124 - * Dn:125 - * Up:126 - */ - - -/* - * Optimize non-blocking calls to "CheckEvents()" - * Idea from "Maarten Hazewinkel <mmhazewi@cs.ruu.nl>" - */ -#define EVENT_TICKS 6 - - -/* - * Check for Events, return TRUE if we process any - * - * Hack -- Handle AppleEvents if appropriate (ignore result code). - */ -static bool CheckEvents(bool wait) -{ - EventRecord event; - - WindowPtr w; - - Rect r; - - long newsize; - - int ch, ck; - - int mc, ms, mo, mx; - - int i; - - term_data *td = NULL; - - UInt32 curTicks; - - static UInt32 lastTicks = 0L; - - - /* Access the clock */ - curTicks = TickCount(); - - /* Hack -- Allow efficient checking for non-pending events */ - if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE); - - /* Timestamp last check */ - lastTicks = curTicks; - - /* Let the "system" run */ - SystemTask(); - - /* Get an event (or null) */ - WaitNextEvent(everyEvent, &event, 0L, nil); - - /* Hack -- Nothing is ready yet */ - if (event.what == nullEvent) return (FALSE); - - - /* Analyze the event */ - switch (event.what) - { - -#if 0 - - case activateEvt: - { - w = (WindowPtr)event.message; - - activate(w); - - break; - } - -#endif - - case updateEvt: - { - /* Extract the window */ - w = (WindowPtr)event.message; - - /* Find the window */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Skip dead windows */ - if (!data[i].t) continue; - - /* Notice matches */ - if (data[i].w == w) td = &data[i]; - } - - /* Hack XXX XXX XXX */ - BeginUpdate(w); - EndUpdate(w); - - /* Redraw the window */ - if (td) term_data_redraw(td); - - break; - } - - case keyDown: - case autoKey: - { - /* Extract some modifiers */ - mc = (event.modifiers & controlKey) ? TRUE : FALSE; - ms = (event.modifiers & shiftKey) ? TRUE : FALSE; - mo = (event.modifiers & optionKey) ? TRUE : FALSE; - mx = (event.modifiers & cmdKey) ? TRUE : FALSE; - - /* Keypress: (only "valid" if ck < 96) */ - ch = (event.message & charCodeMask) & 255; - - /* Keycode: see table above */ - ck = ((event.message & keyCodeMask) >> 8) & 255; - - /* Command + "normal key" -> menu action */ - if (mx && (ck < 64)) - { - /* Hack -- Prepare the menus */ - setup_menus(); - - /* Mega-Hack -- allow easy exit if nothing to save */ - /* if (!character_generated && (ch=='Q' || ch=='q')) ch = 'e'; */ - - /* Run the Menu-Handler */ - menu(MenuKey(ch)); - - /* Turn off the menus */ - HiliteMenu(0); - - /* Done */ - break; - } - - - /* Hide the mouse pointer */ - ObscureCursor(); - - /* Normal key -> simple keypress */ - if ((ck < 64) || (ck == 93)) - { - /* Enqueue the keypress */ - Term_keypress(ch); - } - - /* Keypad keys -> trigger plus simple keypress */ - else if (!mc && !ms && !mo && !mx && (ck < 96)) - { - /* Hack -- "enter" is confused */ - if (ck == 76) ch = '\n'; - - /* Begin special trigger */ - Term_keypress(31); - - /* Send the "keypad" modifier */ - Term_keypress('K'); - - /* Send the "ascii" keypress */ - Term_keypress(ch); - - /* Terminate the trigger */ - Term_keypress(13); - } - - /* Bizarre key -> encoded keypress */ - else if (ck <= 127) - { - /* Begin special trigger */ - Term_keypress(31); - - /* Send some modifier keys */ - if (mc) Term_keypress('C'); - if (ms) Term_keypress('S'); - if (mo) Term_keypress('O'); - if (mx) Term_keypress('X'); - - /* Downshift and encode the keycode */ - Term_keypress(I2D((ck - 64) / 10)); - Term_keypress(I2D((ck - 64) % 10)); - - /* Terminate the trigger */ - Term_keypress(13); - } - - break; - } - - case mouseDown: - { - int code; - - /* Analyze click location */ - code = FindWindow(event.where, &w); - - /* Find the window */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Skip dead windows */ - if (!data[i].t) continue; - - /* Notice matches */ - if (data[i].w == w) td = &data[i]; - } - - /* Analyze */ - switch (code) - { - case inMenuBar: - { - setup_menus(); - menu(MenuSelect(event.where)); - HiliteMenu(0); - break; - } - - case inSysWindow: - { - SystemClick(&event, w); - break; - } - - case inDrag: - { - Point p; - - WindowPtr old_win; - - r = qd.screenBits.bounds; - r.top += 20; /* GetMBarHeight() XXX XXX XXX */ - InsetRect(&r, 4, 4); - DragWindow(w, event.where, &r); - - /* Oops */ - if (!td) break; - - /* Save */ - old_win = active; - - /* Activate */ - activate(td->w); - - /* Analyze */ - p.h = td->w->portRect.left; - p.v = td->w->portRect.top; - LocalToGlobal(&p); - td->r.left = p.h; - td->r.top = p.v; - - /* Restore */ - activate(old_win); - - /* Apply and Verify */ - term_data_check_size(td); - - break; - } - - case inGoAway: - { - /* Oops */ - if (!td) break; - - /* Track the go-away box */ - if (TrackGoAway(w, event.where)) - { - /* Not Mapped */ - td->mapped = FALSE; - - /* Not Mapped */ - td->t->mapped_flag = FALSE; - - /* Hide the window */ - HideWindow(td->w); - } - - break; - } - - case inGrow: - { - int x, y; - - term *old = Term; - - /* Oops */ - if (!td) break; - -#ifndef ALLOW_BIG_SCREEN - - /* Fake rectangle */ - r.left = 20 * td->tile_wid + td->size_ow1; - r.right = 80 * td->tile_wid + td->size_ow1 + td->size_ow2 + 1; - r.top = 1 * td->tile_hgt + td->size_oh1; - r.bottom = 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1; - -#else /* ALLOW_BIG_SCREEN */ - - /* Fake rectangle */ - r.left = 20 * td->tile_wid + td->size_ow1; - r.right = qd.screenBits.bounds.right; - r.top = 1 * td->tile_hgt + td->size_oh1; - r.bottom = qd.screenBits.bounds.bottom; - -#endif /* ALLOW_BIG_SCREEN */ - - /* Grow the rectangle */ - newsize = GrowWindow(w, event.where, &r); - - /* Handle abort */ - if (!newsize) break; - - /* Extract the new size in pixels */ - y = HiWord(newsize) - td->size_oh1 - td->size_oh2; - x = LoWord(newsize) - td->size_ow1 - td->size_ow2; - - /* Extract a "close" approximation */ - td->rows = y / td->tile_hgt; - td->cols = x / td->tile_wid; - - /* Apply and Verify */ - term_data_check_size(td); - - /* Activate */ - Term_activate(td->t); - - /* Hack -- Resize the term */ - Term_resize(td->cols, td->rows); - - /* Resize and Redraw */ - term_data_resize(td); - term_data_redraw(td); - - /* Restore */ - Term_activate(old); - - break; - } - - case inContent: - { - SelectWindow(w); - - break; - } - } - - break; - } - - /* Disk Event -- From "Maarten Hazewinkel" */ - case diskEvt: - { - /* check for error when mounting the disk */ - if (HiWord(event.message) != noErr) - { - Point p = - {120, 120}; - - DILoad(); - DIBadMount(p, event.message); - DIUnload(); - } - - break; - } - - /* OS Event -- From "Maarten Hazewinkel" */ - case osEvt: - { - switch ((event.message >> 24) & 0x000000FF) - { - case suspendResumeMessage: - - /* Resuming: activate the front window */ - if (event.message & resumeFlag) - { - SetPort(FrontWindow()); - SetCursor(&qd.arrow); - } - - /* Suspend: deactivate the front window */ - else - { - /* Nothing */ - } - - break; - } - - break; - } - -#ifdef USE_SFL_CODE - - /* From "Steve Linberg" and "Maarten Hazewinkel" */ - case kHighLevelEvent: - { - /* Process apple events */ - if (AEProcessAppleEvent(&event) != noErr) - { - plog("Error in Apple Event Handler!"); - } - - /* Handle "quit_when_ready" */ - if (quit_when_ready) - { - /* Forget */ - quit_when_ready = FALSE; - - /* Do the menu key */ - menu(MenuKey('q')); - - /* Turn off the menus */ - HiliteMenu(0); - } - - /* Handle "open_when_ready" */ - handle_open_when_ready(); - - break; - } - -#endif - - } - - - /* Something happened */ - return (TRUE); -} - - - - -/*** Some Hooks for various routines ***/ - - -/* - * Mega-Hack -- emergency lifeboat - */ -static void *lifeboat = NULL; - - -/* - * Hook to "release" memory - */ -#ifdef NEW_ZVIRT_HOOKS /* [V] removed the unused 'size' argument. */ -static void *hook_rnfree(void *v) -#else -static void *hook_rnfree(void *v, size_t size) -#endif /* NEW_ZVIRT_HOOKS */ -{ - -#ifndef NEW_ZVIRT_HOOKS /* Oh, no. */ -#pragma unused (size) -#endif - -#ifdef USE_MALLOC - - /* Alternative method */ - free(v); - -#else - - /* Dispose */ - DisposePtr(v); - -#endif - - /* Success */ - return (NULL); -} - -/* - * Hook to "allocate" memory - */ -static void *hook_ralloc(size_t size) -{ - -#ifdef USE_MALLOC - - /* Make a new pointer */ - return (malloc(size)); - -#else - - /* Make a new pointer */ - return (NewPtr(size)); - -#endif - -} - -/* - * Hook to handle "out of memory" errors - */ -static void *hook_rpanic(size_t size) -{ - -#pragma unused (size) - - /* void *mem = NULL; */ - - /* Free the lifeboat */ - if (lifeboat) - { - /* Free the lifeboat */ - DisposePtr(lifeboat); - - /* Forget the lifeboat */ - lifeboat = NULL; - - /* Mega-Hack -- Warning */ - mac_warning("Running out of Memory!\rAbort this process now!"); - - /* Mega-Hack -- Never leave this function */ - while (TRUE) CheckEvents(TRUE); - } - - /* Mega-Hack -- Crash */ - return (NULL); -} - - -/* - * Hook to tell the user something important - */ -static void hook_plog(cptr str) -{ - /* Warning message */ - mac_warning(str); -} - - -/* - * Hook to tell the user something, and then quit - */ -static void hook_quit(cptr str) -{ - /* Warning if needed */ - if (str) mac_warning(str); - -#ifdef USE_ASYNC_SOUND - - /* Cleanup sound player */ - cleanup_sound(); - -#endif /* USE_ASYNC_SOUND */ - - /* Dispose of graphic tiles */ - if (frameP) - { - /* Unlock */ - BenSWUnlockFrame(frameP); - - /* Dispose of the GWorld */ - DisposeGWorld(frameP->framePort); - - /* Dispose of the memory */ - DisposePtr((Ptr)frameP); - } - - /* Write a preference file */ - save_pref_file(); - - /* All done */ - ExitToShell(); -} - - -/* - * Hook to tell the user something, and then crash - */ -static void hook_core(cptr str) -{ - /* XXX Use the debugger */ - /* DebugStr(str); */ - - /* Warning */ - if (str) mac_warning(str); - - /* Warn, then save player */ - mac_warning("Fatal error.\rI will now attempt to save and quit."); - - /* Attempt to save */ - if (!save_player()) mac_warning("Warning -- save failed!"); - - /* Quit */ - quit(NULL); -} - - - -/*** Main program ***/ - - -/* - * Init some stuff - * - * XXX XXX XXX Hack -- This function attempts to "fix" the nasty - * "Macintosh Save Bug" by using "absolute" path names, since on - * System 7 machines anyway, the "current working directory" often - * "changes" due to background processes, invalidating any "relative" - * path names. Note that the Macintosh is limited to 255 character - * path names, so be careful about deeply embedded directories... - * - * XXX XXX XXX Hack -- This function attempts to "fix" the nasty - * "missing lib folder bug" by allowing the user to help find the - * "lib" folder by hand if the "application folder" code fails... - */ -static void init_stuff(void) -{ - int i; - - short vrefnum; - long drefnum; - long junk; - - SFTypeList types; - SFReply reply; - - Rect r; - Point topleft; - - char path[1024]; - - - /* Fake rectangle */ - r.left = 0; - r.top = 0; - r.right = 344; - r.bottom = 188; - - /* Center it */ - center_rect(&r, &qd.screenBits.bounds); - - /* Extract corner */ - topleft.v = r.top; - topleft.h = r.left; - - - /* Default to the "lib" folder with the application */ - refnum_to_name(path, app_dir, app_vol, (char*)("\plib:")); - - - /* Check until done */ - while (1) - { - /* Prepare the paths */ - init_file_paths(path); - - /* Build the filename */ - path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt"); - - /* Attempt to open and close that file */ - if (0 == fd_close(fd_open(path, O_RDONLY))) break; - - /* Warning */ - plog_fmt("Unable to open the '%s' file.", path); - - /* Warning */ - plog("The Angband 'lib' folder is probably missing or misplaced."); - - /* Warning */ - plog("Please 'open' any file in any sub-folder of the 'lib' folder."); - - /* Allow "text" files */ - types[0] = 'TEXT'; - - /* Allow "save" files */ - types[1] = 'SAVE'; - - /* Allow "data" files */ - types[2] = 'DATA'; - - /* Get any file */ - SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply); - - /* Allow cancel */ - if (!reply.good) quit(NULL); - - /* Extract textual file name for given file */ - GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk); - refnum_to_name(path, drefnum, vrefnum, (char*)reply.fName); - - /* Hack -- Remove the "filename" */ - i = strlen(path) - 1; - while ((i > 0) && (path[i] != ':')) i--; - if (path[i] == ':') path[i + 1] = '\0'; - - /* Hack -- allow "lib" folders */ - if (suffix(path, "lib:")) continue; - - /* Hack -- Remove the "sub-folder" */ - i = i - 1; - while ((i > 1) && (path[i] != ':')) i--; - if (path[i] == ':') path[i + 1] = '\0'; - } -} - - -/* - * Macintosh Main loop - */ -int main(void) -{ - int i; - - EventRecord tempEvent; - int numberOfMasters = 10; - - /* Increase stack space by 64K */ - SetApplLimit(GetApplLimit() - 65536L); - - /* Stretch out the heap to full size */ - MaxApplZone(); - - /* Get more Masters */ - while (numberOfMasters--) MoreMasters(); - - /* Set up the Macintosh */ - InitGraf(&qd.thePort); - InitFonts(); - InitWindows(); - InitMenus(); - /* TEInit(); */ - InitDialogs(NULL); - InitCursor(); - - /* Flush events */ - FlushEvents(everyEvent, 0); - - /* Flush events some more (?) */ - if (EventAvail(everyEvent, &tempEvent)) FlushEvents(everyEvent, 0); - - -#ifdef ANGBAND_LITE_MAC - - /* Nothing */ - -#else /* ANGBAND_LITE_MAC */ - -# if defined(powerc) || defined(__powerc) - - /* Assume System 7 */ - - /* Assume Color Quickdraw */ - -# else - - /* Block */ - if (TRUE) - { - OSErr err; - long versionNumber; - - /* Check the Gestalt */ - err = Gestalt(gestaltSystemVersion, &versionNumber); - - /* Check the version */ - if ((err != noErr) || (versionNumber < 0x0700)) - { - quit("You must have System 7 to use this program."); - } - } - - /* Block */ - if (TRUE) - { - SysEnvRec env; - - /* Check the environs */ - if (SysEnvirons(1, &env) != noErr) - { - quit("The SysEnvirons call failed!"); - } - - /* Check for System Seven Stuff */ - if (env.systemVersion < 0x0700) - { - quit("You must have System 7 to use this program."); - } - - /* Check for Color Quickdraw */ - if (!env.hasColorQD) - { - quit("You must have Color Quickdraw to use this program."); - } - } - -# endif - -#endif /* ANGBAND_LITE_MAC */ - - -#ifdef USE_SFL_CODE - - /* Obtain a "Universal Procedure Pointer" */ - AEH_Start_UPP = NewAEEventHandlerProc(AEH_Start); - - /* Install the hook (ignore error codes) */ - AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, AEH_Start_UPP, - 0L, FALSE); - - /* Obtain a "Universal Procedure Pointer" */ - AEH_Quit_UPP = NewAEEventHandlerProc(AEH_Quit); - - /* Install the hook (ignore error codes) */ - AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, AEH_Quit_UPP, - 0L, FALSE); - - /* Obtain a "Universal Procedure Pointer" */ - AEH_Print_UPP = NewAEEventHandlerProc(AEH_Print); - - /* Install the hook (ignore error codes) */ - AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, AEH_Print_UPP, - 0L, FALSE); - - /* Obtain a "Universal Procedure Pointer" */ - AEH_Open_UPP = NewAEEventHandlerProc(AEH_Open); - - /* Install the hook (ignore error codes) */ - AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, AEH_Open_UPP, - 0L, FALSE); - -#endif - - - /* Find the current application */ - SetupAppDir(); - - - /* Mark ourself as the file creator */ - _fcreator = ANGBAND_CREATOR; - - /* Default to saving a "text" file */ - _ftype = 'TEXT'; - - -#if defined(ALLOW_NO_SAVE_QUITS) && defined(__MWERKS__) - - /* Obtian a "Universal Procedure Pointer" */ - ynfilterUPP = NewModalFilterProc(ynfilter); - -#endif /* ALLOW_NO_SAVE_QUITS && __MWERKS__ */ - - - /* Hook in some "z-virt.c" hooks */ - rnfree_aux = hook_rnfree; - ralloc_aux = hook_ralloc; - rpanic_aux = hook_rpanic; - - /* Hooks in some "z-util.c" hooks */ - plog_aux = hook_plog; - quit_aux = hook_quit; - core_aux = hook_core; - - - /* Initialize colors */ - for (i = 0; i < 256; i++) - { - u16b rv, gv, bv; - - /* Extract the R,G,B data */ - rv = angband_color_table[i][1]; - gv = angband_color_table[i][2]; - bv = angband_color_table[i][3]; - - /* Save the actual color */ - color_info[i].red = (rv | (rv << 8)); - color_info[i].green = (gv | (gv << 8)); - color_info[i].blue = (bv | (bv << 8)); - } - - - /* Show the "watch" cursor */ - SetCursor(*(GetCursor(watchCursor))); - - /* Prepare the menubar */ - init_menubar(); - - /* Prepare the windows */ - init_windows(); - - /* Hack -- process all events */ - while (CheckEvents(TRUE)) /* loop */; - - /* Reset the cursor */ - SetCursor(&qd.arrow); - - - /* Mega-Hack -- Allocate a "lifeboat" */ - lifeboat = NewPtr(16384); - - /* Note the "system" */ - ANGBAND_SYS = "mac"; - - - /* Initialize */ - init_stuff(); - - /* Initialize */ - init_angband(); - - - /* Hack -- process all events */ - while (CheckEvents(TRUE)) /* loop */; - - - /* We are now initialized */ - initialized = TRUE; - - - /* Handle "open_when_ready" */ - handle_open_when_ready(); - -#ifndef SAVEFILE_SCREEN - - /* Prompt the user */ - /* In [Z], it's currently prtf(17, 23, <msg>); */ - prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15); - - /* Flush the prompt */ - Term_fresh(); - - /* Hack -- Process Events Forever */ - while (TRUE) CheckEvents(TRUE); - -#else - - /* Game is in progress */ - game_in_progress = 1; - - /* Wait for keypress */ - pause_line(23); - - /* flush input - Warning: without this, _system_ would hang */ - flush(); - - /* Play the game - note the value of the argument */ - play_game(FALSE); - - /* Quit */ - quit(NULL); - -#endif /* !SAVEFILE_SCREEN */ -} - -#endif /* MACINTOSH */ diff --git a/src/main-ros.c b/src/main-ros.c deleted file mode 100644 index 124505d2..00000000 --- a/src/main-ros.c +++ /dev/null @@ -1,8670 +0,0 @@ -/* - * File: main-ros.c - * - * Abstract: Support for RISC OS versions of Angband, including support - * for multitasking and dynamic areas. - * - * Authors: Musus Umbra, Andrew Sidwell, Ben Harrison, and others. - * - * Licences: Angband licence. - */ - -#ifdef __riscos - -#include "angband.h" - -/* - * Purpose: Support for RISC OS Angband 2.9.x onwards (and variants) - * - * NB: This code is still under continuous development - if you want to use - * it for your own compilation/variant, please contact me so that I can - * keep you up to date and give you support :) - * - * Prerequisites to compiling: - * - * DeskLib 2.30 or later (earlier versions may be OK though) - * - * An ANSI C compiler (tested with Acorn's C/C++ and GCC, but should be OK - * with any decent compiler) - * - * My binary distribution (for the templates and other bits) - * - * Note: - * The following symbols are *required* and *must* be defined properly. - */ - -/* - * VARIANT & VERSION - * These two get variant and version data from Angband itself; older - * variants may not have these defined and will have to be altered. - */ -#define VARIANT "ToME" -#define VERSION "2.2.2" - -/* - * PORTVERSION - * This is the port version; it appears in the infobox. - */ -#define PORTVERSION "1.29-dev (2003-08-06)" - -/* - * RISCOS_VARIANT - * This must match the entry in the !Variant Obey file, and it must only - * contain characters that are valid as part of a RISC OS path variable. - * [eg. "Yin-Yangband" is not okay, "EyAngband" is.] - */ -#define RISCOS_VARIANT "ToME" - -/* - * AUTHORS - * For the info box. [eg. "Ben Harrison"] - */ -#define AUTHORS "DarkGod & co." - -/* - * PORTERS - * For the info box. [eg. "Musus Umbra"] - */ -#define PORTERS "A. Sidwell" - -/* - * ICONNAME - * Iconbar icon sprite name eg. "!angband". Note that this must be a valid - * sprite name; it may need modifying for long variant names. - */ -#define ICONNAME "!"RISCOS_VARIANT - -/* - * PDEADCHK - * This should expand to an expression that is true if the player is dead. - * [eg. (p_ptr->is_dead) for Angband or (!alive || dead) for some Zangbands] - */ - -#define PDEADCHK (!alive) - -/* - * The following symbols control the (optional) file-cache: - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * NB: Variants that don't repeatedly read any files whilst running - * (eg. vanilla, sang, etc) should NOT define USE_FILECACHE, etc. as - * it causes a non-negligable amount of code to be compiled in. - * - * NB: The file-cache functions require that some code in files.c is modified - * to use the cached_* functions. This should be utterly trivial. - * - * NB: The returned handle from cached_fopen() is almost certainly *NOT* - * a |FILE*| (although it may be if the cache cannot accomodate the file). - * - * Therefore, you *MUST* ensure that any file opened with cached_fopen() - * is only ever accessed via cached_fgets() and cached_fclose(). - * - * Failure to do so will result in, ahem, unpleasantness. Extreme - * unpleasantness. "Him fall down, go boom." - * - * This /may/ change in the near future (ie. to apply caching in a - * transparent manner), so do keep a backup of files.c (and any other files - * you modify). You always keep backups anyway, don't you? Don't you?! - */ - -/* - * USE_FILECACHE - * if defined then some caching functions will be compiled for use by the - * various get_rnd_line(), etc. in files.c. This could be used in a - * variety of places that read data repeatedly, but it's up to you to - * implement it then. - */ - -/* #define USE_FILECACHE */ - -/* - * SMART_FILECACHE - * This causes lines beginning with '#' (and blank lines) to be discarded - * when caching files. This should help Zangband 2.2.5+ but could cause - * trouble for other variants. If defined, then smart file caching will be - * on by default. - */ - -/* #define SMART_FILECACHE */ - -/* - * ABBR_FILECACHE - * ABBR_FILECACHE causes data read into file-cache to be compressed (using a - * simple set of abbreviations) by default. This can be overridden using a - * command line option. If this symbol is not defined then no compression - * code will be compiled and the user option will be ignored/unavailable. - */ - -/* #define ABBR_FILECACHE */ - -/* - * Note: - * The following symbols control debugging information. - */ - -/* - * FE_DEBUG_INFO - * If defined, some functions will be compiled to display some info. on the - * state of the front-end (accessible) from the '!' user menu. - * - * NB: For actual releases you should NOT define this symbol since it causes - * a non-negligable amount of code/data to be sucked in. - */ -/* #define FE_DEBUG_INFO */ - -/* - * USE_DA - * If defined, it enables the use of dynamic areas (these are still only - * used when the !Variant file allows it). It is likely that this option - * will eventually be removed altogether as there is no major advantege - * to using DAs over just using the Wimpslot. - */ -#define USE_DA - - -/* Constants, etc. ---------------------------------------------------------*/ - -/* Deal with any weird file-caching symbols */ -#ifndef USE_FILECACHE -# undef ABBR_FILECACHE -# undef SMART_FILECACHE -#endif - -/* Maximum terminals */ -#define MAX_TERM_DATA 8 - -/* Menu entry numbers */ -#define IBAR_MENU_INFO 0 -#define IBAR_MENU_SAVE 1 -#define IBAR_MENU_FULLSCREEN 2 -#define IBAR_MENU_GAMMA 3 -#define IBAR_MENU_SOUND 4 -#define IBAR_MENU_WINDOWS 5 -#define IBAR_MENU_SAVECHOICES 6 -#define IBAR_MENU_QUIT 7 - -#define TERM_MENU_INFO 0 -#define TERM_MENU_SAVE 1 -#define TERM_MENU_FONT 2 -#define TERM_MENU_WINDOWS 3 - -/* Icon numbers */ -#define SND_VOL_SLIDER 0 -#define SND_VOL_DOWN 1 -#define SND_VOL_UP 2 -#define SND_ENABLE 3 - -#define GAMMA_ICN 0 -#define GAMMA_DOWN 1 -#define GAMMA_UP 2 - -#define SAVE_ICON 2 -#define SAVE_PATH 1 -#define SAVE_OK 0 -#define SAVE_CANCEL 3 - -/* Position and size of the colours strip in the gamma window */ -#define GC_XOFF 20 -#define GC_YOFF -14 -#define GC_WIDTH 512 -#define GC_HEIGHT 72 - -/* Maximum and minimum allowed volume levels */ -#define SOUND_VOL_MIN 16 -#define SOUND_VOL_MAX 176 - -/*--------------------------------------------------------------------------*/ - - -#undef rename -#undef remove - -#include "Desklib:Event.h" -#include "Desklib:EventMsg.h" -#include "Desklib:Template.h" -#include "Desklib:Window.h" -#include "Desklib:Handler.h" -#include "Desklib:Screen.h" -#include "Desklib:Menu.h" -#include "Desklib:Msgs.h" -#include "Desklib:Icon.h" -#include "Desklib:Resource.h" -#include "Desklib:SWI.h" -#include "Desklib:Time.h" -#include "Desklib:Sound.h" -#include "Desklib:KeyCodes.h" -#include "Desklib:Kbd.h" -#include "Desklib:GFX.h" -#include "Desklib:ColourTran.h" -#include "Desklib:Error.h" -#include "Desklib:Coord.h" -#include "Desklib:Slider.h" -#include "Desklib:Hourglass.h" -#include "Desklib:Save.h" -#include "Desklib:Sprite.h" -#include "Desklib:KernelSWIs.h" -#include "DeskLib:Filing.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <signal.h> -#include <stdarg.h> -#include <time.h> -#include <math.h> - -/*--------------------------------------------------------------------------*/ - -/* - | We use the hourglass around calls to Wimp_Poll in an attempt to stop - | users thinking that the game has 'hung'. - | Kamband/Zangband and the Borg in particular can have quite long delays at - | times. - */ -#define Start_Hourglass \ - { if ( use_glass && !glass_on ) { glass_on=1; Hourglass_Start(50); } } -#define Stop_Hourglass \ - { if ( glass_on ) { glass_on=0; Hourglass_Off(); } } - - -/*--------------------------------------------------------------------------*/ -/* Types */ -/*--------------------------------------------------------------------------*/ - -/* - | A ZapRedraw block - */ -typedef struct -{ - union - { - unsigned int value; - struct - { - unsigned int vdu:1; - unsigned int double_height:1; - unsigned int extension:1; - unsigned int padding:29; - } - bits; - } - r_flags; - - int r_minx; /* min x of redraw in pixels from LHS, incl */ - int r_miny; /* min y of redraw in pixels from top, incl */ - int r_maxx; /* max x of redraw in pixels from LHS, excl */ - int r_maxy; /* max y of redraw in pixels from top, excl */ - - void *r_screen; /* DSA: address of screen to write to (0=>read) */ - int r_bpl; /* DSA: bytes per raster line */ - - int r_bpp; /* log base 2 of bits per pixel */ - int r_charw; /* width of a character in pixels */ - int r_charh; /* height of a character in pixels */ - void *r_caddr; /* DSA: ->character cache | VDU: ->font name */ - int r_cbpl; /* DSA: #bytes/character line | VDU: x OS offset */ - int r_cbpc; /* DSA: #bytes/character | VDU: y OS offset */ - - int r_linesp; /* line spacing (pixels) */ - - void *r_data; /* -> text to display */ - int r_scrollx; /* see Redraw dox */ - int r_scrolly; /* see Redraw dox */ - - void *r_palette; /* -> palette lookup table */ - int r_for; /* foreground colour at start of line */ - int r_bac; /* background colour at start of line */ - - void *r_workarea; /* -> word aligned workspace */ - - int r_magx; /* log2 x OS coords per pixel */ - int r_magy; /* log2 y OS coords per pixel */ - - int r_xsize; /* width of screen in pixels */ - int r_ysize; /* height of screen in pixels */ - - int r_mode; /* current screen mode */ -} -ZapRedrawBlock; - - -/* - | We cache font data using an array of 'font handles' (since there is a - | known maximum no. of fonts required). - | This is what a font 'handle' looks like: - */ -typedef struct -{ - char *name; /* font name */ - int usage; /* usage count */ - int w, h; /* width, height */ - int f, l; /* first and last character defined */ - void *bpp_1; /* source bitmap */ - void *bpp_n; /* bitmap for the current screen mode */ -} -ZapFont; - -/* - | A struct to hold all the data relevant to a term window - */ -typedef struct -{ - term t; /* The Term itself */ - window_handle w; /* Window handle */ - ZapFont *font; /* Font */ - wimp_box changed_box; /* Area out of date */ - struct - { - wimp_point pos; /* Cursor position */ - BOOL visible; /* visibility flag */ - } - cursor; - char name[12]; /* Name to give menus opened from the term */ - int def_open; /* Open by default? */ - wimp_box def_pos; /* default position */ - wimp_point def_scroll; /* default scroll offset */ - int unopened; /* Has this window not been opened yet? */ -} -term_data; - - - -/*--------------------------------------------------------------------------*/ -/* ZapRedraw SWI numbers */ -/*--------------------------------------------------------------------------*/ - -#define SWI_ZapRedraw_ 0x48480 -#define SWI_ZapRedraw_RedrawArea (SWI_ZapRedraw_ + 0x00) -#define SWI_ZapRedraw_GetPaletteEntry (SWI_ZapRedraw_ + 0x01) -#define SWI_ZapRedraw_RedrawRaster (SWI_ZapRedraw_ + 0x02) -#define SWI_ZapRedraw_ConvertBitmap (SWI_ZapRedraw_ + 0x03) -#define SWI_ZapRedraw_PrepareDataLine (SWI_ZapRedraw_ + 0x04) -#define SWI_ZapRedraw_AddCursor (SWI_ZapRedraw_ + 0x05) -#define SWI_ZapRedraw_FindCharacter (SWI_ZapRedraw_ + 0x06) -#define SWI_ZapRedraw_MoveBytes (SWI_ZapRedraw_ + 0x07) -#define SWI_ZapRedraw_CachedCharSize (SWI_ZapRedraw_ + 0x08) -#define SWI_ZapRedraw_ConvBitmapChar (SWI_ZapRedraw_ + 0x09) -#define SWI_ZapRedraw_CreatePalette (SWI_ZapRedraw_ + 0x0a) -#define SWI_ZapRedraw_InsertChar (SWI_ZapRedraw_ + 0x0b) -#define SWI_ZapRedraw_ReadSystemChars (SWI_ZapRedraw_ + 0x0c) -#define SWI_ZapRedraw_ReverseBitmaps (SWI_ZapRedraw_ + 0x0d) -#define SWI_ZapRedraw_ReadVduVars (SWI_ZapRedraw_ + 0x0e) -#define SWI_ZapRedraw_GetRectangle (SWI_ZapRedraw_ + 0x0f) -#define SWI_ZapRedraw_AddVduBitmaps (SWI_ZapRedraw_ + 0x10) -#define SWI_ZapRedraw_CacheFontChars (SWI_ZapRedraw_ + 0x11) -#define SWI_ZapRedraw_SpriteSize (SWI_ZapRedraw_ + 0x12) -#define SWI_ZapRedraw_RedrawWindow (SWI_ZapRedraw_ + 0x13) - - -/* - | Other SWI numbers that aren't defined in DeskLib's SWI.h: - */ -#define SWI_OS_ScreenMode 0x65 -#define SWI_OS_DynamicArea 0x66 -#define SWI_ColourTrans_ReturnColourNumber 0x40744 -#define SWI_Wimp_ReportError 0x400df -#define SWI_PlayIt_Volume 0x4d146 - - - -/*--------------------------------------------------------------------------* - | File scope variables | - *--------------------------------------------------------------------------*/ -static int ftype = 0xffd; /* hack so saved games get the right type */ -static int filehandle[16]; /* we keep track of open files with this */ -static int openfiles = 0; /* how many files are currently open */ - -/* - | Paths we use... - */ -static char resource_path[260] = ""; /* Path pointng to "!Angband.Lib." */ -static char scrap_path[260] = ""; /* Path to create scrap files on */ -static char choices_file[3][260] = -{ "", "", "" }; /* Choices paths (read/write, mirror, read) */ -static char alarm_file[2][260] = -{ "", "" }; /* Alarm choices paths (read/write, mirror, read) */ -/* - | So we can use something more meaningful later... - | NB: Mirror is only meaningful for Choices and we don't - | even reserve space for alarm_file[CHFILE_MIRROR]. - */ -#define CHFILE_WRITE 0 -#define CHFILE_READ 1 -#define CHFILE_MIRROR 2 - -/* - | Other 'globals': - */ -static int initialised = 0; /* Used to determine whether to try to save */ -static int game_in_progress = 0; /* if Quit (or core() is called), etc. */ - -static byte a_palette[256][4]; /* a copy of the raw Angband palette */ -static unsigned int palette[256]; /* palette as gamma'd bbggrrxx words */ -static unsigned int zpalette[256]; /* And our version for ZapRedraw */ -static double gamma = 1.0; /* assume gamma of 1.0 if unspecified */ - -static int enable_sound = 0; /* enable sound FX */ -static int sound_volume = 127; /* Full volume */ -static int force_mono = 0; /* force monochrome */ -static int start_fullscreen = 0; /* start up full screen (added in 1.18) */ -static int hack_flush = 0; /* Should TERM_XTRA_FLUSH wait for all keys to be released? */ -static int flush_scrap = 1; /* Should any scrapfiles (incl. filecache) be deleted at exit? */ -static int max_file_cache_size = 64 << 10; -static unsigned int vfiletype; -static int allow_iclear_hack = 0; /* Allow the hideously evil Iclear workaround thing */ -static int alarm_type = 0; /* is there an alarm set? */ -static int alarm_h = 0, alarm_m = 0; /* alarm time (midnight) */ -static char alarm_message[80] = "Time for bed!"; /* the message to give */ -static int alarm_disp = 0; /* is the alarm being displayed? */ -static int alarm_beep = 0; /* should be beep? */ -static const char *alarm_types[] = -{ "Off", "On (one-shot)", "On (repeating)", "On (one-shot)" }; -static unsigned int alarm_lastcheck = 0; - - -/* A little macro to save some typing later: */ -#define COLOUR_CHANGED(x) \ - ( (angband_color_table[x][1]!=a_palette[x][1]) || \ - (angband_color_table[x][2]!=a_palette[x][2]) || \ - (angband_color_table[x][3]!=a_palette[x][3]) ) - -static int got_caret = 0; /* Do we own the caret? */ -static int key_pressed = 0; /* 'Key has been pressed' Flag */ -static int use_glass = 1; /* use the hourglass between WimpPolls? */ -static int glass_on = 1; /* is the hourglass on? */ -static int user_menu_active = FALSE; /* set to TRUE when the user menu is active */ - -/* Font system variables */ -static ZapFont fonts[MAX_TERM_DATA + 1]; /* The +1 is for the system font */ - -/* The system font is always font 0 */ -#define SYSTEM_FONT (&(fonts[0])) - -/* Term system variables */ -static term_data data[MAX_TERM_DATA]; /* One per term */ - -#ifndef FULLSCREEN_ONLY -static char r_data[24 * (80 * 5 + 4) + 25 * 4]; /* buffer for ZapRedraw data */ - -/* Wimp variables */ -static icon_handle ibar_icon; /* Iconbar icon handle */ -static window_handle info_box; /* handle of the info window */ -static window_handle gamma_win; /* gamma correction window */ -static window_handle sound_win; /* sound options window */ -static window_handle save_box; /* The savebox */ -static menu_ptr ibar_menu; /* Iconbar menu */ -static menu_ptr term_menu; /* Term window menu */ -static menu_ptr wind_menu; /* windows (sub) menu */ -static menu_ptr font_menu; /* Font (sub)menu */ - -static save_saveblock *saveblk = NULL; /* For the save box */ - -/* List of Wimp messages we want to be given */ -static int message_list[] = -{ - message_MODECHANGE, - message_PALETTECHANGE, - - /* For the savebox */ - message_MENUWARN, - message_DATASAVEACK, - - message_PREQUIT, - 0 -}; - - -static term_data *menu_term; /* term the last menu was opened for */ - -#endif /* FULLSCREEN_ONLY */ - -static ZapRedrawBlock zrb; /* a redraw block */ - -/* Cursor colour */ -#define CURSOR_COLOUR 255 /* Cursor's Angband colour */ -#define CURSOR_RGB 0x00ffff00 /* if undefined, use bbggrrxx */ - -static int cursor_rgb = -1; /* colour to use for cursor */ - -static int fullscreen_mode = 0; /* screen mode in use */ -static int old_screenmode = 0; /* Mode we started out in */ -static int *fullscreen_font = 0; /* font data for fullscreen use */ -static int *fullscreen_base = 0; /* base address of screen */ -static int fullscreen_height; /* height of the fullscreen font */ -static int fullscreen_topline; /* raster offset of fullscreen */ - -#define KEYPRESS_QUIT 0x1cc /* F12 gets back to the desktop */ -#define TERM_TOPLINE_HR 32 /* vertical pixel offset in mode 27 */ -#define TERM_TOPLINE_LR 16 /* vertical pixel offset in mode 12 */ -#define TIME_LINE 26 /* Line to display the clock on */ - -/* text to display at the bottom left of the fullscreen display */ -static const char *fs_quit_key_text = "Press f12 to return to the desktop"; -static const char *alarm_cancel_text = "(Press ^Escape to cancel the alarm)"; - -/* Debugging flags, etc. */ -static int log_g_malloc = 0; /* Log calls to ralloc, etc */ -static int show_sound_alloc = 0; /* Log sound mappings, etc */ - -/* Activate file caching? */ -#ifdef USE_FILECACHE -static int use_filecache = TRUE; -#else -static int use_filecache = FALSE; -#endif - -/* Cripple some things to save memory */ -static int minimise_memory = 0; - -/* Forward declarations of some of the Full Screen Mode stuff */ -static void enter_fullscreen_mode(void); -static void leave_fullscreen_mode(void); -static void set_keys(int claim); - -/* Forwards declarations of the sound stuff */ -static void initialise_sound(void); -static void play_sound(int event); - -/* Forward declarations of Term hooks, etc. */ -static void Term_init_acn(term *t); -static errr Term_user_acn(int n); - -#ifndef FULLSCREEN_ONLY -static errr Term_curs_acn(int x, int y); -static errr Term_text_acn(int x, int y, int n, byte a, cptr s); -static errr Term_xtra_acn(int n, int v); -static errr Term_wipe_acn(int x, int y, int n); -static errr Term_xtra_acn_check(void); -static errr Term_xtra_acn_event(void); -static errr Term_xtra_acn_react(void); -#endif /* FULLSCREEN_ONLY */ - -static errr Term_curs_acnFS(int x, int y); -static errr Term_text_acnFS(int x, int y, int n, byte a, cptr s); -static errr Term_xtra_acnFS(int n, int v); -static errr Term_wipe_acnFS(int x, int y, int n); -static errr Term_xtra_acn_checkFS(void); -static errr Term_xtra_acn_clearFS(void); -static errr Term_xtra_acn_eventFS(void); -static errr Term_xtra_acn_reactFS(int force); - -#ifdef USE_DA -/* Forward declarations of the memory stuff */ -static void init_memory(int, int); -#endif - -/* Forward declarations of the alarm stuff */ -static void check_alarm(void); -#ifndef FULLSCREEN_ONLY -static void trigger_alarm_desktop(void); -#endif /* FULLSCREEN_ONLY */ -static void ack_alarm(void); -static void write_alarm_choices(void); -static void read_alarm_choices(void); - - -/* This just shows some debugging info (if enabled with FE_DEBUG_INFO) */ -static void show_debug_info(void); - - - -/* File-caching functions (if enabled at compile time) */ -#ifdef USE_FILECACHE -FILE *cached_fopen(char *name, char *mode); -errr cached_fclose(FILE *fch); -errr cached_fgets(FILE *fch, char *buffer, int max_len); -#endif - -/* - | These functions act as malloc/free, but (if possible) using memory - | in the 'Game' Dynamic Area created by init_memory() - | We attach these functions to the ralloc_aux and rnfree_aux hooks - | that z-virt.c provides. - */ -#ifdef USE_DA -static vptr g_malloc(huge size); -static vptr g_free(vptr blk, huge); -#else - #define g_malloc(size) malloc(size); - #define g_free(block, size) free(block); -#endif - -/* - | These functions act as malloc/free, but (if possible) using memory - | in the 'Fonts' Dynamic Area created by init_memory() - */ -#ifdef USE_DA -static void* f_malloc(size_t size); -static void f_free(void *blk); -#else - #define f_malloc(size) malloc(size); - #define f_free(block) free(block); -#endif - -/* - | These two functions perpetrate great evil to stop IClear from mucking - | with the cursor keys in fullscreen mode. - */ -static void iclear_hack(void); -static void remove_iclear_hack(void); - -/* - | We use this to locate the choices file(s)... - */ -static char *find_choices(int write); -static char *find_choices_mirror(void); -static char *find_alarmfile(int write); - - - -/* - | This function is supplied as a wrapper to the save_player function. - | - | Its purpose is to change the filename that the game will be saved with - | the leafname "!!PANIC!!" so that panic saves that break the savefile - | won't overwrite the original savefile. - | - | To get this to work, you'll need to ammend files.c and change the call - | to save_player in the panic save function(s) (search for "panic save") - | to a call to save_player_panic_acn. You can declare a prototype for - | the function if you like. - */ - -extern int save_player_panic_acn(void) -{ - char *e, *l; - - /* Find the final / in the savefile name */ - for (l = e = savefile; *e; e++) - if (*e == '/') - { - l = e + 1; - } - - /* Write over the current leaf with the special panic one */ - strcpy(l, "!!PANIC!!"); - - /* save the game */ - return save_player(); -} - - -/*--------------------------------------------------------------------------*/ -/* Error reporting, etc. */ -/*--------------------------------------------------------------------------*/ - - -/* Tell the user something important */ -static void plog_hook(cptr str) -{ - Msgs_Report(1, "err.plog", str); -} - -/* Tell the user something, then quit */ -static void quit_hook(cptr str) -{ - /* str may be null */ - if (str) Msgs_Report(1, "err.quit", str); - exit(0); -} - -/* Tell the user something then crash ;) */ -static void core_hook(cptr str) -{ - Msgs_Report(1, "err.core", str); - - if (game_in_progress && character_generated) - save_player_panic_acn(); - - quit(NULL); -} - -static void debug(const char *fmt, ...) -{ - va_list ap; - char buffer[260]; - va_start(ap, fmt); - vsprintf(buffer, fmt, ap); - va_end(ap); - plog(buffer); -} - - - -/* -static void oserror_handler( int sig ) -{ - core(_kernel_last_oserror()->errmess); -} -*/ - - -/*--------------------------------------------------------------------------*/ -/* File handling */ -/*--------------------------------------------------------------------------*/ - -static int myFile_Open(const char *name, int mode) -{ - int handle; - if (SWI(2, 1, SWI_OS_Find, mode, name, /**/ &handle)) - return 0; - return handle; -} - -static int myFile_Size(const char *name) -{ - int size, type; - if (SWI(2, 5, SWI_OS_File, 17, name, /**/ &type, 0, 0, 0, &size)) - return -2; - return type ? size : -1; -} - -static os_error *myFile_Close(const int handle) -{ - return SWI(2, 0, SWI_OS_Find, 0, handle); -} - -static os_error *myFile_Seek(const int handle, const int offset) -{ - return SWI(3, 0, SWI_OS_Args, 1, handle, offset); -} - -static int myFile_WriteBytes(const int handle, const void *buf, const int n) -{ - int ntf; - if (SWI(4, 4, SWI_OS_GBPB, 2, handle, buf, n, /**/ NULL, NULL, NULL, &ntf)) - return n; - return ntf; -} - -static int myFile_ReadBytes(const int handle, void *buf, const int n) -{ - int ntf; - if (SWI(4, 4, SWI_OS_GBPB, 4, handle, buf, n, /**/ NULL, NULL, NULL, &ntf)) - return n; - return ntf; -} - -static os_error *myFile_SetType(const char *n, const int type) -{ - return SWI(3, 0, SWI_OS_File, 18, n, type); -} - - -static int myFile_Extent(const int handle) -{ - int ext; - if (SWI(2, 3, SWI_OS_Args, 2, handle, /**/ NULL, NULL, &ext)) - return -1; - return ext; -} - - -/* - | Determine if one file is newer than another. - | - | The filenames should be specified in RISC OS style. - | - | Returns -1 if 'a' is newer than 'b'. - */ -static int file_is_newer(const char *a, const char *b) -{ - os_error *e; - struct - { - unsigned int msw; - unsigned int lsw; - } - a_time; - struct - { - unsigned int msw; - unsigned int lsw; - } - b_time; - int a_type, b_type; - - /* Get the datestamp of the 'a' file */ - e = SWI(2, 4, SWI_OS_File, - /* In */ - 17, (int)a, - /* Out */ - &a_type, /* object type */ - NULL, &(a_time.msw), /* Load Addr */ - &(a_time.lsw) /* Exec Addr */ - ); - if (e) - { - core(e->errmess); - } - - - /* Get the datestamp of the 'b' file */ - e = SWI(2, 4, SWI_OS_File, - /* In */ - 17, (int)b, - /* Out */ - &b_type, /* object type */ - NULL, &(b_time.msw), /* Load Addr */ - &(b_time.lsw) /* Exec Addr */ - ); - if (e) - { - core(e->errmess); - } - - /* If 'b' doesn't exist then 'b' is OOD. */ - if (!b_type) - { - return -1; - } - /* If 'a' doesn't exist then 'b' isn't OOD. (?) */ - if (!a_type) - { - return 0; - } - - /* Compare the timestamps (assume that the files are typed) */ - if ((a_time.msw & 0xff) >= (b_time.msw & 0xff)) - if ((a_time.lsw) > (b_time.lsw)) - return -1; /* OOD */ - return 0; /* Not OOD */ -} - - -/* - | As fprintf, but outout to all files (if their handles are non zero). - | NB: void type. - */ -static void f2printf(FILE *a, FILE *b, const char *fmt, ...) -{ - va_list ap; - char buffer[2048]; - va_start(ap, fmt); - vsprintf(buffer, fmt, ap); - va_end(ap); - if (a) - { - fprintf(a, buffer); - } - if (b) - { - fprintf(b, buffer); - } - va_end(ap); -} - - - - -/*--------------------------------------------------------------------------*/ -/* Clean up (ie. close files, etc). */ -/*--------------------------------------------------------------------------*/ - -static void final_acn(void) -{ - int i; - - for (i = 0; i < openfiles; i++) - myFile_Close(filehandle[i]); - - if (fullscreen_mode) - { - /* Restore the screen mode */ - Wimp_SetMode(old_screenmode); - - /* Restore the various soft keys */ - set_keys(FALSE); - - /* - | Hack: Early WIMP versions do the "Press SPACE" thing, or something - | odd. It's bloody annoying, whatever it is... - */ - if (event_wimpversion < 300) - Wimp_CommandWindow(-1); - } - - if (flush_scrap && *scrap_path) - { - char tmp[512]; - strcpy(tmp, scrap_path); - tmp[strlen(tmp) - 1] = 0; /* Remove trailing dot */ - SWI(4, 0, SWI_OS_FSControl, 27, tmp, 0, 1); /* ie. "*Wipe <scrapdir> r~c~v~f" */ - } - -#ifdef FULLSCREEN_ONLY - Wimp_CommandWindow(-1); -#endif /* FULLSCREEN_ONLY */ - - Stop_Hourglass; -} - - -/*--------------------------------------------------------------------------* - | Various UNIX-like support funtions | - *--------------------------------------------------------------------------*/ - -/* - | Hack: determine whether filenames should be truncated to 10 chars or not. - | - | Needed since RO2 (and RO3 with Truncate configured off) will return - | errors instead of automatically truncating long filenames. - */ -static int truncate_names(void) -{ - int r1, r2; - - /* First, check the OS version */ - OS_Byte(osbyte_READOSIDENTIFIER, 0x00, 0xff, &r1, &r2); - - /* Assume that we need to truncate if running under RO2 */ - if (r1 == 0xa1 || r1 == 0xa2) - return TRUE; - - /* Okay, so we've got RO3 (or later), so check the CMOS RAM */ - OS_Byte(osbyte_READCMOSRAM, 28, 0, &r1, &r2); - - /* Bit 0 of byte 28 is the Truncate flag */ - return !(r2 & 1); -} - - -/* - | The PathName translation is now done by two separate functions: - | unixify_name() and riscosify_name(). - | - | This is done because only the UNIX=>RISCOS translation should - | ever affect the length of the leafname (ie. by truncating it to - | 10 chars if necessary). - | - | Note that the two functions are identical but for the truncation - | check so all that's really been done is that translate_name() now - | takes an extra argument: 'trunc' that controls whether truncation - | is applied, and riscosify and unixify just call translate_name(). - */ -static char *translate_name(const char *path, int trunc) -{ - static char buf[260]; - char c, *p; - - /* Copy 'path' into 'buf', swapping dots and slashes */ - p = buf; /* Output position */ - do - { - c = *path++; - if (c == '/') - c = '.'; - else if (c == '.') - c = '/'; - *p++ = c; - } - while (c); /* Terminator /is/ copied */ - - /* - | When saving a game, the old game is renamed as - | "SavedGame.old", the new one is saved as "SavedGame.new", - | "SavedGame.old" is deleted, "SavedGame.new" is renamed - | as "SavedGame". This will go wrong on a Filecore based filing - | system if the saved game has a leafname > 8 chars. - */ - - if ((p = strstr(buf, "/old")) == NULL) - { - p = strstr(buf, "/new"); - } - if (!p) - { - ftype = 0xffd; - } - else - { - char *q = strrchr(buf, '.'); - if (q) - if (p - q > 6) - { - memmove(q + 6, p, 5); - } - ftype = vfiletype; - } - - /* - | Hack: Do we need to truncate the leafname? - */ - if (trunc) - { - if (truncate_names()) - { - char *a, *b; - /* - | Assume that only the leafname needs attention - | (this should be true for any variant) - */ - for (a = b = buf; *a; a++) - if (*a == '.') - b = a + 1; - /* - | Now b points to the start of the leafname. - | If the leafname is >10 chars, write over the 10th with a - | terminator. - */ - if (strlen(b) > 10) - { - b[10] = 0; - }; - } - } - - return buf; -} - - -extern char *riscosify_name(const char *path) -{ - return translate_name(path, TRUE); -} - -static char *unixify_name(const char *path) -{ - return translate_name(path, FALSE); -} - - -/*--------------------------------------------------------------------------*/ - - -/* Open a file [as fopen()] but translate the requested filename first */ - -FILE *my_fopen(const char *f, const char *m) -{ - FILE *fp; - char *n = riscosify_name(f); /* translate for RO */ - - /* Try to open the file */ - fp = fopen(n, m); - - /* If it succeded and the file was opened for binary output - | then set the type according to the 'ftype' hack. - | NB: This will fail on some filing systems. - */ - - if (fp && strstr(m, "wb")) - { - myFile_SetType(n, ftype); - } - - return fp; -} - - - - -/* Close a file, a la fclose() */ - -errr my_fclose(FILE *fp) -{ - /* Close the file, return 1 for an error, 0 otherwise */ - return fclose(fp) ? 1 : 0; -} - - -/* Open/Create a file */ - -int fd_make(cptr file, int mode) -{ - char *real_path; - int handle; - - /* Translate the filename into a RISCOS one */ - real_path = riscosify_name(file); - - /* Try to OPENOUT the file (no path, error if dir or not found) */ - handle = myFile_Open(real_path, 0x8f); - - /* Check for failure */ - if (!handle) - { - return -1; - } - - /* Try to set the filetype according to the ftype hack */ - myFile_SetType(real_path, ftype); - - /* We keep track of up to 16 open files at any given time */ - if (openfiles < 16) - filehandle[openfiles++] = handle; - - return (handle); -} - - -/* Delete a file [as remove()] */ -errr fd_kill(cptr file) -{ - return remove(riscosify_name(file)) ? 1 : 0; -} - - -/* Rename a file [as rename()] */ -errr fd_move(cptr old, cptr new) -{ - char new_[260]; - strcpy(new_, riscosify_name(new)); - return rename(riscosify_name(old), new_) ? 1 : 0; -} - -/* Open a file */ -int fd_open(cptr path, int flags) -{ - int handle = 0; - char *real_path = riscosify_name(path); - - switch (flags & 0x0f) - { - case O_RDONLY: /* Read only */ - handle = myFile_Open(real_path, 0x4f); - break; - case O_WRONLY: /* Write only */ - case O_RDWR: /* Read/Write */ - handle = myFile_Open(real_path, 0xcf); - } - - /* Check for failure */ - if (!handle) - { - return (-1); - } - - /* Keep track of upto 16 open files... */ - if (openfiles < 16) - filehandle[openfiles++] = handle; - - return (handle); -} - - -/* Close a file opened with fd_make or fd_open */ -errr fd_close(int handle) -{ - int i; - - if (handle <= 0) - { - return -1; - } /* Illegal handle */ - - /* Try to close the file */ - if (myFile_Close(handle)) - { - return 1; - } - - /* Mark the file as closed in our array of file handles */ - openfiles--; - /* Find the entry in the array (if it exists) */ - for (i = 0; i < 16; i++) - if (filehandle[i] == handle) - { - break; - } - /* Shuffle the remaining entries down */ - for (; i < openfiles; i++) - filehandle[i] = filehandle[i + 1]; - - return 0; /* Sucess */ -} - - - -/* Read some bytes from a file */ -errr fd_read(int handle, char *buf, huge nbytes) -{ - int unread; - - if (handle <= 0) - { - return -1; - } /* Illegal handle */ - unread = myFile_ReadBytes(handle, buf, (int)nbytes); - - return unread ? 1 : 0; -} - - -/* Write some bytes to a file */ -errr fd_write(int handle, const char *buf, huge nbytes) -{ - int unwritten; - - if (handle <= 0) - { - return -1; - } /* Illegal handle */ - unwritten = myFile_WriteBytes(handle, (const void *)buf, (int)nbytes); - - return unwritten ? 1 : 0; -} - - -/* Seek in a file */ -errr fd_seek(int handle, huge offset) -{ - os_error *e; - - if (handle <= 0) - { - return -1; - } /* Illegal handle */ - e = myFile_Seek(handle, (int)offset); - - return e ? 1 : 0; -} - - -/* RISC OS provides no file locking facilities, so: */ -errr fd_lock(int handle, int what) -{ - return 0; -} - - -/* Get a temporary filename */ -errr path_temp(char *buf, int max) -{ - - /* - | New in 1.25 - use the scrap path we decided on earlier, or - | fall back on tmpnam() if that fails for some reason. - */ - if (*scrap_path) - { - time_t t; - int m; - char tmp[512]; - - time(&t); - for (m = 0; m < 80; m++) - { - sprintf(tmp, "%s0x%08x", scrap_path, (int)t + m); - if (myFile_Size(tmp) == -1) - { - break; - } - } - - if (m < 80) - { - strncpy(buf, unixify_name(tmp), max); - return 0; - } - } - - strncpy(buf, unixify_name(tmpnam(NULL)), max); - return 0; -} - - - -/* - * Create a new path by appending a file (or directory) to a path - * - * This requires no special processing on simple machines, except - * for verifying the size of the filename, but note the ability to - * bypass the given "path" with certain special file-names. - * - * Note that the "file" may actually be a "sub-path", including - * a path and a file. - * - * Note that this function yields a path which must be "parsed" - * using the "parse" function above. - */ -errr path_build(char *buf, int max, cptr path, cptr file) -{ - /* Special file */ - if (file[0] == '~') - { - /* Use the file itself */ - strnfmt(buf, max, "%s", file); - } - - /* Absolute file, on "normal" systems */ - else if (prefix(file, PATH_SEP) && !streq(PATH_SEP, "")) - { - /* Use the file itself */ - strnfmt(buf, max, "%s", file); - } - - /* No path given */ - else if (!path[0]) - { - /* Use the file itself */ - strnfmt(buf, max, "%s", file); - } - - /* Path and File */ - else - { - /* Build the new path */ - strnfmt(buf, max, "%s%s%s", path, PATH_SEP, file); - } - - /* Success */ - return (0); -} - - - -/*--------------------------------------------------------------------------*/ - - - - - -/*--------------------------------------------------------------------------*/ -/* Font Functions */ -/*--------------------------------------------------------------------------*/ - -/* - | Cache the system font as fonts[0] - | Returns 1 for sucess or 0 for failure. - | NB: The n_bpp data is *not* cached, just the 1bpp data and font info. - | Also, the usage is never affected. - */ -static int cache_system_font(void) -{ - ZapFont *sys = SYSTEM_FONT; - ZapRedrawBlock zrb; - char work_area[16]; - int i; - - /* Cache the system font (as fonts[0]) */ - if (sys->bpp_1) - { - f_free(sys->bpp_1); - sys->bpp_1 = 0; - } - sys->bpp_1 = f_malloc(8 * 256); /* 2K */ - if (!sys->bpp_1) - { - return 0; - } - - /* Mung so that undefined characters show up as inverted ?s */ - work_area[3] = '?'; - SWI(2, 0, SWI_OS_Word, 10, work_area + 3); - for (i = 4; i < 12; i++) - work_area[i] ^= 255; /* invert colours */ - SWI(4, 0, SWI_ZapRedraw_ReverseBitmaps, 0, work_area + 4, work_area + 4, 8); - for (i = 0; i < 0x20; i++) - memcpy(((char *)sys->bpp_1) + i * 8, work_area + 4, 8); - - /* Read the system font */ - zrb.r_workarea = work_area; - SWI(2, 0, SWI_ZapRedraw_ReadSystemChars, sys->bpp_1, &zrb); - - /* Set up some little bits of info */ - sys->name = (char *) "<System>"; - sys->w = sys->h = 8; - sys->f = 0; - sys->l = 255; - - return 1; -} - - - -/* - | Prepare the font system - */ -static void initialise_fonts(void) -{ - /* Initialise the array */ - memset(fonts, 0, sizeof(fonts)); /* Clear to zeroes */ - - /* Cache the system font */ - cache_system_font(); - fonts[0].usage = 0; /* No users */ -} - - -#ifndef FULLSCREEN_ONLY -/* - | Find a font (by name) in the array. - | Returns 0 if the font isn't loaded, or a ZapFont* for it if it is. - */ -static ZapFont *find_font_by_name(char *name) -{ - int i; - for (i = 0; i <= MAX_TERM_DATA; i++) - if (fonts[i].name) - if (!strcmp(fonts[i].name, name)) - return &(fonts[i]); - return NULL; -} - -/* - | Find a free slot in the fonts array - */ -static ZapFont *find_free_font(void) -{ - int i; - for (i = 1; i <= MAX_TERM_DATA; i++) - if (!fonts[i].name) - { - return &(fonts[i]); - } - return NULL; -} - - - -/* - | Load a font from disc and set up the header info, etc. - | NB: doesn't cache the nbpp data, just the 1bpp data. - | (Sets usage to 1) - | Returns NULL if failed. - */ -static ZapFont *load_font(char *name, ZapFont *f) -{ - int handle, extent; - char path[260]; - struct - { - char id[8]; - int w, h, f, l, r1, r2; - } - header; - char *font_path; - char *t; - char *real_name = name; /* need to preserve this */ - - /* - | 1.10 - the first element of the name determines the path to load - | the font from. - */ - - /* The font paths start <RISCOS_VARIANT>$ */ - t = path + sprintf(path, "%s$", RISCOS_VARIANT); - - /* Copy the path specifier and move 'name' past it */ - for (; *name != '.'; *t++ = *name++) ; - - /* After this, the name now points to the font name proper */ - name++; - - /* Append the end of the path name */ - strcpy(t, "$FontPath"); - - /* Get the path setting */ - font_path = getenv(path); - if (!font_path || !*font_path) - strcpy(path, "null:$."); - else - { - strcpy(path, font_path); - for (t = path; *t > ' '; t++) - ; - if (t[-1] != '.' && t[-1] != ':') - { - *t++ = '.'; - } - *t = 0; - } - strcat(path, name); - - - /* Open the file */ - handle = myFile_Open(path, 0x4f); - if (!handle) - { - return NULL; - } - - /* Read the header */ - if (myFile_ReadBytes(handle, &header, sizeof(header))) - { - myFile_Close(handle); - return NULL; - } - - /* Check that it's a zapfont */ - if (strncmp(header.id, "ZapFont\r", 8)) - { - myFile_Close(handle); - return NULL; - } - - /* Calculate the size of the 1bpp data */ - extent = myFile_Extent(handle) - sizeof(header); - - /* Allocate the storage for the 1bpp data */ - f->bpp_1 = f_malloc(extent); - if (!f->bpp_1) - { - myFile_Close(handle); - return NULL; - } - - /* Load the 1bpp data */ - if (myFile_ReadBytes(handle, f->bpp_1, extent)) - { - f_free(f->bpp_1); - f->bpp_1 = 0; - myFile_Close(handle); - return NULL; - } - - /* Close the file and set the header, etc. */ - myFile_Close(handle); - f->name = f_malloc(strlen(real_name) + 1); - if (!f->name) - { - f_free(f->bpp_1); - f->bpp_1 = 0; - return NULL; - } - - strcpy(f->name, real_name); - f->w = header.w; - f->h = header.h; - f->f = header.f; - f->l = header.l; - f->usage = 1; - - return f; -} - - - - -/* - | Cache a font at a suitable number of bpp for the current mode - | Returns 0 for failure, 1 for sucess. - | If the call fails then the font's bpp_n entry will be NULL. - */ -static int cache_font_for_mode(ZapFont *f) -{ - ZapRedrawBlock b; - char work_area[128]; - int size; - - if (!f) - { - return 0; - } - if (!f->bpp_1) - { - return 0; - } - - b.r_workarea = work_area; - SWI(2, 0, SWI_ZapRedraw_ReadVduVars, 0, &b); - - b.r_workarea = work_area; /* Paranoia */ - b.r_charh = f->h; - b.r_charw = f->w; - SWI(4, 4, SWI_ZapRedraw_CachedCharSize, b.r_bpp, 0, f->w, f->h, - NULL, NULL, &(b.r_cbpl), &(b.r_cbpc)); - - size = 256 * b.r_cbpc; - if (f->bpp_n) - { - f_free(f->bpp_n); - f->bpp_n = NULL; - } - f->bpp_n = f_malloc(size); - if (!f->bpp_n) - { - return 0; - } - - b.r_workarea = work_area; /* Paranoia */ - b.r_caddr = f->bpp_n; - SWI(5, 0, SWI_ZapRedraw_ConvertBitmap, 0, &b, 0, 255, f->bpp_1); - - return 1; -} - - - -/* - | Stop using a font. - | If the font's usage drops to zero then the font data is purged. - */ -static void lose_font(ZapFont *f) -{ - if (--f->usage) - { - /*debug("Losing font %s (still cached)",f->name); */ - return; - } - /*debug("Losing font %s (no longer in use)",f->name); */ - f_free(f->name); - f_free(f->bpp_1); - if (f->bpp_n) - { - f_free(f->bpp_n); - } - memset(f, 0, sizeof(ZapFont)); -} - - -/* - | Get a font. - */ -static ZapFont *find_font(char *name) -{ - ZapFont *f; - - /* Check to see if it's already loaded */ - f = find_font_by_name(name); - if (f) - { - /*debug("Find font %s (already cached)",name); */ - f->usage++; - if (f == SYSTEM_FONT) - { - if (!cache_system_font()) - core("Failed to cache system font!"); - if (!cache_font_for_mode(SYSTEM_FONT)) - core("Failed to cache system font!"); - } - return f; - } - - /* Ok, now check to see if there's a free slot for it */ - f = find_free_font(); - if (!f) - { - return NULL; - } /* Oh dear :( */ - - /* Load the font */ - /*debug("Find font %s (loading)",name); */ - f = load_font(name, f); - if (f) - { - if (!cache_font_for_mode(f)) - return NULL; - return f; - } - return NULL; -} - - - - -/* - | Cache the n_bpp data for all the active fonts (including system) - */ -static void cache_fonts(void) -{ - int i; - for (i = 0; i <= MAX_TERM_DATA; i++) - if (fonts[i].name) - if (!cache_font_for_mode(&(fonts[i]))) - core("Failed to (re)cache font tables"); -} - - - - - - -typedef struct -{ - int load, exec, size, attr, type; - char name[4]; /* Actual size is unknown */ -} -osgbpb10_block; - - -static char *leafname(char *path) -{ - char *s = path + strlen(path); - while (--s > path) - if (*s == '.' || *s == ':') - { - return s + 1; - } - return path; -} - -/* - | NB: This function is recursive. - */ -static menu_ptr make_zfont_menu(char *dir) -{ - int entries, entry; - int read, offset; - unsigned int max_width; - menu_ptr m; - menu_item *mi; - char *temp; - osgbpb10_block *item_info; - char buffer[1024]; /* 1Kb buffer */ - - /* Count the entries in the directory */ - entries = read = offset = 0; - while (offset != -1) - { - if (SWI(7, 5, SWI_OS_GBPB, 10, dir, buffer, 77, offset, 1024, 0, - NULL, NULL, NULL, &read, &offset)) - { - offset = -1; - read = 0; - } - entries += read; - } - - if (!entries) - { - return NULL; - } - - /* Allocate a big enough area of storage for the number of entries */ - m = f_malloc(sizeof(menu_block) + entries * sizeof(menu_item)); - if (!m) - { - return NULL; - } - memset(m, 0, sizeof(menu_block) + entries * sizeof(menu_item)); - - /* Set up the menu header */ - strncpy(m->title, leafname(dir), 12); - m->titlefore = 7; - m->titleback = 2; - m->workfore = 7; - m->workback = 0; - m->height = 44; - m->gap = 0; - mi = (menu_item *) (((int)m) + sizeof(menu_block)); - max_width = strlen(m->title); - - entry = 0; - - /* Read the entries */ - read = offset = 0; - while (offset != -1) - { - if (SWI(7, 5, SWI_OS_GBPB, 10, dir, buffer, 77, offset, 1024, 0, - NULL, NULL, NULL, &read, &offset)) - { - offset = -1; - read = 0; - /*free(m);return NULL; */ - } - - item_info = (osgbpb10_block *) buffer; - - /* Create a menu item for each entry read (if it fits) */ - while (read-- > 0) - { - switch (item_info->type) - { - case 1: /* File */ - if ((item_info->load & 0xffffff00) == 0xfffffd00) - { - /* Data file */ - mi[entry].submenu.value = -1; - mi[entry].iconflags.data.text = 1; - mi[entry].iconflags.data.filled = 1; - mi[entry].iconflags.data.foreground = 7; - mi[entry].iconflags.data.background = 0; - strncpy(mi[entry].icondata.text, item_info->name, 12); - if (strlen(mi[entry].icondata.text) > max_width) - max_width = strlen(mi[entry].icondata.text); - entry++; - } - break; - case 2: /* Directory */ - case 3: /* Image */ - { - menu_ptr sub; - char new_path[260]; - if (strchr(":.", dir[strlen(dir) - 1])) - sprintf(new_path, "%s%s", dir, item_info->name); - else - sprintf(new_path, "%s.%s", dir, item_info->name); - sub = make_zfont_menu(new_path); - if (sub) - { - /* Add the submenu */ - mi[entry].submenu.menu = sub; - mi[entry].iconflags.data.text = 1; - mi[entry].iconflags.data.filled = 1; - mi[entry].iconflags.data.foreground = 7; - mi[entry].iconflags.data.background = 0; - strncpy(mi[entry].icondata.text, item_info->name, 12); - if (strlen(mi[entry].icondata.text) > max_width) - max_width = strlen(mi[entry].icondata.text); - entry++; - } - } - break; - } - temp = ((char *)item_info) + 20; - while (*temp++) ; - item_info = (osgbpb10_block *) ((((int)temp) + 3) & ~3); - } - } - - if (entry) - { - m->width = (max_width + 2) * 16; - mi[entry - 1].menuflags.data.last = 1; - /* - | We could possibly realloc() the storage to fit the - | actual no. of entries read, but this is probably more - | trouble than it's worth. - */ - } - else - { - /* - | No point in returning an empty menu. - */ - f_free(m); - m = NULL; - } - - return m; -} - -#endif /* FULLSCREEN_ONLY */ - - - - -/*--------------------------------------------------------------------------*/ - -/* - | Initialise the palette stuff - */ -static void initialise_palette(void) -{ - memset(a_palette, 0, sizeof(a_palette)); - memset(palette, 0, sizeof(palette)); - memset(zpalette, 0, sizeof(zpalette)); -} - - - -#ifndef FULLSCREEN_ONLY - -/* - | Cache the ZapRedraw palette - */ -static void cache_palette(void) -{ - static ZapRedrawBlock b; - char workspace[128]; - int i; - - static double old_gamma = -1.0; - - /* Idiocy check: */ - if (gamma < 0.01) - { - plog("Internal error: Attempt to apply zero gamma - recovering..."); - gamma = 1.00; - } - - if (gamma != old_gamma) - { - memset(a_palette, 0, sizeof(a_palette)); - old_gamma = gamma; - } - - /* Go through the palette updating any changed values */ - for (i = 0; i < 256; i++) - { - if (COLOUR_CHANGED(i)) - { - int r, g, b; - r = (int)(255.0 * - pow(angband_color_table[i][1] / 255.0, 1.0 / gamma)); - g = (int)(255.0 * - pow(angband_color_table[i][2] / 255.0, 1.0 / gamma)); - b = (int)(255.0 * - pow(angband_color_table[i][3] / 255.0, 1.0 / gamma)); - palette[i] = (b << 24) | (g << 16) | (r << 8); - a_palette[i][1] = angband_color_table[i][1]; - a_palette[i][2] = angband_color_table[i][2]; - a_palette[i][3] = angband_color_table[i][3]; - } - } - - cursor_rgb = palette[CURSOR_COLOUR]; - - /* Cache the ZapRedraw palette for it */ - b.r_workarea = workspace; - if (b.r_mode != screen_mode) - SWI(2, 0, SWI_ZapRedraw_ReadVduVars, 0, &b); - SWI(5, 0, SWI_ZapRedraw_CreatePalette, 2, &b, palette, zpalette, 256); -} - - - - -/*--------------------------------------------------------------------------*/ - -/* - | Functions for dealing with the SaveBox - */ - -/* - | Create the window and claim various handlers for it - */ -static void init_save_window(void) -{ - /* Create the window */ - save_box = Window_Create("save", template_TITLEMIN); - - /* Set the file icon */ - Icon_printf(save_box, SAVE_ICON, "file_%03x", vfiletype); - -} -#endif /* FULLSCREEN_ONLY */ - -/* - | Hack: can't use Str.h without defining HAS_STRICMP. Rather than - | require that the header files are altered we simply provide our - | own strnicmp() function. - */ -static int my_strnicmp(const char *a, const char *b, int n) -{ - int i; - - n--; - - for (i = 0; i <= n; i++) - { - if (tolower((unsigned char)a[i]) != tolower((unsigned char)b[i])) - return tolower((unsigned char)a[i]) - tolower((unsigned char)b[i]); - - if (a[i] == '\0') - break; - } - - return 0; -} - -#ifndef FULLSCREEN_ONLY -/* - | This is the handler called when a 'save' occurrs. - | All it does is to update the game's own savefile setting and - | then (if possible) save the character. - */ -static BOOL SaveHnd_FileSave(char *filename, void *ref) -{ - char old_savefile[1024]; - - /* Hack: refuse to save if the character is dead */ - if (PDEADCHK) - { - Msgs_Report(0, "err.cheat"); - return FALSE; - } - - /* Hack: disallow saves to <Wimp$Scrap>* */ - if (!my_strnicmp("<wimp$scrap>", filename, 12)) - { - Msgs_Report(0, "err.scrap"); - return FALSE; - } - - /* Preserve the old path, in case something goes wrong... */ - strcpy(old_savefile, savefile); - - /* Set the new path */ - strcpy(savefile, unixify_name(filename)); - - /* Try a save (if sensible) */ - if (game_in_progress && character_generated) - { - if (!save_player()) - { - Msgs_Report(0, "err.save", filename); - strcpy(savefile, old_savefile); - return FALSE; /* => failure */ - } - } - - /* Set the pathname icon */ - Icon_printf(save_box, SAVE_PATH, "%s", riscosify_name(savefile)); - - /* Kill the menu */ - Wimp_CreateMenu((menu_block *) - 1, -1, -1); - - return TRUE; /* => Success */ -} - - - -/* - | Init the handlers for the savebox (eg. as a result of a menuwarning - | being received for the savebox) - */ - -static void init_savehandlers(void) -{ - if (saveblk) - { - Save_ReleaseSaveHandlers(saveblk); - saveblk = 0; - } - - saveblk = Save_InitSaveWindowHandler(save_box, /* Window handle */ - TRUE, /* it's part of a menu */ - FALSE, /* not a window */ - FALSE, /* Don't auto release the handlers */ - SAVE_ICON, /* The file icon */ - SAVE_OK, /* The OK icon */ - SAVE_CANCEL, /* The cancel icon */ - SAVE_PATH, /* The pathname icon */ - SaveHnd_FileSave, /* Handler to "save the file" */ - NULL, /* No RAM transfer support */ - NULL, /* No 'result handler' */ - 100 << 10, /* Est. size (irelevant anyway) */ - vfiletype, /* filetype (irelevant) */ - NULL /* ref */ - ); -} - - -/* - | Handle a MenuWarning message for the savebox - */ -static BOOL Hnd_SaveWarning(event_pollblock * pb, void *ref) -{ - os_error *e; - - init_savehandlers(); - - /* Set the pathname */ - Icon_printf(save_box, SAVE_PATH, "%s", riscosify_name(savefile)); - - /* Open the submenu */ - e = Wimp_CreateSubMenu((menu_block *) save_box, - pb->data.message.data.menuwarn.openpos.x, - pb->data.message.data.menuwarn.openpos.y); - - if (e) - { - Msgs_ReportFatal(0, "err.swi", __LINE__, e->errmess); - } - - return TRUE; -} - - -/*--------------------------------------------------------------------------*/ - - -/* - | Initialise the r_data array - | Mainly we just set up the line offset pointers and make sure that the - | lines themselves are 'safe' by writing end-of-line codes to them. - */ -static void initialise_r_data(void) -{ - int *lo = (int *)r_data; - char *ld; - int j; - for (j = 0; j < 24; j++) - { - lo[j] = 25 * 4 + (80 * 5 + 4) * j; /* Offset of line */ - ld = r_data + lo[j]; - *ld++ = 0; /* 0,2 == */ - *ld = 2; /* end of line */ - } - lo[j] = 0; /* Terminate line index */ -} - - - -/* - | Create the r_data array for a term - | This is typically quite fast (1ms or so on a RPC700) - | so we don't bother caching r_data for each term or using the - | 'frosh' concept. - */ -static void make_r_data(term_data *t) -{ - char **c = t->t.old->c; /* char array [24][80] */ - byte **a = t->t.old->a; /* attr array [24][80] */ - char *o; - int i, j, cf; - -/* New code: */ - - o = r_data + 25 * 4; /* First byte of r_data after line index */ - - if (force_mono) - { - for (j = 0; j < 24; j++) - { - /* Set up the line offset entry */ - ((int *)r_data)[j] = o - r_data; - - for (i = 0; i < 80; i++) - *o++ = a[j][i] != TERM_DARK ? c[j][i] : ' '; - /* 0,2 => end of line */ - *o++ = 0; - *o++ = 2; - } - } - else - { - for (j = 0; j < 24; j++) - { - /* Set up the line offset entry */ - ((int *)r_data)[j] = o - r_data; - - /* Each line starts in white */ - cf = TERM_WHITE; - - for (i = 0; i < 80; i++) - { - if (a[j][i] != cf) - { - /* 0,6 => change FG */ - *o++ = 0; - *o++ = 6; - cf = *o++ = a[j][i]; - } - *o++ = c[j][i]; - } - /* 0,2 => end of line */ - *o++ = 0; - *o++ = 2; - } - } -} - - -/* - | Set up 'zrb' for the current screen mode. - */ -static void set_up_zrb_for_mode(void) -{ - static char work_area[4096]; - zrb.r_workarea = work_area; - zrb.r_palette = zpalette; - zrb.r_linesp = 0; - zrb.r_for = TERM_WHITE; - zrb.r_bac = 0; - zrb.r_data = r_data; - SWI(2, 0, SWI_ZapRedraw_ReadVduVars, 0, &zrb); -} - - - -/* - | Set up the ZapRedrawBlock ready to redraw term 't' - | (caches the r_data as part of the process) - */ -static void set_up_zrb(term_data *t) -{ - int fw, fh; - - zrb.r_flags.value = 0; - - /* Set font info up */ - fw = t->font->w; - fh = t->font->h; - SWI(4, 4, SWI_ZapRedraw_CachedCharSize, zrb.r_bpp, 0, fw, fh, - NULL, NULL, &(zrb.r_cbpl), &(zrb.r_cbpc)); - zrb.r_caddr = (void *)(((int)t->font->bpp_n) - (t->font->f * zrb.r_cbpc)); - - zrb.r_charw = fw; /* Character size in pixels */ - zrb.r_charh = fh; - - if (t->font == SYSTEM_FONT) - zrb.r_flags.bits.double_height = screen_eig.y == 1; - else - zrb.r_flags.bits.double_height = 0; - - make_r_data(t); /* Cache the r_data */ -} - - - - - -static void redraw_window(window_redrawblock * rb, BOOL *more, term_data *t) -{ - int cx, cy, cw, ch; - - /* set GCOL for cursor colour */ - if (t->cursor.visible) - { - cw = zrb.r_charw << screen_eig.x; - ch = -(zrb.r_charh << screen_eig.y); - if (zrb.r_flags.bits.double_height) - { - ch *= 2; - } - cx = t->cursor.pos.x * cw; - cy = t->cursor.pos.y * ch; - cx += (rb->rect.min.x - rb->scroll.x); - cy += (rb->rect.max.y - rb->scroll.y); - cw -= (1 << screen_eig.x); - ch += (1 << screen_eig.y); - cy -= (1 << screen_eig.y); - } - - while (*more) - { - SWI(2, 0, SWI_ZapRedraw_GetRectangle, rb, &zrb); - SWI(2, 0, SWI_ZapRedraw_RedrawArea, NULL, &zrb); - if (t->cursor.visible) - { - ColourTrans_SetGCOL(cursor_rgb, 0, 0); - GFX_Move(cx, cy); - GFX_DrawBy(cw, 0); - GFX_DrawBy(0, ch); - GFX_DrawBy(-cw, 0); - GFX_DrawBy(0, -ch); - } - Wimp_GetRectangle(rb, more); - } -} - - - - - -static BOOL Hnd_Redraw(event_pollblock * pb, void *ref) -{ - term_data *t = (term_data *)ref; - window_redrawblock rb; - BOOL more; - - rb.window = t->w; - Wimp_RedrawWindow(&rb, &more); - - set_up_zrb(t); - - redraw_window(&rb, &more, t); - - return TRUE; -} - - - - - -static void refresh_window(term_data *t) -{ - window_redrawblock rb; - BOOL more; - int fw, fh; - - if ((t->changed_box.min.x >= t->changed_box.max.x) || - (t->changed_box.min.y >= t->changed_box.max.y)) - return; - - set_up_zrb(t); - - fw = zrb.r_charw << screen_eig.x; - fh = -(zrb.r_charh << screen_eig.y); - if (zrb.r_flags.bits.double_height) - { - fh *= 2; - } - - rb.window = t->w; - rb.rect.min.x = fw * t->changed_box.min.x; - rb.rect.max.x = fw * t->changed_box.max.x; - - rb.rect.max.y = fh * t->changed_box.min.y; - rb.rect.min.y = fh * t->changed_box.max.y; - - Wimp_UpdateWindow(&rb, &more); - redraw_window(&rb, &more, t); - - t->changed_box.min.x = t->changed_box.min.y = 255; - t->changed_box.max.x = t->changed_box.max.y = 0; -} - - - -static void refresh_windows(void) -{ - int i; - window_info info; - for (i = 0; i < MAX_TERM_DATA; i++) - { - info.window = data[i].w; - Wimp_GetWindowInfo(&info); - if (info.block.flags.data.open) - refresh_window(&(data[i])); - } -} - - -/* - | Set the size of a window. - | If the window grows but has no scroll bars then it is re-sized to - | the new extent. If it shrinks then it is resized regardless. - | - | If the window isn't open then it is opened behind the backwindow, - | resized and then closed again... I /did/ have a reason for doing this - | rather than simply recreating the window at the new size, but for the - | life of me I can't remember what it was... - */ -static void set_window_size(window_handle w, int width, int height) -{ - window_state ws; - int reclose; -/* - * int cw,ch; - */ - - Wimp_GetWindowState(w, &ws); - Window_SetExtent(w, 0, -height, width, 0); - - reclose = !ws.flags.data.open; - if (!(ws.flags.value & (0xf << 27))) - { - if (reclose) - { - ws.openblock.behind = -3; - Wimp_OpenWindow(&(ws.openblock)); - } - /* Removed - caused "pixel creep" :) - * cw = ws.openblock.screenrect.max.x; - * ch = ws.openblock.screenrect.max.y; - * cw -= ws.openblock.screenrect.min.x; - * ch -= ws.openblock.screenrect.min.y; - * ws.openblock.screenrect.min.x -= ((width-cw)/2)-(1<<screen_eig.x); - * ws.openblock.screenrect.min.y -= ((height-ch)/2)-(1<<screen_eig.y); - */ - ws.openblock.screenrect.max.x = ws.openblock.screenrect.min.x + width; - ws.openblock.screenrect.max.y = ws.openblock.screenrect.min.y + height; - Wimp_OpenWindow(&(ws.openblock)); - if (reclose) - { - Wimp_CloseWindow(w); - } - } -} - - - - - - - - - - - - - - - -/* - | Change the size of a window to suit the font displayed in it - */ -static void resize_term_for_font(term_data *t) -{ - int fw, fh; - set_up_zrb(t); - - fw = zrb.r_charw << screen_eig.x; - fh = zrb.r_charh << screen_eig.y; - if (zrb.r_flags.bits.double_height) - { - fh *= 2; - } - - /* Caulculate new size */ - fw *= 80; - fh *= 24; - - set_window_size(t->w, fw, fh); -} - - - - - - - - - - - - - - - - - - - -static BOOL Hnd_Caret(event_pollblock * pb, void *ref) -{ - if (ref) - got_caret = 1; - else - got_caret = 0; - return TRUE; -} - - - - -/* - | Attach a (named) font to the specified term. - | If 'font' is NULL then the system font is attached. - | The bpp_n data is calculated if necessary - | returns: - | 1 => the font was attached OK - | 0 => the system font was substituted - */ -static int attach_font_to_term(term_data *t, char *font) -{ - if (t->font != SYSTEM_FONT) - { - lose_font(t->font); - } - if (font) - { - t->font = find_font(font); - } - if (!t->font) - { - t->font = SYSTEM_FONT; - if (font) - { - Msgs_Report(1, "err.font_l", font); - } - } - else - { - if (!t->font->bpp_n) - { - lose_font(t->font); - t->font = SYSTEM_FONT; - if (font) - { - Msgs_Report(1, "err.font_c", font); - } - } - } - resize_term_for_font(t); - return !(t->font == SYSTEM_FONT); -} - - - - -/*--------------------------------------------------------------------------*/ - - - -/* - | Create a menu of all the (probable!) fonts in the specified location - | NB: Any file of type 'data' is considered a font. - | - | Subdirectories are recursively searched. - | - | 1.10 - Uses <variant>$FontPaths to get a (space separated) list of paths - | to search. For each path name, the menu text will be the name and the - | path searched will be <variant>$<name>$FontPath - | - | Eg. (for angband): - | Angband$FontPaths Zap Angband - | Angband$Zap$FontPath ZapFonts: - | Angband$Angband$FontPath Angband:xtra.fonts. - */ -static void make_font_menu(void) -{ - char *t; - char buffer[260]; - char menu_buffer[260]; - int paths; - int i; - unsigned int max_width; - const char *path[64]; /* pointers to path names */ - menu_item *mi; - - font_menu = NULL; - - /* Get the path (ie. dir) to look under */ - t = getenv(RISCOS_VARIANT "$FontPaths"); - - /* Hack: cope if the path isn't set */ - if (!t) - { - t = ""; - } - - strcpy(buffer, t); - - /* - | Count how many paths there are, build an array of pointers to them - | and terminate them in the buffer - */ - paths = 1; /* including the system font fake path '<System>' */ - for (t = buffer; *t; t++) - { - if (*t == ' ') - { - *t = 0; - } - else - { - if (t == buffer || !t[-1]) - { - path[paths] = t; - paths++; - } - } - } - - /* - | Create the menu - */ - path[0] = SYSTEM_FONT->name; - - font_menu = f_malloc(sizeof(menu_block) + paths * sizeof(menu_item)); - if (!font_menu) - { - core("Out of memory (building font menu)"); - } - memset(font_menu, 0, sizeof(menu_block) + paths * sizeof(menu_item)); - - strncpy(font_menu->title, "Fonts", 12); - font_menu->titlefore = 7; - font_menu->titleback = 2; - font_menu->workfore = 7; - font_menu->workback = 0; - font_menu->height = 44; - font_menu->gap = 0; - max_width = strlen(font_menu->title); - - mi = (menu_item *) (font_menu + 1); - - for (i = 0; i < paths; i++) - { - mi[i].submenu.value = -1; - mi[i].iconflags.data.text = 1; - mi[i].iconflags.data.filled = 1; - mi[i].iconflags.data.foreground = 7; - mi[i].iconflags.data.background = 0; - strncpy(mi[i].icondata.text, path[i], 12); - if (strlen(mi[i].icondata.text) > max_width) - max_width = strlen(mi[i].icondata.text); - } - font_menu->width = (max_width + 2) * 16; - mi[i - 1].menuflags.data.last = 1; - - /* - | Hack: add a dotted line after the system font entry if appropriate - */ - if (paths > 1) mi[0].menuflags.data.dotted = 1; - - /* - | Iterate over the paths, building the appropriate submenus - */ - for (i = 1; i < paths; i++) - { - menu_ptr sub_menu = NULL; - - sprintf(menu_buffer, "%s$%s$FontPath", RISCOS_VARIANT, path[i]); - t = getenv(menu_buffer); - /* Hack: cope if the path isn't defined */ - if (!t) - { - t = ""; - } - - /* Fudge so that the fontpath can be a path, not just a dir. */ - strcpy(menu_buffer, t); - for (t = menu_buffer; *t > ' '; t++) - ; - if (t[-1] == '.') - { - t--; - } - *t = 0; - - /* Build the menu. Don't bother if the path variable was empty */ - if (*menu_buffer) - sub_menu = make_zfont_menu(menu_buffer); - - if (!sub_menu) - { - mi[i].iconflags.data.shaded = 1; - } - else - { - mi[i].submenu.menu = sub_menu; - /* Override the title of the 'root' sub-menu */ - strncpy(sub_menu->title, path[i], 12); - /* Add the submenu to the main menu */ - } - } - - return; -} - -/* ----------------------------------------------- musus, xxxx-xx-xx --- - * Create and set up the infobox. - * --------------------------------------------------------------------- */ -static void create_info_box(void) -{ - info_box = Window_Create("info", template_TITLEMIN); - Icon_printf(info_box, 0, "%s %s", VARIANT, VERSION); - Icon_SetText(info_box, 2, AUTHORS); - Icon_SetText(info_box, 3, PORTERS); - Icon_SetText(info_box, 7, PORTVERSION); - - return; -} - -/* - | Create the various menus - */ -static void init_menus(void) -{ - char buffer1[256]; - char buffer2[32]; - char *o; - - create_info_box(); /* For the Info> entries */ - make_font_menu(); /* Make the fonts menu */ - - Msgs_Lookup("menu.ibar:Info|>Save As|Full screen,Gamma correction,Sound," - "Windows|Save choices|Quit (& save)", buffer1, 256); - ibar_menu = Menu_New(VARIANT, buffer1); - if (!ibar_menu) core("Can't create Iconbar menu!"); - - Msgs_Lookup("menu.term:Info|>Save As|Font,Windows", buffer1, 256); - term_menu = Menu_New(VARIANT, buffer1); - if (!term_menu) core("Can't create Term menu!"); - -#ifndef OLD_TERM_MENU - o = buffer1; - o += sprintf(buffer1, "%s|", VARIANT); - o += sprintf(o, "%s,%s,%s|", angband_term_name[1], angband_term_name[2], - angband_term_name[3]); - sprintf(o, "%s,%s,%s,%s", angband_term_name[4], angband_term_name[5], - angband_term_name[6], angband_term_name[7]); -#else - Msgs_printf(buffer1, "menu.windows:%s|Term-1 (Mirror),Term-2 (Recall)," - "Term-3 (Choice)|Term-4,Term-5,Term-6,Term-7", VARIANT); -#endif - Msgs_Lookup("menu.winT:Windows", buffer2, 32); - wind_menu = Menu_New(buffer2, buffer1); - if (!wind_menu) - { - core("Can't create Windows menu!"); - } - - /* Now attach the various submenus to where they belong */ - Menu_AddSubMenu(ibar_menu, IBAR_MENU_INFO, (menu_ptr) info_box); - Menu_AddSubMenu(ibar_menu, IBAR_MENU_GAMMA, (menu_ptr) gamma_win); - Menu_AddSubMenu(ibar_menu, IBAR_MENU_SOUND, (menu_ptr) sound_win); - Menu_AddSubMenu(ibar_menu, IBAR_MENU_WINDOWS, (menu_ptr) wind_menu); - Menu_AddSubMenu(term_menu, TERM_MENU_INFO, (menu_ptr) info_box); - Menu_AddSubMenu(term_menu, TERM_MENU_WINDOWS, wind_menu); - - /* Add the savebox */ - Menu_Warn(ibar_menu, IBAR_MENU_SAVE, TRUE, Hnd_SaveWarning, NULL); - Menu_Warn(term_menu, TERM_MENU_SAVE, TRUE, Hnd_SaveWarning, NULL); - - if (font_menu) - /* add the submenu */ - Menu_AddSubMenu(term_menu, TERM_MENU_FONT, font_menu); - else - /* If the font menu is buggered, shade its entry */ - /* unticked, shaded */ - Menu_SetFlags(term_menu, TERM_MENU_FONT, FALSE, TRUE); -} - - - - -static void grab_caret(void) -{ - caret_block cb; - cb.window = data[0].w; - cb.icon = -1; - cb.height = 1 << 25; /* Invisible */ - Wimp_SetCaretPosition(&cb); -} - - - - -/* - | (Recursively) clear all ticks from the specified menu - */ -static void clear_all_menu_ticks(menu_ptr mp) -{ - menu_item *mi = (menu_item *) (mp + 1); - - do - { - if (mi->menuflags.data.ticked) - mi->menuflags.data.ticked = 0; - if (mi->submenu.value != -1) - clear_all_menu_ticks(mi->submenu.menu); - mi++; - } - while (mi[-1].menuflags.data.last != 1); -} - - - - - - -/* - | Set the font menu's ticks to match the specifed font name. - | - | fm is the (sub) menu to scan down (recursing into it's submenus (if any)) - | fn is the font name to match - | prefix is the menu text to be prepended to the menu entries due to - | previous menus (eg. "08x16" will cause fn="08x16.fred" to match menu - | entry "fred". - | - | NB: recursive. - | - */ - -static void set_font_menu_ticks(menu_ptr fm, char *fn, const char *prefix) -{ - char buffer[260]; - char *b_leaf; /* -> menu 'leaf' text in buffer */ - int pl; /* prefix string length */ - menu_item *mi = (menu_item *) (fm + 1); - - strcpy(buffer, prefix); - pl = strlen(buffer); - b_leaf = buffer + pl; - - do - { - /* Check for (substring) match */ - strncpy(b_leaf, mi->icondata.text, 12); - - /* Is it a sub-menu? */ - if (mi->submenu.value == -1) - { - /* No - must be an exact match */ - mi->menuflags.data.ticked = !strcmp(buffer, fn); - } - else - { - /* Yes - must be a partial match (with a dot on :) */ - strcat(b_leaf, "."); - mi->menuflags.data.ticked = - !strncmp(buffer, fn, pl + strlen(b_leaf)); - if (mi->menuflags.data.ticked) - set_font_menu_ticks(mi->submenu.menu, fn, buffer); - else - clear_all_menu_ticks(mi->submenu.menu); - } - - /* Next item */ - mi++; - } - while (mi[-1].menuflags.data.last != 1); /* Until finished */ -} - - - - - - - - - - - -/* - | Set ticks, etc. in the term_menu to reflect the current state of the - | term 't' - */ -static void set_up_term_menu(term_data *t) -{ - int i; - menu_ptr mp; - menu_item *mi; - window_state ws; - - /* First of all, set up menu title to be the term's title */ - strncpy(term_menu->title, t->name, 12); - - /* Now set the ticks in the Windows> submenu (cuz it's easy) */ - mp = wind_menu; /* Windows submenu */ - mi = (menu_item *) (mp + 1); /* First entry */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - Wimp_GetWindowState(data[i].w, &ws); - mi[i].menuflags.data.ticked = ws.flags.data.open; - } - - /* - | Now, the tricky bit: find out which font is selected in this - | term and tick it in the menu. Untick all the rest. - */ - set_font_menu_ticks(font_menu, t->font->name, ""); - - /* Shade the 'Save>' entry if saving isn't possible (yet) */ - if (game_in_progress && character_generated) - Menu_SetFlags(term_menu, TERM_MENU_SAVE, 0, PDEADCHK); - else - Menu_SetFlags(term_menu, TERM_MENU_SAVE, 0, TRUE); - -} - - - -/* - | Generic 'click' handler for windows - turns a drag on the window - | into a move-window style drag. - */ -static BOOL Hnd_Click(event_pollblock * pb, void *ref) -{ - if (pb->data.mouse.button.data.dragselect || - pb->data.mouse.button.data.dragadjust) - { - drag_block b; - b.window = pb->data.mouse.window; - b.screenrect.min.x = b.screenrect.min.y = 0; - b.screenrect.max.x = screen_size.x; - b.screenrect.max.y = screen_size.y; - b.type = drag_MOVEWINDOW; - Wimp_DragBox(&b); - } - - return TRUE; -} - - - -/* - | Handle a click on a Term window. - */ -static BOOL Hnd_TermClick(event_pollblock * pb, void *ref) -{ - term_data *t = (term_data *)ref; - - if (pb->data.mouse.button.data.menu) - { - menu_term = t; - set_up_term_menu(t); - Menu_Show(term_menu, pb->data.mouse.pos.x - 32, - pb->data.mouse.pos.y + 32); - } - else - { - grab_caret(); - Hnd_Click(pb, ref); - } - - return TRUE; -} - -#endif /* FULLSCREEN_ONLY */ - - - -static void mark_ood(term_data *t, int minx, int miny, int maxx, int maxy) -{ - if (t->changed_box.min.x > minx) - t->changed_box.min.x = minx; - if (t->changed_box.max.x < maxx) - t->changed_box.max.x = maxx; - if (t->changed_box.min.y > miny) - t->changed_box.min.y = miny; - if (t->changed_box.max.y < maxy) - t->changed_box.max.y = maxy; -} - - -#ifndef FULLSCREEN_ONLY - -/* Check for an event (ie. key press) */ -static errr Term_xtra_acn_check(void) -{ - static int last_poll = 0; - unsigned int curr_time; - int bh, bl; - - /* - | Only poll the wimp if there's something in the keyboard buffer - | or every 10cs. This is presumably so that we process as many - | keypresses as possible before any other application gets a go. - */ - - /* Check the kbd buffer */ - SWI(3, 3, SWI_OS_Byte, 128, 255, 0, /**/ NULL, &bl, &bh); - bl = (bl & 0xff) + (bh << 8); - - /* Check how long it is since we last polled */ - curr_time = Time_Monotonic(); - - if ((bl > 0 && got_caret) || ((curr_time - last_poll) > 9)) - { - last_poll = curr_time; - Stop_Hourglass; - Event_Poll(); - Start_Hourglass; - } - - /* - | This allows the user to interrupt the borg. - */ - if (key_pressed) return key_pressed = 0; - - return 1; -} - - -/* - | Wait for an event (ie. keypress) - | Note that we idle poll once a second to allow us to implement the - | alarm system. - */ -static errr Term_xtra_acn_event(void) -{ - Stop_Hourglass; - - while (!key_pressed && !fullscreen_font) - { - Event_PollIdle(100); - } - Start_Hourglass; - - return key_pressed = 0; -} - - - -/* React to changes (eg. palette change) */ -static errr Term_xtra_acn_react(void) -{ - int c; - - cache_palette(); - - /* Mark the entirety of each window as out of date */ - for (c = 0; c < MAX_TERM_DATA; c++) - mark_ood(&data[c], 0, 0, 80, 24); - - /* Force a redraw of the windows */ - refresh_windows(); - - /* Success */ - return 0; -} - - - -/* Do various things to a term */ -static errr Term_xtra_acn(int n, int v) -{ - term_data *t = (term_data *)Term; - - switch (n) - { - case TERM_XTRA_CLEAR: /* Clear the Term */ - /*for ( i=0; i<Term->hgt; i++ ) - t->froshed[i] = 1; */ - mark_ood(t, 0, 0, Term->wid, Term->hgt); - /*refresh_window( t ); - NB: Term isn't actually cleared yet! */ - /* Success */ - return 0; - - case TERM_XTRA_EVENT: /* Wait/check for an event */ - if (v) - return Term_xtra_acn_event(); - else - return Term_xtra_acn_check(); - - case TERM_XTRA_BORED: /* Bored */ - return Term_xtra_acn_check(); - - case TERM_XTRA_FLUSH: /* Flush input */ - if (got_caret) - { - /* 1.21 - Hack: wait until no keys are pressed */ - if (hack_flush) - for (v = 0; v != 0xff;) - SWI(1, 2, SWI_OS_Byte, 122, 0, &v); - SWI(3, 0, SWI_OS_Byte, 21, 0, 0); /* Flush Kbd buffer */ - } - return 0; - - case TERM_XTRA_FRESH: /* Flush output */ - refresh_window(t); - return 0; - - case TERM_XTRA_FROSH: /* Ensure line 'v' is plotted */ - /* Doesn't do anything */ - return 0; - - case TERM_XTRA_SHAPE: /* Set cursor visibility */ - t->cursor.visible = v ? TRUE : FALSE; - mark_ood(t, t->cursor.pos.x, t->cursor.pos.y, - t->cursor.pos.x + 1, t->cursor.pos.y + 1); - refresh_window(t); /* needed? */ - return 0; - - case TERM_XTRA_NOISE: /* Make a beep */ - Sound_SysBeep(); - return 0; - - case TERM_XTRA_REACT: /* React to, eg. palette changes */ - return Term_xtra_acn_react(); - - case TERM_XTRA_DELAY: /* Delay for 'v' ms */ - if (v > 0) - { - unsigned int start = Time_Monotonic(); - v = (v + 5) / 10; /* Round to nearest cs */ - GFX_Wait(); - while ((Time_Monotonic() - start) < v) - ; - } - return 0; - - case TERM_XTRA_SOUND: /* Play a sound :) */ - if (enable_sound) - { - play_sound(v); - } - return 0; - - /* Subdirectory scan */ - case TERM_XTRA_SCANSUBDIR: - { - filing_dirdata directory; - filing_direntry *entry; - - scansubdir_max = 0; - - if (Filing_OpenDir(riscosify_name(scansubdir_dir), &directory, sizeof(filing_direntry), readdirtype_DIRENTRY) != NULL) - { - Error_Report(0, "Couldn't open directory \"%s\"", riscosify_name(scansubdir_dir)); - return 0; - } - - while ((entry = Filing_ReadDir(&directory)) != NULL) - { - if (entry->objtype == filing_DIRECTORY) - { - string_free(scansubdir_result[scansubdir_max]); - scansubdir_result[scansubdir_max] = string_make(entry->name); - ++scansubdir_max; - } - } - - Filing_CloseDir(&directory); - - return 0; - } - - /* Return current "time" in milliseconds */ - case TERM_XTRA_GET_DELAY: - { - Term_xtra_long = Time_Monotonic() * 100; - - return 0; - } - - /* Rename main window */ - case TERM_XTRA_RENAME_MAIN_WIN: - { - Window_SetTitle(data[0].w, angband_term_name[0]); - return 0; - } - - default: - return 1; /* Unsupported */ - } -} - - - -/* Move (but don't necessarily display) the cursor */ -static errr Term_curs_acn(int x, int y) -{ - term_data *t = (term_data *)Term; - - if (t->cursor.visible) - mark_ood(t, t->cursor.pos.x, t->cursor.pos.y, - t->cursor.pos.x + 1, t->cursor.pos.y + 1); - - t->cursor.pos.x = x; - t->cursor.pos.y = y; - - if (t->cursor.visible) - mark_ood(t, t->cursor.pos.x, t->cursor.pos.y, - t->cursor.pos.x + 1, t->cursor.pos.y + 1); - - return 0; -} - - - -/* - | NB: these two are very simple since we use the Term's contents - | directly to generate the r_data for ZapRedraw. - */ - -/* Erase 'n' characters at (x,y) */ -static errr Term_wipe_acn(int x, int y, int n) -{ - mark_ood((term_data *)Term, x, y, x + n, y + 1); - return 0; -} - -/* Write 'n' characters from 's' with attr 'a' at (x,y) */ -static errr Term_text_acn(int x, int y, int n, byte a, cptr s) -{ - mark_ood((term_data *)Term, x, y, x + n, y + 1); - return 0; -} - -#endif /* FULLSCREEN_ONLY */ - - -/* Initialise one of our terms */ -static void Term_init_acn(term *t) -{ - term_data *term = (term_data *)t; - - /* Ludicrous changed box settings :) */ - term->changed_box.min.x = 256; - term->changed_box.min.y = 256; - term->changed_box.max.x = 0; - term->changed_box.max.y = 0; -} - - - -static void term_data_link(term_data *td, int k) -{ - term *t = &(td->t); - - /* Initialise the term */ - term_init(t, 80, 24, k); - - /* Set flags and hooks */ - t->attr_blank = TERM_WHITE; - t->char_blank = ' '; - - /* Experiment (FS mode requires them) */ - t->always_text = TRUE; - t->never_frosh = TRUE; - /* Experiment (FS mode requires them) */ - -#ifdef FULLSCREEN_ONLY - t->wipe_hook = Term_wipe_acnFS; - t->xtra_hook = Term_xtra_acnFS; - t->curs_hook = Term_curs_acnFS; - t->text_hook = Term_text_acnFS; -#else - t->init_hook = Term_init_acn; - t->xtra_hook = Term_xtra_acn; - t->wipe_hook = Term_wipe_acn; - t->curs_hook = Term_curs_acn; - t->text_hook = Term_text_acn; - t->user_hook = Term_user_acn; -#endif /* FULLSCREEN_ONLY */ - - t->data = td; - - Term_activate(t); -} - - -#ifndef FULLSCREEN_ONLY - -/* Open default windows (ie. as set in choices) at the appropriate sizes */ -static void show_windows(void) -{ - int i; - for (i = MAX_TERM_DATA; i-- > 0;) - { - if (!data[i].unopened) - { - if (data[i].def_open) - Window_Show(data[i].w, open_WHEREVER); - } - else - { - if (data[i].def_open) - { - window_openblock ob; - ob.window = data[i].w; - ob.screenrect = data[i].def_pos; - ob.scroll = data[i].def_scroll; - ob.behind = -1; - Wimp_OpenWindow(&ob); - data[i].unopened = 0; - } - } - } -} - - -/* - | 'ref' is used to indicate whether this close is being forced by some other - | part of the code (eg. the Windows> submenu code). This is used to modify - | the 'adjust doesn't close other terms' behavior. - */ - -static BOOL Hnd_MainClose(event_pollblock * pb, void *ref) -{ - int i; - window_state ws; - mouse_block mb; - - /* New in 1.08: don't close other Terms if closed with adjust */ - Wimp_GetPointerInfo(&mb); - if (ref || mb.button.data.adjust) - { - Wimp_CloseWindow(data[0].w); - } - else - { - /* Close all the terms, but mark the open ones as 'def_open' */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - Wimp_GetWindowState(data[i].w, &ws); - if (!ws.flags.data.open) - { - data[i].def_open = 0; - } - else - { - Wimp_CloseWindow(data[i].w); - data[i].def_open = 1; - } - } - } - - return TRUE; -} - - -static BOOL Hnd_PaletteChange(event_pollblock * pb, void *ref) -{ - cache_palette(); - return TRUE; -} - - - -static BOOL Hnd_ModeChange(event_pollblock * pb, void *ref) -{ - int i; - Screen_CacheModeInfo(); - set_up_zrb_for_mode(); /* (re)set up the redraw block */ - cache_palette(); /* (re)cache the palette */ - cache_fonts(); /* (re)cache the fonts */ - /* Enforce sizes (eg. if screen_eig.y has changed) */ - for (i = 0; i < MAX_TERM_DATA; i++) - resize_term_for_font(&(data[i])); - return TRUE; -} - - - - -static BOOL Hnd_Keypress(event_pollblock * pb, void *ref) -{ - static const char hex[] = "0123456789ABCDEF"; - int c = pb->data.key.code; - /* Check whether this key was pressed in Term 0 */ - if (pb->data.key.caret.window == data[0].w) - { - switch (c) - { - case keycode_F12: - case keycode_SHIFT_F12: - case keycode_CTRL_F12: - case keycode_CTRL_SHIFT_F12: - /* Never intercept these */ - break; - - case 27: /* handle escape specially */ - if (Kbd_KeyDown(inkey_CTRL)) - { - ack_alarm(); - return TRUE; - } - - /* Send everything else onto the Term package */ - default: - /* Take care of "special" keypresses */ - switch (c) - { - case keycode_TAB: - { - c = '\t'; - break; - } - - case keycode_PAGEUP: - { - c = '9'; - break; - } - - case keycode_PAGEDOWN: - { - c = '3'; - break; - } - - case keycode_COPY: - { - c = '1'; - break; - } - - case keycode_HOME: - { - c = '7'; - break; - } - } - /* Pass to the angband engine */ - /* Allow shift & ctrl to modify the keypad keys */ - if (c >= '0' && c <= '9') - { - kbd_modifiers m = Kbd_GetModifiers(FALSE); - if (m.shift) - { - c |= 0x800; - } - if (m.ctrl) - { - c |= 0x400; - } - /* Could maybe add ALT as 0x1000 ??? */ - } - - /* Keys >255 have to be send as escape sequences (31=escape) */ - if (c > 255 || c == 31) - { - Term_keypress(31); - Term_keypress(hex[(c & 0xf00) >> 8]); - Term_keypress(hex[(c & 0x0f0) >> 4]); - Term_keypress(hex[(c & 0x00f)]); - c = 13; - } - Term_keypress(c); - key_pressed = 1; - /*if ( c==27 ) { escape_pressed = 1; } */ - return TRUE; - } - } - - Wimp_ProcessKey(c); - return TRUE; -} - - -/*--------------------------------------------------------------------------*/ -/* Gamma correction window stuff */ -/*--------------------------------------------------------------------------*/ - -static void redraw_gamma(window_redrawblock * rb, BOOL *more) -{ - int i, y, x, h, w; - int bx, by; - int dither; - - bx = Coord_XToScreen(GC_XOFF, (convert_block *) & (rb->rect)); - by = Coord_YToScreen(GC_YOFF, (convert_block *) & (rb->rect)); - - h = GC_HEIGHT / 4; - w = GC_WIDTH / 16; - - x = bx; - - while (*more) - { - for (i = 0; i < 16; i++) - { - y = by; - for (dither = 0; dither < 2; dither++) - { - /* Solid block: */ - ColourTrans_SetGCOL(palette[i], dither << 8, 0); - GFX_RectangleFill(x, y, w, -h); - y -= h; - /* Dot on black: */ - ColourTrans_SetGCOL(palette[0], dither << 8, 0); - GFX_RectangleFill(x, y, w, -h); - ColourTrans_SetGCOL(palette[i], dither << 8, 0); - GFX_RectangleFill(x + (w / 2) - 2, y - (h / 2), 2, 2); - y -= h; - } - x += w; - } - Wimp_GetRectangle(rb, more); - } -} - - -static void update_gamma(void) -{ - window_redrawblock rb; - BOOL more; - - rb.window = gamma_win; - rb.rect.min.x = GC_XOFF; - rb.rect.min.y = GC_YOFF - GC_HEIGHT; - rb.rect.max.y = GC_XOFF + GC_WIDTH + screen_delta.x; - rb.rect.max.y = GC_YOFF + screen_delta.y; - - Wimp_UpdateWindow(&rb, &more); - if (more) - { - redraw_gamma(&rb, &more); - } -} - - - -static BOOL Hnd_RedrawGamma(event_pollblock * pb, void *ref) -{ - window_redrawblock rb; - BOOL more; - - rb.window = pb->data.openblock.window; - Wimp_RedrawWindow(&rb, &more); - if (more) - { - redraw_gamma(&rb, &more); - } - - return TRUE; -} - - -static BOOL Hnd_GammaClick(event_pollblock * pb, void *ref) -{ - int up = (ref == 0); - - if (up) - { - if (gamma < 9.0) - { - gamma += 0.05; - Icon_SetDouble(gamma_win, 0, gamma, 2); - Term_xtra_acn_react(); - update_gamma(); - } - } - else - { - if (gamma > 0.05) - { - gamma -= 0.05; - Icon_SetDouble(gamma_win, GAMMA_ICN, gamma, 2); - Term_xtra_acn_react(); - update_gamma(); - } - } - - /* Hack: if the user menu is active then force it to redraw */ - if (user_menu_active) - { - Term_keypress(18); - key_pressed = 1; - } - - return TRUE; -} - -/* - | Reflect the current options in the gamma window - */ -static void set_gamma_window_state(void) -{ - if (minimise_memory) return; - - Icon_SetDouble(gamma_win, 0, gamma, 2); -} - - -static void init_gamma_window(void) -{ - if (minimise_memory) return; - - Template_UseSpriteArea(resource_sprites); - gamma_win = Window_Create("gamma", template_TITLEMIN); - Template_UseSpriteArea(NULL); - Event_Claim(event_REDRAW, gamma_win, event_ANY, Hnd_RedrawGamma, 0); - Event_Claim(event_CLICK, gamma_win, GAMMA_DOWN, Hnd_GammaClick, (void *)1); - Event_Claim(event_CLICK, gamma_win, GAMMA_UP, Hnd_GammaClick, (void *)0); - set_gamma_window_state(); -} - - -/*--------------------------------------------------------------------------*/ -/* Sound options window stuff */ -/*--------------------------------------------------------------------------*/ - -static slider_info volume_slider; - - -/* - | Reflect the current sound config in the sound options window - */ -static void set_sound_window_state(void) -{ - if (minimise_memory) return; - - Icon_SetSelect(sound_win, SND_ENABLE, enable_sound); - Slider_SetValue(&volume_slider, sound_volume, NULL, NULL); - - if (sound_volume > 127) - volume_slider.colour.foreground = colour_RED; - else - volume_slider.colour.foreground = colour_GREEN; -} - - - -/* - | The sound slider has been dragged, so update the sound volume setting - */ -static int update_volume_from_slider(slider_info *si, void *ref) -{ - sound_volume = Slider_ReadValue(si); - - if (sound_volume > 127) - volume_slider.colour.foreground = colour_RED; - else - volume_slider.colour.foreground = colour_GREEN; - - return 0; -} - - -/* - | Handle redraw events for the sound options window - */ -static BOOL Hnd_RedrawSnd(event_pollblock * pb, void *ref) -{ - window_redrawblock redraw; - BOOL more; - - redraw.window = pb->data.openblock.window; - Wimp_RedrawWindow(&redraw, &more); - - while (more) - { - Slider_Redraw(((slider_info *) ref), &redraw.cliprect); - Wimp_GetRectangle(&redraw, &more); - } - return (TRUE); -} - - -/* - | Handle clicks on the sound options window - */ -static BOOL Hnd_SndClick(event_pollblock * pb, void *ref) -{ - int icn = pb->data.mouse.icon; - int adj = pb->data.mouse.button.data.adjust; - slider_info *si = (slider_info *) ref; - - switch (icn) - { - /* Bump arrows for the slider: */ - case SND_VOL_DOWN: - adj = !adj; - - case SND_VOL_UP: - adj = adj ? -1 : 1; - sound_volume += adj; - if (sound_volume < SOUND_VOL_MIN) - { - sound_volume = SOUND_VOL_MIN; - } - if (sound_volume > SOUND_VOL_MAX) - { - sound_volume = SOUND_VOL_MAX; - } - set_sound_window_state(); - break; - - /* The slider itself */ - case SND_VOL_SLIDER: - Icon_ForceRedraw(sound_win, SND_VOL_SLIDER); - Slider_Drag(si, NULL, NULL, NULL); - break; - - /* The enable/disable icon */ - case SND_ENABLE: - enable_sound = !enable_sound; - Icon_SetSelect(sound_win, SND_ENABLE, enable_sound); - if (enable_sound) - { - initialise_sound(); - } - break; - } - - /* Hack: if the user menu is active then force it to redraw */ - if (user_menu_active) - { - Term_keypress(18); - key_pressed = 1; - } - - return TRUE; -} - - - -/* - | Set the sound options window up, ready to rock :) - */ -static void init_sound_window(void) -{ - Template_UseSpriteArea(resource_sprites); - sound_win = Window_Create("sound", template_TITLEMIN); - Template_UseSpriteArea(NULL); - - Event_Claim(event_REDRAW, sound_win, event_ANY, Hnd_RedrawSnd, - (void *)&volume_slider); - Event_Claim(event_CLICK, sound_win, event_ANY, Hnd_SndClick, - (void *)&volume_slider); - - /* Set up the slider info */ - volume_slider.window = sound_win; - volume_slider.icon = SND_VOL_SLIDER; - volume_slider.limits.min = SOUND_VOL_MIN; - volume_slider.limits.max = SOUND_VOL_MAX; - volume_slider.colour.foreground = colour_GREEN; - volume_slider.colour.background = colour_WHITE; - volume_slider.border.x = 8; - volume_slider.border.y = 8; - volume_slider.update = update_volume_from_slider; - - set_sound_window_state(); -} - - - - - -/*--------------------------------------------------------------------------*/ - - - - - - - - - - - -/* - | A font has been selected. - | At this point, menu_term is a pointer to the term for which the - | menu was opened. - */ -static void handle_font_selection(int *s) -{ - char name[260]; - os_error *e; - char *r; - menu_ptr mp = font_menu; - int *mis; - - /* Follow the >s to the entry specified */ - for (mis = s; *mis != -1; mis++) - mp = ((menu_item *) (mp + 1))[*mis].submenu.menu; - - /* - | Now, check to see if we've hit a leaf entry. - | NB: If the entry isn't a leaf entry then the first entry in its submenu - | is used instead - */ - if (((int)mp) != -1) - { - mis[0] = 0; - mis[1] = -1; - mp = ((menu_item *) (mp + 1))[0].submenu.menu; - } - - if (((int)mp) != -1) - return; - - e = Wimp_DecodeMenu(font_menu, s, name); - if (e) - { - plog(e->errmess); - return; - } - - /* Make sure that the string is NULL terminated */ - for (r = name; *r >= ' '; r++) - ; - *r = 0; - - attach_font_to_term(menu_term, name); - mark_ood(menu_term, 0, 0, 80, 24); - refresh_window(menu_term); -} - - -#endif /* FULLSCREEN_ONLY */ - - - - -static void load_choices(void) -{ - FILE *fp = NULL; - char *cf; - int i; - char buffer[260]; - - cf = find_choices(FALSE); - if (*cf) - fp = fopen(cf, "r"); - - /* Implement default choices */ - data[0].def_open = 1; - data[0].unopened = 1; /* ie. force def_pos */ - data[0].def_pos.min.x = (screen_size.x - 1280) / 2; - data[0].def_pos.max.x = (screen_size.x + 1280) / 2; - data[0].def_pos.min.y = (screen_size.y - 768) / 2 - 32; - data[0].def_pos.max.y = (screen_size.y + 768) / 2 - 32; - data[0].def_scroll.x = data[0].def_scroll.y = 0; - for (i = 1; i < MAX_TERM_DATA; i++) - { - data[i].def_open = 0; - data[i].unopened = 1; /* ie. force def_pos */ - data[i].def_pos.min.x = (screen_size.x - 1280) / 2; - data[i].def_pos.max.x = (screen_size.x + 1280) / 2; - data[i].def_pos.min.y = (screen_size.y - 768) / 2; - data[i].def_pos.max.y = (screen_size.y + 768) / 2; - data[i].def_scroll.x = data[i].def_scroll.y = 0; - } - - if (fp) - { - const char *t_; - char *o_; - - if (!fgets(buffer, sizeof(buffer), fp)) - { - fclose(fp); - return; - } - if (strcmp(buffer, "[Angband config, Musus' port]\n")) - { - fclose(fp); - return; - } - - /* Load choices */ - while (fgets(buffer, sizeof(buffer), fp)) - { - t_ = strtok(buffer, " "); /* Term number (or keyword, "Gamma", etc.) */ - o_ = strtok(NULL, "\n"); /* argument string */ - if (!o_) - { - o_ = ""; - } /* missing (or null) argument? */ - if (t_) - { - if (!strcmp(t_, "Gamma")) - gamma = atof(o_); - else if (!strcmp(t_, "Monochrome")) - force_mono = !strcmp(o_, "on"); - else if (!strcmp(t_, "Sound")) - enable_sound = !strcmp(o_, "on"); - else if (!strcmp(t_, "Volume")) - sound_volume = atoi(o_); - else if (!strcmp(t_, "FullScreen")) - start_fullscreen = !strcmp(o_, "on"); - else if (!strcmp(t_, "Hourglass")) - use_glass = !strcmp(o_, "on"); - else if (!strcmp(t_, "HackFlush")) - hack_flush = !strcmp(o_, "on"); - else if (!strcmp(t_, "AlarmTimeH")) - alarm_h = atoi(o_); - else if (!strcmp(t_, "AlarmTimeM")) - alarm_m = atoi(o_); - else if (!strcmp(t_, "AlarmText")) - strcpy(alarm_message, o_); - else if (!strcmp(t_, "AlarmBeep")) - alarm_beep = !strcmp(o_, "on"); - else if (!strcmp(t_, "AlarmType")) - { - int i; - for (i = 0; i < 4; i++) - if (!strcmp(alarm_types[i], o_)) - alarm_type = i; - } - else if (isdigit((unsigned char)*t_)) - { - int t = atoi(t_); - if (t >= 0 && t < MAX_TERM_DATA) - { - char *f_, *x0_, *y0_, *x1_, *y1_, *sx_, *sy_; - o_ = strtok(o_, " "); /* first word */ - f_ = strtok(NULL, " "); /* font name */ - x0_ = strtok(NULL, " "); /* x posn (min) */ - y0_ = strtok(NULL, " "); /* y posn (min) */ - x1_ = strtok(NULL, " "); /* x posn (max) */ - y1_ = strtok(NULL, " "); /* y posn (max) */ - sx_ = strtok(NULL, " "); /* x scroll offset */ - sy_ = strtok(NULL, "\n"); /* y scroll offset */ - data[t].def_open = (t == 0) || atoi(o_); - data[t].def_pos.min.x = atoi(x0_); - data[t].def_pos.min.y = atoi(y0_); - data[t].def_pos.max.x = atoi(x1_); - data[t].def_pos.max.y = atoi(y1_); - data[t].def_scroll.x = atoi(sx_); - data[t].def_scroll.y = atoi(sy_); - data[t].unopened = 1; /* ie. force def_pos */ -#ifndef FULLSCREEN_ONLY - attach_font_to_term(&(data[t]), f_); -#endif /* FULLSCREEN_ONLY */ - } - } - } - } - fclose(fp); - } - -#ifndef FULLSCREEN_ONLY - /* - | Fudge so that the main term is *always* fullsize - */ - { - int fw, fh; - - set_up_zrb(&(data[0])); - fw = zrb.r_charw << screen_eig.x; - fh = zrb.r_charh << screen_eig.y; - if (zrb.r_flags.bits.double_height) - { - fh *= 2; - } - fw *= 80; - fh *= 24; - data[0].def_pos.max.x = data[0].def_pos.min.x + fw; - data[0].def_pos.max.y = data[0].def_pos.min.y + fh; - data[0].def_scroll.x = 0; - data[0].def_scroll.y = 0; - } -#endif /* FULLSCREEN_ONLY */ - - -} - - - - -static void save_choices(void) -{ - FILE *fp = NULL; - FILE *fpm = NULL; - char *cf; - int i; - - write_alarm_choices(); - - cf = find_choices(TRUE); - if (!*cf) - { - plog("Failed to locate writable choices file!"); - return; - } - - fp = fopen(cf, "w"); - if (!fp) - { - plog("Can't write choices file"); - return; - } - - fpm = fopen(find_choices_mirror(), "w"); - - f2printf(fp, fpm, "[Angband config, Musus' port]\n"); - f2printf(fp, fpm, "Gamma %.2lf\n", gamma); - f2printf(fp, fpm, "Monochrome %s\n", force_mono ? "on" : "off"); - f2printf(fp, fpm, "Sound %s\n", enable_sound ? "on" : "off"); - f2printf(fp, fpm, "Volume %d\n", sound_volume); - f2printf(fp, fpm, "FullScreen %s\n", start_fullscreen ? "on" : "off"); - f2printf(fp, fpm, "Hourglass %s\n", use_glass ? "on" : "off"); - f2printf(fp, fpm, "HackFlush %s\n", hack_flush ? "on" : "off"); - - for (i = 0; i < MAX_TERM_DATA; i++) - { - window_state ws; - Wimp_GetWindowState(data[i].w, &ws); - f2printf(fp, fpm, "%d %d %s ", i, ws.flags.data.open, - data[i].font->name); - f2printf(fp, fpm, "%d ", ws.openblock.screenrect.min.x); - f2printf(fp, fpm, "%d ", ws.openblock.screenrect.min.y); - f2printf(fp, fpm, "%d ", ws.openblock.screenrect.max.x); - f2printf(fp, fpm, "%d ", ws.openblock.screenrect.max.y); - f2printf(fp, fpm, "%d %d\n", ws.openblock.scroll.x, - ws.openblock.scroll.y); - } - - fclose(fp); - - if (fpm) - { - fclose(fpm); - } -} - -/* - | Update the Alarm choices file to reflect changed alarm settings. - */ -static void write_alarm_choices(void) -{ - FILE *fp; - char *cf; - - /* Open the choices file for reading */ - cf = find_alarmfile(TRUE); - if (!*cf) - { - plog("Can't determine Alarm file location!"); - return; - } - - fp = fopen(cf, "w"); - if (!fp) - { - plog("Can't write Alarm file"); - return; - } - - /* Write the new alarm options */ - fprintf(fp, "AlarmType %s\n", alarm_types[alarm_type]); - fprintf(fp, "AlarmTimeH %d\n", alarm_h); - fprintf(fp, "AlarmTimeM %d\n", alarm_m); - fprintf(fp, "AlarmText %s\n", alarm_message); - fprintf(fp, "AlarmBeep %s\n", alarm_beep ? "on" : "off"); - - fclose(fp); -} - -/* - | Read the Alarm choices file. - */ -static void read_alarm_choices(void) -{ - char buffer[260]; - FILE *fp; - char *cf; - - cf = find_alarmfile(FALSE); - if (!*cf) - { - return; - } - - fp = fopen(cf, "r"); - if (fp) - { - const char *t_, *o_; - /* Load choices */ - while (fgets(buffer, sizeof(buffer), fp)) - { - t_ = strtok(buffer, " "); /* Keyword */ - o_ = strtok(NULL, "\n"); /* argument string */ - if (!o_) - { - o_ = ""; - } /* missing (or null) argument? */ - if (t_) - { - if (!strcmp(t_, "AlarmTimeH")) - alarm_h = atoi(o_); - else if (!strcmp(t_, "AlarmTimeM")) - alarm_m = atoi(o_); - else if (!strcmp(t_, "AlarmText")) - strcpy(alarm_message, o_); - else if (!strcmp(t_, "AlarmBeep")) - alarm_beep = !strcmp(o_, "on"); - else if (!strcmp(t_, "AlarmType")) - { - int i; - for (i = 0; i < 4; i++) - if (!strcmp(alarm_types[i], o_)) - alarm_type = i; - } - } - } - fclose(fp); - } -} - - - -#ifndef FULLSCREEN_ONLY -/* - | Handle selections from the term menu(s) - */ -static BOOL Hnd_TermMenu(event_pollblock * pb, void *ref) -{ - mouse_block mb; - int i; - - Wimp_GetPointerInfo(&mb); - - switch (pb->data.selection[0]) - { - case TERM_MENU_INFO: /* Info> */ - break; - case TERM_MENU_FONT: /* Font> */ - /* Sub item selected? */ - if (pb->data.selection[1] == -1) - { - break; - } - handle_font_selection(pb->data.selection + 1); - break; - case TERM_MENU_WINDOWS: /* Windows> */ - if (pb->data.selection[1] == -1) - { - break; - } - i = pb->data.selection[1]; - { - window_state ws; - Wimp_GetWindowState(data[i].w, &ws); - if (ws.flags.data.open) - { - if (!i) - Hnd_MainClose(NULL, (void *)TRUE); - else - Window_Hide(data[i].w); - } - else - { - if (!i) - { - show_windows(); - grab_caret(); - } - else - { - if (!data[i].unopened) - { - Window_Show(data[i].w, open_WHEREVER); - } - else - { - window_openblock ob; - ob.window = data[i].w; - ob.screenrect = data[i].def_pos; - ob.scroll = data[i].def_scroll; - ob.behind = -1; /* could use data[0].w; ? */ - Wimp_OpenWindow(&ob); - data[i].unopened = 0; - } - } - } - } - break; - } - - if (mb.button.data.adjust) - { - set_up_term_menu(menu_term); - Menu_ShowLast(); - } - - return TRUE; -} - - - - - - -/* - | Handle selections from the iconbar menu - */ -static BOOL Hnd_IbarMenu(event_pollblock * pb, void *ref) -{ - mouse_block mb; - Wimp_GetPointerInfo(&mb); - - switch (pb->data.selection[0]) - { - case IBAR_MENU_INFO: /* Info> */ - break; - case IBAR_MENU_FULLSCREEN: /* Full screen */ - /* Do Full Screen mode */ - enter_fullscreen_mode(); - break; - case IBAR_MENU_GAMMA: /* Gamma correction */ - break; - case IBAR_MENU_SOUND: /* Sound */ - /* - | enable_sound = !enable_sound; - | if ( enable_sound ) { initialise_sound(); } - | Menu_SetFlags( ibar_menu, IBAR_MENU_SOUND, enable_sound, 0 ); - | set_sound_window_state(); - */ - break; - case IBAR_MENU_WINDOWS: /* Windows> */ - /* - | Hack: pass it off as the equivalent selection from - | the term menu. - */ - pb->data.selection[0] = TERM_MENU_WINDOWS; - return Hnd_TermMenu(pb, ref); - break; - case IBAR_MENU_SAVECHOICES: /* Save choices */ - save_choices(); - break; - case IBAR_MENU_QUIT: /* Quit */ - if (game_in_progress && character_generated) - save_player(); - quit(NULL); - break; - } - - if (mb.button.data.adjust) - Menu_ShowLast(); - - return TRUE; -} - - - - -/* - * Handler for NULL events (should this check the alarm in the desktop? - */ -static BOOL Hnd_null(event_pollblock *event, void *ref) -{ - /* Really no need to check the alarm more than once per second. */ - if (alarm_type && Time_Monotonic() > alarm_lastcheck + 100) - { - check_alarm(); - } - - return TRUE; -} - - - - - - - - -static BOOL Hnd_MenuSel(event_pollblock * pb, void *ref) -{ - if (menu_currentopen == ibar_menu) - return Hnd_IbarMenu(pb, ref); - else if (menu_currentopen == term_menu) - return Hnd_TermMenu(pb, ref); - return FALSE; -} - - -static BOOL Hnd_IbarClick(event_pollblock * pb, void *ref) -{ - if (pb->data.mouse.button.data.menu) - { - set_gamma_window_state(); - set_sound_window_state(); - - /* Hack: shade the Save> option if appropriate */ - if (game_in_progress && character_generated) - Menu_SetFlags(ibar_menu, IBAR_MENU_SAVE, 0, PDEADCHK); - else - Menu_SetFlags(ibar_menu, IBAR_MENU_SAVE, 0, TRUE); - - /* - | Hack: set up the Term menu as if it was opened over the main - | window (so that the Windows> submenu is set correctly) - */ - menu_term = (term_data *)&data[0]; - set_up_term_menu(menu_term); - - Menu_Show(ibar_menu, pb->data.mouse.pos.x, -1); - return TRUE; - } - - if (pb->data.mouse.button.data.select) - { - show_windows(); - grab_caret(); - return TRUE; - } - - if (pb->data.mouse.button.data.adjust) - { - enter_fullscreen_mode(); - return TRUE; - } - - return FALSE; -} - - - - - - -/* - | Handler for PreQuit messages (eg. at shutdown). - */ -static BOOL Hnd_PreQuit(event_pollblock * b, void *ref) -{ - BOOL shutdown = (b->data.message.data.words[0] & 1) == 0; - task_handle originator = b->data.message.header.sender; - unsigned int quitref; - message_block mb; - char buffer1[64]; - os_error e; - int ok; - - if (!(game_in_progress && character_generated)) - return TRUE; /* ignore, we're OK to die */ - - /* Stop the shutdown/quit */ - memcpy(&mb, &(b->data.message), 24); - quitref = mb.header.yourref; - mb.header.yourref = mb.header.myref; - Wimp_SendMessage(event_ACK, &mb, originator, 0); - - /* - | We handle this differently depending on the version of the Wimp; - | newer versions give us much more flexibility. - */ - if (event_wimpversion < 350) - { - /* - | Older versions - use 'OK' and 'Cancel'. - | There is no "Save & Quit" button. - */ - Msgs_Lookup("err.shuttitl:Query from %s", e.errmess, 64); - sprintf(buffer1, e.errmess, VARIANT); - Msgs_Lookup("err.shutdown:Unsaved game; are you sure you want to quit?", - e.errmess, 260); - e.errnum = 0; - SWI(3, 2, SWI_Wimp_ReportError, &e, 3 | 16, buffer1, NULL, &ok); - - if (ok != 1) - return TRUE; /* no! Pleeeeeease don't kill leeeeddle ol' me! */ - } - else - { - /* - | Newer version: can add buttons to the dialog. - | we add a 'Save and Quit' button to allow the shutdown to - | continue /after/ saving. - */ - int flags; - char buttons[64]; - - Msgs_Lookup("err.shutbuts:Save & quit,Don't quit,Quit anyway", - buttons, 64); - Msgs_Lookup("err.shuttitl:Query from %s", e.errmess, 64); - sprintf(buffer1, e.errmess, VARIANT); - Msgs_Lookup("err.shutdown:Unsaved game; are you sure you want to quit?", - e.errmess, 260); - e.errnum = 0; - - flags = 0 | 16 | 256 | (4 << 9); - - SWI(6, 2, SWI_Wimp_ReportError, &e, flags, buffer1, ICONNAME, 0, - buttons, NULL, &ok); - - if (ok == 4) - return TRUE; /* no! Pleeeeeease don't kill leeeeddle ol' me! */ - - if (ok == 3) - save_player(); /* Save & Quit */ - } - - - /* RO2 doesn't use the shudown flag */ - if (shutdown && event_wimpversion >= 300 && mb.header.size >= 24) - { - key_block kb; - kb.code = 0x1fc; /* restart shutdown sequence */ - Wimp_SendMessage(event_KEY, (message_block *) & kb, originator, 0); - } - - /* "Time... to die." */ - Event_CloseDown(); - exit(0); - return TRUE; /* The one great certainty (sic) */ -} - -#endif /* FULLSCREEN_ONLY */ - - - - -static void initialise_terms(void) -{ - char t[80]; - int i; - -#ifndef FULLSCREEN_ONLY - if (!minimise_memory) - { - /* Create a window for each term. Term 0 is special (no scroll bars) */ - data[0].w = Window_Create("angband", sizeof(angband_term_name[0])); - data[0].font = SYSTEM_FONT; - data[0].def_open = 1; - data[0].unopened = 1; - sprintf(t, "%s %s", VARIANT, VERSION); - Window_SetTitle(data[0].w, t); - strncpy(data[0].name, VARIANT, 12); - Event_Claim(event_KEY, data[0].w, event_ANY, Hnd_Keypress, - (void *)&(data[0])); - Event_Claim(event_REDRAW, data[0].w, event_ANY, Hnd_Redraw, - (void *)&(data[0])); - Event_Claim(event_CLICK, data[0].w, event_ANY, Hnd_TermClick, - (void *)&(data[0])); - Event_Claim(event_CLOSE, data[0].w, event_ANY, Hnd_MainClose, NULL); - - for (i = 1; i < MAX_TERM_DATA; i++) - { - data[i].w = Window_Create("term", template_TITLEMIN); - data[i].font = SYSTEM_FONT; - data[i].def_open = 0; - data[i].unopened = 1; -#ifndef OLD_TERM_MENU - sprintf(t, "%s (%s %s)", angband_term_name[i], VARIANT, VERSION); -#else - sprintf(t, "Term-%d (%s %s)", i, VARIANT, VERSION); -#endif - Window_SetTitle(data[i].w, t); - strncpy(data[i].name, t, 12); - Event_Claim(event_CLICK, data[i].w, event_ANY, Hnd_TermClick, - (void *)&(data[i])); - Event_Claim(event_REDRAW, data[i].w, event_ANY, Hnd_Redraw, - (void *)&(data[i])); - } - } -#endif /* FULLSCREEN_ONLY */ - - term_data_link(&(data[0]), 256); - - for (i = 1; i < MAX_TERM_DATA; i++) - { - term_data_link(&(data[i]), 16); - angband_term[i] = &(data[i].t); - } - - angband_term[0] = &(data[0].t); - Term_activate(&(data[0].t)); -} - - - - -/* - | Hack(ish) - determine the version of RISC OS - */ -static int os_version(void) -{ - int osv; - SWI(3, 2, SWI_OS_Byte, 129, 0, 255, NULL, &osv); - switch (osv) - { - case 0xa0: return 120; - case 0xa1: return 200; - case 0xa2: return 201; - case 0xa3: return 300; - case 0xa4: return 310; - case 0xa5: return 350; - case 0xa6: return 360; - case 0xa7: return 370; - case 0xa8: return 400; - default: return 370; - } - return -1; /* -sigh- */ -} - -#ifndef FULLSCREEN_ONLY -/* - | Determine whether the current screen mode is "high-res" - | (ie. should we use the "Sprites22" or the "Sprites" file. - */ -static int sprites22(void) -{ - int yeig; - - OS_ReadModeVariable(-1, modevar_YEIGFACTOR, &yeig); - - return yeig < 2; -} - -/* - | Determine whether we should use 2D or 3D templates. - | 2D templates *must* be used under Wimp <3.00, but under RO3 we - | use the CMOS settings to decide. - */ -static int templates2d(void) -{ - int r1, r2; - - if (event_wimpversion < 300) - return TRUE; - - /* The 3D bit is bit 0 of byte 140 */ - OS_Byte(osbyte_READCMOSRAM, 140, 0, &r1, &r2); - - return !(r2 && 1); -} -#endif /* FULLSCREEN_ONLY */ - - - -static unsigned int htoi(char *s) -{ - static const char hex[] = "0123456789ABCDEF"; - unsigned int v = 0; - while (*s) - { - char *m; - int d = toupper((unsigned char)*s++); - m = strchr(hex, d); - if (!m) - { - return v; - } - v = (v << 4) + (m - hex); - } - return v; -} - -static int read_unsigned(char *t) -{ - int r; - if (SWI(2, 3, SWI_OS_ReadUnsigned, 2, t, NULL, NULL, &r)) - r = 0; - return r; -} - -/* - | Scan the string at 'n', replacing dodgy characters with underbars - */ -static void sanitise_name(char *n) -{ - for (; *n; n++) - { - if (strchr("\"$%^&*\\\'@#.,", *n)) - *n = '_'; - } -} - - -/* - | Ensure that the path to a given object exists. - | Ie. if |p| = "a.b.c.d" then we attempt to - | create directories a, a.b and a.b.c if they don't - | already exist. - | Note that 'd' may be absent. - */ -static int ensure_path(char *p) -{ - char tmp[260]; - char *l = tmp; - - while (*p) - { - if (*p == '.') - { - *l = 0; - if (SWI(5, 0, SWI_OS_File, 8, tmp, 0, 0, 77)) - return 0; /* Eeek! */ - } - *l++ = *p++; - } - - return 1; -} - - -/* - * Set up the Scrap, Choices and Alarm paths, trying for - * Choices:blah...,etc. by preference, but falling back on lib/xtra - * if need be. - */ -static void init_paths(void) -{ - char tmp[512]; - char subpath[128]; - char *v; - char *t; - - /* Form the sub-path we use for both Choices and Scrap dirs: */ - v = subpath + sprintf(subpath, "%s", VARIANT); - sanitise_name(subpath); - sprintf(v, ".%s", VERSION); - sanitise_name(v + 1); - - /* Do the Scrap path first: */ - *scrap_path = 0; - - /* Try for Wimp$ScrapDir... */ - t = getenv("Wimp$ScrapDir"); - if (t && *t) - { - sprintf(tmp, "%s.AngbandEtc.%s.", t, subpath); - if (ensure_path(tmp)) - { - strcpy(scrap_path, tmp); - } - } - - /* Couldn't use Wimp$ScrapDir, so fall back on lib.xtra.scrap */ - if (!*scrap_path) - { - sprintf(tmp, "%sxtra.scrap.", resource_path); - if (ensure_path(tmp)) - { - strcpy(scrap_path, tmp); - } - } - - /* Now set up the Choices and Alarm files: */ - - /* Read only Choices file is always lib.xtra.Choices */ - sprintf(choices_file[CHFILE_READ], "%sXtra.Choices", resource_path); - /* Default writable Choices file is the same */ - strcpy(choices_file[CHFILE_WRITE], choices_file[CHFILE_READ]); - /* No default mirror Choices file */ - strcpy(choices_file[CHFILE_MIRROR], ""); - - /* Read only Alarm file is always lib.xtra.Alarm */ - sprintf(alarm_file[CHFILE_READ], "%sXtra.Alarm", resource_path); - /* Default writable Alarm file is the same */ - strcpy(alarm_file[CHFILE_WRITE], alarm_file[CHFILE_READ]); - - /* Try to use Choices$Path, etc. for the others... */ - - t = getenv("Choices$Write"); /* Ie. where choices should be written */ - if (t && *t) - { - /* Choices file: */ - sprintf(tmp, "%s.AngbandEtc.%s", t, subpath); - if (ensure_path(tmp)) - { - /* Use for writable file: */ - strcpy(choices_file[CHFILE_WRITE], tmp); - /* Form 'mirror' filename: same path but with a fixed leafname */ - strcpy(v + 1, "Default"); - sprintf(tmp, "%s.AngbandEtc.%s", t, subpath); - strcpy(choices_file[CHFILE_MIRROR], tmp); - } - - /* Alarm file (doesn't involve subpath) */ - sprintf(tmp, "%s.AngbandEtc.Global.Alarm", t); - if (ensure_path(tmp)) - { - /* Use for read/writable file */ - strcpy(alarm_file[CHFILE_WRITE], tmp); - } - } -} - - - - - - - -/* - * Return the appropriate (full) pathname. - * - * For write ops, the read/write file is returned. - * - * For read ops, either the read/write file, the mirror file, - * or the read only file will be returned as appropriate. - */ -static char *find_choices(int write) -{ - if (write) - return choices_file[CHFILE_WRITE]; - - if (myFile_Size(choices_file[CHFILE_WRITE]) > 0) - return choices_file[CHFILE_WRITE]; - - if (myFile_Size(choices_file[CHFILE_MIRROR]) > 0) - return choices_file[CHFILE_MIRROR]; - - return choices_file[CHFILE_READ]; -} - -static char *find_choices_mirror(void) -{ - return choices_file[CHFILE_MIRROR]; -} - -static char *find_alarmfile(int write) -{ - if (write) - return alarm_file[CHFILE_WRITE]; - - if (myFile_Size(alarm_file[CHFILE_WRITE]) > 0) - return alarm_file[CHFILE_WRITE]; - - return alarm_file[CHFILE_READ]; -} - - - - -int main(int argc, char *argv[]) -{ - int i, j; - int start_full = 0; - char *arg_savefile = 0; - char *t; -#ifdef USE_DA - int da_font = 1, da_game = 1; -#endif - - atexit(final_acn); /* "I never did care about the little things." */ - - Start_Hourglass; - - /* Parse arguments */ - for (i = 1; i < argc; i++) - { - if (argv[i][0] == '-') - { - switch (tolower((unsigned char)argv[i][1])) - { - case 'm': - { - /* Minimise Memory */ - minimise_memory = 1; - - /* Break */ - break; - } - case 'c': /* -c[a][s][f][<n>] */ - for (j = 2; argv[i][j]; j++) - { - int on = isupper((unsigned char)argv[i][j]); - - switch (tolower((unsigned char)argv[i][j])) - { -#ifdef ABBR_FILECACHE - case 'a': abbr_filecache = - on; - break; - case 'f': abbr_tmpfile = - on; - break; -#endif -#ifdef SMART_FILECACHE - case 's': smart_filecache = - on; - break; -#endif - - case 'p': flush_scrap = - !on; - break; - - default: - if (isdigit((unsigned char)argv[i][j])) - { - max_file_cache_size = - atoi(argv[i] + j) << 10; - while (isdigit((unsigned char)argv[i][++j])) - ; - if (max_file_cache_size <= 0) - { - use_filecache = 0; - } - j--; - } - else - { - fprintf(stderr, "Unrecognised option: -c%s", - argv[i] + j); - exit(EXIT_FAILURE); - } - } - } - break; - case 'w': /* -waitrelease */ - hack_flush = 1; - break; - case 'e': /* -Evil */ - allow_iclear_hack = 1; - break; - case 's': /* -s<savefile> */ - if (argv[i][2]) - arg_savefile = argv[i] + 2; - break; - case 'f': /* -fullscreen */ - start_full = 1; - break; - case 'h': /* -hourglass */ - use_glass = 1; - break; - case 't': /* -T<filetype> */ - if (argv[i][2]) - vfiletype = htoi(argv[i] + 2); - break; -#ifdef USE_DA - case 'd': /* -df, -dg, -dc or -d : disable DAs */ - switch (tolower((unsigned char)argv[i][2])) - { - case 0: /* -d => disable both */ - da_font = da_game = 0; - break; - case 'f': /* -df => disable font only */ - da_font = 0; - break; - case 'g': /* -dg => disable game only */ - da_game = 0; - break; - } - break; -#endif - case '%': /* -%<debug_opts> */ - { - int v = read_unsigned(argv[i] + 2); - log_g_malloc = v & 1; - show_sound_alloc = v & 2; - } - break; - default: - fprintf(stderr, "Unrecognised option: %s", argv[i]); - exit(EXIT_FAILURE); - } - } - } - - /* 1.27 - new handling of -minimise-memory: */ -#ifndef FULLSCREEN_ONLY - if (minimise_memory) -#endif /* FULLSCREEN_ONLY */ - { - start_full = 1; - fs_quit_key_text = "(fullscreen only mode)"; - } -#ifdef USE_DA - init_memory(da_font, da_game); /* Set up dynamic areas, etc. if possible */ - - /* Install memory allocation hooks */ - ralloc_aux = g_malloc; - rnfree_aux = g_free; -#endif - - /* Install replacement error reporting routines */ - quit_aux = quit_hook; - plog_aux = plog_hook; - core_aux = core_hook; - - /* Expand the (Angband) resource path */ - t = getenv(RISCOS_VARIANT "$Path"); - if (!t || !*t) Msgs_ReportFatal(0, "A resources path could not be formed."); - strcpy(resource_path, t); - - /* Decide where scrap, choices and alarm files live: */ - init_paths(); - - /* Hack: if no savefile specified, use a default */ - if (!arg_savefile) - { - arg_savefile = malloc(strlen(resource_path) + 32); - if (!arg_savefile) - { - Msgs_ReportFatal(0, "err.mem"); - } - sprintf(arg_savefile, "%s%s", resource_path, ">Save.Savefile"); - } - - /* This crap appears here so that plog() will work properly before - init_acn() is called... */ - Resource_Initialise(RISCOS_VARIANT); - Msgs_LoadFile("Messages"); - -#ifndef FULLSCREEN_ONLY - if (!minimise_memory) - { - /* This is a hack to only call Event_Initialise3 under RO3 */ - if (os_version() < 300) - Event_Initialise(RISCOS_VARIANT); - else - Event_Initialise3(RISCOS_VARIANT, 300, message_list); - - EventMsg_Initialise(); - - /* - | This is a possible workaround for the FP regs getting - | bolloxed in the ! menu because the compiler sets them - | up before a call to Wimp_Poll if CSE optimisation is on. - | At the moment I've just turned off CSE for the function - | affected. - | - | event_mask.data.keepfpregisters = 1; - */ - - /* Load Templates */ - Template_Initialise(); - if (templates2d()) - Template_LoadFile("Templates2"); - else - Template_LoadFile("Templates"); - - /* Load Sprites */ - if (sprites22()) - resource_sprites = - Sprite_LoadFile("<" RISCOS_VARIANT "$Dir>.Sprites22"); - else - resource_sprites = Sprite_LoadFile("<" RISCOS_VARIANT "$Dir>.Sprites"); - } -#endif /* FULLSCREEN_ONLY */ - - Screen_CacheModeInfo(); - - /* Initialise some ZapRedraw stuff */ - initialise_palette(); - initialise_fonts(); /* Set up the fonts */ -#ifndef FULLSCREEN_ONLY - initialise_r_data(); /* Set up the r_data buffer */ - - if (!minimise_memory) - { - /* Initialise some Wimp specific stuff */ - init_gamma_window(); - init_sound_window(); - init_save_window(); - init_menus(); - ibar_icon = Icon_BarIcon(ICONNAME, iconbar_RIGHT); - - /* Global handlers */ - Event_Claim(event_OPEN, event_ANY, event_ANY, Handler_OpenWindow, NULL); - Event_Claim(event_CLOSE, event_ANY, event_ANY, Handler_CloseWindow, NULL); - Event_Claim(event_GAINCARET, event_ANY, event_ANY, Hnd_Caret, (void *)1); - Event_Claim(event_LOSECARET, event_ANY, event_ANY, Hnd_Caret, (void *)0); - Event_Claim(event_MENU, event_ANY, event_ANY, Hnd_MenuSel, NULL); - Event_Claim(event_CLICK, window_ICONBAR, ibar_icon, Hnd_IbarClick, NULL); - Event_Claim(event_CLICK, event_ANY, event_ANY, Hnd_Click, NULL); - EventMsg_Claim(message_PALETTECHANGE, event_ANY, Hnd_PaletteChange, NULL); - EventMsg_Claim(message_MODECHANGE, event_ANY, Hnd_ModeChange, NULL); - EventMsg_Claim(message_PREQUIT, event_ANY, Hnd_PreQuit, NULL); - - /* Initialise the sound stuff */ - initialise_sound(); - } -#endif /* FULLSCREEN_ONLY */ - - /* Initialise some Angband stuff */ - initialise_terms(); - load_choices(); - read_alarm_choices(); - init_file_paths(unixify_name(resource_path)); - - Start_Hourglass; /* Paranoia */ - - /* Hack - override the saved options if -F was on the command line */ - start_fullscreen |= start_full; - - /* hack so that the cursor is yellow if undefined */ - if (palette[CURSOR_COLOUR] == palette[0]) - { - angband_color_table[CURSOR_COLOUR][1] = (CURSOR_RGB & 0xff00) >> 8; - angband_color_table[CURSOR_COLOUR][2] = (CURSOR_RGB & 0xff0000) >> 16; - angband_color_table[CURSOR_COLOUR][3] = (CURSOR_RGB & 0xff000000) >> 24; - } - - /* Catch nasty signals */ - signals_init(); - /* use pref-acn.prf */ - ANGBAND_SYS = "acn"; - -#ifndef FULLSCREEN_ONLY - if (start_fullscreen) - { -#endif /* FULLSCREEN_ONLY */ - enter_fullscreen_mode(); -#ifndef FULLSCREEN_ONLY - } - else - { - Start_Hourglass; /* Paranoia */ - Hnd_ModeChange(NULL, NULL); /* Caches the various fonts/palettes */ - show_windows(); - grab_caret(); - - Event_Claim(event_NULL, event_ANY, event_ANY, Hnd_null, NULL); - - /* Wait for a null poll so that the windows can appear */ - do - { - Event_Poll(); - } - while (event_lastevent.type != 0); - } -#endif /* FULLSCREEN_ONLY */ - - /* Initialise Angband */ - Start_Hourglass; /* Paranoia */ - - strncpy(savefile, unixify_name(arg_savefile), sizeof(savefile)); - savefile[sizeof(savefile) - 1] = '\0'; - - use_sound = 1; - init_angband(); - initialised = 1; - game_in_progress = 1; -/* pause_line(23);*/ - flush(); - /* Stop_Hourglass; */ - play_game(FALSE); - - if (fullscreen_mode) leave_fullscreen_mode(); - - Stop_Hourglass; - - quit(NULL); - - return 0; - - debug("to stop the 'unused' warning :)"); -} - - - - - - - - - - - - - -/*--------------------------------------------------------------------------*/ -/* Stuff below here is for the full screen display */ -/*--------------------------------------------------------------------------*/ - -static errr Term_xtra_acn_checkFS(void); -static errr Term_xtra_acn_eventFS(void); -static errr Term_xtra_acn_reactFS(int force); -static errr Term_curs_acnFS(int x, int y); -static errr Term_xtra_acn_clearFS(void); -static errr Term_xtra_acnFS(int n, int v); -static errr Term_wipe_acnFS(int x, int y, int n); -static errr Term_text_acnFS(int x, int y, int n, byte a, cptr s); -static void bored(void); -static void redraw_areaFS(int x, int y, int w, int h); -static void draw_cursor(int x, int y); - -/* - | We use this to keep the mouse in the same place on return from full-screen - | mode. - */ -static wimp_point old_mouse_posn; - -/* - | Take a copy of the current mode descriptor/number and return either - | a pointer to it (as an int) if it's a new mode, or the mode number. - | NB: A static pointer is used and the descriptor returned is only - | valid until the next call to this function. - | - | Basically, a replacement for OS_Byte 135 / OS_ScreenMode1, IYSWIM. - */ -static int current_mode(void) -{ - static void *descriptor = NULL; - int mode; - int size; - int i; - int *vals; - - if (descriptor) - { - free(descriptor); - descriptor = NULL; - } - - SWI(1, 3, SWI_OS_Byte, 135, NULL, NULL, &mode); - if (mode < 256) - { - return mode; - } - - vals = (int *)(mode + 20); - for (i = 0; vals[i] != -1; i += 2) - ; - - size = 24 + 8 * i; /* Size of data */ - descriptor = malloc(size); - if (!descriptor) - { - core("Out of memory!"); - } - memcpy(descriptor, (void *)mode, size); - - return (int)descriptor; -} - - - -/* - | Select the best mode we can for full screen. - | Returns 12 for (low-res, ie. mode 12) or 27 for high-res, - | or a pointer to a mode descriptor (as an int). - */ -static int select_fullscreen_mode(void) -{ - static struct - { - int flags, x, y, l2bpp, hz, term; - } - desc; - int mode = 0; - - desc.flags = 1; /* format 0 */ - desc.x = 640; - desc.y = 480; /* 640x480 */ - desc.l2bpp = 2; /* 16 colours */ - desc.hz = -1; /* best we can get */ - desc.term = -1; /* don't fuss about modevars */ - - SWI(1, 1, SWI_OS_CheckModeValid, &desc, &mode); - if (mode != (int)&desc) - { - SWI(1, 1, SWI_OS_CheckModeValid, 27, /**/ &mode); - if (mode != 27) - { - SWI(1, 1, SWI_OS_CheckModeValid, 12, /**/ &mode); - if (mode != 12) - { - mode = 0; - } - } - } - - return mode; -} - - -/* - | Change screen mode - */ -static void change_screenmode(int to) -{ - if (SWI(2, 0, SWI_OS_ScreenMode, 0, to)) - { - if (to < 256) - { - GFX_VDU(22); - GFX_VDU(to); - } - else - { - /* Finished with my woman / cos she couldn't help me with ... */ - core("Eeek! mode isn't valid, but it /should/ be..."); - } - } -} - - -/* - | Constrain the mouse pointer to a point - this means that the damn - | hourglass won't move around with the mouse :) - */ -static void constrain_pointer(void) -{ - mouse_block ptr; - wimp_rect r; - int ys = screen_eig.y == 1 ? 32 : 64; /* Cope with dbl height glass */ - - Screen_CacheModeInfo(); /* Make sure we know the screen size */ - r.min.x = r.max.x = screen_size.x - 32; - r.min.y = r.max.y = screen_size.y - ys; - - /* Retrieve and store old (wimp) pointer position */ - Wimp_GetPointerInfo(&ptr); - old_mouse_posn = ptr.pos; - - Pointer_RestrictToRect(r); - - /* Turn the pointer off also */ - SWI(2, 0, SWI_OS_Byte, 106, 0); -} - -static void release_pointer() -{ - wimp_rect r; - - r.min.x = r.max.x = old_mouse_posn.x; - r.min.y = r.max.y = old_mouse_posn.y; - - Pointer_RestrictToRect(r); - - Pointer_Unrestrict(); - - /* Turn the pointer back on also */ - SWI(2, 0, SWI_OS_Byte, 106, 1); -} - - - - - -/* - | Convert a 1bpp bitmap into a 4bpp bitmap (bit flipped) - */ -static int byte_to_word_flipped(int b) -{ - int w; - if (b & 128) - { - w = 0xf0000000; - } - else - { - w = 0; - } - if (b & 64) - { - w |= 0x0f000000; - } - if (b & 32) - { - w |= 0x00f00000; - } - if (b & 16) - { - w |= 0x000f0000; - } - if (b & 8) - { - w |= 0x0000f000; - } - if (b & 4) - { - w |= 0x00000f00; - } - if (b & 2) - { - w |= 0x000000f0; - } - if (b & 1) - { - w |= 0x0000000f; - } - return w; -} - - - - -/* - | try to load the fallback fullscreen font and convert it to 4bpp - */ -static int cache_zapfontHR(void) -{ - int handle; - unsigned int extent; - char buffer[260]; - struct - { - char id[8]; - int w, h, f, l, r1, r2; - } - zfh; - int *op; - char *ip; - int l, i; - - /* Try to open the file */ - sprintf(buffer, "%s%s", resource_path, "xtra.FullScreen"); - handle = myFile_Open(buffer, 0x4f); - if (!handle) - { - return 0; - } - - /* Check file's extent */ - extent = myFile_Extent(handle); - if (extent > sizeof(zfh) + 256 * 16) - { - myFile_Close(handle); - return 0; - } - - /* Load the header */ - if (myFile_ReadBytes(handle, &zfh, sizeof(zfh))) - { - myFile_Close(handle); - return 0; - } - - /* Check font size */ - if ((zfh.w != 8) || (zfh.h > 16)) - { - myFile_Close(handle); - return 0; - } - - /* Load the 1bpp data */ - if (myFile_ReadBytes(handle, fullscreen_font, extent - sizeof(zfh))) - { - myFile_Close(handle); - return 0; - } - - myFile_Close(handle); - - l = zfh.l > 255 ? 255 : zfh.l; - - if (zfh.h > 8) - { - op = (int *)(((int)fullscreen_font) + (l + 1) * zfh.h * 4); - ip = (char *)(((int)fullscreen_font) + (l + 1) * zfh.h - - (zfh.f * zfh.h)); - while (l-- >= zfh.f) - { - for (i = 0; i < zfh.h; i++) - { - *--op = byte_to_word_flipped(*--ip); - } - } - fullscreen_height = zfh.h; - } - else - { - op = (int *)(((int)fullscreen_font) + (l + 1) * zfh.h * 8); - ip = (char *)(((int)fullscreen_font) + (l + 1) * zfh.h - - (zfh.f * zfh.h)); - while (l-- >= zfh.f) - { - for (i = -zfh.h; i < zfh.h; i++) - { - int t = byte_to_word_flipped(*--ip); - *--op = t; - *--op = t; - } - } - fullscreen_height = zfh.h * 2; - } - - fullscreen_topline = TERM_TOPLINE_HR; - fullscreen_topline += ((16 - fullscreen_height) * 13); - - return 1; -} - - - - - -static int cache_fs_fontHR(void) -{ - ZapFont *src = SYSTEM_FONT; - int c; - int *op; - char *ip; - - /* Allocate the storage for the font */ - fullscreen_font = f_malloc(256 * 4 * 16); - if (!fullscreen_font) - { - return 0; - } - op = (int *)fullscreen_font; - - /* Check to see if the main term's font is suitable (ie. 8x16 or 8x8) */ - if ((data[0].font->w == 8) && (data[0].font->h <= 16)) - src = data[0].font; - - /* - | Hack: if we're forced to use the system font, try to load the - | 'fullscreen' font from lib.xtra. If that fails, then I guess we're - | stuck with the system font. - */ - - if (src == SYSTEM_FONT) - if (cache_zapfontHR()) - { - return 1; - } - - ip = (char *)(src->bpp_1); - - /* Now, create the font */ - if (src->h > 8) - { - int e = src->h * (src->l > 256 ? 256 : src->l); - op += (src->f * src->h); - for (c = src->f * src->h; c < e; c++) - *op++ = byte_to_word_flipped(*ip++); - fullscreen_height = src->h; - } - else - { - int e = src->h * (src->l > 256 ? 256 : src->l); - op += (src->f * src->h) * 2; - for (c = src->f * src->h; c < e; c++) - { - int t = byte_to_word_flipped(*ip++); - *op++ = t; - *op++ = t; - } - fullscreen_height = src->h * 2; - } - - fullscreen_topline = TERM_TOPLINE_HR; - fullscreen_topline += ((16 - fullscreen_height) * 13); - - return 1; -} - - - - - -static int cache_fs_fontLR(void) -{ - ZapFont *src = SYSTEM_FONT; - int c, e; - int *op; - char *ip; - - /* Allocate the storage for the font */ - fullscreen_font = f_malloc(256 * 4 * 8); - if (!fullscreen_font) - { - return 0; - } - op = (int *)fullscreen_font; - - /* Check to see if the main term's font is suitable (ie. 8x8) */ - if ((data[0].font->w == 8) && (data[0].font->h <= 8)) - src = data[0].font; - - ip = (char *)(src->bpp_1); - - /* Now, create the font */ - e = src->h * (src->l > 256 ? 256 : src->l); - op += (src->f * src->h); - for (c = src->f * src->h; c < e; c++) - *op++ = byte_to_word_flipped(*ip++); - - fullscreen_height = src->h; - fullscreen_topline = TERM_TOPLINE_LR; - fullscreen_topline += ((8 - fullscreen_height) * 13); - - return 1; -} - - - -static void set_keys(int claim) -{ - static int old_c_state; - static int old_f_state[8]; - int i; - - if (claim) - { - /* Cursors/copy act as function keys */ - /* f0-f9, cursors, generate 0x80-0x8f */ - /* sh-f0-f9,cursors, generate 0x90-0x9f */ - /* ctrl f0-f9,cursors, generate 0xa0-0xaf */ - /* sh-c-f0-f9,cursors, generate 0xb0-0xbf */ - /* f10-f12 generate 0xca-0xcc */ - /* shift f10-f12 generate 0xda-0xdc */ - /* ctrl f10-f12 generate 0xea-0xec */ - /* ctrlshift f10-f12 generate 0xfa-0xfc */ - - SWI(3, 2, SWI_OS_Byte, 4, 2, 0, /**/ NULL, &old_c_state); - - for (i = 0; i < 4; i++) - { - SWI(3, 2, SWI_OS_Byte, 225 + i, 0x80 + (i * 0x10), 0, NULL, - old_f_state + i); - SWI(3, 2, SWI_OS_Byte, 221 + i, 0xc0 + (i * 0x10), 0, NULL, - old_f_state + i + 4); - } - } - else - { - SWI(3, 0, SWI_OS_Byte, 4, old_c_state, 0); - for (i = 0; i < 4; i++) - { - SWI(3, 0, SWI_OS_Byte, 225 + i, old_f_state[i], 0); - SWI(3, 0, SWI_OS_Byte, 221 + i, old_f_state[i + 4], 0); - } - } -} - - - - - - -/* - | Enter the full screen mode. - | - | Full screen display uses either mode 27 (if supported) and 8x16 fonts - | (or system font 'twiddled' to double height), or mode 12 (if mode 27 - | is unavailable) and the system font (or an 8x8 font). - | - */ - -static void enter_fullscreen_mode(void) -{ - int vduvars[2] = - { 149, -1 }; - int i; - - /* New in 1.18 - protect against 're-entracy' */ - if (fullscreen_font) - return; - - /* New in 1.20 - hack IClear out of the way */ - if (allow_iclear_hack) - iclear_hack(); - - /* Choose the mode we want */ - fullscreen_mode = select_fullscreen_mode(); - - if (!fullscreen_mode) - { - plog("Unable to select a suitable screen mode (27 or 12)"); - return; - } - - if (!((fullscreen_mode == 12) ? cache_fs_fontLR() : cache_fs_fontHR())) - { - plog("Unable to cache a font for full screen mode"); - return; - } - - /* Read the current screen mode */ - /* SWI( 1,3, SWI_OS_Byte, 135, NULL, NULL, &old_screenmode ); */ - old_screenmode = current_mode(); - - Stop_Hourglass; - - /* Change to the chosen screen mode */ - change_screenmode(fullscreen_mode); - - /* Restrict the pointer */ - constrain_pointer(); - - /* Remove the cursors */ - SWI(0, 0, SWI_OS_RemoveCursors); - - Start_Hourglass; - - /* Get the base address of screen memory */ - SWI(2, 0, SWI_OS_ReadVduVariables, vduvars, vduvars); - fullscreen_base = (int *)(vduvars[0]); - - /* Fudge the Term interface */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - term *t = &(data[i].t); - t->xtra_hook = Term_xtra_acnFS; - t->wipe_hook = Term_wipe_acnFS; - t->curs_hook = Term_curs_acnFS; - t->text_hook = Term_text_acnFS; - } - - /* Grab the palette */ - Term_xtra_acn_reactFS(TRUE); - - /* Make sure that the keys work properly */ - set_keys(TRUE); - - /* refresh the term */ - /*Term_activate( &(data[0].t) ); */ - redraw_areaFS(0, 0, 80, 24); - if (data[0].cursor.visible) - draw_cursor(data[0].cursor.pos.x, data[0].cursor.pos.y); - - /* Display a reminder of how to get back... */ - /* Hack: disable force_mono */ - i = force_mono; - force_mono = 0; - Term_text_acnFS(0, TIME_LINE, strlen(fs_quit_key_text), 8, - fs_quit_key_text); - force_mono = i; -} - - - - -static void leave_fullscreen_mode(void) -{ - int i; - - /* New in 1.18 - protect against 're-entracy' */ - if (!fullscreen_font) - return; - - /* Restore the Term interface */ - for (i = 0; i < MAX_TERM_DATA; i++) - { -#ifndef FULLSCREEN_ONLY - term *t = &(data[i].t); - t->xtra_hook = Term_xtra_acn; - t->wipe_hook = Term_wipe_acn; - t->curs_hook = Term_curs_acn; - t->text_hook = Term_text_acn; -#endif - mark_ood(&(data[i]), 0, 0, 80, 24); - } - - /* Deallocate the font */ - f_free(fullscreen_font); - fullscreen_font = 0; - fullscreen_mode = 0; - - Stop_Hourglass; - - /* Restore the screen mode */ - Wimp_SetMode(old_screenmode); - - /* Restore the pointer */ - release_pointer(); - - Start_Hourglass; - - /* Restore the various soft keys */ - set_keys(FALSE); - - /* New in 1.20 Remove the IClear hack */ - if (allow_iclear_hack) - remove_iclear_hack(); - -#ifndef FULLSCREEN_ONLY - /* Refresh the windows - this probably isn't necessary anyway */ - if (!minimise_memory) - refresh_windows(); -#endif /* FULLSCREEN_ONLY */ -} - - - - - -static void fs_writechars(int x, int y, int n, const char *chars, char attr) -{ - int *scr, *scrb; - int *cdat; - int j; - unsigned int fgm; - - if (force_mono) - { - if (attr != TERM_DARK) - { - attr = TERM_WHITE; - } - } - fgm = (unsigned int)zpalette[(unsigned int) attr]; - - scrb = (int *)(((int)fullscreen_base) + y * fullscreen_height * 320 - + x * 4 + 320 * fullscreen_topline); - - while (n--) - { - scr = scrb++; - cdat = (int *)(((int)fullscreen_font) - + (*chars++) * (fullscreen_height << 2)); - for (j = 0; j < fullscreen_height; j++) - { - *scr = *cdat++ & fgm; - scr += 80; - } - } -} - - -static void fs_writechar(int x, int y, char c, char attr) -{ - int *scrb; - int *cdat; - int j; - unsigned int fgm; - - if (force_mono) - { - if (attr != TERM_DARK) - { - attr = TERM_WHITE; - } - } - fgm = (unsigned int)zpalette[(unsigned int) attr]; - - scrb = (int *)(((int)fullscreen_base) + y * fullscreen_height * 320 - + x * 4 + 320 * fullscreen_topline); - cdat = (int *)(((int)fullscreen_font) + (c * (fullscreen_height << 2))); - for (j = 0; j < fullscreen_height; j++) - { - *scrb = *cdat++ & fgm; - scrb += 80; - } -} - - - -static void draw_cursorHR(int x, int y) -{ - ColourTrans_SetGCOL(cursor_rgb, 0, 0); - GFX_Move(x * 16, - 959 - y * (fullscreen_height * 2) - fullscreen_topline * 2); - GFX_DrawBy(14, 0); - GFX_DrawBy(0, -(fullscreen_height * 2 - 2)); - GFX_DrawBy(-14, 0); - GFX_DrawBy(0, fullscreen_height * 2 - 2); -} - -static void draw_cursorLR(int x, int y) -{ - ColourTrans_SetGCOL(cursor_rgb, 0, 0); - GFX_Move(x * 16, - 1023 - y * (fullscreen_height * 4) - fullscreen_topline * 4); - GFX_DrawBy(14, 0); - GFX_DrawBy(0, -(fullscreen_height * 4 - 4)); - GFX_DrawBy(-14, 0); - GFX_DrawBy(0, fullscreen_height * 4 - 4); -} - - - - - -static void draw_cursor(int x, int y) -{ - if (fullscreen_mode == 12) - draw_cursorLR(x, y); - else - draw_cursorHR(x, y); -} - - - -static void redraw_areaFS(int x, int y, int w, int h) -{ - int i, j; - for (j = y; j < y + h; j++) - for (i = x; i < x + w; i++) - fs_writechar(i, j, data[0].t.old->c[j][i], data[0].t.old->a[j][i]); -} - - - -static int wimp_code(int c) -{ - /* shift/ctrl keypad? */ - if (c >= '0' && c <= '9') - { - kbd_modifiers m = Kbd_GetModifiers(FALSE); - if (m.shift) - { - c |= 0x800; - } - if (m.ctrl) - { - c |= 0x400; - } - return c; - } - if (c == 9) - { - return 0x18a; - } /* Tab */ - if (c <= 127) - { - return c; - } /* normal ASCII/ctrl */ - if (c >= 0x80 && c <= 0xff) - { - return c + 0x100; - } /* f0-f9, etc. */ - - return -1; /* unknown */ -} - - - - -static void do_keypress(int code) -{ - static const char hex[] = "0123456789ABCDEF"; - - if (code == KEYPRESS_QUIT && !minimise_memory) - { -#ifdef FULLSCREEN_ONLY - Sound_SysBeep(); -#else - leave_fullscreen_mode(); -#endif - return; - } - - if (code == 27) - { - if (Kbd_KeyDown(inkey_CTRL)) - { - ack_alarm(); - return; - } - } - - if (code <= 255) - { - Term_keypress(code); - } - else - { - Term_keypress(31); - Term_keypress(hex[(code & 0xf00) >> 8]); - Term_keypress(hex[(code & 0x0f0) >> 4]); - Term_keypress(hex[(code & 0x00f)]); - Term_keypress(13); - } -} - - - - -static errr Term_xtra_acn_checkFS(void) -{ - int bh, bl; - int c; - - Stop_Hourglass; - - bored(); - - SWI(3, 3, SWI_OS_Byte, 128, 255, 0, /**/ NULL, &bl, &bh); - bl = (bl & 0xff) + (bh << 8); - - if (bl > 0) - { - SWI(0, 1, SWI_OS_ReadC, &c); - bl = wimp_code(c); - if (bl >= 0) - { - do_keypress(bl); - } - } - - Start_Hourglass; - - return 0; -} - - - - -static errr Term_xtra_acn_eventFS(void) -{ - int c; - int w = -1; - - Stop_Hourglass; - - for (w = -1; w == -1;) - { - int bh, bl; - do - { - bored(); - SWI(3, 3, SWI_OS_Byte, 128, 255, 0, /**/ NULL, &bl, &bh); - bl = (bl & 0xff) + (bh << 8); - } - while (!bl); - - SWI(0, 1, SWI_OS_ReadC, &c); - w = wimp_code(c); - if (w >= 0) - { - do_keypress(w); - } - } - - Start_Hourglass; - - return 0; -} - - - -/* - * React to changes - */ -static errr Term_xtra_acn_reactFS(int force) -{ - unsigned int i; - int p, r, g, b; - - static double old_gamma = -1.0; - - if (gamma != old_gamma) - { - force = 1; - old_gamma = gamma; - } - - /* Set the screen colours */ - for (i = 0; i < 16; i++) - { - if (COLOUR_CHANGED(i) || force) - { - r = (int)(255.0 * - pow(angband_color_table[i][1] / 255.0, 1.0 / gamma)); - g = (int)(255.0 * - pow(angband_color_table[i][2] / 255.0, 1.0 / gamma)); - b = (int)(255.0 * - pow(angband_color_table[i][3] / 255.0, 1.0 / gamma)); - GFX_VDU(19); - GFX_VDU(i); - GFX_VDU(16); - GFX_VDU(r); - GFX_VDU(g); - GFX_VDU(b); - - palette[i] = (b << 24) | (g << 16) | (r << 8); - p = i; - p |= (p << 4); - p |= (p << 8); - p |= (p << 16); - zpalette[i] = p; - - a_palette[i][1] = angband_color_table[i][1]; - a_palette[i][2] = angband_color_table[i][2]; - a_palette[i][3] = angband_color_table[i][3]; - - /* Find any higher colour numbers and make them "wrong" */ - for (p = 16; p < 256; p++) - if ((zpalette[p] & 0xf) == i) - a_palette[p][1] = angband_color_table[p][1] + 2; - } - } - - - /* Go through the palette updating any changed values */ - for (i = 16; i < 256; i++) - { - if (COLOUR_CHANGED(i) || force) - { - r = (int)(255.0 * - pow(angband_color_table[i][1] / 255.0, 1.0 / gamma)); - g = (int)(255.0 * - pow(angband_color_table[i][2] / 255.0, 1.0 / gamma)); - b = (int)(255.0 * - pow(angband_color_table[i][3] / 255.0, 1.0 / gamma)); - p = (b << 24) | (g << 16) | (r << 8); - palette[i] = p; - SWI(1, 1, SWI_ColourTrans_ReturnColourNumber, palette[i], &p); - p |= (p << 4); - p |= (p << 8); - p |= (p << 16); - zpalette[i] = p; - a_palette[i][1] = angband_color_table[i][1]; - a_palette[i][2] = angband_color_table[i][2]; - a_palette[i][3] = angband_color_table[i][3]; - } - } - - cursor_rgb = palette[CURSOR_COLOUR]; - - return 0; -} - - -static errr Term_curs_acnFS(int x, int y) -{ - if (Term == &(data[0].t)) - { - if (data[0].cursor.visible) - redraw_areaFS(data[0].cursor.pos.x, data[0].cursor.pos.y, 1, 1); - data[0].cursor.pos.x = x; - data[0].cursor.pos.y = y; - if (data[0].cursor.visible) - draw_cursor(x, y); - } - return 0; -} - -static errr Term_xtra_acn_clearFS(void) -{ - char e[80]; - int j; - - if (Term == &(data[0].t)) - { - for (j = 0; j < 80; j++) - e[j] = ' '; - - GFX_Wait(); - - for (j = 0; j < 24; j++) - fs_writechars(0, j, 80, e, 0); - } - - return 0; -} - - - - - - - -static errr Term_xtra_acnFS(int n, int v) -{ - term_data *t = (term_data *)Term; - - switch (n) - { - case TERM_XTRA_CLEAR: - if (t == (&data[0])) - Term_xtra_acn_clearFS(); - return 0; - - case TERM_XTRA_EVENT: - if (v) - return Term_xtra_acn_eventFS(); - else - return Term_xtra_acn_checkFS(); - - case TERM_XTRA_BORED: - bored(); - return Term_xtra_acn_checkFS(); - - case TERM_XTRA_FLUSH: - /* 1.21 - Hack: wait until no keys are pressed */ - if (hack_flush) - for (v = 0; v != 0xff;) - SWI(1, 2, SWI_OS_Byte, 122, 0, &v); - SWI(3, 0, SWI_OS_Byte, 21, 0, 0); /* Flush Kbd buffer */ - return 0; - - case TERM_XTRA_FRESH: - return 0; - - case TERM_XTRA_FROSH: - return 0; - - case TERM_XTRA_SHAPE: - if (t == (&data[0])) - { - t->cursor.visible = v; - if (v) - draw_cursor(t->cursor.pos.x, t->cursor.pos.y); - else - redraw_areaFS(t->cursor.pos.x, t->cursor.pos.y, 1, 1); - } - return 0; - - case TERM_XTRA_NOISE: - Sound_SysBeep(); - return 0; - - case TERM_XTRA_REACT: - return Term_xtra_acn_reactFS(FALSE); - - case TERM_XTRA_DELAY: - if (v > 0) - { - int start = Time_Monotonic(); - v = (v + 5) / 10; /* Round to nearest cs */ - GFX_Wait(); - while ((Time_Monotonic() - start) < v) - ; - } - return (0); - - case TERM_XTRA_SOUND: /* Play a sound :) */ - if (enable_sound) - { - play_sound(v); - } - return 0; - - /* Subdirectory scan */ - case TERM_XTRA_SCANSUBDIR: - { - filing_dirdata directory; - filing_direntry *entry; - - scansubdir_max = 0; - - if (Filing_OpenDir(riscosify_name(scansubdir_dir), &directory, sizeof(filing_direntry), readdirtype_DIRENTRY) != NULL) - { - Error_Report(0, "Couldn't open directory \"%s\"", riscosify_name(scansubdir_dir)); - return 0; - } - - while ((entry = Filing_ReadDir(&directory)) != NULL) - { - if (entry->objtype == filing_DIRECTORY) - { - string_free(scansubdir_result[scansubdir_max]); - scansubdir_result[scansubdir_max] = string_make(entry->name); - ++scansubdir_max; - } - } - - Filing_CloseDir(&directory); - - return 0; - } - - /* Return current "time" in milliseconds */ - case TERM_XTRA_GET_DELAY: - { - Term_xtra_long = Time_Monotonic() * 100; - - return 0; - } - - /* Rename main window */ - case TERM_XTRA_RENAME_MAIN_WIN: - { - Window_SetTitle(data[0].w, angband_term_name[0]); - return 0; - } - - default: - return 1; - } -} - -static errr Term_wipe_acnFS(int x, int y, int n) -{ - if (Term == &(data[0].t)) - while (n--) - fs_writechar(x++, y, ' ', 0); - return 0; -} - -static errr Term_text_acnFS(int x, int y, int n, byte a, cptr s) -{ - if (Term == &(data[0].t)) - fs_writechars(x, y, n, s, (char)a); - return 0; -} - - - -static void bored() -{ - static int last = -1; - char ts[80]; - time_t ct; - struct tm *lt; - unsigned int l; - int ofm; - static int alarm_flash = 1; - - /* Really no need to check the alarm more than once per second. */ - if (alarm_type && Time_Monotonic() > alarm_lastcheck + 100) - { - check_alarm(); - } - - l = Time_Monotonic(); - if ((l - last) < (alarm_flash ? 25 : 50)) - { - return; - } - last = l; - - time(&ct); - lt = localtime(&ct); - l = strftime(ts, 80, "%c %Z", lt); - - /* Hack: disable force_mono around printing the time */ - ofm = force_mono; - force_mono = 0; - - /* Hack: Is the alarm supposed to be going off? */ - if (alarm_disp || alarm_flash) - { - char blk[60]; - int c = 8; - if (!alarm_disp) - { - alarm_flash = 11; - } - switch (alarm_flash / 2) - { - case 4: sprintf(blk, "%-57s", alarm_cancel_text); - break; - case 5: sprintf(blk, "%-57s", fs_quit_key_text); - break; - default: - c = alarm_flash & 1 ? TERM_RED : TERM_WHITE; - sprintf(blk, "%02d:%02d %-51s", alarm_h, alarm_m, - alarm_message); - } - fs_writechars(0, TIME_LINE, 57, blk, c); - if (++alarm_flash > 11) - { - alarm_flash = 0; - } - } - - /* Display time */ - fs_writechar(79 - l, TIME_LINE, ' ', 0); - fs_writechars(80 - l, TIME_LINE, l, ts, 8); - - force_mono = ofm; -} - - - - - - -#ifdef USE_DA -/*--------------------------------------------------------------------------*/ -/* (Simple) Heap management (using OS_Heap) */ -/*--------------------------------------------------------------------------*/ - -typedef void *heap; - -static os_error *Heap_Initialise(heap h, size_t size) -{ - return SWI(4, 0, SWI_OS_Heap, 0, h, 0, size); -} - -static void *Heap_Claim(heap h, size_t size) -{ - void *fred; - os_error *e; - e = SWI(4, 3, SWI_OS_Heap, 2, h, 0, size, NULL, NULL, &fred); - return e ? NULL : fred; -} - -static os_error *Heap_Release(heap h, void *block) -{ - return SWI(3, 0, SWI_OS_Heap, 3, h, block); -} - -static int Heap_ChangeHeapSize(heap h, int resize_by) -{ - int by; - SWI(4, 4, SWI_OS_Heap, 5, h, 0, resize_by, 0, 0, 0, &by); - return by; -} - - - -/*--------------------------------------------------------------------------*/ -/* Stuff below here is for using Dynamic areas (under RO3.5+) */ -/*--------------------------------------------------------------------------*/ - -static int game_area = -1; /* The DA the game is using */ -static int font_area = -1; /* The DA the fonts are using */ - -static void *game_area_base; /* base address of game area */ -static void *font_area_base; /* base address of font area */ - -static int font_area_size; /* size of the fonts' DA */ -static int font_heap_size; /* size of the fonts' heap */ -static int game_area_size; /* size of the game's DA */ -static int game_heap_size; /* size of the game's heap */ - -#define MAX_F_DA_SIZE (2<<20) /* Max size of font area (2Mb) */ -#define MAX_G_DA_SIZE (4<<20) /* Max size of game area (4Mb) */ -#define SHRINK_GRAN (4<<10) /* Try to recalaim wastage > this (4Kb) */ - - -/* - | Free dynamic areas when we exit - */ -static void cleanup_memory(void) -{ - if (game_area != -1) - { - SWI(2, 0, SWI_OS_DynamicArea, 1, game_area); - game_area = -1; - } - - if (font_area != -1) - { - SWI(2, 0, SWI_OS_DynamicArea, 1, font_area); - font_area = -1; - } - -} - - - -/* - | Set up the memory allocation stuff. - | We check to see if DAs are possible and if so initialise two: - | one for the game's use (via the rnalloc() hooks) and one for - | our own use (for fonts, etc). - | - | Each area is created 16Kb in size, with a max size of 2/4Mb. - | - | If 'daf' is TRUE, an area is created for the fonts. - | If 'dag' is TRUE, an area is created for the game. - */ -static void init_memory(int daf, int dag) -{ - os_error *e = NULL; - - if (!daf) - { - /* Paranoia */ - font_area = -1; - font_area_base = 0; - } - else - { - e = SWI(9, 4, SWI_OS_DynamicArea, 0, /* Create */ - -1, /* Let OS allocate no. */ - 16 << 10, /* Initial size */ - -1, /* Let OS allocate address */ - 1 << 7, /* Cacheable, bufferable, RW */ - MAX_F_DA_SIZE, /* Max size */ - 0, /* handler */ - 0, /* handler workspace */ - VARIANT " font data", /* Name */ - /* */ - NULL, /* r0 */ - &font_area, /* area number allocated */ - NULL, /* r2 */ - &font_area_base /* base address of area */ - ); - - if (e) - { - game_area = font_area = -1; - game_area_base = font_area_base = 0; /* paranoia */ - return; - } - else - { - e = SWI(2, 3, SWI_OS_DynamicArea, 2, font_area, - NULL, NULL, &font_area_size); - if (e) - { - Error_ReportFatal(e->errnum, "%d:%s", e->errmess); - } - - e = Heap_Initialise((heap) font_area_base, font_area_size); - if (e) - { - Error_ReportFatal(e->errnum, "%d:%s", e->errmess); - } - font_heap_size = font_area_size; - } - } - - /* Make sure DA(s) are removed when we quit */ - atexit(cleanup_memory); - - if (!dag) - { - /* Paranoia */ - game_area = -1; - game_area_base = 0; - } - else - { - e = SWI(9, 4, SWI_OS_DynamicArea, 0, /* Create */ - -1, /* Let OS allocate no. */ - 16 << 10, /* Initial size */ - -1, /* Let OS allocate address */ - 1 << 7, /* Cacheable, bufferable, RW */ - MAX_G_DA_SIZE, /* Max size */ - 0, /* handler */ - 0, /* handler workspace */ - VARIANT " game data", /* Name */ - /* */ - NULL, /* r0 */ - &game_area, /* area number allocated */ - NULL, /* r2 */ - &game_area_base /* base address of area */ - ); - - if (e) - { - game_area = -1; - game_area_base = 0; /* paranoia */ - } - else - { - e = SWI(2, 3, SWI_OS_DynamicArea, 2, game_area, - NULL, NULL, &game_area_size); - if (e) - { - Error_ReportFatal(e->errnum, "%d:%s", e->errmess); - } - - e = Heap_Initialise((heap) game_area_base, game_area_size); - if (e) - { - Error_ReportFatal(e->errnum, "%d:%s", e->errmess); - } - game_heap_size = game_area_size; - } - } -} - -static int grow_dynamicarea(int area, int by) -{ - os_error *e; - e = SWI(2, 2, SWI_OS_ChangeDynamicArea, area, by, /**/ NULL, &by); - /* Can't check errors since a 'failed' shrink returns one... */ - return by; -} - - -/* - | Try to shrink the font-cache heap and area as much as possible. - */ -static void f_shrink_heap(void) -{ - int s; - /* Shrink the heap as far as possible */ - font_heap_size -= - Heap_ChangeHeapSize((heap) font_area_base, -MAX_F_DA_SIZE); - /* Shrink the dynamic area if necessary */ - s = font_area_size - font_heap_size; - if (s >= SHRINK_GRAN) - font_area_size -= grow_dynamicarea(font_area, -s); -} - -/* - | Allocate a block of memory in the font heap - */ -static void *f_malloc(size_t size) -{ - void *c; - int s; - if (font_area == -1) - { - return malloc(size); - } - c = Heap_Claim((heap) font_area_base, size); - - if (!c) - { - /* The Claim failed. Try to grow the area by the size of the block */ - s = grow_dynamicarea(font_area, size + 64); /* 64 is overkill */ - if (!s) - { - return NULL; - } - font_area_size += s; - s = font_area_size - font_heap_size; - font_heap_size += Heap_ChangeHeapSize((heap) font_area_base, s); - c = Heap_Claim((heap) font_area_base, size); - if (c) - { - f_shrink_heap(); - } - } - return c; -} - - -/* - | Free a block of memory in the font heap - */ -static void f_free(void *blk) -{ - os_error *e; - if (font_area == -1) - { - free(blk); - return; - } - e = Heap_Release((heap) font_area_base, blk); - if (e) - Msgs_ReportFatal(e->errnum, "err.swi", __LINE__, e->errmess); - f_shrink_heap(); -} - - - - - -/* - | Allocate a block of memory in the game heap - */ -static vptr g_malloc(huge size) -{ - void *c; - int s; - - if (game_area == -1) - { - return malloc((size_t) size); - } - c = Heap_Claim((heap) game_area_base, (size_t) size + 4); - if (!c) - { - /* The Claim failed. Try to grow the area by the size of the block */ - s = grow_dynamicarea(game_area, (size_t) size + 64); /* 64 is overkill */ - if (!s) - { - return NULL; - } - game_area_size += s; - s = game_area_size - game_heap_size; - game_heap_size += Heap_ChangeHeapSize((heap) game_area_base, s); - c = Heap_Claim((heap) game_area_base, (size_t) size + 4); - } - - if (c) - { - strcpy((char *)c, "MUSH"); - c = (void *)(((int)c) + 4); - } - - if (log_g_malloc) - fprintf(stderr, "ralloc(%ld) == %p\n", (long)size, c); - - return c; -} - - -/* - | Free a block of memory in the game heap - | - | The 'len' is to be compatible with z-virt.c (we don't need/use it) - | Returns NULL. - */ -static vptr g_free(vptr blk, huge size) -{ - os_error *e; - int s; - - if (game_area == -1) - { - free(blk); - return NULL; - } - - if (log_g_malloc) - fprintf(stderr, "rnfree(%p)\n", blk); - - if (strncmp(((char *)blk) - 4, "MUSH", 4)) - core("game heap corrupt / bad attempt to free memory"); - - blk = (void *)(((int)blk) - 4); - - e = Heap_Release((heap) game_area_base, blk); - if (e) - Msgs_ReportFatal(e->errnum, "err.swi", __LINE__, e->errmess); - - /* Shrink the heap as far as possible */ - game_heap_size -= - Heap_ChangeHeapSize((heap) game_area_base, -MAX_G_DA_SIZE); - - /* Shrink the dynamic area if necessary */ - s = game_area_size - game_heap_size; - if (s >= SHRINK_GRAN) - game_area_size -= grow_dynamicarea(game_area, -s); - - return NULL; -} - - -#endif /* USE_DA */ - - - -/*--------------------------------------------------------------------------*/ - -/* - | New to 1.04: Sound support :) - | - | We use the PlayIt module (for convenience). - | - | The Lib/xtra/sound/sound.cfg file is used to map sample names onto - | event names. - | - | Since textual names are used in the .cfg file, we need to have a lookup - | table to translate them into numbers. At present we use the - | angband_sound_name array defined in variable.c - | - | Since there can be multiple sounds for each event we need to use a - | list to store them. - */ - -/* NB: This will be clipped to 10 under RISC OS 2 */ -#define MAX_SAMPNAME_LEN 64 - - - - -/* - | The list format: - */ -typedef struct samp_node -{ - char sample_name[MAX_SAMPNAME_LEN + 1]; /* Sample name */ - struct samp_node *next; /* -> next node */ -} -SampNode; - -typedef struct samp_info -{ - int samples; /* # samples for this event */ - SampNode *samplist; /* list of sample names */ -} -SampInfo; - - -/* - | Just need an array of SampInfos - */ -static SampInfo sample[SOUND_MAX]; - -/* - | This flag will only be set non-zero if the SampInfo array is - | valid. - */ -static int sound_initd = 0; - - -static void read_sound_config(void) -{ - int i; - char buffer[2048]; - FILE *f; - int max_sampname_len = truncate_names()? 10 : MAX_SAMPNAME_LEN; - FILE *dbo = NULL; - - if (show_sound_alloc) - { - sprintf(buffer, "%s%s", resource_path, "sndmap/out"); - dbo = fopen(buffer, "w"); - if (!dbo) - { - core("can't create sndmap/out debugging file"); - } - } - - if (!sound_initd) - { - /* Initialise the sample array */ - for (i = 0; i < SOUND_MAX; i++) - { - sample[i].samples = 0; - sample[i].samplist = NULL; - } - sound_initd = 1; - } - else - { - /* Deallocate the sample lists */ - for (i = 0; i < SOUND_MAX; i++) - { - SampNode *si = sample[i].samplist; - sample[i].samples = 0; - sample[i].samplist = NULL; - while (si) - { - SampNode *ns = si->next; - free(si); - si = ns; - } - } - } - - - /* Open the config file */ - sprintf(buffer, "%sSound:%s", RISCOS_VARIANT, "sound/cfg"); - f = fopen(buffer, "r"); - - /* No cfg file => no sounds */ - if (!f) - { - if (show_sound_alloc) - { - fprintf(dbo, "** Can't open cfg file '%s'\n", buffer); - fclose(dbo); - } - return; - } - - /* Parse the file */ - while (fgets(buffer, sizeof(buffer), f)) - { - char *sample_name; - int event_number; - - /* Skip comments and lines that begin with whitespace */ - if (*buffer == '#' || isspace((unsigned char)*buffer)) - { - continue; - } - - /* Hack: ignore any line beginning '[' (section marker) */ - if (*buffer == '[') - { - continue; - } - - /* Place a NULL after the event name and find the first sample name */ - sample_name = buffer; - while (*sample_name && !isspace((unsigned char)*sample_name)) - sample_name++; - - /* Bad line? */ - if (*sample_name == 0) - { - continue; - } /* just ignore it */ - - /* Terminate the sample name */ - *sample_name++ = 0; - - /* Look up the event name to get the event number */ - for (event_number = SOUND_MAX - 1; event_number >= 0; event_number--) - if (!strcmp(buffer, angband_sound_name[event_number])) - break; - - /* No match -> just ignore the line */ - if (event_number < 0) - { - if (show_sound_alloc) - fprintf(dbo, "* Ignoring unknown event '%s'\n", buffer); - continue; - } - - /* Find the = */ - while (*sample_name && *sample_name != '=') - sample_name++; - - /* Bad line? */ - if (*sample_name == 0) - { - continue; - } /* just ignore it */ - - /* Skip the '=' */ - sample_name++; - - - /* - | Now we find all the sample names and add them to the - | appropriate list in the sample mapping array - */ - - while (*sample_name) - { - char *s; - SampNode *sn; - - /* Find the start of the next word */ - while (isspace((unsigned char)*sample_name) && *sample_name) - sample_name++; - - /* End of line? */ - if (!*sample_name) - { - break; - } - - /* Find the end of the sample name */ - s = sample_name; /* start of the name */ - while (!isspace((unsigned char)*sample_name) && *sample_name) - sample_name++; - - /* Hack: shorten sample names that are too long */ - if ((sample_name - s) > max_sampname_len) - s[max_sampname_len] = ' '; - - /* Allocate a node in the sample list for the event */ - if ((sn = malloc(sizeof(SampNode))) == NULL) - core("Out of memory (scanning sound.cfg)"); - - /* Link the node to the list */ - sn->next = sample[event_number].samplist; - sample[event_number].samplist = sn; - - /* Imcrement the sample count for that event */ - sample[event_number].samples++; - - /* - | Copy the sample name into the node, converting it into - | RISC OS style as we go. - */ - for (i = 0; !isspace((unsigned char)s[i]) && s[i]; i++) - { - if (s[i] == '.') - sn->sample_name[i] = '/'; - else if (s[i] == '/') - sn->sample_name[i] = '.'; - else - sn->sample_name[i] = s[i]; - } - /* - | The sample name '*' is special and means "no new sound" - | so don't store a filename for these mappings. - */ - if (i == 1 && sn->sample_name[0] == '*') - { - i = 0; - } - sn->sample_name[i] = 0; - } - } - - /* Close the file */ - fclose(f); - - if (show_sound_alloc) - { - int i; - SampNode *l; - - for (i = 0; i < SOUND_MAX; i++) - { - fprintf(dbo, "\n\nEvent '%s'", angband_sound_name[i]); - fprintf(dbo, " (%d sounds)\n", sample[i].samples); - for (l = sample[i].samplist; l; l = l->next) - fprintf(dbo, "\t%s\n", l->sample_name); - } - fclose(dbo); - } - -} - - - -/* - | Try to make sure that PlayIt is loaded. - | This requires AngSound rel. 4 - */ -static void check_playit(void) -{ - if (SWI(2, 0, SWI_OS_Module, 18, "PlayIt")) - { - int t; - SWI(2, 1, SWI_OS_File, 17, "Angsound:LoadPlayIt", &t); - if (t == 1) - SWI(1, 0, SWI_OS_CLI, - "RMEnsure PlayIt 0.00 Run AngSound:LoadPlayIt"); - } -} - - - - -static void initialise_sound(void) -{ - /* Load the configuration file */ - Hourglass_On(); - read_sound_config(); - check_playit(); - Hourglass_Off(); -} - - - -static void play_sample(char *leafname) -{ - char buffer[260]; - - strcpy(buffer, "%playit_stop"); - - if (!SWI(1, 0, SWI_OS_CLI, buffer)) - { - SWI(1, 0, SWI_PlayIt_Volume, sound_volume); - sprintf(buffer, "%%playit_play %sSound:%s", RISCOS_VARIANT, leafname); - SWI(1, 0, SWI_OS_CLI, buffer); - } - - return; -} - - - -static void play_sound(int event) -{ - /* Paranoia */ - if (!sound_initd) - { - return; - } - - /* Paranoia */ - if (event < 0 || event >= SOUND_MAX) - return; - - /* msg_format("Sound '%s'",angband_sound_name[event]); */ - - /* Choose a sample */ - if (sample[event].samples) - { - int s = rand() % sample[event].samples; - SampNode *sn = sample[event].samplist; - while (s--) - { - sn = sn->next; - if (!sn) - { - plog("Adny botched the sound config - please send him a copy of your sound/cfg file."); - } - } - if (*(sn->sample_name)) - play_sample(sn->sample_name); - } -} - - - - -/*--------------------------------------------------------------------------*/ - -/* - | This stuff is for the Term_user hook - */ - - - -static void display_line(int x, int y, int c, const char *fmt, ...) -{ - va_list ap; - char buffer[260]; - - va_start(ap, fmt); - vsprintf(buffer, fmt, ap); - Term_putstr(x, y, -1, c, buffer); - va_end(ap); -} - - - -/* - | Let the user change the alarm message - */ -static void do_alarm_message_input(int y) -{ - int k; - int inspos = strlen(alarm_message); - char old_message[52]; - - strcpy(old_message, alarm_message); - - do - { - display_line(26, y, TERM_YELLOW, "%-51s", alarm_message); - Term_gotoxy(26 + inspos, y); - k = inkey(); - switch (k) - { - case 21: /* ^U */ - *alarm_message = 0; - inspos = 0; - break; - case 128: case 8: /* delete */ - if (inspos > 0) - { - alarm_message[--inspos] = 0; - } - break; - case 27: /* escape */ - strcpy(alarm_message, old_message); - k = 13; - break; - default: - if (k > 31 && k < 127 && inspos < 50) - { - alarm_message[inspos++] = k; - alarm_message[inspos] = 0; - } - } - } - while (k != 13); - - display_line(26, y, TERM_WHITE, "%-51s", alarm_message); -} - - -#define tum_col(X) ((X) ? TERM_L_BLUE : TERM_WHITE ) -#define tum_onoff(X) ((X) ? "On " : "Off") - -static errr Term_user_acn(int n) -{ - int cursor_state; - int optn = 0; - int k, adj; - int redraw_mung = 0; - int max_opt = 11; - int alarm_modified = 0; /* Will be true if the alarm choices need to be (re)saved */ - - /* - | Hack: let the desktop front end know that - | the user menu is active... - */ - user_menu_active = TRUE; - - - /* - | This is thanks to Norcroft CC... it seems to want - | to set up FP regs nice and early and then relies - | on them remaining constant over the function call. - | The trouble is that we implicitly call Wimp_Poll - | whilst waiting for a key press... - */ - event_mask.data.keepfpregisters = 1; - - /* - | Hack: alarm type 1 /looks/ the same as type 3 but doesn't get - | cancelled as a type 3 would. This allows alarms to go off and - | be cancelled without affecting the alarm type whilst it's being - | set up here. - */ - if (alarm_type == 3) - { - alarm_type = 1; - } - - /* - | Store the screen - */ - Term_activate(&(data[0].t)); - Term_save(); - Term_get_cursor(&cursor_state); - Term_set_cursor(TRUE); - - do - { - redraw_mung = 0; - Term_clear(); - display_line(2, 1, TERM_YELLOW, "%s %s", VARIANT, VERSION); - display_line(2, 2, TERM_SLATE, "Front-end %s", PORTVERSION); - display_line(2, 4, TERM_WHITE, - "Use cursor up/down to select an option then cursor left/right to alter it."); - display_line(2, 5, TERM_WHITE, - "Hit 'S' to save these settings (alarm settings are saved automatically)."); - display_line(2, 6, TERM_WHITE, "Hit ESC to return to the game."); - - for (k = 0; k < 16; k++) - display_line(31 + k * 3, 8, k, "##", k); - - do - { - display_line(2, 8, tum_col(optn == 0), - " Gamma correction : %.2lf", gamma); - display_line(2, 9, tum_col(optn == 1), " Force monochrome : %s", - tum_onoff(force_mono)); - display_line(2, 10, tum_col(optn == 2), " Sound effects : %s", - tum_onoff(enable_sound)); - display_line(2, 11, tum_col(optn == 3), " Sound effect volume : "); - display_line(26, 11, - sound_volume > 127 ? TERM_RED : tum_col(optn == 3), - "%-3d", sound_volume); - display_line(30, 11, tum_col(optn == 3), "(127 = full volume)"); - display_line(2, 12, tum_col(optn == 4), " Start fullscreen : %s", - tum_onoff(start_fullscreen)); - display_line(30, 12, tum_col(optn == 4), - "(also selects fullscreen/desktop now)"); - display_line(2, 13, tum_col(optn == 5), " Use hourglass : %s", - tum_onoff(use_glass)); - display_line(2, 14, tum_col(optn == 6), - "'Hard' input flushing : %s", tum_onoff(hack_flush)); - - display_line(7, 16, tum_col(optn == 7), " Alarm type : %-20s", - alarm_types[alarm_type]); - display_line(7, 17, TERM_WHITE, " Time : "); - display_line(26, 17, tum_col(optn == 8), "%02d", alarm_h); - display_line(28, 17, TERM_WHITE, ":"); - display_line(29, 17, tum_col(optn == 9), "%02d", alarm_m); - display_line(7, 18, tum_col(optn == 10), " Message : %-51s", - alarm_message); - display_line(7, 19, tum_col(optn == 11), " Beep : %s", - tum_onoff(alarm_beep)); - -#ifdef FE_DEBUG_INFO - display_line(2, 23, tum_col(optn == 23), "Show debug info"); - max_opt = 12; -#endif - - switch (optn) - { - case 12: Term_gotoxy(2, 23); - break; - case 11: Term_gotoxy(26, 19); - break; - case 10: Term_gotoxy(26, 18); - break; - case 9: Term_gotoxy(29, 17); - break; - case 8: Term_gotoxy(26, 17); - break; - case 7: Term_gotoxy(26, 16); - break; - default: Term_gotoxy(26, optn + 8); - } - - k = inkey(); - adj = (k == '4' || k == 'h') ? -1 : (k == '6' || k == 'l') ? 1 : 0; - - switch (k) - { - case 18: /* Hack: force the screen to update */ - redraw_mung = 1; - k = 27; - break; - case 's': case 'S': - save_choices(); - display_line(2, 23, TERM_YELLOW, "Options saved. "); - Term_fresh(); - Term_xtra(TERM_XTRA_DELAY, 750); - Term_erase(2, 23, 60); - break; - case '8': case 'k': - if (--optn < 0) - { - optn = max_opt; - } - break; - case '2': case 'j': - if (++optn > max_opt) - { - optn = 0; - } - break; - case 13: case 32: case 't': /* Allow return, space and t to toggle some options */ - case '4': case 'h': - case '6': case 'l': - { - switch (optn) - { - case 0: /* Gamma correction */ - gamma += adj * 0.05; - if (gamma > 9.00) - { - gamma = 9.00; - } - if (gamma < 0.05) - { - gamma = 0.05; - } - Term_xtra(TERM_XTRA_REACT, 0); -#ifndef FULLSCREEN_ONLY - set_gamma_window_state(); -#endif /* FULLSCREEN_ONLY */ - /* flush(); */ - Term_fresh(); - break; - case 1: /* Force monochrome */ - force_mono = !force_mono; - if (fullscreen_font) - redraw_areaFS(0, 0, 80, 24); - else - Term_xtra(TERM_XTRA_REACT, 0); - /* flush(); */ - Term_fresh(); - break; - case 2: /* Sound enable / disable */ - enable_sound = !enable_sound; -#ifndef FULLSCREEN_ONLY - set_sound_window_state(); -#endif /* FULLSCREEN_ONLY */ - if (enable_sound) - { - initialise_sound(); - } - break; - case 3: /* Sound volume */ - sound_volume += adj; - if (sound_volume < SOUND_VOL_MIN) - sound_volume = SOUND_VOL_MIN; - if (sound_volume > SOUND_VOL_MAX) - sound_volume = SOUND_VOL_MAX; -#ifndef FULLSCREEN_ONLY - set_sound_window_state(); -#endif /* FULLSCREEN_ONLY */ - break; - case 4: /* Start fullscreen */ - start_fullscreen = !start_fullscreen; - if (start_fullscreen) - enter_fullscreen_mode(); - else if (!minimise_memory) - leave_fullscreen_mode(); - break; - case 5: /* Start fullscreen */ - use_glass = !use_glass; - if (!use_glass) - { - if (glass_on) - { - Hourglass_Off(); - } - glass_on = 0; - } - break; - case 6: /* hack flush */ - hack_flush = !hack_flush; - break; - case 7: /* Alarm on/off */ - alarm_type += adj; - if (adj) - { - alarm_modified = 1; - } - if (alarm_type > 2) - { - alarm_type = 0; - } - if (alarm_type < 0) - { - alarm_type = 2; - } - if (!alarm_type && alarm_disp) - { - ack_alarm(); - } /* XXXXX Cancel an already active alarm? */ - break; - case 8: /* Alarm hours */ - alarm_h += adj; - if (adj) - { - alarm_modified = 1; - } - if (alarm_h < 0) - { - alarm_h += 24; - } - if (alarm_h > 23) - { - alarm_h -= 24; - } - if (alarm_disp) - { - ack_alarm(); - } - break; - case 9: /* Alarm minutes */ - alarm_m += adj; - if (adj) - { - alarm_modified = 1; - } - if (alarm_m < 0) - { - alarm_m += 60; - } - if (alarm_m > 59) - { - alarm_m -= 60; - } - if (alarm_disp) - { - ack_alarm(); - } - break; - case 10: - alarm_modified = 1; - do_alarm_message_input(18); - break; - case 11: - alarm_modified = 1; - alarm_beep = !alarm_beep; - break; - case 12: - show_debug_info(); - redraw_mung = 1; - k = 27; - break; - } - } - } - } - while (k != 27); - } - while (redraw_mung); - - /* Rehack the alarm type: */ - if (alarm_type == 1) - { - alarm_type = 3; - } - - if (alarm_modified) - { - write_alarm_choices(); - } - - Term_set_cursor(cursor_state); - - /* Restore the screen */ - Term_load(); - - /* Don't need to preserve FP regs any more */ - event_mask.data.keepfpregisters = 0; - - /* - | Hack: tell the desktop front end that we're done. - */ - user_menu_active = FALSE; - - return 0; -} - - - - -/*--------------------------------------------------------------------------*/ - -#ifdef USE_FILECACHE - -/* - | 'Random' File-cacheing for *band. - | - | Rewritten since as of Zang 225 the mechanism for handling - | these files has changed dramatically and the old system - | is no longer viable. - | - | These new functions basically provide an alternative to the - | normal my_fopen() (or fopen()) and my_fgets() functions. - | - | To use the file caching it is therefore necessary to alter - | files.c to call cached_fopen(), cached_fclose() and cached_fgets() - | rather than the normal functions. - | - | Note that these funtions will only work for files that are intended - | to be read as a series of \n terminated lines of ASCII text using my_fgets(). - | - */ - -/* - | Hack: use the game's dynamic area if possible: - */ -#define fc_malloc(X) (g_malloc(X)) -#define fc_free(X) (g_free(X,0)) - -#ifndef ABBR_FILECACHE -/* - | Make these to do nothing. They'll never - | be called anyway. Having them present makes - | for neater code later on (ie. we use a variable - | rather than the pre-processor to decide whether - | to do compression). - */ -static int compress_string(char *os, char *s) -{ - core("main-acn internal logic error 001"); - return 0; -} -static int decompress_string(char *d, char *s, int max_len) -{ - core("main-acn internal logic error 002"); - return 0; -} -static int compressed_length(char *s) -{ - core("main-acn internal logic error 003"); - return 0; -} - -#else - -/* - | When caching files we try to use some abbreviations. - | We use both whole words and pairs of letters. - | NB: For this to work, the file must contain only - | 7 bit characters. - */ -static char *abbrv_w[] = -{ - /* These words all begin with a space */ - " of ", " the ", " you ", " to ", " a ", " says", " is ", " that ", " and ", - " your ", " are ", " it ", " be ", " for ", " me", " will ", " in ", - " not ", " this ", " have ", " can ", " on ", " my ", " with ", " say ", - " all", " by ", " get ", " but ", " just ", " die", " as ", " time ", - " if ", - " like ", - /* These words do not */ - "I ", "The ", "You ", "They ", "It ", "don", 0 -}; - -/* Number of words */ -#define FC_ABBRV_NUMWORDS 41 - -/* Number of them that don't start with a space */ -#define FC_ABBRV_NONSPC 6 - -/* - | NB: No letter pair may start with \0. - */ -static char abbrv_lp[] = - "e ttht s heiner aoure'\0, anonf sd y r ongofator.\0" - "n arllstha wes m ieaisen bl yndtoo yometele d f hve" - "ayuralitneelN: chig ilroassaseliti lraa otedbede 'ri" "..u nntno!'ee\0\0"; - - -/* - | Compress the given string using the abbreviation tables above. - | Returns compressed length *including* terminator (it may - | be part of an abbreviation, you see...) - | Note that we can compress the string in-place, ie. 'os' may be - | the same as 's'. - */ -static int compress_string(char *os, char *s) -{ - char *o, *f, *d; - int i; - - o = os; - - while (*s) - { - int fw, lw; - if (*s == ' ') - { - fw = 0; - lw = FC_ABBRV_NUMWORDS - FC_ABBRV_NONSPC; - } - else - { - fw = FC_ABBRV_NUMWORDS - FC_ABBRV_NONSPC; - lw = FC_ABBRV_NUMWORDS; - } - for (i = fw; i < lw; i++) - { - d = abbrv_w[i]; /* Word to check against */ - for (f = s; *f && *f == *d; f++, d++) - ; - if (*d == 0) /* Match? */ - { - s = *f ? f : f - 1; /* Update string pointer */ - *o++ = 128 + i; /* store code */ - break; /* Quit looking for words */ - } - } - - /* Do we need to check the letter pairs? */ - if (i == lw) - { - for (i = 0; abbrv_lp[i]; i += 2) - { - if (s[0] == abbrv_lp[i] && s[1] == abbrv_lp[i + 1]) - { - *o++ = 128 + FC_ABBRV_NUMWORDS + i / 2; - /* NB: If the next character is the terminator then we're done. */ - if (!s[1]) - { - return (o - os); - } - s += 2; /* Quit looking for letters */ - break; - } - } - /* NB: This next check is only safe because no letter pair starts with a NULL */ - if (!abbrv_lp[i]) - *o++ = *s++; - } - } - - /* Don't forget that terminator! */ - *o++ = 0; - - return o - os; -} - -/* - | As compress_string (above), but stores nothing and - | only returns the length of the compressed string. - */ -static int compressed_length(char *s) -{ - char *f, *d; - int i, l; - - l = 0; - while (*s) - { - int fw, lw; - if (*s == ' ') - { - fw = 0; - lw = FC_ABBRV_NUMWORDS - FC_ABBRV_NONSPC; - } - else - { - fw = FC_ABBRV_NUMWORDS - FC_ABBRV_NONSPC; - lw = FC_ABBRV_NUMWORDS; - } - for (i = fw; i < lw; i++) - { - d = abbrv_w[i]; - for (f = s; *f && *f == *d; f++, d++) - ; - if (*d == 0) /* Match? */ - { - s = *f ? f : f - 1; /* Update string pointer */ - l++; /* increment output length */ - break; /* Quit looking for words */ - } - } - - /* Do we need to check the letter pairs? */ - if (i == lw) - { - for (i = 0; abbrv_lp[i]; i += 2) - { - if (s[0] == abbrv_lp[i] && s[1] == abbrv_lp[i + 1]) - { - l++; /* increment output length */ - /* NB: If the next character is the terminator then we're done. */ - if (!s[1]) - { - return l; - } - s += 2; /* Quit looking for letters */ - break; - } - } - /* NB: This next check is only safe because no letter pair starts with a NULL */ - if (!abbrv_lp[i]) - { - l++; - s++; - } - } - } - /* Don't forget that terminator! */ - return l + 1; -} - - - -/* - | Decompress the given string 's' into the buffer at 'd'. - | At most, max_len characters (incl. \0 terminator) will be - | written into d. - | Returns the length of 's'. - */ -static int decompress_string(char *d, char *s, int max_len) -{ - char *os = s; - - while (max_len > 1) - { - int nc = *s++; /* Get next character */ - - if (nc < 128) /* Is it a plain character? */ - { - if (0 == (*d++ = nc)) - { - break; - } - max_len--; - } - else /* Abbreviation to expand. */ - { - if (nc >= FC_ABBRV_NUMWORDS + 128) /* Letter pair? */ - { - *d++ = abbrv_lp[(nc - (FC_ABBRV_NUMWORDS + 128)) * 2]; - if (0 == - (*d++ = abbrv_lp[(nc - (FC_ABBRV_NUMWORDS + 128)) * 2 + 1])) - break; - max_len -= 2; - } - else /* It's a word */ - { - char *ws = abbrv_w[nc - 128]; - while (*ws && max_len > 1) - { - *d++ = *ws++; - max_len--; - } - } - } - } - - /* Skip over the rest of the abbreviated string if we ran out of space */ - if (max_len <= 1) /* Out of space? */ - { - int nc; - *d = 0; /* Terminate */ - do - { - nc = *s++; /* Next char */ - if (nc >= 128 + FC_ABBRV_NUMWORDS) /* Ignore words */ - nc = abbrv_lp[(nc - (FC_ABBRV_NUMWORDS + 128) * 2) + 1]; /* Only check 2nd letter of pair */ - } - while (nc); - } - return s - os; /* Length of abbreviated string */ -} - -#endif /* ABBR_FILECACHE */ - - -/* Each entry in the cache looks like this: */ -typedef struct fce_ -{ - char *name; /* canonical pathname of file */ - char *text; /* text (be it compressed or not) */ - char *eof; /* byte beyond the last byte of text */ - int used; /* access counter when the file was last used */ - int compressed; /* compression method, (ie. 0 for none or 1 for abbreviations) */ -} -FileCacheEntry; - -/* - | The handles we chuck around are pointers to one of these structs. - | Note that since we actually return (and take) |FILE*|s we just - | compare the value of a |FILE*| with the limits of the array of - | |CachedFileHandle|s to decide whether its 'ours' or a genuine - | (ie. stdio) file handle. This /is/ pretty lame, I know... - */ -typedef struct cfh_ -{ - char *ptr; /* sequential file pointer, as it were */ - FileCacheEntry *fce; /* ->the file-cache entry data */ -} -CachedFileHandle; - -#define MAX_OPEN_CACHED_FILES 16 /* We allow up to 16 of these files open at once */ -#define MAX_CACHE_ENTRIES 64 /* We allow up to 64 cache entries */ - -static FileCacheEntry *file_cache; /* to be used as file_cache[MAX_CACHE_ENTRIES] */ -static CachedFileHandle *cached_file_handle; /* to be used as cached_file_handle[MAX_OPEN_CACHED_FILES] */ -static int file_cache_initd = 0; /* Is the cache initialised? */ -static int file_cache_size = 0; /* Total size of the cached files */ -static int fc_access_counter = 1; /* incremented on each cache access */ -/* - | Pre-calculate max. possible value of a FILE* (ie. address in memory) - | that could be a valid |CachedFileHandle*|. - */ -static FILE *max_cfh_addr; /* == (FILE*) (&(cached_file_handle[MAX_OPEN_CACHED_FILES-1])) */ - |