11-06-2004, 03:34 PM
After discussing this with marzec yesterday, we have concluded that accessing stuct members via pointers should use "->" instead of "." but why does Tc++3.0 allow me otherwise?
Here's the code:
Neo: this is how we did structures in farmalloced arrays:
Compile with tc++ 3.0
Compiler switches:
model = Medium
287 instructions enabled
and cpp compiler used.
For an older ver with EXE:
http://quickhost.qbtk.com/download.php?id=311
Here's the code:
Neo: this is how we did structures in farmalloced arrays:
Compile with tc++ 3.0
Compiler switches:
model = Medium
287 instructions enabled
and cpp compiler used.
For an older ver with EXE:
http://quickhost.qbtk.com/download.php?id=311
Code:
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <dos.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <mem.h>
#include <math.h>
#define LENS 256
#define XCENTER 160
#define YCENTER 100
#define TORNUMRINGS 50
#define TORNUMBANDS 40
#define TORRINGRADIUS 45
#define TORBANDRADIUS 40
struct vector
{
float x;
float y;
float z;
};
struct point3d
{
float x;
float y;
float z;
float rx;
float ry;
float rz;
int sx;
int sy;
};
struct xpoly
{
int p1;
int p2;
int p3;
unsigned char color;
};
void pset(unsigned char far *layer, int x, int y, unsigned char clr);
void wu_pset(unsigned char far *page, float x, float y, unsigned char col);
char point(unsigned char far *page, int x, int y);
void wait();
void setpal(unsigned char i,unsigned char r,unsigned char g,unsigned char b);
void cls(unsigned char *page, unsigned char color);
void pcopy(unsigned char *dest, unsigned char *source);
void setmode(unsigned char mode);
void hline(unsigned char far *page, int x1, int y, int x2, unsigned char color);
void vline(unsigned char far *page, int x, int y1, int y2, unsigned char color);
void rectsolid(unsigned char far *page, int x1, int y1,int x2, int y2, unsigned char color);
void rect(unsigned char far *page, int x1, int y1,int x2, int y2, unsigned char color);
void line(unsigned char far *page, int x1, int y1, int x2, int y2, unsigned char color);
void spriteget( unsigned char far *page, unsigned char far *sprite, int x1, int y1, int x2, int y2);
void spriteputsolid( unsigned char far *page, unsigned char far *sprite, int x, int y);
void spriteput( unsigned char far *page, unsigned char far *sprite, int x, int y);
unsigned int size(int x1, int y1, int x2, int y2);
void triflat(unsigned char far *page, int ox1, int oy1, int ox2, int oy2, int ox3, int oy3, unsigned char color);
void trigour(unsigned char far *page, int ox1, int oy1, int ox2, int oy2, int ox3, int oy3, unsigned char oc1, unsigned char oc2, unsigned char oc3);
void hlineg(unsigned char far *page, int ox1, int oy, int ox2, unsigned char oc1, unsigned char oc2);
void hlinet(unsigned char far *page, unsigned char far *sprite, int x1, int y, int x2, unsigned char u1, unsigned char v1, unsigned char u2, unsigned char v2,unsigned char textwid, unsigned char shiftcounter);
void tritext(unsigned char far *page, int x1, int y1, int x2, int y2, int x3, int y3, unsigned char u1, unsigned char v1, unsigned char u2, unsigned char v2, unsigned char u3, unsigned char v3, unsigned char far *sprite);
void matrix_clear(float m[4][4]);
void matrix_set_identity(float m[4][4]);
void matrix_set_scale(float m[4][4], float sx, float sy, float sz);
void matrix_set_translate(float m[4][4], float tx, float ty, float tz);
void matrix_rotate_x(float m[4][4], int angle);
void matrix_rotate_y(float m[4][4], int angle);
void matrix_rotate_z(float m[4][4], int angle);
void matrix_mul_matrix(float m1[4][4],float m2[4][4]);
void matrix_mul_vector(float m[4][4], struct vector v_in, struct vector v_out);
void load_torus(point3d far *model, int rings, int bands, int ringradius, int bandradius);
void set_torus_faces(xpoly far *tri, int rings, int bands);
int get_max_poly(int rings, int bands);
void draw_torus(unsigned char far *page, point3d far *model, int maxpoint, xpoly far *tri, int maxpoly);
void main()
{
unsigned char far *screen;
unsigned char far *buffer;
float mat[4][4];
float tmat[4][4];
int max3dpoint = TORNUMRINGS * TORNUMBANDS;
point3d far *torus;
//!!!!!!!! I want this to be inside the load_torus funk)
if (!(torus = (point3d far *) farmalloc(sizeof(point3d)* max3dpoint)))
{
clrscr();
printf("\n Insufficient memory for 3d object!!!");
getch();
exit (1);
}
int maxpoly = get_max_poly(TORNUMRINGS, TORNUMBANDS);
xpoly far *torpoly;
//!!!!!!!! I want this to be inside the set_torus_faces funk)
if (!(torpoly = (xpoly far *) farmalloc(sizeof(xpoly) * maxpoly)))
{
clrscr();
printf("\n Insufficient memory for poly!!");
getch();
exit (1);
}
int thetax, thetay, thetaz;
screen = (unsigned char far*) 0xa0000000;
buffer = (unsigned char far*) farmalloc(64000);
if (buffer == 0)
return;
setmode(0x13); //13h
//for (int i = 0; i < 256; i++)
// setpal (i, i/4, i/4, i/4);
load_torus (torus, TORNUMRINGS, TORNUMBANDS, TORRINGRADIUS, TORBANDRADIUS);
set_torus_faces(torpoly, TORNUMRINGS, TORNUMBANDS);
randomize();
thetax = rand() % 360;
thetay = rand() % 360;
thetay = rand() % 360;
do
{
thetax = (thetax + 1) % 360;
thetay = (thetay + 1) % 360;
thetaz = (thetaz + 1) % 360;
matrix_clear( mat);
matrix_clear(tmat);
matrix_set_identity( mat);
matrix_rotate_x(tmat, thetax);
matrix_mul_matrix(mat, tmat);
matrix_rotate_y(tmat, thetay);
matrix_mul_matrix(mat, tmat);
matrix_rotate_z(tmat, thetaz);
matrix_mul_matrix(mat, tmat);
_fmemset(buffer, 0, 64000); //cls
for (int i = 0; i < max3dpoint; i++)
{
float x, y, z, xr, yr, zr;
x = torus[i].x;
y = torus[i].y;
z = torus[i].z;
xr = x * mat[0][0] + y * mat[0][1] + z * mat[0][2] + mat[0][3];
yr = x * mat[1][0] + y * mat[1][1] + z * mat[1][2] + mat[1][3];
zr = x * mat[2][0] + y * mat[2][1] + z * mat[2][2] + mat[2][3];
long distance = LENS - zr;
if (distance > 0)
{
int sx = XCENTER + (LENS * xr / distance);
int sy = YCENTER + (LENS * yr / distance);
//pset (buffer , sx, sy, 255);
torus[i].sx = sx;
torus[i].sy = sy;
}
}
draw_torus(buffer, torus, max3dpoint, torpoly, maxpoly);
//wait();
_fmemcpy(screen, buffer, 64000);
}
while ( !kbhit());
farfree(buffer);
setmode(0x3);
farfree(torus);
farfree(torpoly);
clrscr();
printf(" max3dpoint %u", max3dpoint);
printf(" \n maxpoly %u", maxpoly);
getch();
getch();
getch();
}
//***************************************************************************
// 3d torus.cpp generic routines
//***************************************************************************
void draw_torus(unsigned char far *page, point3d far *model, int maxpoint, xpoly far *tri, int maxpoly)
{
int i, x1, y1, x2, y2, x3, y3;
for (i = 0; i < maxpoly ; i++)
{
x1 = model[tri[i].p1].sx;
y1 = model[tri[i].p1].sy;
x2 = model[tri[i].p2].sx;
y2 = model[tri[i].p2].sy;
x3 = model[tri[i].p3].sx;
y3 = model[tri[i].p3].sy;
line(page, x1, y1, x2, y2, tri[i].color);
line(page, x2, y2, x3, y3, tri[i].color);
line(page, x3, y3, x1, y1, tri[i].color);
}
}
void load_torus(point3d far *model, int rings, int bands, int ringradius, int bandradius)
{
float a1 = 2 * 3.141593f / (float)rings;
float a2 = 2 * 3.141593f / (float)bands;
int i = 0;
for (int s2 = 0; s2 < bands; s2++)
{
for (int s1 = 0; s1 < rings; s1++)
{
float x1 = cos(s1 * a1) * ringradius;
float y1 = sin(s1 * a1) * ringradius;
model[i].x = x1 + cos(s1 * a1) * cos(s2 * a2) * bandradius;
model[i].y = y1 + sin(s1 * a1) * cos(s2 * a2) * bandradius;
model[i].z = sin(s2 * a2) * bandradius;
i++;
}
}
}
int get_max_poly(int rings, int bands)
{
int i = 0;
int maxtri = 0;
for (int s1 = (bands - 1); s1 >= 0; s1--)
{
for (int s2 = (rings - 1); s2 >= 0; s2--)
{
i++;
maxtri++;
i++;
maxtri++;
}
}
return maxtri;
}
void set_torus_faces(xpoly far *tri, int rings, int bands)
{
int maxpoint = rings * bands;
int i = 0;
for (int s1 = (bands - 1); s1 >= 0; s1--)
{
for (int s2 = (rings - 1); s2 >= 0; s2--)
{
tri[i].p3 = (s1 * rings + s2 + rings) % maxpoint;
tri[i].p2 = s1 * rings + (s2 + 1) % rings;
tri[i].p1 = s1 * rings + s2;
tri[i].color = i & 0xff;
i++;
tri[i].p3 = (s1 * rings + s2 + rings) % maxpoint;
tri[i].p2 = (s1 * rings + (s2 + 1) % rings + rings) % maxpoint;
tri[i].p1 = s1 * rings + (s2 + 1) % rings;
tri[i].color = i & 0xff;
i++;
}
}
}
//***************************************************************************
// Matrix funks
//***************************************************************************
void matrix_clear(float m[4][4])
{
int row, col;
for (row = 0; row < 4; row++)
{
for (col = 0; col < 4; col++)
m[row][col] = 0;
}
}
void matrix_set_identity(float m[4][4])
{
matrix_clear(m);
m[0][0] = 1;
m[1][1] = 1;
m[2][2] = 1;
m[3][3] = 1;
}
void matrix_set_scale(float m[4][4], float sx, float sy, float sz)
{
m[0][0] = sx;
m[1][1] = sy;
m[2][2] = sz;
}
void matrix_set_translate(float m[4][4], float tx, float ty, float tz)
{
m[0][3] = tx;
m[1][3] = ty;
m[2][3] = tz;
}
void matrix_rotate_x(float m[4][4], int angle)
{
float ang = angle * M_PI / 180.0f;
float sa = sin(ang);
float ca = cos(ang);
matrix_set_identity(m);
m[1][1] = ca;
m[1][2] = -sa;
m[2][1] = sa;
m[2][2] = ca;
}
void matrix_rotate_y(float m[4][4], int angle)
{
float ang = angle * M_PI / 180.0f;
float sa = sin(ang);
float ca = cos(ang);
matrix_set_identity(m);
m[0][0] = ca;
m[0][2] = sa;
m[2][0] = -sa;
m[2][2] = ca;
}
void matrix_rotate_z(float m[4][4], int angle)
{
float ang = angle * M_PI / 180.0f;
float sa = sin(ang);
float ca = cos(ang);
matrix_set_identity(m);
m[0][0] = ca;
m[0][1] = -sa;
m[1][0] = sa;
m[1][1] = ca;
}
void matrix_mul_matrix(float m1[4][4], float m2[4][4])
{
int i, j, k;
float mresult[4][4];
matrix_clear (mresult);
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
mresult[i][j] = 0;
for (k = 0; k < 4; k++)
{
mresult[i][j] += ( m2[i][k] * m1[k][j] );
}
}
}
//copy result back
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
m1[i][j] = mresult[i][j];
}
}
void matrix_mul_vector(float m[4][4], struct vector v_in, struct vector v_out)
{
v_out.x = v_in.x * m[0][0] + v_in.y * m[0][1] + v_in.z * m[0][2] + m[0][3];
v_out.y = v_in.x * m[1][0] + v_in.y * m[1][1] + v_in.z * m[1][2] + m[1][3];
v_out.z = v_in.x * m[2][0] + v_in.y * m[2][1] + v_in.z * m[2][2] + m[2][3];
}
//***************************************************************************
// GFX functions
// GFX functions
// GFX functions
//***************************************************************************
//puts a pixel on a buffer
void pset(unsigned char far *layer, int x, int y, unsigned char clr)
{
if ((x > -1) && (x < 320) && (y > -1) && (y < 200))
*(layer + (y << 6) + (y << 8) + x) = clr;
}
void wu_pset(unsigned char far *page, float x, float y, unsigned char col)
{
unsigned char far *ptr;
int x1 = x;
int y1 = y;
int x2 = x1 + 1;
int y2 = y1 + 1;
float xm = x - x1;
float ym = y - y1;
float xm2 = (1 - xm);
float ym2 = (1 - ym);
unsigned char c1 = xm2 * ym2 * col;
unsigned char c2 = xm * ym2 * col;
unsigned char c3 = xm2 * ym * col;
unsigned char c4 = xm * ym * col;
if ((x1 > -1) && (x1 < 320) && (y1 > -1) && (y1 < 200))
*(page + (y1 << 6) + (y1 << 8) + x1) = c1;
if ((x2 > -1) && (x2 < 320) && (y1 > -1) && (y1 < 200))
*(page + (y1 << 6) + (y1 << 8) + x2) = c2;
if ((x1 > -1) && (x1 < 320) && (y2 > -1) && (y2 < 200))
*(page + (y2 << 6) + (y2 << 8) + x1) = c3;
if ((x2 > -1) && (x2 < 320) && (y2 > -1) && (y2 < 200))
*(page + (y2 << 6) + (y2 << 8) + x1) = c4;
}
//waits for refresh/vertical blank
//needs dos.h
void wait()
{
while ( inportb(0x3da) & 8 );
while ( !(inportb(0x3da) & 8) );
}
//gets a pixel from the screen
char point(unsigned char far *page, int x, int y)
{
char c = *(page+((y<<6) +(y<<8) + x));
return (c);
}
//sets the rgb index into RGB
//needs dos.h
void setpal(unsigned char i,unsigned char r,unsigned char g,unsigned char b)
{
outportb(0x3c8, i);
outportb(0x3c9, r);
outportb(0x3c9, g);
outportb(0x3c9, b);
}
//sets the screen mode to mode
//needs dos.h
void setmode(unsigned char mode)
{
union REGS regs;
regs.h.ah = 0;
regs.h.al = mode;
int86(0x10, ®s, ®s);
}
//draws a horizontal line
//
void hline(unsigned char far *page, int ox1, int oy, int ox2, unsigned char color)
{
unsigned int wid;
unsigned char far *ptr;
unsigned int counter;
int x1, y, x2;
x1 = ox1;
y = oy;
x2 = ox2;
if ( (y < 0) || (y > 199) ) return;
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
}
if (x1 > 319) return;
if (x2 < 0) return;
if (x1 < 0)
{
x1 = 0;
if ((x2 - x1) < 0) return;
}
if (x2 > 319)
{
x2 = 319;
if ((x2 - x1) < 0) return;
}
wid = (x2 - x1) + 1;
if (wid <= 0 ) return;
ptr = page;
ptr = ptr + (y << 8) + (y << 6) + x1;
for (counter = 0; counter < wid; counter++)
{
*ptr = color;
ptr++;
}
}
//draws a vertical line
//
void vline(unsigned char far *page, int ox, int oy1, int oy2, unsigned char color)
{
unsigned int hei;
unsigned char far *ptr;
unsigned int counter;
int x, y1, y2;
x = ox;
y1 = oy1;
y2 = oy2;
if ( (x < 0) || (x > 319) ) return;
if (y1 > y2)
{
int temp = y1;
y1 = y2;
y2 = temp;
}
if (y1 > 199) return;
if (y2 < 0) return;
if (y1 < 0)
{
y1 = 0;
if ((y2 - y1) < 0) return;
}
if (y2 > 199)
{
y2 = 199;
if ((y2 - y1) < 0) return;
}
hei = (y2 - y1) + 1;
if (hei <= 0 ) return;
ptr = page;
ptr = ptr + (y1 << 8) + (y1 << 6) + x;
for (counter = 0; counter < hei; counter++)
{
*ptr = color;
ptr += 320;
}
}
//draws a rectangle
//
void rect(unsigned char far *page, int x1, int y1,int x2, int y2, unsigned char color)
{
hline (page, x1, y1, x2, color);
hline (page, x1, y2, x2, color);
vline (page, x1, y1, y2, color);
vline (page, x2, y1, y2, color);
}
//draws a solid rectangle
//
void rectsolid(unsigned char far *page, int ox1, int oy1,int ox2, int oy2, unsigned char color)
{
unsigned int hei, wid;
unsigned char far *ptr;
unsigned int wcounter, hcounter;
int x1, y1, x2, y2;
x1 = ox1;
y1 = oy1;
x2 = ox2;
y2 = oy2;
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
}
if (x1 > 319) return;
if (x2 < 0) return;
if (x1 < 0)
{
x1 = 0;
if ((x2 - x1) < 0) return;
}
if (x2 > 319)
{
x2 = 319;
if ((x2 - x1) < 0) return;
}
wid = (x2 - x1) + 1;
if (wid <= 0 ) return;
if (y1 > y2)
{
int temp = y1;
y1 = y2;
y2 = temp;
}
if (y1 > 199) return;
if (y2 < 0) return;
if (y1 < 0)
{
y1 = 0;
if ((y2 - y1) < 0) return;
}
if (y2 > 199)
{
y2 = 199;
if ((y2 - y1) < 0) return;
}
hei = (y2 - y1) + 1;
if (hei <= 0 ) return;
ptr = page;
ptr = ptr + (y1 << 8) + (y1 << 6) + x1;
for (hcounter = 0; hcounter < hei; hcounter++)
{
for (wcounter = 0; wcounter < wid; wcounter++)
{
*(ptr + wcounter) = color;
}
ptr +=320;
}
}
//draws a line using the bresenham algo
//needs mem.h
//clipping is a lil buggy ;*(
void line(unsigned char far *page, int x1, int y1, int x2, int y2, unsigned char color)
{
int inc1, inc2, i;
int cnt, y_adj, dy, dx, x_adj;
unsigned char far *p;
if ( x1 == x2 )
{
// vertical line
if ( y1 > y2 )
{
i=y1;
y1=y2;
y2=i;
}
//yclip
if (y1 > 199) return;
if (y2 < 0) return;
if (y1 < 0)
{
y1 = 0;
if ((y2 - y1) < 0) return;
}
if (y2 > 199)
{
y2 = 199;
if ((y2 - y1) < 0) return;
}
//end yclip
p = page;
p = p + (y1 << 8) + (y1 << 6) + x1;
i=y2 - y1 + 1;
while ( i-- )
{
*p=color;
p+= 320;
}
}
else
{
if ( y1 == y2 )
{
// horizontal line
if ( x1 > x2 )
{
i=x1;
x1=x2;
x2=i;
}
//xclip
if (x1 > 319) return;
if (x2 < 0) return;
if (x1 < 0)
{
x1 = 0;
if ((x2 - x1) < 0) return;
}
if (x2 > 319)
{
x2 = 319;
if ((x2 - x1) < 0) return;
}
//end xclip
p = page;
p = p + (y1 << 8) + (y1 << 6) + x1;
i=x2 - x1 + 1;
_fmemset(p, color, i);
}
else
{
// general line --------------------------------------
dy=y2 - y1; // dy is increment
dx=x2 - x1; // dx is line length
// is it a shallow, or steep line?
if ( abs(dy) < abs(dx) )
{
// lo slope
// we always want to draw from left to right
if ( x1 > x2 )
{
// swap x's, and y's
i=x1;
x1=x2;
x2=i;
i=y1;
y1=y2;
y2=i;
}
//yclip
if (y1 > 199) return;
if (y2 < 0) return;
if (y1 < 0)
{
y1 = 0;
if ((y2 - y1) < 0) return;
}
if (y2 > 199)
{
y2 = 199;
if ((y2 - y1) < 0) return;
}
//end yclip
//xclip
if (x1 > 319) return;
if (x2 < 0) return;
if (x1 < 0)
{
x1 = 0;
if ((x2 - x1) < 0) return;
}
if (x2 > 319)
{
x2 = 319;
if ((x2 - x1) < 0) return;
}
//end xclip
dy=y2 - y1; // dy is used to calulate the increments
dx=x2 - x1; // dx is line length
if ( dy < 0 )
{
// going up the screen
dy=-dy;
y_adj=-320;
}
else
y_adj=320; // and down
// calulate the increments
inc1=dy<<1;
inc2=(dy - dx)<<1;
cnt=(dy<<1) - dx;
// set p to start pixel
p = page;
p = p + (y1 << 8) + (y1 << 6) + x1;
dx++;
while ( dx-- ) // for the length of the line
{
*p++=color; // set one pixel, move right one pixel
if ( cnt >= 0 ) // is it time to adjust y?
{
cnt+=inc2;
p+=y_adj;
}
else
cnt+=inc1;
}
}
else
{
// hi slope - like lo slope turned on its side
// always draw top to bottom
if ( y1 > y2 )
{
// swap x's, and y's
i=x1;
x1=x2;
x2=i;
i=y1;
y1=y2;
y2=i;
}
//yclip
if (y1 > 199) return;
if (y2 < 0) return;
if (y1 < 0)
{
y1 = 0;
if ((y2 - y1) < 0) return;
}
if (y2 > 199)
{
y2 = 199;
if ((y2 - y1) < 0) return;
}
//end yclip
//xclip
if (x1 > 319) return;
if (x2 < 0) return;
if (x1 < 0)
{
x1 = 0;
if ((x2 - x1) < 0) return;
}
if (x2 > 319)
{
x2 = 319;
if ((x2 - x1) < 0) return;
}
//end xclip
dy=y2 - y1; // dy is line length
dx=x2 - x1; // dx is used to calculate incr's
if ( dx < 0)
{
dx=-dx;
x_adj=-1; // moving left
}
else
x_adj=1; // moving right
inc1=dx<<1;
inc2=(dx - dy)<<1;
cnt=(dx<<1) - dy;
// set p to first pixel position
p = page;
p = p + (y1 << 8) + (y1 << 6) + x1;
dy++;
while ( dy-- ) // for height of line
{
*p=color; // set one pixel
p+=320; // move down one pixel
if ( cnt >= 0 ) // is it time to move x?
{
cnt+=inc2;
p+=x_adj;
}
else
cnt+=inc1;
}
}
}
}
}
//gets an image from screen or buffer
//sprite[0 to 1] = width
//sprite[2 to 3] = height
//sprite[4...] = pixel
void spriteget( unsigned char far *page, unsigned char far *sprite, int ox1, int oy1, int ox2, int oy2)
{
unsigned int hei, wid;
unsigned char far *p_page, far *p_sprite;
unsigned int wcounter, hcounter;
int x1, y1, x2, y2;
x1 = ox1;
y1 = oy1;
x2 = ox2;
y2 = oy2;
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
}
if (x1 > 319) return;
if (x2 < 0) return;
if (x1 < 0)
{
x1 = 0;
if ((x2 - x1) < 0) return;
}
if (x2 > 319)
{
x2 = 319;
if ((x2 - x1) < 0) return;
}
wid = (x2 - x1) + 1;
if (wid <= 0 ) return;
if (y1 > y2)
{
int temp = y1;
y1 = y2;
y2 = temp;
}
if (y1 > 199) return;
if (y2 < 0) return;
if (y1 < 0)
{
y1 = 0;
if ((y2 - y1) < 0) return;
}
if (y2 > 199)
{
y2 = 199;
if ((y2 - y1) < 0) return;
}
hei = (y2 - y1) + 1;
if (hei <= 0 ) return;
p_sprite = sprite;
p_sprite += 4;
sprite[0] = wid & 0xff;
sprite[1] = wid >> 8;
sprite[2] = hei & 0xff;
sprite[3] = hei >> 8;
p_page = page;
p_page = p_page + (y1 << 8) + (y1 << 6) + x1;
for (hcounter = 0; hcounter < hei; hcounter++)
{
for (wcounter = 0; wcounter < wid; wcounter++)
{
*p_sprite = *(p_page + wcounter);
p_sprite++;
}
p_page +=320;
}
}
//gets an image to screen or buffer
//sprite[0 to 1] = width
//sprite[2 to 3] = height
//sprite[4...] = pixel
//draws solidly
//clipping supported
void spriteputsolid( unsigned char far *page, unsigned char far *sprite, int ox, int oy)
{
unsigned char far *p_page, far *p_sprite;
unsigned int wcounter, hcounter;
int owid, ohei;
int hei, wid;
int x, y;
x = ox;
y = oy;
if (x > 319) return;
if (y > 199) return;
owid = (sprite[0]) + (sprite[1] << 8);
ohei = (sprite[2]) + (sprite[3] << 8);
wid = owid;
hei = ohei;
p_sprite = sprite;
p_sprite += 4;
if (y < 0)
{
y = -y;
p_sprite += (wid * y);
hei -= y;
if (hei <= 0) return;
y = 0;
}
if ( (y + hei) > 199)
{
unsigned int htemp = (y + hei) - 200;
hei -= htemp;
if (hei <= 0) return;
}
if (x < 0)
{
x = -x;
p_sprite += x;
wid -= x;
if (wid <= 0) return;
x = 0;
}
if ( (x + wid) > 319)
{
unsigned int wtemp = (x + wid) - 320;
wid -= wtemp;
if (wid <= 0) return;
}
p_page = page;
p_page = p_page + (y << 8) + (y << 6) + x;
for (hcounter = 0; hcounter < hei; hcounter++)
{
for (wcounter = 0; wcounter < wid; wcounter++)
{
*(p_page + wcounter) = *(p_sprite+ wcounter);
}
p_page +=320;
p_sprite += owid;
}
}
//gets an image to screen or buffer
//sprite[0 to 1] = width
//sprite[2 to 3] = height
//sprite[4...] = pixel
//draws transparently
//clipping supported
void spriteput( unsigned char far *page, unsigned char far *sprite, int ox, int oy)
{
unsigned char far *p_page, far *p_sprite;
unsigned int wcounter, hcounter;
int owid, ohei;
int hei, wid;
int x, y;
x = ox;
y = oy;
if (x > 319) return;
if (y > 199) return;
owid = (sprite[0]) + (sprite[1] << 8);
ohei = (sprite[2]) + (sprite[3] << 8);
wid = owid;
hei = ohei;
p_sprite = sprite;
p_sprite += 4;
if (y < 0)
{
y = -y;
p_sprite += (wid * y);
hei -= y;
if (hei <= 0) return;
y = 0;
}
if ( (y + hei) > 199)
{
unsigned int htemp = (y + hei) - 200;
hei -= htemp;
if (hei <= 0) return;
}
if (x < 0)
{
x = -x;
p_sprite += x;
wid -= x;
if (wid <= 0) return;
x = 0;
}
if ( (x + wid) > 319)
{
unsigned int wtemp = (x + wid) - 320;
wid -= wtemp;
if (wid <= 0) return;
}
p_page = page;
p_page = p_page + (y << 8) + (y << 6) + x;
for (hcounter = 0; hcounter < hei; hcounter++)
{
for (wcounter = 0; wcounter < wid; wcounter++)
{
unsigned char color = *(p_sprite+ wcounter);
if (color != 0 );
*(p_page + wcounter) = color;
}
p_page +=320;
p_sprite += owid;
}
}
//returns size in bytes
//of the rect defined by x1, y1, x2, y2
//for use in allocating mem for spriteget
unsigned int size(int x1, int y1, int x2, int y2)
{
unsigned int s;
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
}
if (y1 > y2)
{
int temp = y1;
y1 = y2;
y2 = temp;
}
s = ((x2 - x1) + 1) * ((y2 - y1) + 1) + 4;
return (s);
}
//draws a flat triangle
//
void triflat(unsigned char far *page, int ox1, int oy1, int ox2, int oy2, int ox3, int oy3, unsigned char color)
{
int x1, y1, x2, y2, x3, y3, y;
int dx1, dy1, dx2, dy2, dx3, dy3;
float delta1, delta2, delta3, lx, rx;
x1 = ox1;
y1 = oy1;
x2 = ox2;
y2 = oy2;
x3 = ox3;
y3 = oy3;
if ( y2 < y1)
{
int temp = y1;
y1 = y2;
y2 = temp;
temp = x1;
x1 = x2;
x2 = temp;
}
if ( y3 < y1)
{
int temp = y1;
y1 = y3;
y3 = temp;
temp = x1;
x1 = x3;
x3 = temp;
}
if ( y3 < y2)
{
int temp = y2;
y2 = y3;
y3 = temp;
temp = x2;
x2 = x3;
x3 = temp;
}
dx1 = x2 - x1; //calculate difference in X
dy1 = y2 - y1; //difference in Y
delta1 = 0;
if (dy1 != 0) //check for divide by zero
delta1 = dx1 / (float)dy1; //interpolate Top-Left side
dx2 = x3 - x2; //Lower left side
dy2 = y3 - y2;
delta2 = 0;
if (dy2 != 0)
delta2 = dx2 / (float)dy2;
dx3 = x1 - x3; //Right side
dy3 = y1 - y3;
delta3 = 0;
if (dy3 != 0)
delta3 = dx3 / (float)dy3;
/*
Flat bottom
Top part of triangle
code: x1 + (y - y1) * delta1
is changed to:
Lx! = x1
For y=y1 to y2
Lx! = Lx! + delta1! '(y - y1) * Delta1! = (Lx!+ Delta1!) * NumberOfLoops
next y */
lx = x1;
rx = lx;
for ( y = y1; y < y2; y++ )
{
hline ( page,(int)lx, y, (int)rx, color );
lx += delta1; //increment derivative
rx += delta3;
}
//Flat top
//Lower part of triangle
lx = x2;
for ( y = y2; y <= y3; y++ )
{
hline ( page, (int)lx, y, (int)rx, color );
lx += delta2; //increment derivative
rx += delta3;
}
}
//draws a gouraud horizontal line
//for gouraud shading
void hlineg(unsigned char far *page, int ox1, int oy, int ox2, unsigned char oc1, unsigned char oc2)
{
unsigned int wid, owid;
unsigned char far *ptr;
unsigned int counter;
int x1, y, x2;
unsigned char c1, c2;
float deltac, col;
x1 = ox1;
y = oy;
x2 = ox2;
c1 = oc1;
c2 = oc2;
if ( (y < 0) || (y > 199) ) return;
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
unsigned char ctemp = c1;
c1 = c2;
c2 = ctemp;
}
owid = (x2 - x1) + 1;
if (x1 > 319) return;
if (x2 < 0) return;
if (x1 < 0)
{
x1 = 0;
if ((x2 - x1) < 0) return;
}
if (x2 > 319)
{
x2 = 319;
if ((x2 - x1) < 0) return;
}
wid = (x2 - x1) + 1;
if (wid <= 0 ) return;
deltac = (c2 - c1) / (float)wid ;
col = (float)(c1+(owid - wid));
ptr = page;
ptr = ptr + (y << 8) + (y << 6) + x1;
for (counter = 0; counter < wid; counter++)
{
*ptr = (unsigned char)col;
ptr++;
col += deltac;
}
}
//draws a gouraud triangle
//uses hlineg
void trigour(unsigned char far *page, int ox1, int oy1, int ox2, int oy2, int ox3, int oy3, unsigned char oc1, unsigned char oc2, unsigned char oc3)
{
int x1, y1, x2, y2, x3, y3, y;
int dx1, dy1, dx2, dy2, dx3, dy3, dc1, dc2, dc3;
float delta1, delta2, delta3, deltac1, deltac2, deltac3;
float lx, rx, lc, rc;
unsigned char c1, c2, c3;
x1 = ox1;
y1 = oy1;
x2 = ox2;
y2 = oy2;
x3 = ox3;
y3 = oy3;
c1 = oc1;
c2 = oc2;
c3 = oc3;
if ( y2 < y1)
{
int temp = y1;
y1 = y2;
y2 = temp;
temp = x1;
x1 = x2;
x2 = temp;
unsigned char ctemp = c1;
c1 = c2;
c2 = ctemp;
}
if ( y3 < y1)
{
int temp = y1;
y1 = y3;
y3 = temp;
temp = x1;
x1 = x3;
x3 = temp;
unsigned char ctemp = c1;
c1 = c3;
c3 = ctemp;
}
if ( y3 < y2)
{
int temp = y2;
y2 = y3;
y3 = temp;
temp = x2;
x2 = x3;
x3 = temp;
unsigned char ctemp = c2;
c2 = c3;
c3 = ctemp;
}
dx1 = x2 - x1; //calculate difference in X
dy1 = y2 - y1; //difference in Y
dc1 = c2 - c1;
delta1 = 0;
deltac1 = 0;
if (dy1 != 0) //check for divide by zero
{
delta1 = dx1 / (float)dy1; //interpolate Top-Left side
deltac1 = dc1 / (float)dy1;
}
dx2 = x3 - x2; //Lower left side
dy2 = y3 - y2;
dc2 = c3 - c2;
delta2 = 0;
deltac2 = 0;
if (dy2 != 0)
{
delta2 = dx2 / (float)dy2;
deltac2 = dc2 / (float)dy2;
}
dx3 = x1 - x3; //Right side
dy3 = y1 - y3;
dc3 = c1 - c3;
delta3 = 0;
deltac3 = 0;
if (dy3 != 0)
{
delta3 = dx3 / (float)dy3;
deltac3 = dc3 / (float)dy3;
}
lx = x1;
rx = lx;
lc = c1;
rc = lc;
for ( y = y1; y < y2; y++ )
{
hlineg ( page,(int)lx, y, (int)rx, (unsigned char)lc, (unsigned char)rc );
lx += delta1;
rx += delta3;
lc += deltac1;
rc += deltac3;
}
//Flat top
//Lower part of triangle
lx = x2;
lc = c2;
for ( y = y2; y <= y3; y++ )
{
hlineg ( page,(int)lx, y, (int)rx, (unsigned char)lc, (unsigned char)rc );
lx += delta2;
rx += delta3;
lc += deltac2;
rc += deltac3;
}
}
//draws a textured horizontal line
//for affine texture mapping
void hlinet(unsigned char far *page, unsigned char far *sprite, int x1, int y, int x2, unsigned char u1, unsigned char v1, unsigned char u2, unsigned char v2,unsigned char textwid, unsigned char shiftcounter)
{
unsigned int wid, owid;
unsigned char far *ptr;
unsigned int counter;
float deltau, deltav, u, v;
unsigned char textwidm1 = textwid - 1;
if ( (y < 0) || (y > 199) ) return;
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
unsigned char utemp = u1;
u1 = u2;
u2 = utemp;
utemp = v1;
v1 = v2;
v2 = utemp;
}
owid = (x2 - x1) + 1;
if (x1 > 319) return;
if (x2 < 0) return;
if (x1 < 0)
{
x1 = 0;
if ((x2 - x1) < 0) return;
}
if (x2 > 319)
{
x2 = 319;
if ((x2 - x1) < 0) return;
}
wid = (x2 - x1) + 1;
if (wid <= 0 ) return;
deltau = (u2 - u1) / (float) wid;
u = (float)(u1+(owid - wid));
deltav = (v2 - v1) / (float) wid;
v = (float)(v1+(owid - wid));
ptr = page;
ptr = ptr + (y << 8) + (y << 6) + x1;
for (counter = 0; counter < wid; counter++)
{
unsigned int uoffs= ((unsigned char) u & textwidm1);
unsigned int voffs= ((unsigned char) v & textwidm1);
unsigned char pix = sprite[(voffs * textwid) + uoffs + 4];
*ptr = pix;
ptr++;
u += deltau;
v += deltav;
}
}
//draws a textured triangle
//uses hlinet
void tritext(unsigned char far *page, int x1, int y1, int x2, int y2, int x3, int y3, unsigned char u1, unsigned char v1, unsigned char u2, unsigned char v2, unsigned char u3, unsigned char v3, unsigned char far *sprite)
{
int dx1, dy1, dx2, dy2, dx3, dy3, du1, du2, du3, dv1, dv2, dv3;
float delta1, delta2, delta3;
float deltau1, deltau2, deltau3;
float deltav1, deltav2, deltav3;
float lx, rx, lu, ru, lv, rv;
if ( y2 < y1)
{
int temp = y1;
y1 = y2;
y2 = temp;
temp = x1;
x1 = x2;
x2 = temp;
unsigned char utemp = u1;
u1 = u2;
u2 = utemp;
unsigned char vtemp = v1;
v1 = v2;
v2 = vtemp;
}
if ( y3 < y1)
{
int temp = y1;
y1 = y3;
y3 = temp;
temp = x1;
x1 = x3;
x3 = temp;
unsigned char utemp = u1;
u1 = u3;
u3 = utemp;
unsigned char vtemp = v1;
v1 = v3;
v3 = vtemp;
}
if ( y3 < y2)
{
int temp = y2;
y2 = y3;
y3 = temp;
temp = x2;
x2 = x3;
x3 = temp;
unsigned char utemp = u2;
u2 = u3;
u3 = utemp;
unsigned char vtemp = v2;
v2 = v3;
v3 = vtemp;
}
dx1 = x2 - x1; //calculate difference in X
dy1 = y2 - y1; //difference in Y
du1 = u2 - u1;
dv1 = v2 - v1;
delta1 = 0;
deltau1 = 0;
deltav1 = 0;
if (dy1 != 0) //check for divide by zero
{
delta1 = dx1 / (float)dy1; //interpolate Top-Left side
deltau1 = du1 / (float)dy1;
deltav1 = dv1 / (float)dy1;
}
dx2 = x3 - x2; //Lower left side
dy2 = y3 - y2;
du2 = u3 - u2;
dv2 = v3 - v2;
delta2 = 0;
deltau2 = 0;
deltav2 = 0;
if (dy2 != 0)
{
delta2 = dx2 / (float)dy2;
deltau2 = du2 / (float)dy2;
deltav2 = dv2 / (float)dy2;
}
dx3 = x1 - x3; //Right side
dy3 = y1 - y3;
du3 = u1 - u3;
dv3 = v1 - v3;
delta3 = 0;
deltau3 = 0;
deltav3 = 0;
if (dy3 != 0)
{
delta3 = dx3 / (float)dy3;
deltau3 = du3 / (float)dy3;
deltav3 = dv3 / (float)dy3;
}
lx = x1;
rx = lx;
lu = u1;
ru = lu;
lv = v1;
rv = lv;
unsigned char twid = (sprite[0]) + (sprite[1] << 8);
for (int y = y1; y < y2; y++ )
{
hlinet ( page, sprite,(int)lx, y, (int)rx, (unsigned char)lu, (unsigned char)lv , (unsigned char)rv, (unsigned char)rv , twid, 5);
lx += delta1;
rx += delta3;
lu += deltau1;
ru += deltau3;
lv += deltav1;
rv += deltav3;
}
//Flat top
//Lower part of triangle
lx = x2;
lu = u2;
lv = v2;
for ( y = y2; y <= y3; y++ )
{
hlinet ( page, sprite,(int)lx, y, (int)rx, (unsigned char)lu, (unsigned char)lv , (unsigned char)rv, (unsigned char)rv , twid, 5);
lx += delta2;
rx += delta3;
lu += deltau2;
ru += deltau3;
lv += deltav2;
rv += deltav3;
}
}