Ogre::Vector3 PlayerSpawner::spawnPlayer(uint32_t player_id, bool is_pinto)
{
	Ogre::Vector3 position;
	if(GameState::instance()->team_mode == FFA || GameState::instance()->game_mode == PINTO)
	{
		position = free_positions[RAND_RANGE(0, free_positions.size())];
	}
	else
	{
		float rand_x = RAND_RANGE(0, SPAWN_RAND_RADIUS_MAX) - SPAWN_RAND_RADIUS_MAX;
		float rand_z = RAND_RANGE(0, SPAWN_RAND_RADIUS_MAX) - SPAWN_RAND_RADIUS_MAX;
		if(NetworkManager::instance()->player_team_id_map[player_id] == RED_TEAM)
		{
			position = red_position;
			position.x = position.x + rand_x;
			position.z = position.z + rand_z;
		}
		else
		{
			position = blue_position;
			position.x = position.x + rand_x;
			position.z = position.z + rand_z;
		}
	}
	
	bool self = false;

	if(player_id == NetworkManager::instance()->player_id)
	{
		self = true;
	}

	uint32_t version = RAND_RANGE(0, 5);

	PlayerCharacter *player = new PlayerCharacter(self, scene, "PixelMan.mesh",
            position.x, position.y + 50, position.z,
            0, 0, 0, 1,
            10, 10, 10,
            player_id, version, is_pinto);

	player->team_id = NetworkManager::instance()->player_team_id_map[player_id];
	if(player->team_id == BLUE_TEAM)
	{
		player->switchToBlueTeam();
	}

	GameState::instance()->players[player_id] = player;

	if(self)
	{
		GameState::instance()->player = player;
	}

	NetworkManager::instance()->vital->setPlayerRespawn(position.x, position.y, position.z, 
				player_id, NetworkManager::instance()->player_team_id_map[player_id], version, is_pinto);

	return position;
}
Example #2
0
void ShotGun::shoot_hook()
{
    Ogre::Vector3 cam_dir = ((Camera*)(player->controller->fps_camera))->camera->getDirection();
    Ogre::Vector3 cam_pos = ((Camera*)(player->controller->fps_camera))->camera->getPosition();

    Ogre::Vector3 shoot_vector = shoot_pos->node->convertLocalToWorldPosition(shoot_pos->node->getPosition());

    btVector3 from = btVector3(cam_pos.x, cam_pos.y, cam_pos.z) + (btVector3(cam_dir.x, cam_dir.y, cam_dir.z) * shoot_from_offset);
    btVector3 pre_to = btVector3(cam_pos.x, cam_pos.y, cam_pos.z) + (btVector3(cam_dir.x, cam_dir.y, cam_dir.z) * shoot_distance);

    btVector3 to;

    for (int i = 0; i < SHOOT_NUM; ++i)
    {
        int rand_shoot_offset = 300;
        to = pre_to + btVector3(RAND_RANGE(0, rand_shoot_offset) - rand_shoot_offset, RAND_RANGE(0, rand_shoot_offset) - rand_shoot_offset, 
            RAND_RANGE(0, rand_shoot_offset) - rand_shoot_offset);

        btCollisionWorld::ClosestRayResultCallback rayCallback(from, to);

        rayCallback.m_collisionFilterGroup = COL_BULLET;
        rayCallback.m_collisionFilterMask = COL_BULLET_COLLIDER_WITH;

        Component::_gameObject->scene->physics_world->rayTest(from, to, rayCallback);
        if(rayCallback.hasHit())
        {
            btVector3 point = rayCallback.m_hitPointWorld;
            
            if(rayCallback.m_collisionObject->getUserPointer() != NULL)
            {
                HitBox* hit_box = (HitBox*)(rayCallback.m_collisionObject->getUserPointer());
                if(hit_box->player->player_id != NetworkManager::instance()->player_id
                    && ((GameState::instance()->team_mode != TEAM) || (hit_box->player->team_id != GameState::instance()->player->team_id)
                        || (GameState::instance()->game_mode == PINTO)))
                {
                    int damage_sent = hit_box->getDamage(damage);
                    uint32_t enemy_id = hit_box->player->player_id;

                    NetworkManager::instance()->vital->setDamage(damage_sent, enemy_id);
                    AudioManager::instance()->playBlootSplat(Ogre::Vector3(point.x(), point.y(), point.z()));
                    ParticleManager::instance()->EmitBloodSpurt(Ogre::Vector3(point.x(), point.y(), point.z()), -cam_dir);
                    NetworkManager::instance()->particle->setBlood(point.x(), point.y() , point.z(), -cam_dir.x, -cam_dir.y, -cam_dir.z);
                }
            }
            else
            {
                AudioManager::instance()->playBulletDirtCollision(Ogre::Vector3(point.x(), point.y(), point.z()));
                
                ParticleManager::instance()->EmitDust(Ogre::Vector3(point.x(), point.y(), point.z()), -cam_dir);

                NetworkManager::instance()->particle->setDust(point.x(), point.y() , point.z(), -cam_dir.x, -cam_dir.y, -cam_dir.z);
            }
        }
    }
}
void AudioManager::stopPinto()
{
	in_pinto = false;
	Mix_HaltMusic();
	current_music =  normal_music[RAND_RANGE(0, MUSIC_NUM)];
	Mix_PlayMusic(current_music, 0);
}
Example #4
0
static unsigned long handle_arg_iovec(struct syscallentry *entry, struct syscallrecord *rec, unsigned int argnum)
{
	unsigned long num_entries;

	num_entries = RAND_RANGE(1, 256);

	switch (argnum) {
	case 1:	if (entry->arg2type == ARG_IOVECLEN)
			rec->a2 = num_entries;
		break;
	case 2:	if (entry->arg3type == ARG_IOVECLEN)
			rec->a3 = num_entries;
		break;
	case 3:	if (entry->arg4type == ARG_IOVECLEN)
			rec->a4 = num_entries;
		break;
	case 4:	if (entry->arg5type == ARG_IOVECLEN)
			rec->a5 = num_entries;
		break;
	case 5:	if (entry->arg6type == ARG_IOVECLEN)
			rec->a6 = num_entries;
		break;
	}
	return (unsigned long) alloc_iovec(num_entries);
}
Example #5
0
const struct yut_kstr *yut_randz(int bin, int min, int max) {
	int i = RAND_RANGE(uint, min, max);
	struct yut_tracked *x = calloc(
		sizeof(*x) + i, 1);
	x->core.len = i;
	if (bin) {
		while (i--)
			x->core.land[i] = (char)RAND_RANGE(uint, 0, 255);
	} else {
		while (i--)
			x->core.land[i] = (char)RAND_RANGE(uint, 32, 126);
	}
	x->next = top->head;
	top->head = x;
	return &x->core;
}
Example #6
0
void FractalTree::generate(
    GLfloat length, 
    GLfloat thickness, 
    GLfloat y,
    GLfloat tx,
    GLfloat ty,
    GLfloat tz) {

    trunkLength = length;
    trunkThickness = thickness;
    thetaX = tx;
    thetaY = ty;
    thetaZ = tz;
    posY   = y;
    GLfloat range  = angleVariation;

    // If the trunkLength is still longer than the minTrunkLength, 
    // then keep drawing the tree recursively.
    if (trunkLength > minTrunkLength) {

        // Generate the subtrees.
        subtrees = new FractalTree*[subtreesNum];

        for (GLint i = 0; i < subtreesNum; ++i) {
            subtrees[i] = new FractalTree(
                angleVariation,
                lengthFactor, 
                thicknessFactor,
                minTrunkLength, 
                subtreesNum    
            );
            subtrees[i]->generate(
                trunkLength * lengthFactor,
                trunkThickness * thicknessFactor,
                trunkLength,
                RAND_RANGE(-range, range),
                RAND_RANGE(-range, range),
                RAND_RANGE(-range, range)
            );
        }
    }
    else {
        subtrees = NULL;
    }

}
Example #7
0
static void fill_swapped(int64_t *dst, const int size, const int swapped_cnt) {
  int i, tmp;
  size_t ind1 = 0;
  size_t ind2 = 0;
  fill_sorted(dst, size);

  for (i = 0; i < swapped_cnt; i++) {
    ind1 = lrand48();
    RAND_RANGE(ind1, 0, size);
    ind2 = lrand48();
    RAND_RANGE(ind2, 0, size);
  }

  tmp = dst[ind1];
  dst[ind1] = dst[ind2];
  dst[ind2] = tmp;
}
Example #8
0
static char * gen(int len, char * token)
{
    char * pt = token;

    while (len--) {
        int choose = RAND_RANGE(rand(), 0, 2, PHP_RAND_MAX);
        if (choose == 0) {
            *pt = RAND_RANGE(rand(), 'A', 'Z', PHP_RAND_MAX);
        } else if(choose == 1) {
            *pt = RAND_RANGE(rand(), 'a', 'z', PHP_RAND_MAX);
        } else {
            *pt = RAND_RANGE(rand(), '0', '9', PHP_RAND_MAX);
        }
        pt++;
    }
    *pt = 0;
    return token;
}
Example #9
0
static int open_socket(unsigned int domain, unsigned int type, unsigned int protocol)
{
	struct object *obj;
	struct sockaddr *sa = NULL;
	const struct netproto *proto;
	socklen_t salen;
	struct sockopt so = { 0, 0, 0, 0 };
	int fd;

	fd = socket(domain, type, protocol);
	if (fd == -1)
		return fd;

	obj = add_socket(fd, domain, type, protocol);

	proto = net_protocols[domain].proto;
	if (proto != NULL)
		if (proto->socket_setup != NULL)
			proto->socket_setup(fd);

	// FIXME:
	// All of this needs to be broken out into child ops instead of
	// special casing it all at creation time.

	/* Set some random socket options. */
	sso_socket(&obj->sockinfo.triplet, &so, fd);

	nr_sockets++;

	/* Sometimes, listen on created sockets. */
	if (RAND_BOOL()) {
		int ret, one = 1;

		/* fake a sockaddr. */
		generate_sockaddr((struct sockaddr **) &sa, (socklen_t *) &salen, domain);

		ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
		if (ret != -1)
			goto skip_bind;

		ret = bind(fd, sa, salen);
		if (ret != -1)
			(void) listen(fd, RAND_RANGE(1, 128));

//		ret = accept4(fd, sa, &salen, SOCK_NONBLOCK);
//		if (ret != -1) {
//			obj = add_socket(ret, domain, type, protocol);
//			nr_sockets++;
//		}
	}

skip_bind:
	if (sa != NULL)
		free(sa);

	return fd;
}
Example #10
0
/** 
 * Shuffle tuples of the relation using Knuth shuffle.
 * 
 * @param relation 
 */
