%s.", str);
+ while ((ch = nhgetch()) != '\n' && ch != '\r' )
+ continue;
+}
+
+/* Follow the PATH, trying to fopen the file.
+ */
+#define PATHSEP ';'
+
+FILE *
+fopenp(name, mode)
+register const char *name, *mode;
+{
+ register char *bp, *pp, lastch;
+ register FILE *fp;
+ register BPTR theLock;
+ char buf[BUFSIZ];
+
+ /* Try the default directory first. Then look along PATH.
+ */
+ if (strlen(name) >= BUFSIZ) return( NULL );
+ strcpy(buf, name);
+ if (theLock = Lock(buf, SHARED_LOCK)) {
+ UnLock(theLock);
+ if (fp = fopen(buf, mode))
+ return fp;
+ }
+ pp = PATH;
+ while (pp && *pp) {
+ bp = buf;
+ while (*pp && *pp != PATHSEP){
+ if( bp > buf + BUFSIZ - 1 ) return( NULL );
+ lastch = *bp++ = *pp++;
+ }
+ if (lastch != ':' && lastch != '/' && bp != buf)
+ *bp++ = '/';
+ if (bp + strlen(name) > buf + BUFSIZ - 1) return( NULL );
+ strcpy(bp, name);
+ if (theLock = Lock(buf, SHARED_LOCK)) {
+ UnLock(theLock);
+ if (fp = fopen(buf, mode)) return fp;
+ }
+ if (*pp)
+ pp++;
+ }
+ return NULL;
+}
+#endif /* MFLOPPY */
+
+#ifdef CHDIR
+
+/*
+ * A not general-purpose directory changing routine.
+ * Assumes you want to return to the original directory eventually,
+ * by chdir()ing to orgdir (which is defined in pcmain.c).
+ * Assumes -1 is not a valid lock, since 0 is valid.
+ */
+
+#define NO_LOCK ((BPTR) -1)
+
+static BPTR OrgDirLock = NO_LOCK;
+
+chdir(dir)
+char *dir;
+{
+ extern char orgdir[];
+
+ if (dir == orgdir) {
+ /* We want to go back to where we came from. */
+ if (OrgDirLock != NO_LOCK) {
+ UnLock(CurrentDir(OrgDirLock));
+ OrgDirLock = NO_LOCK;
+ }
+ } else {
+ /*
+ * Go to some new place. If still at the original
+ * directory, save the FileLock.
+ */
+ BPTR newDir;
+
+ if (newDir = Lock( (char *)dir, SHARED_LOCK)) {
+ if (OrgDirLock == NO_LOCK) {
+ OrgDirLock = CurrentDir(newDir);
+ } else {
+ UnLock(CurrentDir(newDir));
+ }
+ } else {
+ return -1; /* Failed */
+ }
+ }
+ /* CurrentDir always succeeds if you have a lock */
+ return 0;
+}
+
+#endif /* CHDIR */
+
+/* Chdir back to original directory
+ */
+#undef exit
+void
+nethack_exit(code)
+{
+#ifdef CHDIR
+ extern char orgdir[];
+#endif
+
+#ifdef CHDIR
+ chdir(orgdir); /* chdir, not chdirx */
+#endif
+
+#ifdef AMII_GRAPHICS
+ if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows)
+ CleanUp();
+#endif
+ exit(code);
+}
+
+void
+regularize(s) /* normalize file name - we don't like :'s or /'s */
+register char *s;
+{
+ register char *lp;
+
+ while((lp = index(s, ':')) || (lp = index(s, '/')))
+ *lp = '_';
+}
diff --git a/sys/amiga/amidos.p b/sys/amiga/amidos.p
new file mode 100644
index 0000000..86c355d
--- /dev/null
+++ b/sys/amiga/amidos.p
@@ -0,0 +1,42 @@
+/* SCCS Id: @(#)amidos.p 3.1 93/01/08
+/* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993. */
+/* NetHack may be freely redistributed. See license for details. */
+
+/* amidos.c */
+void NDECL(flushout );
+#ifndef getuid
+int NDECL(getuid );
+#endif
+#ifndef getpid
+int NDECL(getpid );
+#endif
+#ifndef getlogin
+char *NDECL(getlogin );
+#endif
+#ifndef abs
+int FDECL(abs, (int ));
+#endif
+int NDECL(tgetch );
+int NDECL(dosh );
+long FDECL(freediskspace, (char *));
+long FDECL(filesize, (char *));
+void FDECL(eraseall, (const char * , const char *));
+char *FDECL(CopyFile, (const char * , const char *));
+void FDECL(copybones, (int ));
+void NDECL(playwoRAMdisk );
+int FDECL(saveDiskPrompt, (int ));
+void NDECL(gameDiskPrompt );
+void FDECL(append_slash, (char *));
+void FDECL(getreturn, (const char *));
+#ifndef msmsg
+void FDECL(msmsg, ( const char *, ... ));
+#endif
+#if !defined(__SASC_60) && !defined(_DCC)
+int FDECL(chdir, (char *));
+#endif
+#ifndef strcmpi
+int FDECL(strcmpi, (char * , char *));
+#endif
+#if !defined(memcmp) && !defined(AZTEC_C) && !defined(_DCC)
+int FDECL(memcmp, (unsigned char * , unsigned char * , int ));
+#endif
diff --git a/sys/amiga/amifont.uu b/sys/amiga/amifont.uu
new file mode 100644
index 0000000..3290ddc
--- /dev/null
+++ b/sys/amiga/amifont.uu
@@ -0,0 +1,9 @@
+begin 777 hack.font
+M#P```6AA8VLO.```````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+G````````````````````````````````````````````````"`!`
+`
+end
diff --git a/sys/amiga/amifont8.uu b/sys/amiga/amifont8.uu
new file mode 100644
index 0000000..c6120e1
--- /dev/null
+++ b/sys/amiga/amifont8.uu
@@ -0,0 +1,59 @@
+begin 644 8
+M```#\P`````````!``````````````)E```#Z0```F5P_TYU```````````,
+M`````!H/@``!``````````````````````````````````````````!&140`
+M```````````,`````!H`````"20`"`!```@`!@`!```@_P```&X`M```!@X`
+M```````````8;&P8`#@8##````````,\P\''X?G
+MYVH```!J:A@````8&!@``!@88L!6`%96```8`!@8`*@5P8.BP:@5YP/_[W_^
+M````P,```P`\;&P^QFP8&!AF&`````9F.&9F/&`P9F9F&!@8`!AFQCQF9FQF
+M9F9F&`9F8,;F;&9L9F9:9L/&9L/&,&`,.``8`&``!@`V`&```&`8````````
+M`!@````````8&!B<,Z6BH:&EI*2AI:6EI*2AI*3__\,8`&:DH:6EI:2DH:2D
+MI58```!65CP````8&!@``!@\96-J`&IJ```8`!@8UB/$`\`C+"O4A`/_]Y_Y
+M````P,```P`\`/Y@S&@P,`P\&`````QN&`8&;'Q@!F9F&!@P?@P&WCQFP&9@
+M8,!F&`9L8.[VQF;&9G`89F;&/&:,,#`,;``,/&P\-CPP.VPX!F889GP\W#WL
+M/CYF9F-C9GX8&!@`S.7BY^?GY^?AY^?GY^3GY^?_`.<8`,/GX>?GY^?DY^?G
+MY6K_#_!KZCP````8&!@``!AF8#97_];7`&8<`#@\;&I6)F1I/&F6YP./]]_[
+M#__PP,```P`8`&P\&'8`,`S_?@!^`!A^&!P,Y^&`9X8/[>QGS&?#@89F;6P8,!@,Q@``!G9F;F9X9G88!FP8=V9F9F9V
+M8!AF9FLV9DQP&`X`,Z6BI*&AH:6AI:&EI:2EI*3_`.<8_P`E(24A)24D)20D
+MI595/5Q55F;_#_`/\/\``-O#?AMJ5:JJ```?__C_JIPY:];X*]I;A`-F[\_S
+M.``,/\//C^
+M\#YF?CSF_L;&./`\XSP\/AC&PSS^/`,\````.SP\.SQXQN8\9N8\8V8\8`;P
+M?`P[ C&'X.&'``S`````````````````````#__\,8`&8`````````````
+M`&H`:VH``,,`&!@``!B<P89F-6:E8``&88&!@`K`/`(\0L(T&"``/_W_F?
+MP``#P````````````````````#```````````````````#``````````````
+M```````````````&`````````````````/X`````````?```/```````\`<`
+M````````<```````,P````````````````````#__\,8`&8`````````````
+M`%8`5E8`````&!@``!@``!@8`,!J5FH````8&!@``,J!7!HL``/_[_Y_
+MP``#P`````````@`"``(`!``"``8``@`(``(`"@`"``P``@`.``(`$``"`!(
+M``@`4``(`%@`"`!@``@`:``(`'``"`!X``@`@``(`(@`"`"0``@`F``(`*``
+M"`"H``@`L``(`+@`"`#```@`R``(`-``"`#8``@`X``(`.@`"`#P``@`^``(
+M`0``"`$(``@!$``(`1@`"`$@``@!*``(`3``"`$X``@!0``(`4@`"`%0``@!
+M6``(`6``"`%H``@!<``(`7@`"`&```@!B``(`9``"`&8``@!H``(`:@`"`&P
+M``@!N``(`<``"`'(``@!T``(`=@`"`'@``@!Z``(`?``"`'X``@"```(`@@`
+M"`(0``@"&``(`B``"`(H``@",``(`C@`"`)```@"2``(`E``"`)8``@"8``(
+M`F@`"`)P``@">``(`H``"`*(``@"D``(`I@`"`*@``@"J``(`K``"`*X``@"
+MP``(`L@`"`+0``@"V``(`N``"`+H``@"\``(`O@`"`,```@#"``(`Q``"`,8
+M``@#(``(`R@`"`,P``@#.``(`T``"`-(``@#4``(`U@`"`-@``@#:``(`W``
+M"`-X``@#@``(`X@`"`.0``@#F``(`Z``"`.H``@#L``(`[@`"`/```@#R``(
+M`]``"`/8``@#X``(`^@`"`/P``@#^``(!```"``(``@`$``(`!@`"``@``@`
+M*``(`#``"``X``@`0``(`$@`"`!0``@`6``(`&``"`!H``@`<``(`'@`"`"`
+M``@`B``(`)``"`"8``@`H``(`*@`"`"P``@`N``(`,``"`#(``@`T``(`-@`
+M"`#@``@`Z``(`/``"`#X``@$"``(!!``"`08``@$(``(!"@`"`0P``@#J``(
+M!#@`"`.8``@$0``(!$@`"`10``@$6``(!&``"`1H``@$<``(!'@`"`2```@$
+MB``(!)``"`28``@$H``(!*@`"`2P``@$N``(!,``"`3(``@!V``(`>``"`'H
+M``@!\``(`?@`"`(```@$T``(!-@`"`3@``@$Z``(!/``"`3X``@%```(!0@`
+M"`40``@%&``(!2``"`4H``@%,``(!3@`"`5```@%2``(!5``"`58``@%8``(
+M!6@`"`5P``@%>``(!8``"`6(``@%D``(!9@`"`+8``@"X``(`N@`"`+P``@"
+M^``(````"``````#[`````0`````````#@```$0```!<````8@````````/R
+`
+end
diff --git a/sys/amiga/amigst.c b/sys/amiga/amigst.c
new file mode 100644
index 0000000..04859c4
--- /dev/null
+++ b/sys/amiga/amigst.c
@@ -0,0 +1,43 @@
+/* SCCS Id: @(#)amigst.c 3.1 93/01/08
+/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#undef strcmpi
+#include
+#include
+
+#ifdef __SASC
+#include /* for __emit */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#include "hack.h"
+#include "winprocs.h"
+#include "winami.h"
+
+#ifdef AZTEC
+#include
+#endif
+
+#include "NH:sys/amiga/winami.p"
+#include "NH:sys/amiga/amiwind.p"
+#include "NH:sys/amiga/amidos.p"
+
+/* end amigst.c */
diff --git a/sys/amiga/amii.hlp b/sys/amiga/amii.hlp
new file mode 100644
index 0000000..c014e42
--- /dev/null
+++ b/sys/amiga/amii.hlp
@@ -0,0 +1,31 @@
+ Amiga-specific help file for NetHack 3.4
+
+The Amiga port of NetHack supports a number of additional commands
+and facilities specific to the Amiga. Listed below are the things
+which are either specific to the Amiga port or might not appear
+in other ports.
+
+While playing NetHack you can press:
+
+ ALT-HELP Color requestor.
+ CTL-HELP Scale display (amitile only).
+ SHIFT-HELP Overview window (amitile only).
+
+Amiga-specific run-time options:
+ altmeta use the alt keys as meta keys
+ flush throw away keyboard type-ahead
+
+Command line options recognized are
+
+ -n No News at game startup.
+ -X Play in discovery mode.
+ -D Play in debug mode.
+ -L Interlaced screen.
+ -l Never Interlaced screen.
+ -u Play as player given as
+ an argument.
+ -r Pick a race given as an
+ argument.
+ -p Pick a profession given
+ as an argument
+ -? Gives command line usage.
diff --git a/sys/amiga/amimenu.c b/sys/amiga/amimenu.c
new file mode 100644
index 0000000..422dfba
--- /dev/null
+++ b/sys/amiga/amimenu.c
@@ -0,0 +1,95 @@
+/* SCCS Id: @(#)amimenu.c 3.2 96/02/04 */
+/* Copyright (c) Olaf 'Rhialto' Seibert, 1989 */
+/* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993, 1996 */
+/* Copyright (c) Janne Salmijärvi, 2000 */
+/* NetHack may be freely redistributed. See license for details. */
+
+/* Originally by John Toebes. */
+
+/* GadTools menus by jhsa */
+
+struct NewMenu GTHackMenu[] = {
+ { NM_TITLE, "Commands", 0, 0, 0, 0},
+ { NM_ITEM, "? Display help menu", 0, 0, 0, (void *)'?'},
+ { NM_ITEM, "& Explain a command", 0, 0, 0, (void *)'&'},
+ { NM_ITEM, "O Set options", 0, 0, 0, (void *)'O'},
+ { NM_ITEM, "! AmigaDos command", 0, 0, 0, (void *)'!'},
+ { NM_ITEM, "v Version number", 0, 0, 0, (void *)'v'},
+ { NM_ITEM, "V Long version and game history", 0, 0, 0, (void *)'V'},
+ { NM_ITEM, "^R Redraw screen", 0, 0, 0, (void *)022},
+ { NM_ITEM, "^P Repeat previous messages", 0, 0, 0, (void *)020},
+ { NM_ITEM, "M-q #quit the game", 0, 0, 0, (void *)(128+'q')},
+ { NM_ITEM, "S Save the game", 0, 0, 0, (void *)'S'},
+ { NM_TITLE, "Inventory", 0, 0, 0, 0},
+ { NM_ITEM, "i Inventory", 0, 0, 0, (void *)'i'},
+ { NM_ITEM, "p Pay your bill", 0, 0, 0, (void *)'p'},
+ { NM_ITEM, "d Drop an object", 0, 0, 0, (void *)'d'},
+ { NM_ITEM, "D Drop several things", 0, 0, 0, (void *)'D'},
+ { NM_ITEM, ", Pickup an object", 0, 0, 0, (void *)','},
+ { NM_ITEM, "@ Toggle pickup", 0, 0, 0, (void *)'@'},
+ { NM_ITEM, "/ Identify something", 0, 0, 0, (void *)'/'},
+ { NM_ITEM, "C Christen a monster", 0, 0, 0, (void *)'C'},
+ { NM_ITEM, "+ List known spells", 0, 0, 0, (void *)'+'},
+ { NM_ITEM, "$ Your gold", 0, 0, 0, (void *)'$'},
+ { NM_TITLE, "Actions", 0, 0, 0, 0},
+ { NM_ITEM, "a Apply/use something", 0, 0, 0, (void *)'a'},
+ { NM_ITEM, "e Eat something", 0, 0, 0, (void *)'e'},
+ { NM_ITEM, "f Fire ammunition", 0, 0, 0, (void *)'f'},
+ { NM_ITEM, "F Fight a monster", 0, 0, 0, (void *)'F'},
+ { NM_ITEM, "q Quaff a monster", 0, 0, 0, (void *)'q'},
+ { NM_ITEM, "r Read scroll/book", 0, 0, 0, (void *)'r'},
+ { NM_ITEM, "t Throw something", 0, 0, 0, (void *)'t'},
+ { NM_ITEM, "z Zap a wand", 0, 0, 0, (void *)'z'},
+ { NM_ITEM, "Z Cast a spell", 0, 0, 0, (void *)'Z'},
+ { NM_TITLE, "Preparations", 0, 0, 0, 0},
+ { NM_ITEM, "A Remove all armor", 0, 0, 0, (void *)'A'},
+ { NM_ITEM, "P Put on a ring", 0, 0, 0, (void *)'P'},
+ { NM_ITEM, "R Remove ring", 0, 0, 0, (void *)'R'},
+ { NM_ITEM, "Q Select ammunition for quiver", 0, 0, 0, (void *)'Q'},
+ { NM_ITEM, "T Take off armor", 0, 0, 0, (void *)'T'},
+ { NM_ITEM, "w Wield a weapon", 0, 0, 0, (void *)'w'},
+ { NM_ITEM, "W Wear armor", 0, 0, 0, (void *)'W'},
+ { NM_ITEM, "x Swap wielded and secondary weapons", 0, 0, 0, (void *)'x'},
+ { NM_ITEM, ") Current weapon", 0, 0, 0, (void *)')'},
+ { NM_ITEM, "[ Current armor", 0, 0, 0, (void *)'['},
+ { NM_ITEM, "= Current rings", 0, 0, 0, (void *)'='},
+ { NM_ITEM,"\" Current amulet", 0, 0, 0, (void *)'"'},
+ { NM_ITEM, "( Current tools", 0, 0, 0, (void *)'('},
+ { NM_ITEM, "* Current equipment", 0, 0, 0, (void *)'*'},
+ { NM_TITLE, "Movement", 0, 0, 0, 0},
+ { NM_ITEM, "o Open door", 0, 0, 0, (void *)'o'},
+ { NM_ITEM, "c Close door", 0, 0, 0, (void *)'c'},
+ { NM_ITEM, "^D Kick door", 0, 0, 0, (void *)004},
+ { NM_ITEM, "s Search", 0, 0, 0, (void *)'s'},
+ { NM_ITEM, "< Go up stairs", 0, 0, 0, (void *)'<'},
+ { NM_ITEM, "> Go down stairs", 0, 0, 0, (void *)'>'},
+ { NM_ITEM, "^T Teleport", 0, 0, 0, (void *)024},
+ { NM_ITEM, ". Wait a moment", 0, 0, 0, (void *)'.'},
+ { NM_ITEM, "E Engrave message on floor", 0, 0, 0, (void *)'E'},
+ { NM_TITLE, "Extended", 0, 0, 0, 0},
+ { NM_ITEM, "M-a #adjust inventory letters", 0, 0, 0, (void *)(128+'a')},
+ { NM_ITEM, "M-c #chat with someone", 0, 0, 0, (void *)(128+'c')},
+ { NM_ITEM, "M-d #dip an object into something", 0, 0, 0, (void *)(128+'d')},
+#ifdef WEAPON_SKILLS
+ { NM_ITEM, "M-e #enhance weapon skills", 0, 0, 0, (void *)(128+'e')},
+#endif
+ { NM_ITEM, "M-f #force a lock", 0, 0, 0, (void *)(128+'f')},
+ { NM_ITEM, "M-i #invoke an object's special powers", 0, 0, 0, (void *)(128+'i')},
+ { NM_ITEM, "M-j #jump to another location", 0, 0, 0, (void *)(128+'j')},
+ { NM_ITEM, "M-l #loot a box on the floor", 0, 0, 0, (void *)(128+'l')},
+ { NM_ITEM, "M-m Use a #monster's special ability", 0, 0, 0, (void *)(128+'m')},
+ { NM_ITEM, "M-n #name an item or type of object", 0, 0, 0, (void *)(128+'n')},
+ { NM_ITEM, "M-o #offer a sacrifice to the gods", 0, 0, 0, (void *)(128+'o')},
+ { NM_ITEM, "M-p #pray to the gods for help", 0, 0, 0, (void *)(128+'p')},
+ { NM_ITEM, "M-q #quit the game", 0, 0, 0, (void *)(128+'q')},
+ { NM_ITEM, "M-r #rub a lamp", 0, 0, 0, (void *)(128+'r')},
+ { NM_ITEM, "M-s #sit down", 0, 0, 0, (void *)(128+'s')},
+ { NM_ITEM, "M-t #turn undead", 0, 0, 0, (void *)(128+'t')},
+ { NM_ITEM, "M-u #untrap something", 0, 0, 0, (void *)(128+'u')},
+ { NM_ITEM, "M-v Long #version information", 0, 0, 0, (void *)(128+'v')},
+ { NM_ITEM, "M-w #wipe off your face", 0, 0, 0, (void *)(128+'w')},
+ { NM_ITEM, " Your #conduct", 0, 0, 0, (void *)'#'}, /* "#co\n" */
+ { NM_ITEM, " #ride your steed", 0, 0, 0, (void *)'#'}, /* "#ri\n" */
+ { NM_ITEM, "M-2 Switch #twoweapon mode on/off", 0, 0, 0, (void *)(128+'2')},
+ { NM_END, NULL, 0, 0, 0, 0}
+};
diff --git a/sys/amiga/amirip.c b/sys/amiga/amirip.c
new file mode 100644
index 0000000..c41110a
--- /dev/null
+++ b/sys/amiga/amirip.c
@@ -0,0 +1,405 @@
+/* SCCS Id: @(#)amirip.c 3.2 96/02/04 */
+/* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1991,1992,1993,1995,1996. */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include "hack.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "winami.h"
+#include "windefs.h"
+#include "winext.h"
+#include "winproto.h"
+
+static struct RastPort *rp;
+
+#ifdef AMII_GRAPHICS
+
+#undef NULL
+#define NULL 0
+
+#ifdef AZTEC_C
+# include
+#else
+# ifdef _DCC
+# include
+# include
+# include
+# include
+# else
+# include
+# include
+# include
+# include
+# endif
+
+static char *load_list[]={"tomb.iff",0};
+static BitMapHeader tomb_bmhd;
+static struct BitMap *tbmp[ 1 ] = {0};
+
+static int cols[2]={154,319}; /* X location of center of columns */
+static int cno = 0; /* current column */
+#define TEXT_TOP (65+yoff)
+
+static xoff, yoff; /* image centering */
+
+/* terrible kludge */
+/* this is why prototypes should have ONLY types in them! */
+# undef red
+# undef green
+# undef blue
+# undef index
+# ifdef _DCC
+# include
+# include
+# else
+# include
+# include
+# endif
+#endif /* AZTEC_C */
+
+extern char *killed_by_prefix[];
+static struct Window *ripwin=0;
+static void tomb_text(char*);
+static void dofade(int,int,int);
+static int search_cmap(int,int,int);
+
+#define STONE_LINE_LEN 13 /* # chars that fit on one line
+ * (note 1 ' ' border) */
+
+#define DEATH_LINE 10
+#define YEAR_LINE 15
+
+static unsigned short tomb_line;
+
+extern struct amii_DisplayDesc *amiIDisplay;
+extern struct Screen *HackScreen;
+extern int havelace;
+
+static unsigned short transpalette[ AMII_MAXCOLORS ] = { 0x0000, };
+
+static struct NewWindow newwin =
+{
+ 0,0,640,200,1,0,
+ MOUSEBUTTONS|VANILLAKEY|NOCAREREFRESH,
+ BORDERLESS|ACTIVATE|SMART_REFRESH,
+ NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN
+};
+
+int wh; /* was local in outrip, but needed for SCALE macro */
+
+int cmap_white, cmap_black;
+
+void
+amii_outrip( tmpwin, how )
+winid tmpwin;
+int how;
+{
+ int just_return = 0;
+ int done, rtxth;
+ struct IntuiMessage *imsg;
+ int i;
+ register char *dpx;
+ char buf[ 200 ];
+ int line, tw, ww;
+ char *errstr = NULL;
+
+ if(!WINVERS_AMIV || HackScreen->RastPort.BitMap->Depth < 4)goto cleanup;
+
+ /* Use the users display size */
+ newwin.Height = amiIDisplay->ypix - newwin.TopEdge;
+ newwin.Width = amiIDisplay->xpix;
+ newwin.Screen = HackScreen;
+
+ for( i = 0; i < amii_numcolors; ++i )
+ flags.amii_curmap[i] = GetRGB4( HackScreen->ViewPort.ColorMap, i );
+
+ ripwin = OpenWindow( (void *)&newwin );
+ if( !ripwin ) goto cleanup;
+
+ LoadRGB4( &HackScreen->ViewPort, transpalette, amii_numcolors );
+
+ rp= ripwin->RPort;
+ wh = ripwin->Height;
+ ww = ripwin->Width;
+
+#ifdef HACKFONT
+ if (HackFont)
+ SetFont(rp, HackFont);
+#endif
+
+ tomb_bmhd = ReadImageFiles(load_list, tbmp, &errstr );
+ if(errstr)goto cleanup;
+ if(tomb_bmhd.w > ww || tomb_bmhd.h > wh)goto cleanup;
+
+#define GENOFF(full,used) ((((full)-(used))/2) & ~7)
+ xoff = GENOFF(ww,tomb_bmhd.w);
+ yoff = GENOFF(wh,tomb_bmhd.h);
+ for(i=0;iBitMap, xoff, yoff, tomb_bmhd.w, tomb_bmhd.h, 0xc0, 0xff, NULL);
+
+ /* Put together death description */
+ switch (killer_format) {
+ default:
+ impossible("bad killer format?");
+ case KILLED_BY_AN:
+ Strcpy(buf, killed_by_prefix[how]);
+ Strcat(buf, an(killer));
+ break;
+ case KILLED_BY:
+ Strcpy(buf, killed_by_prefix[how]);
+ Strcat(buf, killer);
+ break;
+ case NO_KILLER_PREFIX:
+ Strcpy(buf, killer);
+ break;
+ }
+
+ tw = TextLength(rp,buf,STONE_LINE_LEN) + 40;
+
+ {
+ char *p=buf;
+ int x, tmp;
+ for(x=STONE_LINE_LEN;x;x--)*p++='W';
+ *p='\0';
+ tmp = TextLength(rp,buf,STONE_LINE_LEN) + 40;
+ tw = max( tw, tmp);
+ }
+
+ /* There are 5 lines of text on the stone. */
+ rtxth = ripwin->RPort->TxHeight * 5;
+
+ SetAfPt( rp, (UWORD *)NULL, 0 );
+ SetDrPt( rp, 0xFFFF );
+
+ tomb_line=TEXT_TOP;
+
+ SetDrMd(rp,JAM1);
+
+ /* Put name on stone */
+ Sprintf(buf, "%s", plname);
+ buf[STONE_LINE_LEN] = 0;
+ tomb_text(buf);
+
+ /* Put $ on stone */
+ Sprintf(buf, "%ld Au",
+#ifndef GOLDOBJ
+ u.ugold);
+#else
+ done_money);
+#endif
+ buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */
+ tomb_text(buf);
+
+ /* Put together death description */
+ switch (killer_format) {
+ default:
+ impossible("bad killer format?");
+ case KILLED_BY_AN:
+ Strcpy(buf, killed_by_prefix[how]);
+ Strcat(buf, an(killer));
+ break;
+ case KILLED_BY:
+ Strcpy(buf, killed_by_prefix[how]);
+ Strcat(buf, killer);
+ break;
+ case NO_KILLER_PREFIX:
+ Strcpy(buf, killer);
+ break;
+ }
+
+ /* Put death type on stone */
+ for (line=DEATH_LINE, dpx = buf; line STONE_LINE_LEN)
+ {
+ for(i=STONE_LINE_LEN;((i0 > STONE_LINE_LEN) && i); i--)
+ {
+ if(dpx[i] == ' ')
+ i0 = i;
+ }
+ if(!i)
+ i0 = STONE_LINE_LEN;
+ }
+
+ tmpchar = dpx[i0];
+ dpx[i0] = 0;
+ tomb_text(dpx);
+
+ if (tmpchar != ' ')
+ {
+ dpx[i0] = tmpchar;
+ dpx= &dpx[i0];
+ }
+ else
+ {
+ dpx= &dpx[i0+1];
+ }
+ }
+
+ /* Put year on stone */
+ Sprintf(buf, "%4d", getyear());
+ tomb_text(buf);
+
+#ifdef NH320_DEDICATION
+ /* dedication */
+ cno = 1;
+ tomb_line=TEXT_TOP;
+ tomb_text("This release");
+ tomb_text("of NetHack");
+ tomb_text("is dedicated");
+ tomb_text("to the");
+ tomb_text("memory of");
+ tomb_text("");
+ tomb_text("Izchak");
+ tomb_text(" Miller");
+ tomb_text("");
+ tomb_text("1935-1994");
+ tomb_text("");
+ tomb_text("Ascended");
+#endif
+ /* Fade from black to full color */
+ dofade(0,16,1);
+
+ /* Flush all messages to avoid typeahead */
+ while( imsg = (struct IntuiMessage *)GetMsg( ripwin->UserPort ) )
+ ReplyMsg( (struct Message *) imsg );
+ done = 0;
+ while( !done )
+ {
+ WaitPort( ripwin->UserPort );
+ while( imsg = (struct IntuiMessage *)GetMsg(ripwin->UserPort) )
+ {
+ switch( imsg->Class )
+ {
+ case MOUSEBUTTONS:
+ case VANILLAKEY:
+ done = 1;
+ break;
+ }
+ ReplyMsg( (struct Message *)imsg );
+ }
+ }
+
+ /* Fade out */
+ dofade(16,0,-1);
+ just_return = 1;
+
+cleanup:
+ /* free everything */
+ if(ripwin){
+ Forbid();
+ while( imsg = (struct IntuiMessage *)GetMsg( ripwin->UserPort ) )
+ ReplyMsg( (struct Message *)imsg );
+ CloseWindow( ripwin );
+ Permit();
+ }
+ LoadRGB4( &HackScreen->ViewPort, flags.amii_curmap, amii_numcolors );
+
+ if(tbmp[0])FreeImageFiles(load_list, tbmp);
+ if(just_return) return;
+ /* fall back to the straight-ASCII version */
+ genl_outrip(tmpwin, how);
+}
+
+static void tomb_text(p)
+char *p;
+{
+ char buf[STONE_LINE_LEN*2];
+ int l;
+
+ tomb_line += rp->TxHeight;
+
+ if( !*p )
+ return;
+ sprintf(buf," %s ",p);
+ l=TextLength(rp,buf,strlen(buf));
+
+ SetAPen(rp,cmap_white);
+ Move(rp,cols[cno]-(l/2)-1, tomb_line);
+ Text(rp,buf,strlen(buf));
+
+ SetAPen(rp,cmap_white);
+ Move(rp,cols[cno]-(l/2)+1, tomb_line);
+ Text(rp,buf,strlen(buf));
+
+ SetAPen(rp,cmap_white);
+ Move(rp,cols[cno]-(l/2), tomb_line-1);
+ Text(rp,buf,strlen(buf));
+
+ SetAPen(rp,cmap_white);
+ Move(rp,cols[cno]-(l/2), tomb_line+1);
+ Text(rp,buf,strlen(buf));
+
+ SetAPen(rp,cmap_black);
+ Move(rp,cols[cno]-(l/2), tomb_line);
+ Text(rp,buf,strlen(buf));
+}
+
+/* search colormap for best match to given color */
+static int
+search_cmap(int r0, int g0, int b0){
+ int best = 0;
+ int bdiff = 0x0fffffff;
+ int x;
+ for(x=0;x> 8) & 15);
+ int g = g0-((amiv_init_map[x] >> 4) & 15);
+ int b = b0-((amiv_init_map[x] ) & 15);
+ int diff = (r*r) + (g*g) + (b*b);
+ if(diff> 8;
+ g = ( amiv_init_map[ j ] & 0xf0 ) >> 4;
+ b = ( amiv_init_map[ j ] & 0xf );
+ r = ( r * i ) / 16;
+ g = ( g * i ) / 16;
+ b = ( b * i ) / 16;
+ transpalette[ j ] = ((r<<8)|(g<<4)|b);
+ }
+ LoadRGB4( &HackScreen->ViewPort, transpalette, amii_numcolors );
+ Delay( 1 );
+ }
+}
+
+
+
+#endif /* AMII_GRAPHICS */
+
+/*
+TODO:
+ memory leaks
+ fix ReadImageFiles to return error instead of panic on error
+*/
diff --git a/sys/amiga/amisnd.c b/sys/amiga/amisnd.c
new file mode 100644
index 0000000..85a007d
--- /dev/null
+++ b/sys/amiga/amisnd.c
@@ -0,0 +1,284 @@
+/* SCCS Id: @(#)amisnd.c 3.2 2000/01/12*/
+/* Copyright (c) 1992, 1993, 1995 by Gregg Wonderly */
+/* NetHack may be freely redistributed. See license for details. */
+
+/*
+ * This file contains music playing code.
+ *
+ * If we were REALLY determined, we would make the sound play
+ * asynchronously, but I'll save that one for a rainy day...
+ */
+
+#include "hack.h"
+#include "dlb.h"
+
+#undef red
+#undef blue
+#undef green
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#define AMII_AVERAGE_VOLUME 60
+
+int amii_volume = AMII_AVERAGE_VOLUME;
+
+typedef struct VHDR
+{
+ char name[4];
+ long len;
+ unsigned long oneshot, repeat, samples;
+ UWORD freq;
+ UBYTE n_octaves, compress;
+ LONG volume;
+} VHDR;
+
+typedef struct IFFHEAD
+{
+ char FORM[4];
+ long flen;
+ char _8SVX[4];
+ VHDR vhdr;
+ char NAME[4];
+ long namelen;
+} IFFHEAD;
+
+extern struct GfxBase *GfxBase;
+
+UBYTE whichannel[] = { 1, 2, 4, 8 };
+void makesound( char *, char *, int vol);
+void amii_speaker( struct obj *instr, char *melody, int vol );
+
+/* A major scale in indexs to freqtab... */
+int notetab[] = { 0, 2, 4, 5, 7, 9, 11, 12 };
+
+/* Frequencies for a scale starting at one octave below 'middle C' */
+long freqtab[] = {
+ 220, /*A */
+ 233, /*Bb*/
+ 246, /*B */
+ 261, /*C */
+ 277, /*Db*/
+ 293, /*D */
+ 311, /*Eb*/
+ 329, /*E */
+ 349, /*F */
+ 370, /*Gb*/
+ 392, /*G */
+ 415, /*Ab*/
+ 440, /*A */
+};
+
+#ifdef TESTING
+main( argc, argv )
+ int argc;
+ char **argv;
+{
+ makesound( "wooden_flute", "AwBwCwDwEwFwGwawbwcwdwewfwgw", 60 );
+ makesound( "wooden_flute", "AhBhChDhEhFhGhahbhchdhehfhgh", 60 );
+ makesound( "wooden_flute", "AqBqCqDqEqFqGqaqbqcqdqeqfqgq", 60 );
+ makesound( "wooden_flute", "AeBeCeDeEeFeGeaebecedeeefege", 60 );
+ makesound( "wooden_flute", "AxBxCxDxExFxGxaxbxcxdxexfxgx", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+ makesound( "wooden_flute", "AtBtCtDtEtFtGtatbtctdtetftgt", 60 );
+}
+#else
+void
+amii_speaker( struct obj *instr, char *melody, int vol )
+{
+ int typ = instr->otyp;
+ char * actualn = (char *)OBJ_NAME( objects[typ] ) ;
+
+ /* Make volume be relative to users volume level, with 60 being the
+ * average level that will be passed to us.
+ */
+ vol = vol * amii_volume / AMII_AVERAGE_VOLUME;
+
+ makesound( actualn, melody, vol );
+}
+#endif
+
+void
+makesound ( char *actualn , char * melody, int vol )
+{
+ char *t;
+ int c, cycles, dot, dlay;
+ dlb *stream = 0;
+ IFFHEAD iffhead;
+ struct IOAudio *AudioIO = 0;
+ struct MsgPort *AudioMP = 0;
+ struct Message *AudioMSG = 0;
+ ULONG device = -1;
+ BYTE *waveptr = 0;
+ LONG frequency=440, duration=1, clock, samp, samples, samcyc=1;
+ unsigned char name [ 100 ] ;
+
+ if ( flags.silent )
+ return;
+
+ if( GfxBase->DisplayFlags & PAL )
+ clock = 3546895;
+ else
+ clock = 3579545;
+
+ /*
+ * Convert type to file name - if there's nothing to play we
+ * shouldn't be here in the first place.
+ */
+ strncpy(name, actualn,sizeof(name) ) ;
+ for( t = strchr( name, ' ' ); t; t = strchr( name, ' ' ) )
+ *t = '_';
+ if( (stream = dlb_fopen( name, "r" )) == NULL )
+ {
+ perror( name );
+ return;
+ }
+
+ AudioIO = (struct IOAudio *)
+ AllocMem( sizeof( struct IOAudio ), MEMF_PUBLIC|MEMF_CLEAR );
+ if( AudioIO == 0 )
+ goto killaudio;
+
+ AudioMP = CreateMsgPort();
+ if( AudioMP == 0 )
+ goto killaudio;
+
+ AudioIO->ioa_Request.io_Message.mn_ReplyPort = AudioMP;
+ AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri = 0;
+ AudioIO->ioa_Request.io_Command = ADCMD_ALLOCATE;
+ AudioIO->ioa_Request.io_Flags = ADIOF_NOWAIT;
+ AudioIO->ioa_AllocKey = 0;
+ AudioIO->ioa_Data = whichannel;
+ AudioIO->ioa_Length = sizeof( whichannel );
+
+ device = OpenDevice( AUDIONAME, 0L, (struct IORequest *)AudioIO, 0L );
+ if( device != 0 )
+ goto killaudio;
+
+ if( dlb_fread( (genericptr_t)&iffhead, sizeof( iffhead ), 1, stream ) != 1 )
+ goto killaudio;
+
+ /* This is an even number of bytes long */
+ if( dlb_fread( name, (iffhead.namelen+1) & ~1, 1, stream ) != 1 )
+ goto killaudio;
+
+ if( dlb_fread( (genericptr_t)&samples, 4, 1, stream ) != 1 )
+ goto killaudio;
+
+ if( dlb_fread( (genericptr_t)&samples, 4, 1, stream ) != 1 )
+ goto killaudio;
+
+ waveptr = AllocMem( samples, MEMF_CHIP|MEMF_PUBLIC );
+ if( !waveptr )
+ goto killaudio;
+
+ if( dlb_fread( waveptr, samples, 1, stream ) != 1 )
+ goto killaudio;
+
+ while( melody[0] && melody[1] )
+ {
+ c = *melody++;
+ duration = *melody++;
+ dot = 0;
+ if( *melody == '.' )
+ {
+ dot = 1;
+ ++melody;
+ }
+ switch( duration )
+ {
+ case 'w': dlay = 3; duration = 1; cycles = 1; break;
+ case 'h': dlay = 3; duration = 2; cycles = 1; break;
+ case 'q': dlay = 2; duration = 4; cycles = 1; break;
+ case 'e': dlay = 1; duration = 8; cycles = 1; break;
+ case 'x': dlay = 0; duration = 16; cycles = 1; break;
+ case 't': dlay = 0; duration = 32; cycles = 1; break;
+ default: goto killaudio; /* unrecognized duration */
+ }
+
+ /* Lower case characters are one octave above upper case */
+ switch( c )
+ {
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f': case 'g':
+ c -= 'a' - 7;
+ break;
+
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F': case 'G':
+ c -= 'A';
+ break;
+
+ default:
+ continue;
+ }
+
+ samcyc = samples;
+
+ /* lowercase start at middle 'C', upper case are one octave below */
+ frequency = c > 7 ? freqtab[notetab[c%7]]*2 : freqtab[notetab[c]];
+
+ /* We can't actually do a dotted whole note unless we add code for a real
+ * 8SVX sample which includes sustain sample information to tell us how
+ * to hold the note steady... So when duration == 1, ignore 'dot'...
+ */
+ if( dot && duration > 1 )
+ samp = ((samples / duration) * 3) / 2;
+ else
+ samp = samples / duration;
+
+ /* Only use some of the samples based on frequency */
+ samp = frequency * samp / 880;
+
+ /* The 22khz samples are middle C samples, so adjust the play
+ * back frequency accordingly
+ */
+ frequency = (frequency * (iffhead.vhdr.freq*2)/3) / 440L;
+
+ AudioIO->ioa_Request.io_Message.mn_ReplyPort = AudioMP;
+ AudioIO->ioa_Request.io_Command = CMD_WRITE;
+ AudioIO->ioa_Request.io_Flags = ADIOF_PERVOL;
+ AudioIO->ioa_Data = (BYTE *)waveptr;
+ AudioIO->ioa_Length = samp;
+
+ /* The clock rate represents the unity rate, so dividing by
+ * the frequency gives us a period ratio...
+ */
+/*printf( "clock: %ld, freq: %ld, div: %ld\n", clock, frequency, clock/frequency );*/
+ AudioIO->ioa_Period = clock/frequency;
+ AudioIO->ioa_Volume = vol;
+ AudioIO->ioa_Cycles = cycles;
+
+ BeginIO( (struct IORequest *)AudioIO );
+ WaitPort( AudioMP );
+ AudioMSG = GetMsg( AudioMP );
+ if( dlay )
+ Delay( dlay );
+ }
+
+ killaudio:
+ if( stream ) dlb_fclose( stream );
+ if( waveptr ) FreeMem( waveptr, samples );
+ if( device == 0 ) CloseDevice( (struct IORequest *)AudioIO );
+ if( AudioMP ) DeleteMsgPort( AudioMP );
+ if( AudioIO ) FreeMem( AudioIO, sizeof( *AudioIO ) );
+}
diff --git a/sys/amiga/amistack.c b/sys/amiga/amistack.c
new file mode 100644
index 0000000..7e0b6fc
--- /dev/null
+++ b/sys/amiga/amistack.c
@@ -0,0 +1,21 @@
+/* SCCS Id: @(#)amistack.c 3.4 2000/05/03 */
+/* Copyright (c) Janne Salmijärvi, Tampere, Finland, 2000 */
+/* NetHack may be freely redistributed. See license for details. */
+
+/*
+ * Increase stack size to allow deep recursions.
+ *
+ * Note: This is SAS/C specific, using other compiler probably
+ * requires another method for increasing stack.
+ *
+ */
+
+#ifdef __SASC_60
+#include
+
+/*
+ * At the moment 90*1024 would suffice, but just to be on the safe side ...
+ */
+
+long __stack = 128*1024;
+#endif
diff --git a/sys/amiga/amitty.c b/sys/amiga/amitty.c
new file mode 100644
index 0000000..236d4b3
--- /dev/null
+++ b/sys/amiga/amitty.c
@@ -0,0 +1,67 @@
+/* SCCS Id: @(#)amitty.c 3.2 2000/01/12
+/* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */
+/* NetHack may be freely redistributed. See license for details. */
+
+/* TTY-specific code for the Amiga
+ * This is still experimental.
+ * Still to do:
+ * add real termcap handling - currently requires ANSI_DEFAULT
+ */
+
+#include "hack.h"
+#include "tcap.h"
+#include
+#include
+
+#ifdef _DCC
+# define getch() getchar()
+#endif
+#ifdef __SASC_60
+# include
+#endif
+
+void NDECL( tty_change_color );
+char *NDECL( tty_get_color_string );
+
+#ifdef TTY_GRAPHICS
+
+int amibbs=0; /* BBS mode */
+char bbs_id[80]=""; /* BBS uid equivalent */
+long afh_in, afh_out; /* BBS mode Amiga filehandles */
+
+void settty(const char *s){
+ end_screen();
+ if(s)raw_print(s);
+ iflags.cbreak=ON; /* this is too easy: probably wrong */
+#if 1 /* should be version>=36 */
+/* if(IsInteractive(afh_in)){ */
+ SetMode(afh_in,0); /* con mode */
+/* } */
+#endif
+}
+void gettty(){
+#if 1 /* should be VERSION >=36 */
+/* if(IsInteractive(afh_in)){ */
+ SetMode(afh_in,1); /* raw mode */
+/* } */
+#endif
+}
+void setftty(){
+ iflags.cbreak=ON; /* ditto */
+}
+char kill_char='X'-'@';
+char erase_char='\b';
+tgetch(){
+ char x;
+ Read(afh_in,&x,1);
+ return (x=='\r')?'\n':x;
+}
+void get_scr_size(){
+ CO=80;
+ LI=24;
+}
+
+#endif
+
+void tty_change_color() {}
+char *tty_get_color_string() { return( "" ); }
diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c
new file mode 100644
index 0000000..fab7f72
--- /dev/null
+++ b/sys/amiga/amiwind.c
@@ -0,0 +1,953 @@
+/* SCCS Id: @(#)amiwind.c 3.2 2000/01/12
+/* Copyright (c) Olaf Seibert (KosmoSoft), 1989, 1992 */
+/* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include "NH:sys/amiga/windefs.h"
+#include "NH:sys/amiga/winext.h"
+#include "NH:sys/amiga/winproto.h"
+
+/* 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 *FDECL(GetFMsg,(struct MsgPort *));
+#endif
+
+static int BufferGetchar(void);
+static void ProcessMessage( register struct IntuiMessage *message );
+
+#define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch))
+
+#ifdef __GNUC__ /* Conflicting includefiles ... */
+struct Device *ConsoleDevice;
+#else
+struct Library *ConsoleDevice;
+#endif
+
+#include "NH:sys/amiga/amimenu.c"
+
+/* 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 FDECL(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(flags.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 && flags.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(!flags.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
diff --git a/sys/amiga/amiwind.p b/sys/amiga/amiwind.p
new file mode 100644
index 0000000..ca009d4
--- /dev/null
+++ b/sys/amiga/amiwind.p
@@ -0,0 +1,40 @@
+/* SCCS Id: @(#)amiwind.p 3.1 93/01/08 */
+/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */
+/* NetHack may be freely redistributed. See license for details. */
+
+/* amiwind.c */
+#ifdef INTUI_NEW_LOOK
+struct Window *FDECL( OpenShWindow, (struct ExtNewWindow *) );
+#else
+struct Window *FDECL( OpenShWindow, (struct NewWindow *) );
+#endif
+void FDECL( CloseShWindow, (struct Window *));
+int NDECL( kbhit );
+int NDECL( amikbhit );
+int NDECL( WindowGetchar );
+WETYPE NDECL( WindowGetevent );
+void NDECL( WindowFlush );
+void FDECL( WindowPutchar, (char ));
+void FDECL( WindowFPuts, (const char *));
+void FDECL( WindowPuts, (const char *));
+void FDECL( WindowPrintf, ( char *,... ));
+void NDECL( CleanUp );
+int FDECL( ConvertKey, ( struct IntuiMessage * ));
+#ifndef SHAREDLIB
+void FDECL( Abort, (long ));
+#endif
+void FDECL( flush_glyph_buffer, (struct Window *));
+void FDECL( amiga_print_glyph, (winid , int , int ));
+void FDECL( start_glyphout, (winid ));
+void FDECL( amii_end_glyphout, (winid ));
+#ifdef INTUI_NEW_LOOK
+struct ExtNewWindow *FDECL( DupNewWindow, (struct ExtNewWindow *));
+void FDECL( FreeNewWindow, (struct ExtNewWindow *));
+#else
+struct NewWindow *FDECL( DupNewWindow, (struct NewWindow *));
+void FDECL( FreeNewWindow, (struct NewWindow *));
+#endif
+void NDECL( bell );
+void NDECL( amii_delay_output );
+void FDECL( amii_number_pad, (int ));
+void amii_cleanup( void );
diff --git a/sys/amiga/clipwin.c b/sys/amiga/clipwin.c
new file mode 100644
index 0000000..a5ede30
--- /dev/null
+++ b/sys/amiga/clipwin.c
@@ -0,0 +1,268 @@
+static USHORT Palette[] = {
+ 0x0AAA, /* color #0 */
+ 0x0000, /* color #1 */
+ 0x0FFF, /* color #2 */
+ 0x058B, /* color #3 */
+ 0x000F, /* color #4 */
+ 0x0F0F, /* color #5 */
+ 0x00FF, /* color #6 */
+ 0x0FFF /* color #7 */
+#define PaletteColorCount 8
+};
+
+#define PALETTE Palette
+
+static SHORT ClipBorderVectors1[] = {
+ 0,0,
+ 76,0,
+ 76,11,
+ 0,11,
+ 0,0
+};
+static struct Border ClipBorder1 = {
+ -1,-1, /* XY origin relative to container TopLeft */
+ 3,0,JAM1, /* front pen, back pen and drawmode */
+ 5, /* number of XY vectors */
+ ClipBorderVectors1, /* pointer to XY vectors */
+ NULL /* next border in list */
+};
+
+static struct IntuiText ClipIText1 = {
+ 4,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ 15,1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "Cancel", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+static struct Gadget ClipCancel = {
+ NULL, /* next gadget */
+ 240,59, /* origin XY of hit box relative to window TopLeft */
+ 75,10, /* hit box width and height */
+ NULL, /* gadget flags */
+ RELVERIFY, /* activation flags */
+ BOOLGADGET, /* gadget type flags */
+ (APTR)&ClipBorder1, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &ClipIText1, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ NULL, /* SpecialInfo structure */
+ GADCANCEL, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+static SHORT ClipBorderVectors2[] = {
+ 0,0,
+ 78,0,
+ 78,11,
+ 0,11,
+ 0,0
+};
+static struct Border ClipBorder2 = {
+ -1,-1, /* XY origin relative to container TopLeft */
+ 3,0,JAM1, /* front pen, back pen and drawmode */
+ 5, /* number of XY vectors */
+ ClipBorderVectors2, /* pointer to XY vectors */
+ NULL /* next border in list */
+};
+
+static struct IntuiText ClipIText2 = {
+ 4,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ 24,1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "Okay", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+static struct Gadget ClipOkay = {
+ &ClipCancel, /* next gadget */
+ 17,60, /* origin XY of hit box relative to window TopLeft */
+ 77,10, /* hit box width and height */
+ NULL, /* gadget flags */
+ RELVERIFY, /* activation flags */
+ BOOLGADGET, /* gadget type flags */
+ (APTR)&ClipBorder2, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &ClipIText2, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ NULL, /* SpecialInfo structure */
+ GADOKAY, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+static struct PropInfo ClipClipXCLIPSInfo = {
+ AUTOKNOB+FREEHORIZ, /* PropInfo flags */
+ 24504,-1, /* horizontal and vertical pot values */
+ 10922,-1, /* horizontal and vertical body values */
+};
+
+static struct Image ClipImage1 = {
+ 43,0, /* XY origin relative to container TopLeft */
+ 24,3, /* Image width and height in pixels */
+ 0, /* number of bitplanes in Image */
+ NULL, /* pointer to ImageData */
+ 0x0000,0x0000, /* PlanePick and PlaneOnOff */
+ NULL /* next Image structure */
+};
+
+static struct IntuiText ClipIText3 = {
+ 3,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ -116,-1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "X Clip Border:", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+static struct Gadget ClipXCLIP = {
+ &ClipOkay, /* next gadget */
+ 134,37, /* origin XY of hit box relative to window TopLeft */
+ -199,7, /* hit box width and height */
+ GRELWIDTH, /* gadget flags */
+ RELVERIFY+GADGIMMEDIATE, /* activation flags */
+ PROPGADGET, /* gadget type flags */
+ (APTR)&ClipImage1, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &ClipIText3, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ (APTR)&ClipClipXCLIPSInfo, /* SpecialInfo structure */
+ XCLIP, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+static struct PropInfo ClipClipYCLIPSInfo = {
+ AUTOKNOB+FREEHORIZ, /* PropInfo flags */
+ 13106,-1, /* horizontal and vertical pot values */
+ 10922,-1, /* horizontal and vertical body values */
+};
+
+static struct Image ClipImage2 = {
+ 22,0, /* XY origin relative to container TopLeft */
+ 24,3, /* Image width and height in pixels */
+ 0, /* number of bitplanes in Image */
+ NULL, /* pointer to ImageData */
+ 0x0000,0x0000, /* PlanePick and PlaneOnOff */
+ NULL /* next Image structure */
+};
+
+static struct IntuiText ClipIText4 = {
+ 3,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ -116,-1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "Y Clip Border:", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+static struct Gadget ClipYCLIP = {
+ &ClipXCLIP, /* next gadget */
+ 134,46, /* origin XY of hit box relative to window TopLeft */
+ -199,7, /* hit box width and height */
+ GRELWIDTH, /* gadget flags */
+ RELVERIFY+GADGIMMEDIATE, /* activation flags */
+ PROPGADGET, /* gadget type flags */
+ (APTR)&ClipImage2, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &ClipIText4, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ (APTR)&ClipClipYCLIPSInfo, /* SpecialInfo structure */
+ YCLIP, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+static struct PropInfo ClipClipXSIZESInfo = {
+ AUTOKNOB+FREEHORIZ, /* PropInfo flags */
+ 26212,-1, /* horizontal and vertical pot values */
+ 10922,-1, /* horizontal and vertical body values */
+};
+
+static struct Image ClipImage3 = {
+ 45,0, /* XY origin relative to container TopLeft */
+ 24,3, /* Image width and height in pixels */
+ 0, /* number of bitplanes in Image */
+ NULL, /* pointer to ImageData */
+ 0x0000,0x0000, /* PlanePick and PlaneOnOff */
+ NULL /* next Image structure */
+};
+
+static struct IntuiText ClipIText5 = {
+ 3,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ -124,-1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "X Scale Factor:", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+static struct Gadget ClipXSIZE = {
+ &ClipYCLIP, /* next gadget */
+ 134,15, /* origin XY of hit box relative to window TopLeft */
+ -199,7, /* hit box width and height */
+ GRELWIDTH, /* gadget flags */
+ RELVERIFY+GADGIMMEDIATE, /* activation flags */
+ PROPGADGET, /* gadget type flags */
+ (APTR)&ClipImage3, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &ClipIText5, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ (APTR)&ClipClipXSIZESInfo, /* SpecialInfo structure */
+ XSIZE, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+static struct PropInfo ClipClipYSIZESInfo = {
+ AUTOKNOB+FREEHORIZ, /* PropInfo flags */
+ -25937,-1, /* horizontal and vertical pot values */
+ 10922,-1, /* horizontal and vertical body values */
+};
+
+static struct Image ClipImage4 = {
+ 69,0, /* XY origin relative to container TopLeft */
+ 24,3, /* Image width and height in pixels */
+ 0, /* number of bitplanes in Image */
+ NULL, /* pointer to ImageData */
+ 0x0000,0x0000, /* PlanePick and PlaneOnOff */
+ NULL /* next Image structure */
+};
+
+static struct IntuiText ClipIText6 = {
+ 3,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ -124,-1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "Y Scale Factor:", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+static struct Gadget ClipYSIZE = {
+ &ClipXSIZE, /* next gadget */
+ 134,24, /* origin XY of hit box relative to window TopLeft */
+ -199,7, /* hit box width and height */
+ GRELWIDTH, /* gadget flags */
+ RELVERIFY+GADGIMMEDIATE, /* activation flags */
+ PROPGADGET, /* gadget type flags */
+ (APTR)&ClipImage4, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &ClipIText6, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ (APTR)&ClipClipYSIZESInfo, /* SpecialInfo structure */
+ YSIZE, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+#define ClipGadgetList1 ClipYSIZE
+
+static struct NewWindow ClipNewWindowStructure1 = {
+ 114,16, /* window XY origin relative to TopLeft of screen */
+ 346,76, /* window width and height */
+ 0,1, /* detail and block pens */
+ NEWSIZE+MOUSEMOVE+GADGETDOWN+GADGETUP+CLOSEWINDOW+ACTIVEWINDOW+VANILLAKEY+INTUITICKS, /* IDCMP flags */
+ WINDOWSIZING+WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH, /* other window flags */
+ &ClipYSIZE, /* first gadget in gadget list */
+ NULL, /* custom CHECKMARK imagery */
+ "Edit Clipping Parameters", /* window title */
+ NULL, /* custom screen pointer */
+ NULL, /* custom bitmap */
+ 350,76, /* minimum width and height */
+ -1,-1, /* maximum width and height */
+ CUSTOMSCREEN /* destination screen type */
+};
+
+
+/* end of PowerWindows source generation */
diff --git a/sys/amiga/colorwin.c b/sys/amiga/colorwin.c
new file mode 100644
index 0000000..a9cf25c
--- /dev/null
+++ b/sys/amiga/colorwin.c
@@ -0,0 +1,256 @@
+SHORT Col_BorderVectors1[] = {
+ 0,0,
+ 59,0,
+ 59,12,
+ 0,12,
+ 0,0
+};
+struct Border Col_Border1 = {
+ -1,-1, /* XY origin relative to container TopLeft */
+ 3,0,JAM1, /* front pen, back pen and drawmode */
+ 5, /* number of XY vectors */
+ Col_BorderVectors1, /* pointer to XY vectors */
+ NULL /* next border in list */
+};
+
+struct IntuiText Col_IText1 = {
+ 7,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ 13,1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "Save", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+struct Gadget Col_Save = {
+ NULL, /* next gadget */
+ 9,77, /* origin XY of hit box relative to window TopLeft */
+ 58,11, /* hit box width and height */
+ NULL, /* gadget flags */
+ RELVERIFY, /* activation flags */
+ BOOLGADGET, /* gadget type flags */
+ (APTR)&Col_Border1, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &Col_IText1, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ NULL, /* SpecialInfo structure */
+ GADCOLSAVE, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+SHORT Col_BorderVectors2[] = {
+ 0,0,
+ 59,0,
+ 59,12,
+ 0,12,
+ 0,0
+};
+struct Border Col_Border2 = {
+ -1,-1, /* XY origin relative to container TopLeft */
+ 3,0,JAM1, /* front pen, back pen and drawmode */
+ 5, /* number of XY vectors */
+ Col_BorderVectors2, /* pointer to XY vectors */
+ NULL /* next border in list */
+};
+
+struct IntuiText Col_IText2 = {
+ 7,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ 17,1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "Use", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+struct Gadget Col_Okay = {
+ &Col_Save, /* next gadget */
+ 128,77, /* origin XY of hit box relative to window TopLeft */
+ 58,11, /* hit box width and height */
+ NULL, /* gadget flags */
+ RELVERIFY, /* activation flags */
+ BOOLGADGET, /* gadget type flags */
+ (APTR)&Col_Border2, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &Col_IText2, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ NULL, /* SpecialInfo structure */
+ GADCOLOKAY, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+SHORT Col_BorderVectors3[] = {
+ 0,0,
+ 59,0,
+ 59,12,
+ 0,12,
+ 0,0
+};
+struct Border Col_Border3 = {
+ -1,-1, /* XY origin relative to container TopLeft */
+ 3,0,JAM1, /* front pen, back pen and drawmode */
+ 5, /* number of XY vectors */
+ Col_BorderVectors3, /* pointer to XY vectors */
+ NULL /* next border in list */
+};
+
+struct IntuiText Col_IText3 = {
+ 7,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ 6,1, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "Cancel", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+struct Gadget Col_Cancel = {
+ &Col_Okay, /* next gadget */
+ 244,77, /* origin XY of hit box relative to window TopLeft */
+ 58,11, /* hit box width and height */
+ NULL, /* gadget flags */
+ RELVERIFY, /* activation flags */
+ BOOLGADGET, /* gadget type flags */
+ (APTR)&Col_Border3, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ &Col_IText3, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ NULL, /* SpecialInfo structure */
+ GADCOLCANCEL, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+struct PropInfo Col_Col_RedPenSInfo = {
+ AUTOKNOB+FREEHORIZ, /* PropInfo flags */
+ 0,0, /* horizontal and vertical pot values */
+ -1,-1, /* horizontal and vertical body values */
+};
+
+struct Image Col_Image1 = {
+ 0,0, /* XY origin relative to container TopLeft */
+ 263,7, /* Image width and height in pixels */
+ 0, /* number of bitplanes in Image */
+ NULL, /* pointer to ImageData */
+ 0x0000,0x0000, /* PlanePick and PlaneOnOff */
+ NULL /* next Image structure */
+};
+
+struct Gadget Col_RedPen = {
+ &Col_Cancel, /* next gadget */
+ 32,12, /* origin XY of hit box relative to window TopLeft */
+ 271,11, /* hit box width and height */
+ NULL, /* gadget flags */
+ RELVERIFY+GADGIMMEDIATE+FOLLOWMOUSE, /* activation flags */
+ PROPGADGET, /* gadget type flags */
+ (APTR)&Col_Image1, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ NULL, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ (APTR)&Col_Col_RedPenSInfo, /* SpecialInfo structure */
+ GADREDPEN, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+struct PropInfo Col_Col_GreenPenSInfo = {
+ AUTOKNOB+FREEHORIZ, /* PropInfo flags */
+ 0,0, /* horizontal and vertical pot values */
+ -1,-1, /* horizontal and vertical body values */
+};
+
+struct Image Col_Image2 = {
+ 0,0, /* XY origin relative to container TopLeft */
+ 263,7, /* Image width and height in pixels */
+ 0, /* number of bitplanes in Image */
+ NULL, /* pointer to ImageData */
+ 0x0000,0x0000, /* PlanePick and PlaneOnOff */
+ NULL /* next Image structure */
+};
+
+struct Gadget Col_GreenPen = {
+ &Col_RedPen, /* next gadget */
+ 32,24, /* origin XY of hit box relative to window TopLeft */
+ 271,11, /* hit box width and height */
+ NULL, /* gadget flags */
+ RELVERIFY+GADGIMMEDIATE+FOLLOWMOUSE, /* activation flags */
+ PROPGADGET, /* gadget type flags */
+ (APTR)&Col_Image2, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ NULL, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ (APTR)&Col_Col_GreenPenSInfo, /* SpecialInfo structure */
+ GADGREENPEN, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+struct PropInfo Col_Col_BluePenSInfo = {
+ AUTOKNOB+FREEHORIZ, /* PropInfo flags */
+ 0,0, /* horizontal and vertical pot values */
+ -1,-1, /* horizontal and vertical body values */
+};
+
+struct Image Col_Image3 = {
+ 0,0, /* XY origin relative to container TopLeft */
+ 263,7, /* Image width and height in pixels */
+ 0, /* number of bitplanes in Image */
+ NULL, /* pointer to ImageData */
+ 0x0000,0x0000, /* PlanePick and PlaneOnOff */
+ NULL /* next Image structure */
+};
+
+struct Gadget Col_BluePen = {
+ &Col_GreenPen, /* next gadget */
+ 32,36, /* origin XY of hit box relative to window TopLeft */
+ 271,11, /* hit box width and height */
+ NULL, /* gadget flags */
+ RELVERIFY+GADGIMMEDIATE+FOLLOWMOUSE, /* activation flags */
+ PROPGADGET, /* gadget type flags */
+ (APTR)&Col_Image3, /* gadget border or image to be rendered */
+ NULL, /* alternate imagery for selection */
+ NULL, /* first IntuiText structure */
+ NULL, /* gadget mutual-exclude long word */
+ (APTR)&Col_Col_BluePenSInfo, /* SpecialInfo structure */
+ GADBLUEPEN, /* user-definable data */
+ NULL /* pointer to user-definable data */
+};
+
+#define Col_GadgetList1 Col_BluePen
+
+struct IntuiText Col_IText6 = {
+ 3,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ 17,38, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "B", /* pointer to text */
+ NULL /* next IntuiText structure */
+};
+
+struct IntuiText Col_IText5 = {
+ 4,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ 16,26, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "G", /* pointer to text */
+ &Col_IText6 /* next IntuiText structure */
+};
+
+struct IntuiText Col_IText4 = {
+ 7,0,JAM1, /* front and back text pens, drawmode and fill byte */
+ 16,14, /* XY origin relative to container TopLeft */
+ NULL, /* font pointer or NULL for default */
+ "R", /* pointer to text */
+ &Col_IText5 /* next IntuiText structure */
+};
+
+#define Col_IntuiTextList1 Col_IText4
+
+struct NewWindow Col_NewWindowStructure1 = {
+ 175,45, /* window XY origin relative to TopLeft of screen */
+ 312,93, /* window width and height */
+ 0,1, /* detail and block pens */
+ MOUSEBUTTONS+MOUSEMOVE+GADGETDOWN+GADGETUP+CLOSEWINDOW+VANILLAKEY+INTUITICKS, /* IDCMP flags */
+ WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH, /* other window flags */
+ &Col_BluePen, /* first gadget in gadget list */
+ NULL, /* custom CHECKMARK imagery */
+ "Edit Screen Colors", /* window title */
+ NULL, /* custom screen pointer */
+ NULL, /* custom bitmap */
+ 5,5, /* minimum width and height */
+ -1,-1, /* maximum width and height */
+ CUSTOMSCREEN /* destination screen type */
+};
+
+
+/* end of PowerWindows source generation */
diff --git a/sys/amiga/cvtsnd.c b/sys/amiga/cvtsnd.c
new file mode 100644
index 0000000..0e5f9c5
--- /dev/null
+++ b/sys/amiga/cvtsnd.c
@@ -0,0 +1,96 @@
+/* SCCS Id: @(#)cvtsnd.c 3.2 95/09/10 */
+/* Copyright (c) 1995, Andrew Church, Olney, Maryland */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include
+#include
+#include
+
+typedef struct {
+ short namelen;
+ char name[62];
+ char misc[64]; /* rest of MacBinary header */
+ long FORM;
+ long flen;
+ long AIFF;
+ long SSND;
+ long sndlen;
+} AIFF;
+
+typedef struct {
+ char FORM[4];
+ long flen;
+ char _8SVX[4];
+ char VHDR[4];
+ long vhlen;
+ long oneshot, repeat;
+ long samples; /* 'samplesPerHiCycle' in the docs - usually 32, so
+ * we'll use that */
+ short freq;
+ char octaves, compress;
+ long volume;
+ char NAME[4];
+ long nlen; /* should be 64; see name[] comment */
+ char name[64]; /* for simplicity, i.e. just fwrite() entiree header */
+ char BODY[4];
+ long blen;
+} IFF;
+
+
+main(int ac, char **av)
+{
+ FILE *in, *out;
+ AIFF aiff;
+ IFF iff;
+ static char buf[16384];
+ long n, len;
+
+ if (ac != 3) {
+ fprintf(stderr, "Usage: %s input-file output-file\n", av[0]);
+ exit(20);
+ }
+ if (!(in = fopen(av[1], "r"))) {
+ fprintf(stderr, "Can't open input file\n");
+ exit(20);
+ }
+ if (!(out = fopen(av[2], "w"))) {
+ fprintf(stderr, "Can't open output file\n");
+ exit(20);
+ }
+
+ fread(&aiff, sizeof(aiff), 1, in);
+ memcpy(iff.FORM, "FORM", 4);
+ iff.flen = sizeof(iff) + aiff.sndlen - 8;
+ memcpy(iff._8SVX, "8SVX", 4);
+ memcpy(iff.VHDR, "VHDR", 4);
+ iff.vhlen = 20;
+ iff.oneshot = aiff.sndlen;
+ iff.repeat = 0;
+ iff.samples = 32;
+ iff.freq = 22000;
+ iff.octaves = 1;
+ iff.compress= 0;
+ iff.volume = 0x10000;
+ memcpy(iff.NAME, "NAME", 4);
+ iff.nlen = 64;
+ strncpy(iff.name, aiff.name, 62); iff.name[aiff.namelen] = 0;
+ memcpy(iff.BODY, "BODY", 4);
+ iff.blen = aiff.sndlen;
+ fwrite(&iff, sizeof(iff), 1, out);
+ len = aiff.sndlen;
+ do {
+ if (len >= sizeof(buf))
+ n = fread(buf, 1, sizeof(buf), in);
+ else
+ n = fread(buf, 1, len, in);
+ if (n) {
+ fwrite(buf, 1, n, out);
+ len -= n;
+ }
+ } while (len && n);
+
+ if (len)
+ fprintf(stderr, "Warning: %ld bytes of sample missing\n", len);
+ fclose(in); fclose(out);
+ exit(0);
+}
diff --git a/sys/amiga/grave16.xpm b/sys/amiga/grave16.xpm
new file mode 100644
index 0000000..bb0466d
--- /dev/null
+++ b/sys/amiga/grave16.xpm
@@ -0,0 +1,223 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"400 200 16 1",
+/* colors */
+"` c #66686A",
+"a c #797979",
+"b c #929291",
+"c c #43444A",
+"d c #758A74",
+"e c #F2F2F2",
+"f c #D1D0CE",
+"g c #066906",
+"h c #065506",
+"i c #53535C",
+"j c #0C0D0F",
+"k c #A3A5A2",
+"l c #2D332E",
+"m c #C3C4C1",
+"n c #B4B4B2",
+"o c #07840A",
+/* pixels */
+"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjljjjjjjjjjjjjjjjljjjjjjjjjjjljljjljljjljjllljljclljlllljlllljlllllllllllllllcicl``clcllclclllclclclcclclclcccccccccccccccccccii`iiccicicicciiciiiiiibiic`iii`a`iiii`icaii`iiii`iiii`ii`ii`iii```iii`i`ii`ii`ii`iiii`iii`ii`iifi`ii`ii`iiiiiiiiiiiiiiiiiiiiii`iciibicicicicciiccciiibiicciiiiccccbicicccccccciccclcccccclc`aiciiiciccclilccccccccccclcccacccccccclccclcclccc",
+"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjljjjjjjjljjjjjjljjjjjjajljjljljljljjjjljjljc`baljjllcljjcjlljllllllllllllllllllllllcclllllllclllcclcllclclccccccccclccccccccccccicciicciicicicic`cciiciciciciacicii`iiiiii``iiakii`iiii`ii`ii`iiii`bkb`i`ci``iiiiii`iii`ii``i`iiiiiaiiiiiiiiii`iiiiiiiiiiiiiiiiiiiiiciiciciicicciciiiicllic`iciiiicicciliccccccccccccc`ccccliccccccccciciccclccccclclclclcclccclclclllccclcllccll",
+"ijjjjjjjjjjjjjjjjjjljjjjjjjjljjjjjjjjjjjljjjljjjjjjljljjjjjjjljjjljljljljjjjlljljljljcclljllllljlllljllllllllllllllllcclccclcjcllclclclclllcclclcccccccccccciccccciiic`a`icciiccciciiiiiiiiibi`iiiiii`ii`ci`iii`ii`i`iiiiiiiii`iii``ici`i`i`i``ii`ii`iiiiiiic``iiiiiiiiiiiiiiaiiiiiiiiiiciicicii`iiiiiliiccicicccicccci`ccicccicccclccinccccccccclcccaccccccclccccccccccilcl`lllccclcclcclcllcllclcccclllilcllci",
+"jjjjjjjjjjjjj`cjjjjljjjjjjjjcljljjjjjjjljjljijjljjjjjjjljljljjljljljlljljllljjljllflcjljllljljlljllllcllllllllllllcllllccllcc`clclllcllcclclcccclccccccccciccciciccccccic`iciic`iiiiciiiiiiiaiii`iii`i`icak`c``i`iiiiii`ii`i`iii`i`ii`iiiiiiici`iii`ii`i`ii``iiii`c`iiiiiiiii`iiiiiiiiciiiiiiiiiiiccccciccicicciiccccciaillcccciiciccclcccccccccccccc`cclclccillccllcliibilikaicllcclccccclcccclcccccllccllcclcl",
+"jjcjjjjjjjjljjjjjjjjjjjjjjjjljjjljjjjjjjjjjjljjjjjljjcjjjljjljjljjjljjljljjjlljllljlllcljllllllllllllcclllllllllclllcclccibccclclcclcclcllicicccccccclcccccccciciicciccciaaiciccciiiiiiii`ciiiiii`iiiii`ic`iiiiiiii`ii`iiiiiiiiii`iiiiiciiiii`i`iiiii`ii`iiiciiiiiiiiiiiiiiciiiciiciciiccicciiiiiicicc`cccccccicccccicciiccicccicclilccccccclccccclccllcccilcccclcciclccciclcclccclccclclllcllcllccllcccclaacccl",
+"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjljljjjjjjjlljjjjljljjjjjljjljjljljlljljlljlllllljajljljlllllllllllllllcllllllllclccilcicclc`clalcclclclcclcccicclclccccciiccicciccciciiiiiiciib`iiiiiiiiiii`iiii``i`i`iiiiiiii`iiiiiiiiiiiiiiiiiibaiiici`iiiiibiiiii`iiiic`kaiiiiiiiiiiiiiciiiciiiciiciciccicciiiiciiiciccicicccccccciclcccccciiccccaciclclcccciilcccclcclcclcllclilacclcccclccclclcccccclccclclccllcclllllkblllc",
+"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjljjljjjljjjjjljljjjjjjjljljjljjljljlllljljljljjjjjljllljcjllllllllllllllllllllccclclabclccccciccccllclclcclcclclccccccccciiaiiicciciiicccccciiiiiiiiiciiiiiicii`i`i``i`iiiii`iiiiiiiiiiiiiiiiiiiiiibiciiiicciiii`iiiiiiiiiie`i``ic`iiiiiiiiiciiciciiciciciciciiiciic`cccclcccccccccciccccccciccciicilcillcccccclciccccclclccclibaili`lillccccciicliccccccclcccllallclliiiclcliilcll",
+"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjljjljjjjjjjjljjljjjljjjjjljjljljlllllljllljlclllllljlllllllllllllllllllllllllcccclccliiccccciccccclclcclccccccclcciccccciacciciiiccci`iiiiciiiiiiiiiiiiiii`i`c``````i``iiiiciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii`kciiiiiiiiii`c`iciciiiiiiciiiiiiciccicicicciciiiiii`ifcccciccicccccccccccccccclccccccclcclccclccclclclcllilclcclcllclcliilclclclccicccccccccllllcecclclliaacllcllclc",
+"jjjjjjjjjjljjjjjjjjjjjjjjjjjjjjjjljljjjljjjjlljjljjjljljjlijjllllllllllllljljajlljlalllllllllllllllllllllccccclllccclclccccccccccclcccccc`clcccccccccccicacicciciciciiiiiiib`iiciiiii`c`iiii``iii``ii``ciiiiiiciiiiciiiii`biii`iiiiciiiiciiicib`iiiiiiiiiiiiiiiiicii```cccciciciciiiiiiiciiiciiccccccccccciicciccccccccccccciccccclccclcccllccclclc`ccclcclcccccclcccllclccclclllcllcliccllclmccclcccl`lclclclll",
+"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjljjjljjjlljjjllljlljjjljljjjljljlcllllljcljjcljlllijllllllllllllllilcllcccccllicllllclcllcclliccccclccclcccccccccccccccc`iciicicciiiaiciciicl`ici`iiiiiiii`ii`i`ii``iiiiiiiiiiiiiii`iiiiiaciiciiiiiiiciiiciiiiiiicici`ciiciiiiciicciiiciiciciiiciiiiiii`cbi`liicicccccccccclccccccccclclccccccclcilccllccccllcclcccclcclclclllllcllllcllllllclcllccccclllcllilllclllclilillccll",
+"jjjjjjjljljjjjjjjjjjjjjjjjjjljjjjljljjjjjjjjlljjljlllljllljllljlcljjljljcjlllljcljllllcllllllllllim`lljccllcclcbacllcllclccliclcccclccccccccccccccicciciciiciiciiiiiibiiiib``iiii`i`iiaii`ii`iiiiiciiiiiiiiiiicciiiiiii`iiiiiciiiiciciici`cciiciciiiiib`c`aaicciicicciccccciiiiiiiicciiicciilccccclcccccccccccclccccccclccliccccclclclcillccccllcclclccilcccclclcclcccclclclclllcllllcclllllllclllcllcllclcll`cc",
+"jjjjjjjjjjjjjjjjjjjjijljjjjjjjljjljjljjjljjjjjjcjljljlcjjlcljlljkclllllllcllllljllllllljllllllllllliiccccclllllcccllcclcclclclcicccccclcclcccccccicccciicciciiciiiicc`ciii`ciiiiiiiiii``ii`iiiiiiiicii`i`i`iii`iicic`ii``iiiiiiiiiiciciciiiicc`ciicici`cc`iiiciciicicciicicci`iiiiiciciicicccibiccccccclcccccclclcclclcclccicclclcicclikclcllclllcllcllclccccllclclcliclci`cllclllillliccclcllclclbilllclllclcal",
+"jjjjjjcbljjcajjjjjjjljjjljljjjjjljjjjjjljljjljjjlljcjllljlilllllaljlljjl`mllljcillllclllllllllllcllclllciiilccclllclclclcclckaclccccccccclccccccccciiciciiciiciiciiiiii`ic`ii`ii`ii`````i`iiiiiiiiciiciiiiiiiiiiic`ibiiciiiiiiiiicicicicccicicicciciccccicccciiicccciccciccciiiiiiiiciccii`cicbicciccciiciclcccccccclcclcccccllcclllliclclcccccclcclcllclcccclcllclclccllc`lllcllcll`llllllcllllllilllllllclcclc",
+"jjjjjjjljjjlijjjjjjjjljjjjjjjjljjjjjlljjjjljjljljljajljljlljlljcljjlllllljlljijjlllllllllllllllcjcllllaclclllllcccclccclllccclcccccccccccccccccii``a`cccciciciiiiic`i`baba`iiii`ii```ii`ii`iiiiiiiiicciiccciciiiic`ia`iccii`c`iiciciccccccccbcccccic`iciciiiiccciccicicccccccccciiiiciccccccciccccccccccciicii`a``icccccccilclclciaa`iiccciclllcllclcllcllcccllllclllcllllclclcllllamiccaclllllccllllccllclcllcl",
+"ljjjjjjjjljjjjjjjjljljnjjljljljjljllcjljjjljjjlbjllblljljjjljlcljclljlljlljclikllljlllllllllllllcljclccccccccllclllllcccccclcclcccciccciccciabbkakbnaccici`iciiiiiiic`bbnnnnkbaa``iiii`ciiiiicici``ic``ciiiaiiiiiiiciiciciiiiiiicccciciciiccbcciiccccccciccciicicicicccccccccicccicccccccliccicliiccccici```iabkbaccccccccclccclciammnbbbaaicclcclclclclllllllllllclllllclllllllllccijlakillcllllllclllllllcjcll",
+"jjljjjjjjljjjjjljjjjjjjljjjjjjljjjjjljjjljjljljjljjijjljljl`liklljljllllllillljlllllllllllllllllllclllccccllccclcccccllcclcclccccccccciii`abnnbknmnmblciiibiiciicik`i`nbkmnmmnmnnk``i`niiiiciiiiciicccicccibciciiiciciccciciiciccicicccccccciccccccicc`ccccicibfcccccccicccccccccccccccclc`cclcclcci`abbbbaii`nnk`ccccccclllc`cciiknnnnbbakbkkicllclllclclllllclclllcllllclllllllllllclccllcllllllllkalllcljclll",
+"jljjljjjjjljjjliljjljjjjjcljjjjjjljljljljlljjjljljljlljlljlijblljljlljljllcjllllllliklllllllllcllllclccccccclclcccclccclccclcccclccciiaa`babnmnnmnnmkjiiccacciiiiiiiiakkknmmmmmnmnkkbbaiibciiccciciiccccccccccciciicicciccccccciicccccccccccciiiilicicccccccciiiilcccccci`ailciclcccclcccckbcllclciabbkkb`icianmnkcccclllclccccii`ammmnbabknkkaa`iillclllcjcclllllcllli`lllllllllclclllclllllllllllllljcllclllll",
+"jjjljjljlljljjjljjjjjjljcejjlljlljjjjjjjjjjjjlljjljljljljljllkijlllllllcjkllllcllllcallllllllllllclcclilcclclclcllcccllccccccccccc`bk```baabnmnmmmfmklciiciiiiiciiciiakbbknnmnmnnnkbbbbaknicciiiicccciiiccicciccccciicciiccicccccccccccccccccccccicililccccccciiccicccccciiclcclcccclilclliclccli`abbbnkkacciaknmkllllllclllcccii`amnnnnbbakbk`i`aaa`ccicclllcclcljclllclllllllllllllclllccllcllcjcj`alllllllcll",
+"jjjjljljljjjjjjjjljljjjjljjjjljjjjlllljlljjlljjlljljljlllllljilljllljlciacjlljb`llllclllcllllcclclllccciccclclcccclcccccclccllc`aabnkii`bbabbnnnnnmnbljiiiciiiiii`i`i`kkkbknmmmnmnnbbknkak`iccccicicccccccccccccicccccibccccccclcciccccccccccccciciicni`ccccccccccccccclcclccclcclacclcclclliiciabbbbbbnb`cc`bkknnlllllclcllccc`iiamnknnnkaaknaiiabbabbkkcccclccjcclllllllllllllllillllllcllcccllllccelllccclicl",
+"jljjjjjljjjljljljjjjjjljjjjjljbjljjjjjjljjljjlljjljljlljljjljljlllllljlllclllcjllllllllllllcllllll`ccilicccclclc`illcccccccci`bnbaakk``abbb``knbnmmkbllciii`i`i`i`i``akbbbbkmmnnnnbbkkkabnmnb`icccccccciccccccccccccccc`ccccccccciicccccccccccciccccciilcccccccclcclclclcclcclccclicllcllcc`aiiabbbkkbakacl`bnnknklccllllcclciiii`bmnknmmbaabka``akaaaakkicllclccibclllllllllllllc`lllllllcllcllllllcjlccclcc`ll",
+"jjjjljljjjjjjjjjljjljjjljlljjjljljljljljljlljljlljllljlljlcjllllllllllllljcjllmclllljcllllccllllcclcccccclcccccccccclccccciibnmmaaabbbbbbbb``bmbbnmnbljc`ii`ib`iikb``bnkbabbknmmmkbnnkbbbkmmkkaccccccccccccccccccccccclccccclccclcicccclclccclciic`lccciccccccccclclilccclcclcllcllllc`cc`abaliabkkkkkabiciabnmnfnlllllcllllii`i`i`nkbbmmnbbabaakbbba`iknbbbciclcl`llljcllllllllllllllllllllcllllclljclcclllclll",
+"jljjjjjjljjljljjjjjjlljjljjljjjljjjljljliljljljljlljlljllllllljljljllllllllcllallllclllllcbkbaclcciillclcccccccclcccccccciaaaknknbai`bbbbbbb`bmnkmnnalliii`i`aiii`ii``bbbbbbnmmnmmbkkkbbbbnmnnnbaiccccccccccccccccclcccillcccclclccllcclcclclccccclciliccclclclcclclcllclcclclcllcilclbaabb`icaakbbknkbaii`abknmnbclllccllllii`iiiibabbbkkkaa`abbbbkbaaknnkmnalclllclclllllllllllljllllllllccllclljlclclllclclll",
+"jjjljjjjjjljjljljlljjjljlicjljlllljljli`cccjl`cjljlljlllljllllllllllllllljcjlllllllllllllliclclclcmbclicccccccclccccccci`bkbbbbbbaaaabbkbbbbabnmfnbacljici`iiii`ici`iiiaabbbkmmnmnbbbababbnnmknnkbiclc`acccccccclccccclccclccclcllclccccccclccccccicllciccccccccllcclilccllclclclcjccababbicc`bbbbbkknbac`ababbaicllllllllllcii`i`iiiababbbaaaabbbkabbabnnnmmfna`acclclllllllllllllllllllllllllclcalllllclclllll",
+"jjjjjjljjljjjjjl`ailjljjjljjljjljlc`aabkbaba`aiclljllljljcb`ljlllllllllllclllclillllclllllcllclcililclkclcccccccccccccannbabbbbaaaabbbbkkkkbbkmnbiljlllciiiiic`i`i`iiillcakbbknfnkbbnbkbabbkmnnnknnbilccccclccccccccclcaacllcllccclclllcllclccccclclccccccccclllcclclbclclllcllllccl`aaabaicabkkbbkkknka``bkbbilljlllllllllcciiaaijlljcabaaaaaabbbkkkbbknmnnmnnmbillccjlllllllllljlllcllllllllllllllllclllccllll",
+"jljljljjljjlljljcjljjljljjlljljc`bbknnkkkkkkkbbbbbcjllljllllllllllllljlllllllllcclllclllllclllcacclcccclcliliclcclcc`mfnnmkbkkbaai`a`aakmkkbikmmlllljllciiii`iiii`iin`iljcbbdbnmnbbbmknnkaaakmkmmnbbbilclclclclcclclk`abilcaclclcllclcclicccccclillcccclilccclclllclllclllcclllcllibbbaaailiakkkkbbnkkk`bbbaballllcllllllcllci`a`lljlllcba`c`a`aakmbkbabmmnnmnnmbacllccllllljllllllllbjlljljllllllclllllllclllll",
+"jljjjljljjljjljjljljljjjjljjlc`akkkkbkmmnnmnkbkkbkb`cjjllllllllllllllcllllllclacjcllllflclllclc`cclliiicclccclciaciabkkmnmmkkka`cc`a`akbnkkb`knkjllljlll``iiii`aiiiiicccllakkkkkkbbbnnmnmkaabnmnkbbkkbiccccliacllillilccccllli`llllcllllcccclllcailllllcllclcclcclccllllclllllllliabka`i`clibbkknbbkknkbkkbbbillllllllllllllc```llllljjlb`cci``abbknkbianmnnmmnnnallilllljllllcjllljllllllcllllllllllcllllllijjl",
+"ljljjjjjljjljjljljjjjjlljljjibbkmnnkknnfffmnnknnnkbaa`clllllllllllllllllclilllllcccllclclcllccccccclcccccccclcic`cannbbmnnmnbaiiii``akkdknkaabmblljllllciiiabknmniiiiiijljannkkkbbbkkmmnmk``bbkkbbkkkkkaclcclclclclcllclbilcclllillllccllccclclcclcliccll`llilcclllllllclllllllliabba````ccabbbkknbbkkbknkbbbiljcljcljcbnkbabballlljlllc`iii`a`bkbbknbabnnnnmnnnnalcicilllllljllllllljclljljllljljjclllllllla`ll",
+"llljljljjljjljljjlj`ljljljlikbbmnfnnmmnfffmnmnmmmkkbkbiiljlllllllllllllciaiclcllllllclcllclccccclcccclcclaclcilc``bknnbkmnnnka`bba`adbkbbkbaabmkcljllllciicbnmnnkiiiiicljcanmnmnkkbbkmnnn`ibbabbbknkabknbclclllclllcllclcllllllcllcclllllilllilllllliclllllcjliccllclllclclllccci`aa`i`aii`bnkbkkkbabaakbnnkkacllllllc`knmkbbbbljjjjjlj``abba``bkkabkaaaknmnmnnnbacli`acllljllllljlllllllllljlbblljllljcllclabll",
+"jljljljljjljljjljjl`jjljjcabkkbefmmfnfefefffmffmfmfnkkbaillllljlllllcllll`llllllajiclllclcccccclcclcccccc`lciccakbbbknkbnnnmnnnnbaabbbbkbb`iadmmaclllllcclcaknkmmkiiiiicc`knkmmmbkbnnnnnbi`bkbbkbkbbbaakkaiclcclclllcclllcclllllllllllcll`ill`cllcllcllcikllillc`cccclclllllcciii`aa``iii`akkkkbaaaaiakkbknknkaallllcabkknnkabkallllllibkmka`aaabkbbai`akmmnmnnmballcibbillcljllllljlljljlllljcjlllljlllcjlllljl",
+"jlljljjjjljljjljlljljlajl`bkkkkmffffffeffefffmmfffmmnmkbbillllllllllllllcjcllclllilllilclcccccccllclcccccccclcakmnbbbbbkbkmnnmmbabnkbbbkk`cc`bmmmb`ciia`iii`aabnnmaa`c`abkknmnmmbbknmmnkbiababbbaba`ba`aakk`clclllllciccllllcllclllllllllclllllllllclllclllllllliclclcclcclli`aaaaaa`iclc`bbnnkbaiiiibnbnbbknkbb`ccci`knnknnkbbbb`cjjikfmnbabnnbakkk`li`knmnmnnnb`icccaabclilljll`llllllllljllcljlljlljlllllljal",
+"ljljjllljljjljljjjljlabliakknmknmfffefmffefefffffffffnmkkailllllllllllialclcllilcllc`jicccccicccccccclcccciccbnnknnkbbkbbknnnmnbbkmmnkbbbiccabnnmmnknkb`ccii`abmnbbbmknnmmnmmmnmkbkkfmnkaa`aabaaa``ia`akbbkkacllccllliillllllllljiaaillclllclllcclllllllllllllclclllllcllcciaaabkbb`iicciabbkkba`iiiaknbmkbbkkbabknbabnknkknmkkbkabbkmnknnabnmmkbbbbiliabnmmnnnnbbaicii`akallllljilljjllllicljjlljljcljljllllcbl",
+"jljllllcjjljljljlljlljllbbnnmmffffeffeefeefefeeffmmefmmknkbclllllllclllclllclclccccccicccicccclcccccccccclccbnmnnnnmmnbbbbbmnnkknmnnfnbb`i`aabnmmmmnnnbaiii`abbkkbkkknkmmfkmnmmmnkkknnmnaaabkkbaaiii`bknbkbkbcllclclclblllclllllllllllllclllllllcjllclcllllllllllllllllllliabbaaaaa````a`abbkba`a```abbknnkbbbkknkkk`bnmnmnnknnmkbkbabnmnnbnmknfnka`iiaabnmmmnnnnbaci``aabkaljllljlljcljllljllllljlliljlljlljjll",
+"llljljjjljljjljljljjljc`bkbmnfffefeeeefeefeefffeefffmmnnmnkaclllclllclllllclccccccclccccccciccccccliccclbccanmnmmmnknmnbkbbkmnnnnfmmnmnbi`abbaknmnmnnkb``iai`aa`aabknmmnmnnnmnmmmbkbkfnnkbakmnabaabaabnakbbkbbilllllllllllllllllllllllllllllllllllcjallllllllllllllllllllinkbabbba`iaaaa`akbb``````abbbbkfmbabnmmnbakknmmnmnmnnnmkbbbbknnnnnnnmnnmbiiabbakknmmnnkb`````iaa`ailjlljljlljlljlljljlllljljljiclllljl",
+"jljljljljljljljljjllljlbknkfnffffefeeeeefeeeeefeeeefffmmnkkbillllllllllclijcclclclccclclccccccccicinacciiibnmmnnnmnnnmnkbkbamnkmnmmnmmnabdaabbbbmmnnnba``iaii``ii`bnknmnnmnmmmmnnkkbbknmmkbknnbkkbbbabnbbkkbbnaclllllllllllllllllllllllclllllllllllcllllccclllllliclllllikfkbaaaaa``aba```baa`a`aaaabbbbkmnnknmnnkbbknnnnmmmnnnnnnnkbbbknnnnmmmnnnabaaakabbnnmnnba`````c``i`iicjlllljllllljllllijjcjlllllcjjjllj",
+"lljljjljljljljljlcjjllkbknmfnffffeeefeeeeeeeeeefeeefffffmnkkbclllllcl`llllccccklllclclcclcccclcccccilccccbmmnmmnmnmnnnmmkkbbnnnbknmmnmkkmkaabbbaknnkkbaa```c``iiiabkbmmmmnmnnnnmmmkkkkknmnbnmkbkkkaa`bbbbbkkbnkacllljcllllllllllllllllllllllllllllllallllllllllll`cjlljlabkbab`aaa`iaba``abaaaa`aabkkkkkknnnmmnkbabnnnnnnmnnnmnknmnmkbbbnkkbnnnnnkbnnabbbbbbnnnkkaaiii`iaiciaailjjlll`bialjlljjclljljajjljjlljll",
+"jlljjljljjljlljlcjllljanbmmfnffefeefefeeeeeeeeeeeeeeeeffmfnnk`clcllllaclllcclllclcllccciclcccccccccclicc`mmnnnmmnmnnnknmfbbbbdba`abbdbabkaaaabkbbnnnkbaa``ic`iiiaaabbmnbkkbbdbbkbbabkknmnmkmnnabkkbabbkbkbnkkkbb`llcjllllllllllljllllllllllllllllljlllclllljlllljlllcjl`kbbbbbaaaa```a```abaab`ii``aabbabbbbbkkai`bmnnmmmbbkbkmnnnnmka`aaa``aabbbbaknbabbkbbknmkb``a`ii``iiiaaacllijlcklllbljlljljlljijlljla`ljj",
+"ljjllljljljljlljljjljibbknffmfeffeeeeeeeeeeeeeeeeeefeffemfmnkbclllcllclcicbcclillccccclcccccccccclcciclinmnnmnmnnnmmnnnnnnkaai``lllllcllllcllc`abknmnac`i`clclliaaaabnalllclclcclcllcc`kmmnnnkbbbkbkknkknkkkbbaa`iccclljlllljllllljllllljllllllllacljljlllllllllljllcliabnnbaaabbaa``````aababllllllcllllcllcciii`bnnnnnncllllnnnnnnnilcllllllcllllciadkbkkbbnnnb`i``iciilc`aaaaclealljllcecllljjjljljjljljjjjll",
+"jjljljjjlljljljlljllclbbmnmffeefeeeeeeeeeeeeeeeeeeeeefefffmkkb`lclcllllclicciclccclccllccccccccccicccciknmnnmnnmmnnnmnnnkmnbiia`lllllllllllllllliaknnb`i`aclllli``i`abilllllllljllllllliknnnnkbbbbbbknnnkknkbkaiiaillljlllllllljlljlllllllljllllcjjlllcllllllljlllljlcabbbba`babbba```iaaaakkbllllllllllllllclicadkmnmnknlllllmmmnnnmijlllllllllllllccibbkkkkbknna`i```icli``i`aaclljjljljlljjlllljljlljjllllllj",
+"ljljljllljljljlljifccibbmmfffeffeefeeeeeeeeeeeeeeeefefeffffnknaccclccclcccicclcllllclcccccccccccccccccanmnnnknnmnnmnmmmnnnnbi`nilllcllllllllllllliabbkb`aacllll```iiabillllllcllllllllllibnmnnbabbbknnnnnnknbkaiib`ijljcljlljljllllcljcljlllljll`cjlcjjlljllljlllllllibbka``bbbkbba`i``abbbknbcclclllllllclllllladnnnmnnncllllnnnnnnnallllllllllllllllc`bkknbbakbbaaaaaiiii```ciaalllllljljljljjjl`jljllljjjjjjl",
+"ljljljl`llljlljljlcclaakmnfffffeeeeeeeeeeeeeeeeeeeeefefefffmnnacccccllccilcclclccci`cclccccccccccccccinknnmkkmmknnnnnmmmmnbaaakicclc``ai````illlllibbaabaalcllc`aai`abilllciada```aicllllannnmkbbbknnkkkkkbnbk````aklllllljlllllljlillijllljlllljlllllcjlljllllljljllbknbaa`kkbbkbai``abbbbbnbilclcccici`icccccllaknnnkkn`lclcknnfnmndlllc`````aaaaccclldbnnbbbabbaaaa`a`ai`aaiibb`jlljljllljljlll`ljljjjjjlljlj",
+"jjljjljcjljlljlllllllcbnnmneemefeeeeeeeeeeeeeeeeeeeeefeeffmmnbbiccciccccccclcclcccccccccliclicccccicibknnnnnnnnnmnnnnnnmmkabbbbiliclnmmkkkbbkalcclcbbbbaaallllc`ab``abcllllaknffnnnkalllllnkmnbkbbkkknnkkkkkbb```i`alljllllljlljlllilljlljllljlljlllljllljlljljlllljakbkkkaabnmbababbbbkbbbbkacllccciiii``aablllccnkknnnkillcldnnnmnmblllc`kkkknmmnblcillbnnkbbbbabba```aaaaaaa`aabcjlljljljlljljjljjjljlljjjljj",
+"lljlljljlljljlljlllllibnkmnmffefefeeeeeeeeeeeeeeeeeeefffeffmmkkaccccclcillcllclclccccccci`icicccciciakkbknkknnnnnknnnnmnnbadbkkilclcnnmkkbbkkbllllcabbkabblcllcaabaabkilcclakknnnkbkbcilllkbbbbbbbbkbkkbkkbbbaa`iaaaallljjllljljljlclljlllljlllllljljljlbcjllljljjj`nnkbknbbabkbaabkbkkbbbbbbalcllcciabb``bnnilclckkknkkniccccannnnnnalllc`bbbbnnmmnillcldbdnkdabbbbaaaabaabab`aabb`ljlljljljljljljljljjljjljljl",
+"jjljllljljllllccjcljlcbmknnnfefeefeeeeeeeeeeeeeeeeeeeefffemmnkk`cclccli`clbcblilccccccccciccccciial`kkkkknkknnnnnkknnmnnbdaabbkclllcknmnkbkmn`cclliaabbbbbcllclabkdaabilllcbkkkmnkakaliilibbbakbbkbkkbbkkbkkba``ibbaailllljlllllllllljlljljlljljlllillllljlljlljllcaknnbbkkbaaa``abkkkkbbabaa`cllcci`abkkabkkclllcbkknkknilllcannnnnk`clcc`bkbabmnnkllccldkkbkb`abbbbbkbbbbbbbbaabknajljlljljljljljljjljljllljll",
+"ljlljjjljljljlccjlllccamnnnnfemeefeeeeeeeeeeeeeeeeeeeeffmffmfnbacclclllillil`cclcclccccclccccciia`canbkknnnnmnnnmnnknnmkkiidnbbclccl`aa``i``illclc`abbbkkbcllllbbkb``b`llcl````a`a`illicl`bbbbkkabbbbbabbbbkb``i``aaaalljlljjljjljljllljljlljllljlcalljlljllljlibjcbkmkmkbab``iiabbbkbbkbabbaailllcci``iii`icllcl`kkknnnm`cllcannnnnb`lllli```i`ab`ccllccnfnnkdbabbbbkkbakbabkbaiabnkijjljljljljljljjljljlllljlj",
+"lljlljcjlljlljclclljclamnnknnenefeeeeeeeeeeeeeeeeeeeeefemffmmnb`clcllcllcclccclicccccccccccccciiicinnkknknmnnnnnmnmnnnnkbcc`mnklccllllcllllclccll`kkkkbbkkclclcbbkbaabillclcclllclllllllidbbkbnkbkbbkkbkbbkbaii`aiabbklljlllljlljlllljljlljljljlljlcjljllljjjljljlbbannnmba`ii`akbbbbbbbbbkaad`lllclllllllcljlllidmkbnnmn`cllcannnnnb`llccclllllllccllcldkmmnnmkkbbbbkbbbbbbbbbb`babkaljljljljjljljjljllljljljjl",
+"jjljlljljllljllljjcc`l`bnmnnkeffefeeeeeeeeeeeeeeeefeeeeemffnnnb`llclccccclccclciclccccccccicccciccknknkkknnkkkbknnnmnmnka``dnkkllclccllllllcllll`kmnkkbkkkclcllbkabbabclllllllllljlllllibkkabbnkknkbbbbabbkbai`aa`abkkbjljljljljljljljljljljljljljjlljljjlljlicjliakkkmnnkkacc`kkkkbbaababnkabalccclllllcllllllcdnnkkmnkkallll`nnnnnballiclllllllllllll`akkkmmnnkkbkkbbbabbabbbabbbbmnclljljljljljjljljljljljjjj",
+"alljaklllljlllllllllllibknmnneefefeeeeeeeeeeeeeeeeefeeeffmfnmkbicccllclllclcliibcccccccciciiiiiic`nmnnnknnnbbbbkkknknmnkbbkkkbdccclcccllcijcjlcbnmnmnbbkbklllllbkbabbbilcclclllllcllc``kknnbbbkknmnbkkbabbbaa`aaabbabkncljlljjljllljljljljljlljljljljlllljljljjllkbbaannkknac`bkkkkkbbbbbknkbb`lclllllllllcllcibnmnkkmkkb`ccccannnmkbkllllclllllcllllidkbbknnnnnnkkbkkkbbbbbbbbaabbkmmaljjljjljjljljljljjjjjljjl",
+"ljjl`ajljlllljlljllllliinbmnmmefefeeeeeeeeeeeeeeeeeeeeffmnmnnkblclccclccclilillccccccciciciiiicccamnmnknmnkbknnnkbbkkmmknmnmkballclc`aacl`ccibknnmnnmnkbbkclcclkbbbbab`lllc```aaab`iakkkbnmnkbbkkknbbkkbkbaii`babbbbakb`jlaaljllljljljjljljljljljljljljjjlljjljj`nkbbabkknk`cbkkbbkkbbabnkbbbb`lcllcaailllll`bbmmmknnnkkballlcibkkmnnmllclci`iiaaabbkknkbkbnnnnnnnnbbbbbbbbbkabbabkmnmmcljljljjljjljlljljljljjjj",
+"lllljljlllbllljllllllllcaknknmffeffeeeeeeeeeeeefeefeefemmfnnnkacclccclclcccccccccccccccccciii`ciabnmmmnnnnbknnmnmmnkkkknnnmkdballcclbmn`llcll`nknmnknkmnbdlcllcbkbbbbk`lcllkkkknnmnkbbknbnknkbkbnkbbbkbakkaiabaabbbbbbabjljcljljlljjljljljljjlljljljljljljjljjclannbbaanbkacikmnkkbbkkbbnnnkbaacclcibbbilcclcaknmnmknmkbbklllccmkkbnkmclclcai``abbnnknnnkbkkknnnnnknkkbbbbbabkbbkbknmmkaljjlljjjlllljjjjjljjajlj",
+"jljljccjllljllllljllilll`bbnmmfffefefeeeeeeeeeeeefffefenmfmnkbiclccclcccccccccccccccccccciiiiiii`bbknnnnknbbmnmnnnnnnkkkmnkaad`lcllcbkmk`cllll`knmnmnknnnkllllinbbkmnn`clllbnkknknnnkkkkbknnnkbbkkkbkb`iaba`abbbbbknnbbbllilljllljljljljjljjljljljljljjljjlljia`bnkbb`akab`aaknnnnbkbbaabnnbbbdllliibbbailllclabnnnmkbkkbkclcccmnnkkkniclcl`i`akbbknknknnbbkknnmnkknnkbbbabbkbbnknnnnmnnljljjjljljljljljjjjljjlj",
+"klljljjclljlljllllll`cllcakbmmmfefmffeeeeeeeeeeeeefeeffmmfnnbailclccccclccccccccccccccccciiici`iabbbbkkbkkbnmnnknmnnnnnkkkbdab`lcccibknkn`clillakmnnmnkkmkllccinmnknmncjcccknnkkknmmnnbbkbnknnbbbkbabaciaaaabaabaknmnnbbilijljljlljjljjljljjljljjljjljljljjjljjaknkbbaaba``bknnnmnkkbbabbknkbbblllccbbbbailllcc`bkbkkbkbkklclccnnmnnknillcc`c`abbbknnnnnmkbkkknnnnnnnnnkmkbkmnknnmnknnmm`lljjjljjljljjjjljjcjljj",
+"ljlllllljlcljcllllllillll`bbkkmmfffffefffeeeeefeeefefffmmmnkb`ccacclcliccclccccccccicciciiciciaibbbkbkbbakbmmbnnnknnnnnnkkkbbaiclllcbnmknncllllldmfknmnknkllllikbknnnniilllknnkkknnnmmnbkbnknnkkabbbaccaaaaabbabknnnnnnkallljjljjljljjljjljjlljljjjjljjljjjljlcbknkkkbbda`aknnnnnmnkbbbbbbbkbbalcclcknkkbaicllil`bkbbbkdmnlllclnknnnnk`llclii`bbabknkkknnbbbkknnnmnnknnnnnnkbkkknnknnmkkbjjjljjjljljljljjjanjjjj",
+"llmjjljllllllilljlllllllllikbbnmmmfffffefeeeeffeefffmffmmnkbaicclcccccclccccccccccccccciiiiicc``bbkkknkbakbnnknknnkkknnnmnbbbaclcccibnmnmnncllclldmnnmnnnnllclckkkbkmmilllcknnnnbkknmfnnbkknkknnkabaic`bbbabbbbknmnknnnnkljjljljljjjljjljjljjijljljljljjjlljjj`ikkkbnkbaaadnnnkknmmkbbbbbbbkbballlclbbbbbabclllcidnkbbbbnmlccilnkkkknn`llccciabaabnmnnkmnnbbbbnknmmnkkkknmnkbbkbbnnnmnnnflljjljajljljjjjjljjjjjj",
+"illllllllljllclllllllclllll`bbkmnmmfefeffeffefefmeffmffmknkaiclcclclcccccccccccccccicciciicici`aabbbkknkbabknnnkkkknkkkkkknkb`clcllibknnnmkkcllllcdkmfmnnkllllcbbbbabbclcllknnnnkkknnmnbbkkmnknnnkb`c`bbkbbbbbbbknnnnmnknlljljjljjljjljjljjljcjjjjjjjjljljjjllibkkkknnbaabknmnkkkkknkbkkkbbkknklcclcbkbbakdbilllliakkbabkncllllnnnkknkalllliiaaabbbnnnknmnkbbbkbknmmnkkknkbbkbbaabbknnkkniljjjjljjjljljjjjjljjlj",
+"lcljlljlllllljlllllllclllillabbnknmmfmfffffffffffmefmnnnkkaicclcilccbcccccccccicciccciciiciiii`babbbbbbkkakkkmnnknkkkkkkknmnda`clllibbbbbakbacllcl`knmnnnklllc`nmb``bbcllclknnnnnnkknnkbbbknnkknnmna`bbbkbbbbbabkknnnnnnncjjjjjjjljjjjjljjljjjljjljljljljjljjj`anknnmnbbabknmmnnkabnnknmkkbaknkcllllbbkbbakaaillclibkbbbbkiclcckkkknkkaclll`bbkkbaabbkabkbbbabbkkbnmmnnkknmmkkkb`abbkkkbkbjjlljjjljljjjjjjjjjljj",
+"cbjcjllljlllllllllllcllllllclcbbkkmnmnffffffemmmfnmnmknkkbiccccclccliclcccccccciccciccciiiiciciabaabaaabkbnkknnnkkkkknnnknkdakndbkbabbbbbnbkbbaaa`bkbkmfnmbkkbbnna`ammakaaamnnnkkkkkknnkkakknkkkkmnaabakkbbabbbkknnnnnnmkajjljljjjjljljjjjjjljiljjjjjjjjjljjcccknknknnbbdknnnmmnbbbknmmnnnkkbbbabababbbbbkkkbaaa`aiabakdnkdbdbbkbkkkkkkab``bnnnnbkbbbbbbkbkkbbabbbbnnmknnmknmmm``bnmkbkbknjjjjljjjljljljjljjj`jj",
+"lljljlllllllllllllcllllllllllc`abbkknkmfmmfmfknfmmnnnkkba`cclliliccccncccccciicciccciciciiiiii`bbkbaaabbkbnnbkmkkkkkkbkbkkd`bknknnmnkabbnbkkbknbbbbbbbknmnnnnmnbkiannmnnnknnmnnkkkkkkkknnkkknnkknnnbbabbbkbbbbnkbknnmmmmnbcjjjjjjjljjjjlj`jjjlljjjjllljljljlliiknnnnnnkkbkknknfnkknknnnmmnmnmkkbbknkbaabbnknkbbbbaa`bbkbnkbkmnkkkkbbkbkkaabmkknnnnbbakkbkkkkkbakbbbdbmmnmkmnkbbcdnnmnknbkma`ijjjjjjljjjjljjjjljj",
+"ljcbaljllllllllllclllllllclcllcci`bbnbkbnknnmkknkkmkkba`ilccilcclcicl`cccciclcliccicicic`icici`nkkkbaabbkbknkbkfnnkkbbkkbbaannknnnnnnbkbkmkknnkkabaaabbbknnnnmfnk`annnmmnnnnnmnnknnknkknnkkknnnkkkkkkbabkkbbbbbkkknmmnmmfkjjljjlljjjlcljjljjjljjljljjjljjlljii`nknnnmmkbbbbnnnmnknknknnnnnmnmnnnkkkkkbaabkmmnbbnbbaabbkbkkkkknkkkkbkkkkdabknknnnnnnbbbkkkbkkkkbaadbbbkknkkmmfkkibnknnnnknmajjjljjljljljjjjjjjjjj",
+"lljci`cjlllllllllclllllllllccllllc``bbkkkkknknnkbnkba`icccccc`ccccccclcccccccaciciciciciiiiiiiankkmkbbbbbkbbkbbknnnnnkkkbaaknkknnnmmmkbbbnkbknkkbbabbbbbbkmmnmmmb`kmknnnmnknknnnkknnnnknknnkkknnnnkkmnkbbbbbkbbnnkkmmnnnnmjc`ljjjjjjjljjjjlj`jljjjljljjlljlj`c`nnknnnmkbbaabkbbknmnnknknnnnnmnmmnkbnkbbbkbnmnnknnkbbbbbbbkkbknnnnknkbkk`akkkknknnmnnbbknkbkkkkbaaabbabbknmnnmnk`kkknnnnnnbillljjljjjljjjjjjjjljj",
+"jlljcillllllllllclclllllcllllcccclcliiaabbbbbkbabaaiiiiccccccacccclciciccccciaiccicicicici`iiibnnkfnknbbbkaaknkbnnnmnnnkkbknnnkknnnnmkbbbbkbbkkbaaabbbbbbknmnknkbbknnnnnmnnnnnmmnnknknkkkmnnbkknkkkknnkbbbbkknbkkkknnnkknfjjjjjljjlljjjjljjj`jjljljjlljijjjjccaknnkkknnkb`iaabknnmnnnnknnnnnnnnnmnbkkkabkbknmnkkfnkkkbbbabbbbbknnmnnknkaknknnkknnmnnbbbbkabkbbbadaabbaabnmnknkkaknnnnnnnnfkljcjljljljjjjjjjjjjjj",
+"llllcjllllllcllllclllclclclclclcccclclcliiiai``icccccccccccibcccccccccccciciiiiciciciciciiiciinmnkmmnmkkbbbbbabbnnnmknnnkkknknnnnnnnnkkbabbbbkka`aabbbbbabnnnnkknnkmnnmmnmnnmmmnmmnnkkkknnnmkbkknnknnnnnkkkkbmmkkkkkkkkkbnjjjljjjljjjljljlljajljjjjljljjjljjjc`kmnnkknnnba```akmnnnnmnnnnknnnnnnmnkkkkbbkkknnnmknmmmnbbbkbbbbbknnmkknnkknknnknnnnnkkkbabbbbkkbiabbbbbbbdnnkkmbknnknnmnnmkmbjinijljljjjjjjjjjjjjj",
+"llljllllllllllllccclllcllclclllcllcccccccccclcccccccclcccccc`lccccicciccciccicciciciciiiiii`ickmmnmnmnbbbbbclciicccilcciliiilciccicccccclcclicllllcclcccllciiciciiciiiiicciiiicci`iiclliiiciiccciiiicciiiccccamknkkbkbkkkblljljjljjjjjjjjjjljljjlljjljjjjjjlllinmmnnnknmkaacccciiiciiiiiiiciiiciiiicccclciiicc`cciccillccclclciiciclicliicccliiciccccccclccccllllciccccliiciiiakkknnmmnmnnkciijljjjjjjjjjjjjjjjj",
+"ljlcljlllllllllllclllcllllccccccccclccllcccccccccccccccccccclccccccccicccicci`iiciiiicicii`a`ikmnmmmnkbabbijjjjjjjjljljjjjjljjjjjljjjjjjjjljljjjjjjjjjljjjljjjjjjljjljjjjjjjjljjjjljjjjjljjjljjjljjjjjjjjjjjjinnnkkbbbbbkbjjjjjjlljjjjjjjjljjljljjljajjjjjjljccknnnnknnmkbacjjjjjljjjjjljjljjljjjjljjjjjjjjljjljjljjjljjjjjjjjjjjljjljjjljjjjjljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlikkbknnmnnmkncjljjjljjjjjjjjjjjjjj",
+"llllllcllllllllcclclclclccllclclclcclcccccclilccccccccccilicciccicccccciciciibiciciciiciiia``immmmnnmknnkkillljcccjljclljlllccjijljcllljljlljjljljjljlcjlllllllllcllljlcjljjljllljjlclljllilljllclljlcicjclclcknkkkkkabbbkljjjjljjjjjjjjjjjljjljjjjjjjjjjjjjjcianmnnnknmnbacjllclcjcjcjcjllllllllljllllccjlllllljljllcjjllllljlljljjljljjjjlljjjllllllllcjllljllclljjllljljjllabbbbbknknmkn`jjljjjjjjjjjjjjjjjjj",
+"lllllljcllcllllccclllclcclclclclcccccccccmkcccilccccccccccccccicccciccccciciiaiiciiiiiiiciii`immmnmnnmmnnkclnmfffffffeeffmmffmmffmfffffmmffffeffemfffffmmmffffffffffffffffmmmffffffmffmmfffffmffffmffmmmmffmmkkmnnkbbnkabkjailjjjjjjjjjjjjjjjjjjjjjjjljjjjjjlcibknmknnnnmkdidkkkmnnnnmmmnkknkkkkkkkknkkkkkknknknnkkkkkkbkbknknnkkknnkkkbkkbbbbbkkbbbbbbbbnkkbbkbkbbkkkabbkbkda`dbbbbbbkbnmnljljljjjj`jljjjjjjjjj",
+"jlllllcbccnnclclllklclllllcclcclcllccclcciclclciccccccicccccicaiccccciciicciciciiicicicii`ii`innmmnnnmfnmnilmffffeffffffffffffmffmmffffmmfffffffffffmfmmmmffffefffeffeffmffmmmfffmmmffffffffffffffffffmmfffffnbnnkkbbkkkbaljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlcibbmmnknnmkka`bnknmmnnnnnnknnnkkkkkbkknnkbkkknknknnkkkkkkbbbkkkkkkkkkkknnkkkkbbbbkbbbbbkbbbkkkbbbkkkkkkbbbbkkbba`bbabbbabaknniljjjjljjjjjjjjjjjjj`",
+"c`iljllllliclclclkicllicllccccccccccccccaaiciclcccciclilcicccc`cciciccciciiaiiciiiciciiiii`i``nmmnkknmmmmmilmmmfffffmmffffffmmffmfmmfffmfmmfffffemmffffmmfffffffffffffffmffmmnmffmnmmfmmfeffffffffefffmmfffffkbknnmkbbknkbljjjjjjjjjjllcjjjjjjjjjjjjjjiljjjjliibknmkknnnmnnabkkkmnmnkkknknnkkkkknkkkkknkkkbkknknnkkkkkkbbkkbkkkbkbkkkkkkbkkbbbbkbbbbbkbkkkkkkbkbkbkbkkbbbkbkba`bbbbbbaabkknbjljjjjj`jjjjjjjjijjj",
+"lljlcclllllllcccclcllcllccclclcccccclccccccclciccccccciccciccaccccccicicciibiiiciiiiiii`i``i``nmnnnkknmmmnicffffffffmmmmfffmmffmffmmfffffmmmffffffmefefmfffffffnfmmmmmmmmffffffffmmmfffffffffffmefffmmffffffmnbbnnmmkbbbknjjjjjjjjjjjjjjjjjjijjjjjjjjjljjjjjliidbnmnnnknmnnaaknmnnnkkkknknnkkknkkkkbknnknkkbbkknnkkkkkkbbnkknnbbbbkbkkbbbkkkkbkkkbbbbkkkkkbkkbkbkkkbbkbkbkbkkaiabbabkkkbbbbajjjjjjjbljjjjjjjljjj",
+"llllllllcjccjlcllcclalccclclaccccccccccccccccccccciccicicccicbcicicicicicic`iciiiiiiii`iii`ii`nnnnnnknmmnmccmffffffmfmfmffffmffmfffmfeffmfmmffffffmfffmmmmfffffmmmmmmmmmmffffefffffmmffffmfffffffffmmfffefffmnkbkkmmnkbbbkjjjjjjjjjjjjjjljjjjjjjjjjjjjjjjjjjci`bbkmmnkknnnn`annnnnnnnkkknkkkknkkkkkkknnknbkbkkkkkkkkkkkkbnkkkkkbkbbbbbbbbkbknnkkbkbkbkbkbbbkbbbkkkbbbkkkkkkkbbibababbkkkkba`ljjjjjjjjjjjjjjjljjj",
+"llllllcllclliccclllclccllccik`lc`ccicccccclccccccccciclccicccciciciciciciiccciiiciiiiiiiii`ii`nmnkkkknnmnnlcmmmmffmfmffffffmmffmmfffefffmffmfffmmmnmmmmfmfffffmmmfmmmfmmmfffffmmffffmmfffmmfffffffmmmfffmefmnnkkbbknnnkbabjjjjjjjjjjjjjjijjjjjjjjjjjjjjjjjjjlc`kkkbknnnkmnnaakkknknknnkknnkkknkkkkknmnnkkkkkkkkkbbkbbkkkbkkkkkbkbkbbbbkbbbkbkkkbkbkbkbbbkkbkbbkkkbbbbkbbkkbbba`abbbaabknkkb`ljjjjjjjjjjjjjjjcjjj",
+"cllcclllllccccclclclccllcclliccciclcccccciccciccicccicaccciciciiciciciciiciiiiiiiii`i`iiiiiiibnmkkkkkknnnmcifmfmmmmmfmmffffmfffffffeffffmffffefmmfmmffmfmfefmmmmmmfmfmmmnfmmmmnmmffffffefmfffmfffmmmmmmnmfmnmnbkbbbkknnnkbljjcjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjli`bmbbbknmkkkkbannnknkkkkkknnnknnnkkknnnnkkkknknkkkkbkbkkkbkbkkkbbbbkkbkkbbbbbbbbbbbkbkbkkkkbbkkbkbkbbbbbabbkbabb`abbbbaaabkkkbljjjjjjjjjdcjjjjjjjj",
+"lccllcilclllccclllclcccccccclcclccccc`biccccccc`ccicicfiiccciiliiciciciiciiciiciiii``iii`iiiibnmmnkkknnnkklcmmmmmmmmmmmmefffffefffffmmffffmfffffnfmfffnfmfffmmmmfffmfmmmffmnmmmmmnmmfffffmfffnmfnmnmnnmmmfnmfnbkkkkkkknnnmljjljjjjjjjjjjjjjjjjjjjjjjjjljjjjjlciamkba`knnnnbb`nknkkkkkkkkknmkknmnnnkkkkkknknknknnkkkkkknkkbknbbbkkbkbbbbbbkkbbbbbbbbbbbkkkbakkbbbbbbabbababbbbb`aba`aaaabbbbbjjjjljjjjjjjjjjjjjjj",
+"lclccc``cllccclclccclccclcccccccccccccccbaiccci`cicicciicciciciciciciciiiiaiiii````ii`iiii`i``nmmnnkknnmnklammffmfmmmmmmmmffffmffffffffeffffemmmmffffffmmffmmmmffmffmmmmfffmmnmmnfmmmffffffffffmmmmnmnmmmfffmmnkkkknkbkmnnjjjjjjjjljjjjjjjjjjjjjjjjjjjjjjjjjcccbnbbabbbnnknn`nnknnkkkkkkkkknnnkknnnnknkkknnkkbkbbkkkkkkkkkkbbbbkkbkbkbbbkkkbbbbbbbbbbbkkkkbkkkbbbbabbabbbkbbkbbbnbi`ii`abkbbjjjjeajjjjjjjjjjjjjj",
+"ccllllcclclcclcclcllcclccccclcccccccccciciicicccilckciciiciciciciiciiicicii`i`iiii`iiiiii`ii``nnmnnnnnmnnklammfffmfmmmmmmmffmmmmffmfffmfffmffnmmmfmfmfmmnmmmmmmmmmmfmmnmmmmnmmmmmmmnnmmmefffmnmfnnnnmnnmnnffmmkbbkkkbabmnkljljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjl``abkbkbbbknnmm`knknnknkkkkkkknkkkkkkbkkkkknnnknbkbbkkkbbbbbbbkbbbbkkbkkkbbbbbbbbbbbbbbbbbbbkkkbbbkbbbbabbaabbbkbaakbiiii`aabbkcljjjjjjjjjjljjjjdkj",
+"clllclclimalccllcclclcccclcccccccccccccccicccciiiciiccicciciciciiciiiiic`iakciiiiiiiiii`ii`iiakmmnnnnnnmnkjanmmfffmfmmmnmmmmmnmmmmmmmmmmfeffmmfmmffmmffmmmmmmmmmmmffmmmmmmmmmmmmmnmmmnnmmfffffmnmnmmmnmnnmffmnnbbbbbbabnmmcjjjj`jjjjjjjjjjjjjjjjjjjjjjjjjcljlii`knkbbbkkbnnn`kknnnnkkkkkbkknkbbkkkkbbkkbknnknkkbkkkkbkkkbbbbkbbbbbbkbkbbbbbbbbbbbbbbbababbkbkbbbbabbbbababbbbb``ka`icc``aabkljjjjjjjjjjjjjjjjjjj",
+"lclcllcccclcllcclc`kcclcclccclcacicciliccccccccccicciciciciciciciiiciciiii`i`iiiiiii`iiaiii`iakmnmnmnnnnnblbmmfmfffmmmmmmfmmmmmffmmnmnmfmffmmmmmmfmmmffnfmmmmnmnmmmmmmmmmmmmmmnmmmmmmmnmmmmffmmmmmmmmmnnffmfmnnnbbbkkbbbbbcjjjjiljjjljjjjjjjjjjjjjjjjjjjjljjlc`aknnkkbbkbbbk`knnnnnnnkkkkkkkkkkkkkkkkkbbkbnkkkkkbkkkbkkkkbbkbbbbbbbbbbkbbkbkbbbbbbbbbbbbbkbbbkbbababbbbbbbbbkba`bb``lciaabkncjjjjjjjjjjjjjjjjjjj",
+"llllllccccllcclccccciclccclc`iliccclccicicciiicccicciiciciiciiiiciiiiiii`iicii`c`iiiiii`iii``annmmnnnmnnnbjbmffffmfmmmnnmmmmmmmfmmffmmmnmmfmmfmmmmfnmfmmnmnmmmmffmnmnmmmnmmmmmmmmnnmmnmmfmknffmknnmmmnmmffffnmnnnkbbkbbba`ljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjli`annnnnkbbbb`aiknnknknkkkkkkkkkbkknkkbkbkkbkkkkbkkbkkbbbbkbbbbbbbkkkkbbbbbbbbbbbbbbbbbbbbabkbbbkbbbbbabbbakbkbbbb`kbailciankkn`jjjjjjjjjjjljjjjjjj",
+"clllccllllccjcilccllnacllicanaclccn`ccikaicccciicci`cciciciciciiii`iiii`ib`iiiciiiii`iiiii`i`knmmmnmnnmmmblkffffmfmmmmmmmnmmmmmmmmmmmmmnfmfnmffmmmmfmmfmmmfnmmffffmnmmmmmnmnmmnmmmnmmmmfnffffmffmmnmnmmfffffmnnnnnkbbakn``jjjjajji`jjjjjjjjjjjjjljjjjjjjjjjjl`i`nnnnnnbka`ciinnnnnknkkkbkbbkkkkkkkbkkbkbkkkbkbbkkbbkkkkbkkkkbbbnknkbbbbbbbbbbbbbbbbbbbbbkbbbbkbbbbbbbabbbkkkkka`kb`clciannkk`jjjjjjjjjjjjjjjjjjj",
+"clclcclccclicllclcccacciccciicciicacccli`cccccccicimiiciiiciiiiii`i`i`i`iicii`iii`iiii`ii`ii`knnmnnnmmnmmblkmffmfmmmmnmmnmmmmmmfmnmmnmfffmfmmfmmmmmfmffffffmmffmffmnmmmmmmmmmmmmmmmnmmfmfmmmmmffffmmmnmffmffmmnnmnnkbbknblijjljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjiiannnknkbbi`ciinnnnnkkkkkkkkkkkkkkkkkkkkbkkkkkkkkkbbkkkkkknkkkbkkkkkkbbbkbbbbbbbbbbbbbbbbbbbkkbbbkbkbbbbbbbbkbbbbibbicci`kknnnajjjjjjjjjjjjjjjjjjj",
+"llcllclclcjcccclclcclcccbcccccccccicicicccciciiccccicciiciicicii`iii``iiiiiiicii`a`iii`iiiiiinnnnnmnnmnmnbjkmffmmmmmmmmmmmmmmmmmmmffffeffnmmffmmmmmmmnffmffnmffmmmmnnmmmmmmmmmmmmmmnnmmnnmmfmmmmmnmnnmmmmmmmmnmnnmnnkbbba`jijjjjjjjjjjjjjjjjjjjjjjjjjjjjljjjl`iaknmkkb`iiii``nnnkkkkkkkkkkkkkbbkkbbkknnmnkkkkkkkbkbkkbbbkkkkkkknkkkbbbbbkbbbbkbbbbbbbabbbbabkkbabbbbbabakbbbbbb`ab`````nnnkk`jjjjjjjjjjjjjjjjjjj",
+"lcllccccccclclcccccccccciccccccccccccicciciccciciiciciciiciciiiiaiia`iiiiiiiiiii```i`iii`iiiikkkbmmmnmmnnalnfmmmnmmnmmmmmmmmnmmnmffmffmffffmmfmnmmmmmnmffmfmffffffmmmnnmnnmmmmmmmmmmnnnmmmmmmmnmmmmmmmnnmnnmmmnnmkmnnkabi`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjii`nnnka`ic`a``innknkkkkkkbkkkkkkkkbkkkknkkkknkkkkbbkkbkbbbkkkkkbknbkkbbbbbbbbbbbbbbbbbbbababbkbbbbbbabbbbbabbabbbcibbai`akkmkkbjjjjjjjjjjjjjjjjjjj",
+"lccllccclclccclccccccccccccicccc`ciliciccccciccccciciciciciiiii`faiii`iiiiii`ii`ii`ii`iiiiiiikmnkbmmnmmnfalkmmfmmffnmnmmmmmmmmfmffffffnmfmfmffmmmmmmmmmfmfffffffmffmmmmmmmmmmnnmnnnnmmmmnmmmmmmmmmmmmnnmnnnmmmmnnmnnnkba`ajjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj`i`nnbbaa`iaaa`inkkkkknkkkkkkkkkbkkkkkknknnbkkkkknkkkbkbbkbkkbbkkkkbkkknbbbbbbbbkbbbbbbabbbbbbbbbbbbbbbbbbabbababa``bba`aabbbnfkjjjjjjjjjjjjjjjjjjj",
+"clcllclllclccclcclcccccccccclciccicccccciciiiciiciciciiciiiiii`iicciiiiiiiiiiiiiiiiiii`iiiii`nnmbbkmnmmnk`jnnmmmffmmnmnmmnmmnmfmmmfffffmfmfmffnmmmnmmmmfnfmfmfffffffmnnmmmmnmmnmmmnmnmmmmmmmmmmnmmmmmmmfnnnnnnknnfkkknn``aljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji``nnnbbbaaabaaikknkknnkbkbkkkkkkbkknkkknnnkkkkkkkbbbbbbbkkbkkkknkknkkkkbbbbbkbbbbbbbbabbbbbbbbbbbbbbbbbbbbbbbabba`aba`abbbkbakkjjjjjjjjjjjjjjjjjjj",
+"lclclccccccllccccccccccccciciccclic`cciiiciiiiciiiicicciiiiiiiciii`iiiiiiii`iii`ii`i`iii`ii`akbmnabnnnmnb`jffffmfffmmmnmmnmmmmfmfmmmffffffffffmfnmmnmmmfmffmmfffmmfmmmmmmnnmmmmmmmmnmnmnmmmmmmmnmnnnmfmmfmmmmnknnmnkknkaabjlljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlic`bkmkbbbabbaainnnknnnkkkkbkkkkkkknkkkkkkknkknkkkkkkkbbbbbbnnkkkbnnkbbbkbbbbbbbbbbkbbbbbbbbbbbbbbbabbbabbbkbbbbbba`baaabkbnbbkbccjjjjjjjjjjjjjjjjj",
+"clcccclcall`lcclccccccccccccbiciicicccicccciicciciciciiii`iiiiiiiiccii`iiiiii`ii`iiiiiiiiiciabbkbbbbmmnnn`jffmmfmfmmmmnfmmmfffffffmmmfffmfffffffffmnmnnmfffmmmffffmmmmnnmnmmfmfmnmmmmmmmmnmnnnnnmnnmmmmmmfmmmnnknknkknbbbkljjjjjjjljjjjjjjjjjjjjjjjjjjjjjjjjj`iabknnnkknnkbbinnnnnnnkkkkkkkkknnknnkkkkkkkkkkknnknnkkbkbbbnkkkbbkkkkkkbbbbbbbbkkkbkbbbbbbbbbbbbbabbabbbbbbbbbbbbaabababbbbmnkbljjjjjjjjjjjjjjjjjj",
+"clclclcl`lcmcccccccccccccciikiiiii``iiicicciiccicicicii`iiiiiiiii```iiiiii`iiiiii`ii`iiiiiii`bbbbkbbmmnmmilmfnmmmmmmmmmmmmffffffffmmffmmffmmfmffmmmmmmmffmfnmmffffmmmmnnmmmffmmmmnmmmmmmmnmnmnmmmfffnnnnmnnmmnnkkknnkkbkbkljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji``mnkkknnmmkbbiknnnkkkknnkkkknknnnnnnnkkkkkkknkkkkkkkkbkbkbkbkkbbbkkbkbkbbbbbbkbkkbbbbbbbbbbbbbabbbbbbbbbbbabbabba`b`bkkkkabmmbljjjjjjjjjjjjjjjjjj",
+"clcccllclcikcc`cccccccciiciib`iiiiabibiiiiiiciiiiiiiiiiiiiiiiiiiiiiciiiiiiii`i`iiiiiiiiiiiic`kbkbbbbnmnnmicmfffmmmfmfmnmfmmfffffmmmmffmffffmmnmmmmmmffmmmmmnmfffnmmmmfffmffffmnmmmmmmmnnmmnmmmmmmffmmnmmnmmnmnnnkkknkkdbbkljjjjjjjjjjljjjjjjjjjjjjjjjjjjjjjjji``mnkbbkknkkbaiknnnkbkknkkkknkknnknkkkkknnnknkkbkbbbkbkkkkkkkkkbbkkkbbbbkkbkbkkkbbbbbbbbbbbbbbabbkbbbkbbbbabababaaiiibknnkkknnnijjjjjjjjjjjjjjjjjj",
+"cclcclcclccclcnicccccciiiiiiciii`ca`iaiciiiciiiiiiiii`iiiiiiiiiiiiii`ic`i`iiiii`iii`iiiiiiii`bknbkkbbnmnnilnfffnmmmmmmmffmfffffmmfnmffffffnmfnmfmfffffmnffmmnfmmmfmmfmmmmffffmmmmmmnmnmmnmmmmmmfmnnnmmnnmnmnnkknkkbnnkbbnbljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjii`kmnkbbkkbbbbiknnnkknkkkkkknkknnnknkbkkkkkkknbkkkkkkkkknnkbkkbbbkbbbkkkbkbbbkknkbbbkbbbbbbbbbbbbkbbbbbbabbbbbabbalilbkkkknnnnmijjjjjjjjjjjjjjjjjj",
+"lccclccclcccccccccccciiiiiiiiciiiiii`i`iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii`ii`iiiiiiiiiiciankbbkbbbkkmmccnfffffffmffffmmnmmmmfmmmfffffmmfffmfffmmfffmmffffffnmmfffmmmfmfffmmmnfmnmmmnmnnmffmnnnnnnnnmmnmmnnnkknnkkbkkkknljjjjajjjjjjjjjjjjjjjjjjjjjjjjjjjjjc`iknmnbbbkbbba`bnmnnnnnnnnnnnkkkkbnkbkkknkkkkknnkbkknkkkkkbkknnkkbkbkkkbkbkkbbkkbkbbkbbbbbbababkbbabbaabbbaabbbaaalccankknkbnbkajjjjjjjjjjjjjjjjjj",
+"lclliclcccccccccccccciiia`ccciiicickkiiiiiiii`ii`iiiiiiiiiiiiiiiiiiiii`ii`iiii`ai`iiiiii`ii``mnkkbbbabkkklcnnffffffffefffmmnfffmffffmmmmfmfmmnmmffmnmmmffffffmmmmmmmmmffmfffffmmmmnmnnmnmmmmnnnnnnmmmnnkmmmnmnbbknnkbbknnnljjjjjjjjjjjjjjljjjjjjjjjjjjjjjjjjjia`kbnmnbbbbbkaabknnnnmnnnnnnnkkkknkkknkkknkkbkbkkkkknkkkkknnkkkknkkbbkbkbbkkkkkkkkkbbbbbbbbbbbbbbbababbbabbbbbbkbalciakkknnknkkdjjjjjjjjjjjjjjjjjj",
+"cclibccaccclcccccccciiicaccciiicic`aai`iiiiiiiiiiiiiiciii`iiiiiii`i`iii`iii`ii`iiiiiiiiciccc`knknkkkbaaa`lifmfmmmfffffffmmnmmffmmfmmmmmmffmfmfffffmfmmmfmfmmnnfnfmmmmnfffffffmmmnmnmmnmmmfmnnmfmfmmfffmmmnmnmnkkbkkkabkknncjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjc``kbknmnbbknnkabnkkbnnnnmnnnnnkkknknnnnkknbknkkkbkkkkkkkkkkbkkkbbbkbkbbbkbbkkkkkbbbbbbbbbabbbbbbbakbkbkkkbabbabbbkci`akknkknkkkajjjjjjjjjjjjjjjjjj",
+"cclc`lcccccccccccccciiiccciiicciicac`ii`ii`i`iiiiiiiiiiiiiiiiiii`iiii`ii`iiiiiiiiiiiiiiciiiiakkknnmnba``ij`mmmmmffffmmnmnmfmmffmfffffmmmffmmmmnmnffffmmmmfnmmmfffnmfnnffmmmmmmmmmnmnnmmfmmnnnffffmmmmmmnmnnnmnknkbabkkkbbkljjjjjjjjjjjjjjjjjjljjjjjjjjjjjjjjji`ikkkkkmmnnnfnbbnknknnnnkknkkkkkkknkkkknnnbknnkkkkbkkknknkbkkkkbbbbkkkbkbbkkkkbbbbbbbbbabbbbkkababkbkbbbbbbbbbbabki`abkkkkkknnkbjjjjjjjjjjjjjjjjjj",
+"lcllccclcccccccccciiiiiccciicciiciciiiiiiii`iiiiiciiiiiiiiiiiiiiii`iiiiii`bb`iiii`iiiciiiccibnkkbknbba`cijafmmfmfffmmmnmnnmffmffffffffffffmmmmffmffffmmnmfnnmnfmfmmfnnmnmmnnnnmmmnnnmmmmmnnnfmmmnmmfffnnnmmffmknkbabbbkkkkljjjjjjjjjjjjjjjjjjjjjjjjjjjjj`ljjjca`bknkknmnmnnmbannnknkkkkknkbkkkkknnknnnknknkkkbkknkkkkkkkkbbkbbbbbkbbkkbbbbbbbbabbbbbbbbbbkbbabbbbbbbbbkbkbaabkkbaakkkkbbbkknnnjjjjjjjjjjkjjjjjlj",
+"cccclcccccccccccccccciiiiciicciccici`ii`i`i`iiiiiiiiiiiiiiiiiii`iiiii`iiiiiicci`iiiiciiiiiciakkkknkaaa`i`jamfmmmmmmfmmnnfnnmffmfmfmfmmffffffffffffmmmfmmmmnmmnfmmmmfmnmnnmmmmmnnmnnmmmmnnnnmfmmnffmmfmmmnnmmmnnnmkbkbbknnbljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji`ikkknkbkmnnkkbannkkknknnkkbkbkbkknnnnnkkknknnknknkkkkkkkkkbbbkkbbbkkbbkbbabbbbbbbbbbbabbbbbbaabkkbbkkkbkbbbbbbkbbaakkkkkkkbbbknjjjjjjjjjjjjjjjjjj",
+"clcccilcccccccciiciciiicccciciicic`iii``ii`iiiiiciiiiiiiii`iii`ii`iiiiiiiiii`iiiiiiiiiiiiiiibkknnkaaaa`abjanmnnfmmmfmmnnmmnmmmmmffmmnnmmffffmmnnfmfmfffmffmffmmmmfmmnmmnmmmmmnmnnmmmfmnnnnmmmmmfmmnnnnmmnmmnmmnmmnkkkkkkkkljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjc``kbkkkbknmnkkbannkknkkkkkbkkkbkkknkkkkkbbkkknnkkkkbkknkkkkknnkkkkbbbkkbbbbbbbbbbbbbbbbbbbbbabbbbkbbbbbbabbbbbbabbaaknknkknkkbkkljjjjjjjjjjjjjjjjk",
+"lcccbf`cccccciiaccccciiiiciccciiiiim`iaii`iiiciiiiiiiiiiiii`iiiiiii`i`iii`iciiiiiiii```iiiicabbbkb`iba`abjamfnnmfmmmmmmfnffmmmmnnmmmmnmfmmmmmnnnnfffmmfffnmmmfnmmmmnnnmmmmmmnmnmnnnmmnnnnmfmnmmmnnnnnnnnmmfmffmnnmmnkknbbbljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjl`ibabbkkkbnnkbkakkbkkkkknkkknkkknknkbbkkkbbkkbkkbkbbbknnkkkkkkbkkkbkbbkbbbbkbbkkbbbabbbbbbbbabbkbbakbabbabbbabbkkka`knknnmnnnbnkljjljjjjjjjjjjjjjj",
+"k`ii`icclccccciccciicc`ccicicciiciicibniiiiiiiiiiiiiiii`caci`ii`i`iiiiiiiiiiiiciiciiiniiiiic`b`abaiiaaabbjbmmmmmnnnmmmfffffmfmnnmnffmnnnmmmnnnmnnmffmmmffmmffmmmnmfmmmnmmmmnnnmnfffmnnmmffmmmnmnnnnmmnmfnmmfmnnmnmmnnkkknbcjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjci`akkbkkkbbbmkkanknnkkbkkknnkknnknbbbbnknkbkbkkkbbkbbbkkknbkkbbkkkbbbkknkbbbbkbbbbbbbbkkbbabkbbbbbkbbaaabbabbbbbbbaakknnnkbknnkbijjjjjjjjjjjjjjjjj",
+"ilcciccciccccccciccccii`iiiiciiciiiiiiai`iiiiiiiiiiii`ic`ii`iiaciiiiiiiiiiiciiiiii`iiaiiiccaabaab`iiaabbblkfmmfmmnmmmfmmfffmmnnmnnmmffmmffffmmmmmmmmmmmnmnmmmnnmmmnmmnnmnnnnmmnmmmnmnnmfnmmfmnnnnnnmmmmmmmmmmnnnmmnmnnnkbk`jjjjjjjjjjajjjjjjjjjjjjjjjjjjjjjjjc`iabnkkkbbbbkkk`knnnnbbkknnnnnmnbkbkkkbkknkkkknkkkbbbbkkkkbbkbkbbkbbbbbbbbbbbbbbbbbbbbbbbabbkkbkbkababbbbbkkbbbbbbb`knnnnkbbkkkkijjjjjjjjjjjjjjjjj",
+"cccciciclccicliaccccciliiicciiiiiii`iiiiiiiiiiiiifkiikaiiiiii`c`iiiii`aai`c`iiiiiiiiiciiiac`bb`aacc`bbkkalkmnmfmnnnnmmmnfffnnnnmnmmmmmmmmmnmmmnmmffffmmffmmmmmmmnnnffmnmnnmmfmmmnnmmmnmmnnmnnnnnnnmnffmmnmnnmmnfmnmmnmnnkbljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjli`bbbbkkkkkbkkk`knkkkkkbbkbkbknnkbbkbbbkkkbkkkkkbkkkkkkkkkkkkkkbbkbkkbbbknbbbbbbbbkbbbbkkbbbbbbbbabbbbbbbbbkbbbbabaannnknnbbknkk`jjjjjjjjjjjjjjjjj",
+"cciccicccccccciicciciiiiiciiiiiiiiiii`iiiiiiiiiiiic`iicii``ii`iiiiiiiii`iaikiiiiiiiciciiikilab`a`ciakkbk`jnmnmmmmmnmmffmmfmnnmmnnmfmnmmfmmmnmmffmmmfmfmmfmmmmmmfnnmffmnmnnknnnknmmfffmnnnnnnnmmmnmfmnmnmnnnnnnmmnmmnnnnnmkljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjic`bkbbbbkkbbnkk`kkknnnnkbnnnknnkbkbbbkknkbkknkkbkbkkkkkkkkkkkkkbkkbkbbbbkkbbbbabbbbbbbbkkkkbbbaabbbbbbbbbbbbbabbaba`knnnnmkbmmnndjjjjjjjjjjjjjjjjj",
+"ccccccciccccciclcicicia`aiiiicciii`iiai`iiiiiiiic`iikb```ii`eic`iiiiiciccnicbiciiccciciciiickai``c`bnkkkajnmmmmmmnmmmfmmmmmnmmmnnmfmmmffmmnnmmfmnmmfmfmfmnmmnmmnnmfmmmfffnnmnnnmmmfffnnnnnnfffmmmmfmnnmnmfmnnnnmmnkknnnnnn`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlicibnnnkbbkkbnkk`nknnkkkkknnnkkkkbkbbkbnnkkbkkkkkbkkkkbbbkkkkkbbkkbbbbbbkkbkkkbbbabbabkkkkkbbbbbkkkkkbbbkbbbabbbbbbb`aaknnknkmmnnbjjjjjjjjjjjjjjjjj",
+"cclicciiccccccciccciccbib`ciiiiiiiiii`iiiiiiiiii`iiia`ica`iciin`iiii`iii``cinciccicccccciccinic``aaknnkkajnmfmmnnnnnnnnnnmnnmfmmffmfmmmmnmfmmmmnmmmffffmmmmfmnmnnmffmmmnmnnnnnnmmmmmnmnnmffffmmmmfmmmmmmnmmmnmnnmnnkknnnkn`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjiciibkmnkkkkkkkkk`nmkkbbkbbkbbbbkbbkkkkkkkknkkkkbbkbkkbbbkkkknkbkkkbkkbbbkkkkbkbbbbbbbbkbbkbababkbkbkbbbkkbbbbbbbbbbb`baabnnnkmnnkkjjjjjjjjjjjjjjjjj",
+"cclcccciaicccccciic`icacaiciiii`ii`iiiiiiiiiiiiiiiii`ii`i`i`ciaiiiiiiiiciliaf`ilcciccccccicckic`abkknnnnajmmmnnmmmmnmnmnnnnnmfmmnnnmffffmffffmmnnnmmmmmmmnffmmfmnmfffmmnmmfmmmffmmnmnmmffmmmnnmnfmmmfmmmnmmnmnnnnnmkbbknmkijjjjjjjbjjjjjjjjjjjjjjjjjjjjjjjjjlciibbkknnkknbkkbikkkknknkkkkkkkkbbkkknkbkkknnnnkknkkkbbbkkkbkkkkkkbbbkbbbkkbbbbkbbbkbkkbbbbbbkkkbbbbbbbbkbbbkbbbbbbbakkbbknmnmnnnkjjjjjjjjjjjjjjjjj",
+"ccccciciiiicciccccciiciiii`iiiiiiiiiii`iiiiiiiiiiii```ii`iiiiiiiiiiiiii`cicia`aiicicccccciciaca`aknkknnn`jfmmnnmmnmmmnmmnnnnmnnmmmnnmnmffffffnnnnmmmfmfmnmmfmmmmfmmmmmnmnmffmmmnnnmmmmmfnnnnmfmnmmmfmmnmmnnnnnkknmnkabkknnijjjijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjci`akkkkknnbknkkannbnkkkkkkkkkbkbknbkbkbkbbkbkkkknkbbbbbbbbkkkkbbbnkkbkknkkkbkbkkkkbbbbbbbkkbbbabbbbbbbbkkkbbbbbabbb`bnnbbknmmnnkbjjjjjjjjjjjjjjjjj",
+"cccccciiicccccicicicciiiii``biiii`ii`a`iiiiiiiiiiii`iiiia`ii``iciccici`ciicci`icbicccccccici`i`aknknnnnn`jffnnfmmnmnmmmnnnmmmmmnfmmmnmmmnmmffnmnnnmnnnnfnmmfmmmfmnmmmnnnmnnnmmmmmnmmfmmfnnnnmfmmmmmnnmmfnmnnmnmkknnkbbbbkkcjjjjjjjjjjjjjjjjjjjjjjjljcljjjjjjjci`abkkkknkmbnkn`nkkkkkkkkkkknkbkkkbkkknkkbkkkkbbkmkkbbbbbbbbkbbbknkbkkbbbkbkbbbbbbkkkbakkbkkkbbaabbkbkbabbbbkbbbbbbaannnkbbnnmnnnjjjjjjjjjjjjjjjjj",
+"ccccccciicicicciciaaiccc`iii`iiiiiiiii`iiiiiiiii``iiiii`aiiiaa``ciiiiiiccciciiicilcclcccccciaabkkknnnnnn`jfmnnmnmmnnmmnnnnmmmmfmnnmmfnmfnmmffmmmmnmnnnmmnnnmmnnmmmmmmfffmnmmmmmmmnmmfmmmmnnnnmmnmnnnnmnnnnnmnmmnbnnbbkkbakijjjjcljjjjjjjjjjjjjjbljcjjljjjjjjcjiaakbkkbnknnnmm`nkkkkkkkkkkkbbbkkkkkkkkbknbkkkkbbkkkkkbkbbbbbkbbbkbbbbkbkkbkbkbbbbbbbkbbbkbbkkbkabkbkbbbbabbbbabbbaabnnnnbbbknmnnljjjjjjjjjjjjjjjj",
+"lciccciiciciccicciiiiiciii```i``i`iiiiiiiiiiii`iii`ii``b`iiiiiicicicciiiciccccccccicccccccciabkkknnnnnnnilnnnmnmnnnnnnnmnffmmmmmnmmfmnmffmmmfmfmnmmmnnnmmmmmnmmnnnnmnmmmnnmmmnmmmmmmmmnnmmmmfffmmmmnnmmnmmnnnnnnbkbbbkbbabcjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj``iabkbkbkkknknn`kkkkkkkkbkbkbkkknkknkkbkknbkknkkknkknbbkkbbbbbkbbbbbbbbbbkbbkkbbbkbkkbkkkbkbbabkbkbbbbbbaabkbbbbbbaaannnmnbbbkknmcjjjjjjjjjjjjjjjj",
+"iiiccciiiiciciccicicccci``iiii`ii`iiiiiiiiii`iii`i`iiii`iiiiiciiiciciiiiciicccccci`ilccccccaabkknnnnnnnnclmnnmnnnnnnnnmnmfmmmnnmmmmmmnmmmmmmfmmmnnmnmnnnmmmnnmmmnnnnnnnnmnnnffmnmnmmmnnnfmmnmmmmmmmnmmffmmnmnkkknkbkkbabbbcjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjli`abkbkbkkknkkkckkbkkbkbkbkbkkknkkkkbbknkkkbkkkkknkkkbbbkbbbbbkbkkbkkbbbbbbbbbbbbbbkkbbbkbkabbkkbbbknkbkkkbbkkbbbabaamnnnnkbbabbncjjjjj`ljjjjjjjjj",
+"ciicciiiiiiiciicccciiiamb`i`i````iiiiiiiii`iii`iiii`iiciiiiiiiiiiciiiiiciiiccccccciccclccli`kkmmknknknnnccmnnfnnnnnnnnmfnmfnmnnnmmmmmmnnmnmmmmmmnnnmnnnnnnnnmmmmfmnnnnnmnnnmffmmmmmmnnnnnnnnnnmmnfmmnmmfmnnnnnkkkbbkkbabbbcjjjjjbjjjjjjjjjjjjjjjjjcjjjjjjjjjjcci`bbkbbkbkkkbkckkkkkkbbbbbkkkknkkbbbbnnkkkkbkkbbkkkkkbbbbbbbbbbbbbbkkbbbbbbbbbabkkbbbbbbkbabbbbababbbbbbbabkkbbaababnnmnmnbbbbab`jjjjjijjjjjjjjjj",
+"ccccciiciiiiiiiiiiciiccaiii`iiii`iiiiiiiiiii`i`i`iii`i`iiiiiiicciiciii`iiiiiciccclcclccccccaknmmmmnnnkknlcmnnmnnnnnnnnmfmfmmmnnnfmmmffmmmmnnnmnfnmnnmnmnnnnnnmmfnnnmmmnnnmmmnmmmmfmmnknnnnnnmmmfmmmnnmmmmknnnnkbabbbabaakaljjjjjjjjjjjjjjjjjjcjjjjjjjjjjjj`jjli``bkbbbkbkknkkckkkkkbkbkbbkknnknnkbbkkkkknkkkkkbbbbbkkbbbkbbbbabbbkbkbbbbbbbbbbbbkkkkkkkkbdbaabbbkbbbkkbbbbbbbabbabakmnnnkkbkkbbijjjjjjjljjjjjjjj",
+"cccciciiiiiiiiiiciiab`icci`a`ic`i`iii`ii`iiiii`i`iiiicciciiicciiiccicibiiiccccccicccccclcccanmnmmmmnkkkklimnnmnnnnnnnmfffffmnnnnfnnnmffffnmnnmnmmmnmnnnmnnnmmnmmnnmffmmnmmmnnnmmfmnmmnmmmmmnnnnnmmnmmmnmnnnnknkbabkbbbabbaljjjjjjjjjjjbjjjjjjjjjjjjjjjjjjjjijliiabbkbbkkbkkkb`kkkkkkbbkbbknnnnkkkbkbkbbkknkkkkkbbbbkkbkbbbbbbbbbbbbkbbbbkbbbbbbbbbbkbkbbbbbkkbbbbbbbbbbbbbbbbabbba`bnnnnknnbkbb`jjjjjjjjjjjjjjjj",
+"ccccccciiiiiiiiii`iiiiii``iiiiciiiiiii`iiiiii`i`iiiiiiiiiiiciiicciiaicaicciiccccclcclcclllcafmnfnmnnnnnnlcmfnmnmnnnnnmmfmmnnnnnnnnnnmmmmmnmnmfnnfmnnnnnnnnnmnknnnnnnnnnmmnnnnmfmmnnnnmmmmnmnnnmfnnmmmnnmnknkknbbbbbkbaaaaaljjjjjjjjjjjljjji`jjjjjjjjjjjcljjjjj`iabkkkbkkkkkmaaknkkkkbkbbkknnkkkkbbbbnbbbkkkkkbkbnkkbkkkbbbbbbbbkbbbbbabbbbbbbbbbbbbkkbbbbbkbbbbbabbkbabkbbbbbbaaaa`aknnnmnkknbbajjjjjjjjjjjjjjjj",
+"icccci`cciciiiiiii`iiiiiii``iiiiii`iiiii`i```iii``ci`ciiiiiccicicccciciiicicccccccclccccclikmmnmnmnnnnnklammnnknnnnnnnnnmmmnnknmnnnnnnmmmmmmfnnmnmmmmnmnmnnnmmnnnnnnnnnnnnmmmmmfnnnnnfnmmnnnnnkmmnnnmmnnmnmnnkbbabbba`aaailjjcjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjliiakbknkkkbknnk`nkkbbkkbkbbbkknkkbbkbkbkbbbkkkkbknbnbbbkbnkbbbkbkbbbbbbbbbabbbbbbbkbbbbbbbabkkkbbbbbbbbbabbbabbbbbaaibbbbknmmknkabjjjjjjjjjjjjjjjj",
+"icciccccciicci`bi``i`iii`i``ciiiciiiiiiiiiiiii`aci`iiiciiiiiiiccciicccccccciciccccccccclclcbnnmmnnnnnnnklaffmnnmnnnnnnmmmmmnnnmmnnknmmmmnnmmfnnnnnmmnmnnnmnnmnmnknmnnmmnmmfmmnnnnnnmmfmmnnnnnnnmmmmmnnnkmnnnnkbababaa`aaicjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjliiakkabkkkkknnnannkkbbkbbkbkkkknkkkbbnbbbbbbkkkkkkbkkbbbkkkkbbbbbbbbbbbabbbbbbbkkkbbbbbabbbkbbbbabbbabkkbbabbabbbabb`abbbkknmmmkbb`ljjjjjjjjjjjjjj",
+"macciiiicicciii`iii`i`i`i`knai`c`iii`iii`ii`ii`aaciiafiiiciiiciacciccccciciiccclccclccllclcaknnmmnnmnnnnjbmffmnnmnnnnnmmmfnmnnmfmnknmmmnmnmnnnmnmmnmmmnnnnnnnnnnnmmmnmmnnmmnnnnnnnnnnnnnnnmnnnmnnnmnnnknnnnnnkabaaaai```iiljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjiiakbaakkknnnmnankmnkkkkkkbbkkkkkkkbbnkkbbnkkkkbbbbbkbkbnkkkbbbbabbbbbbbkkkkbbbbbbbbbbbbbbabbbbabbabbbbabkabababbbbb`abbbbbknmmnbbljjjjjjjjjjjjjjj",
+"biccclcciicciccii`iiii`iii``ci`ia`iiiii`iii`iii`c`iiii`ciiicccibccciciciiiiiiicccccclccclclabkkkmnnmmnmklanmmnnnmnnnnnnmmfmnnnnmmnknmmnnmnmnnmfmmnmmmmmnnknknnnnmmmmmmnnmnnmmmmmmnmknmmmnmmmmmnnnnnmnnnnknnnmkabbaa```a`iiljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlii`kkbabkbkknmnakknkkbkkkkbbkknkkkkbbnkkbbkkbbbkkkbbknkbkbbkkbabbbbbbbbbkkbbbbbkbbbbbbbbbbbbbbkbbbbkbbbabbabbababbbb`abbbbbabknkkajjjjjjjjjjjjjjjj",
+"cciiiiiicciiccib`iii`ii`i`````ic`ii`iii`i`i`iiiiiiiciiciicciiciiiccciiiciiciccilcclclcllcll``aaknmmnmnmblbnnmnnmmnmnnnnmmmmmnknnmnnnnnnnnnmnmnfnknnnnknnnnnnnnnnnnmmnmnmnmnnmmmmmnfnfmmnnnnmmmmnnnnknnnknnkknkabbaaaabba``cjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjii`baaaabakkbknakkkkbkkkkkkbbkknkkkbbbkkkbbbbbbbkkbbkkbbbbbbbbbbbbbbbkbkbbbkbkbbbkbbkkbbbbbkbbbbbbkkbbabaabaaaabaaaa`i```aabaknnbacjjjjjjjjjjjjjjl",
+"icccciccicciic`b```iiiiii``iiiiiiiii`iii`iiii`iiicii`cicciiciicccccccicciicicciclcclclcllcli``akkmmmnmnbjbnmmnmnmmmmnnnnmmmmnnnkmnnnnnnnkknnnnnnnnnnnknnmnnnnmmmnmmnnnnnnknknnnmmnmnnnnnnnknmmnnkkkknnkknnnknkabbaaabbkabaijjjjjjjjjjjjjjjjjjjjjjjjjjjljjjjjjjcci`ii`abbkkbkkabnkknknknknkbbkknnkkbbbkkbbkkbbbbbkkbkbbbbbbbabbbbbbkbkkkkbbkbbababbbbkbbbbbbabbabbkbabaababbbbbbabaiciii`aabbnnkacjjjjjjjjjjjjjjj",
+"liiicciiiicciiii`i`iiiii``ii``iii`iiii`i`iiiiiiiki`cciciciiccccicccccccccicciiaicccllcllclcaaabknmmnmnnbjkmmfnnnmmfmmnnknmmfmnmnnnnnnnnnnnnnnnnmnnnnnnnnnnnnnnnmmmmnnmmknnnknnmmnnknnmmfmnnmmmnmnnnnnmmnnnnkkbabaaaabkkbnaijjjjjjjjljjjjjjjjjjjjjjjjjjjjjjjjjjilcic``bkbkkkkbaankkkbkkkkkkkbbkknnkkbkbkbbbkkbbbkkbbbbkbbbbabbbbbabbbbbkbbbbbbbbababbkbbabbkkkbbbbkkkbbbbbabbbbabaaalccciabbbkkkbijjjjjjjjjjjjjjj",
+"icciciccciiciiiiii`iiiiiii`iii`iiiii`i`iii`iiiiiiic`ciiiiicciicccciccccccilcclilclclclccllcbbbbmmmmmmnnbjkmmmnknnmmnmmmnmfmfmmmfnnmmmmnnknmnmnnmnnnnnnnnnnnnnnnnmmmmmmmmnnnnnnnmnnnmnmnnnnknnmmnmnnnnnnnnnnnnkbb`i`aabnnkaijjjjjjjjljjjjjjjjjjjjjjjjjjjjjjjjjjcllcc`abbbabbkbaannkbbbkkkkkkkkkkknknnkbkbkkkbbbbkbbkbnbbbbbbbbbbbbbbbbkkkkkkkbbbbbabbbababbbabbabbbbbbbbabbbbabbbab`lllciibbabbbbijjjjjjjjjjjjjjj",
+"ccciciicciiciii``c`i`cii``iiiii`ikbn`iiii`iiiiiiiciiiiiccakaiccccccccccciccccclccllcllclllcbbbnmmmmmmnnajmmmnnnnnnmmnnnmnmmmmmmmmnnnnmmnnnmnmmmknmmnknmnnknknnmnmnmmmnnnmnknnnnnnkkmmmnnmnmnnnnknkknmmmnmnmkkkaaii``bkkkbaijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjicllccaakbbbann`bnnkbbkkknkkkkbkknnkknkkbbbbkkbbbbbkkbbbkbbbbbbbbabbbbkkbbbkbbbbbabbabbbabbkkbbbbbbabbbaaabbbbbbbbaaalccc`abkbbbabajjjjjjjjjjjjjjj",
+"ciiil`ciciciciiii`iiiii`ii```iiii`ia`i`iic`ci`iiiiiicciiiciccccciccccccccccllcclcccllclclccbbbnnnnnmmnn`lnmnknnnnnnmmnmnnmfmmmmmmknkknnknnmnmmmnmnnmmnnnnnnnmnnnnknnnnmmnnknnnnnnnnmmnnnmnnnnnnknnnknmnnknnnmka`i``abbknaaijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjicjcii`bkbkkknmaankbkbkbbknkkkkbknnnknkbbbbbbbbbkkbkkkbbbkkbbbbbbbbbkkbabbbbbbkbbabbbbbbbbbbbbbbbbabbbabbaabbbbaabbbblli``bkbbbbaaajjjjjjjjjjjjjjj",
+"ccciina`iicicii`iaiiiiiii``i`iiii`i``ii`i`a`iic`iciciiccciicciccccccclcccccccclclclccllclciabkmnnnnmmnm`jnnnnknnkknmmmmknmfmmnmfmnnnnnmnnmmnnmmmmmmmmnknnnnnmmmnnnnnmmmfkknnkknnmmmmnnnnmnmnnnnknkkknnnmnnnnmna````bbknbaaijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjljjcila`i`bkbknnnnaabbkkkbbbbnkkkbbkkkkkkknkbbbkkbbbkbkbnkkkkbbbbbbbbbbkkbbabbkbkkbaabababbbbbbbabbkbbbaaabababbbbbbabbbllababkbbbbbbbjjjjjjjjjjjjjjj",
+"iiccik`iiciacii`ibiiii`iii```i`ii`i`iciiiiiiiciciiiiiiiiiccciccccccccccccclccllcieillclllciabknnnnnnnnnilknnnnnnnnmmnmmnnmmmmmmmnnkknmmmmnnnnnmmnfmmnmmknnnnnmmnnnmmmmmmnnknnknnmnnmnnnnnmmnnknnknknkmmmmnkknkaaa`abakkaab`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjicca`iibbbknnnnb`bkbkbbkkkkkknkkknknnkkkbbbbbkkkbbbbbbkkkkbkkkbbbbbkbbbbkbkkkbkbabbbabbbbkbbbabbbbbbabbaabbabbbbbbaablcabbbkkbbbbbbjjjjjjjjjjjjjjj",
+"ciccccicciibiiiiiaiiiiiiiii`i`i``iii```iiiiiiiiiciiiccciciccccicilclcicccilclclclccclclcll`kknnnnmnnnnn`jnknnnnkmmmmnmmmnmmmmmmmmnnnknnnnnknnnnmnnmnnfmmmmnnmnnnmmnnnmmnnnnnknknnmnmmnnknmnnknknnnmnnmmnnnnkkkabaaabbaaibk`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjliccb`iibbbbknknk`kkkkbknknkbnnkbkkknkkkkkbbbkkkkbkbakkkbbkbbkkkbbbkbbbbbkbbbbbkbbbababbbbbbbkbabbbbaabbabbbbbbbbaaabbcibbabbkbbaabbljjjjjjjjjjjjjj",
+"ciciiciicii`iii`i`ii`iiiii`iii``i``iaaai`iici`ciiicc`iccciiiccclccicccciiaillcclcjlallllll`knnnmnmmnnnn`lnnnnnnnmnnnnmmnnnnnnmnnmfmnmmnnnnknnmmmnnmmmmnmmmnmknkkmmnnnmmmnnkknnnnmmmnmmnknnnknnknnnmmnmmnnnmnnkbbb`abba`abkijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjiicnk`cakbbknknkabkbkbkkkbkbkkkbbbbkbkkkkkkkbkkbbbbkbkkkbbkkkkkkkkbbbabbkkdkkbkkbabbbbbbbbbkbbabbbabbabbbbbbbbbbabbbaiiabbabkbabbbbjjjjjjjjjjjjjjj",
+"icciiciciicccii`iiiiiiiiiii`i````iiii`iikiiiabiiiiccaa`ibicbbicicc`iccc`ibcclclllacjclllll`bkknmmmnnnnnilnnnnknnnnnnnmmknnknnnnnnmnmmmnnnnnmnmnnmmmmnknnnnknnkknmmmmmmmmknknnmmmmnmnmnnnnnnknnknnnnnnmnnnnmnknkaiiiab`abbk`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjji`cnnic`bbkbknkk`bkkbbkkbkkkknkkbkkkkbkbkkkkkkkbbbkbbnbnbbkbbbbbbbbbbbabkkkkkkkbbababbbkbkbbbbbabbabbbabbbbabbbbabbab`ibbabbbbbbbkbljjjjjjjjjjjjjj",
+"cciiciciciiii`iiii`iii`i`i`iiii`````iiiiiiciiiicciii`iccciccccicccilccccc`lclllcclcllcllll`bbkbknmnnnnnicnnnnknmnnnnnnnnnnnnnnnnkmmmmmnnknnmnmnnnmmnknnnnnnmnnknknmmmnmnnnknnnmnnnmnnnnnnmnknmnnnnnknnnkkbnmnmbilcci``abkkijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjic`kb``akmbakkknakkbbbbkbknbbkbbbbbbbkbbbkkkkbbbbkkkkbbbkkbbbabbbbkbbbbbbbkkbkkbabbbbkkbkbkbbbbbbkbabbbaababbbaaabbbb`ibkabbbbkbbabljjjjjjjjjjjjjj",
+"iciciiiiiccci`i`iiiiiiiiii``i``i``iiiiiiiiiiciciiacciilccccciicciccccccclclclcllllllllllcl`abbbknmmnmnnlcnnkknnnnmnknnnnknnnnnnmmmnmmknnnffmmmnnnmnkknnnknnknnnnnkknnnnnkknnnmmnnmmnnnmnnnnmmmnknknnmnnnnkmnnnii`ciccikkbbijjjjjjjljjjjjjjjjjjjjjjjjjjjjjjjjjjic`bb``bkknbbbnnakkbbkkkkkbbbkkbbkbkbbbknkbkkbbbbnkkkbbbkkbabbbbbbbbbbbbababbbbababbbbbbbbbbbkbbakbbbbbbbabkbbbaabbbb``bbkaknbbkkakijjjajjjjjjjjjj",
+"cicciccia``ii``i`i`iiiii`i```i```i`iiiiiciiiiiiic`ciccaiciicciicicccccccclclcllclllllllcjcabbbknnmnmnnnlinnnnknmnnnknnnnnmnmmnmnmmnmnkknknmnmnnmknnnknnnknnnkknknnnknnknnnnmmmmmnmnnnnnmnnmnmnnnnnnmmmnnnnnknk`c`iiciiabbbijjjjjjjjjjjjjjjjcjjjjjjjjjjjjjjjjjjci`bb``bkkkkbbkkakbkbbkkkkbbbkkkbkkkkkkkkkkkkbbbbkkkkkkbbbbbbbabbbbababbbbabbbabbbbkbkkbkbbbabbbbbbbbbbbabbbbbbbabbab``babbbkkbbkkbijjjljjjjjjjjjj",
+"cciciiiciiciii``i`i`i`i`ii`````i`iiiiiii`iicicccciciicb`ciiicicicicccccclcllclllllllllllclakknmnmnnmnmmlinknkknmmnnmnkkmnnnmnmnnmnkmmnnmnmmnmmnmmnnmmkknnnnkknknnnnnnnnknnknnnnnnnnnnknmnmmmnnknknmmnnnnkknkkkiciiclcc`ank`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjic`kb`bbbkkkkbbk`bkbbkkknkkkkkbknbbknkkbkkkkbbbbbkbkkkkkbkbbbbbbbbbbbabbbbbkabbbbbbbbbbkbbbbaabbbkkbbbababbbbbbabaaabaibabbbbkkbbnkajjjjjjjjjjjjjj",
+"ciciciciiciiiiiiii`i`i``a`i```i`iiiiiiiiicic`iiiiccccci`iicccciccicciclccllclllcllcllcll`c`bbbmfmnnmmmnl`nknnkkmnnnmmnnmmnknnnnknnnkkkkknmmmnmnnmmnmnnkknnnnkknknnnnnmnnnmnnnmnnnnnnnknnnnmmnnknknnnnnnkkknknk`iicclcciakkajjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlli`bbbknkkkkkkbbibbkbbbkkkbnkkkkkbbbbbbbkbbbbbbbbkkkkbbbbkbkbbbabkkbbbbbbbbbbbbbbbbbbbbbabbbbbabbkbkbbbabbbbbbabaabakaikaabkbkkbbkkajjjjjjjjjjjjjj",
+"cciciciciiiiiiiiiii````ibaiiiii`iiiiiiiiiciabiiliccciiiiccccccccccciclcllclllcllllllllllcjbnkbbknkmmmnmj`nnnnnknnnnnmmnmnnkknnnnknnkknnnnmmnnnkknnnnnnnnnnnnnknkknnkknnnnmmnmmnmknmnknnnmmnnnnknnnnknnkkknnnmkaiiccici`abbbjjjjjjjjjljjjcajjjjjjjjjjjjjjjjjjjjcciabbknkkkkkkkb`kkkkbbkkbkkkkkkkbbbbbbbbbbbbbbbkkkbbbbbbbkbbbbbbkbbababbbbbabbbkkbbbbbbbbbbbabbbbbbbbaabbbbabaaabbaba`nbabbkkkkbbkkjjjjjnljjjjjjj",
+"iiciciciiciiiii`iiiiiii`a`iiiiiiiiiiiiiib`iciciiiciiiibiccccccccccccclcllllclllllccllllllcbbbkkbkkkmnmnlannmnknnknknnmmnmnkknnnmnknnmmnfmnnnknnnknknnmmnknnnnnknknkkknnnmmmnnnnknnmkknnnmnnnnnnknnkkknkkknknnb`icc`ai`a`aa`jjjjjjjjjljjjjjjjjjjjjjjjjjjjjjjjjjlci`abbknkkkknnk`kkkkkbkbbbbkkkkkkbbbbkkkbbbbkbkkkbbbbbbbbabkkkbbaabbbbabaababbbbkbbkbbabbbbabbbbbbbbbabbbaaaabaabaabbikkbakkbbnkbbbljjjjajjjjjjjj",
+"iiciciiiiiiiiiiiiiiii`iiiii`i`iiiiiiiiii`ccciiciiiiiccalcccccccccclclc`lcllllllllcclllllllbbbnbabbbknmkjannmnnnknnknnmmmmnnnnknmfnmnnnkkmnnnnnnnkkkkknnkknknnnnkknknknknnnmnnnnknnnnknmmmnnnknnnnkkkkkkknnnnnk`cc`ab`a`cii`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlciaabbkknkkknnkakkkkkkbbkbbkkkkkkbbbbkkkkkkkkbbkbbkbbbbbabbbbbbbbbbbbbbababbabbbbbbbbbbbbbabakbkbbbabbbabaaabaabbabbaiakbabbbbbkankijjjjjjjjjjjjj",
+"iiicciciciiiiiiiiii`iii`ii`iii`iiiiiiiiciiiiciiiicciccliccciicclcllclcaclcllclllllclllllllbabbdkdddbnnklannnknnkknknnnnmmnnnkknmmmmnnfnnnknnnnnknnknnnnnkknnnnnkkkknkknnnnnnnnmknnnnmnnnmnnkkknnkkkkkkkknnnknb`c`bkbba`i``ijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjcibbbkkbknknkkn`kkbkkbbbbbkkbkkkbkkbbbknkkbkkbbbbbbbbbbbbbbbbbbbbbkbbbbbbabababbakbbbkabbbbkbbbkkbababbbaabaaaabbkaaa`bnabbkkbabbbkcjjjjjjjjjjjjj",
+"ciiiiciiiiciiiiiiiiii``i`iiiiiii`iiiiiiiciiciiicicccicccililccccclccllllllclllllllllbllllikkabbbbbkbkmblanmnknnknnnkknnnnnnnmmnmmnnnnnnnnnnnknnnnknnnnnnnnnknnnknnnkknnnkkkknnknknmnkknnnnknknnbkkkkkkkknmkkkb`ibknnkbaa``cjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjli`akkbbkbknnnnnibkbbbbkbkbbbkkbkkkkkkknkkbkbbbbbbbbbbbbbbbbbbbbbabbbbbabbbbbbbbbababbbabbbkabbbbababbbaaabbaaaakbbaaa`bnbbbbnkkbbbbljjjjjjjjjjjjj",
+"icciccicicii`c`ii`i``cc`ii`iii`ai`iic`iiciiciiiiccccccccclcccclcllciilclllllllllllllcjcllannkbbbkkbaknajknnkkkkkknnknmnnnnnnknnmnnnnnnnknnkkkkkkkknkknkkkknnnnkkmnnkkkkknkkknnnnnknnnknknkknknnnkkkkkkkknnmnnk`aknknknkb`d`jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjl``aknkbbkknnnkkikkbbbbbbbbkbbbkbbbbbbbkkkbbbbkbbbbbbbbbbbbbabbabbbbbbbabkbbaaaabaaababbbabbaabababbaabbbaaaaababbkbbb`ankabbknkbbkbijjjljjjjjjjjj",
+"iccici`c`ciii`kiiiiiiiai`iiiiii`ii`iiiccicciiicccciccccc`mlclclclccccllcllllclllllllllail`bkkbaknkbabkijnnkknknnkkkkknnmnnkkknnmkkkknnnnnknknnkknnnnnkknknnnknkkmmmnnnnkkkknnnnnkkknknkknkkkknnkknnnnnnnnmmnkbaknnnknfnbbnbjjjjjljjjjlcjjjjjjjjjjjjjjjjjjjjjjjl``bnnknkkbkknkk`kbkbkbbbkbkbbkkkbbbbbbkbbbbbbbbbbbbbabbbbbbbbbbbbbbbbbbbkkbbbbbbbbbbbkbbbbabbaabbbabbbaaabbdbbbbbbbaa`amkbbbknknkbbijjjjjjjjjjjjj",
+"ciiiiia`ci`bna`iii`iibfiii``i`iiii`iiiiiiiciiicccccicccclccl`cilcllllllcclllccllllllll``liabbabkkkkbbbilknkknnknnnkkknnnknnnkknnkkknknknknknknknnnnnnknknnnkknnmmnnkkkkknknknnnmknmnkknnnnnmmmnkkknknkknknnkkbbnnnknmmkdakbjjjjjjjjjjjljjjjjjjjjjjjjjjjjjjjjjjli`bnknnnkkbbkkmabbbkbkbbkbbbbbkkbkbbbbbbbbbbkbbbbbbbbbbbbbbbbbbbbbababbbkbbbabaabababbbbabbabbbbabbbbabbababbbaabaabaaamnabbkkkkkkkijjjjjjjjjjjjj",
+"c`icciiciiciiiii`ii`ian`i```iiiaiciiciibiciiiicccccccccccccinlclclcccccllllclclllljcljlilibbbbbbaabkkb`jbkkknkknknkkknnnkknkkkkknkknnkkkkkknknnknnnnkkknknnkknnmmmnnkkknnnnnnnkknnnmnknnkkknnnkbkknnkkkkkkknnkbkkknmnkbbknkjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjl`i`bknknmkkbbbk`bbbbbbkbbkbbbkbbbbbbbbbbbbbbbbbbbbbabbbbbbbbbababbbabbbkkknbababkkbkbbbbkabbabbbabbbbbbaaabbaaabaababa`nkbabbkkkknbaljjjjjjjjjjjj",
+"ibaiiiiiik`ciai`iiiiii`iii`iiii`iciiiciaiiciiccicccccccccllililcclllcclllllllllllclllllllibkbkndaabnkb`jknnkkkknkknnnnkkknknkkkknnnnnknkknkknnnnkkknknknknnnnnnnknnnnkkknmnnnnnnnnkkknnnnnnknmnmknnnkkkkkkkknnbnnknmnbbnnnncjjjjjjjjjjjjjjjjjjl`jjjjjjjjjjjjjjl``abkkkknmkbbbbibbbbbkbbbkbbkbbbkbbbbbbbbbbbbbbbabbbbbbbbbbbabbbabbbbbbbbbkbbbabbbbbbbabbbabbabbabbabbbbabbbaabbaaabaaikbbbabbkkbbbbjjjjjjjjjjjjj",
+"c`iciiiii`i`iiii`a`ii`iiii`iiiiciiiiicciiiiicccccccccccclicjillccllcllcllllllllljlljllljlanmnnnbabnnnbclknnnnnnnkkknnkkkknknknnnnkknkkknnknnknnnknknnnnnknnnnnnnnnnnnnmmnnmnnnnnnkbkknnknnkkknnnnnnnkkkkkkbkkkbnknnkbbkmmnkjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjl`iakkkmnkknkkbbibkkkkkkbbbbbbbbbbbbkbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbkbbbbbkbbbbbkbkbbbbbaababbbbbaabbbbbbabaaaababaaaikbababbbkkkkbjjjjjjjjji`lj",
+"iiiiiciii`iiiiiiiii`iii``i`ii`i`iiicciiciiicicccccccccicc`ciiilallccllcllllllllllllllllllannmnkbbmkkfkljknnmfnnknkkkkkknkkknnnnnknkkkkkknnkknkknkkkknnnnkknnnmmmnnknkknmmmmmmnnnbknnkkmnnnkknnnnnnkkkkkkkknnkkbnknnbbakmnmbjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjl`iiaknnnnknnmnkcakknkbkbkbbbbbbbbbbbbkbbbbbbbabbbbbbbbbbababbbkbabbbbkkkbbbbbabkkbkbkbbaabaaabbbbbbaabbbbbbbaabaaabbabikbbbbaabbknbkjjjjjjjjjjjjj",
+"iiiiiiiiiiiiiiiii`i````ii```ii`iiicicici`iicccccccccccclcclclcclclclllllcllllbllljcbcljllannnnbaknnmnncjnmnnnkkkkkknnkkknnnnnkkkkkkkknnnnknnknkknknnnkkkknmnnnnnmmnnnnnnnnnkkkkkkkkkkkkknnnkknnnnknnnkkknkknnb`knkkbdbnmnmbjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlii`abbkkknnkkmk`kknkkbbbbbbkbbbbbbbkkbbbbbabbbbbbbbbabbbbbbbbbbbbakkbbbbkkbbbkbkbkbbabaababbaaababbabakbbabbbaabbbababcanbaabbabkknkjjjjjjjjjjjjj",
+"ciciiiiiiiiiii`i`i```i`i`icc``i`iiiiiiiiicciciccccclccccccclcccllllllclllllllijllllijllllaknkkabkkknmnclmnknknkbnknnnnkkkkkknnknkkkknknknnkknkkkkknnkkkkkknnkknfnmnnknnnnnkkkkknkkkkkkkbkknmnnnkkkknkkkkknkkkbabnkkkbknnfnmjijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjlii`akdbbbbkmmk`cabbbbbbbbbkkkbbbbbbbbbbbabbbbbbbbbbbbbabbbbbbbaabbbbabbbkbbbbbbbbbbaaabbbaaaabaaabbbkbbaaaaabbbaadababiabbbabaaabbkbljjjjjjjjjjjj",
+"iiiiiiiiiiiii`i````iiiiiiii`baiiiiiiiicccccccccccccccccclclclcclclllcccllllllllllllljlljlbknkbankabknncckknknnnmnnnnmnkkknknkkkkkkknnnkknkknkkknknnnnnnnkkkkkknmknnnkkknknnnnnnknkkkkkkknkknnnnnnnnnnnknkkkkkkbknkkkknnnmnajjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjiciakbkbkkkbbbaiakbkkkkbkkbkkkbbbbbbbbbbbbbbbbbbbbbbbbbababkbbbbbabbaabkbbbbaaabababbbbababbbabababbbkbbbbbbbbabbabaabc`aaaaaaaabkknijjjjjjjjjjjj",
+"iiiiiiii``i`ii`i``i`i`iii`cciiia`i`i`iiiiiccccccccclccccccclccccclcllilllllllllllllllllllkmkkkknbdabkklcknmmnnnnnkknnnkkkkkknknkkkknknnkkkkkkkkkkknnkknknkkkkkkmkkkkkkknnnnnnkkkknnkknnnnkkkknmnnnkkkbkkknkkbkbnmnnnkknmnnajjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjliiibbbbbbkka`caabkkbkkkkbkbbbkbbbbbbbbbbbbbbbbbbbabababbabbbbbbbbbababbbbaabbabbbbbbkbbaabbabbbbbbbbaabbbbaaaabaababaacc`iaaaa`aabkkijjjjjjjjjjjj",
+"lllllllllllllllllllljlllllllllllllllllljlljlljljlljljljljjljjljljjljjljjljjjljjjljjjljjjjknknmnnbbbbkklcnnnnnnkknkknnnkbkkknkkkknknknkknkkkkkkknnnmnnnmnnnnnknnnkkkkkknnmnnkkkkkkknknkmmnknkknnkkbkkkkkkkkbkkbbnnmmkkkkmmnkjljjjjjjljljjjjjjljljjjjjjjjjjjjjjjli``bbbbbbbaiiiaaakbkbbkbkbbbkbbabbbbbbbbbbbbkbbbbbbbbbbbbbbbbbbkbkbbbbbkbbababbbkbbbaaabbbbabbbbbbbabbbbaaaaaaababaaaaiccii`ii``aaab`jjjjjjjjjjjj",
+"ljljljljljljjljlljljlljljjljjjljjjjjjjljljlljljljjjjljljlljljljjljlllllljllljllljlljljjljbbknmmnkbbbbblinnnnnnnnknkknnnnkkkkknknknkkknkkkkkkknkknknnkknknnmnnnmnkkkkkknnnnkkkkknkkkknnnnknnknnnkkkknnnkkkbkkbbakmmkbbbbknnkjjjlljlljljllljljjljlllllllljlljljll`cibabaaa`cliaba`kkkkkbbkbbbbbkbbbbbbbbbbbbbbbbbbbababbbbbkkbbbbbkkbbbkbbbaababbbkbaabaabaabbbbbbababbkababbbbbbaaaaaaiciiicci```aad`ljllllllljlj",
+"ljlljlljljljljljlllljljljljllljllllhllllljljljjjlllljllllllljljljjljjljljlljjjljllllllljlddknmmnkbkbbbj`mmmnkknnnknkknnnkkkkkkkknkkkkkkkkkknkknknknnnnnnnnnnnnnnknkkbkknnkkknkkkkkbkknnknnkkkknkkknnkkbkkkbkkkaknnbbbbbbknnjljljljllllljllllljlljljljljlllllljl```bbaa`cjlcabbakknkkbkkkbbkbbkkbbbbbbbbbbbbbbbababbbbbbbbbbbbbbbbbkbkbbbbbaaabbabbbbbbaaaaabbbbbbbbaabaababbaaaaaaaab`c``icci`aaaa`iljjjljjljljl",
+"jlljlljlllhllhlhlljhlllljlljlljllhjljhjllhlllllhljljllhjllllhllhlhllhjllljhjlhjlhjjljlljlbkmmmmnmbkbkbj`knknnnnnnnknkknnkkkkkknkkkkkkkkkkkkknnknkkbnnnmnnnknkkkkknnnkknmmkkbkkkbkkkbknnnkkknkbkkkkkkkbkkknkknnbkmnkbbbabbadllllllhlllljhjhjljlljlllllllhjlllllc```bba`clliakkbabbbkbbbkkbkkbbbkbbbbbbbbbbbbbbbbbbbbbbbbbbabbbkkbbbbbbbabbbbbabbbbaaaabababaaabbababaaabaaaaaaaaababbaaiaa``i`a`add`cljhljlljljll",
+"lljhjhlhjllllllllhlljlljhjlljllllllhlllhjllhllljlllljljlljljlllllllllhlllhllljljlllllljljnknmnmmmnkkbal`kkknnnkkkkknkknmkkkkkkkkmnkkkkkkkknmnkknnkkbkkkkkkknknknknnnknnnnkkkkbkkkkkkkbkkkkkkknkbkkkkkknnnmnkknnknmnbbbkbbbbljljljjljljhjljlhlhllhjhlllllljljllli``kkaiclc`bbkkkbbbbkkkkbbbbkbbkkbbbbabbbkbbababbabbkkbabbbaabbabbabbbbbbbbkbabbbbbbaaabaabaaabbbaababaaababaabbbbbbabacbbaaa`i`abb`iljlllljhjljj",
+"llllljljlhllhlllhjllhjhllhlllllljhjljhjlllhjllhlhjhlhlhlhlhlhjhjlljhjljlljlllhlhllhllhllhkknmknmmnkkbbj`nnnnnnnnkkkknnkmnnmnkkkkkkkkkkkkkknnkkkkkkkkkkknkkkkkkkkknmnnnnnkkkkkkkkkkkkbkknkknnnkkknknknnnnknkknmnnnnnbbbbbdbdjlljhlhlhlhlllhlllllljljjhjllllllljhiiiba``ic`bnkbbkbbbkbkkbkbbbkbbbkkkkbbbbbababbbbabbbbbabbbbabbbbbbbbabaabbbkbbbkbbbaabaabaaabaaababbbbbbbabbbbbbbbbababiababba``add`iljhjllljhjhl",
+"llhllhjhjllljhjhjlhjllllllllhjhlhllhlllhjljhljljllljlljljljhlllhlhllhlhlhlhlljllljljlllllkbnmkknmmnkkalakknnkkkknknnkkkkmnnnnnnkkkbkkkknkknnkkkkkkkkkknkkkkkkkkknnmnnnnnkkbkbkbkbkbkkbkkkknnkkkkbkknnkkkknknknbkbkbbbabbbkbhllhllljljljhjjljlljhllhlllhlllhjhlli`i````a`abnnkbb`bkkkbbbbbkbbbbbbkkbbkbbbbabababbbbbkbbbaaabaaaabbaababbbbbkbbkbbaaaaaabaabaaabababbabaaaaabbbbaabaabbbibabnnk`iaaa``llljhjhllllj",
+"lllllhlllhllhlllhlllhlhlhjhjlllljlljlhjlllllllhlhlhlhlhlhlhlllllljlljljljlljlhjhjhjhllllckbbkkbknfmkbalannnnkkbknkkknkkknkbknnnkkkkkkknnnnnnnnkkkknnkkkkkkkkkkkkkknnnnnkbkkkkkkkkkkkkkknkkkkkbbkkkkkbkkbkkknnnbbbbbbabbbbbbllllllhlhlhljhlllllhjljljhjljhlllllhiiciiiaaabbnnmnk`kkkkbbbakbbbkbbbbbbbbkbbbbababbkbbkbbbbbbbbbbbabababbabaabbbbbbbaababaaaaabbababbabaaaaaaaaaaaaaabbbbbiabannnb``addahlllllljljll",
+"jhjhjllhlllhllhlllhllllllllhjhjlllllljhjhjhjhljlllllllhlllllhlhllhlhlhlhlllhljhlllllllllhbbbbbkbknkkb`jamnnnnkkkkkkknnnnnkkkkknkkkkkkkknnnnnnkkkknnnnkkkkkkkkkkkkkkkkkkkkkkkkkkkbkkkknnknnkbkkkkkbkbkkbkbkbnnnkkkkkbbbbkbbdljhjhjljljlllllhlllllhlhllhlhljhlllli`lli`aabbkmmnnmakkkkbbbbbbbbkkkkbbbbbkbbbbbbbbbbbbkbbbkabbkbbbbbababbbaabababaaaababaabaabaabbbbbbaabababaaaababaaabbaibbaknmka`abbbillllllllllj",
+"llljhjhjlllllllllhlllhlhlhllllhlhlhlhllhjllljlllljhjhljljllllllhllllhllllhlllhljlhllllllibdbbbbknkabkajbnnnnnnnkkbkknnnmkkkkkkknkkbkbkknnknmnnnnknnnnkkkkkkkkkkkkkkkkkkbkbkkbkbkbbkkkkknnkbkkkkbkkkkkkkkkkknnkbknkkkkbbbbkdlllllllhlhlhlhlljllllllllljljllllllliilc`abaabbknnnn`kkkkkkkkbabbbkkkbbbbbbbbbbababbbkbbkbkkbbbbbbbabababaabbabaaababaababaaaaaabababbbaaababaabbabaaaaaabb`abknkkka`abbbcljlljljllll",
+"lllhjllllljhjhllljhllllllllhllllllllllllhlhlhlhlhlllljhlhllllljllllljlhjhjllllhlhllhllllibdkbabknnbbkalknnnnmmnnnkkkkknnkbbkknnknkkkkkkkkknnnnnnknnnkkkkkkkkkkkkkkbkkkkkkkkkkkkkbkkbknnknkkkkkkbkkkkkkkbbkbbkkbkkkkkbkbbkkkllhjhllljljljlllhlllhllhlhlhlhlllllhiic`aabbbbbbnmmn`kkbkkkkbbbbbbbbbbbbbbbbbkbbabbbbbbkbbkbbbbkbkbbbbbbaabbabababababaaabababaaabbbbbabaaaaaaaaabaaabaaaab`annnkbka`abbdilllllhllllh",
+"lhlllhlhlhllllhjhlljljllllllllllhjhjhjhllllllllllllhlhllllhllhlhlhlhlhjllhjhlhllllllllll`ddbddaknmkkb`jnmnnknnkkkkkbkknnkknnkknnnkkkkkkknkknkbkknnnnnnnknnnkbkkkkkkkkkkkkkbkbkbkkkkknnnnnnkkbbbkkkkkkkkkkkbkbkbbkkbbbkkbkkbhllllhlllhlhlhllllllljljljlllljhjlll`ciakakbbkbbbknnakkkbkkkbbbkabbbkaabbbbkkbbbbbbbbbbbbbabbbkbbbkbabbbbababbabababbbbababaababbbbbbbbbbaaaababaaaabaaab`aibnmnkbnb`abbb`ljhlllllhll",
+"lllhllllhllhlhlllllhlhlhlhllllllllllllllllhlhllhjlljllllllllhllhlhlhlhhhlhhlhlhhhhhhhhhlodddddddknmkdglknknnnnkkkkkkkkkkkkkkknnmkkkknkkbnkkknkknmnnnnnnknkkkkknbkkkkkknnknkkkkkkkkbnnknnnknnnnkbkbkbbbkbkkkbbbbbbkkbbkkkbkkljhlljlhlllllljhjhlllhlhlhlhllhllhlh`i`ababkbbkmbknmakkkbbkbbbbbbbbbabbbbabbbkbbbbbbabbbbbbbbbbbkbbbbbbbbbaabbababbbbbbbabaabbaabbbabbbabbbbaaaaaaaaabaaaa``annnnkbb`bbad`llllhlljlll",
+"hlhllhlhllhlllhlhllllllllllllllhjhlllhjhlljhjhjhlhlhlhlhlhhhlhhhhhhhhhlhhllhhhhhhhhhhhhhhhhhhhhhghghhhhggghhghhhhhhgg`g`g`o`dddbddbbkkkkkkknnnkmnnmnnnkbnnnkbbbkbkbknkkbnknkkkknnkkkkkknnnnnmnkkkbkbkkkkbkkbkkbbbbkkkknnknklljhjhlljljhjllllljllljlllllhllhllllii`dbbbbbkbnnbkncbbbknkbabbkbbabbbbbbbbbbkbbbbabbbababbbbbbkkbkbbbbbbbabaababbbabababababbababbbbkbbbbbbaaaaaaabaaaabaa``mnmkkbb`bbdddllhllhlhlhl",
+"ljllllllhllhlhllhlhhlhhlhhhhhhhlhlhhhlhhlhhlhhhhhhhhhhhhhhhhgghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhghghhghghhhhhhhhhhhhhhhhhhhhhhhchhhco`oddkknnmnnkknnnkknkkbbkkkkkkbkkkkkkkknmnnnnnnnnnkkbkbkbkbbkkbkkkkbbbkknkbknkkhlllhllhlhllhlhlhlhllhlhlllllllljhjlii`abbbbakbmnkkkibbbbkbbbbbkbbbabbbbbbakbkbbbkbabaabbabbkbbkbbkbbbbbbbbbbbaaaaabaaababaabbaabbbbbbbbbbbbabaaadaaaaaaabaa`knnkbdaadd`ddhlhlhlhlllh",
+"lhlhlhlhlhllhlhlhhlhhlhhhlhhlhhhhhhhhhhhhhhhhhhhhhhhgghhggggogoogggghhhhhhhhggggggghhhhhhhhhhhhhhhhhhlghhhhhhhhhgghghhhhlhhhhhghghhhhhhhhhhhhhhhhhhgho`oknknmnnmnkkkbkkkkkkkkkkkkknnnkknnnnnnnkbkbbbkbkbkkkbkkbbkkknnkkkkkblllhllllhlllhlllllllhllllhlhlhjhlllh`i`abbabbbknnnkn`bbbabbbbknkkkbkkbbbbbbbkbbbkkbdbbbbbbbbbbbbkbbkbbabbbbbbbbbaabaabbaabababbbbbbdabbbbbbddadddddddddddddd`kmkdd`higio`ghhhhhhhhhhh",
+"lhlllhllhlhlhlhhhhhhhhhhhhhhhhhhhghhhhhhhhhhhhhhgggghgggggggggggggghghhhhhhhhhhhhhhhhlljhlhhhhhhhhhhhhhhhhhhgggghhhhghggghghhhhhgghhhhhhhgghhhhghhhlhlhhhhhh`oddnnnnkkkkbkkkkkkkkkbkkknnnnnnnnkbkkkbbkkkbkbkbkbbbbbkkkkbkdblhlllllljhlljhlllllllllllljllllljhlli``aaabbanbnnknncaabbbbbbbbbbabbbbbkkbkbbbbbkkdbbdabbbbabbbbbbbkbabbbbbbbkkbbbbbababbbababaaabdbbkbkkbkdddd`oig`og`ghhhhhhhghhhhghhhhhhhhghhhgghh",
+"hhhhhhhhhhhhhhhhghgggggggggggggggggggghghghggggghghghggggogggggogggggghhhhhhggoggggghhghhghggggghhhhhhhhhghghhhhgggggghghhhhgggggggggggghhhhhgghhhhghhhhllhhhhhglhgiodddnknnnnnkkkkkknnnkknnkkbbbbbkkbbkbkkkkkkbbbbbbbbdbbdlljhjhjhlljhllllllllllllllhlhjlllljli`i`baabbbbnnkkblbkkkbbbbkbbbbbbbbbbkbbbbbbbkbdabbdddabbbbbbbabbbbbbbabbabbbkbabbbbabbbbbbbdddddkddd`oihhlhhhhghgggghhhhhhhhhghhhhhhhghghghghgggg",
+"hhhhhhhhhhhhhhghggggghghgghghghgggggggghgggggggggghhhhhhggggggggggggggggggggghhhghghhhhhhhhhhhhhgggghhhhghgggghghggggggggggggggggggghhhhhhghghhhhhhhgghhhhhhhhhhhhlhlhhhhhh`ddkkddbbkkkkkknkkkbkkkkbkkkbbbkbbkknnnnnkbbbkkkllhlllhllhlllhlhlhlhllhllhlllhlhlhlhiii`abbbbakkbba`ibbbbkbbkbbbababbkbbabbkkbbkbdbdbbabbbbbkkbkbbbkbbbbbbbbbabbkkbbbkbkbbdbbddd``o`ohhhhhhhhhhhhhhhlhhhhghggghhhhgghhhggggggggghgggg",
+"gggggggogggggggggggggggggggggggggggghgggggggggggghghgghhhggggghgggggghhhhhggghhghhhhhhhhhhhhhgggghgggggghhhhhghghhhhghhhghghhhhhhhhhhhhhhhhhhhhghhhhhhhhhhhhhhhlhhghhhhhhhhhhhhhhhcg`bknnnnnnnnnnnknnnbbbbbbabkknnnnbbbkmnklllllllllllhllljllljlllllljhjllljlll`i`abababkaa`ii````aababbkkkkkkknnkbbbbbbbkbbabbnbkmnnmknknkkbkkkbbbbbkkkkbbkkddkkddd`gcglhhhhhhhhhhhhhhhhghghhhghhhgggggghghhhhhghhhgggghhhhhhhh",
+"ggoggogogogoggggoggogoggggggghggggggghhgggggggggggggghghgggggggggggghghhhhhhhghhgghghhhhghgggggggggggghghgggghghhhhhhhhhhhhhhhghghhhhhghhhhhhhhlhhhhhhhhhhhhhhhhlhhhhhhlhhhhhhhlhlhhh`ddknnnknnnkknbnnnkabbbbbknnmnnnnnknnnhlllhjhjhjljlllhlllhllllllllllllhljhi`idkkbbabaiciiiccciabbabbknbbkkkkkbabbbbbbbbaabnnkkkmkknnnnkbbknkbdkkkknkkddo`ooggghhhghhhhhggggghghgghhhhhhhgghgggggggggghgggghggogghggghhhhggg",
+"ggogoggoggggggoggggggggggggghggghgggggggggggggggghhgghgggggggggghhhhhhhhhhhhhhhhhhhlhhhhhhhhhhhhhhhhhhhhhghhghghhhhhhhhghghhhghgggghhhhhhhhhhhhhhhhhhgghhhhhhhhhhhhhhhhhhhhhhhhhhhhlhhhhhgddknnkkknknnkbbkkbbbkmnnnnnnnnnnncjhjlllllhlhlllljllljhjllllllllljllli`ibkkbbba`i`aaiccc`aka``abbkbkkkknnbkbaaabkbabbnnkbkknnnknnnkdddmkddo`gghhhhhhhchghhghhhghggggghgghhhhggghhhhhhhhhhggggghgggogogggghhhhhhhghgggg",
+"hghghghghghhhhhhhghhhggghhghgggggogggggggggogggghghhgghgggggggggggghhhhhhhhhhghhhhhghhhhhhhhhhhhhhhhhhhhhhhhhhhghhhhhghhhhhhhhggghhhhhhhhhhhhhhhhghghhhhhghhhhhhhhhhghghghhhhhhhhhhhhhhlhhhhhgddbkmmmnkakkkbbbkbbbbbbnnmmnnhlllhjhljlljhjhlhlllhllhjhlllllhlhjhi`idbnkkkb```aa`ii``i```i`abbbbknbnkkbaaabbbbbabkmnkbbnnnmnkddo`oghhhhhgghhghhhhgghggghghgggggggggggghghgggghhhhhgogogggggghggggggghgghhghhhhhhhg",
+"hhhghhhhhhhhhhhhhhhhghhghgggggggggggoggogoggggggghgghhgghggggggggghhhhhhhhhhghhghhhhhhhhhhhhhhghhhhghggghhhhhhhhhhgggggghhhhhgghghghhghhhhhhhhhhgghhhghhhhhhhhhhggggggggggghhhhhhhhhlhhhhlhhhhhhhhgdddbbbbbabkkkkbbaabkknmnllhllhllhlhllhllllhllllllllhlhllllhli`iabkknkbaaaa`aa```aa`icl`akkkkkkkkka`abaabbbbbbkndddndkd`oghhhhhhhhhhhhhghghhhghggggggghgggggoggggooggghhgogggghghhhgggggggggghhghghgghgghghggh",
+"ggghghhhhhhhlhhhhgggggghgggghghghggggggoggggggggggghhghhhgggggghhhhhhhhhhghhhhghghhhhhhlllhhhhhhhhhhhhhhhhhhhhhhgghggggggghgggggggggggggggghgggghhhhggghghghhhhhgghghhhhhgghghhhhlhhhhhlhhhhlhhhlhlhhhhi`dkdddbbknkkkkkknnmlllhlllhlllhllhlhllhlhlhlhllllhlhlll````bbbbbabbaaabka`akkbicliannkkkbkkba`abbbdkkkbdkkdo`ghhhhhhhhhggghghhggggghggggghhgghghhggggoggghhhhghhhhhhhghgghhhhggohghhhhhgggogogggggggghgh",
+"hghghghhhhhhhhhhhhgggggggghghghggggghggggggggggggggggggghhhhghghhhhhhhhgghggggggggghhhhhhhhhhhhhhhhhhhhhhhhhhhhhghggggggghghhhghggghghghhhhhhhhhhhhhhhhhhghhhhhhlhhhgggghhhhhhhhhhhhhhhhhhhhhhhlhhlhllhhhhh`dkkdkbbbbbbbkknlhlchlhllhllhlllllhlllllhllhlhlllhlhi`i`bbbbbbbbbabbbbaakkaiiliaknkkbkbbaddbddddddddohhhhhhhhhhhhhhhhggggggggggghhhhhggghghhhhgggoggggggggggghgggggggghghhhhhhhhhghggggggggggggghhhhh",
+"gggggghghhhhhhhhggggggghhhghhhghhhgggggggggggggggogggggghgghgggggggggghhhhhhggggggggghhhhhhhhhhhgggghggghhhhhhhghgggggghhhhhhghghhhhhhhhhhhhhhhghhhghhhhhhhhhhhhhhhlhhhhgghgghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhgdnmnnnkbbbkblllllhlchlchlchlhllhlhchlchllchcllcliiiabakbbkbaaaaabaaakaaicciabknbbkbaddbddo`gggghhhhhhhhggggggghhgggggoggggggggogggggghghhhhghgggghhhhghhhhhggggggggggggggggggggggogoogggggggggggg",
+"ghhhhhhhhhhhhghggggggghhhhhhhhhhgggggggggggggoggggggggghggggghghhhhhhhhhhhggghggghgghghghhhhhhhhhhhhhhhhhhhhhghggggggggghghghhghggghhhhllllhhhhgghgggghgghghhhhhhlhhhhhhhgghhhhhhhhhhhhhhhhhhhhhhhhhlhhhhlhlhhlhh`dknmkkbbdlllhlchllhllchllchlchllclllchlllhchlgciabbkbbbbabbbabbabbaailcc`abkkbd`iiihhhhhhhhgghghghgggggggggghhghggggoggogggggggghhhhghgggggggggggghggggghhgggggghggggghggggogogogggggggggghhhh",
+"hhhhhhggggggghghhhhhhhhhhhhhhhhhhhhhhhhhhggggggohggggggggghhhhhhhhhhhhggggggggghghghghhhhhhhhhhhlhlhlhhhhhhgggggggggghghghhghhhhhhhhhhhlhhhhhhhggghhhhhhhhhhghghhhhhhhgggghhhhhhhhhhhhhhhhhhhhlllhhhhhhhhhhhlhhhllhlgakmkdglhlllllclcclllchllchlchlhchllhcllllccciabbabbbbbbababbaaaiiiiii`ddd`dgghhghhggghhhghhgggggggggggggggggggggogggggghhhhhhgggggggghhhhhhgghgggggggggggoggggghghggggggggggggggggghhghgggg",
+"hhgggggggggghhhhhhhhhhlhhhhhhhhhhlhhhhhhgghghhhhhhhhhgggghghhhhhhhhhhhgggggggghgggggggggggggghhhhhhhhhhhhgggggggggggggggghhhhhhhhhghhhhhhlhhhhhhgghhhhjljllhhgggghghhhhghghgghhhhhhlhhhhhhhhhhhhlhlhhhhhhhhhhhhhhhhhhhhg`gchllhlhlljjjjljjljljllllllllllllhllhllhidbbaabaabbkkbbbbaa````igioihhhhghghhhghhgggggggggghhhhgggggggghhhgghgggggghghhgghhhhggggggogggggggggggghggggggoggggggoggghhhhhhhhhhhhhgggggggg",
+"ggggggogggghghhhhhhhhhhhhhhhhhhhhhhhhggghghhhghhhhhhghghgghghhhhhhhhhgggggggggghgggggggggggghghhhhhhhhhgggggggggggghgggghhhghhhhhghghhhhhhhhhhhhhgghhlhjhjhhhhgghhhhhhhhhhghghghhhhhhhhhhhhhlllhhhhhhhhhhhhhhhhhhhhhhjhlhlhlhlhjjjjjjjjjjjjjjjjjjjjjjjjjjljllllhiiidbababbabbbknnkkdido`hhhhhhhhhhghgghghggghhgghgggggggggoggggoggggogggggoggggghgggggghggggggghgggggghhghggggogogghhggggggggggghhhggggggghggggg",
+"ogogoggggggggggghghggggghhhghggghghghggggghghhhghghghhgggggggggghhhhghgggggggggggggggggggghgggggggghggggggggggggggghghhhhghhhhhhggghhhhhhhhhhhhhhgghhhhhhlhjhhhhhhhhghhhhhhhhghhhhhhhhhhhhhhhhhlhhhhhhhhhhhhlhhhhhhhjhhhlhlhlhllljjjjjjjjjjjjjjjjjjjjjjjjjjjjjjc`iibbbbbaaakbdkkkddighhhhhhhhhghgggggggghgghhhhghgggggggggggggggggogggggoggggggggghggggggggggggggogogghghhgggggggghhhhhhhhgghghhghghghhhgggggogo",
+"ggogogogggggghhhhhhhhhhhhhghgghhghhhghhhgggggghhghgggghggggghhhhhhhghhhhgggggggggggggggghhghgggggghghghhghhhhgggggghghhghhhhhhggghghhhhhhhhhhhhhgghghhljhjhhhhhhhhghghgghhhhhhhghhhhhhhhlhhhhhhhhhhhhhghhhhhhhhhhhhhhhllhhhhlhlllljjjjjjjjjjjjjjjjjjjjjjjjjjjjlli``bababbddddddogggghhhhhghghgghgggggggghggghggggggggggoggoggggggggggggggggghgggggggggggggggggogggggghghghgggggogghhhhhhggggggggggggogogggoggogo",
+"oogogogogogghgghhhhhhhhhhhhhhhhhhhhhhhgggggggggghghhhghghghhhhhhhhghgghghhhghhhhhhhhhhhhhghggggghgghghgghgghghhhgghghhghghhhhhhghhhhhhhhhhhhhhhhghghhhhhlhhhhhhhghhhhghhhhhhhhhhhhhhhhhhlhhlhhhhhhhhgghhhghhhhhhhhhhhhhhlhhhhhhhhlhlljjjjjjjjjjjjjjjjjjjjjjjjjjjiiibabbdbd`oghhhhghhghhohhhgggggghghgggghgggggggggggggogggggggogoggggggggogghhggggogoogggggogggggogggggggggggggggggghhgggggggggggggggggggogoogoo",
+"ggogoggggggggghhhhhhhhhhhhhhhhhhhhgggggghhghhhhhhhhhhhhhhhhhhhhhgghggggggghhghhhhhhghggggggghggghghghghgghhhhhghhhghhghghggggggghhhhhhhhhghgggggghhhhhhhhhhhhhghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhghhhhhghhhlhhhhhlhhhhhlhlhlhhhlhjljjjjjjjjjjjjjjjjjjjjjjjjl```kbbd`ggihhhhgggghhghhghhghhhhggggggghgggggghhghggggggoogggggggggggggggoggggggggghhggogggggoggghhhhhhhgggggghgghghgggggggogogggggggggggggggogg",
+"ggggggogggggghhhhhhhhlllhlhhhhhhgghhhhhhghhhhhhhhhhhhhhhhhhhhhhhhghghghghhhhhhhhhhhhhghggghghghghhhhhhghhhhhhhhhhhhhhhhgghhggghhghghhhhgghgggggggghhhhhhhhhhhghghhhhhhhhhhhhhhhhllhhhhhhhhhhhhhhhhhhhhgghhhhhhhhhhhhhhhlhhhhlhhhhhhhlhlhjjjjjjjjjjjjjjjjjjjjjjlhi``ddihhhhhhhghhhghhhghhghhhhhhggggggggggggghhghgghgggggggogghhhghhgooogggogggggggggggggogoggggggogggggoggghghhhghhggogggghhhhghgggggggggggogggg",
+"gggggggghhhhhhhhhlhhhhhhhhhhhhghghhghghhhghghhhhhhhhhhhhhhhhhhgghgggghghhghhhhhghgggggggghgggggggggggghhhhhhhhhhhhhhhghhhggggggggggghghghghggggghhhhhhlhhhhhhhghhhhhhhhhhhhghghhhhhhhhhhhhghhhhghhhhhhhhhhhhhhhhllhhhhhhhhhhlhhhhhhhlhlhlhjjjjjjjjjjjjjjjjjjhlhcgggghghhhhhgghghgghgghgggggghhhhgggggghggggghhhgghhgggggogoggggghggghhgoogogoogggooogogogoggogogogogoggghhgggghhhhhghhgoghghhghhhhhhhgggoogggggh",
+"ghghhhhhhhhhlhhhhhhhhhhhghhhhghhghghhghghhghggghhhhhhhhhhhhhghhhgghghghggghghghghghhghhghggghghgggggggghhhhhlhlhhhhhhhghhhhghggggggghghghgghgggggghhhhhhhhhghhhhhhhhhghhgghgggghhhhhhhhhghhhhhghhhhhhhhhhhhhhhhhhhllhhhhhhhhhhhhhhhhhhhlhlllljjjjjjjjjjjjljlhllhhghhghghhghgggghgghggggghhhhhhhhhghggggghgggggggghhggggogggogogggggggggggggggoggogggggggggggogoggghggggggghggggogggggggggoggggggoggggggggggggggg",
+"hhhhhhhlhhhhhhhhhhhhhhhhhhghghghghghggggggggggggghhhhhhhhghghggggghghhghhhhhhhhghggghgghghhggggggggggggghhhhhhhhhhhhhhhhghgggghghgghghhghghgghggghhhhhhhhgggghghghghgghghghghhhhhhhhhlhhhhhghhghhhhhhhhhhhhhhlhhhhhhhhhhhhhhhhhlhhhhhlhhhlhhhhjljjjjjjllhhhhhhhhhhhggggogghhghhhggggggggggggghhhhhgghggghgggggggghhhhgggggggogoggggggggggggogogoggggggggggggggggggggggogggggggggogggggggoggggggghggghggggggggggg",
+"hhhhhhhhhhhhhhhhhhhhhhhhhghhggggggggggggggggoggggggghghhghghghgghgghghhhhhhhhhhhghghgggggghghhhghggggghghhhhhhhhhhhhhhghhghhhghghgggghhghghghhhhhhghhhhghghgggggghggghghhhhhhhhhhhhhhhhhhhgggghhhhhhhhllhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhlhhlhlhhhlljjhjhlhlhhhhhhggggggggggggggggggggooggggggggggggggghghggggoggghgghhggggggggogogggooogggggoggogogogoggghghghhggggggggggooghhhhhgogggooggggogggghhhggggggghghghg",
+"hhhhhhhghhhhhhhhhhhhhhhhghggggggggghhhghgggggggggghhghhhgghghghghghghhhhhhhhhgggggggghhghghghgghgggggggggggghhhhhhhhhhhhhhhhhhhggggghhhhhhhhghhhhhhhhhhgghghhhhghgghgghghghghhhhhhlhlhlhhhhhhhghhhhhhhhhhhhhhhhlhhhhhhghghhhhhhhhhhhhhlhhlhlhhlhhlhlhlhhhhhghhggggogggogggggghggggggghhggggggghgggggggggghggogggghghhggogggoggggoogggggggoggggggoggggggggggggggggggggggogggghhhghgggggggogoggggggggggggoggghhhhh",
+"hhhhhhhhhhhhhhhhhhhhhhhggggggggggghghhhghhgggggggggghhghhhhghghggghhhhhhhhhhhghgggggggggghghghgggggogggggghhhghggghgghghhhhhhhhghgghghhhhhhhghghhhhhhghggghghhhhhhghghhghhghhhhhhhhlhjhlhhhhhhghhhhhhhhhhhhhhhhhhhhhhghhghghhhhhhhhhhhhlhlhhhhhhhhhlhhhgghggggggggghggghggghghhggoggghhhggggggggggghhgggghggggggghhhhgggogoggogoggggggggggghghgggggoggggogoogggggogggoggggghggggggoogogggggggghghghggogogogoggog",
+"hhhhhhhhhhhhhggggggggggggggggghghghhhhhhgggggogggghgghhhhhhggggghghhhhhhhhhhghgggggggggghghhghgggogogggghhhhhggghggghghghhhhgggggghhhhhhhhhghggghhhhhhhghgghhhhhhhhhhhhhhhhhghhhhhhhhhhhhhhhhgghhghhhhhhghhhhhhhhhhhhgghhhhghhhlhhhhhhhhhhhhhhhhllhhlhhhhggggggoghghggoggoggggggggggghhgggggghggghghgggggggggggghhhhhgoogoggoggggooggghggggggggghggogoggggggggggggoggggggghghhhhggggggoggghgggggggggooooogogoggg",
+"hghhhhhhhhhhggggggggggghhhhhhhhhhhhhhhhgghgggggggghghhhhhghghghhhhhhhhhhhhhggggggggggghhhhghhggggggggghghghgghhghghgggggghggghghgghhhhhhhhhhgggggghhhhhhhhhhgghghhhhhhhhhhhhhhhhlhhhhhhhhhhhhggghhhhhhhgghghhhhhhghghhhghghhhhhhhhhhhhhhhlhlhlhhhhlhhhhhgggggggggghgggggoggggggggggghhhggghggggggggggggggoogggghhhhgoggggggggggggogghhhggggogghhghggghggghgggggggggogooogghhhghhhhhggggghhgggogogogoogogoogogogg",
+"ghghhhhhgggggggghhhhhhhhhhhhhhhhhhhhhhgghgggghghghghghgggggghhhhhhhhhhhhhhggggggggghghghggggghghgghhhhhhhhhhggggggggggggggghgghggghghhhhhhhgghghhhhghhhhhhhhhhhhhhhghhhhhhhhhhllhlhhhhhhhhhhhhghghhgggghhhhhhhhhhhhghghhghhhghhhhhhhhhhlhhhlhlhhlhhhhhhlghhggoggggggogghggogggggggghhghghggghgghggoggogggggggoogggggggggogoggogogggogghhggogghhhhhggggghhggggoooooooogggoggggghhghhhgghggggggogoghgghgggggoggggg",
+"ghghggggggggggggghghhhhhhhhhlhhhhhhhhhhhgghggghggggggggghghhghghhhhhhhghhggggggggggggggggggggggghhghghhhhhhghgghghggggogggggggggggghhhhhhggggghghhhhghhhhhhhhhhhggghhhhhlhlhlhhlhhhhhhhhhhhhhghghghhhghhgghhhhlhlhhhghghhhghhhhhhhhhhhhhhhhlhhhhhhhlhhhhhlhhhggoggggggooggggoggggggghhhhggggghgggggggggggggogogghgggggghhggggggghhgggggogoggggggggggggggggggggogogoggooggggggggggggggogoggggoggggggggghggggogggg",
+"hgggggghghggghghgghghhhhhhhhhhlhhhhhhhhghghhhghgggggghhhghghghhhhhhghghgghghhgggoogogogggghghhgghgghghghghghgghgggggggggggghggggggggghhggggghghhhhghghggghghhhhhhhghhhhhhlhlhlhhhhhhghhhlhhhhhgghhhhhhgghhhhhhhhhhhhhhhghghhhhhhhhhhhghhhhhhhhhhlhhhhhhhlhhhhhhhgggggghhggooggggggoggggggggghghhgooggggogogggggggggghhhhhhgggoghhhggogooggggggggggggogghhggogogoggoggggogggggggggggogogggooogoggoggggggggoggoggg",
+"ghghghhghhhhhghgggggghhhhhhhlhhhlhhhhhghghghhghggggggghhgggghgggggghhhhhhhhggggggggoggggghghhhhghgggggggggggggggggggggoggghghghgggggggghggggggggghhhhghghgghhhhhhhghhlhhlhhlhlhhhhhghhhlhllhhhhhhhhhhhhhhhhhhhhhhhhhhhgggghhhhhhhhlhhhhhhhlhlhhhlhhhhhhhhlhhhhhhhhggggggogoggggggggggggggghggghgggoogogoggoogogggggghhhhhhgggggggggggogggggggooggogoggghgggoogoogoggogogoggghgggggggggggghggggggggggggggoggogogg",
+"hhhhhhhhhghghggggggghhhhhhhhhhhhhhhhhhgggggggggggggghgggghgggghghghhhhhhhhgggggggoggggghhhhhhhhhghgghghhggggggggggggggggggggggggggghghghgghghgghhhhghghgghhhhhhhhggghhlhlhlhlhlhhhghhhhhlhlhhhhhhhhhhhhhhhhhhhhhhhhhhgggghhhhhhhlhhlhlhhlhhlhhhhhhhllhhhhlhhhhhhhhggggghggghggghgghhgggghhggggghggggoggggoggggggggogggghhhgghggggghgggggghgggggggggggggggooggogggggogogoggggghggggoooogoggggggggggggggggggoggggg",
+"hhhhhhhhghggggggggghghhhhhhhhhhhhhhhhggggggggggggggggggggggghghghhhhhhhggggggggoggggghhhhhhhhhhhhghgghggggggghghggggogggogggggghgghggghghghgggggggghghhhhhhhlllhhhghhhhhlhhlhlhhhhhghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhghhhhhgghhjljhlhhlhlhhlhhhhhhlhhhhlhjhhlhhjhhhhhggghhhoghhgggggghhggggogggghhggggggggoggggggggggggggoggghgggggghhggogggghgggggogggggoggggghghghhhgggggggggggggoggggggggggggogggoggggggogogggg",
+"hhhhggggggggggggggghhhhhhhhhhhhhhhhggggggggggggghhhghghghghgghgghhhghgggghgggggggggghhhhhhhhhhhhghghggghgghhhhhghgggggggggggghggghgghgghhhgghgghghhgghghhhlllhlhhhhhhhhhhhhhhhhhhhgghhhhhhhhhhhhlllhlhhhhhhhhhghhhhhhhhhhhhhhhlhjhlhhlhhhhhhhhhlhlhhhhllhhlhjhllhhlhlhggggogooggggggggogggggoggggggooggogggggggggggggggggggghggggggggogoggggggooogogggggggggghghhhhhhhhhhhhggggggggoggghhhhhggggogggghggggoooogg",
+"gggggghggggggggggghgghhhhhhhhhhghgghghggggggggghggggghghggghggghghggghghhhghgggghghhghhhhhhhhhhghhhghggggggghhghghgggggogoggggghgghghghhghghgghghhhghghhhhlhhlhlhhhhhhhhhhhhhhhhhhhghhhhhhhgghhhhlhjhlhlhhhhhhhhhhhhhhhhhhhhhhhhlljlhhhlhhhhhhhhhhlhjhhhjhlhhhgjhhhhhhhhoggoogggoogghggghgggggggggoggggogoggoogggggghgghggghggggggogogogoooggghggoggggggggghhhhhhhhhhhhhhhhggghgggogoggghhhhhggogoghhhhhhgggggog"
+};
diff --git a/sys/amiga/ifchange b/sys/amiga/ifchange
new file mode 100644
index 0000000..db3f4ea
--- /dev/null
+++ b/sys/amiga/ifchange
@@ -0,0 +1,56 @@
+.KEY oper/a,tmp/a,real/a,f1,f2,f3,f4,f5
+
+. ; miscellaneous script functions for the Amiga
+. ; SCCS Id: @(#)ifchange 3.2 96/02/04
+. ; Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993, 1996.
+. ; NetHack may be freely redistributed. See license for details.
+
+FAILAT 6
+IF EQ "MOVE"
+ IF EXISTS
+ diff >T:mic -c
+ search from T:mic SEARCH "---" QUIET
+ IF WARN
+ echo "MOVE: no change"
+ delete
+ ELSE
+ echo "MOVE: copy"
+ copy clone
+ delete
+ ENDIF
+ ELSE
+ echo "MOVE: copy2"
+ copy clone
+ delete
+ ENDIF
+ QUIT
+ENDIF
+
+IF EQ "TOUCH"
+ IF EXISTS
+ diff >T:mic -c
+ search from T:mic SEARCH "---" QUIET
+ IF NOT WARN
+ echo "TOUCH: touch"
+ IF NOT EQ "@"
+ setdate
+ ENDIF
+ IF NOT EQ "@"
+ setdate
+ ENDIF
+ IF NOT EQ "@"
+ setdate
+ ENDIF
+ IF NOT EQ "@"
+ setdate
+ ENDIF
+ IF NOT EQ "@"
+ setdate
+ ENDIF
+ ENDIF
+ ENDIF
+ QUIT
+ENDIF
+
+echo "ifchange: '' not recognized"
+quit 10
diff --git a/sys/amiga/mkdmake b/sys/amiga/mkdmake
new file mode 100644
index 0000000..2d80c85
--- /dev/null
+++ b/sys/amiga/mkdmake
@@ -0,0 +1,14 @@
+GE/$@/%(left)/
+GE/$%(right)/
+GE/\#/#/
+39(F B/#SFD_INSTEAD / ; E/#SFD_INSTEAD // ; N ; D )
+REWIND
+CG
+9(F P/#SFD_BEGIN/; D ; GE /##// ; F P/#SFD_ELSE/ ; CG ; DF P/#SFD_END/ ; D )
+Q
+
+ SCCS Id: @(#)mkdmake 3.3 96/02/17
+Copyright (c) Andrew Church, Olney, Maryland, 1994,1996.
+NetHack may be freely redistributed. See license for details.
+
+See IV.B.4 of Install.ami for instructions on using this file.
diff --git a/sys/amiga/txt2iff.c b/sys/amiga/txt2iff.c
new file mode 100644
index 0000000..4edbbea
--- /dev/null
+++ b/sys/amiga/txt2iff.c
@@ -0,0 +1,457 @@
+/* SCCS Id: @(#)txt2iff.c 3.2 95/07/28 */
+/* Copyright (c) 1995 by Gregg Wonderly, Naperville, Illinois */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include
+
+#include "config.h"
+#include "tile.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifndef _DCC
+# include
+# include
+# include
+#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<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< 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);
+}
diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c
new file mode 100644
index 0000000..2f214b4
--- /dev/null
+++ b/sys/amiga/winami.c
@@ -0,0 +1,1723 @@
+/* SCCS Id: @(#)winami.c 3.2 2000/01/12 */
+/* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993,1996. */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include "NH:sys/amiga/windefs.h"
+#include "NH:sys/amiga/winext.h"
+#include "NH:sys/amiga/winproto.h"
+#include "dlb.h"
+
+#ifdef AMIGA_INTUITION
+
+static int FDECL( put_ext_cmd, ( char *, int, struct amii_WinDesc *, int ) );
+
+struct amii_DisplayDesc *amiIDisplay; /* the Amiga Intuition descriptor */
+struct Rectangle lastinvent, lastmsg;
+int clipping = 0;
+int clipx=0;
+int clipy=0;
+int clipxmax=0;
+int clipymax=0;
+int scrollmsg = 1;
+int alwaysinvent = 0;
+int amii_numcolors;
+long amii_scrnmode;
+
+/* Interface definition, for use by windows.c and winprocs.h to provide
+ * the intuition interface for the amiga...
+ */
+struct window_procs amii_procs =
+{
+ "amii",
+ WC_COLOR|WC_HILITE_PET|WC_INVERSE,
+ amii_init_nhwindows,
+ amii_player_selection,
+ amii_askname,
+ amii_get_nh_event,
+ amii_exit_nhwindows,
+ amii_suspend_nhwindows,
+ amii_resume_nhwindows,
+ amii_create_nhwindow,
+ amii_clear_nhwindow,
+ amii_display_nhwindow,
+ amii_destroy_nhwindow,
+ amii_curs,
+ amii_putstr,
+ amii_display_file,
+ amii_start_menu,
+ amii_add_menu,
+ amii_end_menu,
+ amii_select_menu,
+ genl_message_menu,
+ amii_update_inventory,
+ amii_mark_synch,
+ amii_wait_synch,
+#ifdef CLIPPING
+ amii_cliparound,
+#endif
+#ifdef POSITIONBAR
+ donull,
+#endif
+ amii_print_glyph,
+ amii_raw_print,
+ amii_raw_print_bold,
+ amii_nhgetch,
+ amii_nh_poskey,
+ amii_bell,
+ amii_doprev_message,
+ amii_yn_function,
+ amii_getlin,
+ amii_get_ext_cmd,
+ amii_number_pad,
+ amii_delay_output,
+#ifdef CHANGE_COLOR /* only a Mac option currently */
+ amii_change_color,
+ amii_get_color_string,
+#endif
+ /* other defs that really should go away (they're tty specific) */
+ amii_delay_output,
+ amii_delay_output,
+ amii_outrip,
+ genl_preference_update
+};
+
+/* 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,
+ amii_init_nhwindows,
+ amii_player_selection,
+ amii_askname,
+ amii_get_nh_event,
+ amii_exit_nhwindows,
+ amii_suspend_nhwindows,
+ amii_resume_nhwindows,
+ amii_create_nhwindow,
+ amii_clear_nhwindow,
+ amii_display_nhwindow,
+ amii_destroy_nhwindow,
+ amii_curs,
+ amii_putstr,
+ amii_display_file,
+ amii_start_menu,
+ amii_add_menu,
+ amii_end_menu,
+ amii_select_menu,
+ genl_message_menu,
+ amii_update_inventory,
+ amii_mark_synch,
+ amii_wait_synch,
+#ifdef CLIPPING
+ amii_cliparound,
+#endif
+#ifdef POSITIONBAR
+ donull,
+#endif
+ amii_print_glyph,
+ amii_raw_print,
+ amii_raw_print_bold,
+ amii_nhgetch,
+ amii_nh_poskey,
+ amii_bell,
+ amii_doprev_message,
+ amii_yn_function,
+ amii_getlin,
+ amii_get_ext_cmd,
+ amii_number_pad,
+ amii_delay_output,
+#ifdef CHANGE_COLOR /* only a Mac option currently */
+ amii_change_color,
+ amii_get_color_string,
+#endif
+ /* other defs that really should go away (they're tty specific) */
+ amii_delay_output,
+ amii_delay_output,
+ amii_outrip,
+ genl_preference_update
+};
+
+unsigned short amii_initmap[ AMII_MAXCOLORS ];
+/* Default pens used unless user overides in nethack.cnf. */
+unsigned short amii_init_map[ AMII_MAXCOLORS ] =
+{
+ 0x0000, /* color #0 C_BLACK */
+ 0x0FFF, /* color #1 C_WHITE */
+ 0x0830, /* color #2 C_BROWN */
+ 0x07ac, /* color #3 C_CYAN */
+ 0x0181, /* color #4 C_GREEN */
+ 0x0C06, /* color #5 C_MAGENTA */
+ 0x023E, /* color #6 C_BLUE */
+ 0x0c00, /* color #7 C_RED */
+};
+
+unsigned short amiv_init_map[ AMII_MAXCOLORS ] =
+{
+ 0x0000, /* color #0 C_BLACK */
+ 0x0fff, /* color #1 C_WHITE */
+ 0x00bf, /* color #2 C_CYAN */
+ 0x0f60, /* color #3 C_ORANGE */
+ 0x000f, /* color #4 C_BLUE */
+ 0x0090, /* color #5 C_GREEN */
+ 0x069b, /* color #6 C_GREY */
+ 0x0f00, /* color #7 C_RED */
+ 0x06f0, /* color #8 C_LTGREEN */
+ 0x0ff0, /* color #9 C_YELLOW */
+ 0x0f0f, /* color #10 C_MAGENTA */
+ 0x0940, /* color #11 C_BROWN */
+ 0x0466, /* color #12 C_GREYBLUE */
+ 0x0c40, /* color #13 C_LTBROWN */
+ 0x0ddb, /* color #14 C_LTGREY */
+ 0x0fb9, /* color #15 C_PEACH */
+
+ /* Pens for dripens etc under AA or better */
+ 0x0222, /* color #16 */
+ 0x0fdc, /* color #17 */
+ 0x0000, /* color #18 */
+ 0x0ccc, /* color #19 */
+ 0x0bbb, /* color #20 */
+ 0x0BA9, /* color #21 */
+ 0x0999, /* color #22 */
+ 0x0987, /* color #23 */
+ 0x0765, /* color #24 */
+ 0x0666, /* color #25 */
+ 0x0555, /* color #26 */
+ 0x0533, /* color #27 */
+ 0x0333, /* color #28 */
+ 0x018f, /* color #29 */
+ 0x0f81, /* color #30 */
+ 0x0fff, /* color #31 */
+};
+
+#if !defined( TTY_GRAPHICS ) || defined( SHAREDLIB ) /* this should be shared better */
+char morc; /* the character typed in response to a --more-- prompt */
+#endif
+char spaces[ 76 ] =
+" ";
+
+winid WIN_BASE = WIN_ERR;
+winid WIN_OVER = WIN_ERR;
+winid amii_rawprwin = WIN_ERR;
+
+/* Changed later during window/screen opens... */
+int txwidth = FONTWIDTH, txheight = FONTHEIGHT, txbaseline = FONTBASELINE;
+
+/* If a 240 or more row screen is in front when we start, this will be
+ * set to 1, and the windows will be given borders to allow them to be
+ * arranged differently. The Message window may eventually get a scroller...
+ */
+int bigscreen = 0;
+
+/* This gadget data is replicated for menu/text windows... */
+struct PropInfo PropScroll = { AUTOKNOB|FREEVERT,
+ 0xffff,0xffff, 0xffff,0xffff, };
+struct Image Image1 = { 0,0, 7,102, 0, NULL, 0x0000,0x0000, NULL };
+struct Gadget MenuScroll = {
+ NULL, -15,10, 15,-19, GRELRIGHT|GRELHEIGHT,
+ RELVERIFY|FOLLOWMOUSE|RIGHTBORDER|GADGIMMEDIATE|RELVERIFY,
+ PROPGADGET, (APTR)&Image1, NULL, NULL, NULL, (APTR)&PropScroll,
+ 1, NULL
+};
+
+/* This gadget is for the message window... */
+struct PropInfo MsgPropScroll = { AUTOKNOB|FREEVERT,
+ 0xffff,0xffff, 0xffff,0xffff, };
+struct Image MsgImage1 = { 0,0, 7,102, 0, NULL, 0x0000,0x0000, NULL };
+struct Gadget MsgScroll = {
+ NULL, -15,10, 14,-19, GRELRIGHT|GRELHEIGHT,
+ RELVERIFY|FOLLOWMOUSE|RIGHTBORDER|GADGIMMEDIATE|RELVERIFY,
+ PROPGADGET, (APTR)&MsgImage1, NULL, NULL, NULL, (APTR)&MsgPropScroll,
+ 1, NULL
+};
+
+int wincnt=0; /* # of nh windows opened */
+
+/* We advertise a public screen to allow some people to do other things
+ * while they are playing... like compiling...
+ */
+
+#ifdef INTUI_NEW_LOOK
+extern struct Hook fillhook;
+struct TagItem tags[] =
+{
+ { WA_BackFill, (ULONG)&fillhook },
+ { WA_PubScreenName, (ULONG)"NetHack" },
+ { TAG_DONE, 0 },
+};
+#endif
+
+/*
+ * The default dimensions and status values for each window type. The
+ * data here is generally changed in create_nhwindow(), so beware that
+ * what you see here may not be exactly what you get.
+ */
+struct win_setup new_wins[] =
+{
+
+ /* First entry not used, types are based at 1 */
+ {{0}},
+
+ /* NHW_MESSAGE */
+ {{0,1,640,11,
+ 0xff,0xff,
+ NEWSIZE|GADGETUP|GADGETDOWN|MOUSEMOVE|MOUSEBUTTONS|RAWKEY,
+ BORDERLESS|ACTIVATE|SMART_REFRESH
+#ifdef INTUI_NEW_LOOK
+ |WFLG_NW_EXTENDED
+#endif
+ ,
+ NULL,NULL,(UBYTE*)"Messages",NULL,NULL,320,40,0xffff,0xffff,
+#ifdef INTUI_NEW_LOOK
+ PUBLICSCREEN,tags
+#else
+ CUSTOMSCREEN
+#endif
+ },
+ 0,0,1,1,80,80},
+
+ /* NHW_STATUS */
+ {{0,181,640,24,
+ 0xff,0xff,
+ RAWKEY|MENUPICK|DISKINSERTED,
+ BORDERLESS|ACTIVATE|SMART_REFRESH|BACKDROP
+#ifdef INTUI_NEW_LOOK
+ |WFLG_NW_EXTENDED
+#endif
+ ,
+ NULL,NULL,(UBYTE*)"Game Status",NULL,NULL,0,0,0xffff,0xffff,
+#ifdef INTUI_NEW_LOOK
+ PUBLICSCREEN,tags
+#else
+ CUSTOMSCREEN
+#endif
+ },
+ 0,0,2,2,78,78},
+
+ /* NHW_MAP */
+ {{0,0,WIDTH,WINDOWHEIGHT,
+ 0xff,0xff,
+ RAWKEY|MENUPICK|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE,
+ BORDERLESS|ACTIVATE|SMART_REFRESH|BACKDROP
+#ifdef INTUI_NEW_LOOK
+ |WFLG_NW_EXTENDED
+#endif
+ ,
+ NULL,NULL,(UBYTE*)"Dungeon Map",NULL,NULL,64,64,0xffff,0xffff,
+#ifdef INTUI_NEW_LOOK
+ PUBLICSCREEN,tags
+#else
+ CUSTOMSCREEN
+#endif
+ },
+ 0,0,22,22,80,80},
+
+ /* NHW_MENU */
+ {{400,10,10,10,
+ 0xff,0xff,
+ RAWKEY|MENUPICK|DISKINSERTED|MOUSEMOVE|MOUSEBUTTONS|
+ GADGETUP|GADGETDOWN|CLOSEWINDOW|VANILLAKEY|NEWSIZE|INACTIVEWINDOW,
+ WINDOWSIZING|WINDOWCLOSE|WINDOWDRAG|ACTIVATE|SMART_REFRESH
+#ifdef INTUI_NEW_LOOK
+ |WFLG_NW_EXTENDED
+#endif
+ ,
+ &MenuScroll,NULL,NULL,NULL,NULL,64,32,0xffff,0xffff,
+#ifdef INTUI_NEW_LOOK
+ PUBLICSCREEN,tags
+#else
+ CUSTOMSCREEN
+#endif
+ },
+ 0,0,1,1,22,78},
+
+ /* NHW_TEXT */
+ {{0,0,640,200,
+ 0xff,0xff,
+ RAWKEY|MENUPICK|DISKINSERTED|MOUSEMOVE|
+ GADGETUP|CLOSEWINDOW|VANILLAKEY|NEWSIZE,
+ WINDOWSIZING|WINDOWCLOSE|WINDOWDRAG|ACTIVATE|SMART_REFRESH
+#ifdef INTUI_NEW_LOOK
+ |WFLG_NW_EXTENDED
+#endif
+ ,
+ &MenuScroll,NULL,(UBYTE*)NULL,NULL,NULL,100,32,0xffff,0xffff,
+#ifdef INTUI_NEW_LOOK
+ PUBLICSCREEN,tags
+#else
+ CUSTOMSCREEN
+#endif
+ },
+ 0,0,1,1,22,78},
+
+ /* NHW_BASE */
+ {{0,0,WIDTH,WINDOWHEIGHT,
+ 0xff,0xff,
+ RAWKEY|MENUPICK|MOUSEBUTTONS,
+ BORDERLESS|ACTIVATE|SMART_REFRESH|BACKDROP
+#ifdef INTUI_NEW_LOOK
+ |WFLG_NW_EXTENDED
+#endif
+ ,
+ NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,
+#ifdef INTUI_NEW_LOOK
+ PUBLICSCREEN,tags
+#else
+ CUSTOMSCREEN
+#endif
+ },
+ 0,0,22,22,80,80},
+
+ /* NHW_OVER */
+ {{320,20,319,179,
+ 0xff,0xff,
+ RAWKEY|MENUPICK|MOUSEBUTTONS,
+ BORDERLESS|ACTIVATE|SMART_REFRESH|BACKDROP
+#ifdef INTUI_NEW_LOOK
+ |WFLG_NW_EXTENDED
+#endif
+ ,
+ NULL,NULL,(UBYTE*)NULL,NULL,NULL,64,32,0xffff,0xffff,
+#ifdef INTUI_NEW_LOOK
+ PUBLICSCREEN,tags
+#else
+ CUSTOMSCREEN
+#endif
+ },
+ 0,0,22,22,80,80},
+};
+
+const char winpanicstr[] = "Bad winid %d in %s()";
+
+/* The opened windows information */
+struct amii_WinDesc *amii_wins[ MAXWIN + 1 ];
+
+#ifdef INTUI_NEW_LOOK
+/*
+ * NUMDRIPENS varies based on headers, so don't use it
+ * here, its value is used elsewhere.
+ */
+UWORD amii_defpens[ 20 ];
+
+struct TagItem scrntags[] =
+{
+ { SA_PubName, (ULONG)"NetHack" },
+ { SA_Overscan, OSCAN_TEXT },
+ { SA_AutoScroll, TRUE },
+#if LIBRARY_VERSION >= 39
+ { SA_Interleaved, TRUE },
+#endif
+ { SA_Pens, (ULONG)0 },
+ { SA_DisplayID, 0 },
+ { TAG_DONE, 0 },
+};
+
+#endif
+
+struct NewScreen NewHackScreen =
+{
+ 0, 0, WIDTH, SCREENHEIGHT, 3,
+ 0, 1, /* DetailPen, BlockPen */
+ HIRES,
+ CUSTOMSCREEN
+#ifdef INTUI_NEW_LOOK
+ |NS_EXTENDED
+#endif
+ ,
+ &Hack80, /* Font */
+ NULL, /*(UBYTE *)" NetHack X.Y.Z" */
+ NULL, /* Gadgets */
+ NULL, /* CustomBitmap */
+#ifdef INTUI_NEW_LOOK
+ scrntags
+#endif
+};
+
+/*
+ * plname is filled either by an option (-u Player or -uPlayer) or
+ * explicitly (by being the wizard) or by askname.
+ * It may still contain a suffix denoting pl_character.
+ * Always called after init_nhwindows() and before display_gamewindows().
+ */
+void
+amii_askname()
+{
+ char plnametmp[300]; /* From winreq.c: sizeof(StrStringSIBuff) */
+ *plnametmp = 0;
+ do {
+ amii_getlin( "Who are you?", plnametmp );
+ } while( strlen( plnametmp ) == 0 );
+
+ strncpy(plname, plnametmp, PL_NSIZ-1); /* Avoid overflowing plname[] */
+ plname[PL_NSIZ-1] = 0;
+
+ if( *plname == '\33' )
+ {
+ clearlocks();
+ exit_nhwindows(NULL);
+ terminate(0);
+ }
+}
+
+/* Discarded ... -jhsa
+#include "NH:sys/amiga/char.c"
+*/
+
+/* Get the player selection character */
+
+#if 0 /* New function at the bottom */
+void
+amii_player_selection()
+{
+ register struct Window *cwin;
+ register struct IntuiMessage *imsg;
+ register int aredone = 0;
+ register struct Gadget *gd;
+ static int once = 0;
+ long class, code;
+
+ amii_clear_nhwindow( WIN_BASE );
+ if (validrole(flags.initrole))
+ return;
+ else {
+ flags.initrole=randrole();
+ return;
+ }
+#if 0 /* Don't query the user ... instead give random character -jhsa */
+
+#if 0 /* OBSOLETE */
+ if( *pl_character ){
+ pl_character[ 0 ] = toupper( pl_character[ 0 ] );
+ if( index( pl_classes, pl_character[ 0 ] ) )
+ return;
+ }
+#endif
+
+ if( !once ){
+ if( bigscreen ){
+ Type_NewWindowStructure1.TopEdge =
+ (HackScreen->Height/2) - (Type_NewWindowStructure1.Height/2);
+ }
+ for( gd = Type_NewWindowStructure1.FirstGadget; gd;
+ gd = gd->NextGadget )
+ {
+ if( gd->GadgetID != 0 )
+ SetBorder( gd );
+ }
+ once = 1;
+ }
+
+ if( WINVERS_AMIV )
+ {
+# ifdef INTUI_NEW_LOOK
+ Type_NewWindowStructure1.Extension = wintags;
+ Type_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
+ fillhook.h_Entry = (ULONG(*)())LayerFillHook;
+ fillhook.h_Data = (void *)-2;
+ fillhook.h_SubEntry = 0;
+#endif
+ }
+
+ Type_NewWindowStructure1.Screen = HackScreen;
+ if( ( cwin = OpenShWindow( (void *)&Type_NewWindowStructure1 ) ) == NULL )
+ {
+ return;
+ }
+#if 0
+ WindowToFront( cwin );
+#endif
+
+ while( !aredone )
+ {
+ WaitPort( cwin->UserPort );
+ while( ( imsg = (void *) GetMsg( cwin->UserPort ) ) != NULL )
+ {
+ class = imsg->Class;
+ code = imsg->Code;
+ gd = (struct Gadget *)imsg->IAddress;
+ ReplyMsg( (struct Message *)imsg );
+
+ switch( class )
+ {
+ case VANILLAKEY:
+ if( index( pl_classes, toupper( code ) ) )
+ {
+ pl_character[0] = toupper( code );
+ aredone = 1;
+ }
+ else if( code == ' ' || code == '\n' || code == '\r' )
+ {
+ flags.initrole = randrole();
+#if 0 /* OBSOLETE */
+#ifdef TOURIST
+ strcpy( pl_character, roles[ rnd( 11 ) ] );
+#else
+ strcpy( pl_character, roles[ rnd( 10 ) ] );
+#endif
+#endif
+ aredone = 1;
+ amii_clear_nhwindow( WIN_BASE );
+ CloseShWindow( cwin );
+ RandomWindow( pl_character );
+ return;
+ }
+ else if( code == 'q' || code == 'Q' )
+ {
+ CloseShWindow( cwin );
+ clearlocks();
+ exit_nhwindows(NULL);
+ terminate(0);
+ }
+ else
+ DisplayBeep( NULL );
+ break;
+
+ case GADGETUP:
+ switch( gd->GadgetID )
+ {
+ case 1: /* Random Character */
+ flags.initrole = randrole();
+#if 0 /* OBSOLETE */
+#ifdef TOURIST
+ strcpy( pl_character, roles[ rnd( 11 ) ] );
+#else
+ strcpy( pl_character, roles[ rnd( 10 ) ] );
+#endif
+#endif
+ amii_clear_nhwindow( WIN_BASE );
+ CloseShWindow( cwin );
+ RandomWindow( pl_character );
+ return;
+
+ default:
+ pl_character[0] = gd->GadgetID;
+ break;
+ }
+ aredone = 1;
+ break;
+
+ case CLOSEWINDOW:
+ CloseShWindow( cwin );
+ clearlocks();
+ exit_nhwindows(NULL);
+ terminate(0);
+ break;
+ }
+ }
+ }
+ amii_clear_nhwindow( WIN_BASE );
+ CloseShWindow( cwin );
+#endif /* Do not query user ... -jhsa */
+}
+#endif /* Function elsewhere */
+
+#if 0 /* Unused ... -jhsa */
+
+#include "NH:sys/amiga/randwin.c"
+
+void
+RandomWindow( name )
+ char *name;
+{
+ struct MsgPort *tport;
+ struct timerequest *trq;
+ static int once = 0;
+ struct Gadget *gd;
+ struct Window *w;
+ struct IntuiMessage *imsg;
+ int ticks = 0, aredone = 0, timerdone = 0;
+ long mask, got;
+
+ tport = CreateMsgPort();
+ trq = (struct timerequest *)CreateIORequest( tport, sizeof( *trq ) );
+ if( tport == NULL || trq == NULL )
+ {
+allocerr:
+ if( tport ) DeleteMsgPort( tport );
+ if( trq ) DeleteIORequest( (struct IORequest *)trq );
+ Delay( 8 * 50 );
+ return;
+ }
+
+ if( OpenDevice( TIMERNAME, UNIT_VBLANK, (struct IORequest *)trq, 0L ) != 0 )
+ goto allocerr;
+
+ trq->tr_node.io_Command = TR_ADDREQUEST;
+ trq->tr_time.tv_secs = 8;
+ trq->tr_time.tv_micro = 0;
+
+ SendIO( (struct IORequest *)trq );
+
+ /* Place the name in the center of the screen */
+ Rnd_IText5.IText = name;
+ Rnd_IText6.LeftEdge = Rnd_IText4.LeftEdge +
+ (strlen(Rnd_IText4.IText)+1)*8;
+ Rnd_NewWindowStructure1.Width = (
+ (strlen( Rnd_IText2.IText )+1) * 8 ) +
+ HackScreen->WBorLeft + HackScreen->WBorRight;
+ Rnd_IText5.LeftEdge = (Rnd_NewWindowStructure1.Width -
+ (strlen(name)*8))/2;
+
+ gd = Rnd_NewWindowStructure1.FirstGadget;
+ gd->LeftEdge = (Rnd_NewWindowStructure1.Width - gd->Width)/2;
+ /* Chose correct modifier */
+ Rnd_IText6.IText = "a";
+ switch( *name )
+ {
+ case 'a': case 'e': case 'i': case 'o':
+ case 'u': case 'A': case 'E': case 'I':
+ case 'O': case 'U':
+ Rnd_IText6.IText = "an";
+ break;
+ }
+
+ if( !once )
+ {
+ if( bigscreen )
+ {
+ Rnd_NewWindowStructure1.TopEdge =
+ (HackScreen->Height/2) - (Rnd_NewWindowStructure1.Height/2);
+ }
+ for( gd = Rnd_NewWindowStructure1.FirstGadget; gd; gd = gd->NextGadget )
+ {
+ if( gd->GadgetID != 0 )
+ SetBorder( gd );
+ }
+ Rnd_NewWindowStructure1.IDCMPFlags |= VANILLAKEY;
+
+ once = 1;
+ }
+
+ if( WINVERS_AMIV )
+ {
+#ifdef INTUI_NEW_LOOK
+ Rnd_NewWindowStructure1.Extension = wintags;
+ Rnd_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
+ fillhook.h_Entry = (ULONG(*)())LayerFillHook;
+ fillhook.h_Data = (void *)-2;
+ fillhook.h_SubEntry = 0;
+#endif
+ }
+
+ Rnd_NewWindowStructure1.Screen = HackScreen;
+ if( ( w = OpenShWindow( (void *)&Rnd_NewWindowStructure1 ) ) == NULL )
+ {
+ AbortIO( (struct IORequest *)trq );
+ WaitIO( (struct IORequest *)trq );
+ CloseDevice( (struct IORequest *)trq );
+ DeleteIORequest( (struct IORequest *) trq );
+ DeleteMsgPort( tport );
+ Delay( 50 * 8 );
+ return;
+ }
+
+ PrintIText( w->RPort, &Rnd_IntuiTextList1, 0, 0 );
+
+ mask = (1L << tport->mp_SigBit)|(1L << w->UserPort->mp_SigBit);
+ while( !aredone )
+ {
+ got = Wait( mask );
+ if( got & (1L << tport->mp_SigBit ) )
+ {
+ aredone = 1;
+ timerdone = 1;
+ GetMsg( tport );
+ }
+ while( w && ( imsg = (struct IntuiMessage *) GetMsg( w->UserPort ) ) )
+ {
+ switch( (long)imsg->Class )
+ {
+ /* Must be up for a little while... */
+ case INACTIVEWINDOW:
+ if( ticks >= 40 )
+ aredone = 1;
+ break;
+
+ case INTUITICKS:
+ ++ticks;
+ break;
+
+ case GADGETUP:
+ aredone = 1;
+ break;
+
+ case VANILLAKEY:
+ if(imsg->Code=='\n' || imsg->Code==' ' || imsg->Code=='\r')
+ aredone = 1;
+ break;
+ }
+ ReplyMsg( (struct Message *)imsg );
+ }
+ }
+
+ if( !timerdone )
+ {
+ AbortIO( (struct IORequest *)trq );
+ WaitIO( (struct IORequest *)trq );
+ }
+
+ CloseDevice( (struct IORequest *)trq );
+ DeleteIORequest( (struct IORequest *) trq );
+ DeleteMsgPort( tport );
+ if(w) CloseShWindow( w );
+}
+#endif /* Discarded randwin ... -jhsa */
+
+/* this should probably not be needed (or be renamed)
+void
+flush_output(){} */
+
+/* Read in an extended command - doing command line completion for
+ * when enough characters have been entered to make a unique command.
+ */
+int
+amii_get_ext_cmd( void )
+{
+ menu_item *mip;
+ anything id;
+ struct amii_WinDesc *cw;
+#ifdef EXTMENU
+ winid win;
+ int i;
+ char buf[256];
+#endif
+ int colx;
+ int bottom = 0;
+ struct Window *w;
+ char obufp[ 100 ];
+ register char *bufp = obufp;
+ register int c;
+ int com_index, oindex;
+ int did_comp=0; /* did successful completion? */
+ int sel = -1;
+
+ if( WIN_MESSAGE == WIN_ERR || ( cw = amii_wins[ WIN_MESSAGE ] ) == NULL )
+ panic(winpanicstr, WIN_MESSAGE, "get_ext_cmd");
+ w = cw->win;
+ bottom = amii_msgborder( w );
+ colx = 3;
+
+#ifdef EXTMENU
+ if (iflags.extmenu) {
+ win = amii_create_nhwindow( NHW_MENU );
+ amii_start_menu( win );
+ pline("#");
+ amii_putstr( WIN_MESSAGE, -1, " " );
+
+ for( i = 0; extcmdlist[ i ].ef_txt != NULL; ++i )
+ {
+ 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, buf, MENU_UNSELECTED);
+ }
+
+ amii_end_menu( win, (char*)0 );
+ sel = amii_select_menu( win, PICK_ONE, &mip );
+ amii_destroy_nhwindow( win );
+
+ if( sel == 1 )
+ {
+ sel = mip->item.a_char;
+ for( i = 0; extcmdlist[ i ].ef_txt != NULL; ++i )
+ {
+ if( sel == extcmdlist[i].ef_txt[0] )
+ break;
+ }
+
+ /* copy in the text */
+ if( extcmdlist[ i ].ef_txt != NULL )
+ {
+ amii_clear_nhwindow( WIN_MESSAGE );
+ (void) put_ext_cmd( (char *)extcmdlist[i].ef_txt, 0, cw, bottom );
+ return( i );
+ }
+ else
+ DisplayBeep( NULL );
+ }
+
+ return( -1 );
+ } else {
+#else
+
+ amii_clear_nhwindow( WIN_MESSAGE ); /* Was NHW_MESSAGE */
+ if( scrollmsg )
+ {
+ pline("#");
+ amii_addtopl(" ");
+ }
+ else
+ {
+ pline("# ");
+ }
+
+ sel = -1;
+ while((c = WindowGetchar()) != EOF)
+ {
+ amii_curs( WIN_MESSAGE, colx, bottom );
+ if(c == '?' )
+ {
+ int win, i;
+ char buf[ 100 ];
+
+ if(did_comp){
+ while(bufp!=obufp)
+ {
+ bufp--;
+ amii_curs(WIN_MESSAGE, --colx, bottom);
+ Text(w->RPort,spaces,1);
+ amii_curs(WIN_MESSAGE,colx,bottom);
+ did_comp=0;
+ }
+ }
+
+ win = amii_create_nhwindow( NHW_MENU );
+ amii_start_menu( win );
+
+ for( i = 0; extcmdlist[ i ].ef_txt != NULL; ++i )
+ {
+ 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_UNSELECTED);
+ }
+
+ amii_end_menu( win, (char*)0 );
+ sel = amii_select_menu( win, PICK_ONE, &mip );
+ amii_destroy_nhwindow( win );
+
+ if( sel == 0 )
+ {
+ return( -1 );
+ }
+ else
+ {
+ sel = mip->item.a_char;
+ for( i = 0; extcmdlist[ i ].ef_txt != NULL; ++i )
+ {
+ if( sel == extcmdlist[i].ef_txt[0] )
+ break;
+ }
+
+ /* copy in the text */
+ if( extcmdlist[ i ].ef_txt != NULL )
+ {
+ amii_clear_nhwindow( WIN_MESSAGE );
+ strcpy( bufp = obufp, extcmdlist[ i ].ef_txt );
+ (void) put_ext_cmd( obufp, colx, cw, bottom );
+ return( i );
+ }
+ else
+ DisplayBeep( NULL );
+ }
+ }
+ else if(c == '\033')
+ {
+ return( -1 );
+ }
+ else if(c == '\b')
+ {
+ if(did_comp){
+ while(bufp!=obufp){
+ bufp--;
+ amii_curs(WIN_MESSAGE, --colx, bottom);
+ Text(w->RPort,spaces,1);
+ amii_curs(WIN_MESSAGE,colx,bottom);
+ did_comp=0;
+ sel = -1;
+ }
+ }
+ else if(bufp != obufp)
+ {
+ sel = -1;
+ bufp--;
+ amii_curs( WIN_MESSAGE, --colx, bottom);
+ Text( w->RPort, spaces, 1 );
+ amii_curs( WIN_MESSAGE, colx, bottom);
+ }
+ else
+ DisplayBeep( NULL );
+ }
+ else if( c == '\n' || c == '\r' )
+ {
+ return(sel);
+ }
+ else if( c >= ' ' && c < '\177')
+ {
+ /* avoid isprint() - some people don't have it
+ ' ' is not always a printing char */
+ *bufp = c;
+ bufp[1] = 0;
+ oindex = 0;
+ com_index = -1;
+
+ while(extcmdlist[oindex].ef_txt != NULL)
+ {
+ if(!strnicmp(obufp, (char *)extcmdlist[oindex].ef_txt, strlen(obufp)))
+ {
+ if(com_index == -1) /* No matches yet*/
+ com_index = oindex;
+ else /* More than 1 match */
+ com_index = -2;
+ }
+ oindex++;
+ }
+
+ if(com_index >= 0 && *obufp )
+ {
+ Strcpy(obufp, extcmdlist[com_index].ef_txt);
+ /* finish printing our string */
+ colx = put_ext_cmd( obufp, colx, cw, bottom );
+ bufp = obufp; /* reset it */
+ if(strlen(obufp) < BUFSZ-1 && strlen(obufp) < COLNO)
+ bufp += strlen(obufp);
+ did_comp=1;
+ sel = com_index;
+ }
+ else
+ {
+ colx = put_ext_cmd( obufp, colx, cw, bottom );
+ if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
+ bufp++;
+ }
+ }
+ else if(c == ('X'-64) || c == '\177')
+ {
+ colx = 0;
+ amii_clear_nhwindow( WIN_MESSAGE );
+ pline( "# " );
+ bufp = obufp;
+ } else
+ DisplayBeep( NULL );
+ }
+ return(-1);
+#endif
+}
+
+static int
+put_ext_cmd( obufp, colx, cw, bottom )
+ char *obufp;
+ int colx, bottom;
+ struct amii_WinDesc *cw;
+{
+ struct Window *w = cw->win;
+ char *t;
+
+ t = (char *)alloc( strlen( obufp ) + 7 );
+ if( t != NULL )
+ {
+ if( scrollmsg )
+ {
+ sprintf( t, "xxx%s", obufp );
+ t[0] = 1;
+ t[1] = 1;
+ t[2] = '#';
+ amii_curs( WIN_MESSAGE, 0, bottom);
+ SetAPen( w->RPort, C_WHITE );
+ Text(w->RPort, "># ", 3 );
+ /* SetAPen( w->RPort, C_BLACK ); */ /* Black text on black screen doesn't look too well ... -jhsa */
+ Text(w->RPort, t+3, strlen( t ) - 3 );
+ }
+ else
+ {
+ sprintf( t, "# %s", obufp );
+ amii_curs( WIN_MESSAGE, 0, bottom);
+ SetAPen( w->RPort, C_WHITE );
+ Text(w->RPort, t, strlen( t ) );
+ }
+ if( scrollmsg )
+ SetAPen( w->RPort, C_WHITE );
+ if( cw->data[ cw->maxrow - 1 ] )
+ free( cw->data[ cw->maxrow - 1 ] );
+ cw->data[ cw->maxrow - 1 ] = t;
+ }
+ else
+ {
+ amii_curs( WIN_MESSAGE, 0, bottom);
+ SetAPen( w->RPort, C_WHITE );
+ Text(w->RPort, "# ", 2 );
+ /* SetAPen( w->RPort, C_BLACK ); */ /* Black on black ... -jhsa */
+ Text(w->RPort, obufp, strlen( obufp ) );
+ SetAPen( w->RPort, C_WHITE );
+ }
+ amii_curs( WIN_MESSAGE, colx = strlen( obufp ) + 3 + ( scrollmsg != 0 ), bottom);
+ return( colx );
+}
+
+/* Ask a question and get a response */
+
+char amii_yn_function(query, resp, def)
+const char *query,*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
+ * what's in the string. The 'query' string is printed before the user
+ * is asked about the string.
+ * If resp is NULL, any single character is accepted and returned.
+ * If not-NULL, only characters in it are allowed (exceptions: the
+ * quitchars are always allowed, and if it contains '#' then digits
+ * are allowed); if it includes an , anything beyond that won't
+ * be shown in the prompt to the user but will be acceptable as input.
+ */
+{
+ register char q;
+ char rtmp[40];
+ boolean digit_ok, allow_num;
+ char prompt[QBUFSZ];
+ register struct amii_WinDesc *cw;
+
+ if( cw = amii_wins[ WIN_MESSAGE ] )
+ cw->disprows = 0;
+ if (resp) {
+ char *rb, respbuf[QBUFSZ];
+
+ allow_num = (index(resp, '#') != 0);
+ Strcpy(respbuf, resp);
+ /* any acceptable responses that follow aren't displayed */
+ if ((rb = index(respbuf, '\033')) != 0) *rb = '\0';
+ Sprintf(prompt, "%s [%s] ", query, respbuf);
+ if (def) Sprintf(eos(prompt), "(%c) ", def);
+ pline("%s", prompt);
+ } else {
+ amii_putstr(WIN_MESSAGE, 0, query);
+ cursor_on(WIN_MESSAGE);
+ q = WindowGetchar();
+ cursor_off(WIN_MESSAGE);
+ *rtmp = q;
+ rtmp[ 1 ] = 0;
+ amii_addtopl(rtmp);
+ goto clean_up;
+ }
+
+ do { /* loop until we get valid input */
+ cursor_on(WIN_MESSAGE);
+ q = lowc(WindowGetchar());
+ cursor_off(WIN_MESSAGE);
+#if 0
+/* fix for PL2 */
+ if (q == '\020') { /* ctrl-P */
+ if(!doprev) (void) tty_doprev_message(); /* need two initially */
+ (void) tty_doprev_message();
+ q = (char)0;
+ doprev = 1;
+ continue;
+ } else if(doprev) {
+ tty_clear_nhwindow(WIN_MESSAGE);
+ cw->maxcol = cw->maxrow;
+ doprev = 0;
+ amii_addtopl(prompt);
+ continue;
+ }
+#endif
+ digit_ok = allow_num && isdigit(q);
+ if (q == '\033') {
+ if (index(resp, 'q'))
+ q = 'q';
+ else if (index(resp, 'n'))
+ q = 'n';
+ else
+ q = def;
+ break;
+ } else if (index(quitchars, q)) {
+ q = def;
+ break;
+ }
+ if (!index(resp, q) && !digit_ok) {
+ amii_bell();
+ q = (char)0;
+ } else if (q == '#' || digit_ok) {
+ char z, digit_string[2];
+ int n_len = 0;
+ long value = 0;
+ amii_addtopl("#"), n_len++;
+ digit_string[1] = '\0';
+ if (q != '#') {
+ digit_string[0] = q;
+ amii_addtopl(digit_string), n_len++;
+ value = q - '0';
+ q = '#';
+ }
+ do { /* loop until we get a non-digit */
+ cursor_on(WIN_MESSAGE);
+ z = lowc(WindowGetchar());
+ cursor_off(WIN_MESSAGE);
+ if (isdigit(z)) {
+ value = (10 * value) + (z - '0');
+ if (value < 0) break; /* overflow: try again */
+ digit_string[0] = z;
+ amii_addtopl(digit_string), n_len++;
+ } else if (z == 'y' || index(quitchars, z)) {
+ if (z == '\033') value = -1; /* abort */
+ z = '\n'; /* break */
+ } else if ( z == '\b') {
+ if (n_len <= 1) { value = -1; break; }
+ else { value /= 10; removetopl(1), n_len--; }
+ } else {
+ value = -1; /* abort */
+ amii_bell();
+ break;
+ }
+ } while (z != '\n');
+ if (value > 0) yn_number = value;
+ else if (value == 0) q = 'n'; /* 0 => "no" */
+ else { /* remove number from top line, then try again */
+ removetopl(n_len), n_len = 0;
+ q = '\0';
+ }
+ }
+ } while(!q);
+
+ if (q != '#' && q != '\033') {
+ Sprintf(rtmp, "%c", q);
+ amii_addtopl(rtmp);
+ }
+ clean_up:
+ cursor_off(WIN_MESSAGE);
+ clear_nhwindow(WIN_MESSAGE);
+ return q;
+}
+
+void
+amii_display_file(fn, complain)
+const char *fn;
+boolean complain;
+{
+ register struct amii_WinDesc *cw;
+ register int win;
+ register dlb *fp;
+ register char *t;
+ register char buf[ 200 ];
+
+ if( fn == NULL )
+ panic("NULL file name in display_file()");
+
+ if( ( fp = dlb_fopen( fn, RDTMODE ) ) == (dlb *)NULL )
+ {
+ if (complain) {
+ sprintf( buf, "Can't display %s: %s", fn,
+#if defined(_DCC) || defined(__GNUC__)
+ strerror(errno)
+#else
+# ifdef __SASC_60
+ __sys_errlist[ errno ]
+# else
+ sys_errlist[ errno ]
+# endif
+#endif
+ );
+ amii_addtopl( buf );
+ }
+ return;
+ }
+ win = amii_create_nhwindow( NHW_TEXT );
+
+ /* Set window title to file name */
+ if( cw = amii_wins[ win ] )
+ cw->morestr = (char *)fn;
+
+ while( dlb_fgets( buf, sizeof( buf ), fp ) != NULL )
+ {
+ if( t = index( buf, '\n' ) )
+ *t = 0;
+ amii_putstr( win, 0, buf );
+ }
+ dlb_fclose( fp );
+
+ /* If there were lines in the file, display those lines */
+
+ if( amii_wins[ win ]->cury > 0 )
+ amii_display_nhwindow( win, TRUE );
+
+ amii_wins[win]->morestr = NULL; /* don't free title string */
+ amii_destroy_nhwindow( win );
+}
+
+/* Put a 3-D motif border around the gadget. String gadgets or those
+ * which do not have highlighting are rendered down. Boolean gadgets
+ * are rendered in the up position by default.
+ */
+
+void
+SetBorder( gd )
+ register struct Gadget *gd;
+{
+ register struct Border *bp;
+ register short *sp;
+ register int i, inc = -1, dec = -1;
+ int borders = 6;
+ int hipen = flags.amii_dripens[ SHINEPEN ], shadowpen = flags.amii_dripens[ SHADOWPEN ];
+#ifdef INTUI_NEW_LOOK
+ struct DrawInfo *dip;
+#endif
+
+#ifdef INTUI_NEW_LOOK
+ if( IntuitionBase->LibNode.lib_Version >= 37 )
+ {
+ if( dip = GetScreenDrawInfo( HackScreen ) )
+ {
+ hipen = dip->dri_Pens[ SHINEPEN ];
+ shadowpen = dip->dri_Pens[ SHADOWPEN ];
+ FreeScreenDrawInfo( HackScreen, dip );
+ }
+ }
+#endif
+ /* Allocate two border structures one for up image and one for down
+ * image, plus vector arrays for the border lines.
+ */
+
+ if( gd->GadgetType == STRGADGET )
+ borders = 12;
+
+ if( ( bp = (struct Border *)alloc( ( ( sizeof( struct Border ) * 2 ) +
+ ( sizeof( short ) * borders ) ) * 2 ) ) == NULL )
+ {
+ return;
+ }
+
+ /* For a string gadget, we expand the border beyond the area where
+ * the text will be entered.
+ */
+
+ /* Remove any special rendering flags to avoid confusing intuition
+ */
+
+ gd->Flags &= ~(GADGHIGHBITS|GADGIMAGE);
+
+ sp = (short *)(bp + 4);
+ if( gd->GadgetType == STRGADGET || ( gd->GadgetType == BOOLGADGET &&
+ ( gd->Flags & GADGHIGHBITS ) == GADGHNONE ) )
+ {
+ sp[0] = -1;
+ sp[1] = gd->Height - 1;
+ sp[2] = -1;
+ sp[3] = -1;
+ sp[4] = gd->Width - 1;
+ sp[5] = -1;
+
+ sp[6] = gd->Width + 1;
+ sp[7] = -2;
+ sp[8] = gd->Width + 1;
+ sp[9] = gd->Height + 1;
+ sp[10] = -2;
+ sp[11] = gd->Height + 1;
+
+ sp[12] = -2;
+ sp[13] = gd->Height;
+ sp[14] = -2;
+ sp[15] = -2;
+ sp[16] = gd->Width;
+ sp[17] = -2;
+ sp[18] = gd->Width;
+ sp[19] = gd->Height;
+ sp[20] = -2;
+ sp[21] = gd->Height;
+
+ for( i = 0; i < 3; ++i )
+ {
+ bp[ i ].LeftEdge = bp[ i ].TopEdge = -1;
+ bp[ i ].FrontPen = ( i == 0 || i == 1 ) ? shadowpen : hipen;
+
+ /* Have to use JAM2 so that the old colors disappear. */
+ bp[ i ].BackPen = C_BLACK;
+ bp[ i ].DrawMode = JAM2;
+ bp[ i ].Count = ( i == 0 || i == 1 ) ? 3 : 5;
+ bp[ i ].XY = &sp[ i*6 ];
+ bp[ i ].NextBorder = ( i == 2 ) ? NULL : &bp[ i + 1 ];
+ }
+
+ /* bp[0] and bp[1] two pieces for the up image */
+ gd->GadgetRender = (APTR) bp;
+
+ /* No image change for select */
+ gd->SelectRender = (APTR) bp;
+
+ gd->LeftEdge++;
+ gd->TopEdge++;
+ gd->Flags |= GADGHCOMP;
+ }
+ else
+ {
+ /* Create the border vector values for up and left side, and
+ * also the lower and right side.
+ */
+
+ sp[0] = dec;
+ sp[1] = gd->Height + inc;
+ sp[2] = dec;
+ sp[3] = dec;
+ sp[4] = gd->Width + inc;
+ sp[5] = dec;
+
+ sp[6] = gd->Width + inc;
+ sp[7] = dec;
+ sp[8] = gd->Width + inc;
+ sp[9] = gd->Height + inc;
+ sp[10] = dec;
+ sp[11] = gd->Height + inc;
+
+ /* We are creating 4 sets of borders, the two sides of the
+ * rectangle share the border vectors with the opposite image,
+ * but specify different colors.
+ */
+
+ for( i = 0; i < 4; ++i )
+ {
+ bp[ i ].TopEdge = bp[ i ].LeftEdge = 0;
+
+ /* A GADGHNONE is always down */
+
+ if( gd->GadgetType == BOOLGADGET &&
+ ( gd->Flags & GADGHIGHBITS ) != GADGHNONE )
+ {
+ bp[ i ].FrontPen =
+ ( i == 1 || i == 2 ) ? shadowpen : hipen;
+ }
+ else
+ {
+ bp[ i ].FrontPen =
+ ( i == 1 || i == 3 ) ? hipen : shadowpen;
+ }
+
+ /* Have to use JAM2 so that the old colors disappear. */
+ bp[ i ].BackPen = C_BLACK;
+ bp[ i ].DrawMode = JAM2;
+ bp[ i ].Count = 3;
+ bp[ i ].XY = &sp[ 6 * ((i &1) != 0) ];
+ bp[ i ].NextBorder =
+ ( i == 1 || i == 3 ) ? NULL : &bp[ i + 1 ];
+ }
+
+ /* bp[0] and bp[1] two pieces for the up image */
+ gd->GadgetRender = (APTR) bp;
+
+ /* bp[2] and bp[3] two pieces for the down image */
+ gd->SelectRender = (APTR) (bp + 2);
+ gd->Flags |= GADGHIMAGE;
+ }
+}
+
+/* Following function copied from wintty.c */
+/* Modified slightly to fit amiga needs */
+
+void
+amii_player_selection()
+{
+ int i, k, n;
+ char pick4u = 'n', thisch, lastch = 0;
+ char pbuf[QBUFSZ], plbuf[QBUFSZ], rolenamebuf[QBUFSZ];
+ winid win;
+ anything any;
+ menu_item *selected = 0;
+
+ rigid_role_checks();
+
+ /* Should we randomly pick for the player? */
+ if (flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE ||
+ flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE) {
+ char *prompt = build_plselection_prompt(pbuf, QBUFSZ, flags.initrole,
+ flags.initrace, flags.initgend, flags.initalign);
+ pline("%s", prompt);
+ do { /* loop until we get valid input */
+ cursor_on(WIN_MESSAGE);
+ pick4u = lowc(WindowGetchar());
+ cursor_off(WIN_MESSAGE);
+ if (index(quitchars, pick4u)) pick4u = 'y';
+ } while(!index(ynqchars, pick4u));
+ pbuf[0] = pick4u;
+ pbuf[1] = 0;
+ amii_addtopl(pbuf);
+
+ if (pick4u != 'y' && pick4u != 'n') {
+give_up: /* Quit */
+ if (selected) free((genericptr_t) selected);
+ clearlocks();
+ exit_nhwindows(NULL);
+ terminate(0);
+ /*NOTREACHED*/
+ return;
+ }
+ }
+
+ (void) root_plselection_prompt(plbuf, QBUFSZ - 1,
+ flags.initrole, flags.initrace, flags.initgend, flags.initalign);
+
+ /* Select a role, if necessary */
+ /* we'll try to be compatible with pre-selected race/gender/alignment,
+ * but may not succeed */
+ if (flags.initrole < 0) {
+ /* Process the choice */
+ if (pick4u == 'y' || flags.initrole == ROLE_RANDOM || flags.randomall) {
+ /* Pick a random role */
+ flags.initrole = pick_role(flags.initrace, flags.initgend,
+ flags.initalign, PICK_RANDOM);
+ if (flags.initrole < 0) {
+ amii_putstr(WIN_MESSAGE, 0, "Incompatible role!");
+ flags.initrole = randrole();
+ }
+ } else {
+ /* Prompt for a role */
+ win = create_nhwindow(NHW_MENU);
+ start_menu(win);
+ any.a_void = 0; /* zero out all bits */
+ for (i = 0; roles[i].name.m; i++) {
+ if (ok_role(i, flags.initrace, flags.initgend,
+ flags.initalign)) {
+ any.a_int = i+1; /* must be non-zero */
+ thisch = lowc(roles[i].name.m[0]);
+ if (thisch == lastch) thisch = highc(thisch);
+ if (flags.initgend != ROLE_NONE && flags.initgend != ROLE_RANDOM) {
+ if (flags.initgend == 1 && roles[i].name.f)
+ Strcpy(rolenamebuf, roles[i].name.f);
+ else
+ Strcpy(rolenamebuf, roles[i].name.m);
+ } else {
+ if (roles[i].name.f) {
+ Strcpy(rolenamebuf, roles[i].name.m);
+ Strcat(rolenamebuf, "/");
+ Strcat(rolenamebuf, roles[i].name.f);
+ } else
+ Strcpy(rolenamebuf, roles[i].name.m);
+ }
+ add_menu(win, NO_GLYPH, &any, thisch,
+ 0, ATR_NONE, an(rolenamebuf), MENU_UNSELECTED);
+ lastch = thisch;
+ }
+ }
+ any.a_int = pick_role(flags.initrace, flags.initgend,
+ flags.initalign, PICK_RANDOM)+1;
+ if (any.a_int == 0) /* must be non-zero */
+ any.a_int = randrole()+1;
+ add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE,
+ "Random", MENU_UNSELECTED);
+ any.a_int = i+1; /* must be non-zero */
+ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE,
+ "Quit", MENU_UNSELECTED);
+ Sprintf(pbuf, "Pick a role for your %s", plbuf);
+ end_menu(win, pbuf);
+ n = select_menu(win, PICK_ONE, &selected);
+ destroy_nhwindow(win);
+
+ /* Process the choice */
+ if (n != 1 || selected[0].item.a_int == any.a_int)
+ goto give_up; /* Selected quit */
+
+ flags.initrole = selected[0].item.a_int - 1;
+ free((genericptr_t) selected), selected = 0;
+ }
+ (void) root_plselection_prompt(plbuf, QBUFSZ - 1,
+ flags.initrole, flags.initrace, flags.initgend, flags.initalign);
+ }
+
+ /* Select a race, if necessary */
+ /* force compatibility with role, try for compatibility with
+ * pre-selected gender/alignment */
+ if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) {
+ /* pre-selected race not valid */
+ if (pick4u == 'y' || flags.initrace == ROLE_RANDOM || flags.randomall) {
+ flags.initrace = pick_race(flags.initrole, flags.initgend,
+ flags.initalign, PICK_RANDOM);
+ if (flags.initrace < 0) {
+ amii_putstr(WIN_MESSAGE, 0, "Incompatible race!");
+ flags.initrace = randrace(flags.initrole);
+ }
+ } else { /* pick4u == 'n' */
+ /* Count the number of valid races */
+ n = 0; /* number valid */
+ k = 0; /* valid race */
+ for (i = 0; races[i].noun; i++) {
+ if (ok_race(flags.initrole, i, flags.initgend,
+ flags.initalign)) {
+ n++;
+ k = i;
+ }
+ }
+ if (n == 0) {
+ for (i = 0; races[i].noun; i++) {
+ if (validrace(flags.initrole, i)) {
+ n++;
+ k = i;
+ }
+ }
+ }
+
+ /* Permit the user to pick, if there is more than one */
+ if (n > 1) {
+ win = create_nhwindow(NHW_MENU);
+ start_menu(win);
+ any.a_void = 0; /* zero out all bits */
+ for (i = 0; races[i].noun; i++)
+ 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, MENU_UNSELECTED);
+ }
+ 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_UNSELECTED);
+ any.a_int = i+1; /* must be non-zero */
+ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE,
+ "Quit", MENU_UNSELECTED);
+ Sprintf(pbuf, "Pick the race of your %s", plbuf);
+ end_menu(win, pbuf);
+ n = select_menu(win, PICK_ONE, &selected);
+ destroy_nhwindow(win);
+ if (n != 1 || selected[0].item.a_int == any.a_int)
+ goto give_up; /* Selected quit */
+
+ k = selected[0].item.a_int - 1;
+ free((genericptr_t) selected), selected = 0;
+ }
+ flags.initrace = k;
+ }
+ (void) root_plselection_prompt(plbuf, QBUFSZ - 1,
+ flags.initrole, flags.initrace, flags.initgend, flags.initalign);
+ }
+
+ /* Select a gender, if necessary */
+ /* force compatibility with role/race, try for compatibility with
+ * pre-selected alignment */
+ if (flags.initgend < 0 || !validgend(flags.initrole, flags.initrace,
+ flags.initgend)) {
+ /* pre-selected gender not valid */
+ if (pick4u == 'y' || flags.initgend == ROLE_RANDOM || flags.randomall) {
+ flags.initgend = pick_gend(flags.initrole, flags.initrace,
+ flags.initalign, PICK_RANDOM);
+ if (flags.initgend < 0) {
+ amii_putstr(WIN_MESSAGE, 0, "Incompatible gender!");
+ flags.initgend = randgend(flags.initrole, flags.initrace);
+ }
+ } else { /* pick4u == 'n' */
+ /* Count the number of valid genders */
+ n = 0; /* number valid */
+ k = 0; /* valid gender */
+ for (i = 0; i < ROLE_GENDERS; i++) {
+ if (ok_gend(flags.initrole, flags.initrace, i,
+ flags.initalign)) {
+ n++;
+ k = i;
+ }
+ }
+ if (n == 0) {
+ for (i = 0; i < ROLE_GENDERS; i++) {
+ if (validgend(flags.initrole, flags.initrace, i)) {
+ n++;
+ k = i;
+ }
+ }
+ }
+
+ /* Permit the user to pick, if there is more than one */
+ if (n > 1) {
+ win = create_nhwindow(NHW_MENU);
+ start_menu(win);
+ any.a_void = 0; /* zero out all bits */
+ for (i = 0; i < ROLE_GENDERS; i++)
+ 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_UNSELECTED);
+ }
+ 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_UNSELECTED);
+ any.a_int = i+1; /* must be non-zero */
+ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE,
+ "Quit", MENU_UNSELECTED);
+ Sprintf(pbuf, "Pick the gender of your %s", plbuf);
+ end_menu(win, pbuf);
+ n = select_menu(win, PICK_ONE, &selected);
+ destroy_nhwindow(win);
+ if (n != 1 || selected[0].item.a_int == any.a_int)
+ goto give_up; /* Selected quit */
+
+ k = selected[0].item.a_int - 1;
+ free((genericptr_t) selected), selected = 0;
+ }
+ flags.initgend = k;
+ }
+ (void) root_plselection_prompt(plbuf, QBUFSZ - 1,
+ flags.initrole, flags.initrace, flags.initgend, flags.initalign);
+ }
+
+ /* Select an alignment, if necessary */
+ /* force compatibility with role/race/gender */
+ if (flags.initalign < 0 || !validalign(flags.initrole, flags.initrace,
+ flags.initalign)) {
+ /* pre-selected alignment not valid */
+ if (pick4u == 'y' || flags.initalign == ROLE_RANDOM || flags.randomall) {
+ flags.initalign = pick_align(flags.initrole, flags.initrace,
+ flags.initgend, PICK_RANDOM);
+ if (flags.initalign < 0) {
+ amii_putstr(WIN_MESSAGE, 0, "Incompatible alignment!");
+ flags.initalign = randalign(flags.initrole, flags.initrace);
+ }
+ } else { /* pick4u == 'n' */
+ /* Count the number of valid alignments */
+ n = 0; /* number valid */
+ k = 0; /* valid alignment */
+ for (i = 0; i < ROLE_ALIGNS; i++) {
+ if (ok_align(flags.initrole, flags.initrace, flags.initgend,
+ i)) {
+ n++;
+ k = i;
+ }
+ }
+ if (n == 0) {
+ for (i = 0; i < ROLE_ALIGNS; i++) {
+ if (validalign(flags.initrole, flags.initrace, i)) {
+ n++;
+ k = i;
+ }
+ }
+ }
+
+ /* Permit the user to pick, if there is more than one */
+ if (n > 1) {
+ win = create_nhwindow(NHW_MENU);
+ start_menu(win);
+ any.a_void = 0; /* zero out all bits */
+ for (i = 0; i < ROLE_ALIGNS; i++)
+ 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_UNSELECTED);
+ }
+ 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_UNSELECTED);
+ any.a_int = i+1; /* must be non-zero */
+ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE,
+ "Quit", MENU_UNSELECTED);
+ Sprintf(pbuf, "Pick the alignment of your %s", plbuf);
+ end_menu(win, pbuf);
+ n = select_menu(win, PICK_ONE, &selected);
+ destroy_nhwindow(win);
+ if (n != 1 || selected[0].item.a_int == any.a_int)
+ goto give_up; /* Selected quit */
+
+ k = selected[0].item.a_int - 1;
+ free((genericptr_t) selected), selected = 0;
+ }
+ flags.initalign = k;
+ }
+ }
+ /* Success! */
+}
+#endif /* AMIGA_INTUITION */
diff --git a/sys/amiga/winami.p b/sys/amiga/winami.p
new file mode 100644
index 0000000..b34f8e5
--- /dev/null
+++ b/sys/amiga/winami.p
@@ -0,0 +1,57 @@
+/* SCCS Id: @(#)winami.p 3.1 93/01/08 */
+/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */
+/* NetHack may be freely redistributed. See license for details. */
+/* winami.c */
+void FDECL(amii_raw_print, (const char *));
+void FDECL(amii_raw_print_bold, (const char *));
+void FDECL(amii_start_menu, (winid ));
+void FDECL(amii_add_menu, (winid , char , int , const char *));
+void FDECL(amii_end_menu, (winid , char , const char * , const char *));
+char FDECL(amii_select_menu, (winid ));
+void NDECL(amii_update_inventory );
+void NDECL(amii_mark_synch );
+void NDECL(amii_wait_synch );
+void NDECL(amii_setclipped );
+void FDECL(amii_cliparound, (int , int ));
+void NDECL(amii_askname );
+void NDECL(amii_player_selection );
+void NDECL(flush_output );
+void FDECL(amii_destroy_nhwindow, (winid ));
+int FDECL(amii_create_nhwindow, (int ));
+void NDECL(amii_init_nhwindows );
+int NDECL(amii_get_ext_cmd);
+char FDECL(amii_yn_function, (const char * , const char * , char ));
+void FDECL(amii_addtopl, (const char *));
+void FDECL(TextSpaces, (struct RastPort * , int ));
+void FDECL(amii_putstr, (winid , int , const char *));
+void FDECL(amii_putsym, (winid , int , int , CHAR_P ));
+void FDECL(amii_clear_nhwindow, (winid ));
+void FDECL(amii_exit_nhwindows, (const char *));
+int FDECL(amii_nh_poskey, (int * , int * , int *));
+int NDECL(amii_nhgetch );
+void NDECL(amii_get_nh_event );
+void NDECL(amii_remember_topl );
+int NDECL(amii_doprev_message );
+void FDECL(amii_display_nhwindow, (winid , boolean ));
+void FDECL(amii_display_file, (const char * , boolean ));
+void FDECL(amii_curs, (winid , int , int ));
+void FDECL(amii_print_glyph, (winid , xchar , xchar , int ));
+void FDECL(DoMenuScroll, (int , int ));
+void FDECL(DisplayData, (int , int , int ));
+void FDECL(SetPropInfo, (struct Window * , struct Gadget * , long , long , long ));
+void FDECL(kill_nhwindows, (int ));
+void FDECL(amii_cl_end, (struct amii_WinDesc * , int ));
+void FDECL(cursor_off, (winid ));
+void FDECL(cursor_on, (winid ));
+void NDECL(amii_getret );
+void FDECL(amii_getlin, (const char * , char *));
+void FDECL(getlind, (const char * , char * , const char *));
+void FDECL(amii_suspend_nhwindows, (char * ));
+void NDECL(amii_resume_nhwindows);
+void NDECL(amii_bell);
+void NDECL(EditColor);
+void FDECL(DrawCol, ( struct Window *, int, UWORD * ) );
+void FDECL( DispCol, ( struct Window *w, int idx, UWORD * ) );
+void FDECL( SetBorder, (struct Gadget *) );
+void NDECL( port_help );
+void FDECL( dismiss_nhwindow, (winid) );
diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c
new file mode 100644
index 0000000..2f6e721
--- /dev/null
+++ b/sys/amiga/winchar.c
@@ -0,0 +1,1246 @@
+/* SCCS Id: @(#)winchar.c 3.1 93/07/22 */
+/* Copyright (c) Olaf Seibert (KosmoSoft), 1989, 1992 */
+/* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993 */
+/* Copyright (c) Gregg Wonderly, Naperville Illinois, 1994. */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include
+#include
+#include
+#ifndef _DCC
+#include
+#endif
+
+#ifdef TESTING
+# include "hack.h"
+#else
+# include "NH:src/tile.c"
+#endif
+
+#include "NH:win/share/tile.h"
+
+#include "NH:sys/amiga/windefs.h"
+#include "NH:sys/amiga/winext.h"
+#include "NH:sys/amiga/winproto.h"
+
+#ifdef OPT_DISPMAP
+# define DISPMAP /* use display_map() from dispmap.s */
+#endif
+
+/* NH:sys/amiga/winvchar.c */
+int main ( int , char ** );
+struct BitMap *MyAllocBitMap ( int , int , int , long );
+void MyFreeBitMap ( struct BitMap * );
+void FreeImageFiles ( char **, struct BitMap ** );
+void amiv_flush_glyph_buffer ( struct Window * );
+void amiv_lprint_glyph ( winid , int , int );
+void amii_lprint_glyph ( winid , int , int );
+void amiv_start_glyphout ( winid );
+void amii_end_glyphout ( winid );
+void SetMazeType ( MazeType );
+int GlyphToIcon ( int );
+void amii_start_glyphout ( winid );
+void amii_end_glyphout ( winid );
+void amii_flush_glyph_buffer( struct Window * );
+
+int amii_extraplanes = 0;
+extern int reclip;
+
+struct BitMap *MyAllocBitMap( int xsize, int ysize, int depth, long mflags );
+void MyFreeBitMap( struct BitMap *bmp );
+
+#ifdef DISPMAP
+extern void display_map( struct Window * );
+#endif
+
+/*
+ * These values will be available from tile.c source
+ *
+ * #define MAXMONTILE 335
+ * #define MAXOBJTILE 722
+ * #define MAXOTHTILE 841
+ */
+
+#define IMGROWS 12
+#define IMGCOLUMNS 20
+#define IMGPAGESIZE (IMGROWS*IMGCOLUMNS)
+
+#define ID_BMAP MAKE_ID('B','M','A','P') /* The type of form we use */
+#define ID_BMHD MAKE_ID('B','M','H','D') /* The ILBM bitmap header */
+#define ID_CAMG MAKE_ID('C','A','M','G') /* The ILBM camg (ignored) */
+#define ID_CMAP MAKE_ID('C','M','A','P') /* Standard ILBM color map */
+#define ID_PLNE MAKE_ID('P','L','N','E') /* The plane data */
+#define ID_PDAT MAKE_ID('P','D','A','T') /* The PDAT structure below */
+
+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;
+
+#ifdef TESTING
+short pens[NUMDRIPENS] = { 8, 3, 15, 0, 15, 7, 7, 8, 0 };
+main( int argc, char **argv )
+{
+ BitMapHeader bmhd;
+ struct IntuiMessage *imsg;
+ long code, class;
+ char buf[100];
+ int i, x, y, tbl, done = 0, num;
+ struct Window *w;
+ struct Screen *scr;
+
+ bmhd = ReadTileImageFiles( );
+
+ scr = OpenScreenTags( NULL,
+ SA_Depth, pictdata.nplanes + amii_extraplanes,
+ SA_DisplayID, DBLNTSC_MONITOR_ID|HIRESLACE_KEY,
+ SA_Overscan, OSCAN_TEXT,
+ SA_Top, 0,
+ SA_Left, 0,
+ SA_Width, STDSCREENWIDTH,
+ SA_Height, STDSCREENHEIGHT,
+ SA_Type, CUSTOMSCREEN,
+ SA_DetailPen, 0,
+ SA_BlockPen, 1,
+ SA_Title, "NetHack Chars",
+ SA_Pens, pens,
+ TAG_DONE
+ );
+ if( scr == NULL )
+ {
+ printf( "no screen\n" );
+#undef exit
+ exit( 1 );
+ }
+
+ w = OpenWindowTags( 0,
+ WA_CustomScreen, scr,
+ WA_Flags, WFLG_DRAGBAR|WFLG_SIZEGADGET|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET,
+ WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|IDCMP_MOUSEBUTTONS,
+ WA_Left, 0,
+ WA_Top, scr->WBorTop + 1 + 13,
+ WA_MinWidth, 100,
+ WA_MinHeight, 100,
+ WA_MaxWidth, 700,
+ WA_MaxHeight, 1000,
+ WA_Width, 640,
+ WA_Height, 340,
+ WA_SmartRefresh, TRUE,
+ TAG_DONE );
+ if( w )
+ {
+ while( !done )
+ {
+ for( i = 0; i < NUMTILEIMAGES * IMGPAGESIZE; ++i )
+ {
+ int dx, dy;
+ tbl = i/IMGPAGESIZE;
+ x = i % IMGPAGESIZE;
+ y = x / IMGCOLUMNS;
+ x = x % IMGCOLUMNS;
+ dx = i % (IMGCOLUMNS*2);
+ dy = i / (IMGCOLUMNS*2);
+ BltBitMapRastPort( ifftimg[ tbl ],
+ x * pictdata.xsize, y * pictdata.ysize,
+ w->RPort,
+ w->BorderLeft + 1 + dx*pictdata.xsize,
+ w->BorderTop + 1 + dy*pictdata.ysize,
+ pictdata.xsize, pictdata.ysize, 0xc0 );
+ }
+ WaitPort( w->UserPort );
+ while( imsg = (struct IntuiMessage *)GetMsg( w->UserPort ) )
+ {
+ class = imsg->Class;
+ code = imsg->Code;
+ ReplyMsg( (struct Message *)imsg );
+ switch( class )
+ {
+ case IDCMP_MOUSEBUTTONS:
+ {
+ x = imsg->MouseX - w->BorderLeft;
+ y = imsg->MouseY - w->BorderTop;
+ num = ((y/pictdata.ysize)*IMGCOLUMNS*2)+(x/pictdata.xsize);
+ sprintf( buf, "Char #%d", num );
+ SetWindowTitles( w, buf, buf );
+ }
+ break;
+ case IDCMP_CLOSEWINDOW:
+ done = 1;
+ break;
+ }
+ }
+ }
+ CloseWindow( w );
+ CloseScreen( scr );
+ }
+
+ FreeImageFiles(tileimages, ifftimg );
+
+ return(0);
+}
+#endif
+
+BitMapHeader
+ReadTileImageFiles(){
+ 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;
+ struct IFFHandle *iff;
+ struct StoredProperty *prop;
+
+ IFFParseBase = OpenLibrary( "iffparse.library", 0L );
+ if( !IFFParseBase )
+ {
+ *errstrp = "No iffparse.library";
+ return bmhds;
+ }
+
+/*
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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 );
+ }
+ 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 );
+}
+
+struct MyBitMap
+{
+ struct BitMap bm;
+ long mflags;
+ USHORT xsize, ysize;
+};
+
+struct BitMap *
+MyAllocBitMap( int xsize, int ysize, int depth, long mflags )
+{
+ int j;
+ struct MyBitMap *bm;
+
+ bm = (struct MyBitMap *)alloc( sizeof( *bm ) );
+ if( !bm )
+ return( NULL );
+
+ bm->xsize = xsize;
+ bm->ysize = ysize;
+ InitBitMap( &bm->bm, depth, xsize, ysize );
+ for( j = 0; j < depth; ++j )
+ {
+ if( mflags & MEMF_CHIP )
+ bm->bm.Planes[ j ] = AllocRaster( xsize, ysize );
+ else
+ bm->bm.Planes[ j ] = AllocMem( RASSIZE( xsize, ysize ), mflags );
+
+ if( bm->bm.Planes[ j ] == 0 )
+ {
+ MyFreeBitMap( &bm->bm );
+ return( NULL );
+ }
+ if( mflags & MEMF_CLEAR )
+ memset( bm->bm.Planes[ j ], 0, RASSIZE( xsize, ysize ) );
+ }
+ return( &bm->bm );
+}
+
+void
+MyFreeBitMap( struct BitMap *bmp )
+{
+ int j;
+ struct MyBitMap *bm = (struct MyBitMap *)bmp;
+
+ for( j = 0; j < bm->bm.Depth; ++j )
+ {
+ if( bm->bm.Planes[j] )
+ {
+ if( bm->mflags & MEMF_CHIP )
+ FreeRaster( bm->bm.Planes[j], bm->xsize, bm->ysize );
+ else
+ FreeMem( bm->bm.Planes[j], RASSIZE( bm->xsize, bm->ysize ) );
+ }
+ }
+ free( bm );
+}
+
+#ifdef TESTING
+void
+panic(s,a1,a2,a3,a4)
+ char *s;
+{
+ printf( s, a1, a2, a3, a4 );
+ putchar('\n');
+}
+long *
+alloc(unsigned int x){
+ long *p = (long *)malloc(x);
+ if(!p){panic("malloc failed"); exit(1);}
+ return p;
+}
+#endif
+
+void
+FreeTileImageFiles(){
+ 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 );
+}
+
+#ifndef TESTING
+/*
+ * Define some stuff for our special glyph drawing routines
+ */
+unsigned short glyph_node_index, glyph_buffer_index;
+#define NUMBER_GLYPH_NODES 80
+#define GLYPH_BUFFER_SIZE 512
+struct amiv_glyph_node {
+ short odstx, odsty;
+ short srcx, srcy, dstx, dsty;
+ struct BitMap *bitmap;
+};
+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;
+{
+ if( WINVERS_AMIV )
+ amiv_flush_glyph_buffer ( vw );
+ else
+ amii_flush_glyph_buffer ( vw );
+}
+
+/*
+ * Routine to flush whatever is buffered
+ */
+void
+amiv_flush_glyph_buffer( vw )
+ struct Window *vw;
+{
+#if !defined(DISPMAP) || defined(OPT_DISPMAP)
+ int xsize, ysize, x, y;
+ struct BitScaleArgs bsa;
+ struct BitScaleArgs bsm;
+ struct RastPort rast;
+ struct Window *w = NULL;
+ struct BitMap *imgbm = 0, *bm = 0;
+ int i, k;
+ int scaling_needed;
+ register struct RastPort *rp = vw->RPort;
+#endif
+
+ /* If nothing is buffered, return before we do anything */
+ if(glyph_node_index == 0)
+ return;
+
+ cursor_off( WIN_MAP );
+ amiv_start_glyphout( WIN_MAP );
+
+#ifdef OPT_DISPMAP
+ if(flags.fast_map){
+#endif
+#ifdef DISPMAP
+ display_map( vw );
+#endif
+#ifdef OPT_DISPMAP
+ } else {
+#endif
+#if !defined(DISPMAP) || defined(OPT_DISPMAP)
+/* XXX fix indent */
+ /* This is a dynamic value based on this relationship. */
+ scaling_needed = ( pictdata.xsize != mxsize || pictdata.ysize != mysize );
+
+ /* If overview window is up, set up to render the correct scale there */
+ if( WIN_OVER != WIN_ERR && ( w = amii_wins[ WIN_OVER ]->win ) != NULL )
+ {
+ InitRastPort( &rast );
+
+ /* Calculate the x and y size of each tile for a ROWNO by COLNO map */
+ xsize = (w->Width - w->BorderLeft - w->BorderRight) / COLNO;
+ ysize = (w->Height - w->BorderTop - w->BorderBottom) / ROWNO;
+
+ /* Get a chip memory bitmap to blit out of */
+ bm = MyAllocBitMap( pictdata.xsize, pictdata.ysize,
+ pictdata.nplanes + amii_extraplanes, MEMF_CLEAR|MEMF_CHIP );
+ if( bm == NULL )
+ {
+ amii_putstr( WIN_MESSAGE, 0, "Can't allocate bitmap for scaling overview window" );
+ }
+
+ rast.BitMap = bm;
+
+ memset( &bsa, 0, sizeof( bsa ) );
+ bsa.bsa_SrcX = bsa.bsa_SrcY = 0;
+ bsa.bsa_SrcBitMap = tile;
+ bsa.bsa_SrcWidth = pictdata.xsize;
+ bsa.bsa_SrcHeight = pictdata.ysize;
+ bsa.bsa_XSrcFactor = pictdata.xsize;
+ bsa.bsa_YSrcFactor = pictdata.ysize;
+ bsa.bsa_DestX = 0;
+ bsa.bsa_DestY = 0;
+ bsa.bsa_DestWidth = xsize;
+ bsa.bsa_DestHeight = ysize;
+ bsa.bsa_XDestFactor = xsize;
+ bsa.bsa_YDestFactor = ysize;
+ bsa.bsa_DestBitMap = bm;
+ }
+
+ if( scaling_needed )
+ {
+ /* Fill in scaling data for map rendering */
+ memset( &bsm, 0, sizeof( bsm ) );
+ bsm.bsa_SrcX = bsm.bsa_SrcY = 0;
+ bsm.bsa_SrcBitMap = tile;
+
+ bsm.bsa_SrcWidth = pictdata.xsize;
+ bsm.bsa_SrcHeight = pictdata.ysize;
+
+ bsm.bsa_XSrcFactor = pictdata.xsize;
+ bsm.bsa_YSrcFactor = pictdata.ysize;
+
+ bsm.bsa_DestWidth = mxsize;
+ bsm.bsa_DestHeight = mysize;
+
+ bsm.bsa_XDestFactor = mxsize;
+ bsm.bsa_YDestFactor = mysize;
+ bsm.bsa_DestBitMap = rp->BitMap;
+ bsm.bsa_DestY = bsm.bsa_DestX = 0;
+
+ imgbm = MyAllocBitMap( mxsize, mysize,
+ pictdata.nplanes + amii_extraplanes, MEMF_CLEAR|MEMF_CHIP );
+ if( imgbm == NULL )
+ {
+ amii_putstr( WIN_MESSAGE, 0,
+ "Can't allocate scaling bitmap for map window" );
+ }
+ else
+ bsm.bsa_DestBitMap = imgbm;
+ }
+
+ /* Go ahead and start dumping the stuff */
+ for( i=0; iBytesPerRow;
+ for( j = 0; j < pictdata.nplanes + amii_extraplanes; ++j )
+ {
+ for( k = 0; k < pictdata.ysize; ++k )
+ {
+
+ /* For a 16x16 tile, this could just be short assignments, but
+ * this code is generalized to handle any size tile image...
+ */
+ memcpy( tile->Planes[ j ] + ( ( k * pictdata.ysize ) / 8 ),
+ nodebm->Planes[ j ] + offx + offy + ( nodebm->BytesPerRow * k ),
+ pictdata.ysize/8 );
+ }
+ }
+
+ if( !clipping ||
+ ( x >= clipx && y >= clipy &&
+ x < clipxmax && y < clipymax ) )
+ {
+ /* scaling is needed, do it */
+ if( scaling_needed )
+ {
+ BitMapScale( &bsm );
+ BltBitMapRastPort( imgbm, 0, 0,
+ rp, amiv_g_nodes[ i ].dstx, amiv_g_nodes[ i ].dsty,
+ mxsize, mysize, 0xc0 );
+ }
+ else
+ {
+ BltBitMapRastPort( tile, 0, 0,
+ rp, amiv_g_nodes[ i ].dstx, amiv_g_nodes[ i ].dsty,
+ pictdata.xsize, pictdata.ysize, 0xc0 );
+ }
+ }
+ /* Draw the overview window unless we are scrolling the map raster around */
+ if( bm && w && reclip != 2 )
+ {
+ BitMapScale( &bsa );
+ BltBitMapRastPort( rast.BitMap, 0, 0,
+ w->RPort,
+ w->BorderLeft + amiv_g_nodes[ i ].odstx*xsize,
+ w->BorderTop + amiv_g_nodes[ i ].odsty*ysize,
+ xsize, ysize, 0xc0 );
+ }
+ }
+
+ if( imgbm ) MyFreeBitMap( imgbm );
+ if( bm ) MyFreeBitMap( bm );
+#endif /* DISPMAP */
+#ifdef OPT_DISPMAP
+ }
+#endif
+
+ amii_end_glyphout( WIN_MAP );
+
+ /* Clean up */
+ glyph_node_index = glyph_buffer_index = 0;
+}
+
+/*
+ * Glyph buffering routine. Called instead of WindowPuts().
+ */
+void
+amiv_lprint_glyph(window,color_index, glyph)
+ winid window;
+ int color_index, glyph;
+{
+ int base;
+ struct amii_WinDesc *cw;
+ struct Window *w;
+ int curx;
+ int cury;
+ int tbl, icon;
+ register int xoff, yoff;
+
+ /* Get the real icon index */
+ if( glyph != NO_GLYPH )
+ 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 );
+
+ /* Get the relative offset in the page */
+
+ /* How many pixels to account for y distance down */
+ yoff = ((icon-base) / pictdata.across) * pictdata.ysize;
+
+ /* How many pixels to account for x distance across */
+ xoff = ((icon-base) % pictdata.across) * pictdata.xsize;
+ }
+
+ if(glyph >= 10000){
+ /* Run a single ASCII character out to the rastport right now */
+ char c= glyph-10000;
+ int xxx,xxy;
+ struct RastPort *rp = w->RPort;
+
+ Move(rp, xxx=(((cw->curx-clipx)*rp->TxWidth) + w->BorderLeft),
+ xxy=(w->BorderTop + (((cw->cury-clipy)+1)* rp->TxHeight)+1));
+ Text(rp,&c,1);
+ /* XXX this shouldn't be necessary: */
+ if(cw->cursx == xxx && cw->cursy == xxy){
+ cw->wflags &= ~FLMAP_CURSUP;
+ }
+ cw->curx += rp->TxWidth; /* keep things in sync */
+ return;
+ }
+
+ if( cw->type == NHW_MAP )
+ {
+ curx = cw->curx - clipx;
+ cury = cw->cury - clipy;
+
+ /* See if we're out of glyph nodes */
+ if(glyph_node_index >= NUMBER_GLYPH_NODES)
+ amiv_flush_glyph_buffer( w );
+
+ /* Fill in the node. */
+ amiv_g_nodes[glyph_node_index].dsty = min( w->BorderTop + (cury * mysize),
+ w->Height - 1 );
+
+#ifdef OPT_DISPMAP
+ if(flags.fast_map){
+#endif /* keni */
+#ifdef DISPMAP
+ /* display_map() needs byte-aligned destinations, and we don't want to
+ * overwrite the window border.
+ */
+ amiv_g_nodes[glyph_node_index].dstx =
+ (w->BorderLeft + 8 + (curx * mxsize)) & -8;
+#endif
+#ifdef OPT_DISPMAP
+} else {
+#endif
+#if !defined(DISPMAP) || defined(OPT_DISPMAP)
+ amiv_g_nodes[glyph_node_index].dstx = min( w->BorderLeft + (curx * mxsize),
+ w->Width - 1 );
+#endif
+#ifdef OPT_DISPMAP
+}
+#endif
+ amiv_g_nodes[glyph_node_index].odsty = cw->cury;
+ 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 ];
+ ++glyph_node_index;
+ }
+ else
+ {
+ /* Do it */
+ register int j, k, x, y, apen;
+ struct RastPort *rp = w->RPort;
+ x = rp->cp_x - pictdata.xsize - 3;
+#ifdef OPT_DISPMAP
+ if(flags.fast_map){
+#endif
+#ifdef DISPMAP
+ x &= -8;
+ if(x==0) x = 8;
+#endif
+#ifdef OPT_DISPMAP
+ }
+#endif
+
+ y = rp->cp_y - pictdata.ysize + 1;
+
+ if( glyph != NO_GLYPH )
+ {
+ struct BitMap *bm = ifftimg[ tbl ];
+
+ /* 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 ),
+ bm->Planes[ j ] + xoff + yoff + ( bm->BytesPerRow * k ),
+ pictdata.ysize/8 );
+ }
+ }
+
+ BltBitMapRastPort( tile, 0, 0,
+ rp, x, y,
+ pictdata.xsize, pictdata.ysize, 0xc0 );
+
+ apen = rp->FgPen;
+ SetAPen( rp, flags.amii_dripens[ SHINEPEN ] );
+ Move( rp, x-1, y + pictdata.ysize );
+ Draw( rp, x-1, y - 1 );
+ Draw( rp, x + pictdata.xsize, y - 1 );
+ SetAPen( rp, flags.amii_dripens[ SHADOWPEN ] );
+ Move( rp, x + pictdata.xsize, y );
+ Draw( rp, x + pictdata.xsize, y + pictdata.ysize );
+ Draw( rp, x, y + pictdata.ysize );
+ SetAPen( rp, apen );
+ }
+ else if( x > w->BorderLeft )
+ {
+ int apen, bpen;
+ apen = rp->FgPen;
+ bpen = rp->BgPen;
+ SetAPen( rp, amii_menuBPen );
+ SetBPen( rp, amii_menuBPen );
+ RectFill( rp, x-1, y-1, x + pictdata.xsize, y + pictdata.ysize );
+ SetAPen( rp, apen );
+ SetBPen( rp, bpen );
+ }
+ }
+}
+
+/*
+ * Define some variables which will be used to save context when toggling
+ * back and forth between low level text and console I/O.
+ */
+static long xsave, ysave, modesave, apensave, bpensave;
+static int usecolor;
+
+/*
+ * The function is called before any glyphs are driven to the screen. It
+ * removes the cursor, saves internal state of the window, then returns.
+ */
+
+void
+amiv_start_glyphout(window)
+ winid window;
+{
+ struct amii_WinDesc *cw;
+ struct Window *w;
+
+ if( ( cw=amii_wins[window] ) == (struct amii_WinDesc *)NULL )
+ panic( "bad winid %d in start_glyphout()", window );
+
+ if( cw->wflags & FLMAP_INGLYPH )
+ return;
+
+ if( !(w = cw->win ) )
+ panic( "bad winid %d, no window ptr set", window );
+
+ /*
+ * Save the context of the window
+ */
+ xsave = w->RPort->cp_x;
+ ysave = w->RPort->cp_y;
+ modesave = w->RPort->DrawMode;
+ apensave = w->RPort->FgPen;
+ bpensave = w->RPort->BgPen;
+
+ /*
+ * Set the mode, and be done with it
+ */
+ usecolor = iflags.use_color;
+ iflags.use_color = FALSE;
+ cw->wflags |= FLMAP_INGLYPH;
+}
+
+/*
+ * General cleanup routine -- flushes and restores cursor
+ */
+void
+amii_end_glyphout(window)
+ winid window;
+{
+ struct amii_WinDesc *cw;
+ struct Window *w;
+
+ if( ( cw = amii_wins[ window ] ) == (struct amii_WinDesc *)NULL )
+ panic("bad window id %d in amii_end_glyphout()", window );
+
+ if( ( cw->wflags & FLMAP_INGLYPH ) == 0 )
+ return;
+ cw->wflags &= ~(FLMAP_INGLYPH);
+
+ if( !(w = cw->win ) )
+ panic( "bad winid %d, no window ptr set", window );
+
+ /*
+ * Clean up whatever is left in the buffer
+ */
+ iflags.use_color = usecolor;
+
+ /*
+ * Reset internal data structs
+ */
+ SetAPen(w->RPort, apensave);
+ SetBPen(w->RPort, bpensave);
+ SetDrMd(w->RPort, modesave);
+
+ Move(w->RPort, xsave, ysave);
+}
+
+static maze_type=COL_MAZE_BRICK;
+
+void SetMazeType(MazeType t)
+{
+ maze_type=t;
+}
+
+int GlyphToIcon(int glyph)
+{
+ if(glyph>10000)return glyph;
+ return( glyph2tile[glyph] );
+}
+#endif
+
+#ifdef AMII_GRAPHICS
+# ifdef TESTING
+/*
+ * Define some stuff for our special glyph drawing routines
+ */
+static unsigned short glyph_node_index, glyph_buffer_index;
+# define NUMBER_GLYPH_NODES 80
+# define GLYPH_BUFFER_SIZE 512
+# endif /* TESTING */
+
+struct amii_glyph_node {
+ short x;
+ short y;
+ short len;
+ unsigned char bg_color;
+ unsigned char fg_color;
+ char *buffer;
+};
+static struct amii_glyph_node amii_g_nodes[NUMBER_GLYPH_NODES];
+static char amii_glyph_buffer[GLYPH_BUFFER_SIZE];
+
+#ifdef TEXTCOLOR
+/*
+ * Map our amiga-specific colormap into the colormap specified in color.h.
+ * See winami.c for the amiga specific colormap.
+ */
+
+int foreg[AMII_MAXCOLORS] = { 0, 7, 4, 2, 6, 5, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
+int backg[AMII_MAXCOLORS] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 1, 6, 5, 3, 1 };
+#if 0
+ #define CLR_BLACK 0
+ #define CLR_RED 1
+ #define CLR_GREEN 2
+ #define CLR_BROWN 3 /* on IBM, low-intensity yellow is brown */
+ #define CLR_BLUE 4
+ #define CLR_MAGENTA 5
+ #define CLR_CYAN 6
+ #define CLR_GRAY 7 /* low-intensity white */
+ #define NO_COLOR 8
+ #define CLR_ORANGE 9
+ #define CLR_BRIGHT_GREEN 10
+ #define CLR_YELLOW 11
+ #define CLR_BRIGHT_BLUE 12
+ #define CLR_BRIGHT_MAGENTA 13
+ #define CLR_BRIGHT_CYAN 14
+ #define CLR_WHITE 15
+ #define CLR_MAX 16
+#endif
+#endif
+
+#ifndef TESTING
+/*
+ * Begin Revamped Text display routines
+ *
+ * Up until version 3.1, the only method for displaying text on the playing
+ * field was by using the console.device. This was nice for a number of
+ * reasons, the most signifigant of which was a lot of the nuts and bolts was
+ * done for you via escape sequences interpreted by said device. This did
+ * not come without a price however. And that price was speed. It has now
+ * come to a point where the speed has now been deemed unacceptable.
+ *
+ * The following series of routines are designed to drop into the current
+ * nethack display code, using hooks provided for such a measure. It works
+ * on similar principals as the WindowPuts(), buffering I/O internally
+ * until either an explicit flush or internal buffering is exceeded, thereby
+ * forcing the flush. The output (or glyphs) does not go to the
+ * console.device, however. It is driven directly to the rasterport of the
+ * nethack window via the low-level Text() calls, increasing the speed by
+ * a very signifigant factor.
+ */
+/*
+ * Routine to simply flush whatever is buffered
+ */
+void
+amii_flush_glyph_buffer( w )
+ struct Window *w;
+{
+ short i, x, y;
+ register struct RastPort *rp = w->RPort;
+
+ /* If nothing is buffered, return before we do anything */
+ if(glyph_node_index == 0)
+ return;
+
+ cursor_off( WIN_MAP );
+ amii_start_glyphout( WIN_MAP );
+
+ /* Set up the drawing mode */
+ SetDrMd( rp, JAM2);
+
+ /* Go ahead and start dumping the stuff */
+ for(i=0; iBorderTop + (amii_g_nodes[i].y-2) * rp->TxHeight +
+ rp->TxBaseline + 1;
+ x = amii_g_nodes[i].x * rp->TxWidth + w->BorderLeft;
+
+ /* Move pens to correct location */
+ Move( rp, (long)x, (long)y);
+
+ /* Setup the colors */
+ SetAPen( rp, (long)amii_g_nodes[i].fg_color);
+ SetBPen( rp, (long)amii_g_nodes[i].bg_color);
+
+ /* Do it */
+ Text( rp, amii_g_nodes[i].buffer, amii_g_nodes[i].len);
+ }
+
+ amii_end_glyphout( WIN_MAP );
+ /* Clean up */
+ glyph_node_index = glyph_buffer_index = 0;
+}
+void
+amiga_print_glyph(window,color_index, glyph)
+ winid window;
+ int color_index, glyph;
+{
+ if( WINVERS_AMIV )
+ amiv_lprint_glyph(window,color_index, glyph);
+ else
+ amii_lprint_glyph(window,color_index, glyph);
+}
+
+/*
+ * Glyph buffering routine. Called instead of WindowPuts().
+ */
+void
+amii_lprint_glyph(window,color_index, glyph)
+ winid window;
+ int color_index, glyph;
+{
+ int fg_color, bg_color;
+ struct amii_WinDesc *cw;
+ struct Window *w;
+ int curx;
+ int cury;
+
+ if( ( cw=amii_wins[window] ) == (struct amii_WinDesc *)NULL )
+ panic("bad winid in amii_lprint_glyph: %d", window );
+
+ w = cw->win;
+ curx=cw->curx;
+ cury=cw->cury;
+
+#ifdef TEXTCOLOR
+ fg_color = foreg[color_index];
+ bg_color = backg[color_index];
+#else
+ fg_color = 1;
+ bg_color = 0;
+#endif /* TEXTCOLOR */
+
+ /* See if we have enough character buffer space... */
+ if(glyph_buffer_index >= GLYPH_BUFFER_SIZE)
+ amii_flush_glyph_buffer( w );
+
+ /*
+ * See if we can append it to the current active node of glyph buffer. It
+ * must satisfy the following conditions:
+ *
+ * * background colors are the same, AND
+ * * foreground colors are the same, AND
+ * * they are precisely side by side
+ */
+ if((glyph_buffer_index != 0) &&
+ (fg_color == amii_g_nodes[glyph_node_index-1].fg_color) &&
+ (bg_color == amii_g_nodes[glyph_node_index-1].bg_color) &&
+ (amii_g_nodes[glyph_node_index-1].x+
+ amii_g_nodes[glyph_node_index-1].len == curx) &&
+ (amii_g_nodes[glyph_node_index-1].y == cury)) {
+ /*
+ * Add it to the end of the buffer
+ */
+ amii_glyph_buffer[glyph_buffer_index++] = glyph;
+ amii_g_nodes[glyph_node_index-1].len ++;
+ } else {
+ /* See if we're out of glyph nodes */
+ if(glyph_node_index >= NUMBER_GLYPH_NODES)
+ amii_flush_glyph_buffer( w );
+ amii_g_nodes[glyph_node_index].len = 1;
+ amii_g_nodes[glyph_node_index].x = curx;
+ amii_g_nodes[glyph_node_index].y = cury;
+ amii_g_nodes[glyph_node_index].fg_color = fg_color;
+ amii_g_nodes[glyph_node_index].bg_color = bg_color;
+ amii_g_nodes[glyph_node_index].buffer = &amii_glyph_buffer[glyph_buffer_index];
+ amii_glyph_buffer[glyph_buffer_index] = glyph;
+ ++glyph_buffer_index;
+ ++glyph_node_index;
+ }
+}
+#endif /* !TESTING */
+
+#ifdef TESTING
+/*
+ * Define some variables which will be used to save context when toggling
+ * back and forth between low level text and console I/O.
+ */
+static long xsave, ysave, modesave, apensave, bpensave;
+static int usecolor;
+#endif /* TESTING */
+
+#ifndef TESTING
+/*
+ * The function is called before any glyphs are driven to the screen. It
+ * removes the cursor, saves internal state of the window, then returns.
+ */
+
+void
+amii_start_glyphout(window)
+ winid window;
+{
+ struct amii_WinDesc *cw;
+ struct Window *w;
+
+ if( ( cw=amii_wins[window] ) == (struct amii_WinDesc *)NULL )
+ panic( "bad winid %d in start_glyphout()", window );
+
+ if( cw->wflags & FLMAP_INGLYPH )
+ return;
+
+ if( !(w = cw->win ) )
+ panic( "bad winid %d, no window ptr set", window );
+
+ /*
+ * Save the context of the window
+ */
+ xsave = w->RPort->cp_x;
+ ysave = w->RPort->cp_y;
+ modesave = w->RPort->DrawMode;
+ apensave = w->RPort->FgPen;
+ bpensave = w->RPort->BgPen;
+
+ /*
+ * Set the mode, and be done with it
+ */
+ usecolor = iflags.use_color;
+ iflags.use_color = FALSE;
+ cw->wflags |= FLMAP_INGLYPH;
+}
+#endif /* !TESTING */
+
+# if 0
+/*
+ * General cleanup routine -- flushes and restores cursor
+ */
+void
+amii_end_glyphout(window)
+ winid window;
+{
+ struct amii_WinDesc *cw;
+ struct Window *w;
+
+ if( ( cw = amii_wins[ window ] ) == (struct amii_WinDesc *)NULL )
+ panic("bad window id %d in amii_end_glyphout()", window );
+
+ if( ( cw->wflags & FLMAP_INGLYPH ) == 0 )
+ return;
+ cw->wflags &= ~(FLMAP_INGLYPH);
+
+ if( !(w = cw->win ) )
+ panic( "bad winid %d, no window ptr set", window );
+
+ /*
+ * Clean up whatever is left in the buffer
+ */
+ iflags.use_color = usecolor;
+
+ /*
+ * Reset internal data structs
+ */
+ SetAPen(w->RPort, apensave);
+ SetBPen(w->RPort, bpensave);
+ SetDrMd(w->RPort, modesave);
+
+ Move(w->RPort, xsave, ysave);
+}
+# endif
+#endif
+
+#ifndef TESTING
+# ifdef OPT_DISPMAP
+/* don't use dispmap unless x & y are 8,16,24,32,48 and equal */
+void
+dispmap_sanity(){
+ if(
+ mxsize != mysize ||
+ dispmap_sanity1(mxsize) ||
+ dispmap_sanity1(mysize)){
+ flags.fast_map = 0;
+ }
+}
+int
+dispmap_sanity1(x)
+ int x;
+{
+ static unsigned char valid[] = {8,16,24,32,48,0};
+ return !!strchr(valid,x);
+}
+# endif /* OPT_DISPMAP */
+#endif /* TESTING */
diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h
new file mode 100644
index 0000000..af017be
--- /dev/null
+++ b/sys/amiga/windefs.h
@@ -0,0 +1,203 @@
+/* SCCS Id: @(#)windefs.h 3.1 93/04/02 */
+/* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include
+#include
+#include
+#if !defined(_DCC) && !defined(__GNUC__)
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+/* stddef.h is included in the precompiled version of hack.h . If we include
+ * it here normally (through string.h) we'll get an "illegal typedef" later
+ * on. This is the easiest way I can think of to fix it without messing
+ * around with the rest of the #includes. --AMC
+ */
+#if defined(_DCC) && !defined(HACK_H)
+# define ptrdiff_t ptrdiff_t_
+# define size_t size_t_
+# define wchar_t wchar_t_
+#endif
+#include
+#undef strcmpi
+#include
+#include
+#if defined(_DCC) && !defined(HACK_H)
+# undef ptrdiff_t
+# undef size_t
+# undef wchar_T
+#endif
+
+#ifdef IDCMP_CLOSEWINDOW
+# ifndef INTUI_NEW_LOOK
+# define INTUI_NEW_LOOK
+# endif
+#endif
+
+#ifndef HACK_H
+#include "hack.h"
+#endif
+#include "wintype.h"
+#include "winami.h"
+#include "func_tab.h"
+
+#ifndef CLIPPING
+CLIPPING must be defined for the AMIGA version
+#endif
+
+#undef LI
+#undef CO
+
+/*#define TOPL_GETLINE /* Don't use a window for getlin() */
+/*#define WINDOW_YN /* Use a window for y/n questions */
+
+#ifdef AZTEC_C
+#include
+#else
+#ifdef _DCC
+#include
+#include
+#include
+#include
+#include
+#include
+#else
+#include
+#include
+#include