Revive Amiga port for NetHack 3.7

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

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

View File

@@ -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);