summaryrefslogtreecommitdiff
path: root/src/main-ros.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main-ros.c')
-rw-r--r--src/main-ros.c8670
1 files changed, 0 insertions, 8670 deletions
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])) */
-
-/*
- | Initialise the file cache
- */
-static void init_file_cache(void)
-{
- int i;
-
- /* Allocate storage */
- file_cache = fc_malloc(MAX_CACHE_ENTRIES * sizeof(FileCacheEntry));
- cached_file_handle =
- fc_malloc(MAX_OPEN_CACHED_FILES * sizeof(CachedFileHandle));
-
- if (!file_cache || !cached_file_handle)
- {
- /* Disable file-caching */
- if (file_cache)
- {
- fc_free(file_cache);
- }
- if (cached_file_handle)
- {
- fc_free(cached_file_handle);
- }
- use_filecache = 0;
- }
- else
- {
- /* Initialise the cache */
- for (i = 0; i < MAX_CACHE_ENTRIES; i++)
- file_cache[i].name = NULL;
- for (i = 0; i < MAX_OPEN_CACHED_FILES; i++)
- cached_file_handle[i].fce = NULL;
- fc_access_counter = 1;
- file_cache_size = 0;
- max_cfh_addr =
- (FILE *)(&(cached_file_handle[MAX_OPEN_CACHED_FILES - 1]));
- }
- file_cache_initd = 1;
-}
-
-
-/*
- | Helper: take a copy of the string and return a pointer to it
- */
-static char *string_cpy(char *s)
-{
- char *d = fc_malloc(strlen(s) + 1L);
- if (d)
- {
- strcpy(d, s);
- }
- return d;
-}
-
-
-/*
- | Cache the specified file, returning either the cache entry
- | that it has been cached at, or NULL for failure.
- |
- | Note that for the abbreviated file cache a temporary file
- | is used to allow the compression to be applied just once.
- | (otherwise it has to be done twice - once to determine the
- | eventual compressed size and once to actually store and compress
- | it).
- */
-static FileCacheEntry *cache_file(char *name)
-{
- int i, size = 0;
- FILE *fp;
- char buffer[1024];
- char *d;
-
- FILE *tf = NULL; /* Used if abbr_filecache and abbr_tmpfile are set */
- char cfn[1024]; /* Used if abbr_filecache and abbr_tmpfile are set */
-
- /* Find the first free slot in the cache */
- for (i = 0; i < MAX_CACHE_ENTRIES; i++)
- if (!file_cache[i].name)
- break;
-
- /* No more entries? */
- if (i >= MAX_CACHE_ENTRIES)
- {
- return NULL;
- }
-
- /* Set up the info on the file */
- if ((file_cache[i].name = string_cpy(name)) == NULL)
- {
- return NULL;
- }
-
- /* Open the file */
- fp = my_fopen(name, "r");
- if (!fp)
- {
- fc_free(file_cache[i].name);
- file_cache[i].name = 0;
- return NULL;
- }
-
- /* Open/create tempfile if need be: */
- if (abbr_filecache && abbr_tmpfile)
- {
- /* Hack: Form the pathname of the cached compressed file (in canonical form) */
- sprintf(cfn, "%s%s", scrap_path,
- riscosify_name(name + strlen(resource_path)));
- /* Ensure that that particular directory exists... */
- ensure_path(cfn);
- /* Check whether cache file is out of date */
- if (file_is_newer(riscosify_name(name), cfn))
- {
- tf = fopen(cfn, "wb");
- size = 0;
- }
- else
- {
- tf = fopen(cfn, "rb");
- if (tf)
- {
- size = myFile_Size(cfn);
- }
- }
- }
-
- /* If we don't have the cached file (but want it), compress the source text to it */
- if (tf)
- {
- if (!size)
- {
- int k;
- while (!my_fgets(fp, buffer, sizeof(buffer)))
- {
- if (smart_filecache && (!*buffer || *buffer == '#'))
- continue;
- k = compress_string(buffer, buffer);
- if (fwrite(buffer, 1, k, tf) != k)
- {
- fclose(tf);
- remove(cfn);
- core("error writing tempfile");
- }
- size += k;
- }
- fclose(tf);
- tf = fopen(cfn, "rb");
- }
- }
- else
- {
- /* Count the number of bytes */
- while (!my_fgets(fp, buffer, sizeof(buffer)))
- {
- if (smart_filecache && (!*buffer || *buffer == '#'))
- continue;
- if (abbr_filecache)
- size += compressed_length(buffer);
- else
- size += strlen(buffer) + 1;
- }
- }
-
- /* Close the (source) file */
- my_fclose(fp);
-
- /* Allocate enough storage for the text */
- file_cache[i].text = fc_malloc(size + 1L);
- if (!file_cache[i].text)
- {
- fc_free(file_cache[i].name);
- file_cache[i].name = 0;
- if (tf)
- {
- fclose(tf);
- }
- return NULL;
- }
-
- /* Do we have a tempfile to load? */
- if (tf)
- {
- if (fread(file_cache[i].text, 1, size, tf) != size)
- core("error reading tempfile");
- fclose(tf);
- }
- else
- {
- /* Re-open the file... */
- fp = my_fopen(name, "r");
- if (!fp)
- {
- fc_free(file_cache[i].name);
- fc_free(file_cache[i].text);
- file_cache[i].name = 0;
- return NULL;
- }
-
- /* And read it into the buffer... */
- d = file_cache[i].text;
- while (!my_fgets(fp, buffer, sizeof(buffer)))
- {
- if (smart_filecache && (!*buffer || *buffer == '#'))
- continue;
- if (abbr_filecache)
- d += compress_string(d, buffer);
- else
- {
- strcpy(d, buffer);
- d += strlen(buffer) + 1;
- }
- }
-
- if ((d - file_cache[i].text) != size)
- {
- debug("Calculated size is %d, pointer offset is %d", size,
- (d - file_cache[i].text));
- core("Cached file is larger than calculated!");
- }
-
- /* Close the file */
- my_fclose(fp);
- }
-
- /* Set up the 'last accessed' value, etc. */
- file_cache[i].used = fc_access_counter++;
- file_cache[i].eof = file_cache[i].text + size;
- file_cache[i].compressed = abbr_filecache;
- file_cache_size += size;
-
- /* Return success */
- return &(file_cache[i]);
-}
-
-
-/*
- | Discard a file from the cache
- */
-static void discard_cached_file(int i)
-{
- if (!file_cache[i].name)
- {
- return;
- } /* invalid request */
- fc_free(file_cache[i].text);
- fc_free(file_cache[i].name);
- file_cache_size -= (file_cache[i].eof) - (file_cache[i].text);
- file_cache[i].name = 0;
-}
-
-
-/*
- | Attempt to flush as much of the cache as required
- | to bring it within the size limit.
- | If protect != 0 then that entry in the cache won't be flushed.
- */
-static void flush_file_cache(FileCacheEntry * protect)
-{
- int i, j, done;
- int oldest_u, oldest_e;
- FileCacheEntry *fce;
- int needed = (4 << 10); /* Hack: try to free at least 4K */
-
- done = (file_cache_size + needed) <= max_file_cache_size;
-
- while (!done)
- {
- oldest_u = fc_access_counter;
- oldest_e = -1;
-
- fce = file_cache;
- /* Find oldest entry that isn't in use */
- for (i = 0; i < MAX_CACHE_ENTRIES; fce++, i++)
- {
- if (fce == protect)
- {
- continue;
- } /* Hack ;) */
- if (fce->name) /* Is this cache slot full? */
- {
- for (j = 0; j < MAX_OPEN_CACHED_FILES; j++)
- if (cached_file_handle[j].fce == fce)
- break;
- if (j < MAX_OPEN_CACHED_FILES)
- continue; /* Cached file is still open */
- if (fce->used < oldest_u)
- {
- oldest_e = i;
- oldest_u = file_cache[i].used;
- }
- }
- }
-
- if (oldest_e < 0)
- done = 1; /* We can flush nothing more */
- else
- {
- discard_cached_file(oldest_e);
- done = (file_cache_size + needed) <= max_file_cache_size;
- }
- }
-}
-
-
-/*
- | Locate the specified file within the cache.
- | Returns NULL if the file is not cached
- */
-static FileCacheEntry *find_cached_file(char *name)
-{
- int i;
- FileCacheEntry *fce = file_cache;
-
- for (i = 0; i < MAX_CACHE_ENTRIES; i++, fce++)
- {
- if (fce->name)
- if (streq(fce->name, name))
- return fce;
- }
- return NULL;
-}
-
-
-
-/*--------------------------------------------------------------------------*/
-/* Externally visible file cache stuff */
-/*--------------------------------------------------------------------------*/
-
-/*
- | Open a file...
- | Returns the file cache handle of the file, or NULL for failure.
- | Note that if mode is anything other than "r" the call defers to
- | my_fopen().
- |
- | NB: The returned handle 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.
- */
-FILE *cached_fopen(char *name, char *mode)
-{
- FileCacheEntry *fcs = NULL;
- int fch;
-
- if (strcmp(mode, "r") || !use_filecache)
- return my_fopen(name, mode);
-
- if (!file_cache_initd)
- {
- init_file_cache();
- }
-
- if (max_file_cache_size >= 0)
- {
- /* Find a free cache entry */
- for (fch = 0; fch < MAX_OPEN_CACHED_FILES; fch++)
- if (!cached_file_handle[fch].fce)
- break;
-
- /* Out of handles? */
- if (fch >= MAX_OPEN_CACHED_FILES)
- return my_fopen(name, mode);
-
- /* Is the file already cached? */
- fcs = find_cached_file(name);
- if (!fcs)
- {
- /* File wasn't cached, so cache it */
- flush_file_cache(NULL); /* Clean stuff out of the cache if need be */
- fcs = cache_file(name); /* Cache the new file */
- flush_file_cache(fcs); /* Flush, but keep the latest file */
- }
- }
-
- /* Did we fail to cache the file? */
- if (!fcs)
- {
- return my_fopen(name, mode);
- }
-
- /* File was cached OK */
- cached_file_handle[fch].ptr = fcs->text; /* Init sequential pointer */
- cached_file_handle[fch].fce = fcs; /* Cache block pointer */
- fcs->used = fc_access_counter++; /* Opening the file counts as an access */
-
- return (FILE *)(&cached_file_handle[fch]);
-}
-
-
-/*
- | Close a file
- */
-errr cached_fclose(FILE *fch_)
-{
- CachedFileHandle *fch;
-
- /* Is the FILE* genuine? */
- if ((fch_ < (FILE *)cached_file_handle) || (fch_ > max_cfh_addr))
- return my_fclose(fch_);
-
- fch = (CachedFileHandle *) fch_;
-
- /* Check for "Ooopses": */
- if (fch->fce == NULL)
- core("cached_fclose called on a non-open file handle");
-
- flush_file_cache(NULL); /* Clean out the cache if need be */
- fch->fce = NULL; /* Mark file handle as inactive */
-
- return 0;
-}
-
-
-/*
- | Do the my_fgets thing on a file
- */
-errr cached_fgets(FILE *fch_, char *buffer, int max_len)
-{
- CachedFileHandle *fch;
- char *eof;
- char *ptr;
-
- /* Is the FILE* genuine? */
- if ((fch_ < (FILE *)cached_file_handle) || (fch_ > max_cfh_addr))
- return my_fgets(fch_, buffer, max_len);
-
- fch = (CachedFileHandle *) fch_;
-
- /* Check for "Oopses": */
- if (!file_cache_initd)
- core("cached_fgets() on uninitialised file-cache");
- if (!fch->fce)
- core("cached_fgets called for a un-open file");
-
- eof = fch->fce->eof;
- ptr = fch->ptr;
-
- /* Out of bounds? */
- if (ptr >= eof)
- {
- return 1;
- } /* Read failed */
-
- /*
- | Read the next line, up to \0 (which would have v=been \n in the original file),
- | or max_len-1 characters
- */
- if (fch->fce->compressed)
- ptr += decompress_string(buffer, ptr, max_len);
- else
- {
- if (eof - ptr < max_len)
- {
- max_len = eof - ptr;
- }
- for (; max_len >= 1; max_len--)
- if ((*buffer++ = *ptr++) == 0)
- break;
- *buffer = 0; /* terminate (paranoia) */
- }
-
- /* Update sequential pointer */
- fch->ptr = ptr;
-
- return 0;
-}
-
-#endif /* USE_FILECACHE */
-
-
-/*
- | This section deals with checking that the .raw files are up to date
- | wrt to the .txt files. Note that this function won't work for RISC OS 2
- | (due to the lack of OS_Args 7) so it simply returns 0 to indicate that
- | the file isn't OOD.
- |
- | For this to work, the equivalent function (in init2.c) needs to be
- | #if-d out (and this function should be declared). You'll probably
- | also need to zap the UNIX #includes at the top of the file
- */
-
-extern errr check_modification_date(int fd, cptr template_file)
-{
- char raw_buf[1024];
- char txt_buf[1024];
- int i;
- os_error *e;
-
- if (os_version() < 300)
- {
- return 0;
- }
-
- /* Use OS_Args 7 to find out the pathname 'fd' refers to */
- e = SWI(6, 0, SWI_OS_Args,
- /* In: */
- 7, /* Get path from filehandle */
- fd, /* file handle */
- raw_buf, /* buffer */
- 0, 0, /* unused */
- 1024 /* size of buffer */
- /* No output regs used */
- );
- if (e)
- {
- core(e->errmess);
- }
-
- /* Build the path to the template_file */
- path_build(txt_buf, sizeof(txt_buf), ANGBAND_DIR_EDIT, template_file);
-
- i = file_is_newer(riscosify_name(txt_buf), raw_buf);
-
- return i;
-}
-
-
-/*--------------------------------------------------------------------------*/
-
-/*
- | This is the hideous IClear hack. Basically what we do is to take a copy
- | of the module and kill it in the RMA. Then, on return to the desktop
- | we reinstate the module.
- |
- | NB: This is truly, truly evil.
- */
-
-static int *iclear_module = NULL;
-
-/*
- | Start the IClear hack
- */
-static void iclear_hack(void)
-{
- os_error *e;
- int code = 0;
- int *i;
-
- /* Get base address of module */
- e = SWI(2, 4, SWI_OS_Module, 18, "IClear", 0, 0, 0, &code);
- if (e || !code)
- return;
-
- /* Module size is at code!-4 */
- i = (int *)code;
- iclear_module = malloc(i[-1] + 4);
- if (!iclear_module)
- return;
-
- /* Copy the module */
- *iclear_module = i[-1];
- memcpy(iclear_module + 1, (void *)code, i[-1]);
-
- /* Kill the current version */
- e = SWI(2, 0, SWI_OS_Module, 4, "IClear");
- if (e)
- {
- free(iclear_module);
- iclear_module = NULL;
- }
-}
-
-
-/*
- | Remove the IClear hack
- */
-static void remove_iclear_hack(void)
-{
- os_error *e;
-
- if (!iclear_module)
- return;
-
- e = SWI(3, 0, SWI_OS_Module, 11, iclear_module + 1, *iclear_module);
- if (e)
- debug("Failed to reinstall IClear: %s", e->errmess);
-
- free(iclear_module);
- iclear_module = NULL;
-}
-
-
-
-/*--------------------------------------------------------------------------*/
-
-/* Alarm functions */
-static int alarm_ackd = 0; /* has the alarm been acknowledged? */
-static window_handle aw = 0; /* alarm window */
-
-/*
- | Is the alarm due to go off, ie. is it enabled, and if so
- | does the current time match the alarm time?
- */
-static void check_alarm()
-{
- time_t t;
- struct tm *lt;
-
- alarm_lastcheck = Time_Monotonic();
-
- time(&t);
- lt = localtime(&t);
- if (lt->tm_hour == alarm_h && lt->tm_min == alarm_m)
- {
- if (!alarm_ackd) alarm_disp = 1;
- }
- else
- {
- alarm_ackd = 0;
- }
-
- /* Hack: if the alarm has already been acknowledged then don't re-trigger it */
- if (alarm_ackd)
- {
- alarm_disp = 0;
- }
-
- /* Hack: if the alarm should make a noise, then make one: */
- if (alarm_disp && alarm_beep == 1)
- {
- static unsigned int last_beep = 0;
- unsigned int t = Time_Monotonic();
- if (t >= last_beep + 100)
- {
- Sound_SysBeep();
- last_beep = t;
- }
- }
-
- /*
- | If we're in the desktop then fire the alarm off if need be.
- | If we aren't then do nothing - the fullscreen bored() function
- | will take care of the alarm.
- */
-#ifndef FULLSCREEN_ONLY
- if (!fullscreen_font && alarm_disp)
- trigger_alarm_desktop();
-#endif /* FULLSCREEN_ONLY */
-}
-
-
-static void ack_alarm(void)
-{
- if (aw)
- {
- Window_Delete(aw);
- aw = 0;
- }
- alarm_ackd = 1;
- alarm_disp = 0;
-
- if (alarm_type == 3)
- {
- /* One shot alarm */
- alarm_type = 0;
- write_alarm_choices();
- }
-
-}
-
-#ifndef FULLSCREEN_ONLY
-/*
- | Click in the (desktop) alarm window
- */
-static BOOL Hnd_AlarmClick(event_pollblock * pb, void *ref)
-{
- ack_alarm();
- return TRUE;
-}
-
-
-/*
- | The alarm has gone off in the desktop
- */
-static void trigger_alarm_desktop(void)
-{
- char buffer[120];
- if (aw)
- return;
-
- aw = Window_Create("alarm", template_TITLEMIN);
- if (!aw)
- {
- core("failed to create Alarm window!");
- }
- sprintf(buffer, "Alarm from %s", VARIANT);
- Window_SetTitle(aw, buffer);
- Event_Claim(event_CLICK, aw, 0, Hnd_AlarmClick, NULL);
- Event_Claim(event_CLOSE, aw, event_ANY, Hnd_AlarmClick, NULL);
-
- Icon_printf(aw, 1, "An alarm was set for %02d:%02d", alarm_h, alarm_m);
- Icon_SetText(aw, 2, alarm_message);
- Window_Show(aw, open_CENTERED);
-}
-
-#endif /* FULLSCREEN_ONLY */
-
-
-/*--------------------------------------------------------------------------*/
-
-#ifndef FE_DEBUG_INFO
-static void show_debug_info(void)
-{
- core("main-acn internal logic error 004");
-}
-#else
-
-static int debug_cx = 0;
-static int debug_cy = 0;
-static int debug_cl = TERM_WHITE;
-static int debug_sl = 0;
-
-
-static void debug_cls(void)
-{
- Term_clear();
- debug_cx = debug_cy = debug_sl = 0;
-}
-
-static void debug_tcol(int c)
-{
- debug_cl = c;
-}
-
-
-static void debug_scroll(void)
-{
- char **c = ((term_data *)Term)->t.scr->c; /* char array [24][80] */
- byte **a = ((term_data *)Term)->t.scr->a; /* attr array [24][80] */
- int cc;
- char tmp[82];
- int y, x, p;
-
- cc = a[1][0];
-
- for (y = 1; y < 23; y++)
- {
- for (x = p = 0; x < 80; x++)
- {
- if (a[y][x] != cc)
- {
- tmp[p] = 0;
- Term_putstr(x - p, y - 1, p, cc, tmp);
- p = 0;
- cc = a[y][x];
- }
- tmp[p++] = c[y][x];
- }
- Term_putstr(x - p, y - 1, p, cc, tmp);
- }
-
- Term_erase(0, 22, 80);
-}
-
-
-static void debug_print_line(char *l)
-{
- char *le;
- int cr = 0;
-
- /* Handle scrolling */
- if (debug_cy > 22)
- {
- debug_cy = 22;
- if (--debug_sl < 0)
- {
- int k;
- display_line(0, 23, TERM_YELLOW, "[RET one line, SPC one page]");
- do
- {
- k = inkey();
- }
- while (k != 32 && k != 13);
- Term_erase(0, 23, 79);
- debug_sl = k == 32 ? 21 : 0;
- }
- debug_scroll();
- }
-
- /* Hack: check for NL */
- for (le = l; *le; le++)
- if (*le == '\n')
- {
- cr = 1;
- break;
- }
-
- /* display text */
- Term_putstr(debug_cx, debug_cy, le - l, debug_cl, l);
-
- /* move cursor */
- if (!cr)
- {
- debug_cx += (le - l);
- if (debug_cx >= 80)
- {
- cr = 1;
- }
- }
- if (cr)
- {
- debug_cx = 0;
- debug_cy += 1;
- }
-
- Term_gotoxy(debug_cx, debug_cy);
-
-}
-
-
-static int debug_next_line(char *lb, char **t, int cx)
-{
- int i = 0;
- char *lt = *t;
-
- if (!*lt)
- {
- return -1;
- } /* Out of text */
-
- while (*lt && cx < 80)
- {
- lb[i] = *lt++;
-
- if (lb[i] == '\n') /* New line */
- {
- cx = 0; /* Cursor x will be 0 after displaying */
- i++; /* Keep the \n in the output */
- break; /* All done */
- }
- else if (lb[i] == '\t') /* Tab */
- {
- while (cx < 80)
- {
- lb[i++] = ' ';
- cx++;
- if ((cx & 7) == 0)
- {
- break;
- }
- }
- }
- else /* Anything else */
- {
- cx++;
- i++;
- }
- }
-
- lb[i] = 0; /* terminate line buffer */
- *t = lt; /* update text pointer */
- return cx; /* return cursor x after printing */
-}
-
-static void debug_printf(char *fmt, ...)
-{
- char buffer[1024];
- char line[82];
- va_list ap;
- char *p = buffer;
-
- va_start(ap, fmt);
- vsprintf(buffer, fmt, ap);
- va_end(ap);
-
- /* Now split the string into display lines */
- while (debug_next_line(line, &p, debug_cx) >= 0)
- debug_print_line(line);
-}
-
-
-static void debug_version_info(void)
-{
- debug_tcol(TERM_YELLOW);
-
- debug_printf("\n\nMisc. Info:\n");
- debug_tcol(TERM_WHITE);
- debug_printf("\tVariant name = \"%s\"\n", VARIANT);
- debug_printf("\tFront-end version: %s\n", PORTVERSION);
- debug_printf("\tFront-end compiled: %s %s\n", __TIME__, __DATE__);
- debug_printf("\tCompile time flags:\n");
-
-#ifdef USE_FILECACHE
- debug_printf("\t\tUSE_FILECACHE\n");
-#endif
-
-#ifdef ABBR_FILECACHE
- debug_printf("\t\tABBR_FILECACHE\n");
-#endif
-
-#ifdef SMART_FILECACHE
- debug_printf("\t\tSMART_FILECACHE\n");
-#endif
-
- debug_tcol(TERM_YELLOW);
- debug_printf("\nResource path:\n");
- debug_tcol(TERM_WHITE);
- debug_printf("\t\"%s\"\n", resource_path);
-
- debug_tcol(TERM_YELLOW);
- debug_printf("\nTempfile path:\n");
- debug_tcol(TERM_WHITE);
- debug_printf("\t\"%s\"\n", scrap_path);
- debug_printf("\tScrapfiles are %s deleted at exit.\n",
- (flush_scrap ? "" : "NOT"));
-
- debug_tcol(TERM_YELLOW);
- debug_printf("\nChoices files:\n");
- debug_tcol(TERM_L_BLUE);
- debug_printf("\tDesired files:\n");
- debug_tcol(TERM_WHITE);
- debug_printf("\tPrimary (r/w): \"%s\"\n", choices_file[CHFILE_WRITE]);
- debug_printf("\t Fallback (r): \"%s\"\n", choices_file[CHFILE_READ]);
- debug_printf("\t Mirror (r/w): \"%s\"\n", choices_file[CHFILE_MIRROR]);
- debug_tcol(TERM_L_BLUE);
- debug_printf("\tActual files:\n");
- debug_tcol(TERM_WHITE);
- debug_printf("\t Write: \"%s\"\n", find_choices(TRUE));
- debug_printf("\t Read: \"%s\"\n", find_choices(FALSE));
-
- debug_tcol(TERM_YELLOW);
- debug_printf("\nAlarm files:\n");
- debug_tcol(TERM_L_BLUE);
- debug_printf("\tDesired files:\n");
- debug_tcol(TERM_WHITE);
- debug_printf("\tPrimary (r/w): \"%s\"\n", alarm_file[CHFILE_WRITE]);
- debug_printf("\t Fallback (r): \"%s\"\n", alarm_file[CHFILE_READ]);
- debug_tcol(TERM_L_BLUE);
- debug_printf("\tActual files:\n");
- debug_tcol(TERM_WHITE);
- debug_printf("\t Write: \"%s\"\n", find_alarmfile(TRUE));
- debug_printf("\t Read: \"%s\"\n", find_alarmfile(FALSE));
-#ifdef USE_DA
- debug_tcol(TERM_YELLOW);
- debug_printf("\nDynamic areas:\n");
- debug_tcol(TERM_WHITE);
- debug_printf("\tFontcache DA = %d\t", font_area);
- debug_printf("size = %d\theap size = %d\n", font_area_size, font_heap_size);
- debug_printf("\t ralloc DA = %d\t", game_area);
- debug_printf("size = %d\theap size = %d\n", game_area_size, game_heap_size);
-#endif
-}
-
-
-static void debug_filecache_info(void)
-{
-#ifndef USE_FILECACHE
- debug_tcol(TERM_L_DARK);
- debug_printf("File cache disabled at compile time.\n");
-#else
- int j, k;
- int t, cs, ucs, cf;
-
- cf = cs = ucs = j = k = 0; /* To stop an usused warning if USE_FILECACHE is undefined */
- t = strlen(resource_path);
-
- if (!file_cache_initd)
- {
- init_file_cache();
- } /* Paranoia */
- debug_tcol(TERM_YELLOW);
- debug_printf("\nFilecache contents:\n");
- debug_tcol(TERM_L_BLUE);
- debug_printf("Flags: Smart=%d; Abbrv=%d; Slave=%d; Enable=%d\n",
- smart_filecache, abbr_filecache, abbr_tmpfile, use_filecache);
- debug_tcol(TERM_SLATE);
- if (smart_filecache || abbr_filecache)
- debug_printf("\t\t%3s %6s/%-6s %6s %6s Path (relative to lib/)\n",
- "Hnd", "Cache", "Disc", "Time", "Status");
- else
- debug_printf("\t\t%3s %6s %6s %6s Path (relative to lib/)\n", "Hnd",
- "Size", "Time", "Status");
-
- for (j = 0; j < MAX_CACHE_ENTRIES; j++)
- {
- FileCacheEntry *fce = &(file_cache[j]);
- if (fce->name)
- {
- cf++;
- debug_tcol(TERM_L_GREEN);
- debug_printf("\t\t%3d ", j);
- debug_tcol(TERM_L_UMBER);
- if (!smart_filecache && !abbr_filecache)
- debug_printf("%6d ", fce->eof - fce->text);
- else
- {
- debug_printf("%6d/", fce->eof - fce->text);
- k = myFile_Size(riscosify_name(fce->name));
- debug_printf("%-6d ", k);
- if (k > 0)
- {
- ucs += k;
- }
- }
- cs += fce->eof - fce->text;
- debug_printf("%6d ", fce->used);
- for (k = 0; k < MAX_OPEN_CACHED_FILES; k++)
- if (cached_file_handle[k].fce == fce)
- break;
- debug_tcol(TERM_RED);
- debug_printf("%-6s ", k < MAX_OPEN_CACHED_FILES ? "Open" : "");
- debug_tcol(TERM_L_UMBER);
- debug_printf("%s\n", fce->name + t);
- }
- }
-
- debug_tcol(TERM_L_BLUE);
- debug_printf("\tTotal:\t%3d ", cf);
- if (ucs)
- debug_printf("%6d/%-6d\n", cs, ucs);
- else
- debug_printf("%6d\n", cs);
- debug_tcol(TERM_BLUE);
-#endif /* USE_FILECACHE */
-}
-
-
-static void show_debug_info(void)
-{
- int k;
- /* blank the term */
- debug_cls();
-
- /* Repeatedly prompt for a command */
- do
- {
- debug_tcol(TERM_VIOLET);
- debug_printf("\nInfo: (V)ersion, (F)ilecache, ESC=exit ");
- do
- {
- k = inkey();
- switch (k)
- {
- case 'v': case 'V': debug_version_info();
- break;
- case 'f': case 'F': debug_filecache_info
- ();
- break;
- case 27: break;
- default: k = 0;
- }
- }
- while (!k);
- }
- while (k != 27);
-
- Term_clear();
-}
-
-#endif /* FE_DEBUG_INFO */
-
-#endif /* __riscos */
-
-