home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR2
/
DVPG30FS.ZIP
/
JVDRAW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-04
|
17KB
|
571 lines
/*
* drawing routines for dvpeg
*
*/
#include "viewdef.h"
#include "extern.h"
#include <dos.h>
#include <conio.h>
#include <alloc.h>
/*
* setup the color pallet
* - apply all tint controls to the global pallet and write it out
* - assume setup_image_info has been called and all tint_factors are setup
uses:
#define new_tint(data, tf_2) ( (((int)data * tint_factor_1) >> 6) + tf_2 )
*/
void setup_pallet(void)
{
unsigned char pallet[256][3]; /* duplicate pallete for contrast / brightness */
int i, red, green, blue, max, min, temp, max_index, min_index;
union REGS regs;
max = -1; /* find max, minimum brightness pallet colors - regardless of color clashing ;-) */
min = 32760;
for (i = 0; i < 256; i++){
/* first init the pallet so that any colors that are not updated are at least at their default */
red = palbuf[i][0];
green = palbuf[i][1];
blue = palbuf[i][2];
pallet[i][0] = red >> 2;
pallet[i][1] = green >> 2;
pallet[i][2] = blue >> 2;
red += new_tint(red, tint_factor_red);
green += new_tint(green, tint_factor_green);
blue += new_tint(blue, tint_factor_blue);
if (((red | green | blue) & 0xff00) == 0){
/* if (red < 256 && green < 256 && blue < 256 && red >= 0 && green >= 0 && blue >= 0){*/
pallet[i][0] = red >> 2; /* only change if no color wrapping > 64 */
pallet[i][1] = green >> 2;
pallet[i][2] = blue >> 2;
}
if (i < number_pallet_colors){
temp = (int)pallet[i][0] + pallet[i][1] + pallet[i][2]; /* (quick and dirty magnitude calculation */
if (temp > max){
max_index = i;
max = temp;
}
if (temp < min){
min_index = i;
min = temp;
}
}
}
text_drawing_for = max_index; /* set text drawing colors */
text_drawing_bk = min_index;
setmany(pallet, 0, 256);
/* If using only VGA then set the EGA pallet to point index properly into the SVGA one */
if (video_resolution == VGA)
for (i = 0; i < 16; i++){
regs.h.bl = i;
regs.h.bh = i;
regs.x.ax = 0x1000;
int86(0x10, ®s, ®s);
}
}
/*
* setup tint controls for tinting the pallet or screen
* this converts the tint controls to values that are faster to process
*
* then setup the viewing variables for _all_ drawing routines
* this assumes that we know the video mode and what part of the image should
* be at the center of the screen
*/
#define mod_limit(value) ((value) - ((value) % zoom_inc_factor))
void setup_image_info(void)
{
int zoom_inc_factor;
/* now the byte increment per pixel */
switch (video_resolution){
case VGA:
case SVGA:
bytes_per_pixel = 1;
break;
case SVGA_15_bit:
case SVGA_16_bit:
bytes_per_pixel = 2;
break;
case SVGA_24_bit:
bytes_per_pixel = 3;
}
zoom_inc_factor = 5 - zoom_inc; /* this is the scaling for S/W zooming in */
tint_factor_1 = color_scale + contrast_scale; /* result is -127 to + 127 */
tint_lookup = tint_factor_1 + 128; /* scale tint factor 1 to get 0 .. 255 */
tint_factor_red = red_tint - (contrast_scale << 1);
tint_factor_green = green_tint - (contrast_scale << 1);
tint_factor_blue = blue_tint - (contrast_scale << 1);
/* first start off by figuring out how many pixels are available in each dimension
* and then figure out what the picture will use
*
* variables: imageXXXXX are the screen pixels
* pictureXXX are the picture elements
* now image or picture are XX, and ? is x or y:
* XX_?_dim = ? dimension, ie width show/used
* XX_?_max = ? maximum value, ie maximum pixel drawn or picture element drawn
* XX_?_offset = ? start value, ie the first pixel or picture element drawn
* picture_?_center = center of the picture in picture elements as drawn on the screen
*/
/* set up screen limits */
x_max = video_cards[video_mode_used].x_size;
y_max = video_cards[video_mode_used].y_size;
/* X Axis */
image_x_offset = 0;
image_x_dim = mod_limit(x_max);
picture_x_dim = image_x_dim * shrink / zoom_inc_factor;
if (picture_x_dim > picture_x_size){ /* test if screen > picture */
picture_x_dim = picture_x_size;
image_x_dim = picture_x_dim / shrink * zoom_inc_factor;
image_x_offset = (x_max - image_x_dim) >> 1;
picture_x_center = picture_x_size >> 1;
}
picture_x_offset = picture_x_center - (picture_x_dim >> 1);
if (picture_x_offset < 0){ /* case of screen > image; so add offset */
picture_x_offset = - picture_x_offset;
}
picture_x_offset = mod_limit(picture_x_offset);
/* now check if the screen is presenting a larger dimension that the image
* ie the screen < image and being panned off the image
* or if the image is smaller than the screen but the image is
* being panned off of the screen */
picture_x_max = picture_x_offset + picture_x_dim;
if (picture_x_max > picture_x_size){
picture_x_dim = mod_limit(picture_x_size - picture_x_offset);
picture_x_max = picture_x_offset + picture_x_dim;
image_x_dim = picture_x_dim / shrink * zoom_inc_factor;
}
image_x_max = image_x_offset + image_x_dim;
/* Y Axis */
image_y_offset = 0;
image_y_dim = mod_limit(y_max);
picture_y_dim = image_y_dim * shrink / zoom_inc_factor;
if (picture_y_dim > picture_y_size){
picture_y_dim = picture_y_size;
image_y_dim = picture_y_dim * zoom_inc_factor / shrink;
image_y_offset = (y_max - image_y_dim) >> 1;
picture_y_center = picture_y_size >> 1;
}
picture_y_offset = picture_y_center - (picture_y_dim >> 1);
if (picture_y_offset < 0){ /* case of screen > image; so add offset */
picture_y_offset = - picture_y_offset;
}
picture_y_offset = mod_limit(picture_y_offset);
/* now check if the screen is presenting a larger dimension that the image
* ie the screen < image and being panned off the image
* or if the image is smaller than the screen but the image is
* being panned off of the screen */
picture_y_max = picture_y_offset + picture_y_dim;
if (picture_y_max > picture_y_size){
picture_y_dim = mod_limit(picture_y_size - picture_y_offset);
picture_y_max = picture_y_offset + picture_y_dim;
image_y_dim = picture_y_dim / shrink * zoom_inc_factor;
}
image_y_max = image_y_offset + image_y_dim;
bytes_per_line = picture_x_size * bytes_per_pixel; /* to copy into picture buffer */
visable_bytes_per_line = image_x_dim * bytes_per_pixel;
}
/*
* setup a new video mode,
* reinit the color pallet if required
* do pallet stuff first so it does not seem like a big time delay
*/
void reset_video_mode(void)
{
int i;
int red, green, blue;
i = video_cards[video_mode_used].resolution; /* get the video card type */
set_video(video_mode_used); /* reinitialize video mode only if we really found a good mode */
setup_image_info();
if (i <= SVGA)
setup_pallet();
}
void output_term (decompress_info_ptr cinfo)
/* Finish up at the end of the output */
{
static int
y_delta, x_delta,
redraw, /* cmd to force redraw */
step, /* step size (pixels) for pan - first used as a keypress counter*/
video_card_type, /* a unique # for card using {hicolor, Tseng_hi_color, Ati_hi_color, other_VGA) */
update_pallet,
i, j, /* indexes for loops */
zoom_inc_factor, /* factor due to S/W zoom of image */
cmd,
cmd2,
old_tf1, /* old tint factor 1, R,G,B tinting values */
old_red, /* used for tinting 15/16/24 bit screens in memory */
old_green,
old_blue,
multiplier; /* multiplier for contrast, tint, bright controls */
/* get and save memory free data */
near_memory_view = coreleft();
far_memory_view = farcoreleft();
/* write picture file-name/text onto the screen */
if (defaults & show_text)
writeText(text_line_x, text_line_y, picture_text);
/* write picture title onto the screen centered, 8 pixels wide per char, 16 pixels high */
if (defaults & show_title)
writeText(x_max / 2 - strlen(picture_title) * 4, 10, picture_title);
if (view_defaults & beep_on){
sound(1500);
delay(150);
nosound();
}
if (do_slide_show){
return;
}
redraw = 0;
multiplier = 1;
/*ERREXIT(cinfo->emethods, "Memory size check");*/
old_tf1 = color_scale + contrast_scale; /* defaults for 15/16/24 bit on screen tinting */
old_red = red_tint;
old_green = green_tint;
old_blue = blue_tint;
while(1){
y_delta = x_delta = redraw = 0;
step = 0; /* assume 1 keypress only */
cmd = 0;
update_pallet = 0;
allow_video_exit = 1;
while (kbhit()){
cmd2 = get_key(); /* count the number of times a key is hit (for panning) */
if (cmd == 0) cmd = cmd2;
if (cmd >= 0x3b00 && cmd <= 0x4400) multiplier = (cmd >> 8) - 58; /* multiplier for contrast, tint, ..*/
if (cmd2 == cmd) step++;
if (cmd2 == escape) /* if ESC then exit regardless */
cmd = escape;
}
step = (step << 4) * multiplier; /* step 16 pixels per keypress */
zoom_inc_factor = 5 - zoom_inc; /* this gives a number betwen 1 and 4 (ie * 4 expand) that the S/W expands the image */
switch (cmd){
#ifndef small_viewer
case 's': /* save the picture tint, contrast .... */
case 'S':
delete_from_setup_file(file_being_viewed);
save_viewing_info();
break;
case 'd': /* delete the default info for this file */
case 'D':
delete_from_setup_file(file_being_viewed);
break;
#endif
case 'R': /* redraw the screen - also reset video mode to graphics */
red_tint = green_tint = blue_tint = color_scale = contrast_scale = 0;
case 'r': /* don't reset the defaults like R does */
if (enable_pan){
reset_video_mode();
redraw = 1;
}
else
update_pallet = 1; /* if can't repaint then try just updating the pallet */
break;
case RTN:
case 'N':
case 'n':
show_next_file = 1;
return;
case 'P':
case 'p':
show_next_file = -1;
return;
case minus:
if (enable_pan){ /* only bother if panning is on */
if (shrink == 1){
/*
* - this works because the list is ordered from smallest to largest
* basically look in the video_card list and find the next smallest mode
* of the same resolution
*
* zoom out (ie see more of the image)
*/
if (zoom_inc < 4){
zoom_inc++;
redraw = 1;
}
else
if (mode_lock < 0 && ((view_defaults & lock_during_pan) == 0))
for (i = video_mode_used + 1; i < number_modes_in_list; i++)
/* find the same resolution type if it exists */
if (video_cards[i].card_number >= 0) /* only bother if its a valid mode */
if (video_cards[video_mode_used].resolution == video_cards[i].resolution){
video_mode_used = i;
reset_video_mode();
i = number_modes_in_list + 2; /* force exit */
redraw = 1;
shrink = 1; /* what the heck, maby it fits */
}
}
if (redraw == 0){ /* if we did not change modes use a S/W shrink */
shrink++;
if (shrink > max_shrink)
shrink = max_shrink; /* limit to 1/max_shrink size */
else
redraw = 1;
}
if (redraw && (view_defaults & clear_during_pan))
if (video_card_type == VGA)
reset_video_mode();
else
clear_video_memory(16);
}
break;
case plus: /* zoom in */
if (enable_pan){
shrink--;
if (shrink < 1){ /* limit to 1:1 since can't zoom */
shrink = 1;
/* now try changing to a smaller video mode ie zooming */
/* find the same resolution type if it exists */
if (mode_lock < 0 && ((view_defaults & lock_during_pan) == 0))
for (i = video_mode_used - 1; i >= 0; i--)
if (video_cards[video_mode_used].resolution == video_cards[i].resolution){
video_mode_used = i;
reset_video_mode();
redraw = 1;
break;
}
if (redraw == 0) /* use S/W zoom by pixel doubling, tripling */
if (zoom_inc > 0){
zoom_inc--;
redraw = 1;
}
}
else redraw = 1;
}
break;
case page_up:
if (color_scale < 64){
color_scale += multiplier; /* turn up intensity */
if (color_scale >= 64){
allow_video_exit = 0;
color_scale = 64;
}
update_pallet = 1;
}
break;
case page_down:
if (color_scale > -64){
color_scale -= multiplier;
if (color_scale <= -64){
allow_video_exit = 0;
color_scale = -64; /* turn down intensity */
}
update_pallet = 1;
}
break;
case arrow_up:
i = picture_y_dim >> 1;
if (picture_y_center - i - step > 0)
y_delta = -step;
else
if (picture_y_center - i > 0){ /* only do this if the window on the picture can be moved */
allow_video_exit = 0;
y_delta = i - picture_y_center; /* move all the way to top */
}
break;
case arrow_down:
i = picture_y_dim >> 1;
if (picture_y_center + step + i < picture_y_size)
y_delta = step;
else
if (picture_y_center + i < picture_y_size){
allow_video_exit = 0;
y_delta = picture_y_size - picture_y_center - i;
}
break;
case arrow_left:
i = picture_x_dim >> 1;
if (picture_x_center - i - step > 0)
x_delta = -step;
else
if (picture_x_center - i > 0){
x_delta = i - picture_x_center;
allow_video_exit = 0;
}
break;
case arrow_right:
i = picture_x_dim >> 1;
if (picture_x_center + step + i < picture_x_size)
x_delta = step;
else
if (picture_x_center + i < picture_x_size){
allow_video_exit = 0;
x_delta = picture_x_size - picture_x_center - i;
}
break;
#ifndef small_viewer
case red_up: red_tint += (multiplier << 2);
update_pallet = 1;
break;
case red_down:
red_tint -= (multiplier << 2);
update_pallet = 1;
break;
case red_normal:
red_tint = 0;
update_pallet = 1;
break;
case green_up:
green_tint += (multiplier << 2);
update_pallet = 1;
break;
case green_down:
green_tint -= (multiplier << 2);
update_pallet = 1;
break;
case green_normal:
green_tint = 0;
update_pallet = 1;
break;
case blue_up:
blue_tint += (multiplier << 2);
update_pallet = 1;
break;
case blue_down:
blue_tint -= (multiplier << 2);
update_pallet = 1;
break;
case blue_normal:
blue_tint = 0;
update_pallet = 1;
break;
#endif /* small viewer */
case escape:
return;
case home: if (contrast_scale < 64){
contrast_scale += (multiplier << 2);
if (contrast_scale > 64){
allow_video_exit = 0;
contrast_scale = 64;
}
update_pallet = 1;
}
break;
case end: if (contrast_scale > -64){
contrast_scale -= (multiplier << 2);
if (contrast_scale < -64){
allow_video_exit = 0;
contrast_scale = -64;
}
update_pallet = 1;
}
break;
}
if (redraw) allow_video_exit = 0; /* no exit allowed if complete redraw in progress */
if (enable_pan && (x_delta != 0 || y_delta != 0 || redraw)){
picture_x_center += x_delta;
picture_y_center += y_delta;
}
setup_image_info(); /* do the calculations for faster tint controls */
if (update_pallet == 1){
#ifndef small_viewer
if (video_resolution > SVGA){ /* setup look-up table for tinting */
for (i = 0; i < 256; i++){
tint_table[0][i] = tint_table[1][i] = tint_table[2][i] = 0; /* default to do nothing */
switch(video_resolution){
case SVGA_15_bit:
case SVGA_16_bit:
j = (((i * (tint_factor_1 - old_tf1)) >> 6) + red_tint - old_red) >> 3;
if (j > -32 && j < 32) tint_table[0][i] = j;
j = ((i * (tint_factor_1 - old_tf1)) >> 6) + green_tint - old_green;
if (j > -128 && j < 127) tint_table[1][i] = j;
j = ((i * (tint_factor_1 - old_tf1)) >> 6) + blue_tint - old_blue;
if (j > -128 && j < 127) tint_table[2][i] = j;
break;
case SVGA_24_bit:
j = ((i * (tint_factor_1 - old_tf1)) >> 6) + red_tint - old_red;
if (j > -128 && j < 127) tint_table[0][i] = j;
j = ((i * (tint_factor_1 - old_tf1)) >> 6) + green_tint - old_green;
if (j > -128 && j < 127) tint_table[1][i] = j;
j = ((i * (tint_factor_1 - old_tf1)) >> 6) + blue_tint - old_blue;
if (j > -128 && j < 127) tint_table[2][i] = j;
}
}
old_tf1 = tint_factor_1;
old_red = red_tint;
old_green = green_tint;
old_blue = blue_tint;
}
#endif
switch (video_resolution){
case VGA:
case SVGA:
setup_pallet();
break;
case SVGA_16_bit:
tint_16_image(); /* tint the image in video_memory */
break;
case SVGA_15_bit:
tint_15_image(); /* tint the image in video_memory */
break;
case SVGA_24_bit:
tint_24_image(); /* tint screen image in place ie in memory */
break;
}
}
if (enable_pan && (x_delta != 0 || y_delta != 0 || redraw))
pan_image(cinfo);
}
}