Move Amiga port files from outdated/ to sys/amiga/
Move the active Amiga source files back into their proper locations. Legacy native build files (Makefile.ami, Build.ami, etc.) remain in outdated/ as they are not used by the cross-compilation build.
This commit is contained in:
918
sys/amiga/amiwind.c
Normal file
918
sys/amiga/amiwind.c
Normal file
@@ -0,0 +1,918 @@
|
||||
/* NetHack 3.6 amiwind.c $NHDT-Date: 1432512794 2015/05/25 00:13:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */
|
||||
/* Copyright (c) Olaf Seibert (KosmoSoft), 1989, 1992 */
|
||||
/* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#ifndef CROSS_TO_AMIGA
|
||||
#include "NH:sys/amiga/windefs.h"
|
||||
#include "NH:sys/amiga/winext.h"
|
||||
#include "NH:sys/amiga/winproto.h"
|
||||
#else
|
||||
#include "windefs.h"
|
||||
#include "winext.h"
|
||||
#include "winproto.h"
|
||||
#endif
|
||||
|
||||
/* Have to undef CLOSE as display.h and intuition.h both use it */
|
||||
#undef CLOSE
|
||||
|
||||
#ifdef AMII_GRAPHICS /* too early in the file? too late? */
|
||||
|
||||
#ifdef AMIFLUSH
|
||||
static struct Message *GetFMsg(struct MsgPort *);
|
||||
#endif
|
||||
|
||||
static int BufferGetchar(void);
|
||||
static void ProcessMessage(register 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
|
||||
|
||||
#ifndef CROSS_TO_AMIGA
|
||||
#include "NH:sys/amiga/amimenu.c"
|
||||
#else
|
||||
#include "amimenu.c"
|
||||
#endif
|
||||
|
||||
/* Now our own variables */
|
||||
|
||||
struct IntuitionBase *IntuitionBase;
|
||||
struct Screen *HackScreen;
|
||||
struct Window *pr_WindowPtr;
|
||||
struct MsgPort *HackPort;
|
||||
struct IOStdReq ConsoleIO;
|
||||
struct Menu *MenuStrip;
|
||||
APTR *VisualInfo;
|
||||
char Initialized = 0;
|
||||
WEVENT lastevent;
|
||||
|
||||
#ifdef HACKFONT
|
||||
struct GfxBase *GfxBase;
|
||||
struct Library *DiskfontBase;
|
||||
#endif
|
||||
|
||||
#define KBDBUFFER 10
|
||||
static unsigned char KbdBuffer[KBDBUFFER];
|
||||
unsigned char KbdBuffered;
|
||||
|
||||
#ifdef HACKFONT
|
||||
|
||||
struct TextFont *TextsFont = NULL;
|
||||
struct TextFont *HackFont = NULL;
|
||||
struct TextFont *RogueFont = NULL;
|
||||
|
||||
UBYTE FontName[] = "NetHack:hack.font";
|
||||
/* # chars in "NetHack:": */
|
||||
#define SIZEOF_DISKNAME 8
|
||||
|
||||
#endif
|
||||
|
||||
struct TextAttr Hack80 = {
|
||||
#ifdef HACKFONT
|
||||
&FontName[SIZEOF_DISKNAME],
|
||||
#else
|
||||
(UBYTE *) "topaz.font",
|
||||
#endif
|
||||
8, FS_NORMAL, FPF_DISKFONT | FPF_DESIGNED | FPF_ROMFONT
|
||||
};
|
||||
|
||||
struct TextAttr TextsFont13 = { (UBYTE *) "courier.font", 13, FS_NORMAL,
|
||||
FPF_DISKFONT | FPF_DESIGNED
|
||||
#ifndef HACKFONT
|
||||
| FPF_ROMFONT
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Avoid doing a ReplyMsg through a window that no longer exists. */
|
||||
static enum { NoAction, CloseOver } delayed_key_action = NoAction;
|
||||
|
||||
/*
|
||||
* Open a window that shares the HackPort IDCMP. Use CloseShWindow()
|
||||
* to close.
|
||||
*/
|
||||
|
||||
struct Window *
|
||||
OpenShWindow(nw)
|
||||
struct NewWindow *nw;
|
||||
{
|
||||
register struct Window *win;
|
||||
register ULONG idcmpflags;
|
||||
|
||||
if (!HackPort) /* Sanity check */
|
||||
return (struct Window *) 0;
|
||||
|
||||
idcmpflags = nw->IDCMPFlags;
|
||||
nw->IDCMPFlags = 0;
|
||||
if (!(win = OpenWindow((void *) nw))) {
|
||||
nw->IDCMPFlags = idcmpflags;
|
||||
return (struct Window *) 0;
|
||||
}
|
||||
|
||||
nw->IDCMPFlags = idcmpflags;
|
||||
win->UserPort = HackPort;
|
||||
ModifyIDCMP(win, idcmpflags);
|
||||
return win;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a window that shared the HackPort IDCMP port.
|
||||
*/
|
||||
|
||||
void CloseShWindow(struct Window *);
|
||||
void
|
||||
CloseShWindow(win)
|
||||
struct Window *win;
|
||||
{
|
||||
register struct IntuiMessage *msg;
|
||||
|
||||
if (!HackPort)
|
||||
panic("HackPort NULL in CloseShWindow");
|
||||
if (!win)
|
||||
return;
|
||||
|
||||
Forbid();
|
||||
/* Flush all messages for all windows to avoid typeahead and other
|
||||
* similar problems...
|
||||
*/
|
||||
while (msg = (struct IntuiMessage *) GetMsg(win->UserPort))
|
||||
ReplyMsg((struct Message *) msg);
|
||||
KbdBuffered = 0;
|
||||
win->UserPort = (struct MsgPort *) 0;
|
||||
ModifyIDCMP(win, 0L);
|
||||
Permit();
|
||||
CloseWindow(win);
|
||||
}
|
||||
|
||||
static int
|
||||
BufferGetchar()
|
||||
{
|
||||
register int c;
|
||||
|
||||
if (KbdBuffered > 0) {
|
||||
c = KbdBuffer[0];
|
||||
KbdBuffered--;
|
||||
/* Move the remaining characters */
|
||||
if (KbdBuffered < sizeof(KbdBuffer))
|
||||
memcpy(KbdBuffer, KbdBuffer + 1, KbdBuffered);
|
||||
return c;
|
||||
}
|
||||
|
||||
return NO_CHAR;
|
||||
}
|
||||
|
||||
/*
|
||||
* This should remind you remotely of DeadKeyConvert, but we are cheating
|
||||
* a bit. We want complete control over the numeric keypad, and no dead
|
||||
* keys... (they are assumed to be on Alted keys).
|
||||
*
|
||||
* Also assumed is that the IntuiMessage is of type RAWKEY. For some
|
||||
* reason, IECODE_UP_PREFIX events seem to be lost when they occur while
|
||||
* our console window is inactive. This is particulary troublesome with
|
||||
* qualifier keys... Is this because I never RawKeyConvert those events???
|
||||
*/
|
||||
|
||||
int
|
||||
ConvertKey(message)
|
||||
register struct IntuiMessage *message;
|
||||
{
|
||||
static struct InputEvent theEvent;
|
||||
static char numpad[] = "bjnh.lyku";
|
||||
static char ctrl_numpad[] = "\x02\x0A\x0E\x08.\x0C\x19\x0B\x15";
|
||||
static char shift_numpad[] = "BJNH.LYKU";
|
||||
|
||||
unsigned char buffer[10];
|
||||
struct Window *w = message->IDCMPWindow;
|
||||
register int length;
|
||||
register ULONG qualifier;
|
||||
char numeric_pad, shift, control, alt;
|
||||
|
||||
if (amii_wins[WIN_MAP])
|
||||
w = amii_wins[WIN_MAP]->win;
|
||||
qualifier = message->Qualifier;
|
||||
|
||||
control = (qualifier & IEQUALIFIER_CONTROL) != 0;
|
||||
shift = (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) != 0;
|
||||
alt = (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) != 0;
|
||||
|
||||
/* Allow ALT to function as a META key ... */
|
||||
/* But make it switchable - alt is needed for some non-US keymaps */
|
||||
if (sysflags.altmeta)
|
||||
qualifier &= ~(IEQUALIFIER_LALT | IEQUALIFIER_RALT);
|
||||
numeric_pad = (qualifier & IEQUALIFIER_NUMERICPAD) != 0;
|
||||
|
||||
/*
|
||||
* Shortcut for HELP and arrow keys. I suppose this is allowed.
|
||||
* The defines are in intuition/intuition.h, and the keys don't
|
||||
* serve 'text' input, normally. Also, parsing their escape
|
||||
* sequences is such a mess...
|
||||
*/
|
||||
|
||||
switch (message->Code) {
|
||||
case RAWHELP:
|
||||
if (alt) {
|
||||
EditColor();
|
||||
return (-1);
|
||||
}
|
||||
#ifdef CLIPPING
|
||||
else if (WINVERS_AMIV && control) {
|
||||
EditClipping();
|
||||
|
||||
CO = (w->Width - w->BorderLeft - w->BorderRight) / mxsize;
|
||||
LI = (w->Height - w->BorderTop - w->BorderBottom) / mysize;
|
||||
clipxmax = CO + clipx;
|
||||
clipymax = LI + clipy;
|
||||
if (CO < COLNO || LI < ROWNO) {
|
||||
clipping = TRUE;
|
||||
amii_cliparound(u.ux, u.uy);
|
||||
} else {
|
||||
clipping = FALSE;
|
||||
clipx = clipy = 0;
|
||||
}
|
||||
BufferQueueChar('R' - 64);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
else if (WINVERS_AMIV && shift) {
|
||||
if (WIN_OVER == WIN_ERR) {
|
||||
WIN_OVER = amii_create_nhwindow(NHW_OVER);
|
||||
BufferQueueChar('R' - 64);
|
||||
} else {
|
||||
delayed_key_action = CloseOver;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
return ('?');
|
||||
break;
|
||||
case CURSORLEFT:
|
||||
length = '4';
|
||||
numeric_pad = 1;
|
||||
goto arrow;
|
||||
case CURSORDOWN:
|
||||
length = '2';
|
||||
numeric_pad = 1;
|
||||
goto arrow;
|
||||
case CURSORUP:
|
||||
length = '8';
|
||||
numeric_pad = 1;
|
||||
goto arrow;
|
||||
case CURSORRIGHT:
|
||||
length = '6';
|
||||
numeric_pad = 1;
|
||||
goto arrow;
|
||||
}
|
||||
|
||||
theEvent.ie_Class = IECLASS_RAWKEY;
|
||||
theEvent.ie_Code = message->Code;
|
||||
theEvent.ie_Qualifier = numeric_pad ? IEQUALIFIER_NUMERICPAD : qualifier;
|
||||
theEvent.ie_EventAddress = (APTR)(message->IAddress);
|
||||
|
||||
length = RawKeyConvert(&theEvent, (char *) buffer, (long) sizeof(buffer),
|
||||
NULL);
|
||||
|
||||
if (length == 1) { /* Plain ASCII character */
|
||||
length = buffer[0];
|
||||
/*
|
||||
* If iflags.num_pad is set, movement is by 4286.
|
||||
* If not set, translate 4286 into hjkl.
|
||||
* This way, the numeric pad can /always/ be used
|
||||
* for moving, though best results are when it is off.
|
||||
*/
|
||||
arrow:
|
||||
if (!iflags.num_pad && numeric_pad && length >= '1'
|
||||
&& length <= '9') {
|
||||
length -= '1';
|
||||
if (control) {
|
||||
length = ctrl_numpad[length];
|
||||
} else if (shift) {
|
||||
length = shift_numpad[length];
|
||||
} else {
|
||||
length = numpad[length];
|
||||
}
|
||||
}
|
||||
|
||||
/* Kludge to allow altmeta on eg. scandinavian keymap (# ==
|
||||
shift+alt+3)
|
||||
and prevent it from interfering with # command (M-#) */
|
||||
if (length == ('#' | 0x80))
|
||||
return '#';
|
||||
if (alt && sysflags.altmeta)
|
||||
length |= 0x80;
|
||||
return (length);
|
||||
} /* else shift, ctrl, alt, amiga, F-key, shift-tab, etc */
|
||||
else if (length > 1) {
|
||||
int i;
|
||||
|
||||
if (length == 3 && buffer[0] == 155 && buffer[2] == 126) {
|
||||
int got = 1;
|
||||
switch (buffer[1]) {
|
||||
case 53:
|
||||
mxsize = mysize = 8;
|
||||
break;
|
||||
case 54:
|
||||
mxsize = mysize = 16;
|
||||
break;
|
||||
case 55:
|
||||
mxsize = mysize = 24;
|
||||
break;
|
||||
case 56:
|
||||
mxsize = mysize = 32;
|
||||
break;
|
||||
case 57:
|
||||
mxsize = mysize = 48;
|
||||
break;
|
||||
default:
|
||||
got = 0;
|
||||
break;
|
||||
}
|
||||
#ifdef OPT_DISPMAP
|
||||
dispmap_sanity();
|
||||
#endif
|
||||
|
||||
if (got) {
|
||||
CO = (w->Width - w->BorderLeft - w->BorderRight) / mxsize;
|
||||
LI = (w->Height - w->BorderTop - w->BorderBottom) / mysize;
|
||||
clipxmax = CO + clipx;
|
||||
clipymax = LI + clipy;
|
||||
if (CO < COLNO || LI < ROWNO) {
|
||||
amii_cliparound(u.ux, u.uy);
|
||||
} else {
|
||||
CO = COLNO;
|
||||
LI = ROWNO;
|
||||
}
|
||||
reclip = 1;
|
||||
doredraw();
|
||||
flush_screen(1);
|
||||
reclip = 0;
|
||||
/*BufferQueueChar( 'R'-64 );*/
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
printf("Unrecognized key: %d ", (int) buffer[0]);
|
||||
for (i = 1; i < length; ++i)
|
||||
printf("%d ", (int) buffer[i]);
|
||||
printf("\n");
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process an incoming IntuiMessage.
|
||||
* It would certainly look nicer if this could be done using a
|
||||
* PA_SOFTINT message port, but we cannot call RawKeyConvert()
|
||||
* during a software interrupt.
|
||||
* Anyway, amikbhit()/kbhit() is called often enough, and usually gets
|
||||
* ahead of input demands, when the user types ahead.
|
||||
*/
|
||||
|
||||
static void
|
||||
ProcessMessage(message)
|
||||
register struct IntuiMessage *message;
|
||||
{
|
||||
int c;
|
||||
int cnt;
|
||||
menu_item *mip;
|
||||
static int skip_mouse = 0; /* need to ignore next mouse event on
|
||||
* a window activation */
|
||||
struct Window *w = message->IDCMPWindow;
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSEBUTTONS: {
|
||||
if (skip_mouse) {
|
||||
skip_mouse = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!amii_wins[WIN_MAP] || w != amii_wins[WIN_MAP]->win)
|
||||
break;
|
||||
|
||||
if (message->Code == SELECTDOWN) {
|
||||
lastevent.type = WEMOUSE;
|
||||
lastevent.un.mouse.x = message->MouseX;
|
||||
lastevent.un.mouse.y = message->MouseY;
|
||||
/* With shift equals RUN */
|
||||
lastevent.un.mouse.qual =
|
||||
(message->Qualifier
|
||||
& (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) != 0;
|
||||
}
|
||||
} break;
|
||||
|
||||
case MENUPICK: {
|
||||
USHORT thismenu;
|
||||
struct MenuItem *item;
|
||||
|
||||
thismenu = message->Code;
|
||||
while (thismenu != MENUNULL) {
|
||||
item = ItemAddress(MenuStrip, (ULONG) thismenu);
|
||||
if (KbdBuffered < KBDBUFFER)
|
||||
BufferQueueChar((char) (GTMENUITEM_USERDATA(item)));
|
||||
thismenu = item->NextSelect;
|
||||
}
|
||||
} 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 CLOSEWINDOW:
|
||||
if (WIN_INVEN != WIN_ERR && w == amii_wins[WIN_INVEN]->win) {
|
||||
dismiss_nhwindow(WIN_INVEN);
|
||||
}
|
||||
if (WINVERS_AMIV
|
||||
&& (WIN_OVER != WIN_ERR && w == amii_wins[WIN_OVER]->win)) {
|
||||
destroy_nhwindow(WIN_OVER);
|
||||
WIN_OVER = WIN_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case RAWKEY:
|
||||
if (!(message->Code & IECODE_UP_PREFIX)) {
|
||||
/* May queue multiple characters
|
||||
* but doesn't do that yet...
|
||||
*/
|
||||
if ((c = ConvertKey(message)) > 0)
|
||||
BufferQueueChar(c);
|
||||
}
|
||||
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:
|
||||
if (WIN_MESSAGE != WIN_ERR && w == amii_wins[WIN_MESSAGE]->win) {
|
||||
if (WINVERS_AMIV) {
|
||||
/* Make sure that new size is honored for good. */
|
||||
SetAPen(w->RPort, amii_msgBPen);
|
||||
SetBPen(w->RPort, amii_msgBPen);
|
||||
SetDrMd(w->RPort, JAM2);
|
||||
RectFill(w->RPort, w->BorderLeft, w->BorderTop,
|
||||
w->Width - w->BorderRight - 1,
|
||||
w->Height - w->BorderBottom - 1);
|
||||
}
|
||||
ReDisplayData(WIN_MESSAGE);
|
||||
} else if (WIN_INVEN != WIN_ERR && w == amii_wins[WIN_INVEN]->win) {
|
||||
ReDisplayData(WIN_INVEN);
|
||||
} else if (WINVERS_AMIV && (WIN_OVER != WIN_ERR
|
||||
&& w == amii_wins[WIN_OVER]->win)) {
|
||||
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;
|
||||
LI = (w->Height - w->BorderTop - w->BorderBottom) / mysize;
|
||||
clipxmax = CO + clipx;
|
||||
clipymax = LI + clipy;
|
||||
if (CO < COLNO || LI < ROWNO) {
|
||||
amii_cliparound(u.ux, u.uy);
|
||||
} else {
|
||||
clipping = FALSE;
|
||||
clipx = clipy = 0;
|
||||
}
|
||||
BufferQueueChar('R' - 64);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
ReplyMsg((struct Message *) message);
|
||||
|
||||
switch (delayed_key_action) {
|
||||
case CloseOver:
|
||||
amii_destroy_nhwindow(WIN_OVER);
|
||||
WIN_OVER = WIN_ERR;
|
||||
delayed_key_action = NoAction;
|
||||
case NoAction:
|
||||
; /* null */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* AMII_GRAPHICS */
|
||||
/*
|
||||
* Get all incoming messages and fill up the keyboard buffer,
|
||||
* thus allowing Intuition to (maybe) free up the IntuiMessages.
|
||||
* Return when no more messages left, or keyboard buffer half full.
|
||||
* We need to do this since there is no one-to-one correspondence
|
||||
* between characters and incoming messages.
|
||||
*/
|
||||
|
||||
#if defined(TTY_GRAPHICS) && !defined(AMII_GRAPHICS)
|
||||
int
|
||||
kbhit()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int
|
||||
kbhit()
|
||||
{
|
||||
int c;
|
||||
#ifdef TTY_GRAPHICS
|
||||
/* a kludge to defuse the mess in allmain.c */
|
||||
/* I hope this is the right approach */
|
||||
if (windowprocs.win_init_nhwindows == amii_procs.win_init_nhwindows)
|
||||
return 0;
|
||||
#endif
|
||||
c = amikbhit();
|
||||
if (c <= 0)
|
||||
return (0);
|
||||
return (c);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef AMII_GRAPHICS
|
||||
|
||||
int
|
||||
amikbhit()
|
||||
{
|
||||
register struct IntuiMessage *message;
|
||||
while (KbdBuffered < KBDBUFFER / 2) {
|
||||
#ifdef AMIFLUSH
|
||||
message = (struct IntuiMessage *) GetFMsg(HackPort);
|
||||
#else
|
||||
message = (struct IntuiMessage *) GetMsg(HackPort);
|
||||
#endif
|
||||
if (message) {
|
||||
ProcessMessage(message);
|
||||
if (lastevent.type != WEUNK && lastevent.type != WEKEY)
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return (lastevent.type == WEUNK) ? KbdBuffered : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a character from the keyboard buffer, waiting if not available.
|
||||
* Ignore other kinds of events that happen in the mean time.
|
||||
*/
|
||||
|
||||
int
|
||||
WindowGetchar()
|
||||
{
|
||||
while ((lastevent.type = WEUNK), amikbhit() <= 0) {
|
||||
WaitPort(HackPort);
|
||||
}
|
||||
return BufferGetchar();
|
||||
}
|
||||
|
||||
WETYPE
|
||||
WindowGetevent()
|
||||
{
|
||||
lastevent.type = WEUNK;
|
||||
while (amikbhit() == 0) {
|
||||
WaitPort(HackPort);
|
||||
}
|
||||
|
||||
if (KbdBuffered) {
|
||||
lastevent.type = WEKEY;
|
||||
lastevent.un.key = BufferGetchar();
|
||||
}
|
||||
return (lastevent.type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up everything. But before we do, ask the user to hit return
|
||||
* when there is something that s/he should read.
|
||||
*/
|
||||
|
||||
void
|
||||
amii_cleanup()
|
||||
{
|
||||
register struct IntuiMessage *msg;
|
||||
|
||||
/* Close things up */
|
||||
if (HackPort) {
|
||||
amii_raw_print("");
|
||||
amii_getret();
|
||||
}
|
||||
|
||||
if (ConsoleIO.io_Device)
|
||||
CloseDevice((struct IORequest *) &ConsoleIO);
|
||||
ConsoleIO.io_Device = 0;
|
||||
|
||||
if (ConsoleIO.io_Message.mn_ReplyPort)
|
||||
DeleteMsgPort(ConsoleIO.io_Message.mn_ReplyPort);
|
||||
ConsoleIO.io_Message.mn_ReplyPort = 0;
|
||||
|
||||
/* Strip messages before deleting the port */
|
||||
if (HackPort) {
|
||||
Forbid();
|
||||
while (msg = (struct IntuiMessage *) GetMsg(HackPort))
|
||||
ReplyMsg((struct Message *) msg);
|
||||
kill_nhwindows(1);
|
||||
DeleteMsgPort(HackPort);
|
||||
HackPort = NULL;
|
||||
Permit();
|
||||
}
|
||||
|
||||
/* Close the screen, under v37 or greater it is a pub screen and there may
|
||||
* be visitors, so check close status and wait till everyone is gone.
|
||||
*/
|
||||
if (HackScreen) {
|
||||
#ifdef INTUI_NEW_LOOK
|
||||
if (IntuitionBase->LibNode.lib_Version >= 37) {
|
||||
if (MenuStrip)
|
||||
FreeMenus(MenuStrip);
|
||||
if (VisualInfo)
|
||||
FreeVisualInfo(VisualInfo);
|
||||
while (CloseScreen(HackScreen) == FALSE) {
|
||||
struct EasyStruct easy = {
|
||||
sizeof(struct EasyStruct), 0, "Nethack Problem",
|
||||
"Can't Close Screen, Close Visiting Windows", "Okay"
|
||||
};
|
||||
EasyRequest(NULL, &easy, NULL, NULL);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
CloseScreen(HackScreen);
|
||||
}
|
||||
HackScreen = NULL;
|
||||
}
|
||||
|
||||
#ifdef HACKFONT
|
||||
if (HackFont) {
|
||||
CloseFont(HackFont);
|
||||
HackFont = NULL;
|
||||
}
|
||||
|
||||
if (TextsFont) {
|
||||
CloseFont(TextsFont);
|
||||
TextsFont = NULL;
|
||||
}
|
||||
|
||||
if (RogueFont) {
|
||||
CloseFont(RogueFont);
|
||||
RogueFont = NULL;
|
||||
}
|
||||
|
||||
if (DiskfontBase) {
|
||||
CloseLibrary(DiskfontBase);
|
||||
DiskfontBase = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GadToolsBase) {
|
||||
CloseLibrary((struct Library *) GadToolsBase);
|
||||
GadToolsBase = NULL;
|
||||
}
|
||||
|
||||
if (LayersBase) {
|
||||
CloseLibrary((struct Library *) LayersBase);
|
||||
LayersBase = NULL;
|
||||
}
|
||||
|
||||
if (GfxBase) {
|
||||
CloseLibrary((struct Library *) GfxBase);
|
||||
GfxBase = NULL;
|
||||
}
|
||||
|
||||
if (IntuitionBase) {
|
||||
CloseLibrary((struct Library *) IntuitionBase);
|
||||
IntuitionBase = NULL;
|
||||
}
|
||||
|
||||
#ifdef SHAREDLIB
|
||||
if (DOSBase) {
|
||||
CloseLibrary((struct Library *) DOSBase);
|
||||
DOSBase = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
((struct Process *) FindTask(NULL))->pr_WindowPtr = (APTR) pr_WindowPtr;
|
||||
|
||||
Initialized = 0;
|
||||
}
|
||||
|
||||
#endif /* AMII_GRAPHICS */
|
||||
|
||||
#ifndef SHAREDLIB
|
||||
void
|
||||
Abort(rc)
|
||||
long rc;
|
||||
{
|
||||
int fault = 1;
|
||||
#ifdef CHDIR
|
||||
extern char orgdir[];
|
||||
chdir(orgdir);
|
||||
#endif
|
||||
#ifdef AMII_GRAPHICS
|
||||
if (Initialized && ConsoleDevice
|
||||
&& windowprocs.win_init_nhwindows == amii_procs.win_init_nhwindows) {
|
||||
printf("\n\nAbort with alert code %08lx...\n", rc);
|
||||
amii_getret();
|
||||
} else
|
||||
#endif
|
||||
printf("\n\nAbort with alert code %08lx...\n", rc);
|
||||
/* Alert(rc); this is too severe */
|
||||
#ifdef __SASC
|
||||
#ifdef INTUI_NEW_LOOK
|
||||
if (IntuitionBase->LibNode.lib_Version >= 37) {
|
||||
struct EasyStruct es = {
|
||||
sizeof(struct EasyStruct), 0, "NetHack Panic Request",
|
||||
"NetHack is Aborting with code == 0x%08lx",
|
||||
"Continue Abort|Return to Program|Clean up and exit",
|
||||
};
|
||||
fault = EasyRequest(NULL, &es, NULL, (long) rc);
|
||||
if (fault == 2)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (fault == 1) {
|
||||
/* __emit(0x4afc); */ /* illegal instruction */
|
||||
__emit(0x40fc); /* divide by */
|
||||
__emit(0x0000); /* #0 */
|
||||
/* NOTE: don't move amii_cleanup() above here - */
|
||||
/* it is too likely to kill the system */
|
||||
/* before it can get the SnapShot out, if */
|
||||
/* there is something really wrong. */
|
||||
}
|
||||
#endif
|
||||
#ifdef AMII_GRAPHICS
|
||||
if (windowprocs.win_init_nhwindows == amii_procs.win_init_nhwindows)
|
||||
amii_cleanup();
|
||||
#endif
|
||||
#undef exit
|
||||
#ifdef AZTEC_C
|
||||
_abort();
|
||||
#endif
|
||||
exit((int) rc);
|
||||
}
|
||||
|
||||
void
|
||||
CleanUp()
|
||||
{
|
||||
amii_cleanup();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef AMII_GRAPHICS
|
||||
|
||||
#ifdef AMIFLUSH
|
||||
/* This routine adapted from AmigaMail IV-37 by Michael Sinz */
|
||||
static struct Message *
|
||||
GetFMsg(port)
|
||||
struct MsgPort *port;
|
||||
{
|
||||
struct IntuiMessage *msg, *succ, *succ1;
|
||||
|
||||
if (msg = (struct IntuiMessage *) GetMsg(port)) {
|
||||
if (!sysflags.amiflush)
|
||||
return ((struct Message *) msg);
|
||||
if (msg->Class == RAWKEY) {
|
||||
Forbid();
|
||||
succ = (struct IntuiMessage *) (port->mp_MsgList.lh_Head);
|
||||
while (succ1 = (struct IntuiMessage *) (succ->ExecMessage.mn_Node
|
||||
.ln_Succ)) {
|
||||
if (succ->Class == RAWKEY) {
|
||||
Remove((struct Node *) succ);
|
||||
ReplyMsg((struct Message *) succ);
|
||||
}
|
||||
succ = succ1;
|
||||
}
|
||||
Permit();
|
||||
}
|
||||
}
|
||||
return ((struct Message *) msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct NewWindow *
|
||||
DupNewWindow(win)
|
||||
struct NewWindow *win;
|
||||
{
|
||||
struct NewWindow *nwin;
|
||||
struct Gadget *ngd, *gd, *pgd = NULL;
|
||||
struct PropInfo *pip;
|
||||
struct StringInfo *sip;
|
||||
|
||||
/* Copy the (Ext)NewWindow structure */
|
||||
|
||||
nwin = (struct NewWindow *) alloc(sizeof(struct NewWindow));
|
||||
*nwin = *win;
|
||||
|
||||
/* Now do the gadget list */
|
||||
|
||||
nwin->FirstGadget = NULL;
|
||||
for (gd = win->FirstGadget; gd; gd = gd->NextGadget) {
|
||||
ngd = (struct Gadget *) alloc(sizeof(struct Gadget));
|
||||
*ngd = *gd;
|
||||
if (gd->GadgetType == STRGADGET) {
|
||||
sip = (struct StringInfo *) alloc(sizeof(struct StringInfo));
|
||||
*sip = *((struct StringInfo *) gd->SpecialInfo);
|
||||
sip->Buffer = (UBYTE *) alloc(sip->MaxChars);
|
||||
*sip->Buffer = 0;
|
||||
ngd->SpecialInfo = (APTR) sip;
|
||||
} else if (gd->GadgetType == PROPGADGET) {
|
||||
pip = (struct PropInfo *) alloc(sizeof(struct PropInfo));
|
||||
*pip = *((struct PropInfo *) gd->SpecialInfo);
|
||||
ngd->SpecialInfo = (APTR) pip;
|
||||
}
|
||||
if (pgd)
|
||||
pgd->NextGadget = ngd;
|
||||
else
|
||||
nwin->FirstGadget = ngd;
|
||||
pgd = ngd;
|
||||
ngd->NextGadget = NULL;
|
||||
ngd->UserData = (APTR) 0x45f35c3d; // magic cookie for FreeNewWindow()
|
||||
}
|
||||
return (nwin);
|
||||
}
|
||||
|
||||
void
|
||||
FreeNewWindow(win)
|
||||
struct NewWindow *win;
|
||||
{
|
||||
register struct Gadget *gd, *pgd;
|
||||
register struct StringInfo *sip;
|
||||
|
||||
for (gd = win->FirstGadget; gd; gd = pgd) {
|
||||
pgd = gd->NextGadget;
|
||||
if ((ULONG) gd->UserData == 0x45f35c3d) {
|
||||
if (gd->GadgetType == STRGADGET) {
|
||||
sip = (struct StringInfo *) gd->SpecialInfo;
|
||||
free(sip->Buffer);
|
||||
free(sip);
|
||||
} else if (gd->GadgetType == PROPGADGET) {
|
||||
free((struct PropInfo *) gd->SpecialInfo);
|
||||
}
|
||||
free(gd);
|
||||
}
|
||||
}
|
||||
free(win);
|
||||
}
|
||||
|
||||
void
|
||||
bell()
|
||||
{
|
||||
if (flags.silent)
|
||||
return;
|
||||
DisplayBeep(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
amii_delay_output()
|
||||
{
|
||||
/* delay 50 ms */
|
||||
Delay(2L);
|
||||
}
|
||||
|
||||
void
|
||||
amii_number_pad(state)
|
||||
int state;
|
||||
{
|
||||
}
|
||||
#endif /* AMII_GRAPHICS */
|
||||
|
||||
#ifndef SHAREDLIB
|
||||
void
|
||||
amiv_loadlib(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
amii_loadlib(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* fatal error */
|
||||
/*VARARGS1*/
|
||||
void error
|
||||
VA_DECL(const char *, s)
|
||||
{
|
||||
VA_START(s);
|
||||
VA_INIT(s, char *);
|
||||
|
||||
putchar('\n');
|
||||
vprintf(s, VA_ARGS);
|
||||
putchar('\n');
|
||||
|
||||
VA_END();
|
||||
Abort(0L);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user