home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 106 / EnigmaAmiga106CD.iso / software / utilities / hexy / src / hexy_edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-23  |  14.4 KB  |  596 lines

  1.  
  2. /*
  3.  * [!BGN - MACHINE GENERATED - DO NOT EDIT THIS HEADER]
  4.  *
  5.  * Program   : Hexy (Binary file viewer/editor for the Amiga.)
  6.  * Version   : 1.6
  7.  * File      : Work:Source/!WIP/HisoftProjects/Hexy/Hexy_edit.c
  8.  * Author    : Andrew Bell
  9.  * Copyright : Copyright © 1998-1999 Andrew Bell (See GNU GPL)
  10.  * Created   : Saturday 28-Feb-98 16:00:00
  11.  * Modified  : Sunday 22-Aug-99 23:31:45
  12.  * Comment   : 
  13.  *
  14.  * (Generated with StampSource 1.2 by Andrew Bell)
  15.  *
  16.  * [!END - MACHINE GENERATED - DO NOT EDIT THIS HEADER]
  17.  *
  18.  */
  19.  
  20. /* Created: Sun/09/Aug/1998 */
  21.  
  22. /*
  23.  *  Hexy, binary file viewer and editor for the Amiga.
  24.  *  Copyright (C) 1999 Andrew Bell
  25.  *
  26.  *  Author's email address: andrew.ab2000@bigfoot.com
  27.  *
  28.  *  This program is free software; you can redistribute it and/or modify
  29.  *  it under the terms of the GNU General Public License as published by
  30.  *  the Free Software Foundation; either version 2 of the License, or
  31.  *  (at your option) any later version.
  32.  *
  33.  *  This program is distributed in the hope that it will be useful,
  34.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  35.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  36.  *  GNU General Public License for more details.
  37.  *
  38.  *  You should have received a copy of the GNU General Public License
  39.  *  along with this program; if not, write to the Free Software
  40.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  41.  *
  42.  */
  43.  
  44.  
  45. #include <Hexy.h>
  46.  
  47. Prototype void Edit_Begin( void );
  48. Prototype void Edit_End( void );
  49. Prototype void Edit_DisplayCursor( void );
  50. Prototype void Edit_WriteChar( register __d0 LONG TempCursorOffset, register __d1 UBYTE Ch );
  51. Prototype void Edit_WipeCursor( void );
  52. Prototype BOOL Edit_ShiftCursor( register __d0 LONG Offset );
  53. Prototype BOOL Edit_DoEditIDCMP( struct IntuiMessage *IM );
  54. Prototype BOOL EditFlag;
  55.  
  56. BOOL EditFlag = FALSE;
  57. LONG CursorOffset = 0;
  58. LONG CursorOffsetNibble;  /* 0 = Lower 4 bits ($0F), 1 = upper 4 bits ($F0) */
  59.  
  60. #define LOWER_NIBBLE 0  /* ($0F) */
  61. #define UPPER_NIBBLE 1  /* ($F0) */
  62.  
  63. ULONG OldCursX1, OldCursY1;
  64. ULONG OldCursX2, OldCursY2;
  65.  
  66. void Edit_Begin( void )
  67. {
  68.   /*************************************************
  69.    *
  70.    * Start edit mode 
  71.    *
  72.    */
  73.  
  74.   ULONG Sel;
  75.  
  76.   if (EditFlag) return;
  77.  
  78.   if (GT_GetGadgetAttrs(MAINGadgets[GD_GEDIT], MAINWnd, NULL,
  79.         GTCB_Checked, &Sel,
  80.         TAG_DONE))
  81.   {
  82.     if (!Sel) GT_SetGadgetAttrs(MAINGadgets[GD_GEDIT], MAINWnd, NULL,
  83.       GTCB_Checked, TRUE,
  84.       TAG_DONE);
  85.   }
  86.  
  87.   EditFlag = TRUE;
  88.   CursorOffsetNibble = UPPER_NIBBLE;
  89.   OldCursX1 = -1;
  90.   Edit_DisplayCursor();
  91. }
  92.  
  93. void Edit_End( void )
  94. {
  95.   /*************************************************
  96.    *
  97.    * End edit mode 
  98.    *
  99.    */
  100.  
  101.   ULONG Sel;
  102.  
  103.   if (!EditFlag) return;
  104.  
  105.   if (GT_GetGadgetAttrs(MAINGadgets[GD_GEDIT], MAINWnd, NULL,
  106.         GTCB_Checked, &Sel,
  107.         TAG_DONE))
  108.   {
  109.     if (Sel) GT_SetGadgetAttrs(MAINGadgets[GD_GEDIT], MAINWnd, NULL,
  110.               GTCB_Checked, FALSE,
  111.               TAG_DONE);
  112.   }
  113.  
  114.   EditFlag = FALSE;
  115.   Edit_WipeCursor();
  116.  
  117.   PrintStatus("", NULL);  
  118. }
  119.  
  120. /* Initial offset for invisible HEX edit grid */
  121.  
  122. #define DUMPGRIDHEX_XPOS ((13 + (9 * 8)) - 5)
  123. #define DUMPGRIDHEX_YPOS (18-10)
  124. #define DUMPGRIDHEXASC_XPOS (DUMPGRIDHEX_XPOS + (((XAMOUNT_HEX * 2) + 6) * 8))
  125. #define DUMPGRIDHEXASC_YPOS 18            
  126.  
  127. /* Initial offset for invisible ASCII edit grid */
  128.  
  129. #define DUMPGRIDASC_XPOS ((13 + (10 * 8)) - 5)
  130. #define DUMPGRIDASC_YPOS (18-10)
  131. #define CURSOR_XSIZE 8
  132. #define CURSOR_YSIZE 7
  133.  
  134. void Edit_DisplayCursor( void )
  135. {
  136.   /*************************************************
  137.    *
  138.    * Display the edit cursor
  139.    *
  140.    */
  141.  
  142.   /* This fuction should check to see if cursor is out of bounds,
  143.      if so, modify it to fit within the bounds. */
  144.  
  145.   ULONG CursorOffset_X, CursorOffset_Y;
  146.  
  147.   if (!EditFlag) return;
  148.  
  149.   SetDrMd(MAINWnd->RPort, COMPLEMENT);
  150.  
  151.   if (OldCursX1 != -1)  /* Delete old cursor, if it exists! */
  152.   {
  153.     RectFill( MAINWnd->RPort,
  154.       OldCursX1, OldCursY1,
  155.       OldCursX2, OldCursY2 );
  156.   }
  157.  
  158.   /* Has the cursor move passed EOF? */
  159.  
  160.   if (CursorOffset > ((VC.VC_FileLength - VC.VC_CurrentPoint) - 1 ))
  161.   {
  162.     CursorOffset = (VC.VC_FileLength - VC.VC_CurrentPoint) - 1;
  163.   }
  164.  
  165.   if (VC.VC_Mode == HEXYMODE_HEX)
  166.   {
  167.     CursorOffset_X = CursorOffset % XAMOUNT_HEX;
  168.     CursorOffset_Y = CursorOffset / XAMOUNT_HEX;
  169.  
  170.     CursorOffset_X *= 2;
  171.  
  172.     if (CursorOffset_X >= (16 * 2)) CursorOffset_X += 4;
  173.     else if (CursorOffset_X >= (12 * 2)) CursorOffset_X += 3;
  174.     else if (CursorOffset_X >= (8 * 2)) CursorOffset_X += 2;
  175.     else if (CursorOffset_X >= (4 * 2)) CursorOffset_X++;
  176.  
  177.     RectFill(MAINWnd->RPort,
  178.       OldCursX1 = ((CursorOffset_X * 8) + DUMPGRIDHEX_XPOS + 1),
  179.       OldCursY1 = ((CursorOffset_Y * 8) + DUMPGRIDHEX_YPOS),
  180.       OldCursX2 = ((CursorOffset_X * 8) + DUMPGRIDHEX_XPOS +
  181.                                           (CURSOR_XSIZE * 2) + 1),
  182.       OldCursY2 = ((CursorOffset_Y * 8) + DUMPGRIDHEX_YPOS +
  183.                                           CURSOR_YSIZE));
  184.  
  185.   }
  186.   else if (VC.VC_Mode == HEXYMODE_ASCII)
  187.   {
  188.     CursorOffset_X = CursorOffset % XAMOUNT_ASCII;
  189.     CursorOffset_Y = CursorOffset / XAMOUNT_ASCII;
  190.  
  191.     RectFill(MAINWnd->RPort,
  192.       OldCursX1 = ((CursorOffset_X * 8) + DUMPGRIDASC_XPOS + 1),
  193.       OldCursY1 = ((CursorOffset_Y * 8) + DUMPGRIDASC_YPOS),
  194.       OldCursX2 = ((CursorOffset_X * 8) + DUMPGRIDASC_XPOS + (CURSOR_XSIZE * 1) + 1),
  195.       OldCursY2 = ((CursorOffset_Y * 8) + DUMPGRIDASC_YPOS + CURSOR_YSIZE));
  196.   }
  197.  
  198.   SetDrMd(MAINWnd->RPort, JAM2);
  199.  
  200.   {
  201.     ULONG res;    
  202.     res = VC.VC_CurrentPoint + CursorOffset;
  203.     PrintStatus("Offset = %lu", &res);
  204.   }
  205.  
  206. }
  207.  
  208. UBYTE HexByte;
  209. UBYTE HexByte_UpperCode;
  210. UBYTE HexByte_LowerCode;
  211. UBYTE HexByte_Upper;
  212. UBYTE HexByte_Lower;
  213.  
  214. void Edit_WriteChar( register __d0 LONG TempCursorOffset,
  215.                      register __d1 UBYTE Ch )
  216. {
  217.   /*************************************************
  218.    *
  219.    * Write a char to the file 
  220.    *
  221.    */
  222.  
  223.   ULONG CursorOffset_X, CursorOffset_Y;
  224.   UBYTE ChCode;
  225.   UBYTE *EditBit;
  226.   BOOL r;
  227.   UBYTE TmpCh; 
  228.  
  229.   if (VC.VC_Mode == HEXYMODE_HEX)
  230.   {
  231.     CursorOffset_X = TempCursorOffset % XAMOUNT_HEX;
  232.     CursorOffset_Y = TempCursorOffset / XAMOUNT_HEX;
  233.  
  234.     CursorOffset_X *= 2;
  235.  
  236.     /* VALID HEX DIGITS: 0123456789 abcdef ABCDEF  */
  237.     
  238.     if ((Ch >= 'a') && (Ch <= 'f'))
  239.     {
  240.       Ch -= 0x20;   /* Change lowercase to UPPERCASE */
  241.     }
  242.  
  243.     /* Make sure we have a valid HEX digit! */
  244.  
  245.     if (!(((Ch >= 'A') && (Ch <= 'F')) ||
  246.        ((Ch >= '0') && (Ch <= '9'))))
  247.       {
  248.         DisplayBeep(Scr);
  249.         PrintStatus("Not a hexdecimal digit!", NULL);
  250.         return;
  251.       }
  252.  
  253.     if ((Ch >= 'A') && (Ch <= 'F'))
  254.       ChCode = (Ch - ('A' + 0x10)); /* + $10 */
  255.     else
  256.       ChCode = (Ch - '0');
  257.  
  258.     if (CursorOffsetNibble == LOWER_NIBBLE)
  259.     {
  260.       HexByte_LowerCode = ChCode;
  261.       HexByte_Lower = Ch;
  262.  
  263.       if (CursorOffset_X >= (16 * 2)) CursorOffset_X += 4;
  264.       else if (CursorOffset_X >= (12 * 2)) CursorOffset_X += 3;
  265.       else if (CursorOffset_X >= (8 * 2)) CursorOffset_X += 2;
  266.       else if (CursorOffset_X >= (4 * 2)) CursorOffset_X++;
  267.  
  268.       HexByte = ((HexByte_UpperCode << 4) | HexByte_LowerCode);
  269.  
  270.       EditBit = (UBYTE *)
  271.         (VC.VC_FileAddress + VC.VC_CurrentPoint + CursorOffset);
  272.  
  273.       /* A basic safety check */
  274.  
  275.       if ((EditBit <= (VC.VC_FileAddress + VC.VC_FileLength)) &&
  276.         (EditBit >= (VC.VC_FileAddress)))
  277.       {
  278.         EditBit[0] = HexByte; /* Modify the actual file */
  279.       }
  280.       else
  281.       {
  282.         DisplayBeep(Scr);
  283.         PrintStatus("INTERNAL ERROR: "
  284.                     "Hexadecimal write back out of bounds!", NULL);
  285.       }
  286.  
  287.       if (r = Edit_ShiftCursor(1)) Edit_WipeCursor();
  288.  
  289.       SetAPen(MAINWnd->RPort, 1);   /* Pen to black */
  290.  
  291.       Move(MAINWnd->RPort,                    /* First hex digit */
  292.           (CursorOffset_X * 8) + DUMPGRIDASC_XPOS + 1 - 8,
  293.           (CursorOffset_Y * 8) + DUMPGRIDASC_YPOS + 6);
  294.  
  295.       Text(MAINWnd->RPort, &HexByte_Upper, 1);
  296.  
  297.       Move(MAINWnd->RPort,                    /* Second hex digit */
  298.           (CursorOffset_X * 8) + DUMPGRIDASC_XPOS + 1 + 8 - 8,
  299.           (CursorOffset_Y * 8) + DUMPGRIDASC_YPOS + 6);
  300.       Text(MAINWnd->RPort, &HexByte_Lower, 1);
  301.  
  302.       if (r) Edit_DisplayCursor();
  303.  
  304.       /* Display text on other side of HEX dump here!!! */
  305.  
  306.       CursorOffset_X = TempCursorOffset % XAMOUNT_HEX;
  307.       CursorOffset_Y = TempCursorOffset / XAMOUNT_HEX;
  308.  
  309.       /* Write ch to ASCII dump (at right hand side of screen) */
  310.  
  311.       Move(MAINWnd->RPort,
  312.           (CursorOffset_X * 8) + DUMPGRIDHEXASC_XPOS + 1 - 8,
  313.           (CursorOffset_Y * 8) + DUMPGRIDHEXASC_YPOS + 6 - 10);
  314.  
  315.       Text(MAINWnd->RPort, &HexByte, 1);
  316.  
  317.       CursorOffsetNibble = UPPER_NIBBLE;
  318.     }
  319.     else /* UPPER_NIBBLE */
  320.     {
  321.       HexByte_Upper = Ch;
  322.       HexByte_UpperCode = ChCode;
  323.       CursorOffsetNibble = LOWER_NIBBLE;
  324.     }
  325.  
  326.   }
  327.   else if (VC.VC_Mode == HEXYMODE_ASCII)
  328.   {
  329.     UBYTE *EditBit = (UBYTE *)
  330.       (VC.VC_FileAddress + VC.VC_CurrentPoint + CursorOffset);
  331.  
  332.     /* A basic safety check */
  333.  
  334.     if ((EditBit <= (VC.VC_FileAddress + VC.VC_FileLength)) &&
  335.       (EditBit >= (VC.VC_FileAddress)))
  336.     {
  337.      /* Modify the actual file */
  338.  
  339.       EditBit[0] = Ch;
  340.     }
  341.     else
  342.     {
  343.       DisplayBeep(Scr);
  344.       PrintStatus("Internal error: "
  345.                   "ASCII write back out of bounds!", NULL);
  346.     }
  347.  
  348.     r = Edit_ShiftCursor(1); if (r) Edit_WipeCursor();
  349.  
  350.     CursorOffset_X = TempCursorOffset % XAMOUNT_ASCII;
  351.     CursorOffset_Y = TempCursorOffset / XAMOUNT_ASCII;
  352.  
  353.     SetAPen(MAINWnd->RPort, 1);
  354.  
  355.     Move(MAINWnd->RPort,                  /* Display ch */
  356.         (CursorOffset_X * 8) + DUMPGRIDASC_XPOS + 1 ,
  357.         (CursorOffset_Y * 8) + DUMPGRIDASC_YPOS + 6 );
  358.  
  359.     TmpCh = Ch;
  360.  
  361.     Text(MAINWnd->RPort, &TmpCh, 1);
  362.  
  363.     if (r) Edit_ShiftCursor(0);
  364.   }
  365. }
  366.  
  367. void Edit_WipeCursor( void )
  368. {
  369.   /*************************************************
  370.    *
  371.    * Clear the cursor from view 
  372.    *
  373.    */
  374.  
  375.   SetDrMd(MAINWnd->RPort, COMPLEMENT);
  376.  
  377.   if (OldCursX1 != -1)  /* Delete old cursor, if it exists. */
  378.   {
  379.     RectFill( MAINWnd->RPort,
  380.       OldCursX1, OldCursY1,
  381.       OldCursX2, OldCursY2 );
  382.       
  383.     OldCursX1 = ~NULL;
  384.   }
  385.  
  386.   SetDrMd(MAINWnd->RPort, JAM2);
  387. }
  388.  
  389. BOOL Edit_ShiftCursor( register __d0 LONG ShiftOffset )
  390. {
  391.   /*************************************************
  392.    *
  393.    * Move the cursor 
  394.    *
  395.    */
  396.  
  397.   /* This function will return TRUE if the cursor cannot be moved
  398.      any further because of EOF! (SOF is not an issue here) */
  399.  
  400.   ULONG XAmt;
  401.   ULONG EndAmt = (VC.VC_FileLength - VC.VC_CurrentPoint) - 1;
  402.  
  403.   /* Get the current display mode (HEX/ASCII) dump widths. */
  404.  
  405.   if (VC.VC_Mode == HEXYMODE_HEX)
  406.   {
  407.     XAmt = XAMOUNT_HEX;
  408.   }
  409.   else/* ASCII */
  410.   {
  411.     XAmt = XAMOUNT_ASCII;
  412.   }
  413.  
  414.   /* This code will catch a flip from ASCII to HEX (and vise versa),
  415.      when the cursor position is out of bounds. */
  416.  
  417.   if (CursorOffset > ((XAmt * YLINES) - 1))
  418.   {
  419.     CursorOffset = (XAmt * YLINES) - 1;
  420.   }
  421.  
  422.   /* Has the cursor passed the display limits? */
  423.  
  424.   if ((CursorOffset + ShiftOffset) < 0)
  425.   {
  426.     if ((VC.VC_CurrentPoint - XAmt) < 0)  /* SOF check */
  427.     {
  428.       return(FALSE);
  429.     }
  430.  
  431.     if (ShiftOffset == -1) XAmt = 1;
  432.  
  433.     AdjustView(&VC, -XAmt);
  434.     SetVDragBar(&VC);
  435.     return(FALSE);
  436.   }
  437.   else if ((CursorOffset + ShiftOffset) > ((XAmt * YLINES) - 1) )
  438.   {
  439.     if ((CursorOffset + ShiftOffset) > EndAmt)  /* EOF check */
  440.     {
  441.       return(TRUE);
  442.     }
  443.  
  444.     if (ShiftOffset == 1) XAmt = 1;
  445.  
  446.     AdjustView(&VC, XAmt);
  447.     SetVDragBar(&VC);
  448.     return(FALSE);
  449.   }
  450.  
  451.   /* Is the cursor at the EOF? */
  452.  
  453.   if ((CursorOffset + ShiftOffset) > EndAmt)
  454.   {
  455.     PrintStatus("Check 1", NULL);
  456.     CursorOffset = (VC.VC_FileLength - VC.VC_CurrentPoint) - 1;
  457.     Edit_DisplayCursor();
  458.     return(TRUE);
  459.   }
  460.  
  461.   CursorOffset += ShiftOffset;
  462.  
  463.   Edit_DisplayCursor();
  464.  
  465.   return(FALSE);
  466. }
  467.  
  468. /* This flag is set to TRUE when the users
  469.    scrolls the display while in edit mode. */
  470.  
  471. BOOL EditScrollFlag = FALSE;
  472.  
  473. BOOL Edit_DoEditIDCMP(struct IntuiMessage *EditIM)
  474. {
  475.   /*************************************************
  476.    *
  477.    * Parse IDCMP messages while in edit mode 
  478.    *
  479.    */
  480.  
  481.   /*
  482.    * This function will return FALSE if the message has no use!
  483.    *
  484.    * NOTES: It should also handle scroller events
  485.    *
  486.    */
  487.  
  488.   struct Gadget *TempGad;
  489.  
  490.   if (!EditFlag) return(FALSE);
  491.  
  492.   TempGad = EditIM->IAddress;
  493.  
  494.   switch( EditIM->Class )
  495.   {
  496.     ULONG XShift;
  497.  
  498.     case IDCMP_RAWKEY:    
  499.  
  500.       if (VC.VC_Mode == HEXYMODE_HEX)
  501.         XShift = XAMOUNT_HEX;
  502.       else
  503.         XShift = XAMOUNT_ASCII;
  504.                 
  505.       CursorOffsetNibble = UPPER_NIBBLE;
  506.       switch(EditIM->Code)
  507.       {
  508.         case CURSORLEFT: Edit_ShiftCursor(-1); break;
  509.         case CURSORRIGHT: Edit_ShiftCursor(1); break;
  510.         case CURSORUP: Edit_ShiftCursor(-XShift); break;
  511.         case CURSORDOWN: Edit_ShiftCursor(XShift); break;
  512.         default: return(FALSE); break;
  513.       }
  514.       break;
  515.  
  516.     case IDCMP_VANILLAKEY:
  517.     {
  518.       UBYTE ChStr[2] = {'?', 0};  /* Ch + NULL termination */
  519.       ChStr[0] = (UBYTE) EditIM->Code;
  520.       stream[0] = (ULONG) &ChStr;
  521.       stream[1] = (ULONG) EditIM->Code;
  522.       PrintStatus("Last key press: '%.1s' (0x%lx)", &stream);
  523.       Edit_WriteChar(CursorOffset, (UBYTE) EditIM->Code);
  524.       break;
  525.     }
  526.  
  527.     case IDCMP_GADGETDOWN:
  528.       if ( TempGad->GadgetID == GD_GVDRAGBAR )
  529.       {
  530.         EditScrollFlag = TRUE;
  531.         switch(TempGad->GadgetID)
  532.         {
  533.           case GD_GVDRAGBAR:
  534.             if (VC.VC_Mode == HEXYMODE_HEX)
  535.             {
  536.               VC.VC_CurrentPoint = (ULONG)(IM.Code * XAMOUNT_HEX);
  537.             }
  538.             else
  539.             {
  540.               VC.VC_CurrentPoint = (ULONG)(IM.Code * XAMOUNT_ASCII);
  541.             }
  542.             UpdateView(&VC, NULL);
  543.           break;
  544.         }
  545.         return(TRUE);
  546.       }
  547.       return(FALSE);
  548.       break;
  549.  
  550.     case IDCMP_GADGETUP:
  551.     {
  552.       ULONG XAmt, MoveAmt = -1;
  553.  
  554.       if (VC.VC_Mode == HEXYMODE_HEX)
  555.         XAmt = XAMOUNT_HEX;
  556.       else
  557.         XAmt = XAMOUNT_ASCII;
  558.  
  559.       switch( TempGad->GadgetID )
  560.       {
  561.         case GD_GVDRAGBAR:
  562.           EditScrollFlag = FALSE;
  563.           return(TRUE);
  564.           break;
  565.  
  566.         case GD_GNEXTL: MoveAmt = XAmt; break;
  567.         case GD_GPREVL: MoveAmt = -XAmt; break;
  568.         case GD_GNEXTP: MoveAmt = XAmt * YLINES; break;
  569.         case GD_GPREVP: MoveAmt = -(XAmt * YLINES); break;
  570.         case GD_GSEARCH:
  571.             ViewFindWindow();
  572.             break;
  573.       }
  574.  
  575.       if (MoveAmt != -1)
  576.       {
  577.         AdjustView(&VC, MoveAmt);
  578.         SetVDragBar(&VC);
  579.         return(TRUE);
  580.       }
  581.       return(FALSE);
  582.       break;
  583.     }
  584.     default: return(FALSE); break;
  585.   }
  586.   return(TRUE);
  587. }
  588.  
  589. /*************************************************
  590.  *
  591.  * 
  592.  *
  593.  */
  594.  
  595.  
  596.