triangle.cpp
C++ source for C++ graphics effects, 1820 lines. Raw file
// triangle.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include "math.h"
#include "mmsystem.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
HWND hMainWindow;
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int MessageLoop();
typedef struct _BITMAPINFO256 {
BITMAPINFOHEADER bmiHeader;
WORD bmiColors[256];
} BITMAPINFO256;
BITMAPINFO256 bmi;
void Display(HDC dc, unsigned short *buf, int x, int y, int w, int h)
{
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = w;
bmi.bmiHeader.biHeight = -h;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 16;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 1000;
bmi.bmiHeader.biYPelsPerMeter = 1000;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
StretchDIBits(
dc,
x, y, w, h,
0, 0, w, h,
(LPVOID)buf,
(LPBITMAPINFO)&bmi,
DIB_RGB_COLORS, SRCCOPY
);
}
/*
VERSION 1 - 8 clocks
;AGI
mov eax, ebx
add edx, 0x00000000 // SM
START:
rol eax, width
and eax, mask
adc ebx, 0x00000000 // SM
add esi, 0x00000000 // SM
mov ax, [eax+0x00000000] // SM
mov [edi+ebp], ax
mov eax, ecx
rol eax, width
and eax, mask
adc ecx, 0x00000000 // SM
add edx, 0x00000000 // SM
mov ax, [eax+0x00000000] // SM
mov [edi+ebp+1], ax
mov eax, ebx
add ebp, 2
jnc start
*/
//----------------------------------------------------------------------------//
#define SCREEN_W 1024
#define SCREEN_H 768
bool tri_backfacecull = false;
float tri_x1, tri_y1, tri_z1, tri_r1, tri_g1, tri_b1, tri_a1, tri_u1, tri_v1, tri_d1, tri_s1;
float tri_x2, tri_y2, tri_z2, tri_r2, tri_g2, tri_b2, tri_a2, tri_u2, tri_v2, tri_d2, tri_s2;
float tri_x3, tri_y3, tri_z3, tri_r3, tri_g3, tri_b3, tri_a3, tri_u3, tri_v3, tri_d3, tri_s3;
int clip_x1 = 0, clip_y1 = 0, clip_x2 = SCREEN_W, clip_y2 = SCREEN_H;
unsigned int screen_w = SCREEN_W, screen_h = SCREEN_H;
unsigned short screen[SCREEN_H][SCREEN_W];
unsigned short texture[256][256];
//----------------------------------------------------------------------------//
void Tri_Tex16_0001()
{
int i, j;
//- Sort points
float t;
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
if(tri_y3 < tri_y2)
{
t = tri_x2; tri_x2 = tri_x3; tri_x3 = t;
t = tri_y2; tri_y2 = tri_y3; tri_y3 = t;
t = tri_u2; tri_u2 = tri_u3; tri_u3 = t;
t = tri_v2; tri_v2 = tri_v3; tri_v3 = t;
}
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
//- Work out deltas along edges
float dx12 = (tri_x2-tri_x1)/(tri_y2-tri_y1), dx23 = (tri_x3-tri_x2)/(tri_y3-tri_y2), dx13 = (tri_x3-tri_x1)/(tri_y3-tri_y1);
float du12 = (tri_u2-tri_u1)/(tri_y2-tri_y1), du23 = (tri_u3-tri_u2)/(tri_y3-tri_y2), du13 = (tri_u3-tri_u1)/(tri_y3-tri_y1);
float dv12 = (tri_v2-tri_v1)/(tri_y2-tri_y1), dv23 = (tri_v3-tri_v2)/(tri_y3-tri_y2), dv13 = (tri_v3-tri_v1)/(tri_y3-tri_y1);
//- Round to pixel and clip to top & bottom of screen
int y1 = (int)tri_y1; if(y1 < tri_y1) y1++;
int y2 = (int)tri_y2; if(y2 < tri_y2) y2++;
int y3 = (int)tri_y3; if(y3 < tri_y3) y3++;
if(y1 < clip_y1) y1 = clip_y1;
if(y2 < clip_y1) y2 = clip_y1;
if(y3 < clip_y1) y3 = clip_y1;
if(y1 > clip_y2) y1 = clip_y2;
if(y2 > clip_y2) y2 = clip_y2;
if(y3 > clip_y2) y3 = clip_y2;
if(y3 <= y1) return;
//- Calculate horizontal and vertical deltas for parameters
float d = (tri_x3-tri_x1)*(tri_y2-tri_y1) - (tri_y3-tri_y1)*(tri_x2-tri_x1);
float dux = ( (tri_y2-tri_y1)*(tri_u3-tri_u1) + (tri_y1-tri_y3)*(tri_u2-tri_u1) ) / d;
float duy = ( (tri_x1-tri_x2)*(tri_u3-tri_u1) + (tri_x3-tri_x1)*(tri_u2-tri_u1) ) / d;
float dvx = ( (tri_y2-tri_y1)*(tri_v3-tri_v1) + (tri_y1-tri_y3)*(tri_v2-tri_v1) ) / d;
float dvy = ( (tri_x1-tri_x2)*(tri_v3-tri_v1) + (tri_x3-tri_x1)*(tri_v2-tri_v1) ) / d;
//- See if we need to flip triangle horizontally
bool side13onleft = dx13 < dx12;
//- Draw top of triangle
float xa, xb, dxa, dxb;
if(side13onleft) {
xa = tri_x1 + dx13 * (y1-tri_y1);
xb = tri_x1 + dx12 * (y1-tri_y1);
dxa = dx13;
dxb = dx12;
} else {
xa = tri_x1 + dx12 * (y1-tri_y1);
xb = tri_x1 + dx13 * (y1-tri_y1);
dxa = dx12;
dxb = dx13;
}
float ul = tri_u1 - tri_x1*dux + (y1-tri_y1)*duy;
float vl = tri_v1 - tri_x1*dvx + (y1-tri_y1)*dvy;
for(j=y1; j<y2; j++)
{
int xai = (int)xa; if(xai < xa) xai++;
int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
float u = ul + xai*dux;
float v = vl + xai*dvx;
for(i=xai; i<xbi; i++)
{
screen[j][i] = texture[(int)v][(int)u];
u += dux; v += dvx;
}
xa += dxa; xb += dxb;
ul += duy;
vl += dvy;
}
//- Draw bottom of triangle
if(side13onleft) {
xb = tri_x2 + dx23 * (y2-tri_y2);
dxb = dx23;
} else {
xa = tri_x2 + dx23 * (y2-tri_y2);
dxa = dx23;
}
for(j=y2; j<y3; j++)
{
int xai = (int)xa; if(xai < xa) xai++;
int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
float u = ul + xai*dux;
float v = vl + xai*dvx;
for(i=xai; i<xbi; i++)
{
screen[j][i] = texture[(int)v][(int)u];
u += dux; v += dvx;
}
xa += dxa; xb += dxb;
ul += duy;
vl += dvy;
}
}
//----------------------------------------------------------------------------//
void Tri_Tex16_0002()
{
int i, j;
//- Sort points
float t;
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
if(tri_y3 < tri_y2)
{
t = tri_x2; tri_x2 = tri_x3; tri_x3 = t;
t = tri_y2; tri_y2 = tri_y3; tri_y3 = t;
t = tri_u2; tri_u2 = tri_u3; tri_u3 = t;
t = tri_v2; tri_v2 = tri_v3; tri_v3 = t;
}
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
//- Work out deltas along edges
float dx12 = (tri_x2-tri_x1)/(tri_y2-tri_y1), dx23 = (tri_x3-tri_x2)/(tri_y3-tri_y2), dx13 = (tri_x3-tri_x1)/(tri_y3-tri_y1);
float du12 = (tri_u2-tri_u1)/(tri_y2-tri_y1), du23 = (tri_u3-tri_u2)/(tri_y3-tri_y2), du13 = (tri_u3-tri_u1)/(tri_y3-tri_y1);
float dv12 = (tri_v2-tri_v1)/(tri_y2-tri_y1), dv23 = (tri_v3-tri_v2)/(tri_y3-tri_y2), dv13 = (tri_v3-tri_v1)/(tri_y3-tri_y1);
//- Round to pixel and clip to top & bottom of screen
int y1 = (int)tri_y1; if(y1 < tri_y1) y1++;
int y2 = (int)tri_y2; if(y2 < tri_y2) y2++;
int y3 = (int)tri_y3; if(y3 < tri_y3) y3++;
if(y1 < clip_y1) y1 = clip_y1;
if(y2 < clip_y1) y2 = clip_y1;
if(y3 < clip_y1) y3 = clip_y1;
if(y1 > clip_y2) y1 = clip_y2;
if(y2 > clip_y2) y2 = clip_y2;
if(y3 > clip_y2) y3 = clip_y2;
if(y3 <= y1) return;
//- Calculate horizontal and vertical deltas for parameters
float d = (tri_x3-tri_x1)*(tri_y2-tri_y1) - (tri_y3-tri_y1)*(tri_x2-tri_x1);
float dux = ( (tri_y2-tri_y1)*(tri_u3-tri_u1) + (tri_y1-tri_y3)*(tri_u2-tri_u1) ) / d;
float duy = ( (tri_x1-tri_x2)*(tri_u3-tri_u1) + (tri_x3-tri_x1)*(tri_u2-tri_u1) ) / d;
float dvx = ( (tri_y2-tri_y1)*(tri_v3-tri_v1) + (tri_y1-tri_y3)*(tri_v2-tri_v1) ) / d;
float dvy = ( (tri_x1-tri_x2)*(tri_v3-tri_v1) + (tri_x3-tri_x1)*(tri_v2-tri_v1) ) / d;
//- See if we need to flip triangle horizontally
bool side13onleft = dx13 < dx12;
//- Draw top of triangle
float xa, xb, dxa, dxb;
if(side13onleft) {
xa = tri_x1 + dx13 * (y1-tri_y1);
xb = tri_x1 + dx12 * (y1-tri_y1);
dxa = dx13;
dxb = dx12;
} else {
xa = tri_x1 + dx12 * (y1-tri_y1);
xb = tri_x1 + dx13 * (y1-tri_y1);
dxa = dx12;
dxb = dx13;
}
float ul = tri_u1 - tri_x1*dux + (y1-tri_y1)*duy;
float vl = tri_v1 - tri_x1*dvx + (y1-tri_y1)*dvy;
int fxa = xa *0x10000, fxb = xb *0x10000;
int fdxa = dxa*0x10000, fdxb = dxb*0x10000;
int ful = ul *0x10000, fvl = vl *0x10000;
int fdux = dux*0x10000, fdvx = dvx*0x10000;
int fduy = duy*0x10000, fdvy = dvy*0x10000;
for(j=y1; j<y2; j++)
{
int xai = (fxa+0xFFFF) >> 16; // int xai = (int)xa; if(xai < xa) xai++;
int xbi = (fxb+0xFFFF) >> 16; // int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
int fu = ful + xai*fdux; // float u = ul + xai*dux;
int fv = fvl + xai*fdvx; // float v = vl + xai*dvx;
unsigned short *buf = &screen[j][xai];
for(i=xai; i<xbi; i++)
{
*buf++ = texture[fv>>16][fu>>16];
fu += fdux; fv += fdvx;
}
fxa += fdxa; fxb += fdxb;
ful += fduy;
fvl += fdvy;
}
//- Draw bottom of triangle
if(side13onleft) {
xb = tri_x2 + dx23 * (y2-tri_y2);
dxb = dx23;
fxb = xb *0x10000;
fdxb = dxb*0x10000;
} else {
xa = tri_x2 + dx23 * (y2-tri_y2);
dxa = dx23;
fxa = xa *0x10000;
fdxa = dxa*0x10000;
}
for(j=y2; j<y3; j++)
{
int xai = (fxa+0xFFFF) >> 16; // int xai = (int)xa; if(xai < xa) xai++;
int xbi = (fxb+0xFFFF) >> 16; // int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
int fu = ful + xai*fdux; // float u = ul + xai*dux;
int fv = fvl + xai*fdvx; // float v = vl + xai*dvx;
unsigned short *buf = &screen[j][xai];
for(i=xai; i<xbi; i++)
{
*buf++ = texture[fv>>16][fu>>16];
fu += fdux; fv += fdvx;
}
fxa += fdxa; fxb += fdxb;
ful += fduy;
fvl += fdvy;
}
}
//----------------------------------------------------------------------------//
void Tri_Tex16_0003()
{
int i, j;
//- Sort points
float t;
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
if(tri_y3 < tri_y2)
{
t = tri_x2; tri_x2 = tri_x3; tri_x3 = t;
t = tri_y2; tri_y2 = tri_y3; tri_y3 = t;
t = tri_u2; tri_u2 = tri_u3; tri_u3 = t;
t = tri_v2; tri_v2 = tri_v3; tri_v3 = t;
}
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
//- Work out deltas along edges
float dx12 = (tri_x2-tri_x1)/(tri_y2-tri_y1), dx23 = (tri_x3-tri_x2)/(tri_y3-tri_y2), dx13 = (tri_x3-tri_x1)/(tri_y3-tri_y1);
float du12 = (tri_u2-tri_u1)/(tri_y2-tri_y1), du23 = (tri_u3-tri_u2)/(tri_y3-tri_y2), du13 = (tri_u3-tri_u1)/(tri_y3-tri_y1);
float dv12 = (tri_v2-tri_v1)/(tri_y2-tri_y1), dv23 = (tri_v3-tri_v2)/(tri_y3-tri_y2), dv13 = (tri_v3-tri_v1)/(tri_y3-tri_y1);
//- Round to pixel and clip to top & bottom of screen
int y1 = (int)tri_y1; if(y1 < tri_y1) y1++;
int y2 = (int)tri_y2; if(y2 < tri_y2) y2++;
int y3 = (int)tri_y3; if(y3 < tri_y3) y3++;
if(y1 < clip_y1) y1 = clip_y1;
if(y2 < clip_y1) y2 = clip_y1;
if(y3 < clip_y1) y3 = clip_y1;
if(y1 > clip_y2) y1 = clip_y2;
if(y2 > clip_y2) y2 = clip_y2;
if(y3 > clip_y2) y3 = clip_y2;
if(y3 <= y1) return;
//- Calculate horizontal and vertical deltas for parameters
float d = (tri_x3-tri_x1)*(tri_y2-tri_y1) - (tri_y3-tri_y1)*(tri_x2-tri_x1);
float dux = ( (tri_y2-tri_y1)*(tri_u3-tri_u1) + (tri_y1-tri_y3)*(tri_u2-tri_u1) ) / d;
float duy = ( (tri_x1-tri_x2)*(tri_u3-tri_u1) + (tri_x3-tri_x1)*(tri_u2-tri_u1) ) / d;
float dvx = ( (tri_y2-tri_y1)*(tri_v3-tri_v1) + (tri_y1-tri_y3)*(tri_v2-tri_v1) ) / d;
float dvy = ( (tri_x1-tri_x2)*(tri_v3-tri_v1) + (tri_x3-tri_x1)*(tri_v2-tri_v1) ) / d;
int fdux = dux*0x10000, fdvx = dvx*0x10000;
int fduy = duy*0x10000, fdvy = dvy*0x10000;
//- See if we need to flip triangle horizontally
bool side13onleft = dx13 < dx12;
//- Draw top of triangle
float xa, xb, dxa, dxb;
// Swap over if necessary
if(side13onleft) {
xa = tri_x1 + dx13 * (y1-tri_y1);
xb = tri_x1 + dx12 * (y1-tri_y1);
dxa = dx13;
dxb = dx12;
} else {
xa = tri_x1 + dx12 * (y1-tri_y1);
xb = tri_x1 + dx13 * (y1-tri_y1);
dxa = dx12;
dxb = dx13;
}
float ul = tri_u1 - tri_x1*dux + (y1-tri_y1)*duy;
float vl = tri_v1 - tri_x1*dvx + (y1-tri_y1)*dvy;
int fxa = xa *0x10000, fxb = xb *0x10000;
int fdxa = dxa*0x10000, fdxb = dxb*0x10000;
int ful = ul *0x10000, fvl = vl *0x10000;
for(j=y1; j<y2; j++)
{
int xai = (fxa+0xFFFF) >> 16; // int xai = (int)xa; if(xai < xa) xai++;
int xbi = (fxb+0xFFFF) >> 16; // int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
int fu = ful + xai*fdux; // float u = ul + xai*dux;
int fv = fvl + xai*fdvx; // float v = vl + xai*dvx;
unsigned short *buf = &screen[j][xai];
/*
for(i=xai; i<xbi; i++)
{
*buf++ = texture[fv>>16][fu>>16];
fu += fdux; fv += fdvx;
}
*/
_asm {
mov edi, buf
mov ecx, xai
sub ecx, xbi
jge t_xloop_end
// Set up registers for loop
// ebx = vf: ui edx = uf: vi
// esi = dvf:dui ebp = duf:dvi
push ebp
mov ebx, fv
mov edx, fu
mov esi, fdvx
mov ebp, fdux
rol ebx, 16
rol edx, 16
rol esi, 16
rol ebp, 16
xchg bx, dx
xchg si, bp
sub edi, ecx
sub edi, ecx
sub edi, 2 // Make up for putting inc ecx before mov [
xor eax, eax // Make sure top word of eax is clear for texture lookup
sub dx, bp // Set up carry for loop
add edx, ebp
// Inner loop
t_xloop:
mov al, bl
adc ebx, esi
mov ah, dl
adc edx, ebp
mov ax, texture[eax*2]
inc ecx
mov [edi+ecx*2], ax
jnz t_xloop
// Inner loop done
pop ebp
t_xloop_end:
}
fxa += fdxa; fxb += fdxb;
ful += fduy;
fvl += fdvy;
}
//- Draw bottom of triangle
if(side13onleft) {
xb = tri_x2 + dx23 * (y2-tri_y2);
dxb = dx23;
fxb = xb *0x10000;
fdxb = dxb*0x10000;
} else {
xa = tri_x2 + dx23 * (y2-tri_y2);
dxa = dx23;
fxa = xa *0x10000;
fdxa = dxa*0x10000;
}
for(j=y2; j<y3; j++)
{
int xai = (fxa+0xFFFF) >> 16; // int xai = (int)xa; if(xai < xa) xai++;
int xbi = (fxb+0xFFFF) >> 16; // int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
int fu = ful + xai*fdux; // float u = ul + xai*dux;
int fv = fvl + xai*fdvx; // float v = vl + xai*dvx;
unsigned short *buf = &screen[j][xai];
/*
for(i=xai; i<xbi; i++)
{
*buf++ = texture[fv>>16][fu>>16];
fu += fdux; fv += fdvx;
}
*/
_asm {
mov edi, buf
mov ecx, xai
sub ecx, xbi
jge b_xloop_end
// Set up registers for loop
// ebx = vf: xx edx = uf: vi
// esi = dvf:dui ebp = duf:dvi
push ebp
mov ebx, fv
mov edx, fu
mov esi, fdvx
mov ebp, fdux
rol ebx, 16
rol edx, 16
rol esi, 16
rol ebp, 16
xchg bx, dx
xchg si, bp
sub edi, ecx
sub edi, ecx
xor eax, eax // Make sure top word of eax is clear for texture lookup
sub dx, bp // Set up carry for loop
add edx, ebp
// Inner loop
b_xloop:
mov al, bl
adc ebx, esi
mov ah, dl
adc edx, ebp
mov ax, texture[eax*2]
inc ecx
mov [edi+ecx*2], ax
jnz b_xloop
// Inner loop done
pop ebp
b_xloop_end:
}
fxa += fdxa; fxb += fdxb;
ful += fduy;
fvl += fdvy;
}
}
//----------------------------------------------------------------------------//
void Tri_Tex16_256()
{
int i, j;
//- Sort points
float t;
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
if(tri_y3 < tri_y2)
{
t = tri_x2; tri_x2 = tri_x3; tri_x3 = t;
t = tri_y2; tri_y2 = tri_y3; tri_y3 = t;
t = tri_u2; tri_u2 = tri_u3; tri_u3 = t;
t = tri_v2; tri_v2 = tri_v3; tri_v3 = t;
}
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
//- Work out deltas along edges
float dx12 = (tri_x2-tri_x1)/(tri_y2-tri_y1), dx23 = (tri_x3-tri_x2)/(tri_y3-tri_y2), dx13 = (tri_x3-tri_x1)/(tri_y3-tri_y1);
float du12 = (tri_u2-tri_u1)/(tri_y2-tri_y1), du23 = (tri_u3-tri_u2)/(tri_y3-tri_y2), du13 = (tri_u3-tri_u1)/(tri_y3-tri_y1);
float dv12 = (tri_v2-tri_v1)/(tri_y2-tri_y1), dv23 = (tri_v3-tri_v2)/(tri_y3-tri_y2), dv13 = (tri_v3-tri_v1)/(tri_y3-tri_y1);
//- Round to pixel and clip to top & bottom of screen
int y1 = (int)tri_y1; if(y1 < tri_y1) y1++;
int y2 = (int)tri_y2; if(y2 < tri_y2) y2++;
int y3 = (int)tri_y3; if(y3 < tri_y3) y3++;
if(y1 < clip_y1) y1 = clip_y1;
if(y2 < clip_y1) y2 = clip_y1;
if(y3 < clip_y1) y3 = clip_y1;
if(y1 > clip_y2) y1 = clip_y2;
if(y2 > clip_y2) y2 = clip_y2;
if(y3 > clip_y2) y3 = clip_y2;
if(y3 <= y1) return;
//- Calculate horizontal and vertical deltas for parameters
float d = (tri_x3-tri_x1)*(tri_y2-tri_y1) - (tri_y3-tri_y1)*(tri_x2-tri_x1);
float dux = ( (tri_y2-tri_y1)*(tri_u3-tri_u1) + (tri_y1-tri_y3)*(tri_u2-tri_u1) ) / d;
float duy = ( (tri_x1-tri_x2)*(tri_u3-tri_u1) + (tri_x3-tri_x1)*(tri_u2-tri_u1) ) / d;
float dvx = ( (tri_y2-tri_y1)*(tri_v3-tri_v1) + (tri_y1-tri_y3)*(tri_v2-tri_v1) ) / d;
float dvy = ( (tri_x1-tri_x2)*(tri_v3-tri_v1) + (tri_x3-tri_x1)*(tri_v2-tri_v1) ) / d;
int fdux = dux*0x10000, fdvx = dvx*0x10000;
int fduy = duy*0x10000, fdvy = dvy*0x10000;
//- See if we need to flip triangle horizontally
bool side13onleft = dx13 < dx12;
//- Draw top of triangle
float xa, xb, dxa, dxb;
// Swap over if necessary
if(side13onleft) {
xa = tri_x1 + dx13 * (y1-tri_y1);
xb = tri_x1 + dx12 * (y1-tri_y1);
dxa = dx13;
dxb = dx12;
} else {
xa = tri_x1 + dx12 * (y1-tri_y1);
xb = tri_x1 + dx13 * (y1-tri_y1);
dxa = dx12;
dxb = dx13;
}
float ul = tri_u1 - tri_x1*dux + (y1-tri_y1)*duy;
float vl = tri_v1 - tri_x1*dvx + (y1-tri_y1)*dvy;
int fxa = xa *0x10000, fxb = xb *0x10000;
int fdxa = dxa*0x10000, fdxb = dxb*0x10000;
int ful = ul *0x10000, fvl = vl *0x10000;
for(j=y1; j<y2; j++)
{
int xai = (fxa+0xFFFF) >> 16; // int xai = (int)xa; if(xai < xa) xai++;
int xbi = (fxb+0xFFFF) >> 16; // int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
int fu = ful + xai*fdux; // float u = ul + xai*dux;
int fv = fvl + xai*fdvx; // float v = vl + xai*dvx;
unsigned short *buf = &screen[j][xai];
/*
for(i=xai; i<xbi; i++)
{
*buf++ = texture[fv>>16][fu>>16];
fu += fdux; fv += fdvx;
}
*/
_asm {
// Set up loop registers
mov edi, xai
sub edi, xbi
jge t_xloop_end
// Set up delta registers
// ebx = [ Ui Uf Uf Vi ]
// ecx = [ dUi dUf 0 dVi ]
// edx = [ Vf Vf 0 0 ]
// esi = [ dVf dVf 0 0 ]
mov esi, fdvx
mov edx, fv
shl esi, 16
shl edx, 16
mov ebx, fu
mov eax, fv
shl ebx, 8
shr eax, 16
and eax, 0x000000FF
add ebx, eax
mov ecx, fdux
mov eax, fdvx
shl ecx, 8
shr eax, 16
and eax, 0x000000FF
add ecx, eax
// Set up loop registers
mov eax, edi
mov edi, buf
sub edi, eax
sub edi, eax
push ebp
mov ebp, eax
// Inner loop
mov eax, ebx
rol eax, 8
t_xloop:
and eax, 0x0000FFFF
add edx, esi
adc ebx, ecx
mov ax, texture[eax*2]
mov [edi+ebp*2], ax
mov eax, ebx
rol eax, 8
inc ebp
jnz t_xloop
// Inner loop done
pop ebp
t_xloop_end:
}
fxa += fdxa; fxb += fdxb;
ful += fduy;
fvl += fdvy;
}
//- Draw bottom of triangle
if(side13onleft) {
xb = tri_x2 + dx23 * (y2-tri_y2);
dxb = dx23;
fxb = xb *0x10000;
fdxb = dxb*0x10000;
} else {
xa = tri_x2 + dx23 * (y2-tri_y2);
dxa = dx23;
fxa = xa *0x10000;
fdxa = dxa*0x10000;
}
for(j=y2; j<y3; j++)
{
int xai = (fxa+0xFFFF) >> 16; // int xai = (int)xa; if(xai < xa) xai++;
int xbi = (fxb+0xFFFF) >> 16; // int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
int fu = ful + xai*fdux; // float u = ul + xai*dux;
int fv = fvl + xai*fdvx; // float v = vl + xai*dvx;
unsigned short *buf = &screen[j][xai];
/*
for(i=xai; i<xbi; i++)
{
*buf++ = texture[fv>>16][fu>>16];
fu += fdux; fv += fdvx;
}
*/
_asm {
// Set up loop registers
mov edi, xai
sub edi, xbi
jge b_xloop_end
// Set up delta registers
// ebx = [ Ui Uf Uf Vi ]
// ecx = [ dUi dUf 0 dVi ]
// edx = [ Vf Vf 0 0 ]
// esi = [ dVf dVf 0 0 ]
mov esi, fdvx
mov edx, fv
shl esi, 16
shl edx, 16
mov ebx, fu
mov eax, fv
shl ebx, 8
shr eax, 16
and eax, 0x000000FF
add ebx, eax
mov ecx, fdux
mov eax, fdvx
shl ecx, 8
shr eax, 16
and eax, 0x000000FF
add ecx, eax
// Set up loop registers
mov eax, edi
mov edi, buf
sub edi, eax
sub edi, eax
push ebp
mov ebp, eax
// Inner loop
mov eax, ebx
rol eax, 8
b_xloop:
and eax, 0x0000FFFF
add edx, esi
adc ebx, ecx
mov ax, texture[eax*2]
mov [edi+ebp*2], ax
mov eax, ebx
rol eax, 8
inc ebp
jnz b_xloop
// Inner loop done
pop ebp
b_xloop_end:
}
fxa += fdxa; fxb += fdxb;
ful += fduy;
fvl += fdvy;
}
}
//----------------------------------------------------------------------------//
/*
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
r r r r r g g g g g g b b b b b
8-bit lighting value ?
*/
void Tri_SpecularTex16()
{
int i, j;
//- Sort points
float t;
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
t = tri_s1; tri_s1 = tri_s2; tri_s2 = t;
}
if(tri_y3 < tri_y2)
{
t = tri_x2; tri_x2 = tri_x3; tri_x3 = t;
t = tri_y2; tri_y2 = tri_y3; tri_y3 = t;
t = tri_u2; tri_u2 = tri_u3; tri_u3 = t;
t = tri_v2; tri_v2 = tri_v3; tri_v3 = t;
t = tri_s2; tri_s2 = tri_s3; tri_s3 = t;
}
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
t = tri_s1; tri_s1 = tri_s2; tri_s2 = t;
}
//- Work out deltas along edges
float dx12 = (tri_x2-tri_x1)/(tri_y2-tri_y1), dx23 = (tri_x3-tri_x2)/(tri_y3-tri_y2), dx13 = (tri_x3-tri_x1)/(tri_y3-tri_y1);
float du12 = (tri_u2-tri_u1)/(tri_y2-tri_y1), du23 = (tri_u3-tri_u2)/(tri_y3-tri_y2), du13 = (tri_u3-tri_u1)/(tri_y3-tri_y1);
float dv12 = (tri_v2-tri_v1)/(tri_y2-tri_y1), dv23 = (tri_v3-tri_v2)/(tri_y3-tri_y2), dv13 = (tri_v3-tri_v1)/(tri_y3-tri_y1);
float ds12 = (tri_s2-tri_s1)/(tri_y2-tri_y1), ds23 = (tri_s3-tri_s2)/(tri_y3-tri_y2), ds13 = (tri_s3-tri_s1)/(tri_y3-tri_y1);
//- Round to pixel and clip to top & bottom of screen
int y1 = (int)tri_y1; if(y1 < tri_y1) y1++;
int y2 = (int)tri_y2; if(y2 < tri_y2) y2++;
int y3 = (int)tri_y3; if(y3 < tri_y3) y3++;
if(y1 < clip_y1) y1 = clip_y1;
if(y2 < clip_y1) y2 = clip_y1;
if(y3 < clip_y1) y3 = clip_y1;
if(y1 > clip_y2) y1 = clip_y2;
if(y2 > clip_y2) y2 = clip_y2;
if(y3 > clip_y2) y3 = clip_y2;
if(y3 <= y1) return;
//- Calculate horizontal and vertical deltas for parameters
float d = (tri_x3-tri_x1)*(tri_y2-tri_y1) - (tri_y3-tri_y1)*(tri_x2-tri_x1);
float dux = ( (tri_y2-tri_y1)*(tri_u3-tri_u1) + (tri_y1-tri_y3)*(tri_u2-tri_u1) ) / d;
float duy = ( (tri_x1-tri_x2)*(tri_u3-tri_u1) + (tri_x3-tri_x1)*(tri_u2-tri_u1) ) / d;
float dvx = ( (tri_y2-tri_y1)*(tri_v3-tri_v1) + (tri_y1-tri_y3)*(tri_v2-tri_v1) ) / d;
float dvy = ( (tri_x1-tri_x2)*(tri_v3-tri_v1) + (tri_x3-tri_x1)*(tri_v2-tri_v1) ) / d;
float dsx = ( (tri_y2-tri_y1)*(tri_s3-tri_s1) + (tri_y1-tri_y3)*(tri_s2-tri_s1) ) / d;
float dsy = ( (tri_x1-tri_x2)*(tri_s3-tri_s1) + (tri_x3-tri_x1)*(tri_s2-tri_s1) ) / d;
int fdux = dux*0x10000, fduy = duy*0x10000;
int fdvx = dvy*0x10000, fdvy = dvy*0x10000;
int fdsx = dsx*0x10000, fdsy = dsy*0x10000;
//- See if we need to flip triangle horizontally
bool side13onleft = dx13 < dx12;
//- Draw top of triangle
float xa, xb, dxa, dxb;
// Swap over if necessary
if(side13onleft) {
xa = tri_x1 + dx13 * (y1-tri_y1);
xb = tri_x1 + dx12 * (y1-tri_y1);
dxa = dx13;
dxb = dx12;
}
else
{
xa = tri_x1 + dx12 * (y1-tri_y1);
xb = tri_x1 + dx13 * (y1-tri_y1);
dxa = dx12;
dxb = dx13;
}
float ul = tri_u1 - tri_x1*dux + (y1-tri_y1)*duy;
float vl = tri_v1 - tri_x1*dvx + (y1-tri_y1)*dvy;
float sl = tri_s1 - tri_x1*dsx + (y1-tri_y1)*dsy;
int fxa = xa *0x10000, fxb = xb *0x10000;
int fdxa = dxa*0x10000, fdxb = dxb*0x10000;
int ful = ul *0x10000;
int fvl = vl *0x10000;
int fsl = sl *0x10000;
for(j=y1; j<y2; j++)
{
int xai = (fxa+0xFFFF) >> 16; // int xai = (int)xa; if(xai < xa) xai++;
int xbi = (fxb+0xFFFF) >> 16; // int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
int fu = ful + xai*fdux; // float u = ul + xai*dux;
int fv = fvl + xai*fdvx; // float v = vl + xai*dvx;
int fs = fsl + xai*fdsx;
unsigned short *buf = &screen[j][xai];
for(i=xai; i<xbi; i++)
{
*buf++ = texture[fv>>16][fu>>16];
fu += fdux; fv += fdvx;
}
fxa += fdxa; fxb += fdxb;
ful += fduy;
fvl += fdvy;
fsl += fdsy;
}
//- Draw bottom of triangle
if(side13onleft)
{
xb = tri_x2 + dx23 * (y2-tri_y2);
dxb = dx23;
fxb = xb *0x10000;
fdxb = dxb*0x10000;
}
else
{
xa = tri_x2 + dx23 * (y2-tri_y2);
dxa = dx23;
fxa = xa *0x10000;
fdxa = dxa*0x10000;
}
for(j=y2; j<y3; j++)
{
int xai = (fxa+0xFFFF) >> 16; // int xai = (int)xa; if(xai < xa) xai++;
int xbi = (fxb+0xFFFF) >> 16; // int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
int fu = ful + xai*fdux; // float u = ul + xai*dux;
int fv = fvl + xai*fdvx; // float v = vl + xai*dvx;
unsigned short *buf = &screen[j][xai];
for(i=xai; i<xbi; i++)
{
*buf++ = texture[fv>>16][fu>>16];
fu += fdux; fv += fdvx;
}
fxa += fdxa; fxb += fdxb;
ful += fduy;
fvl += fdvy;
}
}
//----------------------------------------------------------------------------//
void Tri_PerspTex16()
{
int i, j;
//- Sort points
float t;
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_z1; tri_z1 = tri_z2; tri_z2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
if(tri_y3 < tri_y2)
{
t = tri_x2; tri_x2 = tri_x3; tri_x3 = t;
t = tri_y2; tri_y2 = tri_y3; tri_y3 = t;
t = tri_z2; tri_z2 = tri_z3; tri_z3 = t;
t = tri_u2; tri_u2 = tri_u3; tri_u3 = t;
t = tri_v2; tri_v2 = tri_v3; tri_v3 = t;
}
if(tri_y2 < tri_y1)
{
t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
t = tri_z1; tri_z1 = tri_z2; tri_z2 = t;
t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
}
//- Divide by z to do perspective correction
tri_u1 /= tri_z1; tri_u2 /= tri_z2; tri_u3 /= tri_z3;
tri_v1 /= tri_z1; tri_v2 /= tri_z2; tri_v3 /= tri_z3;
tri_z1 = 1.0/tri_z1; tri_z2 = 1.0/tri_z2; tri_z3 = 1.0/tri_z3;
//- Work out deltas along edges
float dx12 = (tri_x2-tri_x1)/(tri_y2-tri_y1), dx23 = (tri_x3-tri_x2)/(tri_y3-tri_y2), dx13 = (tri_x3-tri_x1)/(tri_y3-tri_y1);
float dz12 = (tri_z2-tri_z1)/(tri_y2-tri_y1), dz23 = (tri_z3-tri_z2)/(tri_y3-tri_y2), dz13 = (tri_z3-tri_z1)/(tri_y3-tri_y1);
float du12 = (tri_u2-tri_u1)/(tri_y2-tri_y1), du23 = (tri_u3-tri_u2)/(tri_y3-tri_y2), du13 = (tri_u3-tri_u1)/(tri_y3-tri_y1);
float dv12 = (tri_v2-tri_v1)/(tri_y2-tri_y1), dv23 = (tri_v3-tri_v2)/(tri_y3-tri_y2), dv13 = (tri_v3-tri_v1)/(tri_y3-tri_y1);
//- Round to pixel and clip to top & bottom of screen
int y1 = (int)tri_y1; if(y1 < tri_y1) y1++;
int y2 = (int)tri_y2; if(y2 < tri_y2) y2++;
int y3 = (int)tri_y3; if(y3 < tri_y3) y3++;
if(y1 < clip_y1) y1 = clip_y1;
if(y2 < clip_y1) y2 = clip_y1;
if(y3 < clip_y1) y3 = clip_y1;
if(y1 > clip_y2) y1 = clip_y2;
if(y2 > clip_y2) y2 = clip_y2;
if(y3 > clip_y2) y3 = clip_y2;
if(y3 <= y1) return;
//- Calculate horizontal and vertical deltas for parameters
float d = (tri_x3-tri_x1)*(tri_y2-tri_y1) - (tri_y3-tri_y1)*(tri_x2-tri_x1);
float dzx = ( (tri_y2-tri_y1)*(tri_z3-tri_z1) + (tri_y1-tri_y3)*(tri_z2-tri_z1) ) / d;
float dzy = ( (tri_x1-tri_x2)*(tri_z3-tri_z1) + (tri_x3-tri_x1)*(tri_z2-tri_z1) ) / d;
float dux = ( (tri_y2-tri_y1)*(tri_u3-tri_u1) + (tri_y1-tri_y3)*(tri_u2-tri_u1) ) / d;
float duy = ( (tri_x1-tri_x2)*(tri_u3-tri_u1) + (tri_x3-tri_x1)*(tri_u2-tri_u1) ) / d;
float dvx = ( (tri_y2-tri_y1)*(tri_v3-tri_v1) + (tri_y1-tri_y3)*(tri_v2-tri_v1) ) / d;
float dvy = ( (tri_x1-tri_x2)*(tri_v3-tri_v1) + (tri_x3-tri_x1)*(tri_v2-tri_v1) ) / d;
//- See if we need to flip triangle horizontally
bool side13onleft = dx13 < dx12;
//- Draw top of triangle
float xa, xb, dxa, dxb;
if(side13onleft)
{
xa = tri_x1 + dx13 * (y1-tri_y1);
xb = tri_x1 + dx12 * (y1-tri_y1);
dxa = dx13;
dxb = dx12;
}
else
{
xa = tri_x1 + dx12 * (y1-tri_y1);
xb = tri_x1 + dx13 * (y1-tri_y1);
dxa = dx12;
dxb = dx13;
}
float zl = tri_z1 - tri_x1*dzx + (y1-tri_y1)*dzy;
float ul = tri_u1 - tri_x1*dux + (y1-tri_y1)*duy;
float vl = tri_v1 - tri_x1*dvx + (y1-tri_y1)*dvy;
for(j=y1; j<y2; j++)
{
int xai = (int)xa; if(xai < xa) xai++;
int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
float z = zl + xai*dzx;
float u = ul + xai*dux;
float v = vl + xai*dvx;
for(i=xai; i<xbi; i++)
{
screen[j][i] = texture[(int)(v/z)][(int)(u/z)];
z += dzx;
u += dux;
v += dvx;
}
xa += dxa; xb += dxb;
zl += dzy;
ul += duy;
vl += dvy;
}
//- Draw bottom of triangle
if(side13onleft)
{
xb = tri_x2 + dx23 * (y2-tri_y2);
dxb = dx23;
}
else
{
xa = tri_x2 + dx23 * (y2-tri_y2);
dxa = dx23;
}
for(j=y2; j<y3; j++)
{
int xai = (int)xa; if(xai < xa) xai++;
int xbi = (int)xb; if(xbi < xb) xbi++;
if(xai < clip_x1) xai = clip_x1;
if(xbi < clip_x1) xbi = clip_x1;
if(xai > clip_x2) xai = clip_x2;
if(xbi > clip_x2) xbi = clip_x2;
float z = zl + xai*dzx;
float u = ul + xai*dux;
float v = vl + xai*dvx;
for(i=xai; i<xbi; i++)
{
screen[j][i] = texture[(int)(v/z)][(int)(u/z)];
z += dzx;
u += dux;
v += dvx;
}
xa += dxa; xb += dxb;
zl += dzy;
ul += duy;
vl += dvy;
}
}
//----------------------------------------------------------------------------//
bool init = false;
void Init()
{
if(init) return;
int i, j;
for(j=0; j<256; j++) for(i=0; i<256; i++) {
texture[j][i] = ((i>>3)*951)+((j>>3)*91);
}
}
//----------------------------------------------------------------------------//
BOOL Idle(unsigned long time)
{
Init();
int i, j;
//- Clear buffer
// ZeroMemory(screen, sizeof(screen));
//- Draw triangle
/*
float a = time*3.14159/15000.0;
float d = 3.14159*2.0/3.0;
tri_x1 = 320.33 + 200.33 * sin(a+d*0); tri_y1 = 240.33 + 200.33 * cos(a+d*0);
tri_x2 = 320.33 + 200.33 * sin(a+d*1); tri_y2 = 240.33 + 200.33 * cos(a+d*1);
tri_x3 = 320.33 + 200.33 * sin(a+d*2); tri_y3 = 240.33 + 200.33 * cos(a+d*2);
tri_u1 = 128 + 32 * sin(d*0); tri_v1 = 128 + 32 * cos(d*0);
tri_u2 = 128 + 32 * sin(d*1); tri_v2 = 128 + 32 * cos(d*1);
tri_u3 = 128 + 32 * sin(d*2); tri_v3 = 128 + 32 * cos(d*2);
Tri_Tex16();
*/
//- Draw tiled triangles
float a = time*3.14159/16000.0;
float d = 3.14159*2.0/3.0;
float s = sqrt(3);
// Create array of points
float tx[16][16], ty[16][16];
for(j=-3; j<=3; j++) for(i=-3; i<=3; i++) {
float y = j*s;
float x = i*s - (j&1)*0.5*s;
tx[3+j][3+i] = (x*cos(a) - y*sin(a))/s;
ty[3+j][3+i] = (x*sin(a) + y*cos(a))/s;
}
// Draw array of triangles
float aa;
float scale = 200;
float ttx, tty;
float ccx = SCREEN_W*0.5 + 0.33, ccy = SCREEN_H*0.5 + 0.33;
for(j=0; j<6; j++) for(i=0; i<6; i++) {
// if(j & 1) {
tri_x1 = ccx + scale * tx[j+0][i+0]; tri_y1 = ccy + scale * ty[j+0][i+0];
tri_x2 = ccx + scale * tx[j+0][i+1]; tri_y2 = ccy + scale * ty[j+0][i+1];
tri_x3 = ccx + scale * tx[j+1][i+1]; tri_y3 = ccy + scale * ty[j+1][i+1];
aa = 0.2781 - 0.7218*i + 1.8724*j + 0.1919*(i^j);
ttx = 128 + 90*sin(1.2874-i*0.2847+j*0.1912+(i^j)*0.7821);
tty = 128 + 90*sin(0.1551+i*1.1511-j*1.5215-(i^j)*1.5128);
tri_u1 = ttx + 32 * sin(aa+d*0); tri_v1 = tty + 32 * cos(aa+d*0);
tri_u2 = ttx + 32 * sin(aa+d*1); tri_v2 = tty + 32 * cos(aa+d*1);
tri_u3 = ttx + 32 * sin(aa+d*2); tri_v3 = tty + 32 * cos(aa+d*2);
tri_z1 = 10; tri_z2 = 6; tri_z3 = 2;
Tri_Tex16();
tri_x1 = ccx + scale * tx[j+1][i+1]; tri_y1 = ccy + scale * ty[j+1][i+1];
tri_x2 = ccx + scale * tx[j+1][i+0]; tri_y2 = ccy + scale * ty[j+1][i+0];
tri_x3 = ccx + scale * tx[j+0][i+0]; tri_y3 = ccy + scale * ty[j+0][i+0];
aa = 1.2614 + 1.3281*i + 0.6117*j - 0.9162*(i^j);
ttx = 128 + 90*sin(0.3265+i*0.6611+j*1.3262-(i^j)*1.6121);
tty = 128 + 90*sin(0.1551-i*1.7188-j*0.5215+(i^j)*0.1171);
tri_u1 = ttx + 32 * sin(aa+d*0); tri_v1 = tty + 32 * cos(aa+d*0);
tri_u2 = ttx + 32 * sin(aa+d*1); tri_v2 = tty + 32 * cos(aa+d*1);
tri_u3 = ttx + 32 * sin(aa+d*2); tri_v3 = tty + 32 * cos(aa+d*2);
tri_z1 = 10; tri_z2 = 6; tri_z3 = 2;
Tri_Tex16();
/*
} else {
tri_x1 = 320.33 + scale * tx[j+0][i+0]; tri_y1 = 240.33 + scale * ty[j+0][i+0];
tri_x2 = 320.33 + scale * tx[j+1][i+0]; tri_y2 = 240.33 + scale * ty[j+1][i+0];
tri_x3 = 320.33 + scale * tx[j+1][i+1]; tri_y3 = 240.33 + scale * ty[j+1][i+1];
aa = 0.2781 - 0.7218*i + 1.8724*j + 0.1919*(i^j);
ttx = 128 + 90*sin(1.2874-i*0.2847+j*0.1912+(i^j)*0.7821);
tty = 128 + 90*sin(0.1551+i*1.1511-j*1.5215-(i^j)*1.5128);
tri_u1 = ttx + 32 * sin(aa+d*0); tri_v1 = tty + 32 * cos(aa+d*0);
tri_u2 = ttx + 32 * sin(aa+d*1); tri_v2 = tty + 32 * cos(aa+d*1);
tri_u3 = ttx + 32 * sin(aa+d*2); tri_v3 = tty + 32 * cos(aa+d*2);
Tri_Tex16();
tri_x1 = 320.33 + scale * tx[j+1][i+1]; tri_y1 = 240.33 + scale * ty[j+1][i+1];
tri_x2 = 320.33 + scale * tx[j+0][i+1]; tri_y2 = 240.33 + scale * ty[j+0][i+1];
tri_x3 = 320.33 + scale * tx[j+0][i+0]; tri_y3 = 240.33 + scale * ty[j+0][i+0];
aa = 1.2614 + 1.3281*i + 0.6117*j - 0.9162*(i^j);
ttx = 128 + 90*sin(0.3265+i*0.6611+j*1.3262-(i^j)*1.6121);
tty = 128 + 90*sin(0.1551-i*1.7188-j*0.5215+(i^j)*0.1171);
tri_u1 = ttx + 32 * sin(aa+d*0); tri_v1 = tty + 32 * cos(aa+d*0);
tri_u2 = ttx + 32 * sin(aa+d*1); tri_v2 = tty + 32 * cos(aa+d*1);
tri_u3 = ttx + 32 * sin(aa+d*2); tri_v3 = tty + 32 * cos(aa+d*2);
Tri_Tex16();
}
*/
}
//- Draw stuff
/*
for(j=0; j<256; j++) for(i=0; i<256; i++) {
screen[j][i] = texture[j][i];
}
*/
for(j=0; j<8; j++) for(i=0; i<8; i++) {
screen[j][i] = GetTickCount()+i*99+j*17;
}
//- Display
HDC dc = GetDC(hMainWindow);
Display(dc, (unsigned short *)screen, 0, 0, SCREEN_W, SCREEN_H);
ReleaseDC(hMainWindow, dc);
return TRUE;
}
//----------------------------------------------------------------------------//
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TRIANGLE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TRIANGLE);
// Main message loop:
MessageLoop();
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TRIANGLE);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_TRIANGLE;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
hMainWindow = hWnd;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
int MessageLoop()
{
MSG msg;
BOOL idle = TRUE;
while(TRUE) {
// Idle handler loop
while(idle) {
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) return TRUE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
unsigned long time = timeGetTime();//GetTickCount();
idle = Idle(time);
}
// Blocking (non-idle) loop
while(!idle) {
GetMessage(&msg, NULL, 0, 0);
if (msg.message == WM_QUIT) return msg.wParam;
if (msg.message == WM_USER) idle = TRUE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}