void 
knuth_shuffle(relation_t * relation)
{
    int i;
    for (i = relation->num_tuples - 1; i > 0; i--) {
        int64_t  j              = RAND_RANGE(i);
        intkey_t tmp            = relation->tuples[i].key;
        relation->tuples[i].key = relation->tuples[j].key;
        relation->tuples[j].key = tmp;
    }
}
Example #11
0
int64 f_rand(int64 min /* = 0 */, int64 max /* = RAND_MAX */) {
  if (!s_rand_is_seeded) {
    s_rand_is_seeded = true;
    srand(GENERATE_SEED());
  }

  int64 number = rand();
  if (min != 0 || max != RAND_MAX) {
    RAND_RANGE(number, min, max, RAND_MAX);
  }
  return number;
}
Example #12
0
int64_t f_rand(int64_t min /* = 0 */, int64_t max /* = RAND_MAX */) {
  if (!s_rand_is_seeded) {
    s_rand_is_seeded = true;
    srand(math_generate_seed());
  }

  int64_t number = rand();
  if (min != 0 || max != RAND_MAX) {
    RAND_RANGE(number, min, max, RAND_MAX);
  }
  return number;
}
Example #13
0
/*
 * Generate, and munge a 32bit number.
 */
unsigned int rand32(void)
{
	unsigned long r = 0;

	switch (rnd() % 7) {
	case 0:	r = RAND_BYTE();
		break;

	case 1:	r = rand16();
		break;

	case 2: r = rand_single_bit(32);
		break;
	case 3:	r = randbits(32);
		break;
	case 4: r = rnd();
		break;
	case 5:	r = rept_byte();
		break;

	case 6:	return get_interesting_value();
	}

	/* Sometimes deduct it from INT_MAX */
	if (ONE_IN(25))
		r = INT_MAX - r;

	/* Sometimes flip sign */
	if (ONE_IN(25))
		r = ~r + 1;

	/* we might get lucky if something is counting ints/longs etc. */
	if (ONE_IN(4)) {
		int _div = 1 << RAND_RANGE(1, 4);	/* 2,4,8 or 16 */
		r /= _div;
	}

	/* limit the size */
	switch (rnd() % 5) {
	case 0: r &= 0xff;
		break;
	case 1: r &= 0xffff;
		break;
	case 2: r &= PAGE_MASK;
		break;
	case 3: r &= 0xffffff;
		break;
	case 4:	// do nothing
		break;
	}

	return r;
}
Example #14
0
/**
 * Generate tuple IDs -> random distribution
 * relation must have been allocated
 */
void
random_gen(relation_t *rel, const int64_t maxid) 
{
    uint64_t i;

    for (i = 0; i < rel->num_tuples; i++) {
        rel->tuples[i].key = RAND_RANGE(maxid);
        rel->tuples[i].payload = rel->num_tuples - i;

        /* avoid NaN in values */
        avoid_NaN((int64_t*)&(rel->tuples[i]));
    }
}
void musicDone()
{
	if(AudioManager::instance()->in_pinto)
	{
		Mix_HaltMusic();
		AudioManager::instance()->current_music = AudioManager::instance()->pinto_music;
		Mix_PlayMusic(AudioManager::instance()->current_music, 0);
	}
	else
	{
		Mix_HaltMusic();
		AudioManager::instance()->current_music =  AudioManager::instance()->normal_music[RAND_RANGE(0, MUSIC_NUM)];
		Mix_PlayMusic(AudioManager::instance()->current_music, 0);
	}
}
Example #16
0
/*
 * OR a random number of bits into a mask.
 * Used by ARG_LIST generation, and get_o_flags()
 */
unsigned long set_rand_bitmask(unsigned int num, const unsigned long *values)
{
	unsigned long i;
	unsigned long mask = 0;
	unsigned int bits;

	bits = RAND_RANGE(0, num);      /* num of bits to OR */
	if (bits == 0)
		return mask;

	for (i = 0; i < bits; i++)
		mask |= values[rnd() % num];

	return mask;
}
Example #17
0
int main(void)
{
	int i = 0;
	int64_t sizes[TESTS];

	srand48(SEED);

	fill_random(sizes, TESTS);
	for (i = 0; i < TESTS; i++) {
		RAND_RANGE(sizes[i], 0, MAXSIZE);
	}

	for (i = 0; i < FILL_LAST_ELEMENT; i++) {
		run_tests(sizes, TESTS, i);
	}
	return 0;
}
Example #18
0
static int open_socket(unsigned int domain, unsigned int type, unsigned int protocol)
{
	int fd;
	struct sockaddr *sa = NULL;
	socklen_t salen;
	struct sockopt so = { 0, 0, 0, 0 };

	fd = socket(domain, type, protocol);
	if (fd == -1)
		return fd;

	shm->sockets[nr_sockets].fd = fd;
	shm->sockets[nr_sockets].triplet.family = domain;
	shm->sockets[nr_sockets].triplet.type = type;
	shm->sockets[nr_sockets].triplet.protocol = protocol;

	output(2, "fd[%i] = domain:%i (%s) type:0x%x protocol:%i\n",
		fd, domain, get_domain_name(domain), type, protocol);

	/* Set some random socket options. */
	sso_socket(&shm->sockets[nr_sockets].triplet, &so, fd);

	nr_sockets++;

	/* Sometimes, listen on created sockets. */
	if (RAND_BOOL()) {
		int ret;

		/* fake a sockaddr. */
		generate_sockaddr((struct sockaddr **) &sa, (socklen_t *) &salen, domain);

		ret = bind(fd, sa, salen);
		if (ret != -1) {
			(void) listen(fd, RAND_RANGE(1, 128));
		}
	}

	if (sa != NULL)
		free(sa);

	return fd;
}
Example #19
0
/*
 * SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
 */
