1
0
Fork 0

Added several improvements from an old branch

* Added body rotation using hit button
* Added rotating decapitation camera
* Added slow motion on death
* Improved camera tracking
* Added motion blur
* Fixed several bugs
This commit is contained in:
Michaël Lemaire 2015-06-02 22:25:50 +02:00
parent 371731a73b
commit bf1f9192e5
38 changed files with 1020 additions and 204 deletions

View File

@ -17,7 +17,8 @@ SRC = 3dutils.cpp appearance.cpp audio.cpp camera.cpp collision.cpp \
fight.cpp font.cpp glapi.cpp graphics.cpp legoblocks.cpp \
legoman.cpp light.cpp main.cpp material.cpp menu.cpp mesh.cpp \
object.cpp objectfactory.cpp particle.cpp run.cpp shape.cpp \
sphere.cpp texture.cpp utils.cpp vector.cpp world.cpp end.cpp
sphere.cpp texture.cpp utils.cpp vector.cpp world.cpp end.cpp \
fonct.cpp
OBJ = $(SRC:%.cpp=src/%.o)

Binary file not shown.

BIN
data/fight.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
data/menu.ogg Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 KiB

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 KiB

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 KiB

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 KiB

After

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 635 KiB

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

@ -214,12 +214,15 @@ void createSkyBox(float x, float y, float z, float w, float h, float l) {
glEnable(GL_TEXTURE_2D);
glClear(GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
glDisable(GL_ALPHA_TEST);
glDisable(GL_LIGHTING);
glShadeModel(GL_FLAT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0, 1.0, 1.0, 0.5);
float modelview[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
@ -243,8 +246,6 @@ void createSkyBox(float x, float y, float z, float w, float h, float l) {
skybacktexture->enable();
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1.0);
glTexCoord2f(1 - d, 1 - d);
glVertex3f(x + w, y, z);
glTexCoord2f(1 - d, 0 + d);
@ -260,9 +261,6 @@ void createSkyBox(float x, float y, float z, float w, float h, float l) {
skyfronttexture->enable();
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1.0);
glTexCoord2f(1 - d, 1 - d);
glVertex3f(x, y, z + l);
glTexCoord2f(1 - d, 0 + d);
@ -277,8 +275,6 @@ void createSkyBox(float x, float y, float z, float w, float h, float l) {
skytoptexture->enable();
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1.0);
glTexCoord2f(0 + d, 0 + d);
glVertex3f(x + w, y + h, z + l);
glTexCoord2f(1 - d, 0 + d);
@ -298,8 +294,6 @@ void createSkyBox(float x, float y, float z, float w, float h, float l) {
skybottomtexture->enable();
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1.0);
glTexCoord2f(1 - d, 0 + d);
glVertex3f(x, y, z);
glTexCoord2f(1 - d, 1 - d);
@ -315,7 +309,6 @@ void createSkyBox(float x, float y, float z, float w, float h, float l) {
skylefttexture->enable();
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1.0);
glTexCoord2f(1 - d, 0 + d);
glVertex3f(x, y + h, z);
glTexCoord2f(0 + d, 0 + d);
@ -331,7 +324,6 @@ void createSkyBox(float x, float y, float z, float w, float h, float l) {
skyrighttexture->enable();
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1.0);
glTexCoord2f(0 + d, 1 - d);
glVertex3f(x + w, y, z);
glTexCoord2f(1 - d, 1 - d);
@ -351,6 +343,7 @@ void createSkyBox(float x, float y, float z, float w, float h, float l) {
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
glDisable(GL_BLEND);
}
void enable2D(void) {

View File

@ -79,18 +79,19 @@ void Sound::load(char *filename, int type, bool loops) {
this->loops = false;
} else if (type == SOUNDTYPE_SAMPLE) {
if (loops) {
sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_NORMAL, 0);
FSOUND_Sample_SetLoopMode(sample, FSOUND_LOOP_NORMAL);
sample =
FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_NORMAL, 0, 0);
FSOUND_Sample_SetMode(sample, FSOUND_LOOP_NORMAL);
} else {
sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_OFF, 0);
FSOUND_Sample_SetLoopMode(sample, FSOUND_LOOP_OFF);
sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_OFF, 0, 0);
FSOUND_Sample_SetMode(sample, FSOUND_LOOP_OFF);
}
this->loops = loops;
} else if (type == SOUNDTYPE_STREAM) {
if (loops) {
stream = FSOUND_Stream_OpenFile(filename, FSOUND_LOOP_NORMAL, 0);
stream = FSOUND_Stream_Open(filename, FSOUND_LOOP_NORMAL, 0, 0);
} else {
stream = FSOUND_Stream_OpenFile(filename, FSOUND_LOOP_OFF, 0);
stream = FSOUND_Stream_Open(filename, FSOUND_LOOP_OFF, 0, 0);
}
this->loops = loops;
}
@ -116,17 +117,17 @@ bool Sound::play() {
#ifdef AUDIO_FMOD
if (type == SOUNDTYPE_MODULE) {
FMUSIC_PlaySong(module);
FMUSIC_SetMasterVolume(module, volume * 256);
FMUSIC_SetMasterVolume(module, (int)(volume * 256));
} else if (type == SOUNDTYPE_SAMPLE) {
channel = FSOUND_PlaySound(FSOUND_FREE, sample);
FSOUND_SetVolume(channel, volume * 256);
FSOUND_SetVolume(channel, (int)(volume * 256));
if (!loops) {
running = false;
finished = false;
}
} else if (type == SOUNDTYPE_STREAM) {
channel = FSOUND_Stream_Play(FSOUND_FREE, stream);
FSOUND_SetVolume(channel, volume * 256);
FSOUND_SetVolume(channel, (int)(volume * 256));
}
#endif
// printf("Done: %f\n", volume);
@ -151,14 +152,13 @@ void Sound::stop() {
}
void Sound::setVolume(float volume) {
// printf("Volume %s: %f\n", filename, volume);
#ifdef AUDIO_FMOD
if (type == SOUNDTYPE_MODULE) {
FMUSIC_SetMasterVolume(module, volume * 256);
FMUSIC_SetMasterVolume(module, (int)(volume * 256));
} else if (type == SOUNDTYPE_SAMPLE) {
FSOUND_SetVolume(channel, volume * 256);
FSOUND_SetVolume(channel, (int)(volume * 256));
} else if (type == SOUNDTYPE_STREAM) {
FSOUND_SetVolume(channel, volume * 256);
FSOUND_SetVolume(channel, (int)(volume * 256));
}
#endif
this->volume = volume;
@ -180,7 +180,8 @@ void Sound::setStopCallback(STOPCALLBACK callback) {
} else if (type == SOUNDTYPE_SAMPLE) {
// NOT SUPPORTED
} else if (type == SOUNDTYPE_STREAM) {
FSOUND_Stream_SetEndCallback(stream, streamendcallback, (int)this);
// FSOUND_Stream_SetEndCallback(stream,
// (FSOUND_STREAMCALLBACK)streamendcallback, (int)this);
}
#endif
}
@ -240,7 +241,7 @@ void Sound::fadeIn(int length) {
void Sound::fadeOut(int length) {
if (fademode == SOUND_FADEIN) {
float percent = 1.0 - (float)fadepos / fadetarget;
fadepos = fadetarget * percent;
fadepos = (int)(fadetarget * percent);
}
fadepos = 0;
fadetarget = length;

View File

@ -3,19 +3,145 @@
#include "camera.h"
#include "vector.h"
#include "glapi.h"
#include "fight.h"
#include "fonct.h"
Camera::Camera(void) {
right = &matrix[0];
up = &matrix[3];
forward = &matrix[6];
vectorSet(position, 0, 2, 2);
vectorSet(target, 0, 0, 0);
// vectorSet(position, 0, 2, 2);
// vectorSet(target, 0, 0, 0);
vectorSet(up, 0, 1, 0);
// vectorSet(positionang, 0, 5, 20);
this->setStart();
calculateMatrix();
}
void Camera::setStart() {
vectorSet(position, 0, 2, 2);
vectorSet(target, -2, 10, 0); // hum...cela affecte la lumière du menu
vectorSet(positionang, 3.0 * M_PI / 2.0, 8.0, 5.0);
this->end = false;
}
void Camera::setAutoNormal(Object *obj1, Object *obj2, bool finish) {
float diff[3];
float dist = flmax(fabs(this->position[0]), fabs(this->position[2]));
vectorSub(diff, obj1->position, obj2->position);
this->target[0] = (obj1->position[0] + obj2->position[0]) / 2.0;
this->target[1] = (obj1->position[1] + obj2->position[1]) / 2.0;
this->target[2] = (obj1->position[2] + obj2->position[2]) / 2.0;
this->optimalposition[0] = angle(diff[0], diff[2]) + M_PI / 2.0;
this->optimalposition[1] = flmin(flmax(vectorLength(diff) * 4.0, 5.0), 20.0);
if (this->target[1] > 8.0) {
this->optimalposition[1] *= 2.0;
this->optimalposition[2] = this->target[1] + 5.0;
} else {
if (dist < ARENASIZE * 0.8) {
this->optimalposition[2] = 5.0;
} else {
this->optimalposition[2] = dist;
}
}
if (finish) {
this->positionang[0] = this->optimalposition[0];
this->positionang[1] = this->optimalposition[1] / 2.0;
} else {
this->positionang[0] +=
modulo(this->optimalposition[0] - this->positionang[0], -M_PI,
2 * M_PI) /
250.0;
this->positionang[1] +=
(this->optimalposition[1] - this->positionang[1]) / 500.0;
}
this->positionang[2] +=
(this->optimalposition[2] - this->positionang[2]) / 100.0;
this->position[0] =
this->target[0] + cos(this->positionang[0]) * this->positionang[1];
this->position[1] = this->positionang[2];
this->position[2] =
this->target[2] + sin(this->positionang[0]) * this->positionang[1];
}
void Camera::setAutoCastOut(Object *obj) {
if ((obj->position[0] > ARENASIZE) || (obj->position[2] > ARENASIZE)) {
if (!end) {
this->position[0] = 5.0 + ARENASIZE;
this->position[2] = 5.0 + ARENASIZE;
}
if (obj->position[0] + 1.0 > this->position[0]) {
this->position[0] += 0.1;
}
if (obj->position[2] + 1.0 > this->position[2]) {
this->position[2] += 0.1;
}
} else {
if (!end) {
this->position[0] = -5.0 - ARENASIZE;
this->position[2] = -5.0 - ARENASIZE;
}
if (obj->position[0] - 1.0 < this->position[0]) {
this->position[0] -= 0.1;
}
if (obj->position[2] - 1.0 < this->position[2]) {
this->position[2] -= 0.1;
}
}
// this->position[1] = -10.0 - obj->position[1] / 2.0;
this->position[1] = obj->position[1] / 2.0 + 10.0;
// this->position[1] = 5.0;
this->target[0] = obj->position[0] * 0.7;
this->target[1] = obj->position[1];
this->target[2] = obj->position[2] * 0.7;
// this->target[1] = -5.0;
this->end = true;
}
void Camera::setAutoBeheaded(Object *head, float angle) {
this->target[0] = head->position[0];
this->target[1] = head->position[1];
this->target[2] = head->position[2];
this->position[0] = this->target[0] + 5.0 * cos(angle);
this->position[2] = this->target[2] + 5.0 * sin(angle);
this->position[1] = ARENAHEIGHT / 2.0 + 1.0 + cos(angle);
;
}
void Camera::setAutoFallHead(Object *head, Object *torso) {
float angh, d;
angh = angle(torso->position[0] - head->position[0],
torso->position[2] - head->position[2]);
d = dist3d(head->position[0], head->position[1], head->position[2],
torso->position[0], torso->position[1], torso->position[2]);
d = MIN(d, 25.0);
angh += (25.0 - d) * M_PI / 25.0 - M_PI_2;
d = MAX(d, 10.0);
this->target[0] = head->position[0];
this->target[1] =
head->position[1] + (torso->position[1] - head->position[1]) / 2.0;
this->target[2] = head->position[2];
this->position[0] = torso->position[0] + d * cos(angh);
this->position[1] = d / 2.0 + 3.0;
this->position[2] = torso->position[2] + d * sin(angh);
}
void Camera::setPosition(float position[3]) {
vectorCopy(this->position, position);
}

View File

@ -1,6 +1,8 @@
#ifndef __CAMERA_H_INCLUDED__
#define __CAMERA_H_INCLUDED__
#include "object.h"
class Camera {
private:
float position[3];
@ -8,11 +10,23 @@ private:
float matrix[9];
float *right, *up, *forward;
float positionang[3]; // position angulaire actuelle
float optimalposition[3]; // position angulaire que doit atteindre la caméra
// desc: {angh, dist, h}
bool end; // controle si c'est une caméra placée pour la mort
void calculateMatrix(void);
public:
Camera(void);
void setStart();
void setAutoNormal(Object *obj1, Object *obj2, bool finish);
void setAutoCastOut(Object *obj);
void setAutoBeheaded(Object *head, float angle);
void setAutoFallHead(Object *head, Object *torso);
void setPosition(float position[3]);
void setPosition(float x, float y, float z);
void getPosition(float *position);

View File

@ -284,7 +284,7 @@ bool handleLink(ObjectLink *link) {
bool checkCollisions(Object *object, float *contactnormal) {
// bool collision = false;
int group = object->getCollisionGroup();
int groups = collisionlinks[group];
// UNUSED//int groups = collisionlinks[group];
group = 0;
int collisions = 0;
/*float oldmomentum[3];
@ -652,8 +652,8 @@ bool checkEdgeMeshCollision(float *p1, float *p2, Mesh *mesh, float *normal,
float ray[3];
vectorSub(ray, p2, p1);
float maxdist = 0;
bool collision = false;
// UNUSED//float maxdist = 0;
// UNUSED//bool collision = false;
int i, j;
@ -688,7 +688,7 @@ bool checkEdgeMeshCollision(float *p1, float *p2, Mesh *mesh, float *normal,
int negative = -1, positive = -1;
for (i = 0; i < hitcount; i++) {
float t = hits[i].t;
// UNUSED//float t = hits[i].t;
class Polygon *polygon = hits[i].polygon;
float dot = vectorDot(ray, polygon->planenormal);

View File

@ -2,8 +2,7 @@
#define __COLLISION_H_INCLUDED__
#include "mesh.h"
class ObjectLink;
#include "world.h"
#define COLLISIONGROUP_NONE 0
#define COLLISIONGROUP_ARENA 1

View File

@ -1,5 +1,6 @@
#include "main.h"
#include <stdlib.h>
#include <math.h>
#include "legoblocks.h"
@ -39,13 +40,22 @@ Sound *fightsound;
Sound *victorysound;
Legoman *man1, *man2;
Legoman *manout = NULL;
Legoman *beheaded = NULL;
int points1, points2;
#define ARENASIZE 10
#define ARENAHEIGHT 10
int startcounter, endcounter, rockcounter = 0;
float fightfade;
bool dead;
Legoman *winner;
bool fightinitialized = false;
void resetFight(void); // prototype
void initFight(void) {
if (!fightinitialized) {
initCollisions();
@ -70,8 +80,8 @@ void initFight(void) {
addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_MAN2HAND);
// Sound* backgroundsong = new Sound("mixdown.mp3");
Sound *backgroundsong = new Sound(BGSONG, true);
camera.setPosition(-5, 8, 18);
// UNUSED//Sound* backgroundsong = new Sound(BGSONG, true);
// camera.setPosition(-5, 8, 18);
arenaworld = new World();
@ -174,7 +184,7 @@ void initFight(void) {
Mesh *linegeometry;
MultiAppearance *lineappearance;
BasicBlockAppearance *line;
int geometryheight = BLOCKHEIGHT * ARENAHEIGHT;
int geometryheight = (int)(BLOCKHEIGHT * ARENAHEIGHT);
linegeometry =
createBox(-0.5, 0.5, -geometryheight / 2,
@ -286,17 +296,19 @@ void initFight(void) {
fightsound = new Sound(DATAPATH "fight.wav");
victorysound = new Sound(DATAPATH "victory.wav");
fightmusic = new Sound(DATAPATH "fight.mp3", true);
fightmusic = new Sound(DATAPATH "fight.ogg", true);
}
float cameraTarget[3] = {0, 6, 0};
camera.setTarget(cameraTarget);
// float cameraTarget[3] = {0, 6, 0};
// camera.setTarget(cameraTarget);
// camera.setStart();
arenaworld->prepare();
resetFight();
points1 = 0;
points2 = 0;
winner = man1;
}
#define MAXSCORE 3
@ -304,6 +316,7 @@ void initFight(void) {
int trophycounter = -1;
void resetFight(void) {
arenaworld->setGravity(9.81);
float movement[3];
man1->heal();
man2->heal();
@ -315,16 +328,21 @@ void resetFight(void) {
man1->lockPart(LEFTLEG | RIGHTLEG);
man2->lockPart(LEFTLEG | RIGHTLEG);
man1->getMainObject()->setGravity(true);
man1->getHead()->setGravity(true);
man2->getMainObject()->setGravity(true);
man2->getHead()->setGravity(true);
manout = NULL;
beheaded = NULL;
rockcounter = 0;
camera.setStart();
removeAllBlood();
}
int startcounter, endcounter;
float fightfade;
bool dead;
Legoman *winner;
void gameOver(Legoman *loser) {
endcounter = 0;
dead = true;
@ -351,12 +369,12 @@ SDLKey player1backward = SDLK_DOWN;
SDLKey player1jump = SDLK_RSHIFT;
SDLKey player1hit = SDLK_RCTRL;
SDLKey player2left = SDLK_a;
SDLKey player2right = SDLK_d;
SDLKey player2forward = SDLK_w;
SDLKey player2backward = SDLK_s;
SDLKey player2jump = SDLK_LSHIFT;
SDLKey player2hit = SDLK_LCTRL;
SDLKey player2left = SDLK_f;
SDLKey player2right = SDLK_h;
SDLKey player2forward = SDLK_t;
SDLKey player2backward = SDLK_g;
SDLKey player2jump = SDLK_s;
SDLKey player2hit = SDLK_x;
void stopGame(void) {
light1.setEnabled(false);
@ -401,6 +419,7 @@ void calculateFight(int framecount) {
if (endcounter == VICTORY) {
victorysound->play();
setSpeedFactor(1.0); // TK
if (winner == man1)
points1++;
if (winner == man2)
@ -418,9 +437,39 @@ void calculateFight(int framecount) {
dead = false;
endcounter = 0;
}
} else if (endcounter == 1) // ralenti au début de la mort
{
// Wythel
// arenaworld->setGravity(2.0);
if (man1->isBeheaded() &&
man1->getHead()->position[1] > ARENAHEIGHT / 2.0 - 2.0) {
man1->getMainObject()->setGravity(false);
man1->getHead()->setGravity(false);
beheaded = man1;
setSpeedFactor(0.0);
} else if (man2->isBeheaded() &&
man2->getHead()->position[1] > ARENAHEIGHT / 2.0 - 2.0) {
man2->getMainObject()->setGravity(false);
man2->getHead()->setGravity(false);
beheaded = man2;
setSpeedFactor(0.0);
} else {
setSpeedFactor(0.3);
}
} else if (endcounter == VICTORY / 4) {
setSpeedFactor(0.5);
} else if (endcounter == VICTORY / 2) {
setSpeedFactor(0.5); // au cas ou ca ait été modifié
man1->getMainObject()->setGravity(true);
man1->getHead()->setGravity(true);
man2->getMainObject()->setGravity(true);
man2->getHead()->setGravity(true);
}
if (dead)
if (dead) {
endcounter++;
}
if (trophycounter != -1) {
fightfade = (float)trophycounter / TROPHYFADE;
trophycounter++;
@ -433,13 +482,9 @@ void calculateFight(int framecount) {
float vel[3] = {randomf(2)-1, randomf(2)-1, randomf(2)-1};
createBlood(pos, vel);
}*/
// arenalight.setPosition(sin(framecount*0.01)*6, 3, cos(framecount*0.01)*4);
// light2.setPosition(sin(framecount*0.017)*6, 2, cos(framecount*0.027)*5);
// light3.setPosition(sin(framecount*0.023)*3, 4, cos(framecount*0.013)*3);
camera.setPosition(sin(framecount * 0.0005) * 20,
sin(framecount * 0.0013) * 5 + 15,
cos(framecount * 0.0005) * 20);
// camera.setPosition(8, 5, 5);
@ -462,8 +507,12 @@ void calculateFight(int framecount) {
man1->walk(-0.03);
if (keys[player1jump])
man1->jump();
if (keys[player1hit])
if (keys[player1hit]) {
man1->hit();
man1->hitcounter = 1;
} else {
man1->hitcounter = 0;
}
}
if (man2->isAlive()) {
@ -477,12 +526,17 @@ void calculateFight(int framecount) {
man2->walk(-0.03);
if (keys[player2jump])
man2->jump();
if (keys[player2hit])
if (keys[player2hit]) {
man2->hit();
man2->hitcounter = 1;
} else {
man2->hitcounter = 0;
}
}
}
if (keys[SDLK_ESCAPE]) {
setSpeedFactor(1.0);
stopGame();
}
@ -541,10 +595,10 @@ void drawFight(int framecount) {
drawDamageMeters();
flaretexture->enable();
light1.createFlare();
light2.createFlare();
light3.createFlare();
light4.createFlare();
light1.createFlare(&camera);
light2.createFlare(&camera);
light3.createFlare(&camera);
light4.createFlare(&camera);
flaretexture->disable();
enable2D();
@ -598,6 +652,39 @@ void drawFight(int framecount) {
glColor4f(0, 0, alpha, alpha);
print(x, y, "Victory!", size);
}
if (beheaded != NULL) {
/* camera.setAutoBeheaded(((Legoman *)beheaded)->getHead(),
(float)M_PI * (float)(rockcounter++ % 80) / 40.0);
if (rockcounter == 80)
{
beheaded = NULL;
setSpeedFactor(0.25);
}*/
if (rockcounter < 80) {
camera.setAutoBeheaded(((Legoman *)beheaded)->getHead(),
(float)M_PI * (float)(rockcounter++ % 80) /
40.0);
} else if (rockcounter == 80) {
setSpeedFactor(0.25);
rockcounter++;
} else {
// camera.setAutoNormal(((Legoman *)beheaded)->getHead(), ((Legoman
// *)beheaded)->getOpponent()->getMainObject(), true);
camera.setAutoFallHead(((Legoman *)beheaded)->getHead(),
((Legoman *)beheaded)->getMainObject());
}
} else if (manout != NULL) {
camera.setAutoCastOut(manout->getMainObject());
} else if (man1->isOutOfRing()) {
manout = man1;
} else if (man2->isOutOfRing()) {
manout = man2;
} else {
camera.setAutoNormal(man1->getMainObject(), man2->getMainObject(), true);
}
} else {
camera.setAutoNormal(man1->getMainObject(), man2->getMainObject(), false);
}
disable2D();

View File

@ -4,6 +4,10 @@
#include <SDL.h>
#include "audio.h"
#include "legoman.h"
#include "camera.h"
#define ARENASIZE 10
#define ARENAHEIGHT 10
extern Sound *fightmusic;
extern Sound *hitsound1;

168
src/fonct.cpp Normal file
View File

@ -0,0 +1,168 @@
#include "main.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_TIME_H
#include <time.h>
#else
#include "SDL.h"
#endif
#include "fonct.h"
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#undef MAX
#undef MIN
#undef SGN
#undef ABS
#undef CARRE
#define MAX(x, y) ((x > y) ? x : y)
#define MIN(x, y) ((x < y) ? x : y)
#define SGN(x) ((x > 0) ? 1 : ((x == 0) ? 0 : -1))
#define ABS(x) ((x >= 0) ? x : -x)
#define CARRE(x) (x * x)
int iabs(int val) { return ABS(val); }
double carre(double x)
/*retourne x²*/
{
return CARRE(x);
}
double dist2d(double x1, double y1, double x2, double y2)
/*calcule la distance entre (x1,y1) et (x2,y2)*/
{
return sqrt(carre(x2 - x1) + carre(y2 - y1));
}
double dist3d(double x1, double y1, double z1, double x2, double y2, double z2)
/*calcule la distance entre (x1,y1) et (x2,y2)*/
{
return sqrt(carre(x2 - x1) + carre(y2 - y1) + carre(z2 - z1));
}
double interpol_lin(double v00, double v10, double v01, double v11, double x,
double y)
/*effectue une interpolation linéaire entre les valeurs de 4 coins*/
{
double a, b;
a = v00 + (v01 - v00) * y;
b = v10 + (v11 - v10) * y;
return a + (b - a) * x;
}
int imax(int a, int b)
/*maximum de 2 entiers*/
{
return MAX(a, b);
}
int imin(int a, int b)
/*minimum de 2 entiers*/
{
return MIN(a, b);
}
float flmax(float a, float b)
/*maximum de 2 réels*/
{
return MAX(a, b);
}
float flmin(float a, float b)
/*minimum de 2 réels*/
{
return MIN(a, b);
}
double dmax(double a, double b)
/*maximum de 2 réels*/
{
return MAX(a, b);
}
double dmin(double a, double b)
/*minimum de 2 réels*/
{
return MIN(a, b);
}
/**************************************************************************/
/*effectue un range modulo mod à partir de base*/
/*la valeur finale se trouve dans [base..base+mod[ */
double modulo(double nb, double base, double mod) {
float temp = nb;
while (temp - base >= mod)
temp -= mod;
while (temp < base)
temp += mod;
return temp;
}
/*****************************************************************************/
/*angle fait par un point par rapport à l'angle de référence*/
double angle(double x, double y) {
double nx, ny, d, ret;
if (x == 0.0) {
if (y == 0.0) {
return 0.0;
} else {
return M_PI - (SGN(y) * M_PI / 2);
}
}
d = dist2d(0.0, 0.0, x, y);
nx = x / d;
ny = y / d;
ret = asin(ny);
if (nx < 0.0) {
ret = M_PI - ret;
}
return modulo(ret, 0.0, 2.0 * M_PI);
}
/***********************************************************************************/
/*convertit un entier en chaine formatée d'une certaine longueur completée par
* des 0*/
void format0(int num, char *st, int nbchar) {
int n = num;
int i;
for (i = 0; i < nbchar; i++) {
st[i] = 48 + (int)((float)n / pow(10, nbchar - i - 1));
n = n - (st[i] - 48) * (int)pow(10, nbchar - i - 1);
}
}
/*******************************************************************************/
/*initialise au mieux le générateur de nombres aléatoires*/
void rnd_init() {
#ifdef HAVE_TIME_H
srand((unsigned int)time(NULL));
#else
int i;
for (i = 0; i < 10000000; i++)
; /*pour grapiller des millisecondes aléatoires */
srand((unsigned int)SDL_GetTicks());
#endif
}
/*******************************************************************************/
/*génère un entier aléatoire entre base et base+range-1 inclus*/
int rnd(int base, int range) {
if (range == 0) {
return base;
}
return base + (rand() % range);
}

78
src/fonct.h Normal file
View File

@ -0,0 +1,78 @@
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#undef MAX
#undef MIN
#undef SGN
#undef ABS
#undef CARRE
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define SGN(x) (((x) > 0) ? 1 : (((x) == 0) ? 0 : -1))
#define ABS(x) (((x) >= 0) ? (x) : -(x))
#define CARRE(x) ((x) * (x))
#define RAD2DEG(x) ((unsigned int)((x)*180 / M_PI))
#define DEG2RAD(x) ((double)(x)*M_PI / 180.0)
/*retourne la valeur absolue entière de val*/
int iabs(int val);
double carre(double x);
/*retourne x²*/
double dist2d(double x1, double y1, double x2, double y2);
/*calcule la distance entre (x1,y1) et (x2,y2)*/
double dist3d(double x1, double y1, double z1, double x2, double y2, double z2);
/*calcule la distance entre (x1,y1) et (x2,y2)*/
double interpol_lin(double v00, double v10, double v01, double v11, double x,
double y);
/*effectue une interpolation linéaire entre les valeurs de 4 coins*/
int imax(int a, int b);
/*maximum de 2 entiers*/
int imin(int a, int b);
/*minimum de 2 entiers*/
float flmax(float a, float b);
/*maximum de 2 réels*/
float flmin(float a, float b);
/*minimum de 2 réels*/
double dmax(double a, double b);
/*maximum de 2 réels*/
double dmin(double a, double b);
/*minimum de 2 réels*/
/*effectue un range modulo mod à partir de base*/
/*la valeur finale se trouve dans [base..base+mod[ */
double modulo(double nb, double base, double mod);
/*angle fait par un point par rapport à l'angle de référence*/
double angle(double x, double y);
/*convertit un entier en chaine formatée d'une certaine longueur completée par
* des 0*/
void format0(int num, char *st, int nbchar);
/*initialise au mieux le générateur de nombres aléatoires*/
void rnd_init();
/*génère un nombre aléatoire entre base et base+range*/
int rnd(int base, int range);

View File

@ -2,6 +2,7 @@
#include "font.h"
#include "glapi.h"
#include <string.h>
Texture *fonttexture;
@ -62,7 +63,7 @@ void print(float x, float y, char *text, float size) {
float px = x;
float py = y;
for (i = 0; i < textlength; i++) {
char ch = text[i];
unsigned char ch = text[i];
if (ch == '\n') {
px = x;
py += size * 1.2;

View File

@ -58,5 +58,7 @@ void setupOpengl(int width, int height) {
gluPerspective(60.0, ratio, 1.0, 1024.0);
glColorMask(true, true, true, true);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}

View File

@ -312,7 +312,7 @@ void FlowerAppearance::prepare(void) {
glRotatef(90, 1, 0, 0);
glTranslatef(0, BLOCKHEIGHT * (3 + i * 0.7), 0);
float r, g, b;
float r = 0.0, g = 0.0, b = 0.0;
switch (colors[i]) {
case FLOWER_RED:
r = 1.0;

View File

@ -13,6 +13,7 @@
#include "utils.h"
#include "particle.h"
#include "fight.h"
#include "fonct.h"
#include "glapi.h"
BodyPart::BodyPart(Legoman *parent, float strength) {
@ -29,6 +30,8 @@ void BodyPart::reset(void) {
vectorSet(momentum, 0, 0, 0);
matrixIdentity(rotation);
vectorSet(angularmomentum, 0, 0, 0);
vectorSet(velocity, 0, 0, 0);
vectorSet(angularvelocity, 0, 0, 0);
}
void BodyPart::move(void) {
@ -87,6 +90,25 @@ void BodyPart::makeDamage(float amount) {
immortal = 30;
}
bool BodyPart::isInContact() {
if (!isAttached())
return false;
Object *obj = (Object *)this;
int collgroup = obj->getCollisionGroup();
for (int i = 0; i < contactcount; i++) {
if (contacts[i].object1 == obj) {
if (contacts[i].object2->getCollisionGroup() != collgroup)
return true;
} else if (contacts[i].object2 == obj) {
if (contacts[i].object1->getCollisionGroup() != collgroup)
return true;
}
}
return false;
}
Sensor::Sensor() {}
void Sensor::attach(Object *object, float *relativeposition) {
@ -138,7 +160,7 @@ float leftLegOffset[3] = {0.1, 0.4, 0.0};
Legoman::Legoman(int side) {
this->side = side;
int collisiongroup, collisiongrouphand;
int collisiongroup = 0, collisiongrouphand = 0;
if (side == PLAYER1) {
collisiongroup = COLLISIONGROUP_MAN1;
collisiongrouphand = COLLISIONGROUP_MAN1HAND;
@ -161,11 +183,11 @@ Legoman::Legoman(int side) {
// Legs
Mesh *geomLegMesh = createBox(-0.45, 0.45, -BLOCKHEIGHT * LEGHEIGHT / 2.0,
BLOCKHEIGHT * LEGHEIGHT / 2.0, -0.5, 0.5);
float tmpScale = 1.0;
// UNUSED//float tmpScale = 1.0;
// Left leg
{
leftleg = new BodyPart(this, 8);
leftleg = new BodyPart(this, 3);
Mesh *leftLegMesh =
loadAscModel((char *)LEFTLEGASC, MODELSCALE, leftLegOffset);
MeshShape *leftLegGeom = new MeshShape(leftleg, geomLegMesh);
@ -182,7 +204,7 @@ Legoman::Legoman(int side) {
// Right leg
{
rightleg = new BodyPart(this, 8);
rightleg = new BodyPart(this, 3);
Mesh *rightLegMesh =
loadAscModel((char *)RIGHTLEGASC, MODELSCALE, rightLegOffset);
MeshShape *rightLegGeom = new MeshShape(rightleg, geomLegMesh);
@ -219,7 +241,7 @@ Legoman::Legoman(int side) {
// Torso
{
torso = new BodyPart(this, 4);
torso = new BodyPart(this, 3);
Mesh *torsoMesh = loadAscModel((char *)TORSOASC, TORSOSCALE);
// int i;
// for (i = 0; i < torsoMesh->polygoncount; i++)
@ -248,7 +270,7 @@ Legoman::Legoman(int side) {
// Left hand
{
lefthand = new BodyPart(this, 5);
lefthand = new BodyPart(this, 2);
Mesh *leftHandMesh =
loadAscModel((char *)LEFTARMASC, MODELSCALE, leftHandOffset);
@ -277,7 +299,7 @@ Legoman::Legoman(int side) {
// Right hand
{
righthand = new BodyPart(this, 5);
righthand = new BodyPart(this, 2);
Mesh *rightHandMesh =
loadAscModel((char *)RIGHTARMASC, MODELSCALE, rightHandOffset);
Mesh *rightPalmMesh =
@ -494,6 +516,9 @@ void Legoman::heal(void) {
(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT / 2 + 0.5),
0);
walkphase = 0;
jumpphase = 0;
headsensor->attach(head);
torsosensor->attach(torso);
@ -657,12 +682,19 @@ void Legoman::update(void) {
}
/*if (jumpphase > 0){
jumpphase--;
jumpphase--;
}*/
if (torso->momentum[1] < 0 && isOnGround()) {
// if (torso->momentum[1] < 0 && isOnGround()){
// if (torso->momentum[1] < 0 && (isStanding() || isOnGround())){
if (leftleg->isInContact() || rightleg->isInContact() ||
(torso->momentum[1] < 0 && isOnGround())) {
jumpphase--;
if (jumpphase == 0)
if (jumpphase == 0) {
jumpenabled = true;
leftleg->setGravity(true);
rightleg->setGravity(true);
}
}
if (hitside < 10)
@ -690,7 +722,7 @@ void Legoman::updateLegs(void) {
float temp[3];
float angle;
walkphase = sfmod(walkphase, PI / LEGSPEED);
walkphase = (int)sfmod(walkphase, PI / LEGSPEED);
// Left leg
angle = sfmod(walkphase * LEGSPEED, PI);
@ -722,10 +754,17 @@ void Legoman::walk(float amount) {
else
sign = -1;
walkphase += sign;
walkphase += (int)sign;
updateLegs();
if (hitcounter && (jumpphase > 0)) {
float axis[3];
vectorScale(axis, &torso->rotation[0], -100.0 * amount);
vectorAdd(torso->angularmomentum, axis);
vectorSaturate(torso->angularmomentum, 0.0, 18.0);
}
if (!isStanding())
return;
@ -750,7 +789,8 @@ void Legoman::walk(float amount) {
vectorScale(xmove, 0.5);
float wh = waist->position[1];
if (wh < WAISTHEIGHT + 1.0) {
if (wh < WAISTHEIGHT + 1.0 &&
(!isOutOfRing() || leftleg->isInContact() || rightleg->isInContact())) {
float hd = WAISTHEIGHT + 1.0 - wh;
vectorScale(ymove, ydir, hd * 10);
}
@ -767,90 +807,104 @@ void Legoman::walk(float amount) {
vectorAdd(movement, ymove);
vectorAdd(movement, zmove);
// if (isStanding() && isOnGround())
// if (!isOnGround() || isOutOfRing()) return;
vectorCopy(torso->momentum, movement);
vectorScale(movement, torso->invmass * waist->getMass());
vectorCopy(waist->momentum, movement);
/*float speed = vectorDot(oldmomentum, movement);
float speedadd = 1;
float maxspeed = 5;
/*speed += speedadd;
if (speed > maxspeed) speed = maxspeed;
if (speed + speedadd > maxspeed){
speedadd = maxspeed - speed;
}
// TK: pour conserver le moment éventuel d'un saut
torso->momentum[1] = MAX(oldmomentum[1], torso->momentum[1]);
vectorScale(movement, speedadd);
if (waist->position[1] < WAISTHEIGHT + 1.0){
movement[1] = 3;
}
vectorAdd(torso->momentum, movement);*/
// Wythel pour faire des saltos
/* if (jumpphase == 2 && hitcounter){
float axis[3];
vectorScale(axis, &torso->rotation[0], amount*-500);
vectorAdd(torso->angularmomentum, axis);
}*/
/*float proj[3];
vectorProject(proj, oldmomentum, movement);
float len = vectorLength(proj);
vectorAdd(movement, proj);
vectorSaturate(movement, 0,
#if 0
float speed = vectorDot(oldmomentum, movement);
float speedadd = 1;
float maxspeed = 5;
/*speed += speedadd;
if (speed > maxspeed) speed = maxspeed;
if (speed + speedadd > maxspeed){
speedadd = maxspeed - speed;
}
movement[1] = 300;
//torso->addExternalForce(movement);
}*/
vectorScale(movement, speedadd);
if (waist->position[1] < WAISTHEIGHT + 1.0){
movement[1] = 3;
}
vectorAdd(torso->momentum, movement);*/
/*float linkpoint[3];
vectorScale(linkpoint, &leftleg->rotation[3], -1);
vectorAdd(linkpoint, leftleg->position);*/
/*float proj[3];
vectorProject(proj, oldmomentum, movement);
float len = vectorLength(proj);
vectorAdd(movement, proj);
vectorSaturate(movement, 0,
movement[1] = 300;
//torso->addExternalForce(movement);
}*/
/*float linkpoint[3];
vectorScale(linkpoint, &leftleg->rotation[3], -1);
vectorAdd(linkpoint, leftleg->position);*/
/*float movement[3];
float temp[3];
vectorScale(temp, &torso->rotation[3], amount*0.1);
vectorScale(movement, &torso->rotation[6], amount);
vectorAdd(movement, temp);
/*float movement[3];
float temp[3];
vectorScale(temp, &torso->rotation[3], amount*0.1);
vectorScale(movement, &torso->rotation[6], amount);
vectorAdd(movement, temp);
if (walkphase == 0){
walkphase = 40;
vectorAdd(leftleg->momentum, movement);
}
if (walkphase == 20){
walkphase = 19;
vectorAdd(rightleg->momentum, movement);
}*/
if (walkphase == 0){
walkphase = 40;
vectorAdd(leftleg->momentum, movement);
}
if (walkphase == 20){
walkphase = 19;
vectorAdd(rightleg->momentum, movement);
}*/
/*float axis[3];
vectorScale(axis, &leftleg->rotation[0], amount);
/*float axis[3];
vectorScale(axis, &leftleg->rotation[0], amount);
if (walkphase == 0){
//walkphase = 40;
vectorAdd(leftleg->angularmomentum, axis);
vectorAdd(rightleg->angularmomentum, axis);
}*/
/*if (walkphase == 0){
walkphase = 1;
vectorAdd(rightleg->momentum, movement);
}*/
/*float axis[3];
float movement[3];
if (walkphase == 0){
//walkphase = 40;
vectorAdd(leftleg->angularmomentum, axis);
vectorAdd(rightleg->angularmomentum, axis);
}*/
/*if (walkphase == 0){
walkphase = 1;
vectorAdd(rightleg->momentum, movement);
}*/
/*float axis[3];
float movement[3];
if (walkphase == 0){
unlockPart(LEFTLEG);
if (walkphase == 0){
unlockPart(LEFTLEG);
vectorScale(axis, &leftleg->rotation[0], 5);
vectorAdd(leftleg->angularmomentum, axis);
vectorScale(axis, &leftleg->rotation[0], 5);
vectorAdd(leftleg->angularmomentum, axis);
float temp[3];
vectorScale(temp, &torso->rotation[6], -10);
vectorScale(movement, &torso->rotation[3], 5);
vectorAdd(movement, temp);
vectorAdd(torso->momentum, movement);
vectorAdd(leftleg->momentum, movement);
float temp[3];
vectorScale(temp, &torso->rotation[6], -10);
vectorScale(movement, &torso->rotation[3], 5);
vectorAdd(movement, temp);
vectorAdd(torso->momentum, movement);
vectorAdd(leftleg->momentum, movement);
walkphase = 40;
}*/
walkphase = 40;
}*/
#endif
}
void Legoman::turn(float amount) {
float axis[3];
if (isStanding()) {
vectorScale(axis, &torso->rotation[3], amount);
vectorCopy(torso->angularmomentum, axis);
@ -858,6 +912,13 @@ void Legoman::turn(float amount) {
vectorScale(axis, &torso->rotation[3], amount * 0.3);
vectorAdd(torso->angularmomentum, axis);
}
if (hitcounter && (jumpphase == 2)) {
vectorScale(axis, &torso->rotation[6], amount * 2.0);
vectorAdd(torso->angularmomentum, axis);
}
vectorSaturate(torso->angularmomentum, 0.0, 18.0);
}
void Legoman::hit(void) {
@ -883,10 +944,15 @@ void Legoman::hit(void) {
float axis[3];
if (hitside & 1) {
vectorScale(axis, &lefthand->rotation[0], 20);
// vectorScale(axis, &lefthand->rotation[0], 20.0);
// du bras à l'horizontal
vectorScale(axis, &lefthand->rotation[0],
20.0 / (1 + 3.0 * fabs(lefthand->rotation[1])));
vectorCopy(lefthand->angularmomentum, axis);
} else {
vectorScale(axis, &righthand->rotation[0], 20);
// vectorScale(axis, &righthand->rotation[0], 20.0);
vectorScale(axis, &righthand->rotation[0],
20.0 / (1 + 3.0 * fabs(righthand->rotation[1])));
vectorCopy(righthand->angularmomentum, axis);
}
}
@ -894,20 +960,49 @@ void Legoman::hit(void) {
void Legoman::jump(void) {
if (!leftleg->attached && !rightleg->attached)
return;
if (jumpenabled) { // == 0 && isOnGround()){
if (jumpenabled &&
(!isOutOfRing() || leftleg->isInContact() || rightleg->isInContact())) {
float r = BLOCKHEIGHT * HEADHEIGHT / 2;
float strength = (2 * LEGHEIGHT + 2 * WAISTHEIGHT + 2 * TORSOHEIGHT +
2 * HANDHEIGHT + 4.0 * PI * r * r * r) /
3.0 * getInvMass();
float jumpvector[3] = {0, 100.0 / strength, 0};
// vectorCopy(torso->momentum, jumpvector);
torso->momentum[1] = jumpvector[1];
head->momentum[1] = 0; // jumpvector[1];
waist->momentum[1] = 0; // jumpvector[1];
leftleg->momentum[1] = 0; // jumpvector[1];
rightleg->momentum[1] = 0; // jumpvector[1];
lefthand->momentum[1] = 0; // jumpvector[1];
jumpvector[0] =
3.0 * ((float)opponent->torso->position[0] - (float)torso->position[0]);
jumpvector[2] =
3.0 * ((float)opponent->torso->position[2] - (float)torso->position[2]);
if (hitcounter) {
jumpvector[0] *= 3.0;
jumpvector[2] *= 3.0;
if (!isOnGround()) {
jumpvector[1] =
((float)opponent->torso->position[1] - (float)torso->position[1]);
}
// leftleg->setGravity(false);
// rightleg->setGravity(false);
}
//#if 0
if ((!isOnGround()) && ((torso->position[0] < -(float)ARENASIZE + 1.0) ||
(torso->position[0] > (float)ARENASIZE - 1.0) ||
(torso->position[2] < -(float)ARENASIZE + 1.0) ||
(torso->position[2] > (float)ARENASIZE - 1.0))) {
// le blocko est à peu près sur le rebord, on autorise le jump du dernier
// recours
jumpvector[0] += -5.0 * (float)torso->position[0];
jumpvector[2] += -5.0 * (float)torso->position[2];
}
//#endif
vectorCopy(torso->momentum, jumpvector);
// torso->momentum[1] = jumpvector[1];
head->momentum[1] = 0; // jumpvector[1];
waist->momentum[1] = 0; // jumpvector[1];
leftleg->momentum[1] = 0; // jumpvector[1];
rightleg->momentum[1] = 0; // jumpvector[1];
lefthand->momentum[1] = 0; // jumpvector[1];
righthand->momentum[1] = 0; // jumpvector[1];
// vectorSet(head->momentum, 0, 0, 0);
// jumpphase = 150;
@ -926,7 +1021,14 @@ bool Legoman::isOnGround(void) {
return false;
// if (fabs(head->momentum[1]) > 10) return false;
// if (fabs(waist->momentum[1]) > 3) return false;
return true;
return not isOutOfRing();
}
bool Legoman::isOutOfRing(void) {
return ((torso->position[0] < -(float)ARENASIZE - 0.5) ||
(torso->position[0] > (float)ARENASIZE + 0.5) ||
(torso->position[2] < -(float)ARENASIZE - 0.5) ||
(torso->position[2] > (float)ARENASIZE + 0.5));
}
bool Legoman::isStanding(void) {

View File

@ -45,9 +45,13 @@ private:
int immortal;
bool isInContact();
public:
BodyPart(Legoman *parent, float strength);
inline bool isAttached() { return attached; }
void move(void);
void hitForce(float speed, float *speed2, Object *source);
@ -117,7 +121,6 @@ private:
int hitside;
bool jumpenabled;
int hitcounter;
World *world;
@ -134,6 +137,12 @@ private:
public:
Legoman(int side);
inline Object *getMainObject() { return (Object *)torso; }
inline Object *getHead() { return (Object *)head; }
inline bool isBeheaded() { return not(Object *)head->isAttached(); }
bool isOutOfRing(void); // TK
void insertToWorld(World *world);
void heal(void);
@ -161,6 +170,7 @@ public:
bool isAlive(void);
Legoman *getOpponent(void);
int hitcounter;
void drawVisuals();

View File

@ -69,9 +69,9 @@ void Light::setEnabled(bool enabled) {
void Light::glUpdate(void) { glLightfv(glnum, GL_POSITION, position); }
extern Camera camera;
// extern Camera camera;
void Light::createFlare(void) {
void Light::createFlare(Camera *camera) {
glPushMatrix();
GLint viewport[4];
@ -94,8 +94,8 @@ void Light::createFlare(void) {
cz/=len;*/
float dir[3];
float cameratarget[3], cameraposition[3];
camera.getTarget(cameratarget);
camera.getPosition(cameraposition);
camera->getTarget(cameratarget);
camera->getPosition(cameraposition);
vectorSub(dir, cameratarget, cameraposition);
vectorNormalize(dir);

View File

@ -1,6 +1,8 @@
#ifndef __LIGHT_H_INCLUDED__
#define __LIGHT_H_INCLUDED__
#include "camera.h"
class Light {
private:
float position[4];
@ -21,7 +23,7 @@ public:
void setAttenuation(float constant, float linear, float quadratic);
void setEnabled(bool enabled);
void glUpdate(void);
void createFlare(void);
void createFlare(Camera *camera);
};
void updateLights(void);

View File

@ -8,6 +8,7 @@
#endif
#include "audio.h"
#include "fonct.h"
#include "run.h"
#include "texture.h"
#include "fight.h"
@ -18,7 +19,15 @@
int screenwidth = 1024;
int screenheight = 768;
int screenbpp;
int screenbpp = 32;
// static float speedfactor = 1.0;
#define FRAMESNEEDED_DEFAULT 6
static int framesneeded = FRAMESNEEDED_DEFAULT;
#define FPS 30
#define FPS_RELEASETIME (1000 / FPS)
void exitProgram(int code) {
SDL_Quit();
@ -78,11 +87,15 @@ void processEvents(void) {
}
int getTime(void) {
#ifdef WIN32
return timeGetTime();
#else
//#ifdef WIN32
// return timeGetTime();
//#else
return SDL_GetTicks();
#endif
//#endif
}
void setSpeedFactor(float factor) {
framesneeded = (int)(factor * FRAMESNEEDED_DEFAULT);
}
int main(int argc, char *argv[]) {
@ -111,30 +124,82 @@ int main(int argc, char *argv[]) {
initAudio();
changeResolution(screenwidth, screenheight, false);
changeResolution(1024, 768, false);
// printf("SDL initialized.\n");
double calculatefps = 200.0;
int framecounter, oldframecounter = 0;
int currenttime;
int framesdrawn = 0;
int skipframes;
/*double calculatefps = 200.0;
const int maxskipframes = 20;
int framecounter, absframecounter = 0;
int currenttime;
int framesdrawn=0;
int skipframes;
int starttime = getTime();
while (1){
do{
currenttime = getTime()-starttime;
} while (currenttime == 0);
framecounter = (int)((calculatefps/1000.0)*currenttime*speedfactor);
starttime = getTime();
skipframes = framecounter;
//ajustement de la vitesse pour ne pas accumuler le retard de frames
if (skipframes > maxskipframes)
{
if (calculatefps > 200.0)
{
calculatefps -= 20;
//printf("%f\n", calculatefps);
}
}
else
{
if (calculatefps < 200.0)
{
calculatefps += 20;
//printf("%f\n", calculatefps);
}
}
for (; skipframes > 0; skipframes--){
calculateFrame(++absframecounter);
}
//calculateFrame(absframecounter++);
processEvents();
drawFrame(absframecounter);
framesdrawn++;
}*/
unsigned int absframecounter = 0;
int i;
int currenttime;
int framesdrawn = 0;
while (1) {
do {
currenttime = getTime() - starttime;
framecounter = calculatefps * currenttime / 1000.0;
} while (oldframecounter == framecounter);
skipframes = framecounter - oldframecounter;
for (; skipframes > 0; skipframes--) {
calculateFrame(++oldframecounter);
currenttime = getTime();
// on calcule les frames physiques
for (i = 0; i < framesneeded; i++) {
calculateFrame(absframecounter++);
}
// calculateFrame(oldframecounter++);
// on applique les évènements
processEvents();
drawFrame(framecounter);
// on trace l'image associée à la dernière frame physique
drawFrame(absframecounter);
framesdrawn++;
// on attend que le temps autorisé pour la frame graphique soit dépassé
while (getTime() - currenttime < FPS_RELEASETIME) {
}
}
return 0;
}

View File

@ -8,7 +8,21 @@
disable : 4305) // Disable: truncation from 'const double' to 'double'
#endif
#include <SDL.h>
#include "SDL.h"
#ifdef DEBUG
#define _DEBUG
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#define HAVE_TIME_H
#ifdef WIN32
#define VERSION "W32"
#define HAVE_FMOD_H
#endif
#endif
#define DATAPATH "data/"
extern bool keys[SDLK_LAST];
@ -17,6 +31,8 @@ void exitProgram(int code);
void changeResolution(int width, int height, bool fullscreen);
extern int screenwidth, screenheight;
void setSpeedFactor(float factor);
extern int debugcounter;
#ifdef DEBUG
#define DP \

View File

@ -213,7 +213,7 @@ int rletter[5][4] = {
float z = 0.5;
int i, j;
int dx = -15;
int dy = BLOCKHEIGHT * (4 * 3 + 1);
int dy = (int)(BLOCKHEIGHT * (4 * 3 + 1));
int dz = -5;
for (i = 0; i < LETTERCOUNT; i++) {
int size = lettersizes[i];
@ -277,7 +277,7 @@ int rletter[5][4] = {
changesound = new Sound(DATAPATH "menuchange.wav");
selectsound = new Sound(DATAPATH "menuselect.wav");
menumusic = new Sound(DATAPATH "menu.mp3", true);
menumusic = new Sound(DATAPATH "menu.ogg", true);
}
titleworld->prepare();
@ -311,15 +311,16 @@ int oldresolution;
int resolution = 2;
bool fullscreen = false;
int olddetail;
int detail = 2;
int detail = 3;
#define RESOLUTIONCOUNT 6
#define RESOLUTIONCOUNT 7
int resolutions[RESOLUTIONCOUNT][2] = {{640, 480},
{800, 600},
{1024, 768},
{1280, 960},
{1280, 1024},
{1600, 1200}};
{1600, 1200},
{1920, 1080}};
#define DETAILCOUNT 4
char *details[DETAILCOUNT] = {"Off", "Low", "Medium", "High"};
@ -435,6 +436,9 @@ void calculateMenu(int framecount) {
cos(framecount * 0.001) * 2 + 25);
titlecamera.setTarget(cameratarget);
// titlelight.setPosition(sin(framecount*0.01)*5-4, sin(framecount*0.017)*5+5,
// cos(framecount*0.01)*5+5);
titleworld->move();
xres = resolutions[resolution][0];
@ -605,7 +609,7 @@ void drawMenu(int framecount) {
titleworld->draw();
flaretexture->enable();
titlelight.createFlare();
titlelight.createFlare(&titlecamera);
flaretexture->disable();
/*//2D-view
@ -622,7 +626,7 @@ void drawMenu(int framecount) {
enable2D();
glColor3f(1, 1, 1);
print(0.73, 0.55, "Programming:\n"
print(0.73, 0.58, "Programming:\n"
" Miika Sell\n"
" Juha Kaarlas\n"
"\n"
@ -636,7 +640,7 @@ void drawMenu(int framecount) {
print(0.35, 0.965, "http://blockofighter.kicks-ass.net/", 0.02);
print(0.88, 0.96, "Version 2.0", 0.02);
print(0.86, 0.96, "Version 2.0", 0.02);
tuxtexture->enable();
glEnable(GL_BLEND);
@ -663,7 +667,7 @@ void drawMenu(int framecount) {
tuxtexture->disable();
glColor3f(1, 1, 1);
print(0.88, 0.12, "supported", 0.02);
print(0.88, 0.12, "powaaaaaa", 0.02);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

View File

@ -234,9 +234,9 @@ Mesh *loadAscModel(char *filename, float scale, float *offset) {
fread(data, size, 1, file);
fclose(file);
char *vert = findStringEnd(data, "Vertices:");
target->vertexcount = getValueFromString(vert);
target->vertexcount = (int)getValueFromString(vert);
char *face = findStringEnd(data, "Faces:");
target->polygoncount = getValueFromString(face);
target->polygoncount = (int)getValueFromString(face);
target->vertices = new Vertex[target->vertexcount];
target->polygons = new class Polygon[target->polygoncount];
@ -267,7 +267,7 @@ Mesh *loadAscModel(char *filename, float scale, float *offset) {
for (i = 0; i < target->polygoncount; i++) {
face = findStringEnd(face, "Face");
face = findStringEnd(face, "A:");
vnum = getValueFromString(face);
vnum = (int)getValueFromString(face);
target->polygons[i].vertexcount = 3;
target->polygons[i].vertices = new Vertex *[3];
target->polygons[i].vertices[0] = &(target->vertices[vnum]);
@ -275,13 +275,13 @@ Mesh *loadAscModel(char *filename, float scale, float *offset) {
target->vertices[vnum].texcoords[0],
target->vertices[vnum].texcoords[1]);
face = findStringEnd(face, "B:");
vnum = getValueFromString(face);
vnum = (int)getValueFromString(face);
target->polygons[i].vertices[1] = &(target->vertices[vnum]);
target->polygons[i].vertices[1]->setTexCoords(
target->vertices[vnum].texcoords[0],
target->vertices[vnum].texcoords[1]);
face = findStringEnd(face, "C:");
vnum = getValueFromString(face);
vnum = (int)getValueFromString(face);
target->polygons[i].vertices[2] = &(target->vertices[vnum]);
target->polygons[i].vertices[2]->setTexCoords(
target->vertices[vnum].texcoords[0],

View File

@ -37,7 +37,7 @@ void Particle::move(void) {
int i;
vectorSet(contact->normal, 0, 1, 0);
contact->object2 = NULL;
bool die = false;
// UNUSED//bool die = false;
for (i = 0; i < mesh->vertexcount; i++) {
float point[3];
transformPoint(point, mesh->vertices[i].position);
@ -150,3 +150,9 @@ void removeBlood(int id) {
bloodparticles[bloodcount - 1] = particle;
bloodcount--;
}
void removeAllBlood() {
while (bloodcount > 0) {
removeBlood(0);
}
}

View File

@ -46,5 +46,6 @@ public:
void initBloods(World *world);
void createBlood(float *position, float *velocity);
void removeBlood(int id);
void removeAllBlood();
#endif

View File

@ -5,6 +5,7 @@
#include "run.h"
#include "fight.h"
#include "menu.h"
#include "camera.h"
#include "end.h"
#include "graphics.h"
#include "3dutils.h"
@ -74,7 +75,7 @@ void drawFrame(int framecount) {
if (changed)
calculateFrame(framecount);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);*/
glMatrixMode(GL_MODELVIEW);
@ -86,6 +87,7 @@ void drawFrame(int framecount) {
drawFight(framecount);
break;
case ENDMODE:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawEnd(framecount);
break;
}

129
src/windows.h Normal file
View File

@ -0,0 +1,129 @@
/*
windows.h - main header file for the Win32 API
Written by Anders Norlander <anorland@hem2.passagen.se>
This file is part of a free library for the Win32 API.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _WINDOWS_H
#define _WINDOWS_H
#if __GNUC__ >= 3
#pragma GCC system_header
#endif
/* translate GCC target defines to MS equivalents. Keep this synchronized
with winnt.h. */
#if defined(__i686__) && !defined(_M_IX86)
#define _M_IX86 600
#elif defined(__i586__) && !defined(_M_IX86)
#define _M_IX86 500
#elif defined(__i486__) && !defined(_M_IX86)
#define _M_IX86 400
#elif defined(__i386__) && !defined(_M_IX86)
#define _M_IX86 300
#endif
#if defined(_M_IX86) && !defined(_X86_)
#define _X86_
#elif defined(_M_ALPHA) && !defined(_ALPHA_)
#define _ALPHA_
#elif defined(_M_PPC) && !defined(_PPC_)
#define _PPC_
#elif defined(_M_MRX000) && !defined(_MIPS_)
#define _MIPS_
#elif defined(_M_M68K) && !defined(_68K_)
#define _68K_
#endif
#ifdef RC_INVOKED
/* winresrc.h includes the necessary headers */
#include <winresrc.h>
#else
#include <stdarg.h>
#include <windef.h>
#include <wincon.h>
#include <winbase.h>
#if !(defined NOGDI || defined _WINGDI_H)
#include <wingdi.h>
#endif
#ifndef _WINUSER_H
#include <winuser.h>
#endif
#ifndef _WINNLS_H
#include <winnls.h>
#endif
#ifndef _WINVER_H
#include <winver.h>
#endif
#ifndef _WINNETWK_H
#include <winnetwk.h>
#endif
#ifndef _WINREG_H
#include <winreg.h>
#endif
#ifndef _WINSVC_H
#include <winsvc.h>
#endif
#ifndef WIN32_LEAN_AND_MEAN
#include <cderr.h>
#include <dde.h>
#include <ddeml.h>
#include <dlgs.h>
#include <imm.h>
#include <lzexpand.h>
#include <mmsystem.h>
#include <nb30.h>
#include <rpc.h>
#include <shellapi.h>
#include <winperf.h>
#ifndef NOGDI
#include <commdlg.h>
#include <winspool.h>
#endif
#if defined(Win32_Winsock)
#warning "The Win32_Winsock macro name is deprecated.\
Please use __USE_W32_SOCKETS instead"
#ifndef __USE_W32_SOCKETS
#define __USE_W32_SOCKETS
#endif
#endif
#if defined(__USE_W32_SOCKETS) || \
!(defined(__CYGWIN__) || defined(__MSYS__) || defined(_UWIN))
#if (_WIN32_WINNT >= 0x0400)
#include <winsock2.h>
/*
* MS likes to include mswsock.h here as well,
* but that can cause undefined symbols if
* winsock2.h is included before windows.h
*/
#else
#include <winsock.h>
#endif /* (_WIN32_WINNT >= 0x0400) */
#endif
#ifndef NOGDI
#if !defined(__OBJC__)
#if (__GNUC__ >= 3) || defined(__WATCOMC__)
#include <ole2.h>
#endif
#endif /* __OBJC__ */
#endif
#endif /* WIN32_LEAN_AND_MEAN */
#endif /* RC_INVOKED */
#ifdef __OBJC__
/* FIXME: Not undefining BOOL here causes all BOOLs to be WINBOOL (int),
but undefining it causes trouble as well if a file is included after
windows.h
*/
#undef BOOL
#endif
#endif

View File

@ -4,6 +4,8 @@
#include "collision.h"
#include "vector.h"
float GRAVITY = 9.81;
World::World(void) {
childlist = NULL;
linklist = NULL;
@ -35,8 +37,9 @@ void World::prepare(void) {
contacts = new Contact[MAXCONTACTS]; // childcount*childcount];
}
#define GRAVITY 9.81
//#define GRAVITY 15
//#define GRAVITY 1
void World::setGravity(float grav) { GRAVITY = grav; };
void World::move(void) {
int i, j;

View File

@ -37,6 +37,8 @@ private:
public:
World(void);
void setGravity(float grav);
void prepare(void);
void move(void);
void draw(void);