home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / STK100.ZIP / SPREDSRC.COM / SPREDIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-20  |  13.7 KB  |  396 lines

  1. /**********************************************************************
  2. * spredio.c
  3. * Routines for screen painting and message generation
  4. **********************************************************************
  5.                     This file is part of
  6.  
  7.          STK -- The sprite toolkit -- version 1.0
  8.  
  9.               Copyright (C) Jari Karjala 1990
  10.  
  11. The sprite toolkit (STK) is a FreeWare toolkit for creating high
  12. resolution sprite graphics with PCompatible hardware. This toolkit 
  13. is provided as is without any warranty or such thing. See the file
  14. COPYING for further information.
  15.  
  16. **********************************************************************/
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <ctype.h>
  22. #include <conio.h>
  23. #include <graphics.h>
  24.  
  25. #include "grtypes.h"
  26. #include "gr.h"
  27. #include "mouse.h"
  28.  
  29. #include "spred.h"
  30. #include "spredio.h"
  31.  
  32. /** pointer already disabled **/
  33. int pointer_disabled = 0;
  34.  
  35. /** previously selected button **/
  36. int prev_button = 0;
  37.  
  38.  
  39. /**********************************************************************
  40. * Screen items
  41. **********************************************************************/
  42. typedef struct _screen_item {
  43.     int x1,y1,x2,y2;    /* positive from left/top, negative from right/bot */
  44.     MSG msg;
  45.     char *text;         /* max 14 char. (14*8<116) */
  46.     int hotkey;
  47. } SCREEN_ITEM;
  48.     
  49. #define LEF(sip) ((sip)->x1>=0 ? (sip)->x1 : gr_max_x + (sip)->x1)
  50. #define RIG(sip) ((sip)->x2>=0 ? (sip)->x2 : gr_max_x + (sip)->x2)
  51. #define TOP(sip) ((sip)->y1>=0 ? (sip)->y1 : gr_max_y + (sip)->y1)
  52. #define BOT(sip) ((sip)->y2>=0 ? (sip)->y2 : gr_max_y + (sip)->y2)
  53.  
  54. /**********************************************************************
  55. * The screen layout definition.
  56. * - The first entry must be big bitmap, 
  57. * - the second the shape button,
  58. * - the third mask button (must be as large as the shape button),
  59. * - the rest are little text buttons.
  60. **********************************************************************/
  61. SCREEN_ITEM screen_def[] = {
  62.      120,   0,  -1, 240, MSG_NONE,           NULL,          -1,
  63.        0,   0, 120, 120, MSG_ACTIVATE_SHAPE, "Shape",       's',
  64.        0, 120, 120, 240, MSG_ACTIVATE_MASK,  "Mask",        'm',
  65.     /*** first column buttons ***/
  66.        0,-100, 118, -90, MSG_CLEAR,         "Clear",        256*46,
  67.        0, -88, 118, -78, MSG_LOAD,          "Load",         256*38,
  68.        0, -76, 118, -66, MSG_SAVE,          "Save",         256*31,
  69.        0, -64, 118, -54, MSG_NEXT,          "Next Sprite",  256*49,
  70.        0, -52, 118, -42, MSG_PREV,          "Prev Sprite",  256*25,
  71.        0, -40, 118, -30, MSG_EXIT,          "Save & Exit",  256*45,
  72.        0, -28, 118, -16, MSG_QUIT,          "Quit",         256*16,
  73.     /*** second column buttons ***/
  74.      120,-100, 238, -90, MSG_INVERT,        "Invert",       'i',
  75.      120, -88, 238, -78, MSG_FATTER,        "Make Fatter",  'f',
  76.      120, -76, 238, -66, MSG_THINNER,       "Make Thinner", 't',
  77.      120, -64, 238, -54, MSG_OVERLAY,       "Overlay",      'o',
  78.      120, -52, 238, -42, MSG_NONE,          "",             -1,
  79.      120, -40, 238, -30, MSG_COPY_TO_MASK,  "Shape -> Mask",-1,
  80.      120, -28, 238, -16, MSG_COPY_TO_SHAPE, "Mask -> Shape",-1,
  81.     /*** third column buttons ***/
  82.      240,-100, 358, -90, MSG_HFLIP,         "Horiz Flip",   'h',
  83.      240, -88, 358, -78, MSG_VFLIP,         "Vert Flip",    'v',
  84.      240, -76, 358, -66, MSG_HMIRROR,       "Horiz Mirror", -1,
  85.      240, -64, 358, -54, MSG_VMIRROR,       "Vert Mirror",  -1,
  86.      240, -52, 358, -42, MSG_ROTATE,        "Rotate",       -1,
  87.      240, -40, 358, -30, MSG_ROTATE90,      "Rotate 90deg", 'r', 
  88.      240, -28, 358, -16, MSG_NONE,          "",             -1,
  89.          
  90.        0,   0,   0,   0, 0, NULL
  91. };
  92.  
  93.  
  94. /**********************************************************************
  95. * Print the message, clear old message
  96. **********************************************************************/
  97. void message(char *s,...)
  98. {
  99.     char buf[100];
  100.     va_list argptr;
  101.  
  102.     va_start(argptr,100);
  103.     vsprintf(buf,s,argptr);
  104.     va_end(argptr);
  105.     
  106.     setfillstyle(EMPTY_FILL,0);
  107.     bar(0,gr_max_y-10, gr_max_x, gr_max_y);
  108.     moveto(0,gr_max_y-10);
  109.     mouse_hide_pointer();
  110.     gr_printf(buf);
  111.     mouse_show_pointer();
  112. }
  113.  
  114. /**********************************************************************
  115. * Draw the given button type screen item
  116. **********************************************************************/
  117. void draw_button_item(SCREEN_ITEM *sip)
  118. {
  119.     int oldcolor;
  120.  
  121.     oldcolor = getcolor();
  122.     setfillstyle(SOLID_FILL,getmaxcolor());
  123.     bar(LEF(sip), TOP(sip), RIG(sip), BOT(sip));
  124.     settextstyle(DEFAULT_FONT,0,1); 
  125.     setcolor(0);
  126.     outtextxy(LEF(sip)+((RIG(sip)-LEF(sip)-textwidth(sip->text)) >> 1),
  127.               TOP(sip)+((BOT(sip)-TOP(sip)-textheight(sip->text)) >> 1)+1, 
  128.               sip->text);
  129.     setcolor(oldcolor);    
  130.     setfillstyle(EMPTY_FILL,0);
  131. }
  132.  
  133. /**********************************************************************
  134. * highlight the given button type screen item
  135. **********************************************************************/
  136. void highlight_button_item(SCREEN_ITEM *sip)
  137. {
  138.     int oldcolor;
  139.  
  140.     mouse_hide_pointer();
  141.     oldcolor = getcolor();
  142.     setwritemode(1);
  143.     rectangle(LEF(sip)+1, TOP(sip)+1, RIG(sip)-1, BOT(sip)-1);
  144.     setwritemode(0);
  145.     setcolor(oldcolor);    
  146.     mouse_show_pointer();
  147. }
  148.  
  149. /**********************************************************************
  150. * Draw a point in the i:th map (shape/mask) of sprite.
  151. * If i & DOT_OVERLAY then the other map is overlayed.
  152. **********************************************************************/
  153. void draw_point(SPRED_DATA *sdp, int x, int y, int i)
  154. {
  155.     int xofs, yofs, overlay, max_col;
  156.  
  157.     max_col = getmaxcolor();
  158.     overlay = (i & DOT_OVERLAY);
  159.     i &= 0xFF;
  160.  
  161.     if (!pointer_disabled)
  162.         mouse_hide_pointer();
  163.  
  164.     /** draw the little bitmap **/
  165.     xofs = (RIG(&screen_def[1]) - LEF(&screen_def[1]) - sdp->w) / 2;
  166.     yofs = (BOT(&screen_def[1]) - TOP(&screen_def[1]) - sdp->h) / 2;
  167.     if (i == SPR_SHAPE)
  168.         putpixel(x+xofs, y+yofs, 
  169.                  max_col*sdp->maps[i][x][y]);
  170.     else
  171.         putpixel(x+xofs, y+yofs+TOP(&screen_def[2]), 
  172.                  max_col*sdp->maps[i][x][y]);
  173.              
  174.     /** draw the big bitmap **/
  175.     xofs = sdp->wo + x*sdp->ws; 
  176.     yofs = sdp->ho + y*sdp->hs;
  177.     
  178.     if (i==sdp->map) {
  179.         if (sdp->maps[i][x][y]!=DOT_BACKGROUND) {
  180.             setfillstyle(SOLID_FILL, max_col);
  181.             bar(xofs, yofs, xofs + sdp->ws - 1, yofs + sdp->hs - 1);
  182.         }
  183.         else {
  184.             setfillstyle(EMPTY_FILL, 0);
  185.             bar(xofs, yofs, xofs + sdp->ws - 1, yofs + sdp->hs - 1);
  186.             
  187.             if (sdp->ws > 4) {  /** no corner dots, if grid too small **/
  188.                 putpixel(xofs, yofs, max_col);
  189.                 putpixel(xofs + sdp->ws-1, yofs, max_col);
  190.                 putpixel(xofs, yofs + sdp->hs - 1, max_col);
  191.                 putpixel(xofs + sdp->ws - 1, yofs + sdp->hs - 1, max_col);
  192.             }
  193.         }   
  194.     }
  195.     /** draw the other map overlayed, if requested **/
  196.     if (overlay) {
  197.         int s;
  198.         s = sdp->ws / 3;
  199.         if (sdp->maps[ (i==0) ][x][y]!=0)
  200.             setfillstyle(SOLID_FILL, max_col);
  201.         else
  202.             setfillstyle(EMPTY_FILL, 0);
  203.         bar(xofs + s,  yofs + s, xofs + sdp->ws - s ,  yofs + sdp->hs - s);
  204.     }
  205.  
  206.     if (!pointer_disabled)
  207.         mouse_show_pointer();
  208. }
  209.  
  210. /**********************************************************************
  211. * Draw the ind:th map (shape/mask) of the given sprite (bigmap too, 
  212. * if active).
  213. * Pointer is disabled if it is inside map area, otherwise it is
  214. * only restricted into menu area.
  215. **********************************************************************/
  216. void draw_map(SPRED_DATA *sdp, int ind)
  217. {
  218.     int i,j, x, y;
  219.  
  220.     mouse_get_pointer_xy(&x,&y);
  221.     mouse_set_pointer_shape(0,0,mouse_pointer_hourglass);
  222.     if (y>BOT(&screen_def[0])) {
  223.         pointer_disabled = 1;
  224.         mouse_set_pointer_window(0,BOT(&screen_def[0]),gr_max_x,gr_max_y);
  225.     }
  226.     
  227.     if (sdp->map == ind && 0xFF)
  228.         rectangle(sdp->wo-1, sdp->ho-1,
  229.                   sdp->wo + sdp->w*sdp->ws, sdp->ho + sdp->h*sdp->hs);
  230.  
  231.     moveto(LEF(&screen_def[0])+2, TOP(&screen_def[0])+2);
  232.     if (sdp->map==SPR_SHAPE)
  233.         gr_puts("Shape bitmap");
  234.     else
  235.         gr_puts("Mask bitmap ");
  236.               
  237.     for (i=0; i<sdp->h; i++)
  238.         for (j=0; j<sdp->w; j++)
  239.             draw_point(sdp, j, i, ind);
  240.         
  241.     pointer_disabled = 0;
  242.     mouse_set_pointer_window(0,0,getmaxx(),getmaxy());
  243.     mouse_set_pointer_shape(1,1,mouse_pointer_arrow);
  244. }
  245.  
  246. /**********************************************************************
  247. * Draw the screen layout. Must be called before any other draw function.
  248. **********************************************************************/
  249. void draw_screen(SPRED_DATA *sdp)
  250. {
  251.     int i;
  252.     
  253.     mouse_hide_pointer();
  254.     
  255.     bar(LEF(&screen_def[0])+1, TOP(&screen_def[0])+1, 
  256.         RIG(&screen_def[0])-1, BOT(&screen_def[0])-1);
  257.     rectangle(LEF(&screen_def[0]), TOP(&screen_def[0]), 
  258.               RIG(&screen_def[0]), BOT(&screen_def[0]));
  259.           
  260.     bar(LEF(&screen_def[1])+1, TOP(&screen_def[1])+1, 
  261.         RIG(&screen_def[1])-1, BOT(&screen_def[1])-1);
  262.     outtextxy(LEF(&screen_def[1])+2, TOP(&screen_def[1])+2,
  263.               screen_def[1].text);
  264.     rectangle(LEF(&screen_def[1]), TOP(&screen_def[1]), 
  265.               RIG(&screen_def[1]), BOT(&screen_def[1]));
  266.           
  267.     bar(LEF(&screen_def[2])+1, TOP(&screen_def[2])+1,
  268.         RIG(&screen_def[2])-1, BOT(&screen_def[2])-1);
  269.     outtextxy(LEF(&screen_def[2])+2, TOP(&screen_def[2])+2,
  270.               screen_def[2].text);
  271.     rectangle(LEF(&screen_def[2]), TOP(&screen_def[2]), 
  272.               RIG(&screen_def[2]), BOT(&screen_def[2]));
  273.  
  274.     i = 3;
  275.     while((screen_def[i].x1 | screen_def[i].x2 |
  276.            screen_def[i].y1 | screen_def[i].y2) != 0)
  277.                draw_button_item(&screen_def[i++]);
  278.     
  279.     sdp->hs = (BOT(&screen_def[0]) - TOP(&screen_def[0])) / (sdp->h+1);
  280.     sdp->ws = (RIG(&screen_def[0]) - LEF(&screen_def[0])) / (sdp->w+1);
  281.     if (sdp->ws < sdp->hs)  /** take smallest **/
  282.         sdp->hs = sdp->ws;
  283.     else
  284.         sdp->ws = sdp->hs;
  285.     if (sdp->hs<3)          /** no smaller than 3 **/
  286.         sdp->hs = 3;
  287.     
  288.     sdp->wo = LEF(&screen_def[0]) +
  289.               (RIG(&screen_def[0]) - LEF(&screen_def[0]) - sdp->w*sdp->ws)/2;
  290.                
  291.     sdp->ho = (BOT(&screen_def[0]) - TOP(&screen_def[0]) - sdp->h*sdp->hs)/2;
  292.  
  293.     draw_map(sdp, SPR_SHAPE);
  294.     draw_map(sdp, SPR_MASK);
  295.  
  296.     mouse_show_pointer();
  297.     prev_button = 0;    /** no buttons selected **/
  298. }
  299.  
  300.  
  301. /**********************************************************************
  302. * Find the screen item in the given position form the screen_def array.
  303. * Return: index into array or negative if no match.
  304. **********************************************************************/
  305. int find_clicked_item(int x, int y)
  306. {
  307.     int i;
  308.     
  309.     i = 0;
  310.     while((screen_def[i].x1 | screen_def[i].x2 |
  311.            screen_def[i].y1 | screen_def[i].y2) != 0) {
  312.                if (x>LEF(&screen_def[i]) && y>TOP(&screen_def[i]) &&
  313.                    x<RIG(&screen_def[i]) && y<BOT(&screen_def[i]))
  314.                        return i;
  315.            i++;
  316.     }
  317.     return -1;
  318. }
  319.  
  320. /**********************************************************************
  321. * Find the screen item matching the given hotkey.
  322. * Return: index into array or negative if no match.
  323. **********************************************************************/
  324. int find_hotkeyed_item(int ch)
  325. {
  326.     int i;
  327.     
  328.     i = 0;
  329.     while((screen_def[i].x1 | screen_def[i].x2 |
  330.            screen_def[i].y1 | screen_def[i].y2) != 0) {
  331.                if (screen_def[i].hotkey == ch)
  332.                        return i;
  333.            i++;
  334.     }
  335.     return -1;
  336. }
  337.  
  338. /**********************************************************************
  339. * Checks for user interaction.
  340. * Return: The event message, and the *x & *y contain the click point
  341. *          in big map coordinates (ie 0..sdp->w-1 and 0..sdp->h-1).
  342. **********************************************************************/
  343. MSG get_msg(SPRED_DATA *sdp, int *xp, int *yp)
  344. {
  345.     int buttons, i;
  346.     MSG msg = MSG_NONE;
  347.  
  348.     if (prev_button > 0) {
  349.         highlight_button_item(&screen_def[prev_button]);
  350.         prev_button = 0;
  351.     }
  352.             
  353.     buttons = mouse_get_buttons();
  354.     mouse_get_pointer_xy(xp,yp);
  355.     if (buttons!=0) {
  356.         i = find_clicked_item(*xp, *yp);
  357.         if (i>0) {
  358.             prev_button = i;
  359.             highlight_button_item(&screen_def[prev_button]);            
  360.             msg = screen_def[i].msg;
  361.         }
  362.         else if (i==0) {
  363.             switch (buttons) {
  364.             case BUTTON_LEFT   : msg = MSG_BTN1_CLICK;
  365.                 break;
  366.             case BUTTON_RIGHT  : msg = MSG_BTN3_CLICK;
  367.                 break;
  368.             case BUTTON_MS_MIDDLE:
  369.             case BUTTON_MIDDLE : msg = MSG_BTN2_CLICK;
  370.                 break;
  371.             }
  372.             *xp = (*xp - sdp->wo)/sdp->ws;
  373.             *yp = (*yp - sdp->ho)/sdp->hs;
  374.             
  375.             if (*xp<0 || *yp<0 || *xp >= sdp->w || *yp >= sdp->h)
  376.                 msg = MSG_NONE; /* out of big bitmap */
  377.         }
  378.     }
  379.     else if (kbhit()) {
  380.         int ch = getch();
  381.  
  382.         if (ch==0)  /** special key, put significant part into high byte **/
  383.             ch = getch()<<8;
  384.         
  385.         i = find_hotkeyed_item(ch);
  386.         if (i>0) {
  387.             prev_button = i;
  388.             highlight_button_item(&screen_def[prev_button]);            
  389.             msg = screen_def[i].msg;
  390.         }
  391.     }
  392.     return msg;
  393. }
  394.