static void sanitise_sendmsg(struct syscallrecord *rec)
{
	struct socketinfo *si = (struct socketinfo *) rec->a1;
	struct msghdr *msg;
	struct sockaddr *sa = NULL;
	socklen_t salen = 0;

	if (si == NULL)	// handle --disable-fds=sockets
		goto skip_si;

	rec->a1 = fd_from_socketinfo((struct socketinfo *) rec->a1);

	generate_sockaddr((struct sockaddr **) &sa, (socklen_t *) &salen, si->triplet.family);

skip_si:
	msg = zmalloc(sizeof(struct msghdr));
	msg->msg_name = sa;
	msg->msg_namelen = salen;

	if (RAND_BOOL()) {
		unsigned int num_entries;

		num_entries = RAND_RANGE(1, 3);
		msg->msg_iov = alloc_iovec(num_entries);
		msg->msg_iovlen = num_entries;
	}

	if (RAND_BOOL()) {
		msg->msg_controllen = rand32() % 20480;	// /proc/sys/net/core/optmem_max
		msg->msg_control = get_address();
	} else {
		msg->msg_controllen = 0;
	}

	if (ONE_IN(100))
		msg->msg_flags = rand32();
	else
		msg->msg_flags = 0;

	rec->a2 = (unsigned long) msg;
}
Example #20
0
/*
 * Generate, and munge a 16bit number.
 */
unsigned short rand16(void)
{
	unsigned short r = 0, r2;

	switch (rnd() % 5) {
	case 0:	r = RAND_BYTE();
		break;

	case 1: r = rand_single_bit(16);
		break;
	case 2:	r = randbits(16);
		break;
	case 3: r = rnd();
		break;
	case 4:	r2 = rnd() & 0xff;
		r = r2 | r2 << 8;
		break;
	}

	/* Sometimes flip sign */
	if (ONE_IN(25))
		r = ~r + 1;

	if (ONE_IN(4)) {
		int _div = 1 << RAND_RANGE(1, 4);	/* 2,4,8 or 16 */
		r /= _div;
	}

	/* limit the size */
	switch (rnd() % 4) {
	case 0: r &= 0xff;
		break;
	case 1: r &= 0xfff;
		break;
	case 2: r &= PAGE_MASK;
		break;
	case 3:	// do nothing
		break;
	}
	return r;
}
		void Attractor::update(Particle* particle, float k, gvec3& movement)
		{
			this->_direction = this->position + this->space->getPosition() - particle->position;
			this->_squaredLength = this->_direction.squaredLength();
			if (is_inside(this->_squaredLength, 0.02f, this->radius * this->radius))
			{
				this->_factor = (this->radius - hsqrt(this->_squaredLength)) / this->radius;
				if (this->exponent != 1.0f)
				{
					if (this->exponent == (int)this->exponent)
					{
						this->_factor = pow(this->_factor, (int)this->exponent);
					}
					else
					{
						this->_factor = pow(this->_factor, this->exponent);
					}
				}
				movement += this->_direction.normalized() * (RAND_RANGE(Randomness) * this->force * this->_factor * k);
			}
		}
