home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 4 / CDPD_IV.bin / fish / 931-950 / ff944 / blocked / blocked.c < prev    next >
C/C++ Source or Header  |  1993-12-22  |  29KB  |  1,212 lines

  1. /*
  2.  *    Copyright (C) 1989 Andrew Kemmis
  3.  *
  4.  *    All Rights Reserved
  5.  *
  6.  *    Date:    Mar 1989
  7.  */
  8. #define  AK___CRYPT
  9.  
  10. #include <ak/stdak.h>
  11.  
  12. char    Program_name[]    = "BlockEd";
  13. int    Version     = CRYPTNUM(1);
  14. int    MinorVer    = CRYPTNUM(4);
  15. char    Date[]        = "Oct 1993";
  16. char    CRDate[]    = "1989-93";
  17.  
  18. #include <ak/err.h>
  19. #include <ak/err_num.h>
  20. #include <ak/pool.h>
  21. #include <ak/dev.h>
  22. #include <ak/dos.h>
  23. #include <ak/menu.h>
  24. #include <ak/gad.h>
  25. #include <ak/filesystem.h>
  26. #include <ak/rawkey.h>
  27. #include <intuition/intuition.h>
  28. #include <graphics/gfxbase.h>
  29. #include <ctype.h>
  30.  
  31. #include "blocked.qi"
  32.  
  33. #define STRINGJUST    (Hex ? STRINGCENTER : (Left ? 0L : STRINGRIGHT))
  34.  
  35. #define INTUITION_MESSAGE    (1L<<MyWin->UserPort->mp_SigBit)
  36.  
  37. extern    char    *strchr();
  38. extern    char    *strrchr();
  39. extern    struct    Window    *OpenWindow();
  40. extern    struct    Screen    *OpenScreen();
  41. extern    struct    IntuiMessage    *GetMsg();
  42. extern    struct    MenuItem    *ItemAddress();
  43. extern    struct    TextFont    *OpenDiskFont();
  44. extern    LONG    Wait();
  45. extern    void    *AllocMem();
  46.  
  47. int    cli;
  48.  
  49. struct    IBASE    *IBASE = (struct IBASE *)NULL;
  50. struct    GfxBase *GfxBase = (struct GfxBase *)NULL;
  51. struct    Library *DiskfontBase = (struct Library *)NULL;
  52.  
  53. Static    struct    AkMenu    AkMenu = AKMENUINIT;
  54. Static    struct    TextFont    *Opal = (struct TextFont *)NULL;
  55. Static    struct    TextAttr    OpalAttr = { (STRPTR)NULL, 0, 0, 0 };   /* Setup in main */
  56. Static    UWORD    FXSize;
  57. Static    UWORD    FYSize;
  58. Static    UWORD    FYBase;
  59. Static    int    Inhibited = 0;
  60. Static    struct    AkGad    AkGad = AKGADINIT;
  61. Static    struct    Gadget    *BlkGad;
  62. Static    struct    Gadget    *DirGad;
  63. Static    struct    Gadget    *NumGad;
  64.  
  65. Static    char    *Device;
  66.  
  67. Static    struct    AkDevStuff    Stuff = DEVSTUFFINIT;
  68. Static    ulong    TheBlock;
  69. Static    char    TheBlockBuf[10+1];
  70. Static    ulong    CurBlock = 0;
  71. Static    ulong    *Buffer;
  72. Static    ulong    *Buffer2;
  73. Static    uchar    *BufPtr;
  74. Static    long    Dev = -1;
  75. Static    int    LongPos = 0;
  76. Static    int    BytePos = 0;
  77. Static    struct    Menu    *ProjectMenu;
  78. Static    struct    MenuItem    *RestoreItem;
  79. Static    struct    RastPort    *rp;
  80. Static    char    DirBuf[FILENAMELENGTH+1];
  81. Static    char    NumBuf[10+1];
  82.  
  83. #define EDIT_NO     0
  84. #define EDIT_YES    1
  85.  
  86. Static    int    Edit = EDIT_NO;
  87.  
  88. #define MENUFLAGS    (USHORT)MENUENABLED
  89.  
  90. #define ITEMFLAGS    (USHORT)(ITEMTEXT | COMMSEQ | HIGHBOX)
  91. #define MOREITEMFLAGS    (USHORT)(ITEMENABLED | ITEMFLAGS)
  92. #define EXTRAITEMFLAGS    (USHORT)(CHECKIT | MENUTOGGLE | MOREITEMFLAGS)
  93.  
  94. Static    struct    PoolKey GenPoolKey;
  95.  
  96. Static    struct    Screen    *MyScreen = (struct Screen *)NULL;
  97. Static    struct    NewScreen    MyNewScreen =
  98. {
  99.     0,    0,    640,    330,    2,
  100.     0,    1,
  101.     LACE | SPRITES | HIRES,
  102.     CUSTOMSCREEN | SCREENBEHIND | BEEPING,
  103.     &OpalAttr,
  104.     (UBYTE *)Program_name,
  105.     (struct Gadget *)NULL,
  106.     (struct BitMap *)NULL
  107. };
  108.  
  109. Static    struct    Window    *MyWin = (struct Window *)NULL;
  110. Static    struct    NewWindow    MyNewWin =
  111. {
  112.     0, 7,
  113.     640, 323,
  114.     -1, -1,
  115.     MENUVERIFY | MOUSEBUTTONS | GADGETDOWN | GADGETUP | MENUPICK | CLOSEWINDOW | RAWKEY,
  116.     WINDOWCLOSE | SMART_REFRESH | REPORTMOUSE | NOCAREREFRESH | ACTIVATE,
  117.     (struct Gadget *)NULL,
  118.     (struct Image *)NULL,
  119.     (UBYTE *)Program_name,
  120.     (struct Screen *)NULL,
  121.     (struct BitMap *)NULL,
  122.     0, 0, 0, 0,
  123.     CUSTOMSCREEN
  124. };
  125.  
  126. #define MoveTo(x, y)    Move(rp, (long)(x), (long)(y))
  127. #define TextTo(s, n)    Text(rp, (s), (long)(n))
  128.  
  129. Static send(str, x, y, len)
  130. REG    char    *str;
  131. REG    int    x;
  132. REG    int    y;
  133. REG    int    len;
  134. {
  135.     MoveTo(x, y);
  136.     TextTo(str, len);
  137. }
  138.  
  139. #define DSP_BIG     1
  140. #define DSP_MEDIUM    2
  141. #define DSP_TINY    4
  142.  
  143. Static display_num(x, y, num, size, buf)
  144. REG    int    x;
  145. REG    int    y;
  146. REG    ulong    num;
  147. int    size;
  148. char    *buf;
  149. {
  150.     static    char    Str[11];
  151.     REG    int    hex;
  152.     REG    int    dec;
  153.  
  154.     switch (size)
  155.     {
  156.     case DSP_BIG:
  157.         hex = 8;
  158.         dec = 10;
  159.         break;
  160.     case DSP_MEDIUM:
  161.         hex = 4;
  162.         dec = 6;
  163.         break;
  164.     case DSP_TINY:
  165.         hex = 2;
  166.         dec = 4;
  167.         break;
  168.     }
  169.  
  170.     if (!buf)
  171.     {    if (Hex)
  172.             sprintf(Str, " %0*lx ", hex, num);
  173.         else
  174.             if (Left)
  175.                 sprintf(Str, "%-*lu", dec, num);
  176.             else
  177.                 sprintf(Str, "%*lu", dec, num);
  178.  
  179.         send(Str, x, y, dec);
  180.     }
  181.     else
  182.     {    if (Hex)
  183.             sprintf(buf, "%0*lx", hex, num);
  184.         else
  185.             sprintf(buf, "%lu", num);
  186.     }
  187. }
  188.  
  189. #define NXTIMES ((FXSize * 10) + 4)
  190. #define NYTIMES FYSize
  191. #define AXTIMES FXSize
  192. #define AYTIMES FYSize
  193. #define NXPLUS    7
  194. #define NYPLUS    (FYSize * 4)
  195. #define AXPLUS    ((FXSize * 42) + 6)
  196. #define AYPLUS    (FYSize * 4)
  197.  
  198. #define ACTIVE    1
  199. #define BACKGR    0
  200.  
  201. Static display_pos(pos, active)
  202. REG    int    pos;
  203. REG    int    active;
  204. {
  205.     REG    int    xn;
  206.     REG    int    xs;
  207.     REG    int    y;
  208.     REG    uchar    ptr[4];
  209.     int    i;
  210.  
  211.     for (i = (ByteMove ? 0 : 3); i >= 0; i--)
  212.         if (isprint(BufPtr[i+pos]))
  213.             ptr[i] = BufPtr[i+pos];
  214.         else
  215.             ptr[i] = NullChar;
  216.  
  217.     xn = (pos / 4) % 4;
  218.     xs = pos % 16;
  219.     y = pos / 16;
  220.  
  221.     if (active == ACTIVE)
  222.     {    SetAPen(rp, SelectPen);
  223.         SetBPen(rp, OtherPen);
  224.     }
  225.     else
  226.     {    SetAPen(rp, DataPen);
  227.         SetBPen(rp, BackPen);
  228.     }
  229.  
  230.     display_num(xn * NXTIMES + NXPLUS, y * NYTIMES + NYPLUS, Buffer[pos/4], DSP_BIG, NULL);
  231.  
  232.     send(ptr, xs * AXTIMES + AXPLUS, y * AYTIMES + AYPLUS, ByteMove ? 1 : 4);
  233. }
  234.  
  235. #define PT_STR    0
  236. #define PT_NUM    1
  237. #define PT_BUF    2
  238. #define PT_PTR    3
  239. #define PT_NPT    4
  240. #define PT_DEV    5
  241. #define PT_LON    6
  242. #define PT_BYT    7
  243. #define PT_SAV    8
  244. #define PT_END    9
  245.  
  246. #define DRAW_ONCE_ONLY        1
  247. #define DRAW_EACH_BLOCK     2
  248. #define DRAW_EACH_CHECKSUM    4
  249. #define DRAW_EACH_MOVE        8
  250. #define DRAW_MARK_EDIT        16
  251. #define DRAW_UNMARK_EDIT    32
  252.  
  253. #define BLKGAD_SAV    0L
  254. #define DIRGAD_SAV    1L
  255. #define MAX_SAV     1L
  256.  
  257. Static    struct
  258. {    int    x;
  259.     int    y;
  260. } saves[MAX_SAV+1];
  261.  
  262. Static draw_page(often)
  263. REG    int    often;
  264. {
  265.     static struct ScrDat
  266.     {    char    *str;
  267.         int    often;
  268.         int    reset;
  269.         int    xt;
  270.         int    xa;
  271.         int    yt;
  272.         int    ya;
  273.         int    type;
  274.         long    *pen;
  275.     } Page[] =
  276.     {
  277.     "Offset",               1,      1,      1,      2,      2,      4,      PT_STR, &DataPen,
  278.     "O",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  279.     (char *)BLKGAD_SAV,     1,      0,      7,      0,      0,      0,      PT_SAV, NULL,
  280.  
  281.     "Long",                 1,      0,      16,     0,      0,      0,      PT_STR, &DataPen,
  282.     (char *)&LongPos,       10,     0,      5,      0,      0,      0,      PT_LON, &SelectPen,
  283.  
  284.     "Byte",                 1,      0,      11,     0,      0,      0,      PT_STR, &DataPen,
  285.     (char *)&BytePos,       10,     0,      5,      0,      0,      0,      PT_BYT, &SelectPen,
  286.  
  287.     "Root",                 1,      0,      14,     4,      0,      0,      PT_STR, &OtherPen,
  288.     "R",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  289.     (char *)&Stuff.Info.Root, 3,    0,      10,     -4,     0,      0,      PT_NUM, &DataPen,
  290.  
  291.     "Parent",               1,      0,      -10,    4,      1,      4,      PT_STR, &OtherPen,
  292.     "P",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  293.     (char *)POS_PAR,        3,      0,      10,     -4,     0,      0,      PT_BUF, &DataPen,
  294.     "Key",                  1,      0,      -10,    4,      1,      0,      PT_STR, &OtherPen,
  295.     "K",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  296.     (char *)POS_KEY,        3,      0,      10,     -4,     0,      0,      PT_BUF, &DataPen,
  297.     "HashChain",            1,      0,      -10,    4,      1,      0,      PT_STR, &OtherPen,
  298.     "H",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  299.     (char *)POS_HASH_CH,    3,      0,      10,     -4,     0,      0,      PT_BUF, &DataPen,
  300.     "Extension",            1,      0,      -10,    4,      1,      0,      PT_STR, &OtherPen,
  301.     "E",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  302.     (char *)POS_EXT,        3,      0,      10,     -4,     0,      0,      PT_BUF, &DataPen,
  303.     "FirstData",            1,      0,      -10,    4,      1,      0,      PT_STR, &OtherPen,
  304.     "F",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  305.     (char *)POS_FST_DAT,    3,      0,      10,     -4,     0,      0,      PT_BUF, &DataPen,
  306.     "NextData",             1,      0,      -10,    4,      1,      0,      PT_STR, &OtherPen,
  307.     "N",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  308.     (char *)POS_D_NXT_DAT,  3,      0,      10,     -4,     0,      0,      PT_BUF, &DataPen,
  309.     "CheckSum",             1,      0,      -10,    4,      1,      0,      PT_STR, &OtherPen,
  310.     "C",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  311.     (char *)POS_CHKSUM,     3,      0,      10,     -4,     0,      0,      PT_BUF, &DataPen,
  312.  
  313.     "+/= Advance One",      1,      0,      -10,    4,      1,      4,      PT_STR, &OtherPen,
  314.     "+/=",                  1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  315.     "+/",                   1,      0,      0,      0,      0,      0,      PT_STR, &OtherPen,
  316.     "+",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  317.     "-/_ Retreat One",      1,      0,      0,      0,      1,      0,      PT_STR, &OtherPen,
  318.     "-/_",                  1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  319.     "-/",                   1,      0,      0,      0,      0,      0,      PT_STR, &OtherPen,
  320.     "-",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  321.     "Goto Current",         1,      0,      0,      0,      1,      0,      PT_STR, &OtherPen,
  322.     "G",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  323.     "Zero Goto",            1,      0,      0,      0,      1,      0,      PT_STR, &OtherPen,
  324.     "Z",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  325.     "ALT-ReRead",           1,      0,      0,      0,      1,      4,      PT_STR, &OtherPen,
  326.     "ALT-R",                1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  327.     "ALT-Update",           1,      0,      0,      0,      1,      0,      PT_STR, &OtherPen,
  328.     "ALT-U",                1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  329.     "*",                    16,     0,      -1,     0,      1,      4,      PT_STR, &SelectPen,
  330.     "*",                    32,     0,      0,      0,      0,      0,      PT_STR, &BackPen,
  331.     "Ascii/Number Edit",    1,      0,      1,      0,      0,      0,      PT_STR, &OtherPen,
  332.     "A",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  333.     "Spread Current",       1,      0,      0,      0,      1,      0,      PT_STR, &OtherPen,
  334.     "S",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  335.     "Byte/Long Move",       1,      0,      0,      0,      1,      4,      PT_STR, &OtherPen,
  336.     "B",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  337.     "Mode Hex/Dec",         1,      0,      0,      0,      1,      0,      PT_STR, &OtherPen,
  338.     "M",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  339.     "Justify Left/Right",   1,      0,      0,      0,      1,      0,      PT_STR, &OtherPen,
  340.     "J",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  341.  
  342.     "Driver",               1,      0,      0,      0,      1,      4,      PT_STR, &OtherPen,
  343.     (char *)&Stuff.Info.dname, 1,   0,      7,      0,      0,      0,      PT_DEV, &DataPen,
  344.     "Unit",                 1,      0,      -7,     0,      1,      0,      PT_STR, &OtherPen,
  345.     (char *)&Stuff.Info.unit, 1,    0,      11,     0,      0,      0,      PT_NPT, &DataPen,
  346.     "Device",               1,      0,      -11,    0,      1,      0,      PT_STR, &OtherPen,
  347.     (char *)&Stuff.Info.name, 1,    0,      11,     0,      0,      0,      PT_PTR, &DataPen,
  348.     "LowCyl",               1,      0,      -11,    0,      1,      0,      PT_STR, &OtherPen,
  349.     (char *)&Stuff.Info.lowcyl, 1,  0,      11,     0,      0,      0,      PT_NPT, &DataPen,
  350.     "HiCyl",                1,      0,      -11,    0,      1,      0,      PT_STR, &OtherPen,
  351.     (char *)&Stuff.Info.hicyl, 1,   0,      11,     0,      0,      0,      PT_NPT, &DataPen,
  352.     "Heads",                1,      0,      -11,    0,      1,      0,      PT_STR, &OtherPen,
  353.     (char *)&Stuff.Info.heads, 1,   0,      11,     0,      0,      0,      PT_NPT, &DataPen,
  354.     "BlksPerTrk",           1,      0,      -11,    0,      1,      0,      PT_STR, &OtherPen,
  355.     (char *)&Stuff.Info.bpt, 1,     0,      11,     0,      0,      0,      PT_NPT, &DataPen,
  356.     "Reserved",             1,      0,      -11,    0,      1,      0,      PT_STR, &OtherPen,
  357.     (char *)&Stuff.Info.res, 1,     0,      11,     0,      0,      0,      PT_NPT, &DataPen,
  358.  
  359.     "Directory/Filename",   1,      0,      -11,    0,      1,      4,      PT_STR, &OtherPen,
  360.     "D",                    1,      0,      0,      0,      0,      0,      PT_STR, &SelectPen,
  361.     (char *)DIRGAD_SAV,     1,      0,      0,      0,      1,      4,      PT_SAV, NULL,
  362.  
  363.     NULL,            0,    0,    0,    0,    0,    0,    PT_END
  364.     };
  365.     REG    struct    ScrDat    *ScrPtr = Page;
  366.     REG    int    x;
  367.     REG    int    y;
  368.     REG    long    pen = -1;
  369.     char    NBuf[9];
  370.     char    *ptr;
  371.     char    *str;
  372.  
  373.     SetBPen(rp, BackPen);
  374.  
  375.     while (ScrPtr->type != PT_END)
  376.     {    if (ScrPtr->reset)
  377.             (x = 0), (y = 0);
  378.  
  379.         x += (ScrPtr->xt * FXSize + ScrPtr->xa);
  380.         y += (ScrPtr->yt * FYSize + ScrPtr->ya);
  381.  
  382.         if (ScrPtr->often & often)
  383.         {    if (pen != *(ScrPtr->pen))
  384.             {    pen = *(ScrPtr->pen);
  385.                 SetAPen(rp, pen);
  386.             }
  387.             switch(ScrPtr->type)
  388.             {
  389.             case PT_STR:
  390.                 send(ScrPtr->str, x, y, strlen(ScrPtr->str));
  391.                 break;
  392.             case PT_NUM:
  393.                 display_num(x, y, *(ulong *)(ScrPtr->str), DSP_BIG, NULL);
  394.                 break;
  395.             case PT_BUF:
  396.                 display_num(x, y, Buffer[(long)(ScrPtr->str)], DSP_BIG, NULL);
  397.                 break;
  398.             case PT_PTR:
  399.                 send(*(char **)(ScrPtr->str), x, y, strlen(*(char **)(ScrPtr->str)));
  400.                 break;
  401.             case PT_NPT:
  402.                 sprintf(NBuf, "%ld", *(ulong *)(ScrPtr->str));
  403.                 send(NBuf, x, y, strlen(NBuf));
  404.                 break;
  405.             case PT_DEV:
  406.                 str = *(char **)(ScrPtr->str);
  407.                 ptr = strrchr(str, '.');
  408.                 if (!ptr)
  409.                     ptr = strchr(str, '\0');
  410.  
  411.                 send(str, x, y, ptr - str);
  412.                 break;
  413.             case PT_BYT:
  414.                 display_num(x, y, (ulong)(*(int *)(ScrPtr->str)), DSP_MEDIUM, NULL);
  415.                 break;
  416.             case PT_LON:
  417.                 display_num(x, y, (ulong)(*(int *)(ScrPtr->str)), DSP_TINY, NULL);
  418.                 break;
  419.             case PT_SAV:
  420.                 saves[(long)(ScrPtr->str)].x = x;
  421.                 saves[(long)(ScrPtr->str)].y = y;
  422.             }
  423.         }
  424.         ScrPtr++;
  425.     }
  426.  
  427.     if (often & DRAW_EACH_BLOCK)
  428.         BlkGadRefresh();
  429. }
  430.  
  431. Static    int    NotBeenHere = !0;
  432.  
  433. Static display_block()
  434. {
  435.     REG    int    x;
  436.     REG    int    y;
  437.     REG    ulong    *Buf = Buffer;
  438.     REG    uchar    *Ptr = BufPtr;
  439.     char    Str[20];
  440.  
  441.     if (NotBeenHere)
  442.     {    NotBeenHere = 0;
  443.         draw_page(DRAW_ONCE_ONLY);      /* Fills in saves[] */
  444.  
  445.         add_gadgets();
  446.     }
  447.  
  448.     draw_page(DRAW_EACH_BLOCK);
  449.  
  450.     SetAPen(rp, DataPen);
  451.     SetBPen(rp, BackPen);
  452.  
  453.     for (y = 0; y < 32; y++)
  454.     {    for (x = 0; x < 4; x++)
  455.         {    display_num(x * NXTIMES + NXPLUS, y * NYTIMES + NYPLUS, *Buf, DSP_BIG, NULL);
  456.             Buf++;
  457.         }
  458.         for (x = 0; x < 16; x++)
  459.         {    send(isprint(*Ptr) ? Ptr : &((uchar)NullChar),
  460.                 x * AXTIMES + AXPLUS, y * AYTIMES + AYPLUS, 1);
  461.             Ptr++;
  462.         }
  463.     }
  464.     display_pos(BytePos, ACTIVE);
  465. }
  466.  
  467. Static read(ignore)
  468. REG    int    ignore;
  469. {
  470.     REG    ulong    l = TheBlock;
  471.     REG    LONG    ret;
  472.  
  473.     if (l != CurBlock || ignore)
  474.     {    if (l < 0 || l > (Stuff.Info.End - Stuff.Info.Begin))
  475.         {    sprintf(err_buf,
  476.                 "Invalid block Min = 0 Max = %lu (0x%08lx)",
  477.                 Stuff.Info.End - Stuff.Info.Begin,
  478.                 Stuff.Info.End - Stuff.Info.Begin);
  479.             WinMistake(MyWin, err_buf);
  480.             EnableRestore();
  481.             TheBlock = CurBlock;
  482.         }
  483.         else
  484.         {    AkMotorOn(&Stuff);
  485.             ret = AkDevRead(l + Stuff.Info.Begin, Buffer, &Stuff, BLOCK_SIZE);
  486.             AkMotorOff(&Stuff);
  487.  
  488.             if (ret != 0)
  489.             {    sprintf(err_buf, "Read Failed Status = 0x%lx (IoErr - 0x%lx)", ret, IoErr());
  490.                 WinMistake(MyWin, err_buf);
  491.                 EnableRestore();
  492.                 TheBlock = CurBlock;
  493.                 if (NotBeenHere)
  494.                     display_block();
  495.             }
  496.             else
  497.             {    CurBlock = l;
  498.                 display_block();
  499.             }
  500.         }
  501.     }
  502. }
  503.  
  504. Static Update()
  505. {
  506.     REG    ulong    lb = TheBlock + Stuff.Info.Begin;
  507.     REG    LONG    ret;
  508.  
  509.     AkMotorOn(&Stuff);
  510.     ret = AkDevRead(lb, Buffer2, &Stuff, BLOCK_SIZE);
  511.  
  512.     if (ret != 0)
  513.     {    sprintf(err_buf, "Read for Update Failed Status = 0x%lx (IoErr - 0x%lx)", ret, IoErr());
  514.         WinMistake(MyWin, err_buf);
  515.         EnableRestore();
  516.     }
  517.     else
  518.     {    for (ret = 0; ret < LBlockSize; ret++)
  519.             if (Buffer[ret] != Buffer2[ret])
  520.             {    ret = AkDevWrite(lb, Buffer, &Stuff, BLOCK_SIZE);
  521.                 if (ret != 0)
  522.                 {    sprintf(err_buf,
  523.                         "Write Failed Status = 0x%lx (IoErr - 0x%lx)",
  524.                         ret, IoErr());
  525.                     WinMistake(MyWin, err_buf);
  526.                     EnableRestore();
  527.                 }
  528.                 else
  529.                 {    ret = AkDevUpdate(&Stuff);
  530.                     if (ret != 0)
  531.                     {    sprintf(err_buf,
  532.                             "Update Failed Status = 0x%lx (IoErr - 0x%lx)",
  533.                             ret, IoErr());
  534.                         WinMistake(MyWin, err_buf);
  535.                         EnableRestore();
  536.                     }
  537.                 }
  538.                 break;
  539.             }
  540.     }
  541.     AkMotorOff(&Stuff);
  542. }
  543.  
  544. Static Checksum()
  545. {
  546.     REG    ulong    *Chk = &Buffer[POS_CHKSUM];
  547.  
  548.     *Chk -= DosChecksum(Buffer);
  549.  
  550.     display_pos((int)(POS_CHKSUM)*4, BACKGR);
  551.  
  552.     display_pos(BytePos, ACTIVE);
  553.  
  554.     draw_page(DRAW_EACH_BLOCK);
  555. }
  556.  
  557. Static BlkGadRefresh()
  558. {
  559.     RemoveGad(&AkGad, BlkGad, 0);
  560.     BlkGad->Activation &= (~(STRINGRIGHT | STRINGCENTER));
  561.     BlkGad->Activation |= STRINGJUST;
  562.     display_num(0, 0, TheBlock, DSP_BIG, TheBlockBuf);
  563.     ActivateGad(&AkGad, BlkGad);
  564. }
  565.  
  566. Static DoBlk(Class, Gad)
  567. ULONG    Class;
  568. struct    Gadget    *Gad;
  569. {
  570.     int    ret;
  571.  
  572.     switch(Class)
  573.     {
  574.     case GADGETUP:
  575.         if (Hex)
  576.             ret = sscanf(TheBlockBuf, "%lx", &TheBlock);
  577.         else
  578.             ret = sscanf(TheBlockBuf, "%ld", &TheBlock);
  579.  
  580.         if (ret)
  581.             read(0);
  582.         else
  583.         {    TheBlock = CurBlock;
  584.             BlkGadRefresh();
  585.         }
  586.         break;
  587.     case GADGETDOWN:
  588.         break;
  589.     default:    /* Ignore */
  590.         break;
  591.     }
  592. }
  593.  
  594. Static DoDir(Class, Gad)
  595. ULONG    Class;
  596. struct    Gadget    *Gad;
  597. {
  598.     int    NewLongPos;
  599.  
  600.     switch(Class)
  601.     {
  602.     case GADGETUP:
  603.         NewLongPos = DosHash(DirBuf);
  604.         if (LongPos != NewLongPos)
  605.         {    display_pos(BytePos, BACKGR);
  606.             LongPos = NewLongPos;
  607.             BytePos = LongPos * 4;
  608.             display_pos(BytePos, ACTIVE);
  609.             draw_page(DRAW_EACH_MOVE);
  610.         }
  611.         break;
  612.     case GADGETDOWN:
  613.         break;
  614.     default:    /* Ignore */
  615.         break;
  616.     }
  617. }
  618.  
  619. Static DoNum(Class, Gad)
  620. ULONG    Class;
  621. struct    Gadget    *Gad;
  622. {
  623.     int    ret;
  624.     ulong    NewNum;
  625.  
  626.     switch(Class)
  627.     {
  628.     case GADGETUP:
  629.         if (Hex)
  630.             ret = sscanf(NumBuf, "%lx", &NewNum);
  631.         else
  632.             ret = sscanf(NumBuf, "%ld", &NewNum);
  633.  
  634.         RemoveGad(&AkGad, NumGad, 1);
  635.  
  636.         if (ret)
  637.         {    Buffer[LongPos] = NewNum;
  638.             display_pos(BytePos, BACKGR);
  639.             if (++LongPos > 127)
  640.                 LongPos -= 128;
  641.             BytePos = LongPos * 4;
  642.         }
  643.  
  644.         display_pos(BytePos, ACTIVE);
  645.  
  646.         Edit = EDIT_NO;
  647.         ActivateGad(&AkGad, BlkGad);
  648.         ActivateGad(&AkGad, DirGad);
  649.         draw_page(DRAW_EACH_MOVE|DRAW_EACH_BLOCK);
  650.  
  651.         break;
  652.     case GADGETDOWN:
  653.         break;
  654.     default:    /* Ignore */
  655.         break;
  656.     }
  657. }
  658.  
  659. #define BIT_DOREAD    1
  660. #define BIT_TESTVAL    2
  661. #define BIT_DOBYTE    4
  662.  
  663. Static no_edit(key)
  664. ushort    key;
  665. {
  666.     REG    int    tests = 0;
  667.     REG    int    NewLongPos;
  668.     REG    int    NewBytePos;
  669.  
  670.     switch(key)
  671.     {
  672.     case RAW_R | RAWB_SHIFT:
  673.     case RAW_R:
  674.         TheBlock = Stuff.Info.Root;
  675.         tests = BIT_DOREAD;
  676.         break;
  677.     case RAW_P | RAWB_SHIFT:
  678.     case RAW_P:
  679.         TheBlock = Buffer[POS_PAR];
  680.         tests = BIT_DOREAD | BIT_TESTVAL;
  681.         break;
  682.     case RAW_K | RAWB_SHIFT:
  683.     case RAW_K:
  684.         TheBlock = Buffer[POS_KEY];
  685.         tests = BIT_DOREAD | BIT_TESTVAL;
  686.         break;
  687.     case RAW_H | RAWB_SHIFT:
  688.     case RAW_H:
  689.         TheBlock = Buffer[POS_HASH_CH];
  690.         tests = BIT_DOREAD | BIT_TESTVAL;
  691.         break;
  692.     case RAW_E | RAWB_SHIFT:
  693.     case RAW_E:
  694.         TheBlock = Buffer[POS_EXT];
  695.         tests = BIT_DOREAD | BIT_TESTVAL;
  696.         break;
  697.     case RAW_F | RAWB_SHIFT:
  698.     case RAW_F:
  699.         TheBlock = Buffer[POS_FST_DAT];
  700.         tests = BIT_DOREAD | BIT_TESTVAL;
  701.         break;
  702.     case RAW_N | RAWB_SHIFT:
  703.     case RAW_N:
  704.         TheBlock = Buffer[POS_D_NXT_DAT];
  705.         tests = BIT_DOREAD | BIT_TESTVAL;
  706.         break;
  707.     case RAW_G | RAWB_SHIFT:
  708.     case RAW_G:
  709.         TheBlock = Buffer[LongPos];
  710.         tests = BIT_DOREAD | BIT_TESTVAL;
  711.         break;
  712.     case RAW_UP:
  713.         if (ByteMove)
  714.             NewBytePos = BytePos - 16;
  715.         else
  716.             NewLongPos = LongPos - 4;
  717.         tests = BIT_DOBYTE;
  718.         break;
  719.     case RAW_UP | RAWB_SHIFT:
  720.         if (ByteMove)
  721.             NewBytePos = BytePos % 16;
  722.         else
  723.             NewLongPos = LongPos % 4;
  724.         tests = BIT_DOBYTE;
  725.         break;
  726.     case RAW_LEFT:
  727.         if (ByteMove)
  728.             NewBytePos = BytePos - 1;
  729.         else
  730.             NewLongPos = LongPos - 1;
  731.         tests = BIT_DOBYTE;
  732.         break;
  733.     case RAW_LEFT | RAWB_SHIFT:
  734.         if (ByteMove)
  735.             NewBytePos = BytePos - (BytePos % 16);
  736.         else
  737.             NewLongPos = LongPos - (LongPos % 4);
  738.         tests = BIT_DOBYTE;
  739.         break;
  740.     case RAW_LEFT | RAWB_LALT:
  741.     case RAW_LEFT | RAWB_RALT:
  742.         if (ByteMove)
  743.         {    NewBytePos = BytePos - 1;
  744.             if (NewBytePos < 0)
  745.                 NewBytePos = 511;
  746.             while (NewBytePos != BytePos && !BufPtr[NewBytePos])
  747.             {    NewBytePos--;
  748.                 if (NewBytePos < 0)
  749.                     NewBytePos = 511;
  750.             }
  751.         }
  752.         else
  753.         {    NewLongPos = LongPos - 1;
  754.             if (NewLongPos < 0)
  755.                 NewLongPos = 127;
  756.             while (NewLongPos != LongPos && !Buffer[NewLongPos])
  757.             {    NewLongPos--;
  758.                 if (NewLongPos < 0)
  759.                     NewLongPos = 127;
  760.             }
  761.         }
  762.         tests = BIT_DOBYTE;
  763.         break;
  764.     case RAW_DOWN:
  765.         if (ByteMove)
  766.             NewBytePos = BytePos + 16;
  767.         else
  768.             NewLongPos = LongPos + 4;
  769.         tests = BIT_DOBYTE;
  770.         break;
  771.     case RAW_DOWN | RAWB_SHIFT:
  772.         if (ByteMove)
  773.             NewBytePos = (512-16) + (BytePos % 16);
  774.         else
  775.             NewLongPos = (128-4) + (LongPos % 4);
  776.         tests = BIT_DOBYTE;
  777.         break;
  778.     case RAW_RIGHT:
  779.         if (ByteMove)
  780.             NewBytePos = BytePos + 1;
  781.         else
  782.             NewLongPos = LongPos + 1;
  783.         tests = BIT_DOBYTE;
  784.         break;
  785.     case RAW_RIGHT | RAWB_SHIFT:
  786.         if (ByteMove)
  787.             NewBytePos = BytePos - (BytePos % 16) + 15;
  788.         else
  789.             NewLongPos = LongPos - (LongPos % 4) + 3;
  790.         tests = BIT_DOBYTE;
  791.         break;
  792.     case RAW_RIGHT | RAWB_LALT:
  793.     case RAW_RIGHT | RAWB_RALT:
  794.         if (ByteMove)
  795.         {    NewBytePos = BytePos + 1;
  796.             if (NewBytePos > 511)
  797.                 NewBytePos = 0;
  798.             while (NewBytePos != BytePos && !BufPtr[NewBytePos])
  799.             {    NewBytePos++;
  800.                 if (NewBytePos > 511)
  801.                     NewBytePos = 0;
  802.             }
  803.         }
  804.         else
  805.         {    NewLongPos = LongPos + 1;
  806.             if (NewLongPos > 127)
  807.                 NewLongPos = 0;
  808.             while (NewLongPos != LongPos && !Buffer[NewLongPos])
  809.             {    NewLongPos++;
  810.                 if (NewLongPos > 127)
  811.                     NewLongPos = 0;
  812.             }
  813.         }
  814.         tests = BIT_DOBYTE;
  815.         break;
  816.     case RAW_EQ | RAWB_SHIFT:
  817.     case RAW_EQ:
  818.         TheBlock++;
  819.         tests = BIT_DOREAD;
  820.         break;
  821.     case RAW_MINUS | RAWB_SHIFT:
  822.     case RAW_MINUS:
  823.         TheBlock--;
  824.         tests = BIT_DOREAD;
  825.         break;
  826.     case RAW_J | RAWB_SHIFT:
  827.     case RAW_J:
  828.         Left = !Left;
  829.         if (!Hex)
  830.             display_block();
  831.         break;
  832.     case RAW_M | RAWB_SHIFT:
  833.     case RAW_M:
  834.         Hex = !Hex;
  835.         display_block();
  836.         break;
  837.     case RAW_U | RAWB_LALT:
  838.     case RAW_U | RAWB_RALT:
  839.         Update();
  840.         break;
  841.     case RAW_C | RAWB_SHIFT:
  842.     case RAW_C:
  843.         Checksum();
  844.         break;
  845.     case RAW_O | RAWB_SHIFT:
  846.     case RAW_O:
  847.         ActivateGadget(BlkGad, MyWin, NULL);
  848.         break;
  849.     case RAW_D | RAWB_SHIFT:
  850.     case RAW_D:
  851.         ActivateGadget(DirGad, MyWin, NULL);
  852.         break;
  853.     case RAW_S | RAWB_SHIFT:
  854.     case RAW_S:
  855.         if (ByteMove)
  856.             for (NewBytePos = 0; NewBytePos < 512; NewBytePos++)
  857.                 BufPtr[NewBytePos] = BufPtr[BytePos];
  858.         else
  859.             for (NewLongPos = 0; NewLongPos < 128; NewLongPos++)
  860.                 Buffer[NewLongPos] = Buffer[LongPos];
  861.         display_block();
  862.         break;
  863.     case RAW_B | RAWB_SHIFT:
  864.     case RAW_B:
  865.         display_pos(BytePos, BACKGR);
  866.         if (ByteMove)
  867.             BytePos = LongPos * 4;
  868.         ByteMove = !ByteMove;
  869.         display_pos(BytePos, ACTIVE);
  870.         break;
  871.     case RAW_R | RAWB_LALT:
  872.     case RAW_R | RAWB_RALT:
  873.         read(!0);
  874.         break;
  875.     case RAW_Z | RAWB_SHIFT:
  876.     case RAW_Z:
  877.         TheBlock = 0;
  878.         tests = BIT_DOREAD;
  879.         break;
  880.     case RAW_A | RAWB_SHIFT:
  881.     case RAW_A:
  882.         Edit = EDIT_YES;
  883.         RemoveGad(&AkGad, BlkGad, 0);
  884.         RemoveGad(&AkGad, DirGad, 0);
  885.         if (ByteMove)
  886.             draw_page(DRAW_MARK_EDIT);
  887.         else
  888.         {    display_pos(BytePos, BACKGR);
  889.             NumGad->LeftEdge = (LongPos % 4) * NXTIMES + NXPLUS;
  890.             NumGad->TopEdge = (LongPos / 4) * NYTIMES + NYPLUS - FYBase;
  891.             NumGad->Activation &= (~(STRINGRIGHT | STRINGCENTER));
  892.             NumGad->Activation |= STRINGJUST;
  893.             display_num(0, 0, Buffer[LongPos], DSP_BIG, NumBuf);
  894.             ActivateGad(&AkGad, NumGad);
  895.             ActivateGadget(NumGad, MyWin, NULL);
  896.         }
  897.         break;
  898.     default:
  899.         break;
  900.     }
  901.  
  902.     if (tests & BIT_DOBYTE)
  903.     {    if (ByteMove)
  904.         {    if (NewBytePos < 0)
  905.                 NewBytePos += 512;
  906.             if (NewBytePos > 511)
  907.                 NewBytePos -= 512;
  908.             if (BytePos != NewBytePos)
  909.             {    display_pos(BytePos, BACKGR);
  910.                 BytePos = NewBytePos;
  911.                 LongPos = BytePos / 4;
  912.                 display_pos(BytePos, ACTIVE);
  913.                 draw_page(DRAW_EACH_MOVE);
  914.             }
  915.         }
  916.         else
  917.         {    if (NewLongPos < 0)
  918.                 NewLongPos += 128;
  919.             if (NewLongPos > 127)
  920.                 NewLongPos -= 128;
  921.             if (LongPos != NewLongPos)
  922.             {    display_pos(BytePos, BACKGR);
  923.                 LongPos = NewLongPos;
  924.                 BytePos = LongPos * 4;
  925.                 display_pos(BytePos, ACTIVE);
  926.                 draw_page(DRAW_EACH_MOVE);
  927.             }
  928.         }
  929.     }
  930.  
  931.     if (tests & BIT_TESTVAL)
  932.         if (TheBlock == 0)
  933.             TheBlock = CurBlock;
  934.  
  935.     if (tests & BIT_DOREAD)
  936.         read(0);
  937. }
  938.  
  939. Static edit(key)
  940. ushort    key;
  941. {
  942.     REG    int    NewBytePos;
  943.     REG    char    ch;
  944.     REG    int    modify = FALSE;
  945.  
  946.     NewBytePos = BytePos;
  947.     switch (key)
  948.     {
  949.     case RAW_RIGHT:
  950.         NewBytePos++;
  951.         break;
  952.     case RAW_LEFT:
  953.         NewBytePos--;
  954.         break;
  955.     case RAW_DOWN:
  956.         NewBytePos += 16;
  957.         break;
  958.     case RAW_UP:
  959.         NewBytePos -= 16;
  960.         break;
  961.     default:
  962.         ch = AKCOOK(key);
  963.  
  964.         switch(ch)
  965.         {
  966.         case '\033':
  967.             Edit = EDIT_NO;
  968.             ActivateGad(&AkGad, BlkGad);
  969.             ActivateGad(&AkGad, DirGad);
  970.             draw_page(DRAW_UNMARK_EDIT);
  971.             break;
  972.         case '\0':
  973.             break;
  974.         default:
  975.             BufPtr[BytePos] = ch;
  976.             NewBytePos++;
  977.             modify = TRUE;
  978.             break;
  979.         }
  980.         break;
  981.     }
  982.     if (NewBytePos < 0)
  983.         NewBytePos += 512;
  984.     if (NewBytePos > 511)
  985.         NewBytePos -= 512;
  986.     if (BytePos != NewBytePos)
  987.     {    display_pos(BytePos, BACKGR);
  988.         BytePos = NewBytePos;
  989.         LongPos = BytePos / 4;
  990.         display_pos(BytePos, ACTIVE);
  991.  
  992.         if (modify)
  993.             draw_page(DRAW_EACH_MOVE|DRAW_EACH_BLOCK);
  994.         else
  995.             draw_page(DRAW_EACH_MOVE);
  996.     }
  997. }
  998.  
  999. Static gotkey(key)
  1000. ushort    key;
  1001. {
  1002.     switch(Edit)
  1003.     {
  1004.     case EDIT_NO:
  1005.         no_edit(key);
  1006.         break;
  1007.     case EDIT_YES:
  1008.         if (ByteMove)
  1009.             edit(key);
  1010.         break;
  1011.     }
  1012. }
  1013.  
  1014. #define KEYS_WANTED    (RAWB_CHARS | RAWB_SHIFT | RAWB_CTRL | RAWB_LALT | RAWB_RALT)
  1015.  
  1016. Static BlockEd()
  1017. {
  1018.     REG    struct    IntuiMessage    *Msg;
  1019.     REG    ULONG    WaitMask;
  1020.  
  1021.     TheBlock = Stuff.Info.Root;
  1022.  
  1023.     read(!0);
  1024.  
  1025.     WaitMask = INTUITION_MESSAGE;
  1026.  
  1027.     while (1)
  1028.     {    Wait(WaitMask);
  1029.  
  1030.         while ((Msg = GetMsg(MyWin->UserPort)))
  1031.         {    switch(Msg->Class)
  1032.             {
  1033.             case RAWKEY:
  1034.                 AkCookKey(Msg->Code, gotkey, KEYS_WANTED);
  1035.                 ReplyMsg(Msg);
  1036.                 break;
  1037.             case CLOSEWINDOW:
  1038.                 cleanup();
  1039.                 break;
  1040.             case MENUPICK:
  1041.                 MnuMsg(&AkMenu, Msg);
  1042.                 break;
  1043.             case GADGETUP:
  1044.             case GADGETDOWN:
  1045.                 GadMsg(&AkGad, Msg);
  1046.                 break;
  1047.             default:
  1048.                 ReplyMsg(Msg);
  1049.                 break;
  1050.             }
  1051.         }
  1052.     }
  1053. }
  1054.  
  1055. Static EnableRestore()
  1056. {
  1057.     (RestoreItem->Flags) |= ITEMENABLED;
  1058. }
  1059.  
  1060. Static Restore(Menu, MenuItem, Item)
  1061. struct    Menu    *Menu;
  1062. struct    MenuItem    *MenuItem;
  1063. USHORT    Item;
  1064. {
  1065.     (RestoreItem->Flags) &= (~ITEMENABLED);
  1066.     WinMistake(MyWin, NULL);
  1067. }
  1068.  
  1069. Static add_gadgets()
  1070. {
  1071.     GadInit(&AkGad, MyWin);
  1072.  
  1073.     BlkGad = AddStrGad(&AkGad, 0L, saves[BLKGAD_SAV].x, saves[BLKGAD_SAV].y-FYBase, FXSize*10, FYSize, STRINGJUST, TheBlockBuf, sizeof(TheBlockBuf), DoBlk);
  1074.     DirGad = AddStrGad(&AkGad, 0L, saves[DIRGAD_SAV].x, saves[DIRGAD_SAV].y-FYBase, FXSize*18, FYSize, 0L, DirBuf, sizeof(DirBuf), DoDir);
  1075.  
  1076.     ActivateGads(&AkGad);
  1077.  
  1078.     NumGad = AddStrGad(&AkGad, 0L, 0, 0, FXSize*10, FYBase, 0L, NumBuf, sizeof(NumBuf), DoNum);
  1079. }
  1080.  
  1081. main(argc, argv)
  1082. int    argc;
  1083. char    *argv[];
  1084. {
  1085.     cli = argc;
  1086.  
  1087.     DECRYPT();
  1088.  
  1089.     DO_QUAL();
  1090.  
  1091.     Device = argv[1];
  1092.  
  1093.     if (!Quiet && cli)
  1094.         STARTUP_MSG;
  1095.  
  1096.     OPEN_LIB(IBASE, "intuition.library", INTUITION_REV);
  1097.     OPEN_LIB(GfxBase, "graphics.library", GRAPHICS_REV);
  1098.     OPEN_LIB(DiskfontBase, "diskfont.library", 0L);
  1099.  
  1100.     OpalAttr.ta_Name = (STRPTR)FontName;
  1101.     OpalAttr.ta_YSize = FontSize;
  1102.  
  1103.     Opal = OpenDiskFont(&OpalAttr);
  1104.     if (!Opal)
  1105.         error("Can't open font", ERR_NOVAL);
  1106.  
  1107.     FXSize = Opal->tf_XSize;
  1108.     FYSize = Opal->tf_YSize + 1;
  1109.     FYBase = Opal->tf_Baseline;
  1110.  
  1111.     PoolInit(&GenPoolKey, 0L, MEMF_CHIP|MEMF_CLEAR);
  1112.     PoolAlloc(Buffer, (long)BLOCK_SIZE, &GenPoolKey);
  1113.     BufPtr = (uchar *)Buffer;
  1114.     PoolAlloc(Buffer2, (long)BLOCK_SIZE, &GenPoolKey);
  1115.  
  1116.     if (Dev = AkDevOpen(Device, &Stuff))
  1117.         error(Device, Dev);
  1118.  
  1119.     if (Inhibit)
  1120.         Inhibited = AkDevInhibit(&Stuff, -1L);
  1121.  
  1122.     if (!(MyScreen = OpenScreen(&MyNewScreen)))
  1123.         error(MyNewScreen.DefaultTitle, ERR_NOSCR);
  1124.  
  1125.     SetRGB4(&(MyScreen->ViewPort), 0L, (long)((ColTbl0 & 0xf00) >> 8),
  1126.                        (long)((ColTbl0 & 0x0f0) >> 4),
  1127.                        (long)((ColTbl0 & 0x00f) >> 0));
  1128.     SetRGB4(&(MyScreen->ViewPort), 1L, (long)((ColTbl1 & 0xf00) >> 8),
  1129.                        (long)((ColTbl1 & 0x0f0) >> 4),
  1130.                        (long)((ColTbl1 & 0x00f) >> 0));
  1131.     SetRGB4(&(MyScreen->ViewPort), 2L, (long)((ColTbl2 & 0xf00) >> 8),
  1132.                        (long)((ColTbl2 & 0x0f0) >> 4),
  1133.                        (long)((ColTbl2 & 0x00f) >> 0));
  1134.     SetRGB4(&(MyScreen->ViewPort), 3L, (long)((ColTbl3 & 0xf00) >> 8),
  1135.                        (long)((ColTbl3 & 0x0f0) >> 4),
  1136.                        (long)((ColTbl3 & 0x00f) >> 0));
  1137.  
  1138.     ScreenToFront(MyScreen);
  1139.  
  1140.     MyNewWin.Screen = MyScreen;
  1141.  
  1142.     if (!(MyWin = OpenWindow(&MyNewWin)))
  1143.         error(MyNewWin.Title, ERR_NOWIN);
  1144.  
  1145.     rp = MyWin->RPort;
  1146.  
  1147.     WinMistake(MyWin, NULL);
  1148.  
  1149.     MenuInit(&AkMenu, MyWin, (struct TextAttr *)NULL);
  1150.  
  1151.     ProjectMenu = AddMenu(&AkMenu," Project ", MENUFLAGS, NULL, 0);
  1152.     AddItem(&AkMenu, ProjectMenu, " Quit ", MOREITEMFLAGS, NULL, 0, 'Q', cleanup);
  1153.     RestoreItem = AddItem(&AkMenu, ProjectMenu, " Restore ", ITEMFLAGS, NULL, 0, 'R', Restore);
  1154.  
  1155.     AlignMenus(&AkMenu, NULL);
  1156.  
  1157.     BlockEd();
  1158.  
  1159.     cleanup();
  1160. }
  1161.  
  1162. error(why, num)
  1163. char    *why;
  1164. long    num;
  1165. {
  1166.     ERROR_INIT
  1167.  
  1168.     FreeGads(&AkGad);
  1169.  
  1170.     ClearMenu(&AkMenu);
  1171.  
  1172.     if (MyWin)
  1173.         CloseWindow(MyWin);
  1174.  
  1175.     if (MyScreen)
  1176.         CloseScreen(MyScreen);
  1177.  
  1178.     if (Inhibited)
  1179.         AkDevInhibit(&Stuff, 0L);
  1180.  
  1181.     if (!Dev)
  1182.         AkDevClose(&Stuff);
  1183.  
  1184.     if (Opal)
  1185.         CloseFont(Opal);
  1186.  
  1187.     ERROR_TEST
  1188.         CASE_ERR_NOGADDEV
  1189.         CASE_ERR_AKDEVALL
  1190.         CASE_ERR_NOVAL
  1191.         CASE_ERR_NOMEM
  1192.         CASE_ERR_NOWIN
  1193.         CASE_ERR_NOSCR
  1194.         CASE_ERR_NOLIB
  1195.     ERROR_END(FACILITY_BLOCKED)
  1196.  
  1197.     PoolFree(&GenPoolKey);
  1198.  
  1199.     if (DiskfontBase)
  1200.         CloseLibrary(DiskfontBase);
  1201.  
  1202.     if (GfxBase)
  1203.         CloseLibrary(GfxBase);
  1204.  
  1205.     if (IBASE)
  1206.         CloseLibrary(IBASE);
  1207.  
  1208.     CLEANUP_QUAL();
  1209.  
  1210.     ERROR_EXIT
  1211. }
  1212.