Revive Amiga port for NetHack 3.7

Update the Amiga Intuition window port (AMII/AMIV) for the 3.7
window_procs API. Key changes:

- Update all window function signatures for 3.7
- Add assembly trampolines for AmigaOS register-based callbacks
- Convert all K&R function definitions to C99
- Add cross-compilation build system (cross-pre1/pre2/post.370)
  using bebbo's m68k-amigaos-gcc with -noixemul -std=gnu17 -m68000
- Clipping fixes: viewport centering, simplified ScrollRaster,
  duplicate Ctrl-R suppression, glyph buffer invalidation
- Add menucolor support in menu rendering
- Move native txt2iff.c and xpm2iff.c to outdated/
- Add nethack.cnf and README.amiga
This commit is contained in:
Ingo Paschke
2026-03-23 20:48:06 +01:00
parent 7b89255ea8
commit 2d597cb9fa
27 changed files with 1101 additions and 908 deletions

View File

@@ -48,13 +48,9 @@ typedef long off_t;
#define PATHLEN 130 #define PATHLEN 130
/* data librarian defs */ /* data librarian defs */
#ifndef NOCWD_ASSUMPTIONS
#define DLBFILE "NetHack:nhdat" /* main library */
#define DLBFILE2 "NetHack:nhsdat" /* sound library */
#else
#define DLBFILE "nhdat" /* main library */ #define DLBFILE "nhdat" /* main library */
#define DLBFILE2 "nhsdat" /* sound library */ /* nhsdat sound library not used in 3.7 */
#endif #undef DLBFILE2
#ifndef CROSS_TO_AMIGA #ifndef CROSS_TO_AMIGA
#define FILENAME_CMP stricmp /* case insensitive */ #define FILENAME_CMP stricmp /* case insensitive */

View File

@@ -22,6 +22,7 @@ typedef struct amii_mi {
char gselector; /* Group selector */ char gselector; /* Group selector */
char canselect; /* Can user select this entry. */ char canselect; /* Can user select this entry. */
char attr; /* Attribute for the line. */ char attr; /* Attribute for the line. */
int color; /* Color for the line (from menucolors). */
char *str; /* The text of the item. */ char *str; /* The text of the item. */
} amii_menu_item; } amii_menu_item;

View File

@@ -13,8 +13,11 @@
enum wp_ids { wp_tty = 1, wp_X11, wp_Qt, wp_mswin, wp_curses, enum wp_ids { wp_tty = 1, wp_X11, wp_Qt, wp_mswin, wp_curses,
wp_chainin, wp_chainout, wp_safestartup, wp_shim, wp_chainin, wp_chainout, wp_safestartup, wp_shim,
wp_hup, wp_guistubs, wp_ttystubs, wp_hup, wp_guistubs, wp_ttystubs,
#if defined(AMIGA)
wp_amii, wp_amiv,
#endif
#ifdef OUTDATED_STUFF #ifdef OUTDATED_STUFF
wp_mac, wp_Gem, wp_Gnome, wp_amii, wp_amiv, wp_mac, wp_Gem, wp_Gnome,
#endif #endif
wp_trace // XXX do we need this? should chainin/out get an id? TBD wp_trace // XXX do we need this? should chainin/out get an id? TBD
}; };

View File

@@ -9,7 +9,8 @@
necessarily have to be used by a binary with multiple window-ports */ necessarily have to be used by a binary with multiple window-ports */
#if defined(TTY_GRAPHICS) || defined(X11_GRAPHICS) || defined(GEM_GRAPHICS) \ #if defined(TTY_GRAPHICS) || defined(X11_GRAPHICS) || defined(GEM_GRAPHICS) \
|| defined(DUMPLOG) || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS) || defined(DUMPLOG) || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS) \
|| defined(AMII_GRAPHICS)
#define TEXT_TOMBSTONE #define TEXT_TOMBSTONE
#endif #endif
#if defined(mac) || defined(__BEOS__) #if defined(mac) || defined(__BEOS__)

106
sys/amiga/README.amiga Normal file
View File