Example #22
0
void Game::Init()
{
	Modules::Init();

	Modules::GetLog().Init();

	Modules::GetGraphics().Init(main_window_handle,
		WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, WINDOWED_APP, false);

	Modules::GetInput().Init(main_instance);
	Modules::GetInput().InitKeyboard(main_window_handle);

	Modules::GetSound().Init(main_window_handle);
//	Modules::GetMusic().Init(main_window_handle);

	// hide the mouse
	if (!WINDOWED_APP)
		ShowCursor(FALSE);

	// seed random number generator
	srand(Modules::GetTimer().Start_Clock());

// 	// initialize math engine
// 	Build_Sin_Cos_Tables();

	// initialize the camera with 90 FOV, normalized coordinates
	_cam = new Camera(CAM_MODEL_EULER,		// the euler model
					  vec4(0,0,0,1),	// initial camera position
					  vec4(0,0,0,1),		// initial camera angles
					  vec4(0,0,0,1),		// no target
					  10.0,					// near and far clipping planes
					  12000.0,
					  120.0,					// field of view in degrees
					  WINDOW_WIDTH,			// size of final screen viewport
					  WINDOW_HEIGHT);


	// filenames of objects to load
	char *object_filenames[NUM_OBJECTS] = {
		"../../assets/chap12/fighter_01.cob",
	};

	// load in default object
	vec4 vscale(5.00,5.00,5.00,1),
		 vpos(0,0,150,1), 
		 vrot(0,0,0,1);

	// load all the objects in
	for (int index_obj=0; index_obj < NUM_OBJECTS; index_obj++)
	{
		obj_array[index_obj]->LoadCOB(object_filenames[index_obj],
									  &vscale, &vpos, &vrot, 
									  VERTEX_FLAGS_SWAP_YZ  | 
									  VERTEX_FLAGS_INVERT_WINDING_ORDER |
									  VERTEX_FLAGS_TRANSFORM_LOCAL 
									  /* VERTEX_FLAGS_TRANSFORM_LOCAL_WORLD*/ );

	} // end for index_obj

	// set current object
	curr_object = 0;
	obj_work = obj_array[curr_object];

	vscale.Assign(20.00,20.00,20.00);

	// load in the scenery object that we will place all over the place
	obj_scene->LoadCOB("../../assets/chap12/borg_flat_01.cob",  
					   &vscale, &vpos, &vrot, 
					   VERTEX_FLAGS_SWAP_YZ  |
					   VERTEX_FLAGS_TRANSFORM_LOCAL 
					   /* VERTEX_FLAGS_TRANSFORM_LOCAL_WORLD*/ );

	// position the scenery objects randomly
	for (int index = 0; index < NUM_SCENE_OBJECTS; index++)
	{
		// randomly position object
		scene_objects[index].x = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
		scene_objects[index].y = RAND_RANGE(-(UNIVERSE_RADIUS/2), (UNIVERSE_RADIUS/2));
		scene_objects[index].z = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
	} // end for

	// select random velocities
	for (int index = 0; index < NUM_SCENE_OBJECTS; index++)
	{
		// randomly position object
		scene_objects_vel[index].x = RAND_RANGE(-MAX_VEL, MAX_VEL);
		scene_objects_vel[index].y = RAND_RANGE(-MAX_VEL, MAX_VEL);
		scene_objects_vel[index].z = RAND_RANGE(-MAX_VEL, MAX_VEL);
	} // end for

	// set up lights
	LightsMgr& lights = Modules::GetGraphics().GetLights();
	lights.Reset();

	// create some working colors
	Color white(255,255,255,0),
		  gray(100,100,100,0),
		  black(0,0,0,0),
		  red(255,0,0,0),
		  green(0,255,0,0),
		  blue(0,0,255,0);

	// ambient light
	lights.Init(AMBIENT_LIGHT_INDEX,   
				LIGHT_STATE_ON,      // turn the light on
				LIGHT_ATTR_AMBIENT,  // ambient light type
				gray, black, black,    // color for ambient term only
				NULL, NULL,            // no need for pos or dir
				0,0,0,                 // no need for attenuation
				0,0,0);                // spotlight info NA

	vec4 dlight_dir(-1,0,-1,1);

	// directional light
	lights.Init(INFINITE_LIGHT_INDEX,  
				LIGHT_STATE_ON,      // turn the light on
				LIGHT_ATTR_INFINITE, // infinite light type
				black, gray, black,    // color for diffuse term only
				NULL, &dlight_dir,     // need direction only
				0,0,0,                 // no need for attenuation
				0,0,0);                // spotlight info NA

	vec4 plight_pos(0,200,0,1);

	// point light
	lights.Init(POINT_LIGHT_INDEX,
				LIGHT_STATE_ON,      // turn the light on
				LIGHT_ATTR_POINT,    // pointlight type
				black, green, black,   // color for diffuse term only
				&plight_pos, NULL,     // need pos only
				0,.002,0,              // linear attenuation only
				0,0,1);                // spotlight info NA

	vec4 slight2_pos(0,1000,0,1);
	vec4 slight2_dir(-1,0,-1,1);

	// spot light2
	lights.Init(SPOT_LIGHT2_INDEX,
				LIGHT_STATE_ON,         // turn the light on
				LIGHT_ATTR_SPOTLIGHT2,  // spot light type 2
				black, red, black,      // color for diffuse term only
				&slight2_pos, &slight2_dir, // need pos only
				0,.001,0,                 // linear attenuation only
				0,0,1);    


// 	// create lookup for lighting engine
// 	RGB_16_8_IndexedRGB_Table_Builder(DD_PIXEL_FORMAT565,  // format we want to build table for
// 		palette,             // source palette
// 		rgblookup);          // lookup table

	// create the z buffer
	zbuffer->Create(WINDOW_WIDTH, WINDOW_HEIGHT, ZBUFFER_ATTR_32BIT);

	// load in the background
	background->Create(0,0,800,600,1, BOB_ATTR_VISIBLE | BOB_ATTR_SINGLE_FRAME, DDSCAPS_SYSTEMMEMORY, 0, 32);
	BmpFile* bitmap = new BmpFile("../../assets/chap12/nebred01.bmp");
	background->LoadFrame(bitmap, 0,0,0,BITMAP_EXTRACT_MODE_ABS);
	delete bitmap;
}
void AudioManager::startMusic()
{
	current_music = normal_music[RAND_RANGE(0, MUSIC_NUM)];
	Mix_PlayMusic(current_music, 0);
}
void AudioManager::playWalkStep(Ogre::Vector3 v) {
	play3DSound(_footstep[RAND_RANGE(0, 7)], 0, v);
}
Example #25
0
int64_t HHVM_FUNCTION(rand,
                      int64_t min /* = 0 */,
                      const Variant& max /* = null_variant */) {
#if defined(__APPLE__) || defined(_MSC_VER)
  if (!s_rand_is_seeded) {
#else
  if (s_state.state != RandomBuf::RequestInit) {
#endif
    randinit(math_generate_seed());
  }

  int64_t number;
#ifdef __APPLE__
  number = random();
#elif defined(_MSC_VER)
  number = rand();
#else
  int32_t numberIn;
  random_r(&s_state.data, &numberIn);
  number = numberIn;
#endif
  int64_t int_max = max.isNull() ? RAND_MAX : max.toInt64();
  if (min != 0 || int_max != RAND_MAX) {
    RAND_RANGE(number, min, int_max, RAND_MAX);
  }
  return number;
}

int64_t HHVM_FUNCTION(mt_getrandmax) { return MT_RAND_MAX;}

void HHVM_FUNCTION(mt_srand,
                   const Variant& seed /* = null_variant */) {
  if (seed.isNull()) {
    return math_mt_srand(math_generate_seed());
  }
  if (seed.isNumeric(true)) {
    math_mt_srand(seed.toInt32());
  } else {
    raise_warning("mt_srand() expects parameter 1 to be long");
  }
}

int64_t HHVM_FUNCTION(mt_rand,
                      int64_t min /* = 0 */,
                      const Variant& max /* = null_variant */) {
  return math_mt_rand(min, max.isNull() ? RAND_MAX : max.toInt64());
}

double HHVM_FUNCTION(lcg_value) { return math_combined_lcg();}

Variant HHVM_FUNCTION(intdiv, int64_t numerator, int64_t divisor) {
  if (divisor == 0) {
    SystemLib::throwDivisionByZeroErrorObject(Strings::DIVISION_BY_ZERO);
  } else if (divisor == -1 &&
             numerator == std::numeric_limits<int64_t>::min()) {
    SystemLib::throwArithmeticErrorObject(
      "Division of PHP_INT_MIN by -1 is not an integer");
  }
  return numerator/divisor;
}

///////////////////////////////////////////////////////////////////////////////

const StaticString s_PHP_ROUND_HALF_UP("PHP_ROUND_HALF_UP");
const StaticString s_PHP_ROUND_HALF_DOWN("PHP_ROUND_HALF_DOWN");
const StaticString s_PHP_ROUND_HALF_EVEN("PHP_ROUND_HALF_EVEN");
const StaticString s_PHP_ROUND_HALF_ODD("PHP_ROUND_HALF_ODD");

#define ICONST(nm)                                                             \
  Native::registerConstant<KindOfInt64>(makeStaticString(#nm), k_##nm)         \

#define DCONST(nm)                                                             \
  Native::registerConstant<KindOfDouble>(makeStaticString("M_"#nm), k_M_##nm)  \

void StandardExtension::requestInitMath() {
#if !defined(__APPLE__) && !defined(_MSC_VER)
  if (s_state.state == RandomBuf::RequestInit) {
    s_state.state = RandomBuf::ThreadInit;
  }
#endif
}

void StandardExtension::initMath() {
  ICONST(PHP_ROUND_HALF_UP);
  ICONST(PHP_ROUND_HALF_DOWN);
  ICONST(PHP_ROUND_HALF_EVEN);
  ICONST(PHP_ROUND_HALF_ODD);

  DCONST(PI);
  DCONST(1_PI);
  DCONST(2_PI);
  DCONST(2_SQRTPI);
  DCONST(E);
  DCONST(EULER);
  DCONST(LN10);
  DCONST(LN2);
  DCONST(LNPI);
  DCONST(LOG10E);
  DCONST(LOG2E);
  DCONST(PI_2);
  DCONST(PI_4);
  DCONST(SQRT1_2);
  DCONST(SQRT2);
  DCONST(SQRT3);
  DCONST(SQRTPI);

  HHVM_FE(min);
  HHVM_FE(max);
  HHVM_FE(abs);
  HHVM_FE(is_finite);
  HHVM_FE(is_infinite);
  HHVM_FE(is_nan);
  HHVM_FE(ceil);
  HHVM_FE(floor);
  HHVM_FE(round);
  HHVM_FE(deg2rad);
  HHVM_FE(rad2deg);
  HHVM_FE(decbin);
  HHVM_FE(dechex);
  HHVM_FE(decoct);
  HHVM_FE(bindec);
  HHVM_FE(hexdec);
  HHVM_FE(octdec);
  HHVM_FE(base_convert);
  HHVM_FE(pow);
  HHVM_FE(exp);
  HHVM_FE(expm1);
  HHVM_FE(log10);
  HHVM_FE(log1p);
  HHVM_FE(log);
  HHVM_FE(cos);
  HHVM_FE(cosh);
  HHVM_FE(sin);
  HHVM_FE(sinh);
  HHVM_FE(tan);
  HHVM_FE(tanh);
  HHVM_FE(acos);
  HHVM_FE(acosh);
  HHVM_FE(asin);
  HHVM_FE(asinh);
  HHVM_FE(atan);
  HHVM_FE(atanh);
  HHVM_FE(atan2);
  HHVM_FE(hypot);
  HHVM_FE(fmod);
  HHVM_FE(sqrt);
  HHVM_FE(getrandmax);
  HHVM_FE(srand);
  HHVM_FE(rand);
  HHVM_FE(mt_getrandmax);
  HHVM_FE(mt_srand);
  HHVM_FE(mt_rand);
  HHVM_FE(lcg_value);
  HHVM_FE(intdiv);

  loadSystemlib("std_math");
}
int Game_Init(void *parms)
{
// this function is where you do all the initialization 
// for your game

int index; // looping var

// start up DirectDraw (replace the parms as you desire)
DDraw_Init(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, WINDOWED_APP);

// initialize directinput
DInput_Init();

// acquire the keyboard 
DInput_Init_Keyboard();

// add calls to acquire other directinput devices here...

// initialize directsound and directmusic
DSound_Init();
DMusic_Init();

// hide the mouse
if (!WINDOWED_APP)
    ShowCursor(FALSE);

// seed random number generator
srand(Start_Clock());

Open_Error_File("ERROR.TXT");

// initialize math engine
Build_Sin_Cos_Tables();

// initialize the camera with 90 FOV, normalized coordinates
Init_CAM4DV1(&cam,      // the camera object
             CAM_MODEL_EULER, // the euler model
             &cam_pos,  // initial camera position
             &cam_dir,  // initial camera angles
             &cam_target,      // no target
             200.0,      // near and far clipping planes
             12000.0,
             120.0,      // field of view in degrees
             WINDOW_WIDTH,   // size of final screen viewport
             WINDOW_HEIGHT);

// load the master tank object
VECTOR4D_INITXYZ(&vscale,0.75,0.75,0.75);
Load_OBJECT4DV1_PLG(&obj_tank, "tank2.plg",&vscale, &vpos, &vrot);

// load player object for 3rd person view
VECTOR4D_INITXYZ(&vscale,0.75,0.75,0.75);
Load_OBJECT4DV1_PLG(&obj_player, "tank3.plg",&vscale, &vpos, &vrot);

// load the master tower object
VECTOR4D_INITXYZ(&vscale,1.0, 2.0, 1.0);
Load_OBJECT4DV1_PLG(&obj_tower, "tower1.plg",&vscale, &vpos, &vrot);

// load the master ground marker
VECTOR4D_INITXYZ(&vscale,3.0,3.0,3.0);
Load_OBJECT4DV1_PLG(&obj_marker, "marker1.plg",&vscale, &vpos, &vrot);

// position the tanks
for (index = 0; index < NUM_TANKS; index++)
    {
    // randomly position the tanks
    tanks[index].x = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
    tanks[index].y = 0; // obj_tank.max_radius;
    tanks[index].z = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
    tanks[index].w = RAND_RANGE(0,360);
    } // end for


// position the towers
for (index = 0; index < NUM_TOWERS; index++)
    {
    // randomly position the tower
    towers[index].x = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
    towers[index].y = 0; // obj_tower.max_radius;
    towers[index].z = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
    } // end for

// return success
return(1);

} // end Game_Init
int Game_Main(void *parms)
{
// this is the workhorse of your game it will be called
// continuously in real-time this is like main() in C
// all the calls for you game go here!

static MATRIX4X4 mrot;   // general rotation matrix

// these are used to create a circling camera
static float view_angle = 0; 
static float camera_distance = 6000;
static VECTOR4D pos = {0,0,0,0};
static float tank_speed;
static float turning = 0;
// state variables for different rendering modes and help
static int wireframe_mode = 1;
static int backface_mode  = 1;
static int lighting_mode  = 1;
static int help_mode      = 1;
static int zsort_mode     = 1;

char work_string[256]; // temp string

int index; // looping var

// start the timing clock
Start_Clock();

// clear the drawing surface 
//DDraw_Fill_Surface(lpddsback, 0);

#if 1

// draw the sky
//Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, 166, lpddsback);
//Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, rgblookup[RGB16Bit565(115,42,16)], lpddsback);
//Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, rgblookup[RGB16Bit565(0,140,192)], lpddsback);
//Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, RGB16Bit(0,140,192), lpddsback);
Draw_Rectangle(0,0, WINDOW_WIDTH, WINDOW_HEIGHT/2, RGB16Bit(0,35,50), lpddsback);


// draw the ground
//Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, 28, lpddsback);
//Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, rgblookup[RGB16Bit565(115,42,16)], lpddsback);
//Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, RGB16Bit(103,62,3), lpddsback);
Draw_Rectangle(0,WINDOW_HEIGHT/2-1, WINDOW_WIDTH, WINDOW_HEIGHT, RGB16Bit(20,12,0), lpddsback);

// read keyboard and other devices here
DInput_Read_Keyboard();

// game logic here...

// reset the render list
Reset_RENDERLIST4DV2(&rend_list);

// allow user to move camera

// turbo
if (keyboard_state[DIK_SPACE])
    tank_speed = 5*TANK_SPEED;
else
    tank_speed = TANK_SPEED;

// forward/backward
if (keyboard_state[DIK_UP])
   {
   // move forward
   cam.pos.x += tank_speed*Fast_Sin(cam.dir.y);
   cam.pos.z += tank_speed*Fast_Cos(cam.dir.y);
   } // end if

if (keyboard_state[DIK_DOWN])
   {
   // move backward
   cam.pos.x -= tank_speed*Fast_Sin(cam.dir.y);
   cam.pos.z -= tank_speed*Fast_Cos(cam.dir.y);
   } // end if

// rotate
if (keyboard_state[DIK_RIGHT])
   {
   cam.dir.y+=3;
   
   // add a little turn to object
   if ((turning+=2) > 25)
      turning=25;
   } // end if

if (keyboard_state[DIK_LEFT])
   {
   cam.dir.y-=3;

   // add a little turn to object
   if ((turning-=2) < -25)
      turning=-25;

   } // end if
else // center heading again
   {
   if (turning > 0)
       turning-=1;
   else
   if (turning < 0)
       turning+=1;

   } // end else

// modes and lights

// wireframe mode
if (keyboard_state[DIK_W])
   {
   // toggle wireframe mode
   if (++wireframe_mode > 1)
       wireframe_mode=0;
   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if

// backface removal
if (keyboard_state[DIK_B])
   {
   // toggle backface removal
   backface_mode = -backface_mode;
   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if

// lighting
if (keyboard_state[DIK_L])
   {
   // toggle lighting engine completely
   lighting_mode = -lighting_mode;
   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if

// toggle ambient light
if (keyboard_state[DIK_A])
   {
   // toggle ambient light
   if (lights[AMBIENT_LIGHT_INDEX].state == LIGHTV1_STATE_ON)
      lights[AMBIENT_LIGHT_INDEX].state = LIGHTV1_STATE_OFF;
   else
      lights[AMBIENT_LIGHT_INDEX].state = LIGHTV1_STATE_ON;

   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if

// toggle infinite light
if (keyboard_state[DIK_I])
   {
   // toggle ambient light
   if (lights[INFINITE_LIGHT_INDEX].state == LIGHTV1_STATE_ON)
      lights[INFINITE_LIGHT_INDEX].state = LIGHTV1_STATE_OFF;
   else
      lights[INFINITE_LIGHT_INDEX].state = LIGHTV1_STATE_ON;

   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if

// toggle point light
if (keyboard_state[DIK_P])
   {
   // toggle point light
   if (lights[POINT_LIGHT_INDEX].state == LIGHTV1_STATE_ON)
      lights[POINT_LIGHT_INDEX].state = LIGHTV1_STATE_OFF;
   else
      lights[POINT_LIGHT_INDEX].state = LIGHTV1_STATE_ON;

   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if


// toggle spot light
if (keyboard_state[DIK_S])
   {
   // toggle spot light
   if (lights[SPOT_LIGHT2_INDEX].state == LIGHTV1_STATE_ON)
      lights[SPOT_LIGHT2_INDEX].state = LIGHTV1_STATE_OFF;
   else
      lights[SPOT_LIGHT2_INDEX].state = LIGHTV1_STATE_ON;

   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if


// help menu
if (keyboard_state[DIK_H])
   {
   // toggle help menu 
   help_mode = -help_mode;
   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if

// z-sorting
if (keyboard_state[DIK_Z])
   {
   // toggle z sorting
   zsort_mode = -zsort_mode;
   Wait_Clock(100); // wait, so keyboard doesn't bounce
   } // end if

static float plight_ang = 0, slight_ang = 0; // angles for light motion

// move point light source in ellipse around game world
lights[POINT_LIGHT_INDEX].pos.x = 4000*Fast_Cos(plight_ang);
lights[POINT_LIGHT_INDEX].pos.y = 200;
lights[POINT_LIGHT_INDEX].pos.z = 4000*Fast_Sin(plight_ang);

if ((plight_ang+=3) > 360)
    plight_ang = 0;

// move spot light source in ellipse around game world
lights[SPOT_LIGHT2_INDEX].pos.x = 2000*Fast_Cos(slight_ang);
lights[SPOT_LIGHT2_INDEX].pos.y = 200;
lights[SPOT_LIGHT2_INDEX].pos.z = 2000*Fast_Sin(slight_ang);

if ((slight_ang-=5) < 0)
    slight_ang = 360;

// generate camera matrix
Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX);

// insert the player into the world
// reset the object (this only matters for backface and object removal)
Reset_OBJECT4DV2(&obj_player);

// set position of tank

obj_player.world_pos.x = cam.pos.x+300*Fast_Sin(cam.dir.y);
obj_player.world_pos.y = cam.pos.y-70;
obj_player.world_pos.z = cam.pos.z+300*Fast_Cos(cam.dir.y);


// generate rotation matrix around y axis
static int turn=0; 
Build_XYZ_Rotation_MATRIX4X4(1, cam.dir.y+turning, 2, &mrot);

// rotate the local coords of the object
Transform_OBJECT4DV2(&obj_player, &mrot, TRANSFORM_LOCAL_TO_TRANS,1);

// perform world transform
Model_To_World_OBJECT4DV2(&obj_player, TRANSFORM_TRANS_ONLY);

//Light_OBJECT4DV2_World16(&obj_player, &cam, lights, 4);

// insert the object into render list
Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_player,0);

#if 1

//////////////////////////////////////////////////////////

// insert the tanks in the world
for (index = 0; index < NUM_TANKS; index++)
    {
    // reset the object (this only matters for backface and object removal)
    Reset_OBJECT4DV2(&obj_tank);

    // generate rotation matrix around y axis
    Build_XYZ_Rotation_MATRIX4X4(0, tanks[index].w, 0, &mrot);

    // rotate the local coords of the object
    Transform_OBJECT4DV2(&obj_tank, &mrot, TRANSFORM_LOCAL_TO_TRANS,1);

    // set position of tank
    obj_tank.world_pos.x = tanks[index].x;
    obj_tank.world_pos.y = tanks[index].y; 
    obj_tank.world_pos.z = tanks[index].z; 

    // attempt to cull object   
    if (!Cull_OBJECT4DV2(&obj_tank, &cam, CULL_OBJECT_XYZ_PLANES))
       {
       // if we get here then the object is visible at this world position
       // so we can insert it into the rendering list
       // perform local/model to world transform
       Model_To_World_OBJECT4DV2(&obj_tank, TRANSFORM_TRANS_ONLY);

       //Light_OBJECT4DV2_World16(&obj_tank, &cam, lights, 4);

       // insert the object into render list
       Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_tank,0);
       } // end if
 
    } // end for

////////////////////////////////////////////////////////


// insert the towers in the world
for (index = 0; index < NUM_TOWERS; index++)
    {
    // reset the object (this only matters for backface and object removal)
    Reset_OBJECT4DV2(&obj_tower);

    // set position of tower
    obj_tower.world_pos.x = towers[index].x;
    obj_tower.world_pos.y = towers[index].y;
    obj_tower.world_pos.z = towers[index].z;

    // attempt to cull object   
    if (!Cull_OBJECT4DV2(&obj_tower, &cam, CULL_OBJECT_XYZ_PLANES))
       {
       // if we get here then the object is visible at this world position
       // so we can insert it into the rendering list
       // perform local/model to world transform
       Model_To_World_OBJECT4DV2(&obj_tower);

       //Light_OBJECT4DV2_World16(&obj_tower, &cam, lights, 4);

       // insert the object into render list
       Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_tower,0);

       } // end if
 
    } // end for

///////////////////////////////////////////////////////////////

// seed number generator so that modulation of markers is always the same
srand(13);

static int mcount = 0, mdir = 2;

mcount+=mdir;
if (mcount > 200 || mcount < -200) { mdir=-mdir; mcount+=mdir; }

// insert the ground markers into the world
for (int index_x = 0; index_x < NUM_POINTS_X; index_x++)
    for (int index_z = 0; index_z < NUM_POINTS_Z; index_z++)
        {
        // reset the object (this only matters for backface and object removal)
        Reset_OBJECT4DV2(&obj_marker);

        // set position of tower
        obj_marker.world_pos.x = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_x*POINT_SIZE;
        obj_marker.world_pos.y = obj_marker.max_radius[0] + 50*Fast_Sin(index_x*10+Fast_Sin(index_z)+mcount);
        obj_marker.world_pos.z = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_z*POINT_SIZE;

        // attempt to cull object   
        if (!Cull_OBJECT4DV2(&obj_marker, &cam, CULL_OBJECT_XYZ_PLANES))
           {
           // if we get here then the object is visible at this world position
           // so we can insert it into the rendering list
           // perform local/model to world transform
           Model_To_World_OBJECT4DV2(&obj_marker);

           //Light_OBJECT4DV2_World16(&obj_marker, &cam, lights, 4);

           // insert the object into render list
           Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_marker,0);

           } // end if

        } // end for

////////////////////////////////////////////////////////////////////////

#endif

// remove backfaces
if (backface_mode==1)
   Remove_Backfaces_RENDERLIST4DV2(&rend_list, &cam);

// light scene all at once 
if (lighting_mode==1)
   Light_RENDERLIST4DV2_World16(&rend_list, &cam, lights, 4);

// apply world to camera transform
World_To_Camera_RENDERLIST4DV2(&rend_list, &cam);

// sort the polygon list (hurry up!)
if (zsort_mode == 1)
   Sort_RENDERLIST4DV2(&rend_list,  SORT_POLYLIST_AVGZ);

// apply camera to perspective transformation
Camera_To_Perspective_RENDERLIST4DV2(&rend_list, &cam);

// apply screen transform
Perspective_To_Screen_RENDERLIST4DV2(&rend_list, &cam);

sprintf(work_string,"pos:[%f, %f, %f] heading:[%f] elev:[%f], polys[%d]", 
        cam.pos.x, cam.pos.y, cam.pos.z, cam.dir.y, cam.dir.x, debug_polys_rendered_per_frame); 

Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-20, RGB(0,255,0), lpddsback);

sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, Spot=%d | Zsort [%s], BckFceRM [%s]", 
                                                                                 ((lighting_mode == 1) ? "ON" : "OFF"),
                                                                                 lights[AMBIENT_LIGHT_INDEX].state,
                                                                                 lights[INFINITE_LIGHT_INDEX].state, 
                                                                                 lights[POINT_LIGHT_INDEX].state,
                                                                                 lights[SPOT_LIGHT2_INDEX].state,
                                                                                 ((zsort_mode == 1) ? "ON" : "OFF"),
                                                                                 ((backface_mode == 1) ? "ON" : "OFF"));

Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34, RGB(0,255,0), lpddsback);

// draw instructions
Draw_Text_GDI("Press ESC to exit. Press <H> for Help.", 0, 0, RGB(0,255,0), lpddsback);

// should we display help
int text_y = 16;
if (help_mode==1)
    {
    // draw help menu
    Draw_Text_GDI("<A>..............Toggle ambient light source.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<I>..............Toggle infinite light source.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<P>..............Toggle point light source.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<S>..............Toggle spot light source.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<W>..............Toggle wire frame/solid mode.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<B>..............Toggle backface removal.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<RIGHT ARROW>....Rotate player right.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<LEFT ARROW>.....Rotate player left.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<UP ARROW>.......Move player forward.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<DOWN ARROW>.....Move player backward.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<SPACE BAR>......Turbo.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<H>..............Toggle Help.", 0, text_y+=12, RGB(255,255,255), lpddsback);
    Draw_Text_GDI("<ESC>............Exit demo.", 0, text_y+=12, RGB(255,255,255), lpddsback);

    } // end help

// lock the back buffer
DDraw_Lock_Back_Surface();

// reset number of polys rendered
debug_polys_rendered_per_frame = 0;

// render the object

if (wireframe_mode  == 0)
   Draw_RENDERLIST4DV2_Wire16(&rend_list, back_buffer, back_lpitch);
else
if (wireframe_mode  == 1)
   Draw_RENDERLIST4DV2_Solid16(&rend_list, back_buffer, back_lpitch);

#endif

// unlock the back buffer
DDraw_Unlock_Back_Surface();

// flip the surfaces
DDraw_Flip();

// sync to 30ish fps
Wait_Clock(30);

// check of user is trying to exit
if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE])
    {
    PostMessage(main_window_handle, WM_DESTROY,0,0);
    } // end if

// return success
return(1);
 
} // end Game_Main
int Game_Init(void *parms)
{
// this function is where you do all the initialization 
// for your game

int index; // looping var

// start up DirectDraw (replace the parms as you desire)
DDraw_Init(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, WINDOWED_APP);

// initialize directinput
DInput_Init();

// acquire the keyboard 
DInput_Init_Keyboard();

// add calls to acquire other directinput devices here...

// initialize directsound and directmusic
DSound_Init();
DMusic_Init();

// hide the mouse
if (!WINDOWED_APP)
    ShowCursor(FALSE);

// seed random number generator
srand(Start_Clock());

Open_Error_File("ERROR.TXT");

// initialize math engine
Build_Sin_Cos_Tables();

// initialize the camera with 90 FOV, normalized coordinates
Init_CAM4DV1(&cam,      // the camera object
             CAM_MODEL_EULER, // the euler model
             &cam_pos,  // initial camera position
             &cam_dir,  // initial camera angles
             &cam_target,      // no target
             200.0,      // near and far clipping planes
             12000.0,
             120.0,      // field of view in degrees
             WINDOW_WIDTH,   // size of final screen viewport
             WINDOW_HEIGHT);

// load the master tank object
VECTOR4D_INITXYZ(&vscale,0.75,0.75,0.75);
Load_OBJECT4DV2_PLG(&obj_tank, "tank3.plg",&vscale, &vpos, &vrot);

// load player object for 3rd person view
VECTOR4D_INITXYZ(&vscale,15.75,15.75,15.75);
Load_OBJECT4DV2_COB(&obj_player,"tie04.cob",  
                       &vscale, &vpos, &vrot, VERTEX_FLAGS_INVERT_TEXTURE_V |
                        VERTEX_FLAGS_SWAP_YZ | VERTEX_FLAGS_TRANSFORM_LOCAL_WORLD );

// load the master tower object
VECTOR4D_INITXYZ(&vscale,1.0, 2.0, 1.0);
Load_OBJECT4DV2_PLG(&obj_tower, "towerg1.plg",&vscale, &vpos, &vrot);

// load the master ground marker
VECTOR4D_INITXYZ(&vscale,3.0,3.0,3.0);
Load_OBJECT4DV2_PLG(&obj_marker, "marker2.plg",&vscale, &vpos, &vrot);
 
// position the tanks
for (index = 0; index < NUM_TANKS; index++)
    {
    // randomly position the tanks
    tanks[index].x = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
    tanks[index].y = 0; // obj_tank.max_radius;
    tanks[index].z = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
    tanks[index].w = RAND_RANGE(0,360);
    } // end for

// position the towers
for (index = 0; index < NUM_TOWERS; index++)
    {
    // randomly position the tower
    towers[index].x = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
    towers[index].y = 0; // obj_tower.max_radius;
    towers[index].z = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
    } // end for

// set up lights
Reset_Lights_LIGHTV1();

// create some working colors
white.rgba = _RGBA32BIT(255,255,255,0);
gray.rgba  = _RGBA32BIT(100,100,100,0);
black.rgba = _RGBA32BIT(0,0,0,0);
red.rgba   = _RGBA32BIT(255,0,0,0);
green.rgba = _RGBA32BIT(0,255,0,0);
blue.rgba  = _RGBA32BIT(0,0,255,0);

// ambient light
Init_Light_LIGHTV1(AMBIENT_LIGHT_INDEX,   
                   LIGHTV1_STATE_ON,      // turn the light on
                   LIGHTV1_ATTR_AMBIENT,  // ambient light type
                   gray, black, black,    // color for ambient term only
                   NULL, NULL,            // no need for pos or dir
                   0,0,0,                 // no need for attenuation
                   0,0,0);                // spotlight info NA


VECTOR4D dlight_dir = {-1,0,-1,0};

// directional light
Init_Light_LIGHTV1(INFINITE_LIGHT_INDEX,  
                   LIGHTV1_STATE_ON,      // turn the light on
                   LIGHTV1_ATTR_INFINITE, // infinite light type
                   black, gray, black,    // color for diffuse term only
                   NULL, &dlight_dir,     // need direction only
                   0,0,0,                 // no need for attenuation
                   0,0,0);                // spotlight info NA


VECTOR4D plight_pos = {0,200,0,0};

// point light
Init_Light_LIGHTV1(POINT_LIGHT_INDEX,
                   LIGHTV1_STATE_ON,      // turn the light on
                   LIGHTV1_ATTR_POINT,    // pointlight type
                   black, green, black,   // color for diffuse term only
                   &plight_pos, NULL,     // need pos only
                   0,.001,0,              // linear attenuation only
                   0,0,1);                // spotlight info NA


VECTOR4D slight2_pos = {0,200,0,0};
VECTOR4D slight2_dir = {-1,0,-1,0};

// spot light2
Init_Light_LIGHTV1(SPOT_LIGHT2_INDEX,
                   LIGHTV1_STATE_ON,         // turn the light on
                   LIGHTV1_ATTR_SPOTLIGHT2,  // spot light type 2
                   black, red, black,      // color for diffuse term only
                   &slight2_pos, &slight2_dir, // need pos only
                   0,.001,0,                 // linear attenuation only
                   0,0,1);    


// create lookup for lighting engine
RGB_16_8_IndexedRGB_Table_Builder(DD_PIXEL_FORMAT565,  // format we want to build table for
                                  palette,             // source palette
                                  rgblookup);          // lookup table


// return success
return(1);

} // end Game_Init
int Game_Main(void *parms)
{
// this is the workhorse of your game it will be called
// continuously in real-time this is like main() in C
// all the calls for you game go here!

static MATRIX4X4 mrot;   // general rotation matrix

// these are used to create a circling camera
static float view_angle = 0; 
static float camera_distance = 6000;
static VECTOR4D pos = {0,0,0,0};
static float tank_speed;
static float turning = 0;

char work_string[256]; // temp string

int index; // looping var

// start the timing clock
Start_Clock();

// clear the drawing surface 
DDraw_Fill_Surface(lpddsback, 0);

// draw the sky
Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, RGB16Bit(0,140,192), lpddsback);

// draw the ground
Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, RGB16Bit(103,62,3), lpddsback);

// read keyboard and other devices here
DInput_Read_Keyboard();

// game logic here...

// reset the render list
Reset_RENDERLIST4DV1(&rend_list);

// allow user to move camera

// turbo
if (keyboard_state[DIK_SPACE])
    tank_speed = 5*TANK_SPEED;
else
    tank_speed = TANK_SPEED;

// forward/backward
if (keyboard_state[DIK_UP])
   {
   // move forward
   cam.pos.x += tank_speed*Fast_Sin(cam.dir.y);
   cam.pos.z += tank_speed*Fast_Cos(cam.dir.y);
   } // end if

if (keyboard_state[DIK_DOWN])
   {
   // move backward
   cam.pos.x -= tank_speed*Fast_Sin(cam.dir.y);
   cam.pos.z -= tank_speed*Fast_Cos(cam.dir.y);
   } // end if

// rotate
if (keyboard_state[DIK_RIGHT])
   {
   cam.dir.y+=3;
   
   // add a little turn to object
   if ((turning+=2) > 15)
      turning=15;

   } // end if

if (keyboard_state[DIK_LEFT])
   {
   cam.dir.y-=3;

   // add a little turn to object
   if ((turning-=2) < -15)
      turning=-15;

   } // end if
else // center heading again
   {
   if (turning > 0)
       turning-=1;
   else
   if (turning < 0)
       turning+=1;

   } // end else

// generate camera matrix
Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX);

// insert the tanks in the world
for (index = 0; index < NUM_TANKS; index++)
    {
    // reset the object (this only matters for backface and object removal)
    Reset_OBJECT4DV1(&obj_tank);

    // generate rotation matrix around y axis
    Build_XYZ_Rotation_MATRIX4X4(0, tanks[index].w, 0, &mrot);

    // rotate the local coords of the object
    Transform_OBJECT4DV1(&obj_tank, &mrot, TRANSFORM_LOCAL_TO_TRANS,1);

    // set position of tank
    obj_tank.world_pos.x = tanks[index].x;
    obj_tank.world_pos.y = tanks[index].y;
    obj_tank.world_pos.z = tanks[index].z;

    // attempt to cull object   
    if (!Cull_OBJECT4DV1(&obj_tank, &cam, CULL_OBJECT_XYZ_PLANES))
       {
       // if we get here then the object is visible at this world position
       // so we can insert it into the rendering list
       // perform local/model to world transform
       Model_To_World_OBJECT4DV1(&obj_tank, TRANSFORM_TRANS_ONLY);

       // insert the object into render list
       Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_tank);
       } // end if
 
    } // end for

