home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d502 / cells.lha / CELLS / CELLSSource.lzh / cScreen.c < prev    next >
C/C++ Source or Header  |  1991-04-20  |  10KB  |  409 lines

  1. /*
  2.  *  CELLS       An Implementation of the WireWorld cellular automata
  3.  *              as described in Scientific American, Jan 1990.
  4.  *
  5.  *              Copyright 1990 by Davide P. Cervone.
  6.  *  You may use this code, provided this copyright notice is kept intact.
  7.  *  See the CELLS.HELP file for complete information on distribution conditions.
  8.  */
  9.  
  10. /*
  11.  *  File:  cScreen.c        Handles screen updates and scrolls.
  12.  */
  13.  
  14.  
  15. #include "Cells.h"
  16. #undef INTUITION_PREFERENCES_H
  17. #include <intuition/preferences.h>
  18. #include <stdio.h>
  19.  
  20.  
  21. #define COLORFILE       "Cells.Colors"
  22. #define WBCOLOR         0xFFFF
  23. #define MAXLINE         132
  24.  
  25. extern UWORD GetRGB4();
  26.  
  27.  
  28. /*
  29.  *  ClearPatch()
  30.  *
  31.  *  Clear the specified section of screen to the shadow color
  32.  *  Draw the horizontal and vertical grid lines
  33.  */
  34.  
  35. void ClearPatch(X,Y,W,H)
  36. short X,Y,W,H;
  37. {
  38.    register short i;
  39.    short x,y,w,h;
  40.    
  41.    x = X * CellSize + BoardX + 1;
  42.    y = Y * CellSize + BoardY + 1;
  43.    w = W * CellSize + x - 2;
  44.    h = H * CellSize + y - 2;
  45.  
  46.    SetAPen(rp,SHADOW);
  47.    RectFill(rp,x,y,w,h);
  48.    SetAPen(rp,GRID);
  49.  
  50.    W += X; H += Y;
  51.    for (i=Y+1, Y=y+CellSize-1; i<H; i++,Y+=CellSize)
  52.    {
  53.       Move(rp,x,Y);
  54.       Draw(rp,w,Y);
  55.    }
  56.    for (i=X+1, X=x+CellSize-1; i<W; i++,X+=CellSize)
  57.    {
  58.       Move(rp,X,y);
  59.       Draw(rp,X,h);
  60.    }
  61. }
  62.  
  63.  
  64. /*
  65.  *  ClearScreen()
  66.  *
  67.  *  Clear the board area to backgound, then clear the grid to black
  68.  *  Draw the border around the grid area
  69.  *  Update the screen from the double buffer, if necessary.
  70.  */
  71.  
  72. void ClearScreen(update)
  73. int update;
  74. {
  75.    SetDrMd(rp,JAM1);
  76.    SetAPen(rp,FOREGROUND);
  77.    RectFill(rp,0,0,BOARDW-1,BOARDH-1);
  78.    ClearPatch(0,0,GridW,GridH);
  79.    Move(rp,BoardX,BoardY);
  80.    Draw(rp,BoardX,BoardH+1);
  81.    Draw(rp,BoardW+1,BoardH+1);
  82.    Draw(rp,BoardW+1,BoardY);
  83.    Draw(rp,BoardX,BoardY);
  84.    if (update) UpdateScreen();
  85. }
  86.  
  87.  
  88. /*
  89.  *  ScrollScreen()
  90.  *
  91.  *  Scroll the grid area by the specified amount, clearing the new area
  92.  *  If there was a move in the X direction, refresh the frame for that patch
  93.  *  If there was a move in the Y direction, refresh the frame for that path
  94.  */
  95.  
  96. void ScrollScreen(dx,dy)
  97. short dx,dy;
  98. {
  99.    register short x,y;
  100.  
  101.    SetDrMd(rp,JAM1);
  102.    SetAPen(rp,BACKGROUND);
  103.    SetBPen(rp,SHADOW);
  104.    dx *= CellSize;
  105.    dy *= CellSize;
  106.    ScrollRaster(rp,dx,dy,BoardX,BoardY,BoardW+1,BoardH+1);
  107.    if (dx)
  108.    {
  109.       x = (dx < 0)? BoardX: BoardW+1;
  110.       Move(rp,x-dx,BoardY);
  111.       Draw(rp,x,BoardY);
  112.       Draw(rp,x,BoardH+1);
  113.       Draw(rp,x-dx,BoardH+1);
  114.    }
  115.    if (dy)
  116.    {
  117.       y = (dy < 0)? BoardY: BoardH+1;
  118.       Move(rp,BoardX,y-dy);
  119.       Draw(rp,BoardX,y);
  120.       Draw(rp,BoardW+1,y);
  121.       Draw(rp,BoardW+1,y-dy);
  122.    }
  123. }
  124.  
  125.  
  126. /*
  127.  *  RefreshWithSelect()
  128.  *
  129.  *  For each cell in the selected patch
  130.  *    If we are moving or copying and the cell is selected
  131.  *      set the pen according to whether the selection is being dragged or not
  132.  *    Otherwise set the pen to the unselected cell color
  133.  *    If the pen is not the blank color, refresh it on screen
  134.  *    If we are selecing cells, and the cell is selected, and we are not 
  135.  *      moving or copying cells, draw a box around the cell
  136.  */
  137.  
  138. void RefreshWithSelect(x,y,w,h,Grid)
  139. short x,y,w,h;
  140. UBYTE Grid[];
  141. {
  142.    register short X,Y;
  143.    register short i;
  144.    register int Pen;
  145.    int MoveCopy = (MouseMoveType == MM_MOVE || MouseMoveType == MM_COPY);
  146.  
  147.    for (Y=y; Y<y+h; Y++)
  148.    {
  149.       for (X=x, i=GridX+X+MAXGRIDW*(GridY+Y); X<x+w; X++,i++)
  150.       {
  151.          if (MoveCopy && CellSelected(i))
  152.             Pen = (SelectType == SEL_WAIT)? SELECTPEN: MOVEPEN;
  153.            else
  154.             Pen = Grid[i];
  155.          if (Pen != BLANK) ColorScreenCell(X,Y,Pen);
  156.          if (SelectType && NewGen[i] && MoveCopy == FALSE)
  157.             BoxCell(rp,X,Y,MOVEPEN);
  158.       }
  159.    }
  160. }
  161.  
  162.  
  163. /*
  164.  *  RefreshNoSelect()
  165.  *
  166.  *  For each cell in the selected patch
  167.  *    if the cell is not blank, set the screen to that cell's color
  168.  */
  169.  
  170. void RefreshNoSelect(x,y,w,h,Grid)
  171. short x,y,w,h;
  172. UBYTE Grid[];
  173. {
  174.    register short X,Y;
  175.    register short i;
  176.  
  177.    for (Y=y; Y<y+h; Y++)
  178.    {
  179.       for (X=x, i=GridX+X+MAXGRIDW*(GridY+Y); X<x+w; X++,i++)
  180.          if (Grid[i] != BLANK) ColorScreenCell(X,Y,Grid[i]);
  181.    }
  182. }
  183.  
  184.  
  185. /*
  186.  *  RefreshPatch()
  187.  *
  188.  *  Call the correct refresh routine on the selected patch
  189.  */
  190.  
  191. void RefreshPatch(x,y,w,h,Grid)
  192. short x,y,w,h;
  193. UBYTE Grid[];
  194. {
  195.    if (SelectType)
  196.       RefreshWithSelect(x,y,w,h,Grid);
  197.      else
  198.       RefreshNoSelect(x,y,w,h,Grid);
  199. }
  200.  
  201.  
  202. /*
  203.  *  RefreshScreen()
  204.  *
  205.  *  Refresh the entire visible grid area
  206.  */
  207.  
  208. void RefreshScreen(Grid)
  209. UBYTE Grid[];
  210. {
  211.    RefreshPatch(0,0,GridW,GridH,Grid);
  212.    UpdateScreen();
  213. }
  214.  
  215.  
  216. /*
  217.  *  RefreshSelect()
  218.  *
  219.  *  For each cell in the visible area
  220.  *    If the cell is selected
  221.  *      set the pen color appropriately
  222.  *      set the color of the cell on the screen
  223.  *      if we are in select mode and the cell is selected and we are not moving
  224.  *        or copying, box the selected cell
  225.  *  refresh the screen from the double buffer
  226.  */
  227.  
  228. void RefreshSelect(Grid)
  229. UBYTE Grid[];
  230. {
  231.    register short X,Y;
  232.    register short i;
  233.    register int Pen;
  234.    int MoveCopy = (MouseMoveType == MM_MOVE || MouseMoveType == MM_COPY);
  235.    int SelectPen = (SelectType == SEL_WAIT)? SELECTPEN: MOVEPEN;
  236.  
  237.    for (Y=0; Y<GridH; Y++)
  238.    {
  239.       for (X=0, i=GridX+X+MAXGRIDW*(GridY+Y); X<GridW; X++,i++)
  240.       {
  241.          if (CellSelected(i))
  242.          {
  243.             if (MoveCopy) Pen = SelectPen; else Pen = Grid[i];
  244.             ColorScreenCell(X,Y,Pen);
  245.             if (SelectType && NewGen[i] && MoveCopy == FALSE)
  246.                BoxCell(rp,X,Y,MOVEPEN);
  247.          }
  248.       }
  249.    }
  250.    UpdateScreen();
  251. }
  252.  
  253.  
  254. /*
  255.  *  Macros for dealing with colors, and the default color table
  256.  */
  257.  
  258. #define BADVAL(c)       ((c)<0||(c)>15)
  259. #define COLOR(r,g,b)    (((r)<<8)|((g)<<4)|(b))
  260. #define RED(c)          (((c)>>8)&0x0F)
  261. #define GREEN(c)        (((c)>>4)&0x0F)
  262. #define BLUE(c)         ((c)&0x0F)
  263. static UWORD Color[] =
  264. {
  265.    COLOR( 4, 6, 5),         /* background color */
  266.    COLOR(14,15,12),         /* highlight color */
  267.    COLOR( 8,10, 8),         /* foreground color */
  268.    COLOR( 0, 3, 2),         /* shadow color */
  269.    COLOR(15,12, 9),         /* TAIL color */
  270.    COLOR(15, 9, 0),         /* HEAD color */
  271.    COLOR( 9, 6, 1),         /* inverted button color */
  272.    COLOR( 0,10, 0),         /* WIRE color */
  273. };
  274. static UWORD PointerColor;
  275.  
  276.  
  277. /*
  278.  *  COlorVal()
  279.  *
  280.  *  Convert a hexadecimal character into an integer value
  281.  */
  282.  
  283. static short ColorVal(c)
  284. char c;
  285. {
  286.    short color;
  287.  
  288.    if (c >= '0' && c <= '9')
  289.       color = c - '0';
  290.    else if (c >= 'A' && c <= 'F')
  291.       color = c - 'A' + 10;
  292.    else if (c >= 'a' && c <= 'f')
  293.       color = c - 'a' + 10;
  294.    else color = 16;       /* an illegal value */
  295.    return(color);
  296. }
  297.  
  298.  
  299. /*
  300.  *  ReadColorFile()
  301.  *
  302.  *  Open the color file, if it exists
  303.  *    while there are more colors to read, and more lines in the file
  304.  *      if we can read the next line in the file
  305.  *        if there is something on the line to be considered
  306.  *          if command is '=' (use workbench color) indicate that
  307.  *          otherwise if the command is not '*' (use default color)
  308.  *            get the RGB values from the line
  309.  *            give an error if any is no good, and record them if all OK
  310.  *          go on to the next color
  311.  *      otherwise
  312.  *        warn about problems reading the file
  313.  *    if there are additional lines to read after all the colors are
  314.  *      read in, indicate that they are being ignored
  315.  *    close the file
  316.  */
  317.  
  318. void ReadColorFile()
  319. {
  320.    FILE *InFile;
  321.    char Line[MAXLINE];
  322.    short i = 0;
  323.    short R,G,B;
  324.    
  325.    InFile = fopen(COLORFILE,"r");
  326.    if (InFile)
  327.    {
  328.       while (i<(1<<SCREEND) && !feof(InFile))
  329.       {
  330.          if (fgets(Line,MAXLINE-1,InFile))
  331.          {
  332.             if (Line[0] && Line[0] != ' ' && Line[0] != '\n')
  333.             {
  334.                if (Line[0] == '=')
  335.                {
  336.                   Color[i] = WBCOLOR;
  337.                } else if (Line[0] != '*') {
  338.                   R = ColorVal(Line[0]);
  339.                   G = ColorVal(Line[1]);
  340.                   B = ColorVal(Line[2]);
  341.                   if (strlen(Line) < 4 || BADVAL(R) || BADVAL(G) || BADVAL(B))
  342.                      printf("Invalid Color:  %s",Line);
  343.                     else
  344.                      Color[i] = COLOR(R,G,B);
  345.                }
  346.                i++;
  347.             }
  348.          } else {
  349.             printf("Unexpected End of Color File\n");
  350.          }
  351.       }
  352.       if (fgets(Line,MAXLINE,InFile))
  353.          printf("Extra Lines in Color File Ignored\n");
  354.       fclose(InFile);
  355.    }
  356. }
  357.  
  358.  
  359. /*
  360.  *  LoadColors()
  361.  *
  362.  *  For every color in the table that was supposed to come from the workbench
  363.  *    set the color table to that color
  364.  *  Set the screen's color table
  365.  *  Read the preferences setting for the pointer's standard color
  366.  */
  367.  
  368. void LoadColors()
  369. {
  370.    struct Preferences thePreferences;
  371.    short i;
  372.    short Depth = 1 << myScreen->BitMap.Depth;
  373.  
  374.    for (i=0; i<Depth; i++)
  375.       if (Color[i] == WBCOLOR)
  376.           Color[i] = GetRGB4(myScreen->ViewPort.ColorMap,i);
  377.    LoadRGB4(&(myScreen->ViewPort),&Color[0],Depth);
  378.    GetPrefs(&thePreferences,sizeof(struct Preferences));
  379.    PointerColor = thePreferences.color18;
  380. }
  381.  
  382.  
  383. /*
  384.  *  SetPointerColor()
  385.  *
  386.  *  Set the screen's pointer color to the indicated color values for the
  387.  *  specified color in the color table
  388.  */
  389.  
  390. void SetPointerColor(i)
  391. short i;
  392. {
  393.    SetRGB4(&(myScreen->ViewPort),POINTERPEN,
  394.       RED(Color[i]),GREEN(Color[i]),BLUE(Color[i]));
  395. }
  396.  
  397.  
  398. /*
  399.  *  RestorePointerColor()
  400.  *
  401.  *  Set the pointer color to the default preferences color
  402.  */
  403.  
  404. void RestorePointerColor()
  405. {
  406.    SetRGB4(&(myScreen->ViewPort),POINTERPEN,
  407.       RED(PointerColor),GREEN(PointerColor),BLUE(PointerColor));
  408. }
  409.