zterrain/MSVC/test.cpp
C++ source for ZSystem, 572 lines. Raw file
#define WIN32_LEAN_AND_MEAN
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include "qe_ogl.h"
//---- ZSYSTEM TEST VERSION 0.1 ----------------------------------------------//
//---- ZSYSTEM TYPES ---------------------------------------------------------//
typedef struct _ZS_RAND {
unsigned int a, b, c, d;
} ZS_RAND;
//---- ZSYSTEM DATA ----------------------------------------------------------//
int zs_cubes = 0;
int zs_buildings = 0;
//---- ZSYSTEM FUNCTIONS -----------------------------------------------------//
//---- ZS_Rand_Create --------------------------------------------------------//
ZS_RAND *ZS_Rand_Create(int seed)
{
ZS_RAND *r = (ZS_RAND *)malloc(sizeof(ZS_RAND));
if(!r) return NULL;
r->a = seed + 0x87123631;
r->b = seed * 3;
r->c = seed + 0x72319631;
r->d = seed ^ 0x24121531;
return r;
}
//---- ZS_Rand_Delete --------------------------------------------------------//
void ZS_Rand_Delete(ZS_RAND *r)
{
if(!r) return;
free(r);
}
//---- ZS_Rand ---------------------------------------------------------------//
unsigned int ZS_Rand(ZS_RAND *r, unsigned int max)
{
r->d ^= (r->c<<9) + (r->a>>7) + (r->d&r->a);
r->a += r->b>>1;
r->b += r->c^0xF0F0A05;
r->c += r->d;
r->d += 0x35136613;
unsigned int v = ( (r->a*7 + r->c*6)^((r->b<<13)-(r->d>>3)) );
if(max == 0) return v;
return v % max;
}
//---- ZS_Rand_Tween ---------------------------------------------------------//
double ZS_Rand_Tween(ZS_RAND *r, double min, double max)
{
double t = min + ZS_Rand(r, 1000000)*0.000001*(max-min);
return t;
}
//---- ZSYSTEM OBJECT: CUBE --------------------------------------------------//
void Cube(double x1, double y1, double z1, double x2, double y2, double z2, double r, double g, double b)
{
zs_cubes ++;
/*
int rr, gg, bb;
rr = zs_cubes*787;
gg = (zs_cubes*17)^815;
bb = ((zs_cubes*91)|812)/3;
r = (rr%1000)*0.001;
g = (gg%1000)*0.001;
b = (bb%1000)*0.001;
*/
/*
double d;
d = 1.0-(0.0005*x1*0.0005*x1+0.0005*z1*0.0005*z1);
if(d < 0) return;
r *= d; g *= d; b *= d;
*/
glColor3f(r, g, b);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x1, y1, z1);
glVertex3f(x1, y1, z2);
glVertex3f(x2, y1, z2);
glVertex3f(x2, y1, z1);
glEnd();
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x2, y2, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x1, y2, z2);
glVertex3f(x1, y2, z1);
glEnd();
glColor3f(r*0.95, g*0.95, b*0.95);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x1, y2, z1);
glVertex3f(x1, y2, z2);
glVertex3f(x1, y1, z2);
glVertex3f(x1, y1, z1);
glEnd();
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x2, y1, z1);
glVertex3f(x2, y1, z2);
glVertex3f(x2, y2, z2);
glVertex3f(x2, y2, z1);
glEnd();
glColor3f(r*0.90, g*0.90, b*0.90);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x2, y1, z1);
glVertex3f(x2, y2, z1);
glVertex3f(x1, y2, z1);
glVertex3f(x1, y1, z1);
glEnd();
glBegin(GL_TRIANGLE_FAN);
glVertex3f(x1, y1, z2);
glVertex3f(x1, y2, z2);
glVertex3f(x2, y2, z2);
glVertex3f(x2, y1, z2);
glEnd();
}
void Cube2(double x1, double y1, double z1, double x2, double y2, double z2, double r, double g, double b)
{
int i, j;
for(j=-4; j<=4; j++)
for(i=-4; i<=4; i++)
Cube2(x1+i*500, y1, z1+j*500, x2+i*500, y2, z2+j*500, r, g, b);
}
//---- ZSYSTEM OBJECT: BUILDING ----------------------------------------------//
void Building(unsigned int seed, double x1, double z1, double x2, double z2, double y)
{
zs_buildings ++;
ZS_RAND *rand = ZS_Rand_Create(seed);
int i, j, ii, jj;
double x, z, w, h, d;
int r = ZS_Rand(rand, 100);
double lit = ZS_Rand_Tween(rand, 0.8, 1.0);
if((x2-x1) < 10 || (z2-z1) < 10) {
// Nothing - too small
} else if(r < 40) {
// Basic building
Cube(x1, y, z1, x2, y+ZS_Rand_Tween(rand, 10, 50), z2, 0.8*lit, 0.8*lit, 0.8*lit);
} else if(r < 60) {
// Building with array of blocks on top
h = ZS_Rand_Tween(rand, 20, 70);
Cube(x1, y, z1, x2, y+h, z2, 0.75, 0.75, 0.75);
ii = 1+ZS_Rand(rand, (int)((x2-x1)/3)-1);
jj = 1+ZS_Rand(rand, (int)((z2-z1)/3)-1);
w = (x2-x1)/ii;
d = (z2-z1)/jj;
for(j=0; j<jj; j++) {
for(i=0; i<ii; i++) {
if(ZS_Rand(rand, 100) < 95) Cube(x1+i*w+1, y+h, z1+j*d+1, x1+(i+1)*w-1, y+h+0.5, z1+(j+1)*d-1, 0.6*lit, 0.6*lit, 0.6*lit);
}
}
} else if(r < 90) {
// Building with smaller block on top
h = ZS_Rand_Tween(rand, 20, 70);
Cube(x1, y, z1, x2, y+h, z2, 0.65*lit, 0.65*lit, 0.65*lit);
w = ZS_Rand_Tween(rand, (x2-x1)/6, (x2-x1)/3);
d = ZS_Rand_Tween(rand, (z2-z1)/6, (z2-z1)/3);
if(d > w*1.5) d = w*1.5;
if(w > d*1.5) w = d*1.5;
Building(ZS_Rand(rand, 0), x1+w, z1+d, x2-w, z2-d, y+h);
} else {
// Building with array of long blocks
h = ZS_Rand_Tween(rand, 10, 40);
Cube(x1, y, z1, x2, y+h, z2, 0.8*lit, 0.8*lit, 0.8*lit);
if(x2-x1 > z2-z1) {
ii = ZS_Rand(rand, (int)((x2-x1)/3));
if(ii > 0) {
w = (x2-x1)/ii;
for(i=0; i<ii; i++) {
Cube(x1+i*w+1, y+h, z1+1, x1+(i+1)*w-1, y+h+1, z2-1, 0.7*lit, 0.7*lit, 0.7*lit);
}
}
} else {
ii = ZS_Rand(rand, (int)((z2-z1)/3));
if(ii > 0) {
d = (z2-z1)/ii;
for(i=0; i<ii; i++) {
Cube(x1+1, y+h, z1+i*d+1, x2-1, y+h+1, z1+(i+1)*d-1, 0.7*lit, 0.7*lit, 0.7*lit);
}
}
}
}
ZS_Rand_Delete(rand);
}
//---- ZSYSTEM OBJECT: BLOCK -------------------------------------------------//
void Block(unsigned int seed, double x1, double z1, double x2, double z2)
{
ZS_RAND *rand = ZS_Rand_Create(seed);
// Put base
Cube(x1+3, 0, z1+3, x2-3, 0.1, z2-3, 0.5, 0.5, 0.5);
// Put buildings
int r = ZS_Rand(rand, 100);
if(r < 10) {
// No buildings
Building(ZS_Rand(rand, 0), x1+8, z1+8, x2-8, z2-8, 0.1);
} else if(r < 40) {
// Symmetrical array of buildings
Building(ZS_Rand(rand, 0), x1+8, z1+8, (x2+x1)/2-4, z2-8, 0.1);
Building(ZS_Rand(rand, 0), (x2+x1)/2+4, z1+8, x2-8, z2-8, 0.1);
} else if(r < 80) {
// Randomly placed buildings
Building(ZS_Rand(rand, 0), x1+8, z1+8, x2-8, z2-8, 0.1);
} else {
// One big building
Building(ZS_Rand(rand, 0), x1+8, z1+8, x2-8, z2-8, 0.1);
}
ZS_Rand_Delete(rand);
}
//---- ZSYSTEM OBJECT: ROAD --------------------------------------------------//
void Road(unsigned int seed, double x1, double z1, double x2, double z2)
{
ZS_RAND *rand = ZS_Rand_Create(seed);
// Put base
// Put dashes
int i, ii;
double x, y, z;
if(x2-x1 > z2-z1) {
z=0.5*(z1+z2);
for(x=x1; x<x2-1; x+=2) {
Cube(x, 0, z-0.05, x+1, 0.01, z+0.05, 1, 1, 1);
}
for(z=z; z<z2; z+=0.4) {
Cube(x1, 0, z, x1+0.10, 0.01, z+0.2, 1, 1, 1);
Cube(x1+0.30, 0, z, x1+0.40, 0.01, z+0.2, 1, 1, 1);
}
} else {
x=0.5*(x1+x2);
for(z=z1; z<z2-1; z+=2) {
Cube(x-0.05, 0, z, x+0.05, 0.01, z+1, 1, 1, 1);
}
for(x=x; x<x2; x+=0.4) {
Cube(x, 0, z2-0.40, x+0.2, 0.01, z2-0.30, 1, 1, 1);
Cube(x, 0, z2-0.10, x+0.2, 0.01, z2-0.00, 1, 1, 1);
}
}
ZS_Rand_Delete(rand);
}
//---- ZSYSTEM OBJECT: SUBURB ------------------------------------------------//
void Suburb(unsigned int seed, double x1, double z1, double x2, double z2, int iter)
{
ZS_RAND *rand = ZS_Rand_Create(seed);
//- Check size
BOOL smallx, smallz, smallrand;
double x, z;
smallx = (x2-x1) < 70;
smallz = (z2-z1) < 70;
smallrand = (ZS_Rand(rand, 100) < 20 && x2-x1 < 100 && z2-z1 < 100) || iter > 10;
if(smallrand) {
Block(ZS_Rand(rand, 0), x1, z1, x2, z2);
} else if(smallx && smallz) {
Block(ZS_Rand(rand, 0), x1, z1, x2, z2);
} else if(smallx) {
z = ZS_Rand_Tween(rand, z1+23, z2-23);
Suburb(ZS_Rand(rand, 0), x1, z1, x2, z, iter+1);
Suburb(ZS_Rand(rand, 0), x1, z, x2, z2, iter+1);
// Road(ZS_Rand(rand, 0), x1+3, z-3, x2-3, z+3);
} else if(smallz) {
x = ZS_Rand_Tween(rand, x1+23, x2-23);
Suburb(ZS_Rand(rand, 0), x1, z1, x, z2, iter+1);
Suburb(ZS_Rand(rand, 0), x, z1, x2, z2, iter+1);
// Road(ZS_Rand(rand, 0), x-3, z1+3, x+3, z2-3);
} else {
x = ZS_Rand_Tween(rand, x1+23, x2-15);
z = ZS_Rand_Tween(rand, z1+23, z2-15);
Suburb(ZS_Rand(rand, 0), x1, z1, x, z, iter+1);
Suburb(ZS_Rand(rand, 0), x, z1, x2, z, iter+1);
Suburb(ZS_Rand(rand, 0), x1, z, x, z2, iter+1);
Suburb(ZS_Rand(rand, 0), x, z, x2, z2, iter+1);
// Road(ZS_Rand(rand, 0), x-3, z1+3, x+3, z-3);
// Road(ZS_Rand(rand, 0), x-3, z+3, x+3, z2-3);
// Road(ZS_Rand(rand, 0), x1+3, z-3, x-3, z+3);
// Road(ZS_Rand(rand, 0), x+3, z-3, x2-3, z+3);
Cube(x-1, 0, z-1, x+1, 0.01, z+1, 0.4, 0.4, 0.4);
}
ZS_Rand_Delete(rand);
}
//---- ZSYSTEM OBJECT: CITY --------------------------------------------------//
void City(unsigned int seed, double x1, double z1, double x2, double z2)
{
ZS_RAND *rand = ZS_Rand_Create(seed);
// Place floor poly
// Cube(x1, -1, z1, x2, 0, z2, 0.1, 0.1, 0.1);
// Divide into blocks
Suburb(ZS_Rand(rand, 0), x1, z1, x2, z2, 0);
ZS_Rand_Delete(rand);
}
//---- MAKETERRAIN -----------------------------------------------------------//
bool maketerrain=false;
void MakeTerrain()
{
if(maketerrain) return;
}
float GetTerrainHeight(float x, float y)
{
return 0;
}
//---- OLD OPENGL STUFF ------------------------------------------------------//
void Initialise()
{
}
void GameDraw(HWND hwnd)
{
static k=0;
int citysize = 500;
// k++;
int i=0, j=0;
/*
zs_cubes = 0;
zs_buildings = 0;
for(j=-2; j<=2; j++) for(i=-2; i<=2; i++)
City(0xA749F86C + (i<<17) + (j<<5) + k, -citysize/2 + i*citysize, -citysize/2 + j*citysize, citysize/2 + i*citysize, citysize/2 + j*citysize);
static int t = 0;
if(GetTickCount()-t > 500) {
t = GetTickCount();
char buf[50];
sprintf(buf, "City: %d buildings, %d cubes", zs_buildings, zs_cubes);
SetWindowText(hwnd, buf);
}
*/
//- Plot axes
i=0; j=0; k=0;
/*
for(k=-10; k<=10; k++)
for(j=-10; j<=10; j++)
for(i=-10; i<=10; i++) {
*/
Cube(i*25-10, j*25-1 , k*25-1 , i*25+10, j*25+1 , k*25+1 , 1, 0, 0);
Cube(i*25-1 , j*25-10, k*25-1 , i*25+1, j*25+10, k*25+1 , 0, 1, 0);
Cube(i*25-1 , j*25-1 , k*25-10, i*25+1, j*25+1 , k*25+10, 0, 0, 1);
/*
}
*/
//- Make terrain if necessary
MakeTerrain();
//- Draw terrain
float x1, z1, x2, z2;
for(i=-20; i<=20; i++) for(j=-20; j<=20; j++) {
float d = 2*sqrt(i*i+j*j);
x1 = i*d; z1 = j*d;
Cube(x1-1, z1-1, -1, x1+1, z1+1, 1, 1, 1, 0);
}
}
double r1=20/0.2, r2=-50/0.2;
double x=-100, y=100, z=-100;
int moving = 0;
void GameMain(HWND hwnd)
{
static int s = 0;
int t = GetTickCount();
int timediff = t-s;
if(timediff > 200) timediff = 200;
s = t;
{
double vx = 0, vy = 0, vz = -timediff*0.1*moving;
double wx, wy, wz;
wx = vx;
wy = vy*cos(0.2*r2*3.14159/180)-vz*sin(0.2*r2*3.14159/180);
wz = -(vy*sin(0.2*r2*3.14159/180)+vz*cos(0.2*r2*3.14159/180));
vx = wx*cos(0.2*r1*3.14159/180)-wz*sin(0.2*r1*3.14159/180);
vy = wy;
vz = -(wx*sin(0.2*r1*3.14159/180)+wz*cos(0.2*r1*3.14159/180));
x += vx; y += vy; z += vz;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(-r2*0.2, 1.0, 0.0, 0.0);
glRotatef(-r1*0.2, 0.0, 1.0, 0.0);
glTranslatef(-x, -y, -z);
GameDraw(hwnd);
SwapBuffers(gl_dc);
}
//---- END OF FILE -----------------------------------------------------------//