// insert the player into the world
// reset the object (this only matters for backface and object removal)
Reset_OBJECT4DV1(&obj_player);

// set position of tank
obj_player.world_pos.x = cam.pos.x+300*Fast_Sin(cam.dir.y);
obj_player.world_pos.y = cam.pos.y-70;
obj_player.world_pos.z = cam.pos.z+300*Fast_Cos(cam.dir.y);

// generate rotation matrix around y axis
Build_XYZ_Rotation_MATRIX4X4(0, cam.dir.y+turning, 0, &mrot);

// rotate the local coords of the object
Transform_OBJECT4DV1(&obj_player, &mrot, TRANSFORM_LOCAL_TO_TRANS,1);

// perform world transform
Model_To_World_OBJECT4DV1(&obj_player, TRANSFORM_TRANS_ONLY);

// insert the object into render list
Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_player);


// insert the towers in the world
for (index = 0; index < NUM_TOWERS; index++)
    {
    // reset the object (this only matters for backface and object removal)
    Reset_OBJECT4DV1(&obj_tower);

    // set position of tower
    obj_tower.world_pos.x = towers[index].x;
    obj_tower.world_pos.y = towers[index].y;
    obj_tower.world_pos.z = towers[index].z;

    // attempt to cull object   
    if (!Cull_OBJECT4DV1(&obj_tower, &cam, CULL_OBJECT_XYZ_PLANES))
       {
       // if we get here then the object is visible at this world position
       // so we can insert it into the rendering list
       // perform local/model to world transform
       Model_To_World_OBJECT4DV1(&obj_tower);

       // insert the object into render list
       Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_tower);
       } // end if
 
    } // end for

