home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / DVPG30FS.ZIP / JVDRAW.C < prev    next >
C/C++ Source or Header  |  1993-12-04  |  17KB  |  571 lines

  1. /*
  2.  *  drawing routines for dvpeg
  3.  *
  4.  */
  5.  
  6. #include "viewdef.h"
  7. #include "extern.h"
  8.  
  9. #include <dos.h>
  10. #include <conio.h>
  11. #include <alloc.h>
  12.  
  13.  
  14.  
  15.  
  16. /*
  17.  * setup the color pallet
  18.  *  - apply all tint controls to the global pallet and write it out
  19.  *  - assume setup_image_info has been called and all tint_factors are setup
  20. uses:
  21. #define new_tint(data, tf_2) ( (((int)data * tint_factor_1) >> 6) + tf_2 )
  22.  */
  23.  
  24. void setup_pallet(void)
  25. {
  26. unsigned char    pallet[256][3];    /* duplicate pallete for contrast / brightness */
  27. int i, red, green, blue, max, min, temp, max_index, min_index;
  28. union REGS regs;
  29.  
  30. max = -1;        /* find max, minimum brightness pallet colors - regardless of color clashing ;-) */
  31. min = 32760;
  32.  
  33. for (i = 0; i < 256; i++){
  34.     /* first init the pallet so that any colors that are not updated are at least at their default */
  35.     red = palbuf[i][0];
  36.     green = palbuf[i][1];
  37.     blue = palbuf[i][2];
  38.  
  39.     pallet[i][0] = red >> 2;
  40.     pallet[i][1] = green >> 2;
  41.     pallet[i][2] = blue >> 2;
  42.  
  43.     red += new_tint(red, tint_factor_red);
  44.     green += new_tint(green, tint_factor_green);
  45.     blue += new_tint(blue, tint_factor_blue);
  46.     if (((red | green | blue) & 0xff00) == 0){
  47. /*    if (red < 256 && green < 256 && blue < 256 && red >= 0 && green >= 0 && blue >= 0){*/
  48.         pallet[i][0] = red >> 2;    /* only change if no color wrapping > 64 */
  49.         pallet[i][1] = green >> 2;
  50.         pallet[i][2] = blue >> 2;
  51.         }
  52.     if (i < number_pallet_colors){
  53.         temp = (int)pallet[i][0] + pallet[i][1] + pallet[i][2];        /* (quick and dirty magnitude calculation */
  54.         if (temp > max){
  55.             max_index = i;
  56.             max = temp;
  57.             }
  58.         if (temp < min){
  59.             min_index = i;
  60.             min = temp;
  61.             }
  62.         }
  63.     }
  64. text_drawing_for = max_index;        /* set text drawing colors */
  65. text_drawing_bk = min_index;
  66.  
  67. setmany(pallet, 0, 256);
  68.  
  69. /* If using only VGA then set the EGA pallet to point index properly into the SVGA one */
  70. if (video_resolution == VGA)
  71.     for (i = 0; i < 16; i++){
  72.         regs.h.bl = i;
  73.         regs.h.bh = i;
  74.         regs.x.ax = 0x1000;
  75.         int86(0x10, ®s, ®s);
  76.         }
  77. }
  78.  
  79.  
  80.  
  81.  
  82. /*
  83.  * setup tint controls for tinting the pallet or screen
  84.  * this converts the tint controls to values that are faster to process
  85.  *
  86.  * then setup the viewing variables for _all_ drawing routines
  87.  *  this assumes that we know the video mode and what part of the image should
  88.  *  be at the center of the screen
  89.  */
  90.  
  91. #define mod_limit(value) ((value) - ((value) % zoom_inc_factor))
  92.  
  93. void setup_image_info(void)
  94. {
  95. int zoom_inc_factor;
  96.  
  97. /* now the byte increment per pixel */
  98. switch (video_resolution){
  99.     case VGA:
  100.     case SVGA:
  101.         bytes_per_pixel = 1;
  102.         break;
  103.     case SVGA_15_bit:
  104.     case SVGA_16_bit:
  105.         bytes_per_pixel = 2;
  106.         break;
  107.     case SVGA_24_bit:
  108.         bytes_per_pixel = 3;
  109.     }
  110.  
  111. zoom_inc_factor = 5 - zoom_inc;        /* this is the scaling for S/W zooming in */
  112.  
  113. tint_factor_1 = color_scale + contrast_scale;        /* result is -127 to + 127 */
  114. tint_lookup = tint_factor_1 + 128;        /* scale tint factor 1 to get 0 .. 255 */
  115. tint_factor_red = red_tint - (contrast_scale << 1);
  116. tint_factor_green = green_tint - (contrast_scale << 1);
  117. tint_factor_blue = blue_tint - (contrast_scale << 1);
  118.  
  119.  
  120. /* first start off by figuring out how many pixels are available in each dimension
  121.  * and then figure out what the picture will use
  122.  *
  123.  * variables: imageXXXXX are the screen pixels
  124.  *            pictureXXX are the picture elements
  125.  * now image or picture are XX, and ? is x or y:
  126.  *      XX_?_dim = ? dimension, ie width show/used
  127.  *      XX_?_max = ? maximum value, ie maximum pixel drawn or picture element drawn
  128.  *      XX_?_offset = ? start value, ie the first pixel or picture element drawn
  129.  *      picture_?_center = center of the picture in picture elements as drawn on the screen
  130.  */
  131.  
  132. /* set up screen limits */
  133. x_max = video_cards[video_mode_used].x_size;
  134. y_max = video_cards[video_mode_used].y_size;
  135.  
  136. /*             X Axis */
  137.  
  138. image_x_offset = 0;
  139. image_x_dim = mod_limit(x_max);
  140. picture_x_dim = image_x_dim * shrink / zoom_inc_factor;
  141. if (picture_x_dim > picture_x_size){    /* test if screen > picture */
  142.     picture_x_dim = picture_x_size;
  143.     image_x_dim = picture_x_dim / shrink * zoom_inc_factor;
  144.     image_x_offset = (x_max - image_x_dim) >> 1;
  145.     picture_x_center = picture_x_size >> 1;
  146.     }
  147.  
  148. picture_x_offset = picture_x_center - (picture_x_dim >> 1);
  149. if (picture_x_offset < 0){        /* case of screen > image; so add offset */
  150.     picture_x_offset = - picture_x_offset;
  151.     }
  152. picture_x_offset = mod_limit(picture_x_offset);
  153.  
  154. /* now check if the screen is presenting a larger dimension that the image
  155.  *  ie the screen < image and being panned off the image
  156.  * or if the image is smaller than the screen but the image is
  157.  * being panned off of the screen */
  158. picture_x_max = picture_x_offset + picture_x_dim;
  159. if (picture_x_max > picture_x_size){
  160.     picture_x_dim = mod_limit(picture_x_size - picture_x_offset);
  161.     picture_x_max = picture_x_offset + picture_x_dim;
  162.     image_x_dim = picture_x_dim / shrink * zoom_inc_factor;
  163.     }
  164. image_x_max = image_x_offset + image_x_dim;
  165.  
  166. /*             Y Axis */
  167.  
  168. image_y_offset = 0;
  169. image_y_dim = mod_limit(y_max);
  170. picture_y_dim = image_y_dim * shrink / zoom_inc_factor;
  171. if (picture_y_dim > picture_y_size){
  172.     picture_y_dim = picture_y_size;
  173.     image_y_dim = picture_y_dim * zoom_inc_factor / shrink;
  174.     image_y_offset = (y_max - image_y_dim) >> 1;
  175.     picture_y_center = picture_y_size >> 1;
  176.     }
  177.  
  178. picture_y_offset = picture_y_center - (picture_y_dim >> 1);
  179. if (picture_y_offset < 0){        /* case of screen > image; so add offset */
  180.     picture_y_offset = - picture_y_offset;
  181.     }
  182. picture_y_offset = mod_limit(picture_y_offset);
  183.  
  184. /* now check if the screen is presenting a larger dimension that the image
  185.  *  ie the screen < image and being panned off the image
  186.  * or if the image is smaller than the screen but the image is
  187.  * being panned off of the screen */
  188. picture_y_max = picture_y_offset + picture_y_dim;
  189. if (picture_y_max > picture_y_size){
  190.     picture_y_dim = mod_limit(picture_y_size - picture_y_offset);
  191.     picture_y_max = picture_y_offset + picture_y_dim;
  192.     image_y_dim = picture_y_dim / shrink * zoom_inc_factor;
  193.     }
  194. image_y_max = image_y_offset + image_y_dim;
  195.  
  196. bytes_per_line = picture_x_size * bytes_per_pixel;            /* to copy into picture buffer */
  197. visable_bytes_per_line = image_x_dim * bytes_per_pixel;
  198. }
  199.  
  200.  
  201.  
  202. /*
  203.  * setup a new video mode,
  204.  * reinit the color pallet if required
  205.  * do pallet stuff first so it does not seem like a big time delay
  206.  */
  207.  
  208. void reset_video_mode(void)
  209. {
  210. int i;
  211. int red, green, blue;
  212.  
  213. i = video_cards[video_mode_used].resolution;        /* get the video card type */
  214.  
  215. set_video(video_mode_used);        /* reinitialize video mode only if we really found a good mode */
  216.  
  217. setup_image_info();
  218.  
  219. if (i <= SVGA)
  220.     setup_pallet();
  221. }
  222.  
  223.  
  224.  
  225.  
  226. void output_term (decompress_info_ptr cinfo)
  227. /* Finish up at the end of the output */
  228. {
  229. static int
  230.         y_delta, x_delta,
  231.         redraw,                /* cmd to force redraw */
  232.         step,                    /* step size (pixels) for pan - first used as a keypress counter*/
  233.         video_card_type,    /* a unique # for card using {hicolor, Tseng_hi_color, Ati_hi_color, other_VGA) */
  234.         update_pallet,
  235.         i, j,                    /* indexes for loops */
  236.         zoom_inc_factor,    /* factor due to S/W zoom of image */
  237.         cmd,
  238.         cmd2,
  239.         old_tf1,        /* old tint factor 1, R,G,B tinting values */
  240.         old_red,        /* used for tinting 15/16/24 bit screens in memory */
  241.         old_green,
  242.         old_blue,
  243.         multiplier;            /* multiplier for contrast, tint, bright controls */
  244.  
  245. /* get and save memory free data */
  246. near_memory_view = coreleft();
  247. far_memory_view = farcoreleft();
  248.  
  249. /* write picture file-name/text onto the screen */
  250. if (defaults & show_text)
  251.     writeText(text_line_x, text_line_y, picture_text);
  252.  
  253. /* write picture title onto the screen centered, 8 pixels wide per char, 16 pixels high */
  254. if (defaults & show_title)
  255.     writeText(x_max / 2 - strlen(picture_title) * 4, 10, picture_title);
  256.  
  257. if (view_defaults & beep_on){
  258.     sound(1500);
  259.     delay(150);
  260.     nosound();
  261.     }
  262.  
  263. if (do_slide_show){
  264.     return;
  265.     }
  266.  
  267. redraw = 0;
  268.  
  269. multiplier = 1;
  270.  
  271. /*ERREXIT(cinfo->emethods, "Memory size check");*/
  272.  
  273. old_tf1 = color_scale + contrast_scale;        /* defaults for 15/16/24 bit on screen tinting */
  274. old_red = red_tint;
  275. old_green = green_tint;
  276. old_blue = blue_tint;
  277.  
  278. while(1){
  279.     y_delta = x_delta = redraw = 0;
  280.     step = 0;                                /* assume 1 keypress only */
  281.     cmd = 0;
  282.     update_pallet = 0;
  283.     allow_video_exit = 1;
  284.     while (kbhit()){
  285.         cmd2 = get_key();                        /* count the number of times a key is hit (for panning) */
  286.         if (cmd == 0) cmd = cmd2;
  287.         if (cmd >= 0x3b00 && cmd <= 0x4400) multiplier = (cmd >> 8) - 58;        /* multiplier for contrast, tint, ..*/
  288.         if (cmd2 == cmd) step++;
  289.         if (cmd2 == escape)                        /* if ESC then exit regardless */
  290.             cmd = escape;
  291.         }
  292.  
  293.     step = (step << 4) * multiplier;            /* step 16 pixels per keypress */
  294.  
  295.     zoom_inc_factor = 5 - zoom_inc;            /* this gives a number betwen 1 and 4 (ie * 4 expand) that the S/W expands the image */
  296.     switch (cmd){
  297. #ifndef small_viewer
  298.         case 's':        /* save the picture tint, contrast .... */
  299.         case 'S':
  300.             delete_from_setup_file(file_being_viewed);
  301.             save_viewing_info();
  302.             break;
  303.         case 'd':        /* delete the default info for this file */
  304.         case 'D':
  305.             delete_from_setup_file(file_being_viewed);
  306.             break;
  307. #endif
  308.         case 'R':    /* redraw the screen - also reset video mode to graphics */
  309.             red_tint = green_tint = blue_tint = color_scale = contrast_scale = 0;
  310.         case 'r':    /* don't reset the defaults like R does */
  311.             if (enable_pan){
  312.                 reset_video_mode();
  313.                 redraw = 1;
  314.                 }
  315.             else
  316.                 update_pallet = 1;    /* if can't repaint then try just updating the pallet */
  317.             break;
  318.         case RTN:
  319.         case 'N':
  320.         case 'n':
  321.             show_next_file = 1;
  322.             return;
  323.         case 'P':
  324.         case 'p':
  325.             show_next_file = -1;
  326.             return;
  327.         case minus:
  328.             if (enable_pan){        /* only bother if panning is on */
  329.                 if (shrink == 1){
  330.                     /*
  331.                      * - this works because the list is ordered from smallest to largest
  332.                      * basically look in the video_card list and find the next smallest mode
  333.                      * of the same resolution
  334.                      *
  335.                      * zoom out (ie see more of the image)
  336.                      */
  337.                     if (zoom_inc < 4){
  338.                         zoom_inc++;
  339.                         redraw = 1;
  340.                         }
  341.                     else
  342.                         if (mode_lock < 0 && ((view_defaults & lock_during_pan) == 0))
  343.                             for (i = video_mode_used + 1; i < number_modes_in_list; i++)
  344.                                 /* find the same resolution type if it exists */
  345.                                 if (video_cards[i].card_number >= 0)        /* only bother if its a valid mode */
  346.                                     if (video_cards[video_mode_used].resolution == video_cards[i].resolution){
  347.                                         video_mode_used = i;
  348.                                         reset_video_mode();
  349.                                         i = number_modes_in_list + 2;        /* force exit */
  350.                                         redraw = 1;
  351.                                         shrink = 1;        /* what the heck, maby it fits */
  352.                                         }
  353.                     }
  354.                 if (redraw == 0){        /* if we did not change modes use a S/W shrink */
  355.                     shrink++;
  356.                     if (shrink > max_shrink)
  357.                         shrink = max_shrink;            /* limit to 1/max_shrink size */
  358.                     else
  359.                         redraw = 1;
  360.                     }
  361.                 if (redraw && (view_defaults & clear_during_pan))
  362.                     if (video_card_type == VGA)
  363.                         reset_video_mode();
  364.                     else
  365.                         clear_video_memory(16);
  366.             }
  367.             break;
  368.         case plus:        /* zoom in */
  369.             if (enable_pan){
  370.                 shrink--;
  371.                 if (shrink < 1){                /* limit to 1:1 since can't zoom */
  372.                     shrink = 1;
  373.                     /* now try changing to a smaller video mode ie zooming */
  374.                     /* find the same resolution type if it exists */
  375.                     if (mode_lock < 0 && ((view_defaults & lock_during_pan) == 0))
  376.                         for (i = video_mode_used - 1; i >= 0; i--)
  377.                             if (video_cards[video_mode_used].resolution == video_cards[i].resolution){
  378.                                 video_mode_used = i;
  379.                                 reset_video_mode();
  380.                                 redraw = 1;
  381.                                 break;
  382.                                 }
  383.                     if (redraw == 0)    /* use S/W zoom by pixel doubling, tripling */
  384.                         if (zoom_inc > 0){
  385.                             zoom_inc--;
  386.                             redraw = 1;
  387.                             }
  388.                     }
  389.                 else redraw = 1;
  390.                 }
  391.             break;
  392.         case page_up:
  393.             if (color_scale < 64){
  394.                 color_scale += multiplier;            /* turn up intensity */
  395.                 if (color_scale >= 64){
  396.                     allow_video_exit = 0;
  397.                     color_scale = 64;
  398.                     }
  399.                 update_pallet = 1;
  400.                 }
  401.             break;
  402.         case page_down:
  403.             if (color_scale > -64){
  404.                 color_scale -= multiplier;
  405.                 if (color_scale <= -64){
  406.                     allow_video_exit = 0;
  407.                     color_scale = -64;            /* turn down intensity */
  408.                     }
  409.                 update_pallet = 1;
  410.                 }
  411.             break;
  412.         case arrow_up:
  413.             i = picture_y_dim >> 1;
  414.             if (picture_y_center - i - step > 0)
  415.                 y_delta = -step;
  416.             else
  417.                 if (picture_y_center - i > 0){            /* only do this if the window on the picture can be moved */
  418.                     allow_video_exit = 0;
  419.                     y_delta = i - picture_y_center;        /* move all the way to top */
  420.                     }
  421.             break;
  422.         case arrow_down:
  423.             i = picture_y_dim >> 1;
  424.             if (picture_y_center + step + i < picture_y_size)
  425.                 y_delta = step;
  426.             else
  427.                 if (picture_y_center + i < picture_y_size){
  428.                     allow_video_exit = 0;
  429.                     y_delta = picture_y_size - picture_y_center - i;
  430.                     }
  431.             break;
  432.         case arrow_left:
  433.             i = picture_x_dim >> 1;
  434.             if (picture_x_center - i - step > 0)
  435.                 x_delta = -step;
  436.             else
  437.                 if (picture_x_center - i > 0){
  438.                     x_delta = i - picture_x_center;
  439.                     allow_video_exit = 0;
  440.                     }
  441.             break;
  442.         case arrow_right:
  443.             i = picture_x_dim >> 1;
  444.             if (picture_x_center + step + i < picture_x_size)
  445.                 x_delta = step;
  446.             else
  447.                 if (picture_x_center + i < picture_x_size){
  448.                     allow_video_exit = 0;
  449.                     x_delta = picture_x_size - picture_x_center - i;
  450.                     }
  451.             break;
  452. #ifndef small_viewer
  453.         case red_up:        red_tint += (multiplier << 2);
  454.                                 update_pallet = 1;
  455.                                 break;
  456.         case red_down:
  457.                                 red_tint -= (multiplier << 2);
  458.                                 update_pallet = 1;
  459.                                 break;
  460.         case red_normal:
  461.                                 red_tint = 0;
  462.                                 update_pallet = 1;
  463.                                 break;
  464.         case green_up:
  465.                                 green_tint += (multiplier << 2);
  466.                                 update_pallet = 1;
  467.                                 break;
  468.         case green_down:
  469.                                 green_tint -= (multiplier << 2);
  470.                                 update_pallet = 1;
  471.                                 break;
  472.         case green_normal:
  473.                                 green_tint = 0;
  474.                                 update_pallet = 1;
  475.                                 break;
  476.         case blue_up:
  477.                                 blue_tint += (multiplier << 2);
  478.                                 update_pallet = 1;
  479.                                 break;
  480.         case blue_down:
  481.                                 blue_tint -= (multiplier << 2);
  482.                                 update_pallet = 1;
  483.                                 break;
  484.         case blue_normal:
  485.                                 blue_tint = 0;
  486.                                 update_pallet = 1;
  487.                                 break;
  488. #endif    /* small viewer */
  489.         case escape:
  490.                 return;
  491.         case home:            if (contrast_scale < 64){
  492.                                     contrast_scale += (multiplier << 2);
  493.                                     if (contrast_scale > 64){
  494.                                         allow_video_exit = 0;
  495.                                         contrast_scale = 64;
  496.                                         }
  497.                                     update_pallet = 1;
  498.                                     }
  499.                                 break;
  500.         case end:            if (contrast_scale > -64){
  501.                                     contrast_scale -= (multiplier << 2);
  502.                                     if (contrast_scale < -64){
  503.                                         allow_video_exit = 0;
  504.                                         contrast_scale = -64;
  505.                                         }
  506.                                     update_pallet = 1;
  507.                                     }
  508.                                 break;
  509.         }
  510.  
  511.     if (redraw) allow_video_exit = 0;        /* no exit allowed if complete redraw in progress */
  512.     if (enable_pan && (x_delta != 0 || y_delta != 0 || redraw)){
  513.         picture_x_center += x_delta;
  514.         picture_y_center += y_delta;
  515.         }
  516.     setup_image_info();        /* do the calculations for faster tint controls */
  517.  
  518.     if (update_pallet == 1){
  519. #ifndef small_viewer
  520.         if (video_resolution > SVGA){        /* setup look-up table for tinting */
  521.             for (i = 0; i < 256; i++){
  522.                 tint_table[0][i] = tint_table[1][i] = tint_table[2][i] = 0;        /* default to do nothing */
  523.                 switch(video_resolution){
  524.                     case SVGA_15_bit:
  525.                     case SVGA_16_bit:
  526.                         j = (((i * (tint_factor_1 - old_tf1)) >> 6) + red_tint - old_red) >> 3;
  527.                         if (j > -32 && j < 32) tint_table[0][i] = j;
  528.                         j = ((i * (tint_factor_1 - old_tf1)) >> 6) + green_tint - old_green;
  529.                         if (j > -128 && j < 127) tint_table[1][i] = j;
  530.                         j = ((i * (tint_factor_1 - old_tf1)) >> 6) + blue_tint - old_blue;
  531.                         if (j > -128 && j < 127) tint_table[2][i] = j;
  532.                         break;
  533.                     case SVGA_24_bit:
  534.                         j = ((i * (tint_factor_1 - old_tf1)) >> 6) + red_tint - old_red;
  535.                         if (j > -128 && j < 127) tint_table[0][i] = j;
  536.                         j = ((i * (tint_factor_1 - old_tf1)) >> 6) + green_tint - old_green;
  537.                         if (j > -128 && j < 127) tint_table[1][i] = j;
  538.                         j = ((i * (tint_factor_1 - old_tf1)) >> 6) + blue_tint - old_blue;
  539.                         if (j > -128 && j < 127) tint_table[2][i] = j;
  540.                     }
  541.                 }
  542.             old_tf1 = tint_factor_1;
  543.             old_red = red_tint;
  544.             old_green = green_tint;
  545.             old_blue = blue_tint;
  546.             }
  547. #endif
  548.         switch (video_resolution){
  549.             case VGA:
  550.             case SVGA:
  551.                 setup_pallet();
  552.                 break;
  553.             case SVGA_16_bit:
  554.                 tint_16_image();    /* tint the image in video_memory */
  555.                 break;
  556.             case SVGA_15_bit:
  557.                 tint_15_image();    /* tint the image in video_memory */
  558.                 break;
  559.             case SVGA_24_bit:
  560.                 tint_24_image();    /* tint screen image in place ie in memory */
  561.                 break;
  562.             }
  563.         }
  564.  
  565.     if (enable_pan && (x_delta != 0 || y_delta != 0 || redraw))
  566.         pan_image(cinfo);
  567.     }
  568. }
  569.  
  570.  
  571.