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:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user