Working wresize() being exercised by examples/wgt11.c

This commit is contained in:
Adam Greenwood-Byrne 2021-03-12 23:20:55 +00:00
parent 54b30f1684
commit cb1242ca45
3 changed files with 248 additions and 0 deletions

View file

@ -51,6 +51,16 @@ void getch(void) {
// ######## WGT EXAMPLES ########
#define TIMERSPEED 60
int timer;
int size;
int direction = -1;
void timer_routine (void)
{
timer++;
}
void wgt11()
{
block part1; /* part of the screen */
@ -71,6 +81,39 @@ void wgt11()
wputblock (0, 0, part1, 0);
getch ();
wcls (vgapal[0]);
timer = 0;
size = 50;
winittimer ();
wstarttimer (timer_routine, TIMERSPEED);
wclip (0, 0, 319, 199);
do {
if (direction > 0)
{
size += timer * 2;
timer = 0;
if (size > 50)
direction = -1;
}
else
{
size -= timer * 2;
timer = 0;
if (size < -1000)
direction = 1;
}
wresize (size, size, 319 - size, 199 - size, part1, NORMAL);
} while (1);
getch ();
wstoptimer ();
wdonetimer ();
wfreeblock(part1);
}

View file

@ -34,6 +34,10 @@ extern unsigned char vgafont[224][8];
#define TEXTBG 1
#define TEXTFGBG 2
/* Image transfer operations */
#define NORMAL 0
#define XRAY 1
/* Pointer to the active drawing page */
typedef unsigned int *block;
extern block abuf;
@ -102,3 +106,4 @@ void wstoptimer (void);
void wflipblock (block image, short direction);
block wloadblock (unsigned char *data);
void wloadpalette (unsigned char *data, color *pal);
void wresize (short x, short y, short x2, short y2, block image, short mode);

200
part12-wgt/wresize.c Normal file
View file

@ -0,0 +1,200 @@
#include "wgt.h"
void resize_horizontal_line (block src, block dest, unsigned int whole,
unsigned int xfrac, unsigned short step, short length)
/* Where:
src : is a pointer to the source bitmap
dest : is a pointer to the destination screen
whole: is the amount of pixels to increase the source pointer for every
destination pixel across
xfrac: is the initial fractional portion
step : is the fractional pixel amount to increase the source pointer for
every destination pixel across. 1 step = 1/256 of a pixel, so
every 256 fractional steps, the source pointer is increased by 1.
length : is the number of pixels to draw
*/
{
unsigned int px;
for (int i=0; i<length; i++) {
px = *src;
xfrac += step;
if (xfrac > 65535) {
xfrac %= 65536;
src++;
}
src += whole;
*dest = px;
dest++;
}
}
void resize_horizontal_line_xray (block src, block dest, unsigned int whole,
unsigned int xfrac, unsigned short step, short length)
/* Where:
src : is a pointer to the source bitmap
dest : is a pointer to the destination screen
whole: is the amount of pixels to increase the source pointer for every
destination pixel across
xfrac: is the initial fractional portion
step : is the fractional pixel amount to increase the source pointer for
every destination pixel across. 1 step = 1/256 of a pixel, so
every 256 fractional steps, the source pointer is increased by 1.
length : is the number of pixels to draw
*/
{
unsigned int px;
for (int i=0; i<length; i++) {
px = *src;
xfrac += step;
if (xfrac > 65535) {
xfrac %= 65536;
src++;
}
src += whole;
if (px != 0) *dest = px;
dest++;
}
}
void wresize (short x, short y, short x2, short y2, block image, short mode)
{
long xdif, ydif;
long finalwidth, finalheight, endwidth, endheight;
long origwidth,origheight;
int i;
long endx;
block to, from;
block fromt;
unsigned short whole;
unsigned short step;
unsigned short ywhole;
unsigned short ystep;
unsigned long xstepper, ystepper;
unsigned long yfrac;
unsigned long xfrac;
origwidth = wgetblockwidth (image);
origheight = wgetblockheight (image);
/* Get the original width and height of the block */
finalwidth = abs (x2 - x) + 1;
finalheight = abs (y2 - y) + 1;
/* Find the new width and height */
xstepper = ((long)(origwidth) << 16) / ((long)(finalwidth));
/* Calculate the amount to add to the source bitmap for every pixel across.
This is done using a fixed point number by multiplying it by 65536 (<<16)
and using 0-65535 as a fractional amount. */
whole = xstepper >> 16; /* Keep the whole amount */
step = xstepper - whole * 65536;
/* and the fractional amount (1/65536th of a pixel) */
ystepper = ((long)(origheight) << 16) / ((long)(finalheight));
ywhole = ystepper >> 16;
ystep = ystepper - ywhole * 65536;
/* Do the same with the vertical height */
to = &abuf[y*WGT_SYS.xres + x];
/* Make an initial pointer to the destination */
from = &image[2];
/* Skip over the width/height integers */
endwidth = finalwidth;
endheight = finalheight;
xdif = 0;
/* Differences between actual coordinates and */
ydif = 0; /* the clipped coordinates. */
yfrac = 0; /* Reset step to 0 */
xfrac = 0; /* Reset step to 0 */
/* Do the clipping */
if (x < tx)
{
xdif = tx - x;
/* Find the difference between x<--->tx */
/* if we know that tx is the greater number */
to += xdif;
/* Make sure dest is within left clipping */
endwidth -= xdif;
/* Decrease the horizontal number of pixels drawn */
xfrac = (xdif * step) % 65536;
from += ((int)xdif * xstepper) >> 16;
/* Now adjust the source pointer according to the whole and step values.
We multiply the number of pixels and the rate and add this to our
pointer. The fractional part is divided by 65536 because we're only
concerned with the whole pixel amounts. */
}
if (y < ty)
{
ydif = ty - y;
endheight = finalheight - (ydif);
to += ydif * WGT_SYS.xres;
yfrac = (ydif * ystep) % 65536;
/* Do the same for the height */
from += (((long)ydif * (long)ystepper)>>16) * (long)origwidth;
/* Same as above but also multiply be the width of the source since we're
going down a row instead of one pixel across. */
}
if (x + finalwidth - 1 > bx)
endwidth -= ((x + finalwidth - 1) - bx);
if (y + finalheight - 1 > by)
endheight -= ((y + finalheight - 1) - by);
/* Clip the right and bottom edges simply by decreasing the number of
pixels drawn. */
if ((x2 > tx) && (y2 > ty) && (endwidth > 0))
/* If it is even on the screen at all */
{
endx = endwidth;
if (mode == NORMAL) /* Plain and simple */
for (i = 1; i <= endheight; i++) /* Vertical loop */
{
fromt = from;
resize_horizontal_line (fromt, to, whole, xfrac, step, endx);
/* Resize one line using our assembly routine */
to += endx;
yfrac += ystep;
if (yfrac > 65535)
{
yfrac -= 65535;
from += origwidth;
}
from += ywhole * origwidth;
to += WGT_SYS.xres - endwidth;
}
else /* Use XRAY mode */
for (i = 1; i <= endheight; i++)
{
fromt = from;
resize_horizontal_line_xray (fromt, to, whole, xfrac, step, endx);
to += endx;
yfrac += ystep;
if (yfrac > 65535)
{
yfrac -= 65535;
from += origwidth;
}
from += ywhole*origwidth;
to += WGT_SYS.xres - endwidth;
}
}
}