@@ -0,0 +1,106 @@
NetHack 3.7 for Amiga
====================
Requirements
------------
- AmigaOS 3.0 or later (Kickstart 39+)
- 6 MB free RAM minimum (8 MB recommended)
- Hard drive with ~5 MB free space
Recommended: RTG graphics card (Picasso96/CyberGraphX) for best
tile rendering. Native AGA/OCS/ECS chipsets are supported.
Installation
------------
Extract NH370AMI.ZIP to a directory and assign it:
assign NetHack: <path>
The directory should contain:
nethack - game binary
nhdat - data library
symbols - symbol set definitions
sysconf - system configuration
nethack.cnf - game options
hack.font - font descriptor
hack/8 - font bitmap (8pt)
tiles/tiles16.iff - 16-color tiles (OCS/ECS)
tiles/tiles32.iff - 32-color tiles (AGA/RTG)
tomb.iff - tombstone image
record - high score file
To play:
cd NetHack:
nethack
Display Modes
-------------
Two display modes are available, selected in nethack.cnf:
Text mode (AMII):
OPTIONS=symset:AmigaFont
Tile mode (AMIV):
OPTIONS=windowtype:amiv
Tile mode auto-selects tiles32.iff (32 colors, 5 bitplanes) when the
screen supports 32+ colors, otherwise tiles16.iff (16 colors, 4 planes).
Configuration
-------------
Edit nethack.cnf for game options. Key settings:
OPTIONS=windowtype:amiv - tile graphics (default)
OPTIONS=symset:AmigaFont - text mode with line-drawing chars
OPTIONS=menucolors - colored inventory items
OPTIONS=time,lit_corridor - show turn count, lit corridors
OPTIONS=boulder:0 - display boulders as '0'
Menu color examples (add after OPTIONS=menucolors):
MENUCOLOR=" blessed "=green
MENUCOLOR=" cursed "=red
MENUCOLOR=" uncursed "=cyan
Building from Source
--------------------
Cross-compilation from Linux using bebbo's m68k-amigaos-gcc toolchain
(https://franke.ms/git/bebbo/amiga-gcc):
# Install toolchain to /opt/amiga
# Clone NetHack 3.7 source
cd NetHack
make fetch-lua
sys/unix/setup.sh sys/unix/hints/linux.370
make CROSS_TO_AMIGA=1 all
make CROSS_TO_AMIGA=1 package
The distribution ZIP is created at targets/amiga/NH370AMI.ZIP.
Toolchain requirements:
- m68k-amigaos-gcc (bebbo's amigaos-cross-toolchain in /opt/amiga)
- -noixemul (libnix) for linking
- -m68000 for maximum compatibility (or -m68020/040/060)
Known Issues
------------
- Native Amiga compilation (SAS/C, DICE) is not supported;
cross-compilation with GCC is required
Credits
-------
Olaf Seibert first ported NetHack 2.3 and 3.0 to the Amiga.
Richard Addison, Andrew Church, Jochen Erwied, Mark Gooderum,
Ken Lorber, Greg Olson, Mike Passaretti, and Gregg Wonderly
polished and extended the 3.0 and 3.1 ports. Andrew Church,
Ken Lorber, and Gregg Wonderly are responsible for the 3.2 port.
Janne Salmijärvi resurrected the Amiga port for 3.3 and
Teemu Suikki joined before 3.4.0.
Updated for NetHack 3.7, cross compile fixes and 32 color tile support by Ingo
Paschke in 2026.

View File

@@ -9,6 +9,7 @@
#include "hack.h" #include "hack.h"
#include "winami.h" #include "winami.h"
#include "windefs.h"
/* Defined in config.h, let's undefine it here (static function below) */ /* Defined in config.h, let's undefine it here (static function below) */
#undef strcmpi #undef strcmpi
@@ -18,11 +19,17 @@
#include <intuition/intuition.h> #include <intuition/intuition.h>
#undef COUNT #undef COUNT
#if defined(__SASC_60) || defined(__GNUC__) #if defined(__SASC_60) || defined(__GNUC__)
#include <proto/exec.h> #include <proto/exec.h>
#include <proto/dos.h> #include <proto/dos.h>
#endif #endif
/* POSIX stubs needed by libnix (-noixemul) */
#ifdef __noixemul__
int getpid(void) { return (int)FindTask(NULL); }
#endif
#ifdef AZTEC_50 #ifdef AZTEC_50
#include <functions.h> #include <functions.h>
#undef strcmpi #undef strcmpi
@@ -34,11 +41,12 @@
#include "NH:sys/amiga/winami.p" #include "NH:sys/amiga/winami.p"
#include "NH:sys/amiga/amidos.p" #include "NH:sys/amiga/amidos.p"
#else #else
#include "winami.p" #include "amiwind.p"
#include "winami.p" #include "winami.p"
#include "amidos.p" #include "amidos.p"
#endif #endif
extern char Initialized; extern char Initialized;
extern struct window_procs amii_procs; extern struct window_procs amii_procs;
struct ami_sysflags sysflags = {0}; struct ami_sysflags sysflags = {0};
@@ -54,13 +62,14 @@ char PATH[PATHLEN] = "NetHack:";
static boolean record_exists(void); static boolean record_exists(void);
void void
flushout() flushout(void)
{ {
(void) fflush(stdout); (void) fflush(stdout);
} }
#ifndef getuid #ifndef getuid
getuid() int
getuid(void)
{ {
return 1; return 1;
} }
@@ -68,26 +77,19 @@ getuid()
#ifndef getlogin #ifndef getlogin
char * char *
getlogin() getlogin(void)
{ {
return ((char *) NULL); return ((char *) NULL);
} }
#endif #endif
#ifndef AZTEC_50 /* abs() provided by libnix/stdlib */
int
abs(x)
int x;
{
return x < 0 ? -x : x;
}
#endif
#ifdef SHELL #ifdef SHELL
int int
dosh() dosh(void)
{ {
int i; int i = 0;
char buf[BUFSZ]; char buf[BUFSZ];
extern struct ExecBase *SysBase; extern struct ExecBase *SysBase;
@@ -121,8 +123,7 @@ dosh()
*/ */
/* TODO: update this for FFS */ /* TODO: update this for FFS */
long long
freediskspace(path) freediskspace(char *path)
char *path;
{ {
#ifdef UNTESTED #ifdef UNTESTED
/* these changes from Patric Mueller <bhaak@gmx.net> for AROS to /* these changes from Patric Mueller <bhaak@gmx.net> for AROS to
@@ -131,9 +132,9 @@ char *path;
*/ */
unsigned long long freeBytes = 0; unsigned long long freeBytes = 0;
#else #else
register long freeBytes = 0; long freeBytes = 0;
#endif #endif
register struct InfoData *infoData; /* Remember... longword aligned */ struct InfoData *infoData; /* Remember... longword aligned */
char fileName[32]; char fileName[32];
/* /*
@@ -145,7 +146,7 @@ char *path;
* so must be on the current device, so "" is enough... * so must be on the current device, so "" is enough...
*/ */
{ {
register char *colon; char *colon;
strncpy(fileName, path, sizeof(fileName) - 1); strncpy(fileName, path, sizeof(fileName) - 1);
fileName[31] = 0; fileName[31] = 0;
@@ -191,12 +192,11 @@ char *path;
} }
long long
filesize(file) filesize(char *file)
char *file;
{ {
register BPTR fileLock; BPTR fileLock;
register struct FileInfoBlock *fileInfoBlock; struct FileInfoBlock *fileInfoBlock;
register long size = 0; long size = 0;
fileInfoBlock = fileInfoBlock =
(struct FileInfoBlock *) alloc(sizeof(struct FileInfoBlock)); (struct FileInfoBlock *) alloc(sizeof(struct FileInfoBlock));
@@ -212,8 +212,8 @@ char *file;
#if 0 #if 0
void void
eraseall(path, files) void
const char *path, *files; eraseall(const char *path, const char *files)
{ {
BPTR dirLock, dirLock2; BPTR dirLock, dirLock2;
struct FileInfoBlock *fibp; struct FileInfoBlock *fibp;
@@ -248,12 +248,11 @@ const char *path, *files;
#if 0 /* Unused */ #if 0 /* Unused */
#define COPYSIZE 4096 #define COPYSIZE 4096
char *CopyFile(from, to) char *CopyFile(const char *from, const char *to)
const char *from, *to;
{ {
register BPTR fromFile, toFile; BPTR fromFile, toFile;
register char *buffer; char *buffer;
register long size; long size;
char *error = NULL; char *error = NULL;
buffer = (char *) alloc(COPYSIZE); buffer = (char *) alloc(COPYSIZE);
@@ -282,7 +281,8 @@ const char *from, *to;
#ifdef MFLOPPY #ifdef MFLOPPY
/* this should be replaced */ /* this should be replaced */
saveDiskPrompt(start) int
saveDiskPrompt(int start)
{ {
char buf[BUFSIZ], *bp; char buf[BUFSIZ], *bp;
BPTR fileLock; BPTR fileLock;
@@ -338,7 +338,7 @@ saveDiskPrompt(start)
/* Return 1 if the record file was found */ /* Return 1 if the record file was found */
static boolean static boolean
record_exists() record_exists(void)
{ {
FILE *file; FILE *file;
@@ -355,7 +355,7 @@ record_exists()
* For Amiga: do nothing, but called from restore.c * For Amiga: do nothing, but called from restore.c
*/ */
void void
gameDiskPrompt() gameDiskPrompt(void)
{ {
} }
#endif #endif
@@ -365,8 +365,7 @@ gameDiskPrompt()
* be room for the /. * be room for the /.
*/ */
void void
append_slash(name) append_slash(char *name)
char *name;
{ {
char *ptr; char *ptr;
@@ -381,8 +380,7 @@ char *name;
} }
void void
getreturn(str) getreturn(const char *str)
const char *str;
{ {
int ch; int ch;
@@ -396,12 +394,11 @@ const char *str;
#define PATHSEP ';' #define PATHSEP ';'
FILE * FILE *
fopenp(name, mode) fopenp(const char *name, const char *mode)
register const char *name, *mode;
{ {
register char *bp, *pp, lastch; char *bp, *pp, lastch = 0;
register FILE *fp; FILE *fp;
register BPTR theLock; BPTR theLock;
char buf[BUFSIZ]; char buf[BUFSIZ];
/* Try the default directory first. Then look along PATH. /* Try the default directory first. Then look along PATH.
@@ -452,7 +449,8 @@ register const char *name, *mode;
static BPTR OrgDirLock = NO_LOCK; static BPTR OrgDirLock = NO_LOCK;
chdir(dir) char *dir; int
chdir(char *dir)
{ {
extern char orgdir[]; extern char orgdir[];
@@ -489,7 +487,7 @@ chdir(dir) char *dir;
*/ */
#undef exit #undef exit
void void
nethack_exit(code) nethack_exit(int code)
{ {
#ifdef CHDIR #ifdef CHDIR
extern char orgdir[]; extern char orgdir[];
@@ -506,10 +504,10 @@ nethack_exit(code)
exit(code); exit(code);
} }
void regularize(s) /* normalize file name - we don't like :'s or /'s */ void
register char *s; regularize(char *s) /* normalize file name - we don't like :'s or /'s */
{ {
register char *lp; char *lp;
while ((lp = strchr(s, ':')) || (lp = strchr(s, '/'))) while ((lp = strchr(s, ':')) || (lp = strchr(s, '/')))
*lp = '_'; *lp = '_';

View File

@@ -43,15 +43,15 @@ static struct RastPort *rp;
#include <proto/diskfont.h> #include <proto/diskfont.h>
#endif #endif
static char *load_list[] = { "tomb.iff", 0 };
static BitMapHeader tomb_bmhd; static BitMapHeader tomb_bmhd;
static struct BitMap *tbmp[1] = { 0 }; static struct BitMap *tombimg = NULL;
static int cols[2] = { 154, 319 }; /* X location of center of columns */ static const int cols_base[2] = { 154, 319 }; /* X location of center of columns */
static int cols[2]; /* cols_base[] + xoff, computed per call */
static int cno = 0; /* current column */ static int cno = 0; /* current column */
#define TEXT_TOP (65 + yoff) #define TEXT_TOP (65 + yoff)
static xoff, yoff; /* image centering */ static int xoff, yoff; /* image centering */
/* terrible kludge */ /* terrible kludge */
/* this is why prototypes should have ONLY types in them! */ /* this is why prototypes should have ONLY types in them! */
@@ -100,19 +100,16 @@ int wh; /* was local in outrip, but needed for SCALE macro */
int cmap_white, cmap_black; int cmap_white, cmap_black;
void void
amii_outrip(tmpwin, how, when) amii_outrip(winid tmpwin, int how, time_t when)
winid tmpwin;
int how;
time_t when;
{ {
int just_return = 0; int just_return = 0;
int done, rtxth; int done, rtxth;
struct IntuiMessage *imsg; struct IntuiMessage *imsg;
int i; int i;
register char *dpx; char *dpx;
char buf[200]; char buf[200];
int line, tw, ww; int line, tw, ww;
char *errstr = NULL;
long year; long year;
if (!WINVERS_AMIV || HackScreen->RastPort.BitMap->Depth < 4) if (!WINVERS_AMIV || HackScreen->RastPort.BitMap->Depth < 4)
@@ -141,9 +138,7 @@ time_t when;
SetFont(rp, HackFont); SetFont(rp, HackFont);
#endif #endif
tomb_bmhd = ReadImageFiles(load_list, tbmp, &errstr); tomb_bmhd = ReadImageFile("tomb.iff", &tombimg);
if (errstr)
goto cleanup;
if (tomb_bmhd.w > ww || tomb_bmhd.h > wh) if (tomb_bmhd.w > ww || tomb_bmhd.h > wh)
goto cleanup; goto cleanup;
@@ -151,12 +146,12 @@ time_t when;
xoff = GENOFF(ww, tomb_bmhd.w); xoff = GENOFF(ww, tomb_bmhd.w);
yoff = GENOFF(wh, tomb_bmhd.h); yoff = GENOFF(wh, tomb_bmhd.h);
for (i = 0; i < SIZE(cols); i++) for (i = 0; i < SIZE(cols); i++)
cols[i] += xoff; cols[i] = cols_base[i] + xoff;
cmap_white = search_cmap(0, 0, 0); cmap_white = search_cmap(0, 0, 0);
cmap_black = search_cmap(15, 15, 15); cmap_black = search_cmap(15, 15, 15);
BltBitMap(*tbmp, 0, 0, rp->BitMap, xoff, yoff, tomb_bmhd.w, tomb_bmhd.h, BltBitMap(tombimg, 0, 0, rp->BitMap, xoff, yoff, tomb_bmhd.w, tomb_bmhd.h,
0xc0, 0xff, NULL); 0xc0, 0xff, NULL);
/* Put together death description */ /* Put together death description */
@@ -199,7 +194,7 @@ time_t when;
/* Put death type on stone */ /* Put death type on stone */
for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) { for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) {
register int i, i0; int i, i0;
char tmpchar; char tmpchar;
if ((i0 = strlen(dpx)) > STONE_LINE_LEN) { if ((i0 = strlen(dpx)) > STONE_LINE_LEN) {
@@ -280,8 +275,7 @@ cleanup:
} }
LoadRGB4(&HackScreen->ViewPort, sysflags.amii_curmap, amii_numcolors); LoadRGB4(&HackScreen->ViewPort, sysflags.amii_curmap, amii_numcolors);
if (tbmp[0]) FreeImageFile(&tombimg);
FreeImageFiles(load_list, tbmp);
if (just_return) if (just_return)
return; return;
/* fall back to the straight-ASCII version */ /* fall back to the straight-ASCII version */
@@ -289,8 +283,7 @@ cleanup:
} }
static void static void
tomb_text(p) tomb_text(char *p)
char *p;
{ {
char buf[STONE_LINE_LEN * 2]; char buf[STONE_LINE_LEN * 2];
int l; int l;

View File

@@ -1,5 +1,5 @@
/* NetHack 3.6 amistack.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ /* NetHack 3.6 amistack.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */
/* Copyright (c) Janne Salmijärvi, Tampere, Finland, 2000 */ /* Copyright (c) Janne Salmij<EFBFBD>rvi, Tampere, Finland, 2000 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* /*
@@ -12,10 +12,16 @@
#ifdef __SASC_60 #ifdef __SASC_60
#include <dos.h> #include <dos.h>
#endif
/* /*
* At the moment 90*1024 would suffice, but just to be on the safe side ... * Increase stack size to allow deep recursions.
* NetHack 3.7 with Lua needs significantly more stack than 3.6.
*/ */
long __stack = 128 * 1024; #ifdef __SASC_60
long __stack = 256 * 1024;
#else
/* For GCC with -noixemul (libnix), __stack is also recognized */
unsigned long __stack = 256 * 1024;
#endif #endif

View File

@@ -23,12 +23,12 @@
void tty_change_color(void); void tty_change_color(void);
char *tty_get_color_string(void); char *tty_get_color_string(void);
#ifdef TTY_GRAPHICS
int amibbs = 0; /* BBS mode */ int amibbs = 0; /* BBS mode */
char bbs_id[80] = ""; /* BBS uid equivalent */ char bbs_id[80] = ""; /* BBS uid equivalent */
long afh_in, afh_out; /* BBS mode Amiga filehandles */ long afh_in, afh_out; /* BBS mode Amiga filehandles */
#ifdef TTY_GRAPHICS
void void
settty(const char *s) settty(const char *s)
{ {
@@ -58,9 +58,10 @@ setftty()
} }
char kill_char = 'X' - '@'; char kill_char = 'X' - '@';
char erase_char = '\b'; char erase_char = '\b';
tgetch() int
tgetch(void)
{ {
char x; unsigned char x;
Read(afh_in, &x, 1); Read(afh_in, &x, 1);
return (x == '\r') ? '\n' : x; return (x == '\r') ? '\n' : x;
} }

View File

@@ -23,18 +23,20 @@ static struct Message *GetFMsg(struct MsgPort *);
#endif #endif
static int BufferGetchar(void); static int BufferGetchar(void);
static void ProcessMessage(register struct IntuiMessage *message); static void ProcessMessage(struct IntuiMessage *message);
#define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch)) #define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch))
#ifndef CROSS_TO_AMIGA
struct Library *ConsoleDevice; struct Device *ConsoleDevice = NULL;
#else
struct Device * /* Library bases - opened by amii_init_nhwindows, closed by amii_cleanup.
# ifdef __CONSTLIBBASEDECL__ DOSBase is provided by newlib's startup code.
__CONSTLIBBASEDECL__ The rest must be defined here. */
# endif /* __CONSTLIBBASEDECL__ */ struct IntuitionBase *IntuitionBase = NULL;
ConsoleDevice; struct GfxBase *GfxBase = NULL;
#endif struct Library *GadToolsBase = NULL;
struct Library *LayersBase = NULL;
struct Library *AslBase = NULL;
#ifndef CROSS_TO_AMIGA #ifndef CROSS_TO_AMIGA
#include "NH:sys/amiga/amimenu.c" #include "NH:sys/amiga/amimenu.c"
@@ -44,7 +46,6 @@ struct Device *
/* Now our own variables */ /* Now our own variables */
struct IntuitionBase *IntuitionBase;
struct Screen *HackScreen; struct Screen *HackScreen;
struct Window *pr_WindowPtr; struct Window *pr_WindowPtr;
struct MsgPort *HackPort; struct MsgPort *HackPort;
@@ -55,7 +56,6 @@ char Initialized = 0;
WEVENT lastevent; WEVENT lastevent;
#ifdef HACKFONT #ifdef HACKFONT
struct GfxBase *GfxBase;
struct Library *DiskfontBase; struct Library *DiskfontBase;
#endif #endif
@@ -100,11 +100,10 @@ static enum { NoAction, CloseOver } delayed_key_action = NoAction;
*/ */
struct Window * struct Window *
OpenShWindow(nw) OpenShWindow(struct NewWindow *nw)
struct NewWindow *nw;
{ {
register struct Window *win; struct Window *win;
register ULONG idcmpflags; ULONG idcmpflags;
if (!HackPort) /* Sanity check */ if (!HackPort) /* Sanity check */
return (struct Window *) 0; return (struct Window *) 0;
@@ -126,12 +125,10 @@ struct NewWindow *nw;
* Close a window that shared the HackPort IDCMP port. * Close a window that shared the HackPort IDCMP port.
*/ */
void CloseShWindow(struct Window *);
void void
CloseShWindow(win) CloseShWindow(struct Window *win)
struct Window *win;
{ {
register struct IntuiMessage *msg; struct IntuiMessage *msg;
if (!HackPort) if (!HackPort)
panic("HackPort NULL in CloseShWindow"); panic("HackPort NULL in CloseShWindow");
@@ -152,9 +149,9 @@ struct Window *win;
} }
static int static int
BufferGetchar() BufferGetchar(void)
{ {
register int c; int c;
if (KbdBuffered > 0) { if (KbdBuffered > 0) {
c = KbdBuffer[0]; c = KbdBuffer[0];
@@ -180,8 +177,7 @@ BufferGetchar()
*/ */
int int
ConvertKey(message) ConvertKey(struct IntuiMessage *message)
register struct IntuiMessage *message;
{ {
static struct InputEvent theEvent; static struct InputEvent theEvent;
static char numpad[] = "bjnh.lyku"; static char numpad[] = "bjnh.lyku";
@@ -190,8 +186,8 @@ register struct IntuiMessage *message;
unsigned char buffer[10]; unsigned char buffer[10];
struct Window *w = message->IDCMPWindow; struct Window *w = message->IDCMPWindow;
register int length; int length;
register ULONG qualifier; ULONG qualifier;
char numeric_pad, shift, control, alt; char numeric_pad, shift, control, alt;
if (amii_wins[WIN_MAP]) if (amii_wins[WIN_MAP])
@@ -355,10 +351,7 @@ register struct IntuiMessage *message;
return (-1); return (-1);
} }
} }
printf("Unrecognized key: %d ", (int) buffer[0]); /* unrecognized key — silently ignore */
for (i = 1; i < length; ++i)
printf("%d ", (int) buffer[i]);
printf("\n");
} }
return (-1); return (-1);
} }
@@ -373,8 +366,7 @@ register struct IntuiMessage *message;
*/ */
static void static void
ProcessMessage(message) ProcessMessage(struct IntuiMessage *message)
register struct IntuiMessage *message;
{ {
int c; int c;
int cnt; int cnt;
@@ -385,15 +377,7 @@ register struct IntuiMessage *message;
switch (message->Class) { switch (message->Class) {
case ACTIVEWINDOW: case ACTIVEWINDOW:
if (alwaysinvent && WIN_INVEN != WIN_ERR skip_mouse = 1;
&& w == amii_wins[WIN_INVEN]->win) {
cnt = DoMenuScroll(WIN_INVEN, 0, PICK_NONE, &mip);
} else if (scrollmsg && WIN_MESSAGE != WIN_ERR
&& w == amii_wins[WIN_MESSAGE]->win) {
cnt = DoMenuScroll(WIN_MESSAGE, 0, PICK_NONE, &mip);
} else {
skip_mouse = 1;
}
break; break;
case MOUSEBUTTONS: { case MOUSEBUTTONS: {
@@ -429,12 +413,8 @@ register struct IntuiMessage *message;
} }
} break; } break;
case REFRESHWINDOW: { case REFRESHWINDOW:
if (scrollmsg && amii_wins[WIN_MESSAGE] break;
&& w == amii_wins[WIN_MESSAGE]->win) {
cnt = DoMenuScroll(WIN_MESSAGE, 0, PICK_NONE, &mip);
}
} break;
case CLOSEWINDOW: case CLOSEWINDOW:
if (WIN_INVEN != WIN_ERR && w == amii_wins[WIN_INVEN]->win) { if (WIN_INVEN != WIN_ERR && w == amii_wins[WIN_INVEN]->win) {
@@ -458,11 +438,6 @@ register struct IntuiMessage *message;
break; break;
case GADGETDOWN: case GADGETDOWN:
if (WIN_MESSAGE != WIN_ERR && w == amii_wins[WIN_MESSAGE]->win) {
cnt = DoMenuScroll(WIN_MESSAGE, 0, PICK_NONE, &mip);
} else if (WIN_INVEN != WIN_ERR && w == amii_wins[WIN_INVEN]->win) {
cnt = DoMenuScroll(WIN_INVEN, 0, PICK_NONE, &mip);
}
break; break;
case NEWSIZE: case NEWSIZE:
@@ -481,7 +456,17 @@ register struct IntuiMessage *message;
ReDisplayData(WIN_INVEN); ReDisplayData(WIN_INVEN);
} else if (WINVERS_AMIV && (WIN_OVER != WIN_ERR } else if (WINVERS_AMIV && (WIN_OVER != WIN_ERR
&& w == amii_wins[WIN_OVER]->win)) { && w == amii_wins[WIN_OVER]->win)) {
BufferQueueChar('R' - 64); {
int i, have_redraw = 0;
for (i = 0; i < KbdBuffered; i++) {
if (KbdBuffer[i] == 'R' - 64) {
have_redraw = 1;
break;
}
}
if (!have_redraw)
BufferQueueChar('R' - 64);
}
} else if (WIN_MAP != WIN_ERR && w == amii_wins[WIN_MAP]->win) { } else if (WIN_MAP != WIN_ERR && w == amii_wins[WIN_MAP]->win) {
#ifdef CLIPPING #ifdef CLIPPING
CO = (w->Width - w->BorderLeft - w->BorderRight) / mxsize; CO = (w->Width - w->BorderLeft - w->BorderRight) / mxsize;
@@ -494,7 +479,17 @@ register struct IntuiMessage *message;
clipping = FALSE; clipping = FALSE;
clipx = clipy = 0; clipx = clipy = 0;
} }
BufferQueueChar('R' - 64); {
int i, have_redraw = 0;
for (i = 0; i < KbdBuffered; i++) {
if (KbdBuffer[i] == 'R' - 64) {
have_redraw = 1;
break;
}
}
if (!have_redraw)
BufferQueueChar('R' - 64);
}
#endif #endif
} }
break; break;
@@ -506,8 +501,9 @@ register struct IntuiMessage *message;
amii_destroy_nhwindow(WIN_OVER); amii_destroy_nhwindow(WIN_OVER);
WIN_OVER = WIN_ERR; WIN_OVER = WIN_ERR;
delayed_key_action = NoAction; delayed_key_action = NoAction;
break;
case NoAction: case NoAction:
; /* null */ break;
} }
} }
@@ -522,13 +518,13 @@ register struct IntuiMessage *message;
#if defined(TTY_GRAPHICS) && !defined(AMII_GRAPHICS) #if defined(TTY_GRAPHICS) && !defined(AMII_GRAPHICS)
int int
kbhit() kbhit(void)
{ {
return 0; return 0;
} }
#else #else
int int
kbhit() kbhit(void)
{ {
int c; int c;
#ifdef TTY_GRAPHICS #ifdef TTY_GRAPHICS
@@ -547,9 +543,9 @@ kbhit()
#ifdef AMII_GRAPHICS #ifdef AMII_GRAPHICS
int int
amikbhit() amikbhit(void)
{ {
register struct IntuiMessage *message; struct IntuiMessage *message;
while (KbdBuffered < KBDBUFFER / 2) { while (KbdBuffered < KBDBUFFER / 2) {
#ifdef AMIFLUSH #ifdef AMIFLUSH
message = (struct IntuiMessage *) GetFMsg(HackPort); message = (struct IntuiMessage *) GetFMsg(HackPort);
@@ -572,7 +568,7 @@ amikbhit()
*/ */
int int
WindowGetchar() WindowGetchar(void)
{ {
while ((lastevent.type = WEUNK), amikbhit() <= 0) { while ((lastevent.type = WEUNK), amikbhit() <= 0) {
WaitPort(HackPort); WaitPort(HackPort);
@@ -581,7 +577,7 @@ WindowGetchar()
} }
WETYPE WETYPE
WindowGetevent() WindowGetevent(void)
{ {
lastevent.type = WEUNK; lastevent.type = WEUNK;
while (amikbhit() == 0) { while (amikbhit() == 0) {
@@ -601,9 +597,9 @@ WindowGetevent()
*/ */
void void
amii_cleanup() amii_cleanup(void)
{ {
register struct IntuiMessage *msg; struct IntuiMessage *msg;
/* Close things up */ /* Close things up */
if (HackPort) { if (HackPort) {
@@ -713,8 +709,7 @@ amii_cleanup()
#ifndef SHAREDLIB #ifndef SHAREDLIB
void void
Abort(rc) Abort(long rc)
long rc;
{ {
int fault = 1; int fault = 1;
#ifdef CHDIR #ifdef CHDIR
@@ -765,7 +760,7 @@ long rc;
} }
void void
CleanUp() CleanUp(void)
{ {
amii_cleanup(); amii_cleanup();
} }
@@ -776,8 +771,7 @@ CleanUp()
#ifdef AMIFLUSH #ifdef AMIFLUSH
/* This routine adapted from AmigaMail IV-37 by Michael Sinz */ /* This routine adapted from AmigaMail IV-37 by Michael Sinz */
static struct Message * static struct Message *
GetFMsg(port) GetFMsg(struct MsgPort *port)
struct MsgPort *port;
{ {
struct IntuiMessage *msg, *succ, *succ1; struct IntuiMessage *msg, *succ, *succ1;
@@ -803,8 +797,7 @@ struct MsgPort *port;
#endif #endif
struct NewWindow * struct NewWindow *
DupNewWindow(win) DupNewWindow(struct NewWindow *win)
struct NewWindow *win;
{ {
struct NewWindow *nwin; struct NewWindow *nwin;
struct Gadget *ngd, *gd, *pgd = NULL; struct Gadget *ngd, *gd, *pgd = NULL;
@@ -845,11 +838,10 @@ struct NewWindow *win;
} }
void void
FreeNewWindow(win) FreeNewWindow(struct NewWindow *win)
struct NewWindow *win;
{ {
register struct Gadget *gd, *pgd; struct Gadget *gd, *pgd;
register struct StringInfo *sip; struct StringInfo *sip;
for (gd = win->FirstGadget; gd; gd = pgd) { for (gd = win->FirstGadget; gd; gd = pgd) {
pgd = gd->NextGadget; pgd = gd->NextGadget;
@@ -868,7 +860,7 @@ struct NewWindow *win;
} }
void void
bell() bell(void)
{ {
if (flags.silent) if (flags.silent)
return; return;
@@ -876,15 +868,14 @@ bell()
} }
void void
amii_delay_output() amii_delay_output(void)
{ {
/* delay 50 ms */ /* delay 50 ms */
Delay(2L); Delay(2L);
} }
void void
amii_number_pad(state) amii_number_pad(int state)
int state;
{ {
} }
#endif /* AMII_GRAPHICS */ #endif /* AMII_GRAPHICS */

44
sys/amiga/nethack.cnf Normal file
View File

@@ -0,0 +1,44 @@
# NetHack 3.7 Amiga Configuration
#
# For a full list of options, see the opthelp file or press '?'
# then 'o' during gameplay.
# *** DISPLAY MODE ***
#
# Tile mode (graphical tiles, recommended):
OPTIONS=windowtype:amiv
#
# Text mode (uses hack.font line-drawing characters):
#OPTIONS=windowtype:amii
#OPTIONS=symset:AmigaFont
# *** GENERAL OPTIONS ***
OPTIONS=time,showexp,lit_corridor
OPTIONS=boulder:0
OPTIONS=autopickup,pickup_types:$"=/!?+
OPTIONS=catname:Kaori
# *** MENU COLORS ***
# Colour-code inventory items by BUC status and value.
OPTIONS=menucolors
MENUCOLOR=" blessed "=green
MENUCOLOR=" holy "=green
MENUCOLOR=" uncursed "=cyan
MENUCOLOR=" cursed "=red
MENUCOLOR=" unholy "=red
MENUCOLOR=" cursed .* (being worn)"=red&underline
MENUCOLOR=" cursed .* (wielded)"=red&underline
MENUCOLOR="loadstone"=red&underline
MENUCOLOR="gold piece"=brown
MENUCOLOR="worthless"=brown
MENUCOLOR="wand of wishing"=magenta
MENUCOLOR="magic lamp"=magenta
MENUCOLOR="magic marker"=magenta
MENUCOLOR="bag of holding"=magenta
MENUCOLOR="amulet of life saving"=magenta
MENUCOLOR="cloak of magic resistance"=magenta
MENUCOLOR="silver dragon scale"=cyan
MENUCOLOR="gray dragon scale"=cyan
MENUCOLOR="speed boots"=magenta
MENUCOLOR="luckstone"=green
MENUCOLOR="unicorn horn"=green

View File

@@ -15,14 +15,12 @@
/* Start building the text for a menu */ /* Start building the text for a menu */
void void
amii_start_menu(window, mbehavior) amii_start_menu(winid window, unsigned long mbehavior UNUSED)
register winid window;
unsigned long mbehavior UNUSED;
{ {
register int i; int i;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register amii_menu_item *mip; amii_menu_item *mip;
if (window == WIN_ERR || (cw = amii_wins[window]) == NULL if (window == WIN_ERR || (cw = amii_wins[window]) == NULL
|| cw->type != NHW_MENU) || cw->type != NHW_MENU)
@@ -64,17 +62,12 @@ unsigned long mbehavior UNUSED;
/* Add a string to a menu */ /* Add a string to a menu */
void void
amii_add_menu(window, glyph, id, ch, gch, attr, str, itemflags) amii_add_menu(winid window, const glyph_info *glyphinfo, const anything *id,
register winid window; char ch, char gch, int attr, int clr,
register int glyph; const char *str, unsigned int itemflags)
register const anything *id;
register char ch;
register char gch;
register int attr;
register const char *str;
register unsigned int itemflags;
{ {
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
boolean preselected = ((itemflags & MENU_ITEMFLAGS_SELECTED) != 0); boolean preselected = ((itemflags & MENU_ITEMFLAGS_SELECTED) != 0);
amii_menu_item *mip; amii_menu_item *mip;
char buf[4 + BUFSZ]; char buf[4 + BUFSZ];
@@ -90,7 +83,8 @@ register unsigned int itemflags;
mip->identifier = *id; mip->identifier = *id;
mip->selected = preselected; mip->selected = preselected;
mip->attr = attr; mip->attr = attr;
mip->glyph = Is_rogue_level(&u.uz) ? NO_GLYPH : glyph; mip->color = clr;
mip->glyph = Is_rogue_level(&u.uz) ? NO_GLYPH : (glyphinfo ? glyphinfo->glyph : NO_GLYPH);
mip->selector = 0; mip->selector = 0;
mip->gselector = gch; mip->gselector = gch;
mip->count = -1; mip->count = -1;
@@ -131,11 +125,10 @@ register unsigned int itemflags;
/* Done building a menu. */ /* Done building a menu. */
void void
amii_end_menu(window, morestr) amii_end_menu(winid window, const char *morestr)
register winid window;
register const char *morestr;
{ {
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
if (window == WIN_ERR || (cw = amii_wins[window]) == NULL if (window == WIN_ERR || (cw = amii_wins[window]) == NULL
|| cw->type != NHW_MENU) || cw->type != NHW_MENU)
@@ -151,8 +144,8 @@ register const char *morestr;
mip = cw->menu.last; mip = cw->menu.last;
#endif #endif
any.a_void = 0; any.a_void = 0;
amii_add_menu(window, NO_GLYPH, &any, 0, 0, ATR_NONE, morestr, amii_add_menu(window, (const glyph_info *) 0, &any, 0, 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, morestr, MENU_ITEMFLAGS_NONE);
#ifdef PROMPTFIRST /* Do some shuffling. Last first, push others one forward \ #ifdef PROMPTFIRST /* Do some shuffling. Last first, push others one forward \
*/ */
mip->next = NULL; mip->next = NULL;
@@ -178,13 +171,11 @@ register const char *morestr;
/* Select something from the menu. */ /* Select something from the menu. */
int int
amii_select_menu(window, how, mip) amii_select_menu(winid window, int how, menu_item **mip)
register winid window;
register int how;
register menu_item **mip;
{ {
int cnt; int cnt;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
if (window == WIN_ERR || (cw = amii_wins[window]) == NULL if (window == WIN_ERR || (cw = amii_wins[window]) == NULL
|| cw->type != NHW_MENU) || cw->type != NHW_MENU)
@@ -199,7 +190,7 @@ register menu_item **mip;
} }
amii_menu_item * amii_menu_item *
find_menu_item(register struct amii_WinDesc *cw, int idx) find_menu_item(struct amii_WinDesc *cw, int idx)
{ {
amii_menu_item *mip; amii_menu_item *mip;
for (mip = cw->menu.items; idx > 0 && mip; mip = mip->next) for (mip = cw->menu.items; idx > 0 && mip; mip = mip->next)
@@ -209,11 +200,11 @@ find_menu_item(register struct amii_WinDesc *cw, int idx)
} }
int int
make_menu_items(register struct amii_WinDesc *cw, register menu_item **rmip) make_menu_items(struct amii_WinDesc *cw, menu_item **rmip)
{ {
register int idx = 0; int idx = 0;
register amii_menu_item *mip; amii_menu_item *mip;
register menu_item *mmip; menu_item *mmip;
for (mip = cw->menu.items; mip; mip = mip->next) { for (mip = cw->menu.items; mip; mip = mip->next) {
if (mip->selected) if (mip->selected)
@@ -236,19 +227,17 @@ make_menu_items(register struct amii_WinDesc *cw, register menu_item **rmip)
} }
int int
DoMenuScroll(win, blocking, how, retmip) DoMenuScroll(int win, int blocking, int how, menu_item **retmip)
int win, blocking, how;
menu_item **retmip;
{ {
amii_menu_item *amip; amii_menu_item *amip;
register struct Window *w; struct Window *w;
register struct NewWindow *nw; struct NewWindow *nw;
struct PropInfo *pip; struct PropInfo *pip;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
struct IntuiMessage *imsg; struct IntuiMessage *imsg;
struct Gadget *gd; struct Gadget *gd;
register int wheight, xsize, ysize, aredone = 0; int wheight, xsize, ysize, aredone = 0;
register int txwd, txh; int txwd, txh;
long mics, secs, class, code; long mics, secs, class, code;
long oldmics = 0, oldsecs = 0; long oldmics = 0, oldsecs = 0;
int aidx, oidx, topidx, hidden; int aidx, oidx, topidx, hidden;
@@ -819,7 +808,7 @@ menu_item **retmip;
++topidx; ++topidx;
else else
break; break;
} else if (code = CTRL('U') } else if (code == CTRL('U')
|| code == MENU_PREVIOUS_PAGE) { || code == MENU_PREVIOUS_PAGE) {
if (topidx > 0) if (topidx > 0)
--topidx; --topidx;
@@ -1007,11 +996,13 @@ menu_item **retmip;
oldmics = mics; oldmics = mics;
} else { } else {
amip = find_menu_item(cw, oidx); amip = find_menu_item(cw, oidx);
amip->selected = 0; if (amip) {
amip->count = -1; amip->selected = 0;
reset_counting = TRUE; amip->count = -1;
if (amip->canselect && amip->selector) reset_counting = TRUE;
amip->str[SOFF + 2] = '-'; if (amip->canselect && amip->selector)
amip->str[SOFF + 2] = '-';
}
} }
if (counting && amip->selected && amip->canselect if (counting && amip->selected && amip->canselect
&& amip->selector) { && amip->selector) {
@@ -1092,13 +1083,12 @@ menu_item **retmip;
} }
void void
ReDisplayData(win) ReDisplayData(winid win)
winid win;
{ {
int totalvis; int totalvis;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register struct Window *w; struct Window *w;
register struct Gadget *gd; struct Gadget *gd;
unsigned long hidden, aidx, wheight; unsigned long hidden, aidx, wheight;
struct PropInfo *pip; struct PropInfo *pip;
@@ -1123,15 +1113,13 @@ winid win;
} }
long long
FindLine(win, line) FindLine(winid win, int line)
winid win;
int line;
{ {
int txwd; int txwd;
register char *t; char *t;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register struct Window *w; struct Window *w;
register int i, disprow, len; int i, disprow, len;
int col = -1; int col = -1;
if (win == WIN_ERR || !(cw = amii_wins[win]) || !(w = cw->win)) { if (win == WIN_ERR || !(cw = amii_wins[win]) || !(w = cw->win)) {
@@ -1186,15 +1174,14 @@ int line;
} }
long long
CountLines(win) CountLines(winid win)
winid win;
{ {
int txwd; int txwd;
amii_menu_item *mip; amii_menu_item *mip;
register char *t; char *t;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register struct Window *w; struct Window *w;
register int i, disprow, len; int i, disprow, len;
int col = -1; int col = -1;
if (win == WIN_ERR || !(cw = amii_wins[win]) || !(w = cw->win)) { if (win == WIN_ERR || !(cw = amii_wins[win]) || !(w = cw->win)) {
@@ -1250,17 +1237,15 @@ winid win;
} }
void void
DisplayData(win, start) DisplayData(winid win, int start)
winid win;
int start;
{ {
int txwd; int txwd;
amii_menu_item *mip; amii_menu_item *mip;
register char *t; char *t;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register struct Window *w; struct Window *w;
register struct RastPort *rp; struct RastPort *rp;
register int i, disprow, len, wheight; int i, disprow, len, wheight;
int whichcolor = -1; int whichcolor = -1;
int col; int col;
@@ -1363,6 +1348,13 @@ int start;
whichcolor = 2; whichcolor = 2;
} }
/* Apply menucolor if set for this item */
if (mip && mip->color != NO_COLOR && !(mip->selected)) {
extern const int foreg[];
SetAPen(rp, foreg[mip->color]);
whichcolor = 0; /* force re-evaluation next item */
}
/* Next line out, wrap if too long */ /* Next line out, wrap if too long */
t = cw->data[i] + SOFF; t = cw->data[i] + SOFF;
@@ -1427,14 +1419,11 @@ int start;
} }
void void
SetPropInfo(win, gad, vis, total, top) SetPropInfo(struct Window *win, struct Gadget *gad, long vis, long total, long top)
register struct Window *win;
register struct Gadget *gad;
register long vis, total, top;
{ {
long mflags; long mflags;
register long hidden; long hidden;
register int body, pot; int body, pot;
hidden = max(total - vis, 0); hidden = max(total - vis, 0);

View File

@@ -39,7 +39,8 @@ long amii_scrnmode;
* the intuition interface for the amiga... * the intuition interface for the amiga...
*/ */
struct window_procs amii_procs = { struct window_procs amii_procs = {
"amii", WC_COLOR | WC_HILITE_PET | WC_INVERSE, WPID(amii),
WC_COLOR | WC_HILITE_PET | WC_INVERSE,
0L, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
amii_init_nhwindows, amii_init_nhwindows,
@@ -48,7 +49,7 @@ struct window_procs amii_procs = {
amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow,
amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed, amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed,
amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu, amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu,
amii_select_menu, genl_message_menu, amii_update_inventory, amii_select_menu, genl_message_menu,
amii_mark_synch, amii_wait_synch, amii_mark_synch, amii_wait_synch,
#ifdef CLIPPING #ifdef CLIPPING
amii_cliparound, amii_cliparound,
@@ -67,13 +68,16 @@ struct window_procs amii_procs = {
genl_status_init, genl_status_finish, genl_status_enablefield, genl_status_init, genl_status_finish, genl_status_enablefield,
genl_status_update, genl_status_update,
genl_can_suspend_yes, genl_can_suspend_yes,
amii_update_inventory,
amii_ctrl_nhwindow,
}; };
/* The view window layout uses the same function names so we can use /* The view window layout uses the same function names so we can use
* a shared library to allow the executable to be smaller. * a shared library to allow the executable to be smaller.
*/ */
struct window_procs amiv_procs = { struct window_procs amiv_procs = {
"amitile", WC_COLOR | WC_HILITE_PET | WC_INVERSE, WPID(amiv),
WC_COLOR | WC_HILITE_PET | WC_INVERSE,
0L, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
amii_init_nhwindows, amii_init_nhwindows,
@@ -82,7 +86,7 @@ struct window_procs amiv_procs = {
amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow,
amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed, amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed,
amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu, amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu,
amii_select_menu, genl_message_menu, amii_update_inventory, amii_select_menu, genl_message_menu,
amii_mark_synch, amii_wait_synch, amii_mark_synch, amii_wait_synch,
#ifdef CLIPPING #ifdef CLIPPING
amii_cliparound, amii_cliparound,
@@ -101,6 +105,8 @@ struct window_procs amiv_procs = {
genl_status_init, genl_status_finish, genl_status_enablefield, genl_status_init, genl_status_finish, genl_status_enablefield,
genl_status_update, genl_status_update,
genl_can_suspend_yes, genl_can_suspend_yes,
amii_update_inventory,
amii_ctrl_nhwindow,
}; };
unsigned short amii_initmap[AMII_MAXCOLORS]; unsigned short amii_initmap[AMII_MAXCOLORS];
@@ -428,7 +434,7 @@ struct NewScreen NewHackScreen = { 0, 0, WIDTH, SCREENHEIGHT, 3, 0,
* init_sound_disp_gamewindows(). * init_sound_disp_gamewindows().
*/ */
void void
amii_askname() amii_askname(void)
{ {
char plnametmp[300]; /* From winreq.c: sizeof(StrStringSIBuff) */ char plnametmp[300]; /* From winreq.c: sizeof(StrStringSIBuff) */
*plnametmp = 0; *plnametmp = 0;
@@ -454,12 +460,12 @@ amii_askname()
#if 0 /* New function at the bottom */ #if 0 /* New function at the bottom */
void void
amii_player_selection() amii_player_selection(void)
{ {
register struct Window *cwin; struct Window *cwin;
register struct IntuiMessage *imsg; struct IntuiMessage *imsg;
register int aredone = 0; int aredone = 0;
register struct Gadget *gd; struct Gadget *gd;
static int once = 0; static int once = 0;
long class, code; long class, code;
@@ -499,7 +505,7 @@ amii_player_selection()
#ifdef INTUI_NEW_LOOK #ifdef INTUI_NEW_LOOK
Type_NewWindowStructure1.Extension = wintags; Type_NewWindowStructure1.Extension = wintags;
Type_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; Type_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
fillhook.h_Entry = (ULONG(*)())LayerFillHook; fillhook.h_Entry = (void *) &LayerFillHook;
fillhook.h_Data = (void *)-2; fillhook.h_Data = (void *)-2;
fillhook.h_SubEntry = 0; fillhook.h_SubEntry = 0;
#endif #endif
@@ -595,8 +601,7 @@ amii_player_selection()
#include "NH:sys/amiga/randwin.c" #include "NH:sys/amiga/randwin.c"
void void
RandomWindow( name ) RandomWindow(char *name)
char *name;
{ {
struct MsgPort *tport; struct MsgPort *tport;
struct timerequest *trq; struct timerequest *trq;
@@ -672,7 +677,7 @@ allocerr:
#ifdef INTUI_NEW_LOOK #ifdef INTUI_NEW_LOOK
Rnd_NewWindowStructure1.Extension = wintags; Rnd_NewWindowStructure1.Extension = wintags;
Rnd_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; Rnd_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
fillhook.h_Entry = (ULONG(*)())LayerFillHook; fillhook.h_Entry = (void *) &LayerFillHook;
fillhook.h_Data = (void *)-2; fillhook.h_Data = (void *)-2;
fillhook.h_SubEntry = 0; fillhook.h_SubEntry = 0;
#endif #endif
@@ -762,10 +767,11 @@ amii_get_ext_cmd(void)
#endif #endif
int colx; int colx;
int bottom = 0; int bottom = 0;
struct Window *w; struct Window *w;
char obufp[100]; char obufp[100];
register char *bufp = obufp; char *bufp = obufp;
register int c; int c;
int com_index, oindex; int com_index, oindex;
int did_comp = 0; /* did successful completion? */ int did_comp = 0; /* did successful completion? */
int sel = -1; int sel = -1;
@@ -787,7 +793,8 @@ amii_get_ext_cmd(void)
id.a_char = *extcmdlist[i].ef_txt; id.a_char = *extcmdlist[i].ef_txt;
sprintf(buf, "%-10s - %s ", extcmdlist[i].ef_txt, sprintf(buf, "%-10s - %s ", extcmdlist[i].ef_txt,
extcmdlist[i].ef_desc); extcmdlist[i].ef_desc);
amii_add_menu(win, NO_GLYPH, &id, extcmdlist[i].ef_txt[0], 0, 0, amii_add_menu(win, (const glyph_info *) 0, &id,
extcmdlist[i].ef_txt[0], 0, 0, NO_COLOR,
buf, MENU_ITEMFLAGS_NONE); buf, MENU_ITEMFLAGS_NONE);
} }
@@ -848,8 +855,9 @@ amii_get_ext_cmd(void)
id.a_char = extcmdlist[i].ef_txt[0]; id.a_char = extcmdlist[i].ef_txt[0];
sprintf(buf, "%-10s - %s ", extcmdlist[i].ef_txt, sprintf(buf, "%-10s - %s ", extcmdlist[i].ef_txt,
extcmdlist[i].ef_desc); extcmdlist[i].ef_desc);
amii_add_menu(win, NO_GLYPH, &id, extcmdlist[i].ef_txt[0], 0, amii_add_menu(win, (const glyph_info *) 0, &id,
0, buf, MENU_ITEMFLAGS_NONE); extcmdlist[i].ef_txt[0], 0, 0, NO_COLOR,
buf, MENU_ITEMFLAGS_NONE);
} }
amii_end_menu(win, (char *) 0); amii_end_menu(win, (char *) 0);
@@ -941,10 +949,7 @@ amii_get_ext_cmd(void)
} }
static int static int
put_ext_cmd(obufp, colx, cw, bottom) put_ext_cmd(char *obufp, int colx, struct amii_WinDesc *cw, int bottom)
char * obufp;
int colx, bottom;
struct amii_WinDesc *cw;
{ {
struct Window *w = cw->win; struct Window *w = cw->win;
char *t; char *t;
@@ -989,10 +994,9 @@ struct amii_WinDesc *cw;
/* Ask a question and get a response */ /* Ask a question and get a response */
char char
amii_yn_function(query, resp, def) amii_yn_function(const char *query, const char *resp, char def)
const char * query, *resp;
char def;
{ {
/* /*
* Generic yes/no function. 'def' is the default (returned by space or * Generic yes/no function. 'def' is the default (returned by space or
* return; 'esc' returns 'q', or 'n', or the default, depending on * return; 'esc' returns 'q', or 'n', or the default, depending on
@@ -1004,11 +1008,11 @@ char def;
* are allowed); if it includes an <esc>, anything beyond that won't * are allowed); if it includes an <esc>, anything beyond that won't
* be shown in the prompt to the user but will be acceptable as input. * be shown in the prompt to the user but will be acceptable as input.
*/ */
register char q; char q;
char rtmp[40]; char rtmp[40];
boolean digit_ok, allow_num; boolean digit_ok, allow_num;
char prompt[BUFSZ]; char prompt[BUFSZ];
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
if (cw = amii_wins[WIN_MESSAGE]) if (cw = amii_wins[WIN_MESSAGE])
cw->disprows = 0; cw->disprows = 0;
@@ -1138,16 +1142,15 @@ char def;
} }
void void
amii_display_file(fn, complain) amii_display_file(const char *fn, boolean complain)
const char * fn;
boolean complain;
{ {
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register int win; int win;
register dlb *fp; dlb *fp;
register char *t; char *t;
char buf[200]; char buf[200];
if (fn == NULL) if (fn == NULL)
panic("NULL file name in display_file()"); panic("NULL file name in display_file()");
@@ -1194,12 +1197,11 @@ boolean complain;
* are rendered in the up position by default. * are rendered in the up position by default.
*/ */
void void
SetBorder(gd) SetBorder(struct Gadget *gd)
register struct Gadget * gd;
{ {
register struct Border *bp; struct Border *bp;
register short *sp; short *sp;
register int i, inc = -1, dec = -1; int i, inc = -1, dec = -1;
int borders = 6; int borders = 6;
int hipen = sysflags.amii_dripens[SHINEPEN], int hipen = sysflags.amii_dripens[SHINEPEN],
shadowpen = sysflags.amii_dripens[SHADOWPEN]; shadowpen = sysflags.amii_dripens[SHADOWPEN];
@@ -1337,7 +1339,7 @@ register struct Gadget * gd;
/* Following function copied from wintty.c; /* Following function copied from wintty.c;
Modified slightly to fit amiga needs */ Modified slightly to fit amiga needs */
void void
amii_player_selection() amii_player_selection(void)
{ {
int i, k, n; int i, k, n;
char pick4u = 'n', thisch, lastch = 0; char pick4u = 'n', thisch, lastch = 0;
@@ -1346,6 +1348,7 @@ amii_player_selection()
anything any; anything any;
menu_item *selected = 0; menu_item *selected = 0;
rigid_role_checks(); rigid_role_checks();
/* Should we randomly pick for the player? */ /* Should we randomly pick for the player? */
@@ -1424,8 +1427,8 @@ amii_player_selection()
} else } else
Strcpy(rolenamebuf, roles[i].name.m); Strcpy(rolenamebuf, roles[i].name.m);
} }
add_menu(win, NO_GLYPH, &any, thisch, 0, ATR_NONE, add_menu(win, &nul_glyphinfo, &any, thisch, 0, ATR_NONE,
an(rolenamebuf), MENU_ITEMFLAGS_NONE); NO_COLOR, an(rolenamebuf), MENU_ITEMFLAGS_NONE);
lastch = thisch; lastch = thisch;
} }
} }
@@ -1433,11 +1436,11 @@ amii_player_selection()
flags.initalign, PICK_RANDOM) + 1; flags.initalign, PICK_RANDOM) + 1;
if (any.a_int == 0) /* must be non-zero */ if (any.a_int == 0) /* must be non-zero */
any.a_int = randrole(FALSE) + 1; any.a_int = randrole(FALSE) + 1;
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random", add_menu(win, &nul_glyphinfo, &any, '*', 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, "Random", MENU_ITEMFLAGS_NONE);
any.a_int = i + 1; /* must be non-zero */ any.a_int = i + 1; /* must be non-zero */
add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit", add_menu(win, &nul_glyphinfo, &any, 'q', 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, "Quit", MENU_ITEMFLAGS_NONE);
Sprintf(pbuf, "Pick a role for your %s", plbuf); Sprintf(pbuf, "Pick a role for your %s", plbuf);
end_menu(win, pbuf); end_menu(win, pbuf);
n = select_menu(win, PICK_ONE, &selected); n = select_menu(win, PICK_ONE, &selected);
@@ -1498,19 +1501,19 @@ amii_player_selection()
if (ok_race(flags.initrole, i, flags.initgend, if (ok_race(flags.initrole, i, flags.initgend,
flags.initalign)) { flags.initalign)) {
any.a_int = i + 1; /* must be non-zero */ any.a_int = i + 1; /* must be non-zero */
add_menu(win, NO_GLYPH, &any, races[i].noun[0], 0, add_menu(win, &nul_glyphinfo, &any, races[i].noun[0], 0,
ATR_NONE, races[i].noun, ATR_NONE, NO_COLOR, races[i].noun,
MENU_ITEMFLAGS_NONE); MENU_ITEMFLAGS_NONE);
} }
any.a_int = pick_race(flags.initrole, flags.initgend, any.a_int = pick_race(flags.initrole, flags.initgend,
flags.initalign, PICK_RANDOM) + 1; flags.initalign, PICK_RANDOM) + 1;
if (any.a_int == 0) /* must be non-zero */ if (any.a_int == 0) /* must be non-zero */
any.a_int = randrace(flags.initrole) + 1; any.a_int = randrace(flags.initrole) + 1;
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random", add_menu(win, &nul_glyphinfo, &any, '*', 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, "Random", MENU_ITEMFLAGS_NONE);
any.a_int = i + 1; /* must be non-zero */ any.a_int = i + 1; /* must be non-zero */
add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit", add_menu(win, &nul_glyphinfo, &any, 'q', 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, "Quit", MENU_ITEMFLAGS_NONE);
Sprintf(pbuf, "Pick the race of your %s", plbuf); Sprintf(pbuf, "Pick the race of your %s", plbuf);
end_menu(win, pbuf); end_menu(win, pbuf);
n = select_menu(win, PICK_ONE, &selected); n = select_menu(win, PICK_ONE, &selected);
@@ -1571,18 +1574,19 @@ amii_player_selection()
if (ok_gend(flags.initrole, flags.initrace, i, if (ok_gend(flags.initrole, flags.initrace, i,
flags.initalign)) { flags.initalign)) {
any.a_int = i + 1; any.a_int = i + 1;
add_menu(win, NO_GLYPH, &any, genders[i].adj[0], 0, add_menu(win, &nul_glyphinfo, &any, genders[i].adj[0], 0,
ATR_NONE, genders[i].adj, MENU_ITEMFLAGS_NONE); ATR_NONE, NO_COLOR, genders[i].adj,
MENU_ITEMFLAGS_NONE);
} }
any.a_int = pick_gend(flags.initrole, flags.initrace, any.a_int = pick_gend(flags.initrole, flags.initrace,
flags.initalign, PICK_RANDOM) + 1; flags.initalign, PICK_RANDOM) + 1;
if (any.a_int == 0) /* must be non-zero */ if (any.a_int == 0) /* must be non-zero */
any.a_int = randgend(flags.initrole, flags.initrace) + 1; any.a_int = randgend(flags.initrole, flags.initrace) + 1;
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random", add_menu(win, &nul_glyphinfo, &any, '*', 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, "Random", MENU_ITEMFLAGS_NONE);
any.a_int = i + 1; /* must be non-zero */ any.a_int = i + 1; /* must be non-zero */
add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit", add_menu(win, &nul_glyphinfo, &any, 'q', 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, "Quit", MENU_ITEMFLAGS_NONE);
Sprintf(pbuf, "Pick the gender of your %s", plbuf); Sprintf(pbuf, "Pick the gender of your %s", plbuf);
end_menu(win, pbuf); end_menu(win, pbuf);
n = select_menu(win, PICK_ONE, &selected); n = select_menu(win, PICK_ONE, &selected);
@@ -1642,18 +1646,19 @@ amii_player_selection()
if (ok_align(flags.initrole, flags.initrace, if (ok_align(flags.initrole, flags.initrace,
flags.initgend, i)) { flags.initgend, i)) {
any.a_int = i + 1; any.a_int = i + 1;
add_menu(win, NO_GLYPH, &any, aligns[i].adj[0], 0, add_menu(win, &nul_glyphinfo, &any, aligns[i].adj[0], 0,
ATR_NONE, aligns[i].adj, MENU_ITEMFLAGS_NONE); ATR_NONE, NO_COLOR, aligns[i].adj,
MENU_ITEMFLAGS_NONE);
} }
any.a_int = pick_align(flags.initrole, flags.initrace, any.a_int = pick_align(flags.initrole, flags.initrace,
flags.initgend, PICK_RANDOM) + 1; flags.initgend, PICK_RANDOM) + 1;
if (any.a_int == 0) /* must be non-zero */ if (any.a_int == 0) /* must be non-zero */
any.a_int = randalign(flags.initrole, flags.initrace) + 1; any.a_int = randalign(flags.initrole, flags.initrace) + 1;
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random", add_menu(win, &nul_glyphinfo, &any, '*', 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, "Random", MENU_ITEMFLAGS_NONE);
any.a_int = i + 1; /* must be non-zero */ any.a_int = i + 1; /* must be non-zero */
add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "Quit", add_menu(win, &nul_glyphinfo, &any, 'q', 0, ATR_NONE,
MENU_ITEMFLAGS_NONE); NO_COLOR, "Quit", MENU_ITEMFLAGS_NONE);
Sprintf(pbuf, "Pick the alignment of your %s", plbuf); Sprintf(pbuf, "Pick the alignment of your %s", plbuf);
end_menu(win, pbuf); end_menu(win, pbuf);
n = select_menu(win, PICK_ONE, &selected); n = select_menu(win, PICK_ONE, &selected);

View File

@@ -5,10 +5,10 @@
void amii_raw_print(const char *); void amii_raw_print(const char *);
void amii_raw_print_bold(const char *); void amii_raw_print_bold(const char *);
void amii_start_menu(winid , unsigned long ); void amii_start_menu(winid , unsigned long );
void amii_add_menu(winid , char , int , const char *, unsigned int); void amii_add_menu(winid, const glyph_info *, const anything *, char, char, int, int, const char *, unsigned int);
void amii_end_menu(winid , char , const char * , const char *); void amii_end_menu(winid , char , const char * , const char *);
char amii_select_menu(winid ); char amii_select_menu(winid );
void amii_update_inventory (void); void amii_update_inventory(int);
void amii_mark_synch (void); void amii_mark_synch (void);
void amii_wait_synch (void); void amii_wait_synch (void);
void amii_setclipped (void); void amii_setclipped (void);
@@ -27,7 +27,7 @@ void amii_putstr(winid , int , const char *);
void amii_putsym(winid , int , int , CHAR_P ); void amii_putsym(winid , int , int , CHAR_P );
void amii_clear_nhwindow(winid ); void amii_clear_nhwindow(winid );
void amii_exit_nhwindows(const char *); void amii_exit_nhwindows(const char *);
int amii_nh_poskey(int * , int * , int *); int amii_nh_poskey(coordxy *, coordxy *, int *);
int amii_nhgetch (void); int amii_nhgetch (void);
void amii_get_nh_event (void); void amii_get_nh_event (void);
void amii_remember_topl (void); void amii_remember_topl (void);
@@ -35,7 +35,7 @@ int amii_doprev_message (void);
void amii_display_nhwindow(winid , boolean ); void amii_display_nhwindow(winid , boolean );
void amii_display_file(const char * , boolean ); void amii_display_file(const char * , boolean );
void amii_curs(winid , int , int ); void amii_curs(winid , int , int );
void amii_print_glyph(winid , coordxy , coordxy , int, int ); void amii_print_glyph(winid, coordxy, coordxy, const glyph_info *, const glyph_info *);
void DoMenuScroll(int , int ); void DoMenuScroll(int , int );
void DisplayData(int , int , int ); void DisplayData(int , int , int );
void SetPropInfo(struct Window * , struct Gadget * , long , long , long ); void SetPropInfo(struct Window * , struct Gadget * , long , long , long );

View File

@@ -41,7 +41,8 @@
int main(int, char **); int main(int, char **);
struct BitMap *MyAllocBitMap(int, int, int, long); struct BitMap *MyAllocBitMap(int, int, int, long);
void MyFreeBitMap(struct BitMap *); void MyFreeBitMap(struct BitMap *);
void FreeImageFiles(char **, struct BitMap **); BitMapHeader ReadImageFile(const char *, struct BitMap **);
void FreeImageFile(struct BitMap **);
void amiv_flush_glyph_buffer(struct Window *); void amiv_flush_glyph_buffer(struct Window *);
void amiv_lprint_glyph(winid, int, int); void amiv_lprint_glyph(winid, int, int);
void amii_lprint_glyph(winid, int, int); void amii_lprint_glyph(winid, int, int);
@@ -91,17 +92,9 @@ extern int maxmontile, maxobjtile, maxothtile; /* from tile.c */
struct PDAT pictdata; struct PDAT pictdata;
#define NUMTILEIMAGES 3 /* Single tile image file, set at runtime by amii_init_nhwindows */
char *tileimages[] = { char *tilefile;
#define TBLMONTILE 0 struct BitMap *tileimg, *tile;
"NetHack:tiles/monsters.iff",
#define TBLOBJTILE 1
"NetHack:tiles/objects.iff",
#define TBLOTHTILE 2
"NetHack:tiles/other.iff", 0,
};
struct BitMap *ifftimg[NUMTILEIMAGES], *tile;
#ifdef TESTING #ifdef TESTING
short pens[NUMDRIPENS] = { 8, 3, 15, 0, 15, 7, 7, 8, 0 }; short pens[NUMDRIPENS] = { 8, 3, 15, 0, 15, 7, 7, 8, 0 };
@@ -146,7 +139,7 @@ main(int argc, char **argv)
x = x % IMGCOLUMNS; x = x % IMGCOLUMNS;
dx = i % (IMGCOLUMNS * 2); dx = i % (IMGCOLUMNS * 2);
dy = i / (IMGCOLUMNS * 2); dy = i / (IMGCOLUMNS * 2);
BltBitMapRastPort(ifftimg[tbl], x * pictdata.xsize, BltBitMapRastPort(tileimg, x * pictdata.xsize,
y * pictdata.ysize, w->RPort, y * pictdata.ysize, w->RPort,
w->BorderLeft + 1 + dx * pictdata.xsize, w->BorderLeft + 1 + dx * pictdata.xsize,
w->BorderTop + 1 + dy * pictdata.ysize, w->BorderTop + 1 + dy * pictdata.ysize,
@@ -176,175 +169,112 @@ main(int argc, char **argv)
CloseScreen(scr); CloseScreen(scr);
} }
FreeImageFiles(tileimages, ifftimg); FreeTileImageFiles();
return (0); return (0);
} }
#endif #endif
/*
* Read a single BMAP IFF file into a BitMap.
* Returns the BitMapHeader; *bmp receives the bitmap.
* Caller frees via FreeImageFile().
*/
BitMapHeader BitMapHeader
ReadTileImageFiles() ReadImageFile(const char *filename, struct BitMap **bmp)
{ {
char *errstr = NULL; BitMapHeader *bmhd, bmhds;
BitMapHeader ret = ReadImageFiles(tileimages, ifftimg, &errstr); int j, np;
if (errstr) {
panic(errstr);
}
return ret;
}
BitMapHeader
ReadImageFiles(char **filenames, struct BitMap **iffimg, char **errstrp)
{
BitMapHeader *bmhd = NULL, bmhds;
unsigned char *cmap;
extern int errno;
register int i, j;
struct IFFHandle *iff; struct IFFHandle *iff;
struct StoredProperty *prop; struct StoredProperty *prop;
IFFParseBase = OpenLibrary("iffparse.library", 0L); IFFParseBase = OpenLibrary("iffparse.library", 0L);
if (!IFFParseBase) { if (!IFFParseBase)
*errstrp = "No iffparse.library"; panic("No iffparse.library");
return bmhds;
iff = AllocIFF();
if (!iff)
panic("can't start IFF processing");
iff->iff_Stream = Open(filename, MODE_OLDFILE);
if (iff->iff_Stream == 0)
panic("Can't open %s", filename);
InitIFFasDOS(iff);
OpenIFF(iff, IFFF_READ);
PropChunk(iff, ID_BMAP, ID_BMHD);
PropChunk(iff, ID_BMAP, ID_CMAP);
PropChunk(iff, ID_BMAP, ID_PDAT);
StopChunk(iff, ID_BMAP, ID_PLNE);
if ((j = ParseIFF(iff, IFFPARSE_SCAN)) != 0)
panic("ParseIFF failed on %s, code %d",
filename, j);
prop = FindProp(iff, ID_BMAP, ID_BMHD);
if (!prop)
panic("No BMHD chunk in %s", filename);
bmhd = (BitMapHeader *) prop->sp_Data;
np = bmhd->nPlanes;
/* Load CMAP into palette arrays if present */
prop = FindProp(iff, ID_BMAP, ID_CMAP);
if (prop) {
unsigned char *cmap = prop->sp_Data;
for (j = 0; j < (1L << np) * 3; j += 3) {
amii_initmap[j / 3] =
amiv_init_map[j / 3] =
((cmap[j+0] >> 4) << 8)
| ((cmap[j+1] >> 4) << 4)
| (cmap[j+2] >> 4);
}
} }
/* /* Load PDAT if present */
for( i = 0; filenames[i]; ++i ) prop = FindProp(iff, ID_BMAP, ID_PDAT);
memset( iffimg[i], 0, sizeof( struct BitMap ) ); if (prop)
*/ pictdata = *(struct PDAT *) prop->sp_Data;
for (i = 0; filenames[i]; ++i) {
iff = AllocIFF();
if (!iff) {
FreeImageFiles(filenames, iffimg);
*errstrp = "can't start IFF processing";
return bmhds;
}
iff->iff_Stream = Open(filenames[i], MODE_OLDFILE);
if (iff->iff_Stream == 0) {
char *buf = malloc(100 + strlen(filenames[i]));
FreeImageFiles(filenames, iffimg);
sprintf(buf, "Can't open %s: %s", filenames[i], strerror(errno));
*errstrp = buf;
return bmhds;
}
InitIFFasDOS(iff);
OpenIFF(iff, IFFF_READ);
PropChunk(iff, ID_BMAP, ID_BMHD);
PropChunk(iff, ID_BMAP, ID_CMAP);
PropChunk(iff, ID_BMAP, ID_CAMG);
PropChunk(iff, ID_BMAP, ID_PDAT);
StopChunk(iff, ID_BMAP, ID_PLNE);
if ((j = ParseIFF(iff, IFFPARSE_SCAN)) != 0) {
char *buf = malloc(100);
FreeImageFiles(filenames, iffimg);
sprintf(buf, "ParseIFF failed for image %d, failure code: %d", i,
j);
*errstrp = buf;
return bmhds;
}
if (prop = FindProp(iff, ID_BMAP, ID_BMHD)) { *bmp = MyAllocBitMap(bmhd->w, bmhd->h,
bmhd = (BitMapHeader *) prop->sp_Data; np, MEMF_CHIP | MEMF_CLEAR);
} else { if (!*bmp)
FreeImageFiles(filenames, iffimg); panic("Can't allocate bitmap for %s", filename);
CloseIFF(iff);
Close(iff->iff_Stream);
FreeIFF(iff);
*errstrp = "No BMHD CHUNK in file";
return bmhds;
}
if (prop = FindProp(iff, ID_BMAP, ID_CMAP)) { for (j = 0; j < np; j++)
cmap = prop->sp_Data; ReadChunkBytes(iff, (*bmp)->Planes[j],
for (j = 0; j < (1L << bmhd->nPlanes) * 3; j += 3) { RASSIZE(bmhd->w, bmhd->h));
#if 0
/* Some day we will want to use the larger palette
* resolution available under v39 and later. i.e.
* 32 instead of 12 bits of color. Ususally this
* just means shifting the color left by 16-20 bits
* depending on what intensity looks best. Experience
* says that the higher values are better intensities.
*
* For now though we won't do this. The color table
* structure is incompatible with earlier versions of
* intuition. We would have to do some funny things
* to make 3*AMII_MAXCOLORS longs work like 3*AMII_MAXCOLORS
* UWORD's at run time... A union would help, but...
*/
if( IntuitionBase->LibNode.lib_Version >= 39 )
{
/* 8 bits of color, so shift to left end. */
amiv_init_map[ j+0 ] = cmap[j+0]<<24;
amiv_init_map[ j+1 ] = cmap[j+1]<<24;
amiv_init_map[ j+2 ] = cmap[j+2]<<24;
}
else
#endif
{
/* We can only use 4 bits of the 8 that are stored in the
* cmap, so mask them and then shift them into position
* for the UWORD value to store.
*/
#ifndef TESTING
amii_initmap[j / 3] = amiv_init_map[j / 3] =
((cmap[j + 0] >> 4) << 8) | ((cmap[j + 1] >> 4) << 4)
| (cmap[j + 2] >> 4);
#endif
}
}
} else {
FreeImageFiles(filenames, iffimg);
CloseIFF(iff);
Close(iff->iff_Stream);
FreeIFF(iff);
*errstrp = "No CMAP CHUNK in file";
return bmhds;
}
if (prop = FindProp(iff, ID_BMAP, ID_PDAT)) { bmhds = *bmhd;
struct PDAT *pp; CloseIFF(iff);
Close(iff->iff_Stream);
pp = (struct PDAT *) prop->sp_Data; FreeIFF(iff);
pictdata = *pp;
} else {
FreeImageFiles(filenames, iffimg);
CloseIFF(iff);
Close(iff->iff_Stream);
FreeIFF(iff);
*errstrp = "No PDAT CHUNK in file";
return bmhds;
}
iffimg[i] = MyAllocBitMap(bmhd->w, bmhd->h,
pictdata.nplanes + amii_extraplanes,
MEMF_CHIP | MEMF_CLEAR);
if (iffimg[i] == NULL) {
char *buf = malloc(80);
FreeImageFiles(filenames, iffimg);
sprintf(buf, "Can't allocate bitmap for image %d\n", i);
*errstrp = buf;
return bmhds;
}
for (j = 0; j < pictdata.nplanes + amii_extraplanes; ++j) {
ReadChunkBytes(iff, iffimg[i]->Planes[j],
RASSIZE(bmhd->w, bmhd->h));
}
bmhds = *bmhd;
CloseIFF(iff);
Close(iff->iff_Stream);
FreeIFF(iff);
}
CloseLibrary(IFFParseBase); CloseLibrary(IFFParseBase);
tile = MyAllocBitMap(pictdata.xsize, pictdata.ysize, return bmhds;
pictdata.nplanes + amii_extraplanes, }
MEMF_CHIP | MEMF_CLEAR);
if (tile == NULL) { void
FreeImageFiles(filenames, iffimg); FreeImageFile(struct BitMap **bmp)
*errstrp = "Can't allocate tile bitmap for scaling"; {
if (*bmp) {
MyFreeBitMap(*bmp);
*bmp = NULL;
} }
return (bmhds); }
BitMapHeader
ReadTileImageFiles(void)
{
BitMapHeader bmhds;
bmhds = ReadImageFile(tilefile, &tileimg);
tile = MyAllocBitMap(pictdata.xsize, pictdata.ysize,
pictdata.nplanes + amii_extraplanes,
MEMF_CHIP | MEMF_CLEAR);
if (!tile)
panic("Can't allocate tile temp bitmap");
return bmhds;
} }
struct MyBitMap { struct MyBitMap {
@@ -401,8 +331,7 @@ MyFreeBitMap(struct BitMap *bmp)
#ifdef TESTING #ifdef TESTING
void void
panic(s, a1, a2, a3, a4) panic(char *s, long a1, long a2, long a3, long a4)
char *s;
{ {
printf(s, a1, a2, a3, a4); printf(s, a1, a2, a3, a4);
putchar('\n'); putchar('\n');
@@ -420,24 +349,10 @@ alloc(unsigned int x)
#endif #endif
void void
FreeTileImageFiles() FreeTileImageFiles(void)
{ {
FreeImageFiles(tileimages, ifftimg); FreeImageFile(&tileimg);
} FreeImageFile(&tile);
void
FreeImageFiles(char **filenames, struct BitMap **img)
{
register int i;
for (i = 0; filenames[i]; ++i) {
if (img[i])
MyFreeBitMap(img[i]);
}
/* REALLY ugly hack alert! */
if (tile && img == ifftimg)
MyFreeBitMap(tile);
} }
#ifndef TESTING #ifndef TESTING
@@ -456,8 +371,7 @@ struct amiv_glyph_node amiv_g_nodes[NUMBER_GLYPH_NODES];
static char amiv_glyph_buffer[GLYPH_BUFFER_SIZE]; static char amiv_glyph_buffer[GLYPH_BUFFER_SIZE];
void void
flush_glyph_buffer(vw) flush_glyph_buffer(struct Window *vw)
struct Window *vw;
{ {
if (WINVERS_AMIV) if (WINVERS_AMIV)
amiv_flush_glyph_buffer(vw); amiv_flush_glyph_buffer(vw);
@@ -469,8 +383,7 @@ struct Window *vw;
* Routine to flush whatever is buffered * Routine to flush whatever is buffered
*/ */
void void
amiv_flush_glyph_buffer(vw) amiv_flush_glyph_buffer(struct Window *vw)
struct Window *vw;
{ {
#if !defined(DISPMAP) || defined(OPT_DISPMAP) #if !defined(DISPMAP) || defined(OPT_DISPMAP)
int xsize, ysize, x, y; int xsize, ysize, x, y;
@@ -481,7 +394,7 @@ struct Window *vw;
struct BitMap *imgbm = 0, *bm = 0; struct BitMap *imgbm = 0, *bm = 0;
int i, k; int i, k;
int scaling_needed; int scaling_needed;
register struct RastPort *rp = vw->RPort; struct RastPort *rp = vw->RPort;
#endif #endif
/* If nothing is buffered, return before we do anything */ /* If nothing is buffered, return before we do anything */
@@ -577,7 +490,7 @@ struct Window *vw;
/* Go ahead and start dumping the stuff */ /* Go ahead and start dumping the stuff */
for (i = 0; i < glyph_node_index; ++i) { for (i = 0; i < glyph_node_index; ++i) {
/* Do it */ /* Do it */
register int offx, offy, j; int offx, offy, j;
struct BitMap *nodebm = amiv_g_nodes[i].bitmap; struct BitMap *nodebm = amiv_g_nodes[i].bitmap;
/* Get the unclipped coordinates */ /* Get the unclipped coordinates */
@@ -596,10 +509,10 @@ struct Window *vw;
* this code is generalized to handle any size tile * this code is generalized to handle any size tile
* image... * image...
*/ */
memcpy(tile->Planes[j] + ((k * pictdata.ysize) / 8), memcpy(tile->Planes[j] + k * tile->BytesPerRow,
nodebm->Planes[j] + offx + offy nodebm->Planes[j] + offx + offy
+ (nodebm->BytesPerRow * k), + (nodebm->BytesPerRow * k),
pictdata.ysize / 8); pictdata.xsize / 8);
} }
} }
@@ -648,41 +561,30 @@ struct Window *vw;
* Glyph buffering routine. Called instead of WindowPuts(). * Glyph buffering routine. Called instead of WindowPuts().
*/ */
void void
amiv_lprint_glyph(window, color_index, glyph) amiv_lprint_glyph(winid window, int color_index, int glyph)
winid window;
int color_index, glyph;
{ {
int base; int base;
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
struct Window *w; struct Window *w;
int curx; int curx;
int cury; int cury;
int tbl, icon; int icon;
register int xoff, yoff; int xoff, yoff;
/* Get the real icon index */ /* Skip NO_GLYPH — nothing to draw */
if (glyph != NO_GLYPH) if (glyph == NO_GLYPH)
icon = GlyphToIcon(glyph); return;
icon = GlyphToIcon(glyph);
if ((cw = amii_wins[window]) == (struct amii_WinDesc *) NULL) if ((cw = amii_wins[window]) == (struct amii_WinDesc *) NULL)
panic("bad winid in amiv_lprint_glyph: %d", window); panic("bad winid in amiv_lprint_glyph: %d", window);
w = cw->win; w = cw->win;
if (glyph != NO_GLYPH && glyph < 10000) { if (glyph < 10000) {
/* decide on which image has the needed picture */ if (icon >= pictdata.npics)
if (icon <= MAXMONTILE) { icon = 0; /* fallback for out-of-range */
tbl = TBLMONTILE;
base = 0;
} else if (icon <= MAXOBJTILE) {
tbl = TBLOBJTILE;
base = MAXMONTILE + 1;
} else if (icon <= MAXOTHTILE) {
tbl = TBLOTHTILE;
base = MAXOBJTILE + 1;
} else
panic("Bad icon #%d, glyph #%d, only %d icons known\n", icon,
glyph, MAXOTHTILE);
/* Get the relative offset in the page */ /* Get the relative offset in the page */
@@ -748,11 +650,11 @@ int color_index, glyph;
amiv_g_nodes[glyph_node_index].odstx = cw->curx; amiv_g_nodes[glyph_node_index].odstx = cw->curx;
amiv_g_nodes[glyph_node_index].srcx = xoff; amiv_g_nodes[glyph_node_index].srcx = xoff;
amiv_g_nodes[glyph_node_index].srcy = yoff; amiv_g_nodes[glyph_node_index].srcy = yoff;
amiv_g_nodes[glyph_node_index].bitmap = ifftimg[tbl]; amiv_g_nodes[glyph_node_index].bitmap = tileimg;
++glyph_node_index; ++glyph_node_index;
} else { } else {
/* Do it */ /* Do it */
register int j, k, x, y, apen; int j, k, x, y, apen;
struct RastPort *rp = w->RPort; struct RastPort *rp = w->RPort;
x = rp->cp_x - pictdata.xsize - 3; x = rp->cp_x - pictdata.xsize - 3;
#ifdef OPT_DISPMAP #ifdef OPT_DISPMAP
@@ -770,17 +672,17 @@ int color_index, glyph;
y = rp->cp_y - pictdata.ysize + 1; y = rp->cp_y - pictdata.ysize + 1;
if (glyph != NO_GLYPH) { if (glyph != NO_GLYPH) {
struct BitMap *bm = ifftimg[tbl]; struct BitMap *bm = tileimg;
/* 8 bits per byte */ /* 8 bits per byte */
xoff /= 8; xoff /= 8;
yoff *= bm->BytesPerRow; yoff *= bm->BytesPerRow;
for (j = 0; j < pictdata.nplanes; ++j) { for (j = 0; j < pictdata.nplanes; ++j) {
for (k = 0; k < pictdata.ysize; ++k) { for (k = 0; k < pictdata.ysize; ++k) {
memcpy(tile->Planes[j] + ((k * pictdata.ysize) / 8), memcpy(tile->Planes[j] + k * tile->BytesPerRow,
bm->Planes[j] + xoff + yoff bm->Planes[j] + xoff + yoff
+ (bm->BytesPerRow * k), + (bm->BytesPerRow * k),
pictdata.ysize / 8); pictdata.xsize / 8);
} }
} }
@@ -824,8 +726,7 @@ static int usecolor;
*/ */
void void
amiv_start_glyphout(window) amiv_start_glyphout(winid window)
winid window;
{ {
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
struct Window *w; struct Window *w;
@@ -860,8 +761,7 @@ winid window;
* General cleanup routine -- flushes and restores cursor * General cleanup routine -- flushes and restores cursor
*/ */
void void
amii_end_glyphout(window) amii_end_glyphout(winid window)
winid window;
{ {
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
struct Window *w; struct Window *w;
@@ -891,7 +791,7 @@ winid window;
Move(w->RPort, xsave, ysave); Move(w->RPort, xsave, ysave);
} }
static maze_type = COL_MAZE_BRICK; static int maze_type = COL_MAZE_BRICK;
void void
SetMazeType(MazeType t) SetMazeType(MazeType t)
@@ -987,11 +887,10 @@ int backg[AMII_MAXCOLORS] = {
* Routine to simply flush whatever is buffered * Routine to simply flush whatever is buffered
*/ */
void void
amii_flush_glyph_buffer(w) amii_flush_glyph_buffer(struct Window *w)
struct Window *w;
{ {
short i, x, y; short i, x, y;
register struct RastPort *rp = w->RPort; struct RastPort *rp = w->RPort;
/* If nothing is buffered, return before we do anything */ /* If nothing is buffered, return before we do anything */
if (glyph_node_index == 0) if (glyph_node_index == 0)
@@ -1013,6 +912,10 @@ struct Window *w;
+ rp->TxBaseline + 1; + rp->TxBaseline + 1;
x = amii_g_nodes[i].x * rp->TxWidth + w->BorderLeft; x = amii_g_nodes[i].x * rp->TxWidth + w->BorderLeft;
/* Skip if pixel coordinates are outside window */
if (x < 0 || y < 0 || y >= w->Height || x >= w->Width)
continue;
/* Move pens to correct location */ /* Move pens to correct location */
Move(rp, (long) x, (long) y); Move(rp, (long) x, (long) y);
@@ -1029,9 +932,7 @@ struct Window *w;
glyph_node_index = glyph_buffer_index = 0; glyph_node_index = glyph_buffer_index = 0;
} }
void void
amiga_print_glyph(window, color_index, glyph) amiga_print_glyph(winid window, int color_index, int glyph)
winid window;
int color_index, glyph;
{ {
if (WINVERS_AMIV) if (WINVERS_AMIV)
amiv_lprint_glyph(window, color_index, glyph); amiv_lprint_glyph(window, color_index, glyph);
@@ -1043,9 +944,7 @@ int color_index, glyph;
* Glyph buffering routine. Called instead of WindowPuts(). * Glyph buffering routine. Called instead of WindowPuts().
*/ */
void void
amii_lprint_glyph(window, color_index, glyph) amii_lprint_glyph(winid window, int color_index, int glyph)
winid window;
int color_index, glyph;
{ {
int fg_color, bg_color; int fg_color, bg_color;
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
@@ -1120,8 +1019,7 @@ static int usecolor;
*/ */
void void
amii_start_glyphout(window) amii_start_glyphout(winid window)
winid window;
{ {
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
struct Window *w; struct Window *w;
@@ -1195,7 +1093,7 @@ amii_end_glyphout(window)
#ifdef OPT_DISPMAP #ifdef OPT_DISPMAP
/* don't use dispmap unless x & y are 8,16,24,32,48 and equal */ /* don't use dispmap unless x & y are 8,16,24,32,48 and equal */
void void
dispmap_sanity() dispmap_sanity(void)
{ {
if (mxsize != mysize || dispmap_sanity1(mxsize) if (mxsize != mysize || dispmap_sanity1(mxsize)
|| dispmap_sanity1(mysize)) { || dispmap_sanity1(mysize)) {
@@ -1203,11 +1101,10 @@ dispmap_sanity()
} }
} }
int int
dispmap_sanity1(x) dispmap_sanity1(int x)
int x;
{ {
static unsigned char valid[] = { 8, 16, 24, 32, 48, 0 }; static unsigned char valid[] = { 8, 16, 24, 32, 48, 0 };
return !!strchr(valid, x); return !strchr((char *)valid, x);
} }
#endif /* OPT_DISPMAP */ #endif /* OPT_DISPMAP */
#endif /* TESTING */ #endif /* TESTING */

View File

@@ -112,7 +112,7 @@ CLIPPING must be defined for the AMIGA version
#endif #endif
#define WINVERS_AMII (strcmp("amii", windowprocs.name) == 0) #define WINVERS_AMII (strcmp("amii", windowprocs.name) == 0)
#define WINVERS_AMIV (strcmp("amitile", windowprocs.name) == 0) #define WINVERS_AMIV (strcmp("amiv", windowprocs.name) == 0)
#define WINVERS_AMIT (strcmp("amitty", windowprocs.name) == 0) #define WINVERS_AMIT (strcmp("amitty", windowprocs.name) == 0)
/* cw->data[x] contains 2 characters worth of special information. These /* cw->data[x] contains 2 characters worth of special information. These
@@ -196,3 +196,4 @@ struct PDAT
#undef MAXCOLORS #undef MAXCOLORS
#define MAXCOLORS 256 #define MAXCOLORS 256

View File

@@ -14,7 +14,6 @@
#endif #endif
#include "patchlevel.h" #include "patchlevel.h"
#include "date.h"
extern struct TagItem scrntags[]; extern struct TagItem scrntags[];
#ifndef CROSS_TO_AMIGA #ifndef CROSS_TO_AMIGA
@@ -40,6 +39,11 @@ int xclipbord = 4, yclipbord = 2;
#endif #endif
int mxsize, mysize; int mxsize, mysize;
/* Track the last level we centered the clipping viewport on, so that
both amii_clear_nhwindow (pre-docrt centering) and amii_cliparound
(scroll/pan during play) can detect level changes. */
static d_level clip_saved_level = { 127, 127 }; /* XXX */
struct Rectangle amii_oldover; struct Rectangle amii_oldover;
struct Rectangle amii_oldmsg; struct Rectangle amii_oldmsg;
@@ -58,8 +62,7 @@ int amii_otherBPen;
long amii_libvers = LIBRARY_FONT_VERSION; long amii_libvers = LIBRARY_FONT_VERSION;
void void
ami_wininit_data(dir) ami_wininit_data(int dir)
int dir;
{ {
extern unsigned short amii_init_map[AMII_MAXCOLORS]; extern unsigned short amii_init_map[AMII_MAXCOLORS];
extern unsigned short amiv_init_map[AMII_MAXCOLORS]; extern unsigned short amiv_init_map[AMII_MAXCOLORS];
@@ -150,12 +153,13 @@ struct TagItem wintags[] = {
}; };
#endif #endif
void amii_destroy_nhwindow(win) /* just hide */ void
register winid win; amii_destroy_nhwindow(winid win) /* just hide */
{ {
int i; int i;
int type; int type;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
if (win == WIN_ERR || (cw = amii_wins[win]) == NULL) { if (win == WIN_ERR || (cw = amii_wins[win]) == NULL) {
panic(winpanicstr, win, "destroy_nhwindow"); panic(winpanicstr, win, "destroy_nhwindow");
@@ -260,26 +264,37 @@ PPC_LayerFillHook(void)
struct RastPort *rp = (struct RastPort *) REG_A2; struct RastPort *rp = (struct RastPort *) REG_A2;
struct FillParams *fp = (struct FillParams *) REG_A1; struct FillParams *fp = (struct FillParams *) REG_A1;
#else #else
/* Assembly trampoline: Intuition calls LayerFillHook with arguments
in registers a0 (hook), a1 (fillparams), a2 (rastport).
Push them onto the stack and call the C implementation. */
__asm(
" .globl _LayerFillHook\n"
"_LayerFillHook:\n"
" move.l a1,-(sp)\n"
" move.l a2,-(sp)\n"
" move.l a0,-(sp)\n"
" jsr _LayerFillHook_impl\n"
" lea 12(sp),sp\n"
" rts\n"
);
void void
LayerFillHook(void) LayerFillHook_impl(struct Hook *hk, struct RastPort *rp,
struct FillParams *fp)
{ {
register struct Hook *hk asm("a0");
register struct RastPort *rp asm("a2");
register struct FillParams *fp asm("a1");
#endif #endif
#else #else
void void
#ifndef _DCC #ifndef _DCC
__interrupt __interrupt
#endif #endif
__saveds __asm LayerFillHook(register __a0 struct Hook *hk, __saveds __asm LayerFillHook(__a0 struct Hook *hk,
register __a2 struct RastPort *rp, __a2 struct RastPort *rp,
register __a1 struct FillParams *fp) __a1 struct FillParams *fp)
{ {
#endif #endif
register long x, y, xmax, ymax; long x, y, xmax, ymax;
register int apen; int apen;
struct RastPort rptmp; struct RastPort rptmp;
memcpy(&rptmp, rp, sizeof(struct RastPort)); memcpy(&rptmp, rp, sizeof(struct RastPort));
@@ -321,15 +336,17 @@ void
} }
#endif #endif
amii_create_nhwindow(type) register int type; winid
amii_create_nhwindow(int type)
{ {
register struct Window *w = NULL; struct Window *w = NULL;
register struct NewWindow *nw = NULL; struct NewWindow *nw = NULL;
register struct amii_WinDesc *wd = NULL; struct amii_WinDesc *wd = NULL;
struct Window *mapwin = NULL, *stwin = NULL, *msgwin = NULL; struct Window *mapwin = NULL, *stwin = NULL, *msgwin = NULL;
register int newid; int newid;
int maph, stath, scrfontysize; int maph, stath, scrfontysize;
scrfontysize = HackScreen->Font->ta_YSize; scrfontysize = HackScreen->Font->ta_YSize;
/* /*
@@ -563,11 +580,7 @@ amii_create_nhwindow(type) register int type;
case NHW_OVER: case NHW_OVER:
case NHW_MAP: case NHW_MAP:
if (wd) { if (wd) {
#ifdef __GNUC__
fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Entry = (void *) &LayerFillHook;
#else
fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
fillhook.h_Data = (void *) type; fillhook.h_Data = (void *) type;
fillhook.h_SubEntry = 0; fillhook.h_SubEntry = 0;
wd->hook = alloc(sizeof(fillhook)); wd->hook = alloc(sizeof(fillhook));
@@ -665,6 +678,10 @@ amii_create_nhwindow(type) register int type;
/ w->RPort->TxHeight; / w->RPort->TxHeight;
wd->cols = (w->Width - w->BorderLeft - w->BorderRight - 2) wd->cols = (w->Width - w->BorderLeft - w->BorderRight - 2)
/ w->RPort->TxWidth; / w->RPort->TxWidth;
/* Map window uses y+2 offset in amii_print_glyph, so cury
values go up to ROWNO+2. Ensure rows accommodates this. */
if (type == NHW_MAP && wd->rows < ROWNO + 3)
wd->rows = ROWNO + 3;
} }
/* Okay, now do the individual type initialization */ /* Okay, now do the individual type initialization */
@@ -736,7 +753,9 @@ amii_create_nhwindow(type) register int type;
*/ */
wd->data = (char **) alloc(3 * sizeof(char *)); wd->data = (char **) alloc(3 * sizeof(char *));
wd->data[0] = (char *) alloc(wd->cols + 10); wd->data[0] = (char *) alloc(wd->cols + 10);
wd->data[0][0] = '\0';
wd->data[1] = (char *) alloc(wd->cols + 10); wd->data[1] = (char *) alloc(wd->cols + 10);
wd->data[1][0] = '\0';
wd->data[2] = NULL; wd->data[2] = NULL;
break; break;
@@ -771,7 +790,7 @@ amii_create_nhwindow(type) register int type;
SetMenuStrip(w, MenuStrip); SetMenuStrip(w, MenuStrip);
/* Make our requesters come to our screen */ /* Make our requesters come to our screen */
{ {
register struct Process *myProcess = struct Process *myProcess =
(struct Process *) FindTask(NULL); (struct Process *) FindTask(NULL);
pr_WindowPtr = (struct Window *) (myProcess->pr_WindowPtr); pr_WindowPtr = (struct Window *) (myProcess->pr_WindowPtr);
myProcess->pr_WindowPtr = (APTR) w; myProcess->pr_WindowPtr = (APTR) w;
@@ -787,17 +806,7 @@ amii_create_nhwindow(type) register int type;
Abort(AG_OpenDev | AO_ConsoleDev); Abort(AG_OpenDev | AO_ConsoleDev);
} }
ConsoleDevice = ConsoleDevice = (struct Device *) ConsoleIO.io_Device;
#ifndef CROSS_TO_AMIGA
(struct Library *)
#else
(struct Device *
# ifdef __CONSTLIBBASEDECL__
__CONSTLIBBASEDECL__
# endif /* __CONSTLIBBASEDECL__ */
)
#endif
ConsoleIO.io_Device;
KbdBuffered = 0; KbdBuffered = 0;
#ifdef HACKFONT #ifdef HACKFONT
@@ -831,12 +840,23 @@ PPC_SM_Filter(void)
ULONG modeID = (ULONG) REG_A1; ULONG modeID = (ULONG) REG_A1;
struct ScreenModeRequester *smr = (struct ScreenModeRequester *) REG_A2; struct ScreenModeRequester *smr = (struct ScreenModeRequester *) REG_A2;
#else #else
/* Assembly trampoline for SM_Filter hook callback.
SM_Filter is the asm entry point; SM_Filter_impl is the C body. */
extern void SM_Filter(void);
__asm(
" .globl _SM_Filter\n"
"_SM_Filter:\n"
" move.l a2,-(sp)\n"
" move.l a1,-(sp)\n"
" move.l a0,-(sp)\n"
" jsr _SM_Filter_impl\n"
" lea 12(sp),sp\n"
" rts\n"
);
int int
SM_Filter(void) SM_Filter_impl(struct Hook *hk, ULONG modeID,
struct ScreenModeRequester *smr)
{ {
register struct Hook *hk asm("a0");
register ULONG modeID asm("a1");
register struct ScreenModeRequester *smr asm("a2");
#endif #endif
#else #else
int int
@@ -844,8 +864,8 @@ int
__interrupt __interrupt
#endif #endif
__saveds __asm SM_Filter( __saveds __asm SM_Filter(
register __a0 struct Hook *hk, register __a1 ULONG modeID, __a0 struct Hook *hk, __a1 ULONG modeID,
register __a2 struct ScreenModeRequester *smr) __a2 struct ScreenModeRequester *smr)
{ {
#endif #endif
struct DimensionInfo dims; struct DimensionInfo dims;
@@ -869,14 +889,13 @@ int
/* Initialize the windowing environment */ /* Initialize the windowing environment */
void void
amii_init_nhwindows(argcp, argv) amii_init_nhwindows(int *argcp, char **argv)
int *argcp;
char **argv;
{ {
int i; int i;
struct Screen *wbscr; struct Screen *wbscr;
int forcenobig = 0; int forcenobig = 0;
if (HackScreen) if (HackScreen)
panic("init_nhwindows() called twice", 0); panic("init_nhwindows() called twice", 0);
@@ -1192,9 +1211,16 @@ char **argv;
} }
#endif #endif
if (WINVERS_AMIV) if (WINVERS_AMIV) {
extern char *tilefile;
if (amii_numcolors >= 32) {
tilefile = "NetHack:tiles/tiles32.iff";
amii_numcolors = 32;
} else {
tilefile = "NetHack:tiles/tiles16.iff";
}
amii_bmhd = ReadTileImageFiles(); amii_bmhd = ReadTileImageFiles();
else } else
memcpy(amii_initmap, amii_init_map, sizeof(amii_initmap)); memcpy(amii_initmap, amii_init_map, sizeof(amii_initmap));
memcpy(sysflags.amii_curmap, amii_initmap, sizeof(sysflags.amii_curmap)); memcpy(sysflags.amii_curmap, amii_initmap, sizeof(sysflags.amii_curmap));
@@ -1361,11 +1387,11 @@ amii_setdrawpens(struct Window *w, int type)
/* Clear the indicated window */ /* Clear the indicated window */
void void
amii_clear_nhwindow(win) amii_clear_nhwindow(winid win)
register winid win;
{ {
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register struct Window *w; struct Window *w;
if (reclip == 2) if (reclip == 2)
return; return;
@@ -1394,6 +1420,40 @@ register winid win;
amii_setfillpens(w, cw->type); amii_setfillpens(w, cw->type);
SetDrMd(w->RPort, JAM2); SetDrMd(w->RPort, JAM2);
#ifdef CLIPPING
/* When clearing the map for a full redraw (docrt/cls), center the
clipping viewport on the player BEFORE the map is redrawn.
Without this, the first docrt() after a level change or new game
draws with stale clip coordinates (typically 0,0), leaving the
player off-screen until their first move triggers amii_cliparound. */
if (cw->type == NHW_MAP && clipping && u.ux
&& !on_level(&u.uz, &clip_saved_level)) {
int COx, LIx;
struct RastPort *rp = w->RPort;
if (Is_rogue_level(&u.uz)) {
COx = (w->Width - w->BorderLeft - w->BorderRight) / rp->TxWidth;
LIx = (w->Height - w->BorderTop - w->BorderBottom) / rp->TxHeight;
} else {
COx = CO;
LIx = LI;
}
clipx = max(0, (int) u.ux - COx / 2);
clipxmax = clipx + COx;
if (clipxmax > COLNO) {
clipxmax = COLNO;
clipx = clipxmax - COx;
}
clipy = max(0, (int) u.uy - LIx / 2);
clipymax = clipy + LIx;
if (clipymax > ROWNO) {
clipymax = ROWNO;
clipy = clipymax - LIx;
}
clip_saved_level = u.uz;
}
#endif
if (cw->type == NHW_MENU || cw->type == NHW_TEXT) { if (cw->type == NHW_MENU || cw->type == NHW_TEXT) {
RectFill(w->RPort, w->BorderLeft, w->BorderTop, RectFill(w->RPort, w->BorderLeft, w->BorderTop,
w->Width - w->BorderRight - 1, w->Width - w->BorderRight - 1,
@@ -1418,11 +1478,10 @@ register winid win;
/* Dismiss the window from the screen */ /* Dismiss the window from the screen */
void void
dismiss_nhwindow(win) dismiss_nhwindow(winid win)
register winid win;
{ {
register struct Window *w; struct Window *w;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
if (win == WIN_ERR || (cw = amii_wins[win]) == NULL) { if (win == WIN_ERR || (cw = amii_wins[win]) == NULL) {
panic(winpanicstr, win, "dismiss_nhwindow"); panic(winpanicstr, win, "dismiss_nhwindow");
@@ -1458,9 +1517,9 @@ register winid win;
} }
void void
amii_exit_nhwindows(str) amii_exit_nhwindows(const char *str)
const char *str;
{ {
/* Seems strange to have to do this... but we need the BASE window /* Seems strange to have to do this... but we need the BASE window
* left behind... * left behind...
*/ */
@@ -1475,15 +1534,14 @@ const char *str;
} }
void void
amii_display_nhwindow(win, blocking) amii_display_nhwindow(winid win, boolean blocking)
winid win;
boolean blocking;
{ {
menu_item *mip; menu_item *mip;
int cnt; int cnt;
static int lastwin = -1; static int lastwin = -1;
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
if (!Initialized) if (!Initialized)
return; return;
lastwin = win; lastwin = win;
@@ -1513,13 +1571,12 @@ boolean blocking;
} }
void void
amii_curs(window, x, y) amii_curs(winid window, int x, int y)
winid window;
register int x, y;
{ {
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register struct Window *w; struct Window *w;
register struct RastPort *rp; struct RastPort *rp;
if (window == WIN_ERR || (cw = amii_wins[window]) == NULL) if (window == WIN_ERR || (cw = amii_wins[window]) == NULL)
panic(winpanicstr, window, "curs"); panic(winpanicstr, window, "curs");
@@ -1540,8 +1597,14 @@ register int x, y;
cw->curx = x; cw->curx = x;
cw->cury = y; cw->cury = y;
/* Silently skip rendering for out-of-bounds coordinates */
if (cw->rows > 0 && y >= cw->rows)
return;
if (cw->cols > 0 && x >= cw->cols)
return;
#ifdef DEBUG #ifdef DEBUG
if (x < 0 || y < 0 || y >= cw->rows || x >= cw->cols) { if (0 && (x < 0 || y < 0 || y >= cw->rows || x >= cw->cols)) {
char *s = "[unknown type]"; char *s = "[unknown type]";
switch (cw->type) { switch (cw->type) {
case NHW_MESSAGE: case NHW_MESSAGE:
@@ -1663,12 +1726,10 @@ printf("pos: (%d,%d)->(%d,%d)\n",x,y,qqx,qqy);
} }
void void
amii_set_text_font(name, size) amii_set_text_font(char *name, int size)
char *name;
int size;
{ {
register int i; int i;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
int osize = TextsFont13.ta_YSize; int osize = TextsFont13.ta_YSize;
static char nname[100]; static char nname[100];
@@ -1709,11 +1770,10 @@ int size;
} }
void void
kill_nhwindows(all) kill_nhwindows(int all)
register int all;
{ {
register int i; int i;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
/* Foreach open window in all of amii_wins[], CloseShWindow, free memory /* Foreach open window in all of amii_wins[], CloseShWindow, free memory
*/ */
@@ -1726,12 +1786,10 @@ register int all;
} }
void void
amii_cl_end(cw, curs_pos) amii_cl_end(struct amii_WinDesc *cw, int curs_pos)
register struct amii_WinDesc *cw;
register int curs_pos;
{ {
register struct Window *w = cw->win; struct Window *w = cw->win;
register int oy, ox; int oy, ox;
if (!w) if (!w)
panic("NULL window pointer in amii_cl_end()"); panic("NULL window pointer in amii_cl_end()");
@@ -1745,12 +1803,11 @@ register int curs_pos;
} }
void void
cursor_off(window) cursor_off(winid window)
winid window;
{ {
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register struct Window *w; struct Window *w;
register struct RastPort *rp; struct RastPort *rp;
int curx, cury; int curx, cury;
int x, y; int x, y;
long dmode; long dmode;
@@ -1805,13 +1862,12 @@ winid window;
} }
void void
cursor_on(window) cursor_on(winid window)
winid window;
{ {
int x, y; int x, y;
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
register struct Window *w; struct Window *w;
register struct RastPort *rp; struct RastPort *rp;
unsigned char ch; unsigned char ch;
long dmode; long dmode;
short apen, bpen; short apen, bpen;
@@ -1858,10 +1914,13 @@ winid window;
if (WINVERS_AMIV && cw->type == NHW_MAP) { if (WINVERS_AMIV && cw->type == NHW_MAP) {
cursor_common(rp, x, y); cursor_common(rp, x, y);
} else { } else {
Move(rp, x, y); if (w && x >= 0 && y >= 0
ch = CURSOR_CHAR; && x < w->Width && y < w->Height) {
Text(rp, &ch, 1); Move(rp, x, y);
Move(rp, x, y); ch = CURSOR_CHAR;
Text(rp, &ch, 1);
Move(rp, x, y);
}
} }
SetDrMd(rp, dmode); SetDrMd(rp, dmode);
@@ -1870,9 +1929,7 @@ winid window;
} }
static void static void
cursor_common(rp, x, y) cursor_common(struct RastPort *rp, int x, int y)
struct RastPort *rp;
int x, y;
{ {
int x1, x2, y1, y2; int x1, x2, y1, y2;
@@ -1895,29 +1952,27 @@ int x, y;
} }
void void
amii_suspend_nhwindows(str) amii_suspend_nhwindows(const char *str)
const char *str;
{ {
if (HackScreen) if (HackScreen)
ScreenToBack(HackScreen); ScreenToBack(HackScreen);
} }
void void
amii_resume_nhwindows() amii_resume_nhwindows(void)
{ {
if (HackScreen) if (HackScreen)
ScreenToFront(HackScreen); ScreenToFront(HackScreen);
} }
void void
amii_bell() amii_bell(void)
{ {
DisplayBeep(NULL); DisplayBeep(NULL);
} }
void void
removetopl(cnt) removetopl(int cnt)
int cnt;
{ {
struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE]; struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE];
/* NB - this is sufficient for /* NB - this is sufficient for
@@ -1935,7 +1990,7 @@ int cnt;
#ifdef PORT_HELP #ifdef PORT_HELP
void void
port_help() port_help(void)
{ {
display_file(PORT_HELP, 1); display_file(PORT_HELP, 1);
} }
@@ -1951,17 +2006,20 @@ port_help()
*/ */
void void
amii_print_glyph(win, x, y, glyph, bkglyph) amii_print_glyph(winid win, coordxy x, coordxy y,
winid win; const glyph_info *glyphinfo,
coordxy x, y; const glyph_info *bkglyphinfo UNUSED)
int glyph, bkglyph;
{ {
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
uchar ch; uchar ch;
int glyph;
int color, och; int color, och;
extern const int zapcolors[]; extern const int zapcolors[];
unsigned special; unsigned special;
glyph = glyphinfo->glyph;
/* In order for the overview window to work, we can not clip here */ /* In order for the overview window to work, we can not clip here */
if (!WINVERS_AMIV) { if (!WINVERS_AMIV) {
#ifdef CLIPPING #ifdef CLIPPING
@@ -1993,14 +2051,8 @@ if(u.uz.dlevel != x){
} else /* AMII, or Rogue level in either version */ } else /* AMII, or Rogue level in either version */
{ {
/* map glyph to character and color */ /* map glyph to character and color */
#if 0 ch = glyphinfo->ttychar;
(void) mapglyph(glyph, &och, &color, &special, x, y, 0); color = glyphinfo->gm.sym.color;
ch = (uchar) och;
#else
glyph_info gi;
map_glyphinfo(0, 0, glyph, 0, &gi);
ch = gi.ttychar;
#endif
if (WINVERS_AMIV) { /* implies Rogue level here */ if (WINVERS_AMIV) { /* implies Rogue level here */
amii_curs(win, x, y); amii_curs(win, x, y);
amiga_print_glyph(win, NO_COLOR, ch + 10000); amiga_print_glyph(win, NO_COLOR, ch + 10000);
@@ -2021,11 +2073,11 @@ if(u.uz.dlevel != x){
/* Make sure the user sees a text string when no windowing is available */ /* Make sure the user sees a text string when no windowing is available */
void void
amii_raw_print(s) amii_raw_print(const char *s)
register const char *s;
{ {
int argc = 0; int argc = 0;
if (!s) if (!s)
return; return;
if (amiIDisplay) if (amiIDisplay)
@@ -2057,11 +2109,11 @@ register const char *s;
*/ */
void void
amii_raw_print_bold(s) amii_raw_print_bold(const char *s)
register const char *s;
{ {
int argc = 0; int argc = 0;
if (!s) if (!s)
return; return;
@@ -2092,9 +2144,10 @@ register const char *s;
/* Rebuild/update the inventory if the window is up. /* Rebuild/update the inventory if the window is up.
*/ */
void void
amii_update_inventory() amii_update_inventory(int arg UNUSED)
{ {
register struct amii_WinDesc *cw; struct amii_WinDesc *cw;
if (WIN_INVEN != WIN_ERR && (cw = amii_wins[WIN_INVEN]) if (WIN_INVEN != WIN_ERR && (cw = amii_wins[WIN_INVEN])
&& cw->type == NHW_MENU && cw->win) { && cw->type == NHW_MENU && cw->win) {
@@ -2102,10 +2155,17 @@ amii_update_inventory()
} }
} }
/* Stub for ctrl_nhwindow - no special handling needed for Amiga */
win_request_info *
amii_ctrl_nhwindow(winid window UNUSED, int request UNUSED, win_request_info *wri UNUSED)
{
return (win_request_info *) 0;
}
/* Humm, doesn't really do anything useful */ /* Humm, doesn't really do anything useful */
void void
amii_mark_synch() amii_mark_synch(void)
{ {
if (!amiIDisplay) if (!amiIDisplay)
fflush(stderr); fflush(stderr);
@@ -2116,7 +2176,7 @@ amii_mark_synch()
* ask for a key to be pressed. * ask for a key to be pressed.
*/ */
void void
amii_wait_synch() amii_wait_synch(void)
{ {
if (!amiIDisplay || amiIDisplay->rawprint) { if (!amiIDisplay || amiIDisplay->rawprint) {
if (amiIDisplay) if (amiIDisplay)
@@ -2130,7 +2190,7 @@ amii_wait_synch()
} }
void void
amii_setclipped() amii_setclipped(void)
{ {
#ifdef CLIPPING #ifdef CLIPPING
clipping = TRUE; clipping = TRUE;
@@ -2141,12 +2201,35 @@ amii_setclipped()
#endif #endif
} }
/* Redraw a rectangular region of the map via newsym(). Used after
ScrollRaster() shifts existing pixels — only the exposed strip needs
redrawing. Does NOT flush; the caller flushes after all regions. */
static void
redraw_map_region(int x1, int y1, int x2, int y2)
{
int x, y;
if (!u.ux)
return;
if (x1 < 1) x1 = 1;
if (y1 < 0) y1 = 0;
if (x2 >= COLNO) x2 = COLNO - 1;
if (y2 >= ROWNO) y2 = ROWNO - 1;
for (y = y1; y <= y2; y++)
for (x = x1; x <= x2; x++) {
/* Invalidate the glyph buffer so newsym() redraws even if
* the glyph hasn't changed — the pixels were shifted by
* ScrollRaster and no longer match the buffer. */
gg.gbuf[y][x].glyphinfo.glyph = NO_GLYPH;
newsym(x, y);
}
}
/* XXX still to do: suppress scrolling if we violate the boundary but the /* XXX still to do: suppress scrolling if we violate the boundary but the
* edge of the map is already displayed * edge of the map is already displayed
*/ */
void void
amii_cliparound(x, y) amii_cliparound(int x, int y)
register int x, y;
{ {
#ifdef CLIPPING #ifdef CLIPPING
int oldx = clipx, oldy = clipy; int oldx = clipx, oldy = clipy;
@@ -2155,8 +2238,9 @@ register int x, y;
#define SCROLLCNT 1 /* Get there in 3 moves... */ #define SCROLLCNT 1 /* Get there in 3 moves... */
int scrollcnt = SCROLLCNT; /* ...or 1 if we changed level */ int scrollcnt = SCROLLCNT; /* ...or 1 if we changed level */
if (!clipping) /* And 1 in anycase, cleaner, simpler, quicker */ if (!clipping) { /* And 1 in anycase, cleaner, simpler, quicker */
return; return;
}
if (Is_rogue_level(&u.uz)) { if (Is_rogue_level(&u.uz)) {
struct Window *w = amii_wins[WIN_MAP]->win; struct Window *w = amii_wins[WIN_MAP]->win;
@@ -2173,16 +2257,22 @@ register int x, y;
* reasonablely large window extra motion is avoided; for * reasonablely large window extra motion is avoided; for
* the rogue level hopefully this means no motion at all. * the rogue level hopefully this means no motion at all.
*/ */
{ if (!on_level(&u.uz, &clip_saved_level)) {
static d_level saved_level = { 127, 127 }; /* XXX */ scrollcnt = 1; /* jump with blanking */
/* Center viewport on the player for the new level. */
if (!on_level(&u.uz, &saved_level)) { clipx = max(0, x - COx / 2);
scrollcnt = 1; /* jump with blanking */ clipxmax = clipx + COx;
clipx = clipy = 0; if (clipxmax > COLNO) {
clipxmax = COx; clipxmax = COLNO;
clipymax = LIx; clipx = clipxmax - COx;
saved_level = u.uz; /* save as new current level */
} }
clipy = max(0, y - LIx / 2);
clipymax = clipy + LIx;
if (clipymax > ROWNO) {
clipymax = ROWNO;
clipy = clipymax - LIx;
}
clip_saved_level = u.uz; /* save as new current level */
} }
if (x <= clipx + xclipbord) { if (x <= clipx + xclipbord) {
@@ -2204,13 +2294,12 @@ register int x, y;
reclip = 1; reclip = 1;
if (clipx != oldx || clipy != oldy || clipxmax != oldxmax if (clipx != oldx || clipy != oldy || clipxmax != oldxmax
|| clipymax != oldymax) { || clipymax != oldymax) {
#ifndef NOSCROLLRASTER
struct Window *w = amii_wins[WIN_MAP]->win; struct Window *w = amii_wins[WIN_MAP]->win;
struct RastPort *rp = w->RPort; struct RastPort *rp = w->RPort;
int xdelta, ydelta, xmod, ymod, i; int dx = clipx - oldx;
int incx, incy, mincx, mincy; int dy = clipy - oldy;
int savex, savey, savexmax, saveymax; int scrx, scry; /* tile pixel dimensions */
int scrx, scry; int halfW, halfH; /* half viewport in tiles */
if (Is_rogue_level(&u.uz)) { if (Is_rogue_level(&u.uz)) {
scrx = rp->TxWidth; scrx = rp->TxWidth;
@@ -2220,129 +2309,63 @@ register int x, y;
scry = mysize; scry = mysize;
} }
/* Ask that the glyph routines not draw the overview window */ halfW = COx / 2;
reclip = 2; halfH = LIx / 2;
cursor_off(WIN_MAP);
/* Compute how far we are moving in terms of tiles */ /* Erase the map cursor before shifting pixels, otherwise the
mincx = clipx - oldx; old cursor position leaves a COMPLEMENT artifact on screen. */
mincy = clipy - oldy; if (WIN_MAP != WIN_ERR)
cursor_off(WIN_MAP);
/* How many tiles to get there in SCROLLCNT moves */ /* Large jumps (teleport, level change): just redraw everything. */
incx = (clipx - oldx) / scrollcnt; if (abs(dx) > halfW || abs(dy) > halfH
incy = (clipy - oldy) / scrollcnt; || scrollcnt != SCROLLCNT) {
{
/* If less than SCROLLCNT tiles, then move by 1 tile if moving at all int savedAPen = rp->FgPen;
*/ int savedDrMd = rp->DrawMode;
if (incx == 0) SetAPen(rp, amii_otherBPen);
incx = (mincx != 0); SetDrMd(rp, JAM1);
if (incy == 0) RectFill(rp, w->BorderLeft, w->BorderTop,
incy = (mincy != 0); w->Width - w->BorderRight - 1,
w->Height - w->BorderBottom - 1);
/* Get count of pixels to move each iteration and final pixel count */ SetAPen(rp, savedAPen);
xdelta = ((clipx - oldx) * scrx) / scrollcnt; SetDrMd(rp, savedDrMd);
xmod = ((clipx - oldx) * scrx) % scrollcnt;
ydelta = ((clipy - oldy) * scry) / scrollcnt;
ymod = ((clipy - oldy) * scry) % scrollcnt;
/* Preserve the final move location */
savex = clipx;
savey = clipy;
saveymax = clipymax;
savexmax = clipxmax;
/*
* Set clipping rectangle to be just the region that will be exposed so
* that drawing will be faster
*/
#if 0 /* Doesn't seem to work quite the way it should */
/* In some cases hero is 'centered' offscreen */
if( xdelta < 0 )
{
clipx = oldx;
clipxmax = clipx + incx;
}
else if( xdelta > 0 )
{
clipxmax = oldxmax;
clipx = clipxmax - incx;
}
else
{
clipx = oldx;
clipxmax = oldxmax;
}
if( ydelta < 0 )
{
clipy = oldy;
clipymax = clipy + incy;
}
else if( ydelta > 0 )
{
clipymax = oldymax;
clipy = clipymax - incy;
}
else
{
clipy = oldy;
clipymax = oldymax;
}
#endif
/* Now, in scrollcnt moves, move the picture toward the final view */
for (i = 0; i < scrollcnt; ++i) {
#ifdef DISPMAP
if (i == scrollcnt - 1 && (xmod != 0 || ymod != 0)
&& (xdelta != 0 || ydelta != 0)) {
incx += (clipx - oldx) % scrollcnt;
incy += (clipy - oldy) % scrollcnt;
xdelta += xmod;
ydelta += ymod;
} }
#endif redraw_map(FALSE);
/* Scroll the raster if we are scrolling */ } else {
if (xdelta != 0 || ydelta != 0) { /* Flush pending glyphs — they reference old clip coords */
ScrollRaster(rp, xdelta, ydelta, w->BorderLeft, w->BorderTop, flush_glyph_buffer(w);
w->Width - w->BorderRight - 1,
w->Height - w->BorderBottom - 1);
if (mincx == 0) /* Hardware-blit the viewport by the scroll delta */
incx = 0; ScrollRaster(rp, dx * scrx, dy * scry,
else w->BorderLeft, w->BorderTop,
mincx -= incx; w->Width - w->BorderRight - 1,
w->Height - w->BorderBottom - 1);
clipx += incx; /* Redraw only the exposed strip(s) */
clipxmax += incx; if (dx > 0)
redraw_map_region(clipxmax - dx, clipy,
clipxmax, clipymax - 1);
else if (dx < 0)
redraw_map_region(clipx, clipy,
clipx - dx, clipymax - 1);
if (mincy == 0) if (dy > 0)
incy = 0; redraw_map_region(clipx, clipymax - dy,
else clipxmax, clipymax - 1);
mincy -= incy; else if (dy < 0)
redraw_map_region(clipx, clipy,
clipxmax, clipy - dy - 1);
clipy += incy; flush_glyph_buffer(w);
clipymax += incy;
/* Draw the exposed portion */
redraw_map();
flush_glyph_buffer(amii_wins[WIN_MAP]->win);
}
} }
clipx = savex;
clipy = savey;
clipymax = saveymax;
clipxmax = savexmax;
#endif
redraw_map();
flush_glyph_buffer(amii_wins[WIN_MAP]->win);
} }
reclip = 0; reclip = 0;
#endif #endif
} }
void void
flushIDCMP(port) flushIDCMP(struct MsgPort *port)
struct MsgPort *port;
{ {
struct Message *msg; struct Message *msg;
while (msg = GetMsg(port)) while (msg = GetMsg(port))

View File

@@ -12,12 +12,14 @@
#include "winproto.h" #include "winproto.h"
#endif #endif
amii_nh_poskey(x, y, mod) int *x, *y, *mod; int
amii_nh_poskey(coordxy *x, coordxy *y, int *mod)
{ {
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
WETYPE type; WETYPE type;
struct RastPort *rp; struct RastPort *rp;
struct Window *w; struct Window *w;
/* No entry log for nh_poskey -- too noisy (called constantly) */
if (cw = amii_wins[WIN_MESSAGE]) { if (cw = amii_wins[WIN_MESSAGE]) {
cw->wflags &= ~FLMAP_SKIP; cw->wflags &= ~FLMAP_SKIP;
@@ -59,10 +61,11 @@ amii_nh_poskey(x, y, mod) int *x, *y, *mod;
} }
int int
amii_nhgetch() amii_nhgetch(void)
{ {
int ch; int ch;
struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE]; struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE];
/* No entry log for nhgetch -- too noisy (called constantly) */
if (WIN_MAP != WIN_ERR && amii_wins[WIN_MAP]) { if (WIN_MAP != WIN_ERR && amii_wins[WIN_MAP]) {
cursor_on(WIN_MAP); cursor_on(WIN_MAP);
@@ -75,15 +78,15 @@ amii_nhgetch()
} }
void void
amii_get_nh_event() amii_get_nh_event(void)
{ {
/* nothing now - later I have no idea. Is this just a Mac hook? */ /* nothing now - later I have no idea. Is this just a Mac hook? */
} }
void void
amii_getret() amii_getret(void)
{ {
register int c; int c;
raw_print(""); raw_print("");
raw_print("Press Return..."); raw_print("Press Return...");

View File

@@ -8,10 +8,9 @@ void EditClipping(void);
void DrawCol(struct Window *w, int idx, UWORD *colors); void DrawCol(struct Window *w, int idx, UWORD *colors);
void DispCol(struct Window *w, int idx, UWORD *colors); void DispCol(struct Window *w, int idx, UWORD *colors);
void amii_change_color(int, long, int); void amii_change_color(int, long, int);
char *amii_get_color_string(); char *amii_get_color_string(void);
void amii_getlin(const char *prompt, char *bufp); void amii_getlin(const char *prompt, char *bufp);
void getlind(const char *prompt, char *bufp, const char *dflt); void getlind(const char *prompt, char *bufp, const char *dflt);
char *amii_get_color_string(void);
int filecopy(char *from, char *to); int filecopy(char *from, char *to);
char *basename(char *str); char *basename(char *str);
char *dirname(char *str); char *dirname(char *str);
@@ -33,15 +32,15 @@ void amii_scrollmsg(register struct Window *w,
register struct amii_WinDesc *cw); register struct amii_WinDesc *cw);
/* winkey.c */ /* winkey.c */
int amii_nh_poskey(int *x, int *y, int *mod); int amii_nh_poskey(coordxy *x, coordxy *y, int *mod);
int amii_nhgetch(void); int amii_nhgetch(void);
void amii_get_nh_event(void); void amii_get_nh_event(void);
void amii_getret(void); void amii_getret(void);
/* winmenu.c */ /* winmenu.c */
void amii_start_menu(winid window, unsigned long); void amii_start_menu(winid window, unsigned long);
void amii_add_menu(winid, int, const anything *, CHAR_P, CHAR_P, int, void amii_add_menu(winid, const glyph_info *, const anything *, CHAR_P, CHAR_P,
const char *, unsigned int); int, int, const char *, unsigned int);
void amii_end_menu(winid, const char *); void amii_end_menu(winid, const char *);
int amii_select_menu(winid, int, menu_item **); int amii_select_menu(winid, int, menu_item **);
int DoMenuScroll(int win, int blocking, int how, menu_item **); int DoMenuScroll(int win, int blocking, int how, menu_item **);
@@ -55,7 +54,6 @@ struct Window *OpenShWindow(struct NewWindow *nw);
void CloseShWindow(struct Window *win); void CloseShWindow(struct Window *win);
int ConvertKey(struct IntuiMessage *message); int ConvertKey(struct IntuiMessage *message);
int kbhit(void); int kbhit(void);
int kbhit(void);
int amikbhit(void); int amikbhit(void);
int WindowGetchar(void); int WindowGetchar(void);
WETYPE WindowGetevent(void); WETYPE WindowGetevent(void);
@@ -101,19 +99,19 @@ void amii_resume_nhwindows(void);
void amii_bell(void); void amii_bell(void);
void removetopl(int cnt); void removetopl(int cnt);
void port_help(void); void port_help(void);
void amii_print_glyph(winid win, coordxy x, coordxy y, int glyph, int bkglyph); void amii_print_glyph(winid win, coordxy x, coordxy y, const glyph_info *glyphinfo, const glyph_info *bkglyphinfo);
void amii_raw_print(const char *s); void amii_raw_print(const char *s);
void amii_raw_print_bold(const char *s); void amii_raw_print_bold(const char *s);
void amii_update_inventory(void); void amii_update_inventory(int);
void amii_mark_synch(void); void amii_mark_synch(void);
void amii_wait_synch(void); void amii_wait_synch(void);
void amii_setclipped(void); void amii_setclipped(void);
void amii_cliparound(int x, int y); void amii_cliparound(int x, int y);
void amii_set_text_font(char *font, int size); void amii_set_text_font(char *font, int size);
BitMapHeader ReadImageFiles(char **, struct BitMap **, char **); BitMapHeader ReadImageFile(const char *, struct BitMap **);
void FreeImageFile(struct BitMap **);
BitMapHeader ReadTileImageFiles(void); BitMapHeader ReadTileImageFiles(void);
void FreeImageFiles(char **, struct BitMap **); void FreeTileImageFiles(void);
void FreeTileImageFiles();
/* winami.c */ /* winami.c */
#ifdef SHAREDLIB #ifdef SHAREDLIB
@@ -124,12 +122,10 @@ void amii_askname(void);
void amii_player_selection(void); void amii_player_selection(void);
void RandomWindow(char *name); void RandomWindow(char *name);
int amii_get_ext_cmd(void); int amii_get_ext_cmd(void);
char amii_yn_function(const char *prompt, const char *resp, char def);
char amii_yn_function(const char *query, const char *resp, char def); char amii_yn_function(const char *query, const char *resp, char def);
void amii_display_file(const char *fn, boolean complain); void amii_display_file(const char *fn, boolean complain);
void SetBorder(struct Gadget *gd); void SetBorder(struct Gadget *gd);
void *malloc(register unsigned size); /* malloc/free provided by stdlib.h */
void free(void *q);
#ifdef SHAREDLIB #ifdef SHAREDLIB
/* amilib.c */ /* amilib.c */
@@ -141,6 +137,8 @@ void setup_librefs(WinamiBASE *base);
void Abort(long rc); void Abort(long rc);
#endif #endif
win_request_info *amii_ctrl_nhwindow(winid, int, win_request_info *);
/* amirip.c */ /* amirip.c */
void amii_outrip(winid tmpwin, int how, time_t when); void amii_outrip(winid tmpwin, int how, time_t when);
@@ -151,4 +149,3 @@ int GlyphToIcon(int glyph);
void dispmap_sanity(void); void dispmap_sanity(void);
int dispmap_sanity1(int); int dispmap_sanity1(int);
#endif #endif
void FreeTileImageFiles(void);

View File

@@ -67,16 +67,16 @@ struct NewWindow StrWindow = {
void ClearCol(struct Window *w); void ClearCol(struct Window *w);
void void
EditColor() EditColor(void)
{ {
extern char configfile[]; const char *configfile = get_configfile();
int i, done = 0, okay = 0; int i, done = 0, okay = 0;
long code, qual, class; long code, qual, class;
register struct Gadget *gd, *dgad; struct Gadget *gd, *dgad;
register struct Window *nw; struct Window *nw;
register struct IntuiMessage *imsg; struct IntuiMessage *imsg;
register struct PropInfo *pip; struct PropInfo *pip;
register struct Screen *scrn; struct Screen *scrn;
long aidx; long aidx;
int msx, msy; int msx, msy;
int curcol = 0, drag = 0; int curcol = 0, drag = 0;
@@ -128,11 +128,7 @@ EditColor()
#ifdef INTUI_NEW_LOOK #ifdef INTUI_NEW_LOOK
Col_NewWindowStructure1.Extension = wintags; Col_NewWindowStructure1.Extension = wintags;
Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
#ifdef __GNUC__
fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Entry = (void *) &LayerFillHook;
#else
fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
fillhook.h_Data = (void *) -2; fillhook.h_Data = (void *) -2;
fillhook.h_SubEntry = 0; fillhook.h_SubEntry = 0;
#endif #endif
@@ -248,7 +244,7 @@ EditColor()
for (i = 0; i < amii_numcolors; ++i) { for (i = 0; i < amii_numcolors; ++i) {
fprintf(nfp, "%03x", colors[i]); fprintf(nfp, "%03x", colors[i]);
if ((i + 1) < amii_numcolors) if ((i + 1) < amii_numcolors)
putc(',', nfp); putc('/', nfp);
} }
putc('\n', nfp); putc('\n', nfp);
} }
@@ -356,11 +352,11 @@ EditClipping(void)
char buf[40]; char buf[40];
int done = 0, okay = 0; int done = 0, okay = 0;
long code, qual, class; long code, qual, class;
register struct Gadget *gd, *dgad; struct Gadget *gd, *dgad;
register struct Window *nw; struct Window *nw;
register struct IntuiMessage *imsg; struct IntuiMessage *imsg;
register struct PropInfo *pip; struct PropInfo *pip;
register struct Screen *scrn; struct Screen *scrn;
long aidx; long aidx;
int lmxsize = mxsize, lmysize = mysize; int lmxsize = mxsize, lmysize = mysize;
int lxclipbord = xclipbord, lyclipbord = yclipbord; int lxclipbord = xclipbord, lyclipbord = yclipbord;
@@ -388,11 +384,7 @@ EditClipping(void)
#ifdef INTUI_NEW_LOOK #ifdef INTUI_NEW_LOOK
ClipNewWindowStructure1.Extension = wintags; ClipNewWindowStructure1.Extension = wintags;
ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED; ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
#ifdef __GNUC__
fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Entry = (void *) &LayerFillHook;
#else
fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
fillhook.h_Data = (void *) -2; fillhook.h_Data = (void *) -2;
fillhook.h_SubEntry = 0; fillhook.h_SubEntry = 0;
#endif #endif
@@ -546,8 +538,7 @@ EditClipping(void)
} }
char * char *
dirname(str) dirname(char *str)
char *str;
{ {
char *t, c; char *t, c;
static char dir[300]; static char dir[300];
@@ -555,9 +546,9 @@ char *str;
t = strrchr(str, '/'); t = strrchr(str, '/');
if (!t) if (!t)
t = strrchr(str, ':'); t = strrchr(str, ':');
if (!t) if (!t) {
t = str; dir[0] = '\0';
else { } else {
c = *t; c = *t;
*t = 0; *t = 0;
strcpy(dir, str); strcpy(dir, str);
@@ -567,8 +558,7 @@ char *str;
} }
char * char *
basename(str) basename(char *str)
char *str;
{ {
char *t; char *t;
@@ -582,7 +572,8 @@ char *str;
return (t); return (t);
} }
filecopy(from, to) char *from, *to; int
filecopy(char *from, char *to)
{ {
char *buf; char *buf;
int i = 0; int i = 0;
@@ -606,7 +597,7 @@ filecopy(from, to) char *from, *to;
} }
/* The colornames, and the default values for the pens */ /* The colornames, and the default values for the pens */
static struct COLDEF { struct COLDEF {
char *name, *defval; char *name, *defval;
}; };
struct COLDEF amii_colnames[AMII_MAXCOLORS] = { struct COLDEF amii_colnames[AMII_MAXCOLORS] = {
@@ -657,10 +648,7 @@ ClearCol(struct Window *w)
} }
void void
DrawCol(w, idx, colors) DrawCol(struct Window *w, int idx, UWORD *colors)
struct Window *w;
int idx;
UWORD *colors;
{ {
int bxorx, bxory, bxxlen, bxylen; int bxorx, bxory, bxxlen, bxylen;
int i, incx, incy, r, g, b; int i, incx, incy, r, g, b;
@@ -742,10 +730,7 @@ UWORD *colors;
} }
void void
DispCol(w, idx, colors) DispCol(struct Window *w, int idx, UWORD *colors)
struct Window *w;
int idx;
UWORD *colors;
{ {
char buf[50]; char buf[50];
char *colname, *defval; char *colname, *defval;
@@ -824,26 +809,21 @@ amii_setpens(int count)
/* Generate a requester for a string value. */ /* Generate a requester for a string value. */
void void
amii_getlin(prompt, bufp) amii_getlin(const char *prompt, char *bufp)
const char *prompt;
char *bufp;
{ {
getlind(prompt, bufp, 0); getlind(prompt, bufp, 0);
} }
/* and with default */ /* and with default */
void void
getlind(prompt, bufp, dflt) getlind(const char *prompt, char *bufp, const char *dflt)
const char *prompt;
char *bufp;
const char *dflt;
{ {
#ifndef TOPL_GETLINE #ifndef TOPL_GETLINE
register struct Window *cwin; struct Window *cwin;
register struct IntuiMessage *imsg; struct IntuiMessage *imsg;
register long class, code, qual; long class, code, qual;
register int aredone = 0; int aredone = 0;
register struct Gadget *gd; struct Gadget *gd;
static int once; static int once;
*StrString = 0; *StrString = 0;
@@ -872,11 +852,7 @@ const char *dflt;
#ifdef INTUI_NEW_LOOK #ifdef INTUI_NEW_LOOK
StrWindow.Extension = wintags; StrWindow.Extension = wintags;
StrWindow.Flags |= WFLG_NW_EXTENDED; StrWindow.Flags |= WFLG_NW_EXTENDED;
#ifdef __GNUC__
fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Entry = (void *) &LayerFillHook;
#else
fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
fillhook.h_Data = (void *) -2; fillhook.h_Data = (void *) -2;
fillhook.h_SubEntry = 0; fillhook.h_SubEntry = 0;
#endif #endif
@@ -1006,9 +982,7 @@ const char *dflt;
} }
void void
amii_change_color(pen, val, rev) amii_change_color(int pen, long val, int rev)
int pen, rev;
long val;
{ {
if (rev) if (rev)
sysflags.amii_curmap[pen] = ~val; sysflags.amii_curmap[pen] = ~val;
@@ -1020,12 +994,13 @@ long val;
} }
char * char *
amii_get_color_string() amii_get_color_string(void)
{ {
int i; int i;
char s[10]; char s[10];
static char buf[BUFSZ]; static char buf[BUFSZ];
*buf = 0; *buf = 0;
for (i = 0; i < min(32, amii_numcolors); ++i) { for (i = 0; i < min(32, amii_numcolors); ++i) {
sprintf(s, "%s%03lx", i ? "/" : "", (long) sysflags.amii_curmap[i]); sprintf(s, "%s%03lx", i ? "/" : "", (long) sysflags.amii_curmap[i]);

View File

@@ -14,10 +14,7 @@
/* Put a string into the indicated window using the indicated attribute */ /* Put a string into the indicated window using the indicated attribute */
void void
amii_putstr(window, attr, str) amii_putstr(winid window, int attr, const char *str)
winid window;
int attr;
const char *str;
{ {
int fudge; int fudge;
int len; int len;
@@ -27,6 +24,7 @@ const char *str;
int i, j, n0, bottom, totalvis, wheight; int i, j, n0, bottom, totalvis, wheight;
static int wrapping = 0; static int wrapping = 0;
/* Always try to avoid a panic when there is no window */ /* Always try to avoid a panic when there is no window */
if (window == WIN_ERR) { if (window == WIN_ERR) {
window = WIN_BASE; window = WIN_BASE;
@@ -101,13 +99,13 @@ const char *str;
memcpy(cw->data, &cw->data[1], memcpy(cw->data, &cw->data[1],
(iflags.msg_history - 1) * sizeof(char *)); (iflags.msg_history - 1) * sizeof(char *));
cw->data[iflags.msg_history - 1] = cw->data[iflags.msg_history - 1] =
(char *) alloc(strlen(gt.toplines) + 5); (char *) alloc(strlen(gt.toplines) + SOFF + 4);
strcpy(cw->data[i = iflags.msg_history - 1] + SOFF strcpy(cw->data[i = iflags.msg_history - 1] + SOFF
+ (scrollmsg != 0), + (scrollmsg != 0),
gt.toplines); gt.toplines);
} else { } else {
/* Otherwise, allocate a new one and copy the line in */ /* Otherwise, allocate a new one and copy the line in */
cw->data[cw->maxrow] = (char *) alloc(strlen(gt.toplines) + 5); cw->data[cw->maxrow] = (char *) alloc(strlen(gt.toplines) + SOFF + 4);
strcpy(cw->data[i = cw->maxrow++] + SOFF + (scrollmsg != 0), strcpy(cw->data[i = cw->maxrow++] + SOFF + (scrollmsg != 0),
gt.toplines); gt.toplines);
} }
@@ -196,7 +194,10 @@ const char *str;
/* Display when beam at top to avoid flicker... */ /* Display when beam at top to avoid flicker... */
WaitTOF(); WaitTOF();
Text(w->RPort, (char *) str, strlen((char *) str)); { int slen = strlen((char *) str);
if (slen > cw->cols) slen = cw->cols;
Text(w->RPort, (char *) str, slen);
}
if (cw->cols > strlen(str)) if (cw->cols > strlen(str))
TextSpaces(w->RPort, cw->cols - strlen(str)); TextSpaces(w->RPort, cw->cols - strlen(str));
@@ -286,9 +287,7 @@ const char *str;
} }
void void
amii_scrollmsg(w, cw) amii_scrollmsg(struct Window *w, struct amii_WinDesc *cw)
register struct Window *w;
register struct amii_WinDesc *cw;
{ {
int bottom, wheight; int bottom, wheight;
@@ -311,8 +310,7 @@ register struct amii_WinDesc *cw;
} }
int int
amii_msgborder(w) amii_msgborder(struct Window *w)
struct Window *w;
{ {
register int bottom; register int bottom;
@@ -325,8 +323,7 @@ struct Window *w;
} }
void void
outmore(cw) outmore(struct amii_WinDesc *cw)
register struct amii_WinDesc *cw;
{ {
struct Window *w = cw->win; struct Window *w = cw->win;
@@ -359,11 +356,7 @@ register struct amii_WinDesc *cw;
} }
void void
outsubstr(cw, str, len, fudge) outsubstr(struct amii_WinDesc *cw, char *str, int len, int fudge)
register struct amii_WinDesc *cw;
char *str;
int len;
int fudge;
{ {
struct Window *w = cw->win; struct Window *w = cw->win;
@@ -387,10 +380,7 @@ int fudge;
/* Put a graphics character onto the screen */ /* Put a graphics character onto the screen */
void void
amii_putsym(st, i, y, c) amii_putsym(winid st, int i, int y, CHAR_P c)
winid st;
int i, y;
CHAR_P c;
{ {
amii_curs(st, i, y); amii_curs(st, i, y);
Text(amii_wins[st]->win->RPort, &c, 1); Text(amii_wins[st]->win->RPort, &c, 1);
@@ -399,8 +389,7 @@ CHAR_P c;
/* Add to the last line in the message window */ /* Add to the last line in the message window */
void void
amii_addtopl(s) amii_addtopl(const char *s)
const char *s;
{ {
register struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE]; register struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE];
@@ -413,9 +402,7 @@ const char *s;
} }
void void
TextSpaces(rp, nr) TextSpaces(struct RastPort *rp, int nr)
struct RastPort *rp;
int nr;
{ {
if (nr < 1) if (nr < 1)
return; return;
@@ -429,7 +416,7 @@ int nr;
} }
void void
amii_remember_topl() amii_remember_topl(void)
{ {
/* ignore for now. I think this will be done automatically by /* ignore for now. I think this will be done automatically by
* the code writing to the message window, but I could be wrong. * the code writing to the message window, but I could be wrong.
@@ -437,12 +424,13 @@ amii_remember_topl()
} }
int int
amii_doprev_message() amii_doprev_message(void)
{ {
struct amii_WinDesc *cw; struct amii_WinDesc *cw;
struct Window *w; struct Window *w;
char *str; char *str;
if (WIN_MESSAGE == WIN_ERR || (cw = amii_wins[WIN_MESSAGE]) == NULL if (WIN_MESSAGE == WIN_ERR || (cw = amii_wins[WIN_MESSAGE]) == NULL
|| (w = cw->win) == NULL) { || (w = cw->win) == NULL) {
panic(winpanicstr, WIN_MESSAGE, "doprev_message"); panic(winpanicstr, WIN_MESSAGE, "doprev_message");

View File

@@ -128,6 +128,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
choose_windows(DEFAULT_WINDOW_SYS); choose_windows(DEFAULT_WINDOW_SYS);
#if !defined(AMIGA) && !defined(GNUDOS) #if !defined(AMIGA) && !defined(GNUDOS)
/* Save current directory and make sure it gets restored when /* Save current directory and make sure it gets restored when
* the game is exited. * the game is exited.
@@ -147,6 +148,10 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
if (dir == (char *) 0) if (dir == (char *) 0)
dir = exepath(argv[0]); dir = exepath(argv[0]);
#endif #endif
#if defined(AMIGA) && defined(HACKDIR)
if (dir == (char *) 0)
dir = HACKDIR;
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
if (IsDebuggerPresent()) { if (IsDebuggerPresent()) {
static char exepath[_MAX_PATH]; static char exepath[_MAX_PATH];

View File

@@ -229,6 +229,76 @@ mipspkg: dodata $(GAMEBIN) $(TARGETPFX)recover
@echo MIPS package zip file $(TARGETPFX)nh370mips.zip @echo MIPS package zip file $(TARGETPFX)nh370mips.zip
endif # CROSS_TO_MIPS endif # CROSS_TO_MIPS
ifdef CROSS_TO_AMIGA
$(TARGETPFX)amidos.o : ../sys/amiga/amidos.c $(HACK_H)
$(TARGETPFX)amigst.o : ../sys/amiga/amigst.c $(HACK_H)
$(TARGETPFX)amirip.o : ../sys/amiga/amirip.c $(HACK_H)
$(TARGETPFX)amistack.o : ../sys/amiga/amistack.c $(HACK_H)
$(TARGETPFX)amitty.o : ../sys/amiga/amitty.c $(HACK_H)
$(TARGETPFX)amiwind.o : ../sys/amiga/amiwind.c \
../sys/amiga/amimenu.c $(HACK_H)
$(TARGETPFX)winami.o : ../sys/amiga/winami.c $(HACK_H)
$(TARGETPFX)winchar.o : ../sys/amiga/winchar.c tile.c $(HACK_H)
$(TARGETPFX)winfuncs.o : ../sys/amiga/winfuncs.c $(HACK_H)
$(TARGETPFX)winkey.o : ../sys/amiga/winkey.c $(HACK_H)
$(TARGETPFX)winamenu.o : ../sys/amiga/winamenu.c $(HACK_H)
$(TARGETPFX)winreq.o : ../sys/amiga/winreq.c \
../sys/amiga/colorwin.c \
../sys/amiga/clipwin.c $(HACK_H)
$(TARGETPFX)winstr.o : ../sys/amiga/winstr.c $(HACK_H)
$(GAMEBIN) : $(HOBJ) $(LUACROSSLIB)
$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \
$(HOBJ) $(WINLIB) $(TARGET_LIBS)
#
# Host-side IFF tile conversion tools (run on Linux, produce Amiga IFF files)
#
AMISRC = ../sys/amiga
$(TARGETPFX)xpm2iff_host: $(AMISRC)/xpm2iff_host.c
$(CC) $(CFLAGS) -o $@ $<
$(TARGETPFX)tomb.iff: $(AMISRC)/grave16.xpm $(TARGETPFX)xpm2iff_host
$(TARGETPFX)xpm2iff_host $(AMISRC)/grave16.xpm $@
$(TARGETPFX)bmp2iff_host: $(AMISRC)/bmp2iff_host.c
$(CC) $(CFLAGS) -o $@ $<
$(TARGETPFX)tiles16.iff: ../dat/nhtiles.bmp $(TARGETPFX)bmp2iff_host
$(TARGETPFX)bmp2iff_host -planes 4 ../dat/nhtiles.bmp $@
$(TARGETPFX)tiles32.iff: ../dat/nhtiles.bmp $(TARGETPFX)bmp2iff_host
$(TARGETPFX)bmp2iff_host -planes 5 ../dat/nhtiles.bmp $@
AMITILES = $(TARGETPFX)tiles16.iff $(TARGETPFX)tiles32.iff $(TARGETPFX)tomb.iff
.PHONY: amigapkg amitiles
amitiles: $(AMITILES)
amigapkg: $(AMITILES)
mkdir -p $(TARGETPFX)pkg/tiles $(TARGETPFX)pkg/hack
cp $(GAMEBIN) $(TARGETPFX)pkg/nethack
cp ../dat/nhdat $(TARGETPFX)pkg/nhdat
cp ../dat/license $(TARGETPFX)pkg/license
cp ../dat/symbols $(TARGETPFX)pkg/symbols
cp $(TARGETPFX)tiles16.iff $(TARGETPFX)pkg/tiles/tiles16.iff
cp $(TARGETPFX)tiles32.iff $(TARGETPFX)pkg/tiles/tiles32.iff
cp $(TARGETPFX)tomb.iff $(TARGETPFX)pkg/tomb.iff
cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf
cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt
( cd $(TARGETPFX)pkg && uudecode ../../../sys/amiga/amifont8.uu && mv 8 hack/8 )
( cd $(TARGETPFX)pkg && uudecode ../../../sys/amiga/amifont.uu )
cp $(AMISRC)/nethack.cnf $(TARGETPFX)pkg/nethack.cnf
-( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/dflticon.uu && \
uudecode ../../../sys/amiga/dflticon.uu )
-( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/NHinfo.uu && \
uudecode ../../../sys/amiga/NHinfo.uu )
-( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/NewGame.uu && \
uudecode ../../../sys/amiga/NewGame.uu )
-( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/HackWB.uu && \
uudecode ../../../sys/amiga/HackWB.uu )
touch $(TARGETPFX)pkg/record
( cd $(TARGETPFX)pkg && zip -9r ../NH370AMI.ZIP * )
@echo amiga package zip file $(TARGETPFX)NH370AMI.ZIP
endif # CROSS_TO_AMIGA
ifdef CROSS_SHARED ifdef CROSS_SHARED
# shared file dependencies # shared file dependencies
$(TARGETPFX)pcmain.o : ../sys/share/pcmain.c $(HACK_H) $(TARGETPFX)pcmain.o : ../sys/share/pcmain.c $(HACK_H)

View File

@@ -38,6 +38,16 @@ override TARGETPFX = $(TARGETDIR)/
override TARGET_LIBS= override TARGET_LIBS=
endif endif
ifdef CROSS_TO_AMIGA
CROSS=1
BUILD_TARGET_LUA=1
CROSS_SHARED=1
override TARGET = amiga
override TARGETDIR=../targets/$(TARGET)
override TARGETPFX = $(TARGETDIR)/
override TARGET_LIBS=
endif
ifdef CROSS ifdef CROSS
override PREGAME= override PREGAME=
override BUILDMORE= override BUILDMORE=

View File

@@ -460,6 +460,96 @@ NCURSES_PLATFORM=MIPS
endif # CROSS_TO_MIPS endif # CROSS_TO_MIPS
#================================================================= #=================================================================
#=================================================================
ifdef CROSS_TO_AMIGA
#===============-=================================================
# AmigaOS m68k cross-compile recipe
#===============-=================================================
# Uses an Amiga M68K cross-compiler on linux or macOS.
#
# Cross-compiler: https://franke.ms/git/bebbo/amiga-gcc
# Install to /opt/amiga, then:
# make fetch-lua
# sys/unix/setup.sh sys/unix/hints/linux.370
# make CROSS_TO_AMIGA=1 all
# make CROSS_TO_AMIGA=1 package
#=================================================================
CFLAGS += -DCROSSCOMPILE
#
# Override the build tools and some obj files to
# reflect the amiga-gcc cross-compiler.
#
TOOLTOP = /opt/amiga/bin
TOOLARCH = -m68000
override REGEXOBJ = $(TARGETPFX)posixregex.o
AMIREGEXOBJ = $(TARGETPFX)regcomp.o $(TARGETPFX)regexec.o \
$(TARGETPFX)regerror.o $(TARGETPFX)regfree.o
override TARGET_CC = $(TOOLTOP)/m68k-amigaos-gcc
override TARGET_CXX = $(TOOLTOP)/m68k-amigaos-c++
override TARGET_AR = $(TOOLTOP)/m68k-amigaos-ar
override TARGET_STUBEDIT=
override TARGET_CFLAGS = -c -O2 -noixemul $(TOOLARCH) \
-include sys/types.h \
-I../include \
-I../sys/amiga -I../win/share \
$(LUAINCL) -DAMIGA -DNOTTYGRAPHICS -DNO_TERMS -DNO_SIGNAL \
-DTILES_IN_GLYPHMAP $(PDCURSESDEF) \
-DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_AMIGA \
-DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0"\"
override TARGET_CXXFLAGS = $(TARGET_CFLAGS)
LUA_TARGET_CFLAGS = $(TARGET_CFLAGS) -DLUA_32BITS=1
ifeq "$(REGEXOBJ)" "$(TARGETPFX)cppregex.o"
override TARGET_LINK = $(TARGET_CXX)
else
override TARGET_LINK = $(TARGET_CC)
endif
override TARGET_LFLAGS= $(TOOLARCH) -noixemul -Wl,--allow-multiple-definition
override TARGET_LIBS += $(LIBLM)
VARDATND += nhtiles.bmp
override SYSSRC = ../sys/amiga/amidos.c ../sys/amiga/amigst.c \
../sys/amiga/amimenu.c ../sys/amiga/amirip.c \
../sys/amiga/amistack.c ../sys/amiga/amitty.c \
../sys/amiga/amiwind.c ../sys/amiga/clipwin.c \
../sys/amiga/colorwin.c \
../sys/amiga/winami.c ../sys/amiga/winchar.c \
../sys/amiga/winfuncs.c ../sys/amiga/winkey.c \
../sys/amiga/winamenu.c ../sys/amiga/winreq.c \
../sys/amiga/winstr.c ../sys/share/pcmain.c \
../win/share/bmptiles.c ../win/share/giftiles.c \
../win/share/tileset.c
override SYSOBJ = $(TARGETPFX)amidos.o $(TARGETPFX)amigst.o \
$(TARGETPFX)amirip.o $(TARGETPFX)amistack.o \
$(TARGETPFX)amitty.o $(TARGETPFX)amiwind.o \
$(TARGETPFX)winami.o $(TARGETPFX)winchar.o \
$(TARGETPFX)winfuncs.o $(TARGETPFX)winkey.o \
$(TARGETPFX)winamenu.o $(TARGETPFX)winreq.o \
$(TARGETPFX)winstr.o $(TARGETPFX)pcmain.o \
$(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \
$(TARGETPFX)tileset.o \
$(AMIREGEXOBJ)
override WINLIB=
override LUALIB=
override LUALIBS=
override TOPLUALIB=
override DLLIB=
override WINOBJ=
override GAMEBIN = $(TARGETPFX)nethack
override PACKAGE = amigapkg
override PREGAME += mkdir -p $(TARGETDIR) ;
override CLEANMORE += rm -r $(TARGETDIR) ;
#
# Rule for files in sys/amiga
$(TARGETPFX)%.o : ../sys/amiga/%.c
$(TARGET_CC) $(TARGET_CFLAGS) -o$@ $<
# Rule for BSD regex in sys/amiga/regex
$(TARGETPFX)%.o : ../sys/amiga/regex/%.c
$(TARGET_CC) $(TARGET_CFLAGS) -I../sys/amiga/regex -o$@ $<
endif # CROSS_TO_AMIGA
#=================================================================
ifdef WANT_WIN_CURSES ifdef WANT_WIN_CURSES
ifdef BUILD_PDCURSES ifdef BUILD_PDCURSES
# Rules for PDCurses files # Rules for PDCurses files