// seed number generator so that modulation of markers is always the same
srand(13);

// insert the ground markers into the world
for (int index_x = 0; index_x < NUM_POINTS_X; index_x++)
    for (int index_z = 0; index_z < NUM_POINTS_Z; index_z++)
        {
        // reset the object (this only matters for backface and object removal)
        Reset_OBJECT4DV1(&obj_marker);

        // set position of tower
        obj_marker.world_pos.x = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_x*POINT_SIZE;
        obj_marker.world_pos.y = obj_marker.max_radius;
        obj_marker.world_pos.z = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_z*POINT_SIZE;

        // attempt to cull object   
        if (!Cull_OBJECT4DV1(&obj_marker, &cam, CULL_OBJECT_XYZ_PLANES))
           {
           // if we get here then the object is visible at this world position
           // so we can insert it into the rendering list
           // perform local/model to world transform
           Model_To_World_OBJECT4DV1(&obj_marker);

           // insert the object into render list
           Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_marker);
           } // end if

        } // end for

// remove backfaces
Remove_Backfaces_RENDERLIST4DV1(&rend_list, &cam);

// apply world to camera transform
World_To_Camera_RENDERLIST4DV1(&rend_list, &cam);

// apply camera to perspective transformation
Camera_To_Perspective_RENDERLIST4DV1(&rend_list, &cam);

