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

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

View File

@@ -43,15 +43,15 @@ static struct RastPort *rp;
#include <proto/diskfont.h>
#endif
static char *load_list[] = { "tomb.iff", 0 };
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 */
#define TEXT_TOP (65 + yoff)
static xoff, yoff; /* image centering */
static int xoff, yoff; /* image centering */
/* terrible kludge */
/* 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;
void
amii_outrip(tmpwin, how, when)
winid tmpwin;
int how;
time_t when;
amii_outrip(winid tmpwin, int how, time_t when)
{
int just_return = 0;
int done, rtxth;
struct IntuiMessage *imsg;
int i;
register char *dpx;
char *dpx;
char buf[200];
int line, tw, ww;
char *errstr = NULL;
long year;
if (!WINVERS_AMIV || HackScreen->RastPort.BitMap->Depth < 4)
@@ -141,9 +138,7 @@ time_t when;
SetFont(rp, HackFont);
#endif
tomb_bmhd = ReadImageFiles(load_list, tbmp, &errstr);
if (errstr)
goto cleanup;
tomb_bmhd = ReadImageFile("tomb.iff", &tombimg);
if (tomb_bmhd.w > ww || tomb_bmhd.h > wh)
goto cleanup;
@@ -151,12 +146,12 @@ time_t when;
xoff = GENOFF(ww, tomb_bmhd.w);
yoff = GENOFF(wh, tomb_bmhd.h);
for (i = 0; i < SIZE(cols); i++)
cols[i] += xoff;
cols[i] = cols_base[i] + xoff;
cmap_white = search_cmap(0, 0, 0);
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);
/* Put together death description */
@@ -199,7 +194,7 @@ time_t when;
/* Put death type on stone */
for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) {
register int i, i0;
int i, i0;
char tmpchar;
if ((i0 = strlen(dpx)) > STONE_LINE_LEN) {
@@ -280,8 +275,7 @@ cleanup:
}
LoadRGB4(&HackScreen->ViewPort, sysflags.amii_curmap, amii_numcolors);
if (tbmp[0])
FreeImageFiles(load_list, tbmp);
FreeImageFile(&tombimg);
if (just_return)
return;
/* fall back to the straight-ASCII version */
@@ -289,8 +283,7 @@ cleanup:
}
static void
tomb_text(p)
char *p;
tomb_text(char *p)
{
char buf[STONE_LINE_LEN * 2];
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 $ */
/* 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. */
/*
@@ -12,10 +12,16 @@
#ifdef __SASC_60
#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

View File

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

View File

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

@@ -1,446 +0,0 @@
/* NetHack 3.6 txt2iff.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */
/* Copyright (c) 1995 by Gregg Wonderly, Naperville, Illinois */
/* NetHack may be freely redistributed. See license for details. */
#include <stdlib.h>
#include "config.h"
#include "tile.h"
#include <dos/dos.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/view.h>
#include <libraries/iffparse.h>
#include <libraries/dos.h>
#include <clib/dos_protos.h>
#include <clib/iffparse_protos.h>
#ifndef _DCC
#include <proto/exec.h>
#include <proto/iffparse.h>
#include <proto/dos.h>
#endif
void panic(const char *);
void map_colors(void);
int BestMatch(int, int, int);
extern pixval ColorMap[3][MAXCOLORMAPSIZE];
extern int colorsinmap;
/*
* WARNING:
* This program carries forth the assumption that the colormaps in all
* of the .txt files are the same. This is a bug.
*/
struct {
int Height;
int Width;
} IFFScreen;
/*
* We are using a hybrid form of our own design which we call a BMAP (for
* bitmap) form. It is an ILBM with the bitmaps already deinterleaved,
* completely uncompressed.
* This speeds the loading of the images from the games point of view because
* it
* does not have to deinterleave and uncompress them.
*/
#define ID_BMAP MAKE_ID('B', 'M', 'A', 'P') /* instead of ILBM */
#define ID_BMHD MAKE_ID('B', 'M', 'H', 'D') /* Same as ILBM */
#define ID_CAMG MAKE_ID('C', 'A', 'M', 'G') /* Same as ILBM */
#define ID_CMAP MAKE_ID('C', 'M', 'A', 'P') /* Same as ILBM */
#define ID_PDAT \
MAKE_ID('P', 'D', 'A', 'T') /* Extra data describing plane \
* size due to graphics.library \
* rounding requirements. \
*/
#define ID_PLNE MAKE_ID('P', 'L', 'N', 'E') /* The planes of the image */
#ifndef _DCC
extern
#endif
struct Library *IFFParseBase;
int nplanes;
/* BMHD from IFF documentation */
typedef struct {
UWORD w, h;
WORD x, y;
UBYTE nPlanes;
UBYTE masking;
UBYTE compression;
UBYTE reserved1;
UWORD transparentColor;
UBYTE xAspect, yAspect;
WORD pageWidth, pageHeight;
} BitMapHeader;
typedef struct {
UBYTE r, g, b;
} AmiColorMap;
pixel pixels[TILE_Y][TILE_X];
AmiColorMap *cmap;
int findcolor(register pixel *pix);
void packwritebody(pixel (*tile)[TILE_X], char **planes, int tileno);
void
error(char *str)
{
fprintf(stderr, "ERROR: %s\n", str);
}
/*
* This array maps the image colors to the amiga's first 16 colors. The
* colors
* are reordered to help with maintaining dripen settings.
*/
int colrmap[] = { 0, 6, 9, 15, 4, 10, 2, 3, 5, 11, 7, 13, 8, 1, 14, 12 };
/* How many tiles fit across and down. */
#define COLS 20
#define ROWS ((tiles + COLS - 1) / COLS)
main(int argc, char **argv)
{
int colors;
struct {
long nplanes;
long pbytes;
long across;
long down;
long npics;
long xsize;
long ysize;
} pdat;
long pbytes; /* Bytes of data in a plane */
int i, cnt;
BitMapHeader bmhd;
struct IFFHandle *iff;
long camg = HIRES | LACE;
int tiles = 0;
char **planes;
if (argc != 3) {
fprintf(stderr, "Usage: %s source destination\n", argv[0]);
exit(1);
}
#if defined(_DCC) || defined(__GNUC__)
IFFParseBase = OpenLibrary("iffparse.library", 0);
if (!IFFParseBase) {
error("unable to open iffparse.library");
exit(1);
}
#endif
/* First, count the files in the file */
if (fopen_text_file(argv[1], "r") != TRUE) {
perror(argv[1]);
return (1);
}
nplanes = 0;
i = colorsinmap - 1; /*IFFScreen.Colors - 1; */
while (i != 0) {
nplanes++;
i >>= 1;
}
planes = malloc(nplanes * sizeof(char *));
if (planes == 0) {
error("can not allocate planes pointer");
exit(1);
}
while (read_text_tile(pixels) == TRUE)
++tiles;
fclose_text_file();
IFFScreen.Width = COLS * TILE_X;
IFFScreen.Height = ROWS * TILE_Y;
pbytes = (COLS * ROWS * TILE_X + 15) / 16 * 2 * TILE_Y;
for (i = 0; i < nplanes; ++i) {
planes[i] = calloc(1, pbytes);
if (planes[i] == 0) {
error("can not allocate planes pointer");
exit(1);
}
}
/* Now, process it */
if (fopen_text_file(argv[1], "r") != TRUE) {
perror(argv[1]);
return (1);
}
iff = AllocIFF();
if (!iff) {
error("Can not allocate IFFHandle");
return (1);
}
iff->iff_Stream = Open(argv[2], MODE_NEWFILE);
if (!iff->iff_Stream) {
error("Can not open output file");
return (1);
}
InitIFFasDOS(iff);
OpenIFF(iff, IFFF_WRITE);
PushChunk(iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN);
bmhd.w = IFFScreen.Width;
bmhd.h = IFFScreen.Height;
bmhd.x = 0;
bmhd.y = 0;
bmhd.nPlanes = nplanes;
bmhd.masking = 0;
bmhd.compression = 0;
bmhd.reserved1 = 0;
bmhd.transparentColor = 0;
bmhd.xAspect = 100;
bmhd.yAspect = 100;
bmhd.pageWidth = TILE_X;
bmhd.pageHeight = TILE_Y;
PushChunk(iff, ID_BMAP, ID_BMHD, sizeof(bmhd));
WriteChunkBytes(iff, &bmhd, sizeof(bmhd));
PopChunk(iff);
PushChunk(iff, ID_BMAP, ID_CAMG, sizeof(camg));
WriteChunkBytes(iff, &camg, sizeof(camg));
PopChunk(iff);
/* We need to reorder the colors to get reasonable default pens but
* we also need to know where some of the colors are - so go find out.
*/
map_colors();
cmap = malloc((colors = (1L << nplanes)) * sizeof(AmiColorMap));
for (i = 0; i < colors; ++i) {
cmap[colrmap[i]].r = ColorMap[CM_RED][i];
cmap[colrmap[i]].g = ColorMap[CM_GREEN][i];
cmap[colrmap[i]].b = ColorMap[CM_BLUE][i];
}
PushChunk(iff, ID_BMAP, ID_CMAP, IFFSIZE_UNKNOWN);
for (i = 0; i < colors; ++i)
WriteChunkBytes(iff, &cmap[i], 3);
PopChunk(iff);
cnt = 0;
while (read_text_tile(pixels) == TRUE) {
packwritebody(pixels, planes, cnt);
if (cnt % 20 == 0)
printf("%d..", cnt);
++cnt;
fflush(stdout);
}
pdat.nplanes = nplanes;
pdat.pbytes = pbytes;
pdat.xsize = TILE_X;
pdat.ysize = TILE_Y;
pdat.across = COLS;
pdat.down = ROWS;
pdat.npics = cnt;
PushChunk(iff, ID_BMAP, ID_PDAT, IFFSIZE_UNKNOWN);
WriteChunkBytes(iff, &pdat, sizeof(pdat));
PopChunk(iff);
PushChunk(iff, ID_BMAP, ID_PLNE, IFFSIZE_UNKNOWN);
for (i = 0; i < nplanes; ++i)
WriteChunkBytes(iff, planes[i], pbytes);
PopChunk(iff);
CloseIFF(iff);
Close(iff->iff_Stream);
FreeIFF(iff);
printf("\n%d tiles converted\n", cnt);
#if defined(_DCC) || defined(__GNUC__)
CloseLibrary(IFFParseBase);
#endif
exit(0);
}
findcolor(register pixel *pix)
{
register int i;
for (i = 0; i < MAXCOLORMAPSIZE; ++i) {
if ((pix->r == ColorMap[CM_RED][i])
&& (pix->g == ColorMap[CM_GREEN][i])
&& (pix->b == ColorMap[CM_BLUE][i])) {
return (i);
}
}
return (-1);
}
void
packwritebody(pixel (*tile)[TILE_X], char **planes, int tileno)
{
register int i, j, k, col;
register char *buf;
register int across, rowbytes, xoff, yoff;
/* how many tiles fit across? */
across = COLS;
/* How many bytes per pixel row */
rowbytes = ((IFFScreen.Width + 15) / 16) * 2;
/* How many bytes to account for y distance in planes */
yoff = ((tileno / across) * TILE_Y) * rowbytes;
/* How many bytes to account for x distance in planes */
xoff = (tileno % across) * (TILE_X / 8);
/* For each row... */
for (i = 0; i < TILE_Y; ++i) {
/* For each bitplane... */
for (k = 0; k < nplanes; ++k) {
const int mask = 1l << k;
/* Go across the row */
for (j = 0; j < TILE_X; j++) {
col = findcolor(&tile[i][j]);
if (col == -1) {
error("can not convert pixel color to colormap index");
return;
}
/* Shift the colors around to have good complements and to
* know the dripen values.
*/
col = colrmap[col];
/* To top left corner of tile */
buf = planes[k] + yoff + xoff;
/*To i'th row of tile and the correct byte for the j'th
* pixel*/
buf += (i * rowbytes) + (j / 8);
/* Or in the bit for this color */
*buf |= (((col & mask) != 0) << (7 - (j % 8)));
}
}
}
}
/* #define DBG */
/* map_colors
* The incoming colormap is in arbitrary order and has arbitrary colors in
* it, but we need (some) specific colors in specific places. Find the
* colors we need and fix the mapping table to match.
*/
/* What we are aiming for: */
/* XXX was 0-7 */
#define CX_BLACK 0
#define CX_WHITE 1
#define CX_BROWN 11
#define CX_CYAN 2
#define CX_GREEN 5
#define CX_MAGENTA 10
#define CX_BLUE 4
#define CX_RED 7
/* we don't care about the rest, at least now */
/* should get: black white blue red grey greyblue ltgrey */
void
map_colors()
{
int x;
#if 1
int tmpmap[] = { 0, 2, 3, 7, 4, 5, 8, 9, 10, 11, 13, 15, 12, 1, 14, 6 };
/* still not right: gray green yellow lost somewhere? */
#else
int tmpmap[16];
int x, y;
for (x = 0; x < 16; x++)
tmpmap[x] = -1; /* set not assigned yet */
tmpmap[BestMatch(0, 0, 0)] = CX_BLACK;
tmpmap[BestMatch(255, 255, 255)] = CX_WHITE;
tmpmap[BestMatch(255, 0, 0)] = CX_RED;
tmpmap[BestMatch(0, 255, 0)] = CX_GREEN;
tmpmap[BestMatch(0, 0, 255)] = CX_BLUE;
/* clean up the rest */
for (x = 0; x < 16; x++) {
for (y = 0; y < 16; y++)
if (tmpmap[y] == x)
goto outer_cont;
for (y = 0; y < 16; y++)
if (tmpmap[y] == -1) {
tmpmap[y] = x;
break;
}
if (y == 16)
panic("too many colors?");
outer_cont:
;
}
for (x = 0; x < 16; x++)
if (tmpmap[y] == -1)
panic("lost color?");
#endif
for (x = 0; x < 16; x++) {
#ifdef DBG
printf("final: c[%d]=%d (target: %d)\n", x, tmpmap[x], colrmap[x]);
#endif
colrmap[x] = tmpmap[x];
}
}
BestMatch(r, g, b) int r, g, b;
{
int x;
int bestslot;
int bestrate = 99999999L;
for (x = 0; x < 16; x++) {
int rr = r - ColorMap[CM_RED][x];
int gg = g - ColorMap[CM_GREEN][x];
int bb = b - ColorMap[CM_BLUE][x];
int rate = rr * rr + gg * gg + bb * bb;
if (bestrate > rate) {
bestrate = rate;
bestslot = x;
}
}
#ifdef DBG
printf("map (%d,%d,%d) -> %d (error=%d)\n", r, g, b, bestslot, bestrate);
#endif
return bestslot;
}
long *
alloc(unsigned int n)
{
long *ret = malloc(n);
if (!ret) {
error("Can't allocate memory");
exit(1);
}
return (ret);
}
void
panic(const char *msg)
{
fprintf(stderr, "PANIC: %s\n", msg);
exit(1);
}

View File

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

View File

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

View File

@@ -5,10 +5,10 @@
void amii_raw_print(const char *);
void amii_raw_print_bold(const char *);
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 *);
char amii_select_menu(winid );
void amii_update_inventory (void);
void amii_update_inventory(int);
void amii_mark_synch (void);
void amii_wait_synch (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_clear_nhwindow(winid );
void amii_exit_nhwindows(const char *);
int amii_nh_poskey(int * , int * , int *);
int amii_nh_poskey(coordxy *, coordxy *, int *);
int amii_nhgetch (void);
void amii_get_nh_event (void);
void amii_remember_topl (void);
@@ -35,7 +35,7 @@ int amii_doprev_message (void);
void amii_display_nhwindow(winid , boolean );
void amii_display_file(const char * , boolean );
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 DisplayData(int , int , int );
void SetPropInfo(struct Window * , struct Gadget * , long , long , long );

View File

@@ -41,7 +41,8 @@
int main(int, char **);
struct BitMap *MyAllocBitMap(int, int, int, long);
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_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;
#define NUMTILEIMAGES 3
char *tileimages[] = {
#define TBLMONTILE 0
"NetHack:tiles/monsters.iff",
#define TBLOBJTILE 1
"NetHack:tiles/objects.iff",
#define TBLOTHTILE 2
"NetHack:tiles/other.iff", 0,
};
struct BitMap *ifftimg[NUMTILEIMAGES], *tile;
/* Single tile image file, set at runtime by amii_init_nhwindows */
char *tilefile;
struct BitMap *tileimg, *tile;
#ifdef TESTING
short pens[NUMDRIPENS] = { 8, 3, 15, 0, 15, 7, 7, 8, 0 };
@@ -146,7 +139,7 @@ main(int argc, char **argv)
x = x % IMGCOLUMNS;
dx = i % (IMGCOLUMNS * 2);
dy = i / (IMGCOLUMNS * 2);
BltBitMapRastPort(ifftimg[tbl], x * pictdata.xsize,
BltBitMapRastPort(tileimg, x * pictdata.xsize,
y * pictdata.ysize, w->RPort,
w->BorderLeft + 1 + dx * pictdata.xsize,
w->BorderTop + 1 + dy * pictdata.ysize,
@@ -176,175 +169,112 @@ main(int argc, char **argv)
CloseScreen(scr);
}
FreeImageFiles(tileimages, ifftimg);
FreeTileImageFiles();
return (0);
}
#endif
/*
* Read a single BMAP IFF file into a BitMap.
* Returns the BitMapHeader; *bmp receives the bitmap.
* Caller frees via FreeImageFile().
*/
BitMapHeader
ReadTileImageFiles()
ReadImageFile(const char *filename, struct BitMap **bmp)
{
char *errstr = NULL;
BitMapHeader ret = ReadImageFiles(tileimages, ifftimg, &errstr);
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;
BitMapHeader *bmhd, bmhds;
int j, np;
struct IFFHandle *iff;
struct StoredProperty *prop;
IFFParseBase = OpenLibrary("iffparse.library", 0L);
if (!IFFParseBase) {
*errstrp = "No iffparse.library";
return bmhds;
if (!IFFParseBase)
panic("No iffparse.library");
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);
}
}
/*
for( i = 0; filenames[i]; ++i )
memset( iffimg[i], 0, sizeof( struct BitMap ) );
*/
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;
}
/* Load PDAT if present */
prop = FindProp(iff, ID_BMAP, ID_PDAT);
if (prop)
pictdata = *(struct PDAT *) prop->sp_Data;
if (prop = FindProp(iff, ID_BMAP, ID_BMHD)) {
bmhd = (BitMapHeader *) prop->sp_Data;
} else {
FreeImageFiles(filenames, iffimg);
CloseIFF(iff);
Close(iff->iff_Stream);
FreeIFF(iff);
*errstrp = "No BMHD CHUNK in file";
return bmhds;
}
*bmp = MyAllocBitMap(bmhd->w, bmhd->h,
np, MEMF_CHIP | MEMF_CLEAR);
if (!*bmp)
panic("Can't allocate bitmap for %s", filename);
if (prop = FindProp(iff, ID_BMAP, ID_CMAP)) {
cmap = prop->sp_Data;
for (j = 0; j < (1L << bmhd->nPlanes) * 3; j += 3) {
#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;
}
for (j = 0; j < np; j++)
ReadChunkBytes(iff, (*bmp)->Planes[j],
RASSIZE(bmhd->w, bmhd->h));
if (prop = FindProp(iff, ID_BMAP, ID_PDAT)) {
struct PDAT *pp;
pp = (struct PDAT *) prop->sp_Data;
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);
}
bmhds = *bmhd;
CloseIFF(iff);
Close(iff->iff_Stream);
FreeIFF(iff);
CloseLibrary(IFFParseBase);
tile = MyAllocBitMap(pictdata.xsize, pictdata.ysize,
pictdata.nplanes + amii_extraplanes,
MEMF_CHIP | MEMF_CLEAR);
if (tile == NULL) {
FreeImageFiles(filenames, iffimg);
*errstrp = "Can't allocate tile bitmap for scaling";
return bmhds;
}
void
FreeImageFile(struct BitMap **bmp)
{
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 {
@@ -401,8 +331,7 @@ MyFreeBitMap(struct BitMap *bmp)
#ifdef TESTING
void
panic(s, a1, a2, a3, a4)
char *s;
panic(char *s, long a1, long a2, long a3, long a4)
{
printf(s, a1, a2, a3, a4);
putchar('\n');
@@ -420,24 +349,10 @@ alloc(unsigned int x)
#endif
void
FreeTileImageFiles()
FreeTileImageFiles(void)
{
FreeImageFiles(tileimages, ifftimg);
}
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);
FreeImageFile(&tileimg);
FreeImageFile(&tile);
}
#ifndef TESTING
@@ -456,8 +371,7 @@ struct amiv_glyph_node amiv_g_nodes[NUMBER_GLYPH_NODES];
static char amiv_glyph_buffer[GLYPH_BUFFER_SIZE];
void
flush_glyph_buffer(vw)
struct Window *vw;
flush_glyph_buffer(struct Window *vw)
{
if (WINVERS_AMIV)
amiv_flush_glyph_buffer(vw);
@@ -469,8 +383,7 @@ struct Window *vw;
* Routine to flush whatever is buffered
*/
void
amiv_flush_glyph_buffer(vw)
struct Window *vw;
amiv_flush_glyph_buffer(struct Window *vw)
{
#if !defined(DISPMAP) || defined(OPT_DISPMAP)
int xsize, ysize, x, y;
@@ -481,7 +394,7 @@ struct Window *vw;
struct BitMap *imgbm = 0, *bm = 0;
int i, k;
int scaling_needed;
register struct RastPort *rp = vw->RPort;
struct RastPort *rp = vw->RPort;
#endif
/* If nothing is buffered, return before we do anything */
@@ -577,7 +490,7 @@ struct Window *vw;
/* Go ahead and start dumping the stuff */
for (i = 0; i < glyph_node_index; ++i) {
/* Do it */
register int offx, offy, j;
int offx, offy, j;
struct BitMap *nodebm = amiv_g_nodes[i].bitmap;
/* Get the unclipped coordinates */
@@ -596,10 +509,10 @@ struct Window *vw;
* this code is generalized to handle any size tile
* image...
*/
memcpy(tile->Planes[j] + ((k * pictdata.ysize) / 8),
memcpy(tile->Planes[j] + k * tile->BytesPerRow,
nodebm->Planes[j] + offx + offy
+ (nodebm->BytesPerRow * k),
pictdata.ysize / 8);
pictdata.xsize / 8);
}
}
@@ -648,41 +561,30 @@ struct Window *vw;
* Glyph buffering routine. Called instead of WindowPuts().
*/
void
amiv_lprint_glyph(window, color_index, glyph)
winid window;
int color_index, glyph;
amiv_lprint_glyph(winid window, int color_index, int glyph)
{
int base;
struct amii_WinDesc *cw;
struct Window *w;
int curx;
int cury;
int tbl, icon;
register int xoff, yoff;
int icon;
int xoff, yoff;
/* Get the real icon index */
if (glyph != NO_GLYPH)
icon = GlyphToIcon(glyph);
/* Skip NO_GLYPH — nothing to draw */
if (glyph == NO_GLYPH)
return;
icon = GlyphToIcon(glyph);
if ((cw = amii_wins[window]) == (struct amii_WinDesc *) NULL)
panic("bad winid in amiv_lprint_glyph: %d", window);
w = cw->win;
if (glyph != NO_GLYPH && glyph < 10000) {
/* decide on which image has the needed picture */
if (icon <= MAXMONTILE) {
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);
if (glyph < 10000) {
if (icon >= pictdata.npics)
icon = 0; /* fallback for out-of-range */
/* 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].srcx = xoff;
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;
} else {
/* Do it */
register int j, k, x, y, apen;
int j, k, x, y, apen;
struct RastPort *rp = w->RPort;
x = rp->cp_x - pictdata.xsize - 3;
#ifdef OPT_DISPMAP
@@ -770,17 +672,17 @@ int color_index, glyph;
y = rp->cp_y - pictdata.ysize + 1;
if (glyph != NO_GLYPH) {
struct BitMap *bm = ifftimg[tbl];
struct BitMap *bm = tileimg;
/* 8 bits per byte */
xoff /= 8;
yoff *= bm->BytesPerRow;
for (j = 0; j < pictdata.nplanes; ++j) {
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->BytesPerRow * k),
pictdata.ysize / 8);
pictdata.xsize / 8);
}
}
@@ -824,8 +726,7 @@ static int usecolor;
*/
void
amiv_start_glyphout(window)
winid window;
amiv_start_glyphout(winid window)
{
struct amii_WinDesc *cw;
struct Window *w;
@@ -860,8 +761,7 @@ winid window;
* General cleanup routine -- flushes and restores cursor
*/
void
amii_end_glyphout(window)
winid window;
amii_end_glyphout(winid window)
{
struct amii_WinDesc *cw;
struct Window *w;
@@ -891,7 +791,7 @@ winid window;
Move(w->RPort, xsave, ysave);
}
static maze_type = COL_MAZE_BRICK;
static int maze_type = COL_MAZE_BRICK;
void
SetMazeType(MazeType t)
@@ -987,11 +887,10 @@ int backg[AMII_MAXCOLORS] = {
* Routine to simply flush whatever is buffered
*/
void
amii_flush_glyph_buffer(w)
struct Window *w;
amii_flush_glyph_buffer(struct Window *w)
{
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 (glyph_node_index == 0)
@@ -1013,6 +912,10 @@ struct Window *w;
+ rp->TxBaseline + 1;
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(rp, (long) x, (long) y);
@@ -1029,9 +932,7 @@ struct Window *w;
glyph_node_index = glyph_buffer_index = 0;
}
void
amiga_print_glyph(window, color_index, glyph)
winid window;
int color_index, glyph;
amiga_print_glyph(winid window, int color_index, int glyph)
{
if (WINVERS_AMIV)
amiv_lprint_glyph(window, color_index, glyph);
@@ -1043,9 +944,7 @@ int color_index, glyph;
* Glyph buffering routine. Called instead of WindowPuts().
*/
void
amii_lprint_glyph(window, color_index, glyph)
winid window;
int color_index, glyph;
amii_lprint_glyph(winid window, int color_index, int glyph)
{
int fg_color, bg_color;
struct amii_WinDesc *cw;
@@ -1120,8 +1019,7 @@ static int usecolor;
*/
void
amii_start_glyphout(window)
winid window;
amii_start_glyphout(winid window)
{
struct amii_WinDesc *cw;
struct Window *w;
@@ -1195,7 +1093,7 @@ amii_end_glyphout(window)
#ifdef OPT_DISPMAP
/* don't use dispmap unless x & y are 8,16,24,32,48 and equal */
void
dispmap_sanity()
dispmap_sanity(void)
{
if (mxsize != mysize || dispmap_sanity1(mxsize)
|| dispmap_sanity1(mysize)) {
@@ -1203,11 +1101,10 @@ dispmap_sanity()
}
}
int
dispmap_sanity1(x)
int x;
dispmap_sanity1(int x)
{
static unsigned char valid[] = { 8, 16, 24, 32, 48, 0 };
return !!strchr(valid, x);
return !strchr((char *)valid, x);
}
#endif /* OPT_DISPMAP */
#endif /* TESTING */

View File

@@ -112,7 +112,7 @@ CLIPPING must be defined for the AMIGA version
#endif
#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)
/* cw->data[x] contains 2 characters worth of special information. These
@@ -196,3 +196,4 @@ struct PDAT
#undef MAXCOLORS
#define MAXCOLORS 256

View File

@@ -14,7 +14,6 @@
#endif
#include "patchlevel.h"
#include "date.h"
extern struct TagItem scrntags[];
#ifndef CROSS_TO_AMIGA
@@ -40,6 +39,11 @@ int xclipbord = 4, yclipbord = 2;
#endif
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_oldmsg;
@@ -58,8 +62,7 @@ int amii_otherBPen;
long amii_libvers = LIBRARY_FONT_VERSION;
void
ami_wininit_data(dir)
int dir;
ami_wininit_data(int dir)
{
extern unsigned short amii_init_map[AMII_MAXCOLORS];
extern unsigned short amiv_init_map[AMII_MAXCOLORS];
@@ -150,12 +153,13 @@ struct TagItem wintags[] = {
};
#endif
void amii_destroy_nhwindow(win) /* just hide */
register winid win;
void
amii_destroy_nhwindow(winid win) /* just hide */
{
int i;
int type;
register struct amii_WinDesc *cw;
struct amii_WinDesc *cw;
if (win == WIN_ERR || (cw = amii_wins[win]) == NULL) {
panic(winpanicstr, win, "destroy_nhwindow");
@@ -260,26 +264,37 @@ PPC_LayerFillHook(void)
struct RastPort *rp = (struct RastPort *) REG_A2;
struct FillParams *fp = (struct FillParams *) REG_A1;
#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
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
#else
void
#ifndef _DCC
__interrupt
#endif
__saveds __asm LayerFillHook(register __a0 struct Hook *hk,
register __a2 struct RastPort *rp,
register __a1 struct FillParams *fp)
__saveds __asm LayerFillHook(__a0 struct Hook *hk,
__a2 struct RastPort *rp,
__a1 struct FillParams *fp)
{
#endif
register long x, y, xmax, ymax;
register int apen;
long x, y, xmax, ymax;
int apen;
struct RastPort rptmp;
memcpy(&rptmp, rp, sizeof(struct RastPort));
@@ -321,15 +336,17 @@ void
}
#endif
amii_create_nhwindow(type) register int type;
winid
amii_create_nhwindow(int type)
{
register struct Window *w = NULL;
register struct NewWindow *nw = NULL;
register struct amii_WinDesc *wd = NULL;
struct Window *w = NULL;
struct NewWindow *nw = NULL;
struct amii_WinDesc *wd = NULL;
struct Window *mapwin = NULL, *stwin = NULL, *msgwin = NULL;
register int newid;
int newid;
int maph, stath, scrfontysize;
scrfontysize = HackScreen->Font->ta_YSize;
/*
@@ -563,11 +580,7 @@ amii_create_nhwindow(type) register int type;
case NHW_OVER:
case NHW_MAP:
if (wd) {
#ifdef __GNUC__
fillhook.h_Entry = (void *) &LayerFillHook;
#else
fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
fillhook.h_Data = (void *) type;
fillhook.h_SubEntry = 0;
wd->hook = alloc(sizeof(fillhook));
@@ -665,6 +678,10 @@ amii_create_nhwindow(type) register int type;
/ w->RPort->TxHeight;
wd->cols = (w->Width - w->BorderLeft - w->BorderRight - 2)
/ 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 */
@@ -736,7 +753,9 @@ amii_create_nhwindow(type) register int type;
*/
wd->data = (char **) alloc(3 * sizeof(char *));
wd->data[0] = (char *) alloc(wd->cols + 10);
wd->data[0][0] = '\0';
wd->data[1] = (char *) alloc(wd->cols + 10);
wd->data[1][0] = '\0';
wd->data[2] = NULL;
break;
@@ -771,7 +790,7 @@ amii_create_nhwindow(type) register int type;
SetMenuStrip(w, MenuStrip);
/* Make our requesters come to our screen */
{
register struct Process *myProcess =
struct Process *myProcess =
(struct Process *) FindTask(NULL);
pr_WindowPtr = (struct Window *) (myProcess->pr_WindowPtr);
myProcess->pr_WindowPtr = (APTR) w;
@@ -787,17 +806,7 @@ amii_create_nhwindow(type) register int type;
Abort(AG_OpenDev | AO_ConsoleDev);
}
ConsoleDevice =
#ifndef CROSS_TO_AMIGA
(struct Library *)
#else
(struct Device *
# ifdef __CONSTLIBBASEDECL__
__CONSTLIBBASEDECL__
# endif /* __CONSTLIBBASEDECL__ */
)
#endif
ConsoleIO.io_Device;
ConsoleDevice = (struct Device *) ConsoleIO.io_Device;
KbdBuffered = 0;
#ifdef HACKFONT
@@ -831,12 +840,23 @@ PPC_SM_Filter(void)
ULONG modeID = (ULONG) REG_A1;
struct ScreenModeRequester *smr = (struct ScreenModeRequester *) REG_A2;
#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
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
#else
int
@@ -844,8 +864,8 @@ int
__interrupt
#endif
__saveds __asm SM_Filter(
register __a0 struct Hook *hk, register __a1 ULONG modeID,
register __a2 struct ScreenModeRequester *smr)
__a0 struct Hook *hk, __a1 ULONG modeID,
__a2 struct ScreenModeRequester *smr)
{
#endif
struct DimensionInfo dims;
@@ -869,14 +889,13 @@ int
/* Initialize the windowing environment */
void
amii_init_nhwindows(argcp, argv)
int *argcp;
char **argv;
amii_init_nhwindows(int *argcp, char **argv)
{
int i;
struct Screen *wbscr;
int forcenobig = 0;
if (HackScreen)
panic("init_nhwindows() called twice", 0);
@@ -1192,9 +1211,16 @@ char **argv;
}
#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();
else
} else
memcpy(amii_initmap, amii_init_map, sizeof(amii_initmap));
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 */
void
amii_clear_nhwindow(win)
register winid win;
amii_clear_nhwindow(winid win)
{
register struct amii_WinDesc *cw;
register struct Window *w;
struct amii_WinDesc *cw;
struct Window *w;
if (reclip == 2)
return;
@@ -1394,6 +1420,40 @@ register winid win;
amii_setfillpens(w, cw->type);
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) {
RectFill(w->RPort, w->BorderLeft, w->BorderTop,
w->Width - w->BorderRight - 1,
@@ -1418,11 +1478,10 @@ register winid win;
/* Dismiss the window from the screen */
void
dismiss_nhwindow(win)
register winid win;
dismiss_nhwindow(winid win)
{
register struct Window *w;
register struct amii_WinDesc *cw;
struct Window *w;
struct amii_WinDesc *cw;
if (win == WIN_ERR || (cw = amii_wins[win]) == NULL) {
panic(winpanicstr, win, "dismiss_nhwindow");
@@ -1458,9 +1517,9 @@ register winid win;
}
void
amii_exit_nhwindows(str)
const char *str;
amii_exit_nhwindows(const char *str)
{
/* Seems strange to have to do this... but we need the BASE window
* left behind...
*/
@@ -1475,15 +1534,14 @@ const char *str;
}
void
amii_display_nhwindow(win, blocking)
winid win;
boolean blocking;
amii_display_nhwindow(winid win, boolean blocking)
{
menu_item *mip;
int cnt;
static int lastwin = -1;
struct amii_WinDesc *cw;
if (!Initialized)
return;
lastwin = win;
@@ -1513,13 +1571,12 @@ boolean blocking;
}
void
amii_curs(window, x, y)
winid window;
register int x, y;
amii_curs(winid window, int x, int y)
{
register struct amii_WinDesc *cw;
register struct Window *w;
register struct RastPort *rp;
struct amii_WinDesc *cw;
struct Window *w;
struct RastPort *rp;
if (window == WIN_ERR || (cw = amii_wins[window]) == NULL)
panic(winpanicstr, window, "curs");
@@ -1540,8 +1597,14 @@ register int x, y;
cw->curx = x;
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
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]";
switch (cw->type) {
case NHW_MESSAGE:
@@ -1663,12 +1726,10 @@ printf("pos: (%d,%d)->(%d,%d)\n",x,y,qqx,qqy);
}
void
amii_set_text_font(name, size)
char *name;
int size;
amii_set_text_font(char *name, int size)
{
register int i;
register struct amii_WinDesc *cw;
int i;
struct amii_WinDesc *cw;
int osize = TextsFont13.ta_YSize;
static char nname[100];
@@ -1709,11 +1770,10 @@ int size;
}
void
kill_nhwindows(all)
register int all;
kill_nhwindows(int all)
{
register int i;
register struct amii_WinDesc *cw;
int i;
struct amii_WinDesc *cw;
/* Foreach open window in all of amii_wins[], CloseShWindow, free memory
*/
@@ -1726,12 +1786,10 @@ register int all;
}
void
amii_cl_end(cw, curs_pos)
register struct amii_WinDesc *cw;
register int curs_pos;
amii_cl_end(struct amii_WinDesc *cw, int curs_pos)
{
register struct Window *w = cw->win;
register int oy, ox;
struct Window *w = cw->win;
int oy, ox;
if (!w)
panic("NULL window pointer in amii_cl_end()");
@@ -1745,12 +1803,11 @@ register int curs_pos;
}
void
cursor_off(window)
winid window;
cursor_off(winid window)
{
register struct amii_WinDesc *cw;
register struct Window *w;
register struct RastPort *rp;
struct amii_WinDesc *cw;
struct Window *w;
struct RastPort *rp;
int curx, cury;
int x, y;
long dmode;
@@ -1805,13 +1862,12 @@ winid window;
}
void
cursor_on(window)
winid window;
cursor_on(winid window)
{
int x, y;
register struct amii_WinDesc *cw;
register struct Window *w;
register struct RastPort *rp;
struct amii_WinDesc *cw;
struct Window *w;
struct RastPort *rp;
unsigned char ch;
long dmode;
short apen, bpen;
@@ -1858,10 +1914,13 @@ winid window;
if (WINVERS_AMIV && cw->type == NHW_MAP) {
cursor_common(rp, x, y);
} else {
Move(rp, x, y);
ch = CURSOR_CHAR;
Text(rp, &ch, 1);
Move(rp, x, y);
if (w && x >= 0 && y >= 0
&& x < w->Width && y < w->Height) {
Move(rp, x, y);
ch = CURSOR_CHAR;
Text(rp, &ch, 1);
Move(rp, x, y);
}
}
SetDrMd(rp, dmode);
@@ -1870,9 +1929,7 @@ winid window;
}
static void
cursor_common(rp, x, y)
struct RastPort *rp;
int x, y;
cursor_common(struct RastPort *rp, int x, int y)
{
int x1, x2, y1, y2;
@@ -1895,29 +1952,27 @@ int x, y;
}
void
amii_suspend_nhwindows(str)
const char *str;
amii_suspend_nhwindows(const char *str)
{
if (HackScreen)
ScreenToBack(HackScreen);
}
void
amii_resume_nhwindows()
amii_resume_nhwindows(void)
{
if (HackScreen)
ScreenToFront(HackScreen);
}
void
amii_bell()
amii_bell(void)
{
DisplayBeep(NULL);
}
void
removetopl(cnt)
int cnt;
removetopl(int cnt)
{
struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE];
/* NB - this is sufficient for
@@ -1935,7 +1990,7 @@ int cnt;
#ifdef PORT_HELP
void
port_help()
port_help(void)
{
display_file(PORT_HELP, 1);
}
@@ -1951,17 +2006,20 @@ port_help()
*/
void
amii_print_glyph(win, x, y, glyph, bkglyph)
winid win;
coordxy x, y;
int glyph, bkglyph;
amii_print_glyph(winid win, coordxy x, coordxy y,
const glyph_info *glyphinfo,
const glyph_info *bkglyphinfo UNUSED)
{
struct amii_WinDesc *cw;
uchar ch;
int glyph;
int color, och;
extern const int zapcolors[];
unsigned special;
glyph = glyphinfo->glyph;
/* In order for the overview window to work, we can not clip here */
if (!WINVERS_AMIV) {
#ifdef CLIPPING
@@ -1993,14 +2051,8 @@ if(u.uz.dlevel != x){
} else /* AMII, or Rogue level in either version */
{
/* map glyph to character and color */
#if 0
(void) mapglyph(glyph, &och, &color, &special, x, y, 0);
ch = (uchar) och;
#else
glyph_info gi;
map_glyphinfo(0, 0, glyph, 0, &gi);
ch = gi.ttychar;
#endif
ch = glyphinfo->ttychar;
color = glyphinfo->gm.sym.color;
if (WINVERS_AMIV) { /* implies Rogue level here */
amii_curs(win, x, y);
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 */
void
amii_raw_print(s)
register const char *s;
amii_raw_print(const char *s)
{
int argc = 0;
if (!s)
return;
if (amiIDisplay)
@@ -2057,11 +2109,11 @@ register const char *s;
*/
void
amii_raw_print_bold(s)
register const char *s;
amii_raw_print_bold(const char *s)
{
int argc = 0;
if (!s)
return;
@@ -2092,9 +2144,10 @@ register const char *s;
/* Rebuild/update the inventory if the window is up.
*/
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])
&& 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 */
void
amii_mark_synch()
amii_mark_synch(void)
{
if (!amiIDisplay)
fflush(stderr);
@@ -2116,7 +2176,7 @@ amii_mark_synch()
* ask for a key to be pressed.
*/
void
amii_wait_synch()
amii_wait_synch(void)
{
if (!amiIDisplay || amiIDisplay->rawprint) {
if (amiIDisplay)
@@ -2130,7 +2190,7 @@ amii_wait_synch()
}
void
amii_setclipped()
amii_setclipped(void)
{
#ifdef CLIPPING
clipping = TRUE;
@@ -2141,12 +2201,35 @@ amii_setclipped()
#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
* edge of the map is already displayed
*/
void
amii_cliparound(x, y)
register int x, y;
amii_cliparound(int x, int y)
{
#ifdef CLIPPING
int oldx = clipx, oldy = clipy;
@@ -2155,8 +2238,9 @@ register int x, y;
#define SCROLLCNT 1 /* Get there in 3 moves... */
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;
}
if (Is_rogue_level(&u.uz)) {
struct Window *w = amii_wins[WIN_MAP]->win;
@@ -2173,16 +2257,22 @@ register int x, y;
* reasonablely large window extra motion is avoided; for
* the rogue level hopefully this means no motion at all.
*/
{
static d_level saved_level = { 127, 127 }; /* XXX */
if (!on_level(&u.uz, &saved_level)) {
scrollcnt = 1; /* jump with blanking */
clipx = clipy = 0;
clipxmax = COx;
clipymax = LIx;
saved_level = u.uz; /* save as new current level */
if (!on_level(&u.uz, &clip_saved_level)) {
scrollcnt = 1; /* jump with blanking */
/* Center viewport on the player for the new level. */
clipx = max(0, x - COx / 2);
clipxmax = clipx + COx;
if (clipxmax > COLNO) {
clipxmax = COLNO;
clipx = clipxmax - COx;
}
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) {
@@ -2204,13 +2294,12 @@ register int x, y;
reclip = 1;
if (clipx != oldx || clipy != oldy || clipxmax != oldxmax
|| clipymax != oldymax) {
#ifndef NOSCROLLRASTER
struct Window *w = amii_wins[WIN_MAP]->win;
struct RastPort *rp = w->RPort;
int xdelta, ydelta, xmod, ymod, i;
int incx, incy, mincx, mincy;
int savex, savey, savexmax, saveymax;
int scrx, scry;
int dx = clipx - oldx;
int dy = clipy - oldy;
int scrx, scry; /* tile pixel dimensions */
int halfW, halfH; /* half viewport in tiles */
if (Is_rogue_level(&u.uz)) {
scrx = rp->TxWidth;
@@ -2220,129 +2309,63 @@ register int x, y;
scry = mysize;
}
/* Ask that the glyph routines not draw the overview window */
reclip = 2;
cursor_off(WIN_MAP);
halfW = COx / 2;
halfH = LIx / 2;
/* Compute how far we are moving in terms of tiles */
mincx = clipx - oldx;
mincy = clipy - oldy;
/* Erase the map cursor before shifting pixels, otherwise the
old cursor position leaves a COMPLEMENT artifact on screen. */
if (WIN_MAP != WIN_ERR)
cursor_off(WIN_MAP);
/* How many tiles to get there in SCROLLCNT moves */
incx = (clipx - oldx) / scrollcnt;
incy = (clipy - oldy) / scrollcnt;
/* If less than SCROLLCNT tiles, then move by 1 tile if moving at all
*/
if (incx == 0)
incx = (mincx != 0);
if (incy == 0)
incy = (mincy != 0);
/* Get count of pixels to move each iteration and final pixel count */
xdelta = ((clipx - oldx) * scrx) / scrollcnt;
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;
/* Large jumps (teleport, level change): just redraw everything. */
if (abs(dx) > halfW || abs(dy) > halfH
|| scrollcnt != SCROLLCNT) {
{
int savedAPen = rp->FgPen;
int savedDrMd = rp->DrawMode;
SetAPen(rp, amii_otherBPen);
SetDrMd(rp, JAM1);
RectFill(rp, w->BorderLeft, w->BorderTop,
w->Width - w->BorderRight - 1,
w->Height - w->BorderBottom - 1);
SetAPen(rp, savedAPen);
SetDrMd(rp, savedDrMd);
}
#endif
/* Scroll the raster if we are scrolling */
if (xdelta != 0 || ydelta != 0) {
ScrollRaster(rp, xdelta, ydelta, w->BorderLeft, w->BorderTop,
w->Width - w->BorderRight - 1,
w->Height - w->BorderBottom - 1);
redraw_map(FALSE);
} else {
/* Flush pending glyphs — they reference old clip coords */
flush_glyph_buffer(w);
if (mincx == 0)
incx = 0;
else
mincx -= incx;
/* Hardware-blit the viewport by the scroll delta */
ScrollRaster(rp, dx * scrx, dy * scry,
w->BorderLeft, w->BorderTop,
w->Width - w->BorderRight - 1,
w->Height - w->BorderBottom - 1);
clipx += incx;
clipxmax += incx;
/* Redraw only the exposed strip(s) */
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)
incy = 0;
else
mincy -= incy;
if (dy > 0)
redraw_map_region(clipx, clipymax - dy,
clipxmax, clipymax - 1);
else if (dy < 0)
redraw_map_region(clipx, clipy,
clipxmax, clipy - dy - 1);
clipy += incy;
clipymax += incy;
/* Draw the exposed portion */
redraw_map();
flush_glyph_buffer(amii_wins[WIN_MAP]->win);
}
flush_glyph_buffer(w);
}
clipx = savex;
clipy = savey;
clipymax = saveymax;
clipxmax = savexmax;
#endif
redraw_map();
flush_glyph_buffer(amii_wins[WIN_MAP]->win);
}
reclip = 0;
#endif
}
void
flushIDCMP(port)
struct MsgPort *port;
flushIDCMP(struct MsgPort *port)
{
struct Message *msg;
while (msg = GetMsg(port))

View File

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

View File

@@ -8,10 +8,9 @@ void EditClipping(void);
void DrawCol(struct Window *w, int idx, UWORD *colors);
void DispCol(struct Window *w, int idx, UWORD *colors);
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 getlind(const char *prompt, char *bufp, const char *dflt);
char *amii_get_color_string(void);
int filecopy(char *from, char *to);
char *basename(char *str);
char *dirname(char *str);
@@ -33,15 +32,15 @@ void amii_scrollmsg(register struct Window *w,
register struct amii_WinDesc *cw);
/* 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);
void amii_get_nh_event(void);
void amii_getret(void);
/* winmenu.c */
void amii_start_menu(winid window, unsigned long);
void amii_add_menu(winid, int, const anything *, CHAR_P, CHAR_P, int,
const char *, unsigned int);
void amii_add_menu(winid, const glyph_info *, const anything *, CHAR_P, CHAR_P,
int, int, const char *, unsigned int);
void amii_end_menu(winid, const char *);
int amii_select_menu(winid, int, 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);
int ConvertKey(struct IntuiMessage *message);
int kbhit(void);
int kbhit(void);
int amikbhit(void);
int WindowGetchar(void);
WETYPE WindowGetevent(void);
@@ -101,19 +99,19 @@ void amii_resume_nhwindows(void);
void amii_bell(void);
void removetopl(int cnt);
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_bold(const char *s);
void amii_update_inventory(void);
void amii_update_inventory(int);
void amii_mark_synch(void);
void amii_wait_synch(void);
void amii_setclipped(void);
void amii_cliparound(int x, int y);
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);
void FreeImageFiles(char **, struct BitMap **);
void FreeTileImageFiles();
void FreeTileImageFiles(void);
/* winami.c */
#ifdef SHAREDLIB
@@ -124,12 +122,10 @@ void amii_askname(void);
void amii_player_selection(void);
void RandomWindow(char *name);
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);
void amii_display_file(const char *fn, boolean complain);
void SetBorder(struct Gadget *gd);
void *malloc(register unsigned size);
void free(void *q);
/* malloc/free provided by stdlib.h */
#ifdef SHAREDLIB
/* amilib.c */
@@ -141,6 +137,8 @@ void setup_librefs(WinamiBASE *base);
void Abort(long rc);
#endif
win_request_info *amii_ctrl_nhwindow(winid, int, win_request_info *);
/* amirip.c */
void amii_outrip(winid tmpwin, int how, time_t when);
@@ -151,4 +149,3 @@ int GlyphToIcon(int glyph);
void dispmap_sanity(void);
int dispmap_sanity1(int);
#endif
void FreeTileImageFiles(void);

View File

@@ -67,16 +67,16 @@ struct NewWindow StrWindow = {
void ClearCol(struct Window *w);
void
EditColor()
EditColor(void)
{
extern char configfile[];
const char *configfile = get_configfile();
int i, done = 0, okay = 0;
long code, qual, class;
register struct Gadget *gd, *dgad;
register struct Window *nw;
register struct IntuiMessage *imsg;
register struct PropInfo *pip;
register struct Screen *scrn;
struct Gadget *gd, *dgad;
struct Window *nw;
struct IntuiMessage *imsg;
struct PropInfo *pip;
struct Screen *scrn;
long aidx;
int msx, msy;
int curcol = 0, drag = 0;
@@ -128,11 +128,7 @@ EditColor()
#ifdef INTUI_NEW_LOOK
Col_NewWindowStructure1.Extension = wintags;
Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
#ifdef __GNUC__
fillhook.h_Entry = (void *) &LayerFillHook;
#else
fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
fillhook.h_Data = (void *) -2;
fillhook.h_SubEntry = 0;
#endif
@@ -248,7 +244,7 @@ EditColor()
for (i = 0; i < amii_numcolors; ++i) {
fprintf(nfp, "%03x", colors[i]);
if ((i + 1) < amii_numcolors)
putc(',', nfp);
putc('/', nfp);
}
putc('\n', nfp);
}
@@ -356,11 +352,11 @@ EditClipping(void)
char buf[40];
int done = 0, okay = 0;
long code, qual, class;
register struct Gadget *gd, *dgad;
register struct Window *nw;
register struct IntuiMessage *imsg;
register struct PropInfo *pip;
register struct Screen *scrn;
struct Gadget *gd, *dgad;
struct Window *nw;
struct IntuiMessage *imsg;
struct PropInfo *pip;
struct Screen *scrn;
long aidx;
int lmxsize = mxsize, lmysize = mysize;
int lxclipbord = xclipbord, lyclipbord = yclipbord;
@@ -388,11 +384,7 @@ EditClipping(void)
#ifdef INTUI_NEW_LOOK
ClipNewWindowStructure1.Extension = wintags;
ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
#ifdef __GNUC__
fillhook.h_Entry = (void *) &LayerFillHook;
#else
fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
fillhook.h_Data = (void *) -2;
fillhook.h_SubEntry = 0;
#endif
@@ -546,8 +538,7 @@ EditClipping(void)
}
char *
dirname(str)
char *str;
dirname(char *str)
{
char *t, c;
static char dir[300];
@@ -555,9 +546,9 @@ char *str;
t = strrchr(str, '/');
if (!t)
t = strrchr(str, ':');
if (!t)
t = str;
else {
if (!t) {
dir[0] = '\0';
} else {
c = *t;
*t = 0;
strcpy(dir, str);
@@ -567,8 +558,7 @@ char *str;
}
char *
basename(str)
char *str;
basename(char *str)
{
char *t;
@@ -582,7 +572,8 @@ char *str;
return (t);
}
filecopy(from, to) char *from, *to;
int
filecopy(char *from, char *to)
{
char *buf;
int i = 0;
@@ -606,7 +597,7 @@ filecopy(from, to) char *from, *to;
}
/* The colornames, and the default values for the pens */
static struct COLDEF {
struct COLDEF {
char *name, *defval;
};
struct COLDEF amii_colnames[AMII_MAXCOLORS] = {
@@ -657,10 +648,7 @@ ClearCol(struct Window *w)
}
void
DrawCol(w, idx, colors)
struct Window *w;
int idx;
UWORD *colors;
DrawCol(struct Window *w, int idx, UWORD *colors)
{
int bxorx, bxory, bxxlen, bxylen;
int i, incx, incy, r, g, b;
@@ -742,10 +730,7 @@ UWORD *colors;
}
void
DispCol(w, idx, colors)
struct Window *w;
int idx;
UWORD *colors;
DispCol(struct Window *w, int idx, UWORD *colors)
{
char buf[50];
char *colname, *defval;
@@ -824,26 +809,21 @@ amii_setpens(int count)
/* Generate a requester for a string value. */
void
amii_getlin(prompt, bufp)
const char *prompt;
char *bufp;
amii_getlin(const char *prompt, char *bufp)
{
getlind(prompt, bufp, 0);
}
/* and with default */
void
getlind(prompt, bufp, dflt)
const char *prompt;
char *bufp;
const char *dflt;
getlind(const char *prompt, char *bufp, const char *dflt)
{
#ifndef TOPL_GETLINE
register struct Window *cwin;
register struct IntuiMessage *imsg;
register long class, code, qual;
register int aredone = 0;
register struct Gadget *gd;
struct Window *cwin;
struct IntuiMessage *imsg;
long class, code, qual;
int aredone = 0;
struct Gadget *gd;
static int once;
*StrString = 0;
@@ -872,11 +852,7 @@ const char *dflt;
#ifdef INTUI_NEW_LOOK
StrWindow.Extension = wintags;
StrWindow.Flags |= WFLG_NW_EXTENDED;
#ifdef __GNUC__
fillhook.h_Entry = (void *) &LayerFillHook;
#else
fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
fillhook.h_Data = (void *) -2;
fillhook.h_SubEntry = 0;
#endif
@@ -1006,9 +982,7 @@ const char *dflt;
}
void
amii_change_color(pen, val, rev)
int pen, rev;
long val;
amii_change_color(int pen, long val, int rev)
{
if (rev)
sysflags.amii_curmap[pen] = ~val;
@@ -1020,12 +994,13 @@ long val;
}
char *
amii_get_color_string()
amii_get_color_string(void)
{
int i;
char s[10];
static char buf[BUFSZ];
*buf = 0;
for (i = 0; i < min(32, amii_numcolors); ++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 */
void
amii_putstr(window, attr, str)
winid window;
int attr;
const char *str;
amii_putstr(winid window, int attr, const char *str)
{
int fudge;
int len;
@@ -27,6 +24,7 @@ const char *str;
int i, j, n0, bottom, totalvis, wheight;
static int wrapping = 0;
/* Always try to avoid a panic when there is no window */
if (window == WIN_ERR) {
window = WIN_BASE;
@@ -101,13 +99,13 @@ const char *str;
memcpy(cw->data, &cw->data[1],
(iflags.msg_history - 1) * sizeof(char *));
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
+ (scrollmsg != 0),
gt.toplines);
} else {
/* 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),
gt.toplines);
}
@@ -196,7 +194,10 @@ const char *str;
/* Display when beam at top to avoid flicker... */
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))
TextSpaces(w->RPort, cw->cols - strlen(str));
@@ -286,9 +287,7 @@ const char *str;
}
void
amii_scrollmsg(w, cw)
register struct Window *w;
register struct amii_WinDesc *cw;
amii_scrollmsg(struct Window *w, struct amii_WinDesc *cw)
{
int bottom, wheight;
@@ -311,8 +310,7 @@ register struct amii_WinDesc *cw;
}
int
amii_msgborder(w)
struct Window *w;
amii_msgborder(struct Window *w)
{
register int bottom;
@@ -325,8 +323,7 @@ struct Window *w;
}
void
outmore(cw)
register struct amii_WinDesc *cw;
outmore(struct amii_WinDesc *cw)
{
struct Window *w = cw->win;
@@ -359,11 +356,7 @@ register struct amii_WinDesc *cw;
}
void
outsubstr(cw, str, len, fudge)
register struct amii_WinDesc *cw;
char *str;
int len;
int fudge;
outsubstr(struct amii_WinDesc *cw, char *str, int len, int fudge)
{
struct Window *w = cw->win;
@@ -387,10 +380,7 @@ int fudge;
/* Put a graphics character onto the screen */
void
amii_putsym(st, i, y, c)
winid st;
int i, y;
CHAR_P c;
amii_putsym(winid st, int i, int y, CHAR_P c)
{
amii_curs(st, i, y);
Text(amii_wins[st]->win->RPort, &c, 1);
@@ -399,8 +389,7 @@ CHAR_P c;
/* Add to the last line in the message window */
void
amii_addtopl(s)
const char *s;
amii_addtopl(const char *s)
{
register struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE];
@@ -413,9 +402,7 @@ const char *s;
}
void
TextSpaces(rp, nr)
struct RastPort *rp;
int nr;
TextSpaces(struct RastPort *rp, int nr)
{
if (nr < 1)
return;
@@ -429,7 +416,7 @@ int nr;
}
void
amii_remember_topl()
amii_remember_topl(void)
{
/* ignore for now. I think this will be done automatically by
* the code writing to the message window, but I could be wrong.
@@ -437,12 +424,13 @@ amii_remember_topl()
}
int
amii_doprev_message()
amii_doprev_message(void)
{
struct amii_WinDesc *cw;
struct Window *w;
char *str;
if (WIN_MESSAGE == WIN_ERR || (cw = amii_wins[WIN_MESSAGE]) == NULL
|| (w = cw->win) == NULL) {
panic(winpanicstr, WIN_MESSAGE, "doprev_message");

View File

@@ -1,363 +0,0 @@
/* NetHack 3.6 xpm2iff.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */
/* Copyright (c) 1995 by Gregg Wonderly, Naperville, Illinois */
/* NetHack may be freely redistributed. See license for details. */
#include <stdlib.h>
#include "config.h"
#include "tile.h"
#include <dos/dos.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/view.h>
#include <libraries/iffparse.h>
#include <libraries/dos.h>
#ifndef _DCC
#include <proto/iffparse.h>
#include <proto/dos.h>
#include <proto/exec.h>
#endif
struct xpmscreen {
int Width;
int Height;
int Colors;
int ColorResolution;
int Background;
int AspectRatio;
int Interlace;
int BytesPerRow;
} XpmScreen;
/* translation table from xpm characters to RGB and colormap slots */
struct Ttable {
char flag;
char r, g, b;
int slot; /* output colortable index */
} ttable[256];
pixval ColorMap[3][MAXCOLORMAPSIZE];
int colorsinmap;
/*
* We are using a hybrid form of our own design which we call a BMAP (for
* bitmap) form. It is an ILBM with the bitmaps already deinterleaved,
* completely uncompressed.
* This speeds the loading of the images from the games point of view because
* it
* does not have to deinterleave and uncompress them.
*/
#define ID_BMAP MAKE_ID('B', 'M', 'A', 'P') /* instead of ILBM */
#define ID_BMHD MAKE_ID('B', 'M', 'H', 'D') /* Same as ILBM */
#define ID_CAMG MAKE_ID('C', 'A', 'M', 'G') /* Same as ILBM */
#define ID_CMAP MAKE_ID('C', 'M', 'A', 'P') /* Same as ILBM */
#define ID_PDAT \
MAKE_ID('P', 'D', 'A', 'T') /* Extra data describing plane \
* size due to graphics.library \
* rounding requirements. \
*/
#define ID_PLNE MAKE_ID('P', 'L', 'N', 'E') /* The planes of the image */
int nplanes;
/* BMHD from IFF documentation */
typedef struct {
UWORD w, h;
WORD x, y;
UBYTE nPlanes;
UBYTE masking;
UBYTE compression;
UBYTE reserved1;
UWORD transparentColor;
UBYTE xAspect, yAspect;
WORD pageWidth, pageHeight;
} BitMapHeader;
typedef struct {
UBYTE r, g, b;
} AmiColorMap;
pixel pixels[TILE_Y][TILE_X];
AmiColorMap *cmap;
void
error(char *str)
{
fprintf(stderr, "ERROR: %s\n", str);
}
char **planes;
main(int argc, char **argv)
{
int colors;
struct {
long nplanes;
long pbytes;
long across;
long down;
long npics;
long xsize;
long ysize;
} pdat;
long pbytes; /* Bytes of data in a plane */
int i, cnt;
BitMapHeader bmhd;
struct IFFHandle *iff;
long camg = HIRES | LACE;
int tiles = 0;
int index;
#if defined(_DCC) || defined(__GNUC__)
IFFParseBase = OpenLibrary("iffparse.library", 0);
if (!IFFParseBase) {
error("unable to open iffparse.library");
exit(1);
}
#endif
if (fopen_xpm_file(argv[1], "r") != TRUE) {
perror(argv[1]);
return (1);
}
nplanes = 0;
i = XpmScreen.Colors - 1;
while (i != 0) {
nplanes++;
i >>= 1;
}
planes = malloc(nplanes * sizeof(char *));
if (planes == 0) {
error("can not allocate planes pointer");
exit(1);
}
XpmScreen.BytesPerRow = ((XpmScreen.Width + 15) / 16) * 2;
pbytes = XpmScreen.BytesPerRow * XpmScreen.Height;
for (i = 0; i < nplanes; ++i) {
planes[i] = malloc(pbytes);
if (planes[i] == 0) {
error("can not allocate planes pointer");
exit(1);
}
memset(planes[i], 0, pbytes);
}
iff = AllocIFF();
if (!iff) {
error("Can not allocate IFFHandle");
return (1);
}
iff->iff_Stream = Open(argv[2], MODE_NEWFILE);
if (!iff->iff_Stream) {
error("Can not open output file");
return (1);
}
InitIFFasDOS(iff);
OpenIFF(iff, IFFF_WRITE);
PushChunk(iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN);
bmhd.w = XpmScreen.Width;
bmhd.h = XpmScreen.Height;
bmhd.x = 0;
bmhd.y = 0;
bmhd.nPlanes = nplanes;
bmhd.masking = 0;
bmhd.compression = 0;
bmhd.reserved1 = 0;
bmhd.transparentColor = 0;
bmhd.xAspect = 100;
bmhd.yAspect = 100;
bmhd.pageWidth = 0; /* not needed for this program */
bmhd.pageHeight = 0; /* not needed for this program */
PushChunk(iff, ID_BMAP, ID_BMHD, sizeof(bmhd));
WriteChunkBytes(iff, &bmhd, sizeof(bmhd));
PopChunk(iff);
PushChunk(iff, ID_BMAP, ID_CAMG, sizeof(camg));
WriteChunkBytes(iff, &camg, sizeof(camg));
PopChunk(iff);
#define SCALE(x) (x)
cmap = malloc((colors = (1L << nplanes)) * sizeof(AmiColorMap));
if (cmap == 0) {
error("Can't allocate color map");
exit(1);
}
for (index = 0; index < 256; index++) {
if (ttable[index].flag) {
cmap[ttable[index].slot].r = SCALE(ttable[index].r);
cmap[ttable[index].slot].g = SCALE(ttable[index].g);
cmap[ttable[index].slot].b = SCALE(ttable[index].b);
}
}
#undef SCALE
PushChunk(iff, ID_BMAP, ID_CMAP, IFFSIZE_UNKNOWN);
WriteChunkBytes(iff, cmap, colors * sizeof(*cmap));
PopChunk(iff);
conv_image();
pdat.nplanes = nplanes;
pdat.pbytes = pbytes;
pdat.xsize = XpmScreen.Width;
pdat.ysize = XpmScreen.Height;
pdat.across = 0;
pdat.down = 0;
pdat.npics = 1;
PushChunk(iff, ID_BMAP, ID_PDAT, IFFSIZE_UNKNOWN);
WriteChunkBytes(iff, &pdat, sizeof(pdat));
PopChunk(iff);
PushChunk(iff, ID_BMAP, ID_PLNE, IFFSIZE_UNKNOWN);
for (i = 0; i < nplanes; ++i)
WriteChunkBytes(iff, planes[i], pbytes);
PopChunk(iff);
CloseIFF(iff);
Close(iff->iff_Stream);
FreeIFF(iff);
#if defined(_DCC) || defined(__GNUC__)
CloseLibrary(IFFParseBase);
#endif
exit(0);
}
#define SETBIT(Plane, Plane_offset, Col, Value) \
if (Value) { \
planes[Plane][Plane_offset + (Col / 8)] |= 1 << (7 - (Col & 7)); \
}
conv_image()
{
int row, col, planeno;
for (row = 0; row < XpmScreen.Height; row++) {
char *xb = xpmgetline();
int plane_offset;
if (xb == 0)
return;
plane_offset = row * XpmScreen.BytesPerRow;
for (col = 0; col < XpmScreen.Width; col++) {
int slot;
int color = xb[col];
if (!ttable[color].flag) {
fprintf(stderr, "Bad image data\n");
}
slot = ttable[color].slot;
for (planeno = 0; planeno < nplanes; planeno++) {
SETBIT(planeno, plane_offset, col, slot & (1 << planeno));
}
}
}
}
long *
alloc(unsigned int n)
{
long *ret = malloc(n);
if (!ret) {
error("Can't allocate memory");
exit(1);
}
return (ret);
}
FILE *xpmfh = 0;
char initbuf[200];
char *xpmbuf = initbuf;
/* version 1. Reads the raw xpm file, NOT the compiled version. This is
* not a particularly good idea but I don't have time to do the right thing
* at this point, even if I was absolutely sure what that was. */
fopen_xpm_file(const char *fn, const char *mode)
{
int temp;
char *xb;
if (strcmp(mode, "r"))
return FALSE; /* no choice now */
if (xpmfh)
return FALSE; /* one file at a time */
xpmfh = fopen(fn, mode);
if (!xpmfh)
return FALSE; /* I'm hard to please */
/* read the header */
xb = xpmgetline();
if (xb == 0)
return FALSE;
if (4 != sscanf(xb, "%d %d %d %d", &XpmScreen.Width, &XpmScreen.Height,
&XpmScreen.Colors, &temp))
return FALSE; /* bad header */
/* replace the original buffer with one big enough for
* the real data
*/
/* XXX */
xpmbuf = malloc(XpmScreen.Width * 2);
if (!xpmbuf) {
error("Can't allocate line buffer");
exit(1);
}
if (temp != 1)
return FALSE; /* limitation of this code */
{
/* read the colormap and translation table */
int ccount = -1;
while (ccount++ < (XpmScreen.Colors - 1)) {
char index;
int r, g, b;
xb = xpmgetline();
if (xb == 0)
return FALSE;
if (4 != sscanf(xb, "%c c #%2x%2x%2x", &index, &r, &g, &b)) {
fprintf(stderr, "Bad color entry: %s\n", xb);
return FALSE;
}
ttable[index].flag = 1; /* this color is valid */
ttable[index].r = r;
ttable[index].g = g;
ttable[index].b = b;
ttable[index].slot = ccount;
}
}
return TRUE;
}
/* This deserves better. Don't read it too closely - you'll get ill. */
#define bufsz 2048
char buf[bufsz];
xpmgetline()
{
char *bp;
do {
if (fgets(buf, bufsz, xpmfh) == 0)
return 0;
} while (buf[0] != '"');
/* strip off the trailing <",> if any */
for (bp = buf; *bp; bp++)
;
bp--;
while (isspace(*bp))
bp--;
if (*bp == ',')
bp--;
if (*bp == '"')
bp--;
bp++;
*bp = '\0';
return &buf[1];
}

View File

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

View File

@@ -229,6 +229,76 @@ mipspkg: dodata $(GAMEBIN) $(TARGETPFX)recover
@echo MIPS package zip file $(TARGETPFX)nh370mips.zip
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
# shared file dependencies
$(TARGETPFX)pcmain.o : ../sys/share/pcmain.c $(HACK_H)

View File

@@ -38,6 +38,16 @@ override TARGETPFX = $(TARGETDIR)/
override TARGET_LIBS=
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
override PREGAME=
override BUILDMORE=

View File

@@ -460,6 +460,96 @@ NCURSES_PLATFORM=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 BUILD_PDCURSES
# Rules for PDCurses files