diff --git a/Makefile b/Makefile index fa60bdf..1c20601 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/data/fight.mp3 b/data/fight.mp3 deleted file mode 100644 index 03f1cde..0000000 Binary files a/data/fight.mp3 and /dev/null differ diff --git a/data/fight.ogg b/data/fight.ogg new file mode 100644 index 0000000..b80b752 Binary files /dev/null and b/data/fight.ogg differ diff --git a/data/menu.mp3 b/data/menu.mp3 deleted file mode 100644 index 92a901e..0000000 Binary files a/data/menu.mp3 and /dev/null differ diff --git a/data/menu.ogg b/data/menu.ogg new file mode 100644 index 0000000..cd005f2 Binary files /dev/null and b/data/menu.ogg differ diff --git a/data/tback.png b/data/tback.png index 291c82d..3aa6584 100644 Binary files a/data/tback.png and b/data/tback.png differ diff --git a/data/tbottom.png b/data/tbottom.png index 95308db..5ce7a48 100644 Binary files a/data/tbottom.png and b/data/tbottom.png differ diff --git a/data/tfront.png b/data/tfront.png index 3983266..f1c754d 100644 Binary files a/data/tfront.png and b/data/tfront.png differ diff --git a/data/tleft.png b/data/tleft.png index 78a451c..e622c7a 100644 Binary files a/data/tleft.png and b/data/tleft.png differ diff --git a/data/tright.png b/data/tright.png index 5e18475..6008225 100644 Binary files a/data/tright.png and b/data/tright.png differ diff --git a/data/ttop.png b/data/ttop.png index 0a0257b..3b168e2 100644 Binary files a/data/ttop.png and b/data/ttop.png differ diff --git a/src/3dutils.cpp b/src/3dutils.cpp index 9599b0f..3922475 100644 --- a/src/3dutils.cpp +++ b/src/3dutils.cpp @@ -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) { diff --git a/src/audio.cpp b/src/audio.cpp index b505df5..623b0c3 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -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; diff --git a/src/camera.cpp b/src/camera.cpp index 1540bed..527b4be 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -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); } diff --git a/src/camera.h b/src/camera.h index c9143ed..3a066e6 100644 --- a/src/camera.h +++ b/src/camera.h @@ -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); diff --git a/src/collision.cpp b/src/collision.cpp index 1aa58f9..225a36f 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -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); diff --git a/src/collision.h b/src/collision.h index ef80b99..19f4336 100644 --- a/src/collision.h +++ b/src/collision.h @@ -2,8 +2,7 @@ #define __COLLISION_H_INCLUDED__ #include "mesh.h" - -class ObjectLink; +#include "world.h" #define COLLISIONGROUP_NONE 0 #define COLLISIONGROUP_ARENA 1 diff --git a/src/fight.cpp b/src/fight.cpp index 50f0718..83a1d84 100644 --- a/src/fight.cpp +++ b/src/fight.cpp @@ -1,5 +1,6 @@ #include "main.h" +#include #include #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(); diff --git a/src/fight.h b/src/fight.h index a1e27e3..0f52caa 100644 --- a/src/fight.h +++ b/src/fight.h @@ -4,6 +4,10 @@ #include #include "audio.h" #include "legoman.h" +#include "camera.h" + +#define ARENASIZE 10 +#define ARENAHEIGHT 10 extern Sound *fightmusic; extern Sound *hitsound1; diff --git a/src/fonct.cpp b/src/fonct.cpp new file mode 100644 index 0000000..6db2c73 --- /dev/null +++ b/src/fonct.cpp @@ -0,0 +1,168 @@ +#include "main.h" + +#include +#include + +#ifdef HAVE_TIME_H +#include +#else +#include "SDL.h" +#endif + +#include "fonct.h" +#include + +#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); +} diff --git a/src/fonct.h b/src/fonct.h new file mode 100644 index 0000000..e83e020 --- /dev/null +++ b/src/fonct.h @@ -0,0 +1,78 @@ +#include + +#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); diff --git a/src/font.cpp b/src/font.cpp index 849997c..911c630 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -2,6 +2,7 @@ #include "font.h" #include "glapi.h" +#include 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; diff --git a/src/glapi.cpp b/src/glapi.cpp index a99530a..16d075c 100644 --- a/src/glapi.cpp +++ b/src/glapi.cpp @@ -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); } diff --git a/src/legoblocks.cpp b/src/legoblocks.cpp index dc328d9..88e13d8 100644 --- a/src/legoblocks.cpp +++ b/src/legoblocks.cpp @@ -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; diff --git a/src/legoman.cpp b/src/legoman.cpp index a837231..0e52dbd 100644 --- a/src/legoman.cpp +++ b/src/legoman.cpp @@ -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) { diff --git a/src/legoman.h b/src/legoman.h index f2d7d0f..118b9b8 100644 --- a/src/legoman.h +++ b/src/legoman.h @@ -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(); diff --git a/src/light.cpp b/src/light.cpp index 9d22164..625fa1e 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -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); diff --git a/src/light.h b/src/light.h index d29148e..cf38733 100644 --- a/src/light.h +++ b/src/light.h @@ -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); diff --git a/src/main.cpp b/src/main.cpp index 111beca..782321f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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; } diff --git a/src/main.h b/src/main.h index ae242fd..968cf3e 100644 --- a/src/main.h +++ b/src/main.h @@ -8,7 +8,21 @@ disable : 4305) // Disable: truncation from 'const double' to 'double' #endif -#include +#include "SDL.h" + +#ifdef DEBUG +#define _DEBUG +#endif + +#ifdef HAVE_CONFIG_H +#include +#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 \ diff --git a/src/menu.cpp b/src/menu.cpp index 232e546..2ce4bfa 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -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); diff --git a/src/objectfactory.cpp b/src/objectfactory.cpp index dacaf28..b248c31 100644 --- a/src/objectfactory.cpp +++ b/src/objectfactory.cpp @@ -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], diff --git a/src/particle.cpp b/src/particle.cpp index c543971..ee8ac18 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -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); + } +} diff --git a/src/particle.h b/src/particle.h index 63dc9f8..aae0980 100644 --- a/src/particle.h +++ b/src/particle.h @@ -46,5 +46,6 @@ public: void initBloods(World *world); void createBlood(float *position, float *velocity); void removeBlood(int id); +void removeAllBlood(); #endif diff --git a/src/run.cpp b/src/run.cpp index 03a7ab3..90c1490 100644 --- a/src/run.cpp +++ b/src/run.cpp @@ -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; } diff --git a/src/windows.h b/src/windows.h new file mode 100644 index 0000000..cb2f761 --- /dev/null +++ b/src/windows.h @@ -0,0 +1,129 @@ +/* + windows.h - main header file for the Win32 API + + Written by Anders Norlander + + 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 +#else + +#include +#include +#include +#include +#if !(defined NOGDI || defined _WINGDI_H) +#include +#endif +#ifndef _WINUSER_H +#include +#endif +#ifndef _WINNLS_H +#include +#endif +#ifndef _WINVER_H +#include +#endif +#ifndef _WINNETWK_H +#include +#endif +#ifndef _WINREG_H +#include +#endif +#ifndef _WINSVC_H +#include +#endif + +#ifndef WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef NOGDI +#include +#include +#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 +/* + * 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 +#endif /* (_WIN32_WINNT >= 0x0400) */ +#endif +#ifndef NOGDI +#if !defined(__OBJC__) +#if (__GNUC__ >= 3) || defined(__WATCOMC__) +#include +#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 diff --git a/src/world.cpp b/src/world.cpp index a3fdebe..8eb5d09 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -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; diff --git a/src/world.h b/src/world.h index 804a47e..f327c13 100644 --- a/src/world.h +++ b/src/world.h @@ -37,6 +37,8 @@ private: public: World(void); + void setGravity(float grav); + void prepare(void); void move(void); void draw(void);