// apply screen transform
Perspective_To_Screen_RENDERLIST4DV1(&rend_list, &cam);

sprintf(work_string,"pos:[%f, %f, %f] heading:[%f] elev:[%f]", 
        cam.pos.x, cam.pos.y, cam.pos.z, cam.dir.y, cam.dir.x); 

Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-20, RGB(0,255,0), lpddsback);

// draw instructions
Draw_Text_GDI("Press ESC to exit. Press Arrow Keys to Move. Space for TURBO.", 0, 0, RGB(0,255,0), lpddsback);

// lock the back buffer
DDraw_Lock_Back_Surface();

// render the object
Draw_RENDERLIST4DV1_Wire16(&rend_list, back_buffer, back_lpitch);

// unlock the back buffer
DDraw_Unlock_Back_Surface();

// flip the surfaces
DDraw_Flip();

// sync to 30ish fps
Wait_Clock(30);

// check of user is trying to exit
if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE])
    {
    PostMessage(main_window_handle, WM_DESTROY,0,0);
    } // end if

// return success
return(1);
 
} // end Game_Main
int Game_Init(void *parms)
{
// this function is where you do all the initialization
// for your game

    int index; // looping var

// start up DirectDraw (replace the parms as you desire)
    DDraw_Init2(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, WINDOWED_APP,1);

// initialize directinput
    DInput_Init();

// acquire the keyboard
    DInput_Init_Keyboard();

// add calls to acquire other directinput devices here...

// initialize directsound and directmusic
    DSound_Init();
    DMusic_Init();

// hide the mouse
    if (!WINDOWED_APP)
        ShowCursor(FALSE);

// seed random number generator
    srand(Start_Clock());

    Open_Error_File("ERROR.TXT");

// initialize math engine
    Build_Sin_Cos_Tables();

// initialize the camera with 90 FOV, normalized coordinates
    Init_CAM4DV1(&cam,      // the camera object
                 CAM_MODEL_EULER, // the euler model
                 &cam_pos,  // initial camera position
                 &cam_dir,  // initial camera angles
                 &cam_target,      // no target
                 10.0,        // near and far clipping planes
                 12000.0,
                 120.0,      // field of view in degrees
                 WINDOW_WIDTH,   // size of final screen viewport
                 WINDOW_HEIGHT);

// set a scaling vector
    VECTOR4D_INITXYZ(&vscale,20.00,20.00,20.00);

// load all the objects in
    for (int index_obj=0; index_obj < NUM_OBJECTS; index_obj++)
    {
        Load_OBJECT4DV2_COB2(&obj_array[index_obj], object_filenames[index_obj],
                             &vscale, &vpos, &vrot, VERTEX_FLAGS_SWAP_YZ
                             | VERTEX_FLAGS_TRANSFORM_LOCAL
                             // | VERTEX_FLAGS_TRANSFORM_LOCAL_WORLD
                             | VERTEX_FLAGS_INVERT_TEXTURE_V
                             ,0 );

    } // end for index_obj

// set current object
    curr_object = 0;
    obj_work = &obj_array[curr_object];

// position the scenery objects randomly
    for (index = 0; index < NUM_SCENE_OBJECTS; index++)
    {
        // set master object link
        scene_objects[index].obj = obj_work;

        // randomly position object
        scene_objects[index].pos.x = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
        scene_objects[index].pos.y = RAND_RANGE(-200, 200);
        scene_objects[index].pos.z = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
        scene_objects[index].rot.y = RAND_RANGE(0,360);
        scene_objects[index].auxi[0] = RAND_RANGE(1,5);

        // set state of object container
        scene_objects[index].state = ((OBJECT4DV2_PTR)scene_objects[index].obj)->state;

        // set attributes
        scene_objects[index].attr = ((OBJECT4DV2_PTR)scene_objects[index].obj)->attr;
    } // end for

// set up lights
    Reset_Lights_LIGHTV2(lights2, MAX_LIGHTS);

// create some working colors
    white.rgba = _RGBA32BIT(255,255,255,0);
    gray.rgba  = _RGBA32BIT(150,150,150,0);
    black.rgba = _RGBA32BIT(0,0,0,0);
    red.rgba   = _RGBA32BIT(255,0,0,0);
    green.rgba = _RGBA32BIT(0,255,0,0);
    blue.rgba  = _RGBA32BIT(0,0,255,0);

// ambient light
    Init_Light_LIGHTV2(lights2,               // array of lights to work with
                       AMBIENT_LIGHT_INDEX,
                       LIGHTV2_STATE_ON,      // turn the light on
                       LIGHTV2_ATTR_AMBIENT,  // ambient light type
                       gray, black, black,    // color for ambient term only
                       NULL, NULL,            // no need for pos or dir
                       0,0,0,                 // no need for attenuation
                       0,0,0);                // spotlight info NA

    VECTOR4D dlight_dir = {-1,0,-1,1};

// directional light
    Init_Light_LIGHTV2(lights2,               // array of lights to work with
                       INFINITE_LIGHT_INDEX,
                       LIGHTV2_STATE_ON,      // turn the light on
                       LIGHTV2_ATTR_INFINITE, // infinite light type
                       black, gray, black,    // color for diffuse term only
                       NULL, &dlight_dir,     // need direction only
                       0,0,0,                 // no need for attenuation
                       0,0,0);                // spotlight info NA


    VECTOR4D plight_pos = {0,200,0,1};

// point light
    Init_Light_LIGHTV2(lights2,               // array of lights to work with
                       POINT_LIGHT_INDEX,
                       LIGHTV2_STATE_ON,      // turn the light on
                       LIGHTV2_ATTR_POINT,    // pointlight type
                       black, green, black,    // color for diffuse term only
                       &plight_pos, NULL,     // need pos only
                       0,.002,0,              // linear attenuation only
                       0,0,1);                // spotlight info NA


    VECTOR4D slight2_pos = {0,1000,0,1};
    VECTOR4D slight2_dir = {-1,0,-1,1};

// spot light2
    Init_Light_LIGHTV2(lights2,                  // array of lights to work with
                       SPOT_LIGHT2_INDEX,
                       LIGHTV2_STATE_ON,         // turn the light on
                       LIGHTV2_ATTR_SPOTLIGHT2,  // spot light type 2
                       black, red, black,        // color for diffuse term only
                       &slight2_pos, &slight2_dir, // need pos only
                       0,.001,0,                 // linear attenuation only
                       0,0,1);


// create lookup for lighting engine
    RGB_16_8_IndexedRGB_Table_Builder(DD_PIXEL_FORMAT565,  // format we want to build table for
                                      palette,             // source palette
                                      rgblookup);          // lookup table

// create the z buffer
    Create_Zbuffer(&zbuffer,
                   WINDOW_WIDTH,
                   WINDOW_HEIGHT,
                   ZBUFFER_ATTR_32BIT);

// create the alpha lookup table
    RGB_Alpha_Table_Builder(NUM_ALPHA_LEVELS, rgb_alpha_table);

// load in the background
    Create_BOB(&background, 0,0,800,600,1, BOB_ATTR_VISIBLE | BOB_ATTR_SINGLE_FRAME, DDSCAPS_SYSTEMMEMORY, 0, 16);
    Load_Bitmap_File(&bitmap16bit, "nebblue01.bmp");
    Load_Frame_BOB16(&background, &bitmap16bit,0,0,0,BITMAP_EXTRACT_MODE_ABS);
    Unload_Bitmap_File(&bitmap16bit);

// build the bounding hierarchical volume tree with 3 divisions per level
    BHV_Build_Tree(&bhv_tree,
                   scene_objects,
                   NUM_SCENE_OBJECTS,
                   0,
                   3,
                   UNIVERSE_RADIUS);

// return success
    return(1);

} // end Game_Init