1
0
mirror of https://github.com/blupi-games/planetblupi synced 2024-12-30 10:15:36 +01:00
planetblupi/src/event.cpp
2017-02-12 17:52:29 +01:00

5304 lines
137 KiB
C++

#include <stdlib.h>
#include <stdio.h>
#include <unordered_map>
#include <assert.h>
#include "gettext.h"
#include "blupi.h"
#include "def.h"
#include "resource.h"
#include "pixmap.h"
#include "sound.h"
#include "decor.h"
#include "movie.h"
#include "button.h"
#include "menu.h"
#include "jauge.h"
#include "event.h"
#include "action.h"
#include "text.h"
#include "misc.h"
#ifdef _WIN32
#define unlink _unlink
#else // _WIN32
#include <unistd.h>
#endif // !_WINE32
#define DEF_TIME_HELP 10000 // ~10 minutes
#define DEF_TIME_DEMO 1000 // ~1 minute
#define MAXDEMO 2000
typedef struct
{
Sint16 majRev;
Sint16 minRev;
Sint16 reserve1[9];
Sint16 exercice; // exercice en cours (0..n)
Sint16 mission; // mission en cours (0..n)
Sint16 speed;
Sint16 bMovie;
Sint16 maxMission; // dernière mission effectuée (0..n)
Sint16 scrollSpeed;
Sint16 audioVolume;
Sint16 midiVolume;
Sint16 bAccessBuild;
Sint16 prive;
Sint16 skill;
Sint16 reserve2[93];
}
DescInfo;
// Toutes les premières lettres doivent
// être différentes !
static char cheat_code[9][20] =
{
"vision", // 0
"power", // 1
"lonesome", // 2
"allmissions", // 3
"quick", // 4
"helpme", // 5
"invincible", // 6
"superblupi", // 7
"construire", // 8 (CPOTUSVJSF)
};
/////////////////////////////////////////////////////////////////////////////
static Phase table[] =
{
{
WM_PHASE_TESTCD,
"image/init.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_INTRO1,
"image/intro1.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_INTRO2,
"image/intro2.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_INIT,
"image/init.blp",
false,
{
{
WM_PHASE_DEMO,
0, {1, 108},
16, 424 - 60 - 42 * 3 - 18,
{ translate ("Demo") },
},
{
WM_PHASE_SCHOOL,
0, {1, 79},
16, 424 - 60 - 42 * 2,
{ translate ("Training") },
},
{
WM_PHASE_MISSION,
0, {1, 80},
16, 424 - 60 - 42 * 1,
{ translate ("Missions") },
},
{
WM_PHASE_PRIVATE,
0, {1, 49},
16, 424 - 60 - 42 * 0,
{ translate ("Construction") },
},
{
WM_PHASE_BYE,
0, {1, 36},
16, 424,
{ translate ("Quit BLUPI") },
},
{
0
},
},
},
{
WM_PHASE_HISTORY0,
"image/history0.blp",
true,
{
{
WM_PHASE_INIT,
0, {1, 50},
42 + 42 * 0, 433,
{ translate ("Previous page") },
},
{
WM_PHASE_H1MOVIE,
0, {1, 51},
558 - 42 * 0, 433,
{ translate ("Next page") },
},
{
0
},
},
},
{
WM_PHASE_HISTORY1,
"image/history1.blp",
true,
{
{
WM_PHASE_HISTORY0,
0, {1, 50},
42 + 42 * 0, 433,
{ translate ("Previous page") },
},
{
WM_PHASE_H2MOVIE,
0, {1, 51},
558 - 42 * 0, 433,
{ translate ("Next page") },
},
{
0
},
},
},
{
WM_PHASE_INFO,
"image/info%.3d.blp",
false,
{
{
WM_PREV,
0, {1, 50},
558 - 42 * 2, 433,
{ translate ("Previous game") },
},
{
WM_PHASE_PLAYMOVIE,
0, {1, 48},
558 - 42 * 1, 433,
{ translate ("Play this game") },
},
{
WM_NEXT,
0, {1, 51},
558 - 42 * 0, 433,
{ translate ("Next game") },
},
{
WM_PHASE_READ,
0, {1, 52},
42 + 42 * 4, 433,
{ translate ("Open another game") },
},
{
WM_PHASE_SETUP,
0, {1, 47},
42 + 42 * 7, 433,
{ translate ("Settings") },
},
{
WM_PHASE_BUILD,
0, {1, 49},
42 + 42 * 8, 433,
{ translate ("Construct this game") },
},
{
WM_PHASE_SKILL1,
0, {1, 94},
150, 230,
{ translate ("Skill level") },
},
{
WM_PHASE_SKILL2,
0, {1, 95},
150, 230 + 42,
{ translate ("Skill level") },
},
{
WM_PHASE_INIT,
0, {1, 40},
42 + 42 * 0, 433,
{ translate ("Finish") },
},
{
0
},
},
},
{
WM_PHASE_PLAY,
"image/play.blp",
false,
{
{
WM_PHASE_STOP,
0, {1, 40},
10 + 42 * 0, 422,
{},
},
{
WM_PHASE_SETUPp,
0, {1, 47},
10 + 42 * 1, 422,
{},
},
{
WM_PHASE_WRITEp,
0, {1, 53},
10 + 42 * 2, 422,
{},
},
{
0
},
},
},
{
WM_PHASE_STOP,
"image/stop%.3d.blp",
false,
{
{
WM_PHASE_PLAY,
0, {1, 77},
558 - 42 * 1, 433,
{ translate ("Continue this game") },
},
{
WM_PHASE_READ,
0, {1, 52},
42 + 42 * 4, 433,
{ translate ("Open another game") },
},
{
WM_PHASE_WRITE,
0, {1, 53},
42 + 42 * 5, 433,
{ translate ("Save this game") },
},
{
WM_PHASE_SETUP,
0, {1, 47},
42 + 42 * 7, 433,
{ translate ("Settings") },
},
{
WM_PHASE_INFO,
0, {1, 78},
42 + 42 * 0, 433,
{ translate ("Quit this game") },
},
{
WM_PHASE_HELP,
0, {1, 86},
42 + 42 * 9, 433,
{ translate ("Help") },
},
{
0
},
},
},
{
WM_PHASE_HELP,
"image/help.blp",
true,
{
{
WM_PHASE_PLAY,
0, {1, 77},
558 - 42 * 1, 433,
{ translate ("Continue this game") },
},
{
WM_PHASE_READ,
0, {1, 52},
42 + 42 * 4, 433,
{ translate ("Open another game") },
},
{
WM_PHASE_WRITE,
0, {1, 53},
42 + 42 * 5, 433,
{ translate ("Save this game") },
},
{
WM_PHASE_SETUP,
0, {1, 47},
42 + 42 * 7, 433,
{ translate ("Settings") },
},
{
WM_PHASE_STOP,
0, {1, 50},
42 + 42 * 0, 433,
{ translate ("Previous page") },
},
{
0
},
},
},
{
WM_PHASE_SETUP,
"image/setup.blp",
false,
{
{
WM_BUTTON1,
0, {1, 50},
54, 330,
{ translate ("Slower") },
},
{
WM_BUTTON2,
0, {1, 51},
54 + 40, 330,
{ translate ("Faster") },
},
{
WM_BUTTON3,
0, {1, 50},
284, 330,
{ translate ("Reduce volume") },
},
{
WM_BUTTON4,
0, {1, 51},
284 + 40, 330,
{ translate ("Increase volume") },
},
{
WM_BUTTON5,
0, {1, 50},
399, 330,
{ translate ("Reduce volume") },
},
{
WM_BUTTON6,
0, {1, 51},
399 + 40, 330,
{ translate ("Increase volume") },
},
{
WM_BUTTON7,
0, {1, 50},
514, 330,
{ translate ("No video") },
},
{
WM_BUTTON8,
0, {1, 51},
514 + 40, 330,
{ translate ("Show videos") },
},
{
WM_BUTTON9,
0, {1, 50},
169, 330,
{ translate ("Slower") },
},
{
WM_BUTTON10,
0, {1, 51},
169 + 40, 330,
{ translate ("Faster") },
},
{
WM_PHASE_STOP,
0, {1, 40},
11, 424,
{ translate ("Finish") },
},
{
0
},
},
},
{
WM_PHASE_SETUPp,
"image/setup.blp",
false,
{
{
WM_BUTTON1,
0, {1, 50},
54, 330,
{ translate ("Slower") },
},
{
WM_BUTTON2,
0, {1, 51},
54 + 40, 330,
{ translate ("Faster") },
},
{
WM_BUTTON3,
0, {1, 50},
284, 330,
{ translate ("Reduce volume") },
},
{
WM_BUTTON4,
0, {1, 51},
284 + 40, 330,
{ translate ("Increase volume") },
},
{
WM_BUTTON5,
0, {1, 50},
399, 330,
{ translate ("Reduce volume") },
},
{
WM_BUTTON6,
0, {1, 51},
399 + 40, 330,
{ translate ("Increase volume") },
},
{
WM_BUTTON7,
0, {1, 50},
514, 330,
{ translate ("No video") },
},
{
WM_BUTTON8,
0, {1, 51},
514 + 40, 330,
{ translate ("Show videos") },
},
{
WM_BUTTON9,
0, {1, 50},
169, 330,
{ translate ("Slower") },
},
{
WM_BUTTON10,
0, {1, 51},
169 + 40, 330,
{ translate ("Faster") },
},
{
WM_PHASE_PLAY,
0, {1, 77},
11, 424,
{ translate ("Continue this game") },
},
{
0
},
},
},
{
WM_PHASE_READ,
"image/read.blp",
false,
{
{
WM_READ0,
0, {0},
420, 30 + 42 * 0,
{},
},
{
WM_READ1,
0, {0},
420, 30 + 42 * 1,
{},
},
{
WM_READ2,
0, {0},
420, 30 + 42 * 2,
{},
},
{
WM_READ3,
0, {0},
420, 30 + 42 * 3,
{},
},
{
WM_READ4,
0, {0},
420, 30 + 42 * 4,
{},
},
{
WM_READ5,
0, {0},
420, 30 + 42 * 5,
{},
},
{
WM_READ6,
0, {0},
420, 30 + 42 * 6,
{},
},
{
WM_READ7,
0, {0},
420, 30 + 42 * 7,
{},
},
{
WM_READ8,
0, {0},
420, 30 + 42 * 8,
{},
},
{
WM_READ9,
0, {0},
420, 30 + 42 * 9,
{},
},
{
WM_PHASE_STOP,
0, {1, 40},
16, 424,
{ translate ("Finish") },
},
{
0
},
},
},
{
WM_PHASE_WRITE,
"image/write.blp",
false,
{
{
WM_WRITE0,
0, {0},
420, 30 + 42 * 0,
{},
},
{
WM_WRITE1,
0, {0},
420, 30 + 42 * 1,
{},
},
{
WM_WRITE2,
0, {0},
420, 30 + 42 * 2,
{},
},
{
WM_WRITE3,
0, {0},
420, 30 + 42 * 3,
{},
},
{
WM_WRITE4,
0, {0},
420, 30 + 42 * 4,
{},
},
{
WM_WRITE5,
0, {0},
420, 30 + 42 * 5,
{},
},
{
WM_WRITE6,
0, {0},
420, 30 + 42 * 6,
{},
},
{
WM_WRITE7,
0, {0},
420, 30 + 42 * 7,
{},
},
{
WM_WRITE8,
0, {0},
420, 30 + 42 * 8,
{},
},
{
WM_WRITE9,
0, {0},
420, 30 + 42 * 9,
{},
},
{
WM_PHASE_STOP,
0, {1, 40},
16, 424,
{ translate ("Finish") },
},
{
0
},
},
},
{
WM_PHASE_WRITEp,
"image/write.blp",
false,
{
{
WM_WRITE0,
0, {0},
420, 30 + 42 * 0,
{},
},
{
WM_WRITE1,
0, {0},
420, 30 + 42 * 1,
{},
},
{
WM_WRITE2,
0, {0},
420, 30 + 42 * 2,
{},
},
{
WM_WRITE3,
0, {0},
420, 30 + 42 * 3,
{},
},
{
WM_WRITE4,
0, {0},
420, 30 + 42 * 4,
{},
},
{
WM_WRITE5,
0, {0},
420, 30 + 42 * 5,
{},
},
{
WM_WRITE6,
0, {0},
420, 30 + 42 * 6,
{},
},
{
WM_WRITE7,
0, {0},
420, 30 + 42 * 7,
{},
},
{
WM_WRITE8,
0, {0},
420, 30 + 42 * 8,
{},
},
{
WM_WRITE9,
0, {0},
420, 30 + 42 * 9,
{},
},
{
WM_PHASE_PLAY,
0, {1, 77},
16, 424,
{ translate ("Continue this game") },
},
{
0
},
},
},
{
WM_PHASE_LOST,
"image/lost.blp",
true,
{
{
WM_PHASE_INFO,
0, {1, 50},
9, 431,
{ translate ("Restart this game") },
},
{
0
},
},
},
{
WM_PHASE_WIN,
"image/win.blp",
true,
{
{
WM_NEXT,
0, {1, 51},
9, 431,
{ translate ("Next game") },
},
{
0
},
},
},
{
WM_PHASE_LASTWIN,
"image/last%.3d.blp",
true,
{
{
WM_PHASE_INIT,
0, {1, 51},
9, 431,
{ translate ("Next game") },
},
{
0
},
},
},
{
WM_PHASE_BUILD,
"image/build.blp",
true,
{
{
WM_DECOR1, // pose des sols
0, {6, 0, 1, 2, 3, 4, 25},
11 + 42 * 2, 190 + 42 * 0,
{
translate ("Normal ground"),
translate ("Inflammable ground"),
translate ("Sterile ground"),
translate ("Water"),
translate ("Special pavings"),
translate ("Incubator or teleporter")
},
},
{
WM_DECOR2, // pose des plantes
0, {4, 6, 7, 8, 11},
11 + 42 * 2, 190 + 42 * 1,
{
translate ("Delete item"),
translate ("Decorative plants"),
translate ("Tree"),
ptranslate ("Flower|1|", "Flowers")
},
},
{
WM_DECOR3, // pose des batiments
0, {11, 18, 81, 33, 61, 82, 93, 20, 21, 22, 57, 58},
11 + 42 * 2, 190 + 42 * 2,
{
translate ("Delete item"),
translate ("Buildings"),
translate ("Protection tower"),
translate ("Mine"),
translate ("Enemy buildings"),
translate ("Enemy barrier"),
translate ("Wall or palisade"),
translate ("Rocks"),
translate ("Items"),
translate ("Weapons"),
translate ("Transport")
},
},
{
WM_DECOR4, // pose des blupi
0, {10, 12, 13, 14, 85, 15, 16, 17, 38, 75, 56},
11 + 42 * 2, 190 + 42 * 3,
{
translate ("Delete figure"),
translate ("Tired Blupi"),
translate ("Blupi"),
translate ("Helper robot"),
translate ("Spider"),
translate ("Virus"),
translate ("Bulldozer"),
translate ("Bouncing bomb"),
translate ("Electrocutor"),
translate ("Master robot")
},
},
{
WM_DECOR5, // pose les catastrophes
0, {2, 36, 37},
11 + 42 * 2, 190 + 42 * 4,
{
translate ("Delete fire"),
translate ("Starting fire")
},
},
{
WM_PHASE_REGION,
0, {1, 5},
11 + 42 * 0, 190 + 42 * 1,
{ translate ("Scenery choice") },
},
{
WM_PHASE_MUSIC,
0, {1, 44},
11 + 42 * 0, 190 + 42 * 2,
{ translate ("Music choice") },
},
{
WM_PHASE_BUTTON,
0, {1, 46},
11 + 42 * 0, 190 + 42 * 3,
{ translate ("Available buttons") },
},
{
WM_PHASE_TERM,
0, {1, 45},
11 + 42 * 0, 190 + 42 * 4,
{ translate ("Ending conditions") },
},
{
WM_PHASE_INFO,
0, {1, 40},
11 + 42 * 0, 424,
{ translate ("Quit construction") },
},
{
WM_PHASE_UNDO,
0, {1, 87},
11 + 42 * 2, 424,
{ translate ("Cancel last operation") },
},
{
0
},
},
},
{
WM_PHASE_BUTTON,
"image/button.blp",
true,
{
{
WM_BUTTON1, // stop
0, {1, 40},
170 + 42 * 0, 30 + 52 * 0,
{ translate ("Stop") },
},
{
WM_BUTTON0, // go
0, {1, 24},
170 + 42 * 1, 30 + 52 * 0,
{ translate ("Go") },
},
{
WM_BUTTON3, // carry
0, {1, 30},
170 + 42 * 3, 30 + 52 * 0,
{ translate ("Take") },
},
{
WM_BUTTON4, // depose
0, {1, 31},
170 + 42 * 4, 30 + 52 * 0,
{ translate ("Drop") },
},
{
WM_BUTTON32, // répète
0, {1, 100},
170 + 42 * 6, 30 + 52 * 0,
{ translate ("Repeat") },
},
{
WM_BUTTON5, // abat
0, {1, 22},
170 + 42 * 0, 30 + 52 * 1,
{ translate ("Cut down a tree") },
},
{
WM_BUTTON16, // abat n
0, {1, 42},
170 + 42 * 1, 30 + 52 * 1,
{ translate ("Cut down trees") },
},
{
WM_BUTTON6, // roc
0, {1, 27},
170 + 42 * 3, 30 + 52 * 1,
{ translate ("Carve a rock") },
},
{
WM_BUTTON17, // roc n
0, {1, 43},
170 + 42 * 4, 30 + 52 * 1,
{ translate ("Carve rocks") },
},
{
WM_BUTTON22, // fleurs
0, {1, 54},
170 + 42 * 6, 30 + 52 * 1,
{ translate ("Make bunch of flowers") },
},
{
WM_BUTTON23, // fleurs n
0, {1, 55},
170 + 42 * 7, 30 + 52 * 1,
{ translate ("Make bunches of flowers") },
},
{
WM_BUTTON9, // build2 (couveuse)
0, {1, 25},
170 + 42 * 0, 30 + 52 * 2,
{ translate ("Incubator") },
},
{
WM_BUTTON15, // palis
0, {1, 26},
170 + 42 * 1, 30 + 52 * 2,
{ translate ("Palisade") },
},
{
WM_BUTTON18, // pont
0, {1, 23},
170 + 42 * 2, 30 + 52 * 2,
{ translate ("Bridge") },
},
{
WM_BUTTON25, // bateau
0, {1, 58},
170 + 42 * 3, 30 + 52 * 2,
{ translate ("Boat") },
},
{
WM_BUTTON13, // build6 (téléporteur)
0, {1, 101},
170 + 42 * 4, 30 + 52 * 2,
{ translate ("Teleporter") },
},
{
WM_BUTTON14, // mur
0, {1, 20},
170 + 42 * 6, 30 + 52 * 2,
{ translate ("Wall") },
},
{
WM_BUTTON19, // tour
0, {1, 33},
170 + 42 * 7, 30 + 52 * 2,
{ translate ("Protection tower") },
},
{
WM_BUTTON8, // build1 (cabane)
0, {1, 19},
170 + 42 * 0, 30 + 52 * 3,
{ translate ("Garden shed") },
},
{
WM_BUTTON7, // cultive
0, {1, 28},
170 + 42 * 1, 30 + 52 * 3,
{ translate ("Grow tomatoes") },
},
{
WM_BUTTON2, // mange
0, {1, 32},
170 + 42 * 2, 30 + 52 * 3,
{ translate ("Eat") },
},
{
WM_BUTTON10, // build3 (laboratoire)
0, {1, 35},
170 + 42 * 0, 30 + 52 * 4,
{ translate ("Laboratory") },
},
{
WM_BUTTON21, // laboratoire
0, {1, 39},
170 + 42 * 1, 30 + 52 * 4,
{ translate ("Transform") },
},
{
WM_BUTTON20, // boit
0, {1, 34},
170 + 42 * 2, 30 + 52 * 4,
{ translate ("Drink") },
},
{
WM_BUTTON24, // dynamite
0, {1, 41},
170 + 42 * 3, 30 + 52 * 4,
{ translate ("Blow up") },
},
{
WM_BUTTON27, // drapeau
0, {1, 64},
170 + 42 * 0, 30 + 52 * 5,
{ translate ("Prospect for iron") },
},
{
WM_BUTTON11, // build4 (mine)
0, {1, 61},
170 + 42 * 1, 30 + 52 * 5,
{ translate ("Mine") },
},
{
WM_BUTTON28, // extrait
0, {1, 62},
170 + 42 * 2, 30 + 52 * 5,
{ translate ("Extract iron") },
},
{
WM_BUTTON12, // build5 (usine)
0, {1, 59},
170 + 42 * 4, 30 + 52 * 5,
{ translate ("Workshop") },
},
{
WM_BUTTON29, // fabrique jeep
0, {1, 65},
170 + 42 * 5, 30 + 52 * 5,
{ translate ("Make a Jeep") },
},
{
WM_BUTTON30, // fabrique mine
0, {1, 63},
170 + 42 * 6, 30 + 52 * 5,
{ translate ("Make a time bomb") },
},
{
WM_BUTTON34, // fabrique armure
0, {1, 106},
170 + 42 * 7, 30 + 52 * 5,
{ translate ("Make armour") },
},
{
WM_BUTTON31, // fabrique disciple
0, {1, 83},
170 + 42 * 8, 30 + 52 * 5,
{ translate ("Make a helper robot") },
},
{
WM_PHASE_BUILD,
0, {1, 50},
11, 424,
{ translate ("Finish") },
},
{
0
},
},
},
{
WM_PHASE_TERM,
"image/term.blp",
true,
{
{
WM_BUTTON8, // home blupi
0, {1, 81},
170 + 42 * 0, 30 + 42 * 0,
{ translate ("Blupi in house") },
},
{
WM_BUTTON9, // kill robots
0, {1, 57},
170 + 42 * 1, 30 + 42 * 0,
{ translate ("No more enemies") },
},
{
WM_BUTTON3, // stop fire
0, {1, 37},
170 + 42 * 2, 30 + 42 * 0,
{ translate ("Fire out") },
},
{
WM_BUTTON1, // hach blupi
0, {1, 14},
170 + 42 * 0, 30 + 42 * 2,
{ translate ("Blupi on striped paving stones") },
},
{
WM_BUTTON2, // hach planche
0, {1, 22},
170 + 42 * 1, 30 + 42 * 2,
{ translate ("Planks on striped paving stones") },
},
{
WM_BUTTON10, // hach tomate
0, {1, 28},
170 + 42 * 2, 30 + 42 * 2,
{ translate ("Tomatoes on striped paving stones") },
},
{
WM_BUTTON11, // hach métal
0, {1, 84},
170 + 42 * 3, 30 + 42 * 2,
{ translate ("Platinium on striped paving stones") },
},
{
WM_BUTTON12, // hach robot
0, {1, 94},
170 + 42 * 4, 30 + 42 * 2,
{ translate ("Robot on striped paving stones") },
},
{
WM_BUTTON4, // - min blupi
0, {1, 50},
170 + 42 * 0, 30 + 42 * 4,
{ "(-)" },
},
{
WM_BUTTON5, // + min blupi
0, {1, 51},
170 + 42 * 1, 30 + 42 * 4,
{ "(+)" },
},
{
WM_BUTTON6, // - max blupi
0, {1, 50},
170 + 42 * 0, 30 + 42 * 5,
{ "(-)" },
},
{
WM_BUTTON7, // + max blupi
0, {1, 51},
170 + 42 * 1, 30 + 42 * 5,
{ "(+)" },
},
{
WM_PHASE_BUILD,
0, {1, 50},
11, 424,
{ translate ("Finish") },
},
{
0
},
},
},
{
WM_PHASE_MUSIC,
"image/music.blp",
true,
{
{
WM_BUTTON1,
0, {1, 40},
170 + 42 * 0, 30 + 42 * 0,
{ translate ("No music") },
},
{
WM_BUTTON2,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 1,
{ translate ("Music number 1") },
},
{
WM_BUTTON3,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 2,
{ translate ("Music number 2") },
},
{
WM_BUTTON4,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 3,
{ translate ("Music number 3") },
},
{
WM_BUTTON5,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 4,
{ translate ("Music number 4") },
},
{
WM_BUTTON6,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 5,
{ translate ("Music number 5") },
},
{
WM_BUTTON7,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 6,
{ translate ("Music number 6") },
},
{
WM_BUTTON8,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 7,
{ translate ("Music number 7") },
},
{
WM_BUTTON9,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 8,
{ translate ("Music number 8") },
},
{
WM_BUTTON10,
0, {1, 44},
170 + 42 * 0, 30 + 42 * 9,
{ translate ("Music number 9") },
},
{
WM_PHASE_BUILD,
0, {1, 50},
11, 424,
{ translate ("Finish") },
},
{
0
},
},
},
{
WM_PHASE_REGION,
"image/region.blp",
true,
{
{
WM_BUTTON1, // normal
0, {0},
220, 60,
{ translate ("Prairie") },
},
{
WM_BUTTON4, // sapins
0, {0},
220, 170,
{ translate ("Forest") },
},
{
WM_BUTTON2, // palmiers
0, {0},
220, 280,
{ translate ("Desert") },
},
{
WM_BUTTON3, // hivers
0, {0},
220, 390,
{ translate ("Forest under snow") },
},
{
WM_PHASE_BUILD,
0, {1, 50},
11, 424,
{ translate ("Finish") },
},
{
0
},
},
},
{
WM_PHASE_PLAYMOVIE,
"image/movie.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_WINMOVIE,
"image/movie.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_H0MOVIE,
"image/movie.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_H1MOVIE,
"image/movie.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_H2MOVIE,
"image/movie.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_BYE,
"image/bye.blp",
false,
{
{
0
},
},
},
{
WM_PHASE_INSERT,
"image/insert.blp",
false,
{
{
WM_PHASE_INIT,
0, {1, 40},
16, 424,
{ translate ("Quit BLUPI") },
},
{
0
},
},
},
{
0
}
};
/////////////////////////////////////////////////////////////////////////////
// Constructeur.
CEvent::CEvent()
{
Sint32 i;
m_bFullScreen = true;
m_mouseType = MOUSETYPEGRA;
m_exercice = 0;
m_mission = 0;
m_private = 0;
m_maxMission = 0;
m_phase = 0;
m_index = -1;
m_bSchool = false;
m_bPrivate = false;
m_bAccessBuild = false;
m_bRunMovie = false;
m_bBuildModify = false;
m_bMouseDown = false;
m_oldMousePos.x = 0;
m_oldMousePos.y = 0;
m_mouseSprite = SPRITE_ARROW;
m_bFillMouse = false;
m_bWaitMouse = false;
m_bHideMouse = false;
m_rankCheat = -1;
m_posCheat = 0;
m_speed = 1;
m_bMovie = true;
m_bSpeed = false;
m_bHelp = false;
m_bAllMissions = false;
m_bChangeCheat = false;
m_scrollSpeed = 1;
m_bPause = false;
m_bShift = false;
m_shiftPhase = 0;
m_movieToStart[0] = 0;
m_bInfoHelp = false;
m_bDemoRec = false;
m_bDemoPlay = false;
m_pDemoBuffer = nullptr;
m_demoTime = 0;
m_keymod = 0;
m_posHelpButton = {-1, -1};
for (i = 0 ; i < MAXBUTTON ; i++)
m_lastFloor[i] = 0;
for (i = 0 ; i < MAXBUTTON ; i++)
m_lastObject[i] = 0;
for (i = 0 ; i < MAXBUTTON ; i++)
m_lastHome[i] = 0;
}
// Destructeur.
CEvent::~CEvent()
{
WriteInfo(); // lit le fichier "info.blp"
}
// Retourne la position de la souris.
POINT CEvent::GetMousePos()
{
POINT pos;
Sint32 x, y;
SDL_GetMouseState (&x, &y);
pos.x = x;
pos.y = y;
return pos;
}
// Initialise le mode full screen ou non.
void CEvent::SetFullScreen (bool bFullScreen)
{
m_bFullScreen = bFullScreen;
}
// Initialise le type de souris.
void CEvent::SetMouseType (Sint32 mouseType)
{
m_mouseType = mouseType;
}
// Crée le gestionnaire d'événements.
void CEvent::Create (CPixmap *pPixmap, CDecor *pDecor,
CSound *pSound, CMovie *pMovie)
{
POINT pos;
m_pPixmap = pPixmap;
m_pDecor = pDecor;
m_pSound = pSound;
m_pMovie = pMovie;
ReadInfo(); // lit le fichier "info.blp"
pos.x = 10;
pos.y = 158;
m_jauges[0].Create (m_pPixmap, m_pSound, pos, 1, true);
pos.y += DIMJAUGEY + 2;
m_jauges[1].Create (m_pPixmap, m_pSound, pos, 3, true);
}
// Retourne l'index d'un bouton.
Sint32 CEvent::GetButtonIndex (Sint32 button)
{
int i = 0;
if (m_index < 0)
return -1;
while (table[m_index].buttons[i].message != 0)
{
if ((Uint32) button == table[m_index].buttons[i].message)
return i;
i ++;
}
return -1;
}
Sint32 CEvent::GetState (Sint32 button)
{
Sint32 index;
index = GetButtonIndex (button);
if (index < 0)
return 0;
return m_buttons[index].GetState();
}
void CEvent::SetState (Sint32 button, Sint32 state)
{
Sint32 index;
index = GetButtonIndex (button);
if (index < 0)
return;
m_buttons[index].SetState (state);
}
bool CEvent::GetEnable (Sint32 button)
{
Sint32 index;
index = GetButtonIndex (button);
if (index < 0)
return 0;
return m_buttons[index].GetEnable();
}
void CEvent::SetEnable (Sint32 button, bool bEnable)
{
Sint32 index;
index = GetButtonIndex (button);
if (index < 0)
return;
m_buttons[index].SetEnable (bEnable);
}
bool CEvent::GetHide (Sint32 button)
{
Sint32 index;
index = GetButtonIndex (button);
if (index < 0)
return 0;
return m_buttons[index].GetHide();
}
void CEvent::SetHide (Sint32 button, bool bHide)
{
Sint32 index;
index = GetButtonIndex (button);
if (index < 0)
return;
m_buttons[index].SetHide (bHide);
}
Sint32 CEvent::GetMenu (Sint32 button)
{
Sint32 index;
index = GetButtonIndex (button);
if (index < 0)
return 0;
return m_buttons[index].GetMenu();
}
void CEvent::SetMenu (Sint32 button, Sint32 menu)
{
Sint32 index;
index = GetButtonIndex (button);
if (index < 0)
return;
m_buttons[index].SetMenu (menu);
}
// Restitue le jeu après une activation en mode fullScreen.
void CEvent::RestoreGame()
{
Sint32 i;
if (m_phase == WM_PHASE_PLAY)
{
if (m_index < 0)
return;
i = 0;
while (table[m_index].buttons[i].message != 0)
{
m_buttons[i].Redraw(); // faudra redessiner
i ++;
}
for (i = 0 ; i < 2 ; i++)
m_jauges[i].Redraw();
}
HideMouse (false);
WaitMouse (true);
WaitMouse (false); // force le changement de sprite !
}
// Crée tous les boutons nécessaires à la phase en cours.
bool CEvent::CreateButtons ()
{
Sint32 i = 0, message;
POINT pos;
bool bMinimizeRedraw = false;
if (m_phase == WM_PHASE_PLAY)
bMinimizeRedraw = true;
if (m_index < 0)
return false;
while (table[m_index].buttons[i].message != 0)
{
pos.x = table[m_index].buttons[i].x;
pos.y = table[m_index].buttons[i].y;
message = table[m_index].buttons[i].message;
if (m_bPrivate)
{
if (message == WM_PHASE_SKILL1)
{
pos.x = 117;
pos.y = 115;
}
if (message == WM_PHASE_SKILL2)
{
pos.x = 117;
pos.y = 115 + 42;
}
}
m_buttons[i].Create (m_pPixmap, m_pSound, pos,
table[m_index].buttons[i].type,
bMinimizeRedraw,
table[m_index].buttons[i].iconMenu + 1,
table[m_index].buttons[i].iconMenu[0],
table[m_index].buttons[i].toolTips,
m_pDecor->GetRegion(),
message);
i ++;
}
return true;
}
// Ajoute un cheat-code dans un buffer.
void AddCheatCode (char *pDst, char *pSrc)
{
Sint32 i;
size_t j;
if (pDst[0] != 0)
strcat (pDst, " / ");
i = 0;
j = strlen (pDst);
while (pSrc[i] != 0)
pDst[j++] = pSrc[i++];
pDst[j] = 0;
}
// Dessine un texte multi-lignes centré.
void CEvent::DrawTextCenter (const char *text, Sint32 x, Sint32 y, Sint32 font)
{
POINT pos;
pos.x = x;
pos.y = y;
::DrawTextCenter (m_pPixmap, pos, text, font);
}
// Dessine tous les boutons de la phase en cours.
bool CEvent::DrawButtons()
{
Sint32 i;
Sint32 levels[2];
Sint32 types[2];
Sint32 world, time, lg, button, volume, pente, icon;
char res[100];
char text[100];
POINT pos;
RECT rect;
bool bEnable;
//?
#if 0
pos.x = 1;
pos.y = 1;
rect.left = pos.x;
rect.right = pos.x + 50;
rect.top = pos.y;
rect.bottom = pos.y + DIMLITTLEY;
m_pPixmap->DrawPart (-1, CHBACK, pos, rect, 1); // dessine le fond
time = m_pDecor->GetTotalTime();
sprintf (text, "time=%d", time);
DrawText (m_pPixmap, pos, text, FONTLITTLE);
#endif
//?
if ((m_phase == WM_PHASE_PLAY && m_bChangeCheat) ||
(m_phase != WM_PHASE_PLAY &&
m_phase != WM_PHASE_INSERT &&
m_phase != WM_PHASE_INTRO1 &&
m_phase != WM_PHASE_INTRO2 &&
m_phase != WM_PHASE_BYE))
{
m_bChangeCheat = false;
text[0] = 0;
if (m_bAllMissions)
AddCheatCode (text, cheat_code[3]);
if (m_bSpeed)
AddCheatCode (text, cheat_code[4]);
if (m_bHelp)
AddCheatCode (text, cheat_code[5]);
if (m_pDecor->GetInvincible())
AddCheatCode (text, cheat_code[6]);
if (m_pDecor->GetSuper())
AddCheatCode (text, cheat_code[7]);
pos.x = 2;
pos.y = 2;
rect.left = pos.x;
rect.right = pos.x + 300;
rect.top = pos.y;
rect.bottom = pos.y + DIMLITTLEY;
m_pPixmap->DrawPart (-1, CHBACK, pos, rect, 1); // dessine le fond
DrawText (m_pPixmap, pos, text, FONTLITTLE);
}
if (m_phase == WM_PHASE_INIT)
{
pos.x = 580;
pos.y = 465;
DrawText (m_pPixmap, pos, "Version 1.7", FONTLITTLE);
}
if (m_phase == WM_PHASE_SETUP ||
m_phase == WM_PHASE_SETUPp)
{
bEnable = true;
if (m_speed == 1)
bEnable = false;
SetEnable (WM_BUTTON1, bEnable);
bEnable = true;
if (m_speed >= (m_bSpeed ? 8 : 2))
bEnable = false;
SetEnable (WM_BUTTON2, bEnable);
volume = m_pSound->GetAudioVolume();
bEnable = true;
if (volume == 0 ||
!m_pSound->GetEnable())
bEnable = false;
SetEnable (WM_BUTTON3, bEnable);
bEnable = true;
if (volume >= MAXVOLUME ||
!m_pSound->GetEnable())
bEnable = false;
SetEnable (WM_BUTTON4, bEnable);
volume = m_pSound->GetMidiVolume();
bEnable = true;
if (volume == 0 ||
!m_pSound->GetEnable())
bEnable = false;
SetEnable (WM_BUTTON5, bEnable);
bEnable = true;
if (volume >= MAXVOLUME ||
!m_pSound->GetEnable())
bEnable = false;
SetEnable (WM_BUTTON6, bEnable);
if (m_pMovie->GetEnable())
{
SetEnable (WM_BUTTON7, m_bMovie);
SetEnable (WM_BUTTON8, !m_bMovie);
}
else
{
SetEnable (WM_BUTTON7, false);
SetEnable (WM_BUTTON8, false);
}
bEnable = true;
if (m_scrollSpeed == 0)
bEnable = false;
SetEnable (WM_BUTTON9, bEnable);
bEnable = true;
if (m_scrollSpeed >= 3)
bEnable = false;
SetEnable (WM_BUTTON10, bEnable);
}
assert (m_index >= 0);
// Dessine les boutons.
i = 0;
while (table[m_index].buttons[i].message != 0)
{
m_buttons[i].Draw ();
++i;
}
if (m_phase == WM_PHASE_PLAY)
{
// Dessine les jauges.
m_pDecor->GetLevelJauge (levels, types);
for (i = 0 ; i < 2 ; i++)
{
if (levels[i] < 0)
m_jauges[i].SetHide (true);
else
{
m_jauges[i].SetHide (false);
m_jauges[i].SetLevel (levels[i]);
m_jauges[i].SetType (types[i]);
}
m_jauges[i].Draw();
}
// Dessine le menu.
if (m_menu.IsExist())
{
m_pDecor->BlupiGetButtons (m_menuPos, m_menuNb,
m_menuButtons, m_menuErrors,
m_menuTexts,
m_menuPerso);
m_menu.Update (m_menuNb, m_menuButtons, m_menuErrors, m_menuTexts);
button = m_menu.GetSel();
m_pDecor->CelHiliButton (m_menuCel, button);
}
m_menu.Draw();
// Dessine la pause.
if (m_bPause)
DrawTextCenter (gettext ("Game paused"), (10 + 134) / 2, 20);
else
{
if (m_bDemoRec) // démo en enregistrement ?
DrawTextCenter (gettext ("REC"), (10 + 134) / 2, 20, FONTRED);
if (m_bDemoPlay) // démo en restitution ?
DrawTextCenter (gettext ("Demo"), (10 + 134) / 2, 20, FONTRED);
}
// Dessine la rose des vents.
if (!m_bPause && !m_bDemoRec && !m_bDemoPlay)
{
DrawTextCenter (gettext ("N"), (10 + 134) / 2, 17);
DrawTextCenter (gettext ("S"), (10 + 134) / 2, 126);
DrawTextCenter (gettext ("W"), 14, 70);
DrawTextCenter (gettext ("E"), 129, 70);
}
// Dessine la vitesse.
pos.x = 64;
pos.y = LYIMAGE - 15;
rect.left = pos.x;
rect.right = pos.x + 20;
rect.top = pos.y;
rect.bottom = pos.y + 15;
m_pPixmap->DrawPart (-1, CHBACK, pos, rect, 1); // dessine le fond
if (m_speed > 1)
{
sprintf (res, "x%d", m_speed);
DrawText (m_pPixmap, pos, res);
}
// Dessine le bouton pour les infos.
if (m_pDecor->GetInfoMode()) // infos visibles ?
{
lg = m_pDecor->GetInfoHeight();
pos.x = POSDRAWX;
pos.y = 0;
rect.left = POSDRAWX;
rect.right = POSDRAWX + DIMDRAWX;
rect.top = 0;
rect.bottom = lg;
m_pPixmap->DrawPart (-1, CHBACK, pos, rect, 1);
pos.x = POSDRAWX;
pos.y = lg;
rect.left = POSDRAWX;
rect.right = POSDRAWX + DIMDRAWX;
rect.top = 0;
rect.bottom = POSDRAWY;
m_pPixmap->DrawPart (-1, CHBACK, pos, rect, 1);
pos.x = POSDRAWX + 20;
pos.y = POSDRAWY + 4;
DrawTextRect (m_pPixmap, pos, m_libelle, 0, FONTLITTLE, 1);
pos.x = POSDRAWX + DIMDRAWX / 2 + 20;
DrawTextRect (m_pPixmap, pos, m_libelle, 0, FONTLITTLE, 2);
pos.x = POSDRAWX + DIMDRAWX / 2 - DIMBUTTONX / 2;
pos.y = lg - 14;
m_pPixmap->DrawIcon (-1, CHBUTTON, m_bHiliInfoButton ? 73 : 72, pos);
if (IsHelpHide()) // bouton pour aide ?
m_posHelpButton.x = -1;
else
{
m_posHelpButton.x = POSDRAWX + DIMDRAWX - DIMBUTTONX - 2;
m_posHelpButton.y = lg - DIMBUTTONY - 2;
m_pPixmap->DrawIcon (-1, CHBUTTON, m_bHiliHelpButton ? 2 : 0, m_posHelpButton);
if (m_bInfoHelp)
icon = 86; // livre
else
icon = 92; // aide
m_pPixmap->DrawIcon (-1, CHBUTTON, icon, m_posHelpButton);
}
}
else // infos cachées ?
{
pos.x = POSDRAWX + DIMDRAWX / 2 - DIMBUTTONX / 2;
pos.y = -12;
m_pPixmap->DrawIcon (-1, CHBUTTON, m_bHiliInfoButton ? 75 : 74, pos);
}
m_posInfoButton = pos;
}
// Dessine les noms des fichiers.
if (m_phase == WM_PHASE_READ ||
m_phase == WM_PHASE_WRITE ||
m_phase == WM_PHASE_WRITEp)
{
if (m_phase == WM_PHASE_READ)
snprintf (res, sizeof (res), "%s", gettext ("Open another game"));
else
snprintf (res, sizeof (res), "%s", gettext ("Save this game"));
pos.x = 420;
pos.y = 8;
DrawText (m_pPixmap, pos, res);
for (i = 0 ; i < 10 ; i++)
{
world = m_fileWorld[i];
time = m_fileTime[i];
sprintf (text, "%d", i + 1);
lg = GetTextWidth (text);
pos.x = (420 + 460) / 2 - lg / 2;
pos.y = 30 + 12 + 42 * i;
DrawText (m_pPixmap, pos, text, FONTSLIM);
pos.x = 420 + 50;
if (world >= 0)
{
if (world >= 200)
snprintf (text, sizeof (text), gettext ("construction %d, time %d"),
(world - 200) + 1, time / 100);
else if (world >= 100)
snprintf (text, sizeof (text), gettext ("mission %d, time %d"),
(world - 100) + 1, time / 100);
else
snprintf (text, sizeof (text), gettext ("training %d, time %d"), world + 1,
time / 100);
DrawText (m_pPixmap, pos, text); // partie x, temps t
}
else
DrawText (m_pPixmap, pos, gettext ("free slot"), FONTRED); // libre
}
}
// Dessine les réglages pour la fin de la partie.
if (m_phase == WM_PHASE_TERM)
{
Term *pTerm = m_pDecor->GetTerminated();
DrawTextCenter (gettext ("Ending conditions"), (10 + 134) / 2, 20);
pos.x = 170 + 42 * 2 + 4;
pos.y = 30 + 12 + 42 * 4;
snprintf (text, sizeof (text), gettext ("Lost if less than %d Blupi"),
pTerm->nbMinBlupi);
DrawText (m_pPixmap, pos, text);
pos.x = 170 + 42 * 2 + 4;
pos.y = 30 + 12 + 42 * 5;
snprintf (text, sizeof (text),
gettext ("Impossible to win if less than %d Blupi"), pTerm->nbMaxBlupi);
DrawText (m_pPixmap, pos, text);
}
// Dessine les textes pour les choix des boutons.
if (m_phase == WM_PHASE_BUTTON)
DrawTextCenter (gettext ("Available buttons"), (10 + 134) / 2, 20);
// Dessine les textes pour le choix des musiques.
if (m_phase == WM_PHASE_MUSIC)
DrawTextCenter (gettext ("Music choice"), (10 + 134) / 2, 20);
// Dessine les textes pour le choix de la région.
if (m_phase == WM_PHASE_REGION)
DrawTextCenter (gettext ("Scenery choice"), (10 + 134) / 2, 20);
// Ajoute "Mission numéro".
if (m_phase == WM_PHASE_INFO)
{
if (m_bSchool)
snprintf (res, sizeof (res), gettext ("Training number"));
else
snprintf (res, sizeof (res), gettext ("Mission number"));
if (m_bPrivate)
snprintf (res, sizeof (res), gettext ("Construction number"));
lg = GetTextWidth (res);
pos.x = (140 + 270) / 2 - lg / 2;
pos.y = 70;
if (m_bSchool)
pos.x -= 40;
if (m_bPrivate)
pos.x -= 100;
if (m_bPrivate)
pos.y += 14;
DrawText (m_pPixmap, pos, res, FONTSLIM);
}
// Ajoute le texte "Partie interrompue".
if (m_phase == WM_PHASE_STOP)
{
char *text = gettext ("Game paused");
lg = GetTextWidth (text);
pos.x = (140 + 270) / 2 - lg / 2;
pos.y = 70;
if (m_bSchool)
pos.x -= 40;
if (m_bPrivate)
pos.x -= 100;
if (m_bPrivate)
pos.y += 14;
DrawText (m_pPixmap, pos, text, FONTRED);
}
// Ajoute le texte "Informations complémentaires".
if (m_phase == WM_PHASE_HELP)
{
char *text = gettext ("Help number");
lg = GetTextWidth (text);
pos.x = (140 + 270) / 2 - lg / 2;
pos.y = 70;
if (m_bSchool)
pos.x -= 40;
if (m_bPrivate)
pos.x -= 100;
if (m_bPrivate)
pos.y += 14;
DrawText (m_pPixmap, pos, text, FONTRED);
}
// Ajoute le numéro du monde.
if (m_phase == WM_PHASE_INFO ||
m_phase == WM_PHASE_STOP ||
m_phase == WM_PHASE_HELP)
{
if (m_bSchool)
world = m_exercice;
else
world = m_mission;
if (m_bPrivate)
world = m_private;
lg = GetBignumWidth (world + 1);
pos.x = (140 + 270) / 2 - lg / 2;
pos.y = 100;
if (m_bSchool)
pos.x -= 40;
if (m_bPrivate)
pos.x -= 135;
if (m_bPrivate)
pos.y = 115;
DrawBignum (m_pPixmap, pos, world + 1);
}
// Affiche facile/difficile.
if (m_phase == WM_PHASE_INFO)
{
if (!m_bSchool)
{
if (m_pDecor->GetSkill() == 0)
{
if (m_bPrivate)
{
pos.x = 117 + 50;
pos.y = 115 + 13;
}
else
{
pos.x = 150 + 50;
pos.y = 230 + 13;
}
DrawText (m_pPixmap, pos, gettext ("Easy"), FONTSLIM);
}
if (m_pDecor->GetSkill() == 1)
{
if (m_bPrivate)
{
pos.x = 117 + 50;
pos.y = 115 + 42 + 13;
}
else
{
pos.x = 150 + 50;
pos.y = 230 + 42 + 13;
}
DrawText (m_pPixmap, pos, gettext ("Difficult"), FONTSLIM);
}
}
}
// Affiche le libellé de l'énigme.
if (m_phase == WM_PHASE_INFO ||
m_phase == WM_PHASE_STOP ||
m_phase == WM_PHASE_HELP ||
m_phase == WM_PHASE_HISTORY0 ||
m_phase == WM_PHASE_HISTORY1)
{
pos.x = 355;
pos.y = 70;
if (m_bSchool)
pos.x -= 20;
if (m_bPrivate)
{
pos.x = 460;
pos.y = 260;
}
if (m_bSchool || m_bPrivate)
pente = 0;
else
pente = 19;
DrawTextRect (m_pPixmap, pos, m_libelle, pente, FONTSLIM);
}
// Affiche le texte lorsque c'est raté.
if (m_phase == WM_PHASE_LOST)
{
static char *list[] = {
gettext ("You have failed, try again..."),
gettext ("No, wrong way ..."),
gettext ("Bang, failed again !"),
gettext ("Another mistake..."),
gettext ("No, not that way !"),
};
pos.x = 60;
pos.y = 443;
DrawText (m_pPixmap, pos, list[GetWorld() % 5]);
}
// Affiche le texte lorsque c'est réussi.
if (m_phase == WM_PHASE_WIN)
{
static char *list[] = {
gettext ("Well done !"),
gettext ("Yes, great ..."),
gettext ("Very good."),
gettext ("Excellent..."),
gettext ("Mission over..."),
};
pos.x = 60;
pos.y = 443;
DrawText (m_pPixmap, pos, list[GetWorld() % 5]);
}
// Affiche le texte lorsque c'est fini.
if (m_phase == WM_PHASE_LASTWIN)
{
char *text;
if (m_bSchool)
text = gettext ("Now go on mission.");
else
text = gettext ("Very good, success on all missions !");
if (m_bPrivate)
text = gettext ("Last construction resolved !");
pos.x = 60;
pos.y = 443;
DrawText (m_pPixmap, pos, text);
}
// Dessine les réglages.
if (m_phase == WM_PHASE_SETUP ||
m_phase == WM_PHASE_SETUPp)
{
DrawTextCenter (gettext ("Global game\nspeed"), 54 + 40, 80);
DrawTextCenter (gettext ("Scroll speed\nwith mouse"), 169 + 40, 80);
DrawTextCenter (gettext ("Sound effect\nvolume"), 284 + 40, 80);
DrawTextCenter (gettext ("Music\nvolume"), 399 + 40, 80);
DrawTextCenter (gettext ("Video\nsequences"), 514 + 40, 80);
sprintf (res, "x%d", m_speed);
lg = GetTextWidth (res);
pos.x = (54 + 40) - lg / 2;
pos.y = 330 - 20;
DrawText (m_pPixmap, pos, res);
sprintf (res, "%d", m_pSound->GetAudioVolume());
lg = GetTextWidth (res);
pos.x = (284 + 40) - lg / 2;
pos.y = 330 - 20;
DrawText (m_pPixmap, pos, res);
sprintf (res, "%d", m_pSound->GetMidiVolume());
lg = GetTextWidth (res);
pos.x = (399 + 40) - lg / 2;
pos.y = 330 - 20;
DrawText (m_pPixmap, pos, res);
char *text = gettext ("No");
if (m_pMovie->GetEnable() && m_bMovie)
text = gettext ("Yes");
lg = GetTextWidth (text);
pos.x = (514 + 40) - lg / 2;
pos.y = 330 - 20;
DrawText (m_pPixmap, pos, text);
if (!m_scrollSpeed)
snprintf (res, sizeof (res), gettext ("None"));
else
sprintf (res, "%d", m_scrollSpeed);
lg = GetTextWidth (res);
pos.x = (169 + 40) - lg / 2;
pos.y = 330 - 20;
DrawText (m_pPixmap, pos, res);
}
// Affiche le texte de fin de la version demo.
if (m_phase == WM_PHASE_BYE)
{
char *text;
text = gettext ("You have played Planet Blupi.");
lg = GetTextWidth (text);
pos.x = LXIMAGE / 2 - lg / 2;
pos.y = 20;
DrawText (m_pPixmap, pos, text);
text = gettext ("We hope you have had as much fun playing the game as we had making it !");
lg = GetTextWidth (text);
pos.x = LXIMAGE / 2 - lg / 2;
pos.y = 40;
DrawText (m_pPixmap, pos, text);
text = gettext ("This game is an original creation of EPSITEC SA, CH-1092 Belmont");
lg = GetTextWidth (text);
pos.x = LXIMAGE / 2 - lg / 2;
pos.y = 430;
DrawText (m_pPixmap, pos, text);
text = gettext ("http://www.blupi.com blupi@epsitec.ch");
lg = GetTextWidth (text);
pos.x = LXIMAGE / 2 - lg / 2;
pos.y = 450;
DrawText (m_pPixmap, pos, text);
}
// Affiche le texte lorsqu'il faut insérer le CD-Rom.
if (m_phase == WM_PHASE_INSERT)
DrawTextCenter (
gettext ("Insert CD-Rom Planet Blupi and wait a few seconds..."), LXIMAGE / 2,
20);
if (m_phase == WM_PHASE_BUILD)
SetEnable (WM_PHASE_UNDO, m_pDecor->IsUndo());
// Dessine les tool tips (info bulle).
if (m_textToolTips[0] != 0)
DrawText (m_pPixmap, m_posToolTips, m_textToolTips);
return true;
}
// Retourne le lutin à utiliser à une position donnée.
MouseSprites CEvent::MousePosToSprite (POINT pos)
{
MouseSprites sprite;
bool bUp = false, bDown = false, bLeft = false, bRight = false;
sprite = SPRITE_POINTER;
if (m_phase == WM_PHASE_PLAY ||
m_phase == WM_PHASE_BUILD)
{
if (pos.x >= POSMAPX && pos.x <= POSMAPX + DIMMAPX &&
pos.y >= POSMAPY && pos.y <= POSMAPY + DIMMAPY)
sprite = SPRITE_MAP;
if (m_bFullScreen &&
!m_bDemoRec &&
!m_bDemoPlay &&
m_scrollSpeed != 0)
{
if (pos.x <= 5 && pos.x >= -2)
bLeft = true;
if (pos.x >= LXIMAGE - 5 && pos.x <= LXIMAGE + 2)
bRight = true;
if (pos.y <= 5 && pos.y >= -2)
bUp = true;
if (pos.y >= LYIMAGE - 5 && pos.y <= LYIMAGE + 2)
bDown = true;
if (bLeft)
sprite = SPRITE_ARROWL;
if (bRight)
sprite = SPRITE_ARROWR;
if (bUp)
sprite = SPRITE_ARROWU;
if (bDown)
sprite = SPRITE_ARROWD;
if (bLeft && bUp)
sprite = SPRITE_ARROWUL;
if (bLeft && bDown)
sprite = SPRITE_ARROWDL;
if (bRight && bUp)
sprite = SPRITE_ARROWUR;
if (bRight && bDown)
sprite = SPRITE_ARROWDR;
}
}
else if (m_phase == WM_PHASE_INTRO1 ||
m_phase == WM_PHASE_INTRO2)
sprite = SPRITE_POINTER;
else if (m_phase == WM_PHASE_BYE)
sprite = SPRITE_POINTER;
else
{
if (!MouseOnButton (pos))
sprite = SPRITE_ARROW;
}
if (m_bFillMouse && // bidon présent ?
pos.x >= POSDRAWX && pos.x <= POSDRAWX + DIMDRAWX &&
pos.y >= POSDRAWY && pos.y <= POSDRAWY + DIMDRAWY)
sprite = SPRITE_FILL;
if (m_bWaitMouse) // sablier présent ?
sprite = SPRITE_WAIT;
if (m_bHideMouse) // souris cachée ?
sprite = SPRITE_EMPTY;
return sprite;
}
// Gère le lutin de la souris.
void CEvent::MouseSprite (POINT pos)
{
m_mouseSprite = MousePosToSprite (pos);
m_pPixmap->ChangeSprite (m_mouseSprite);
}
// Met ou enlève le sablier de la souris.
void CEvent::WaitMouse (bool bWait)
{
m_bWaitMouse = bWait;
if (bWait)
m_mouseSprite = SPRITE_WAIT;
else
m_mouseSprite = MousePosToSprite (GetMousePos ());
m_pPixmap->SetMouseSprite (m_mouseSprite, m_bDemoPlay);
m_pPixmap->ChangeSprite (m_mouseSprite);
}
// Cache ou montre la souris.
void CEvent::HideMouse (bool bHide)
{
m_bHideMouse = bHide;
if (bHide)
m_mouseSprite = SPRITE_EMPTY;
else
m_mouseSprite = MousePosToSprite (GetMousePos ());
m_pPixmap->SetMouseSprite (m_mouseSprite, m_bDemoPlay);
m_pPixmap->ChangeSprite (m_mouseSprite);
}
// Traite les événements pour tous les boutons.
bool CEvent::EventButtons (const SDL_Event &event, POINT pos)
{
POINT test;
Sint32 lg, oldx, sound;
// Cherche le tool tips à utiliser pour la souris.
m_textToolTips[0] = 0;
oldx = m_posToolTips.x;
m_posToolTips.x = -1;
const auto progress = [&] (CJauge & progress, const char *text) -> bool
{
if (progress.GetHide())
return false;
test = progress.GetPos();
if (pos.x >= test.x
&& pos.x <= test.x + DIMJAUGEX
&& pos.y >= test.y
&& pos.y <= test.y + DIMJAUGEY)
{
snprintf (m_textToolTips, sizeof (m_textToolTips), "%s", text);
lg = GetTextWidth (m_textToolTips);
test.x += (DIMJAUGEX - lg) / 2;
test.y += 4;
m_posToolTips = test;
return true;
}
return false;
};
if (m_phase == WM_PHASE_PLAY)
{
const auto spotted = progress (m_jauges[0], gettext ("Blupi's energy"));
if (!spotted)
progress (m_jauges[1], gettext ("Work done"));
if (oldx != m_posToolTips.x)
{
for (Sint32 i = 0; i < 2; i++)
m_jauges[i].SetRedraw();
}
}
else
{
int i = 0;
assert (m_index >= 0);
while (table[m_index].buttons[i].message != 0)
{
const auto text = m_buttons[i].GetToolTips (pos);
if (text)
{
snprintf (m_textToolTips, sizeof (m_textToolTips), "%s", text);
lg = GetTextWidth (m_textToolTips);
pos.x += 10;
pos.y += 20;
if (pos.x > LXIMAGE - lg)
pos.x = LXIMAGE - lg;
if (pos.y > LYIMAGE - 14)
pos.y = LYIMAGE - 14;
m_posToolTips = pos;
break;
}
i ++;
}
}
if (m_phase == WM_PHASE_PLAY)
{
m_bHiliInfoButton = false;
if (pos.x > m_posInfoButton.x + 6 &&
pos.x < m_posInfoButton.x + DIMBUTTONX - 6 &&
pos.y > m_posInfoButton.y + 8 &&
pos.y < m_posInfoButton.y + DIMBUTTONY - 8)
{
m_bHiliInfoButton = true;
if (event.type == SDL_MOUSEBUTTONDOWN
&& (event.button.button == SDL_BUTTON_LEFT
|| event.button.button == SDL_BUTTON_RIGHT))
{
if (m_pDecor->GetInfoMode())
sound = SOUND_CLOSE;
else
sound = SOUND_OPEN;
m_pSound->PlayImage (sound, pos);
}
if (event.type == SDL_MOUSEBUTTONUP
&& (event.button.button == SDL_BUTTON_LEFT
|| event.button.button == SDL_BUTTON_RIGHT))
{
// Montre ou cache les infos tout en haut.
m_pDecor->SetInfoMode (!m_pDecor->GetInfoMode());
}
}
m_bHiliHelpButton = false;
if (m_posHelpButton.x != -1 &&
pos.x > m_posHelpButton.x &&
pos.x < m_posHelpButton.x + DIMBUTTONX &&
pos.y > m_posHelpButton.y &&
pos.y < m_posHelpButton.y + DIMBUTTONY)
{
m_bHiliHelpButton = true;
if (event.type == SDL_MOUSEBUTTONDOWN
&& (event.button.button == SDL_BUTTON_LEFT
|| event.button.button == SDL_BUTTON_RIGHT))
m_pSound->PlayImage (SOUND_CLICK, pos);
if (event.type == SDL_MOUSEBUTTONUP
&& (event.button.button == SDL_BUTTON_LEFT
|| event.button.button == SDL_BUTTON_RIGHT))
{
// Inverse le mode aide dans les infos.
m_bInfoHelp = !m_bInfoHelp;
if (m_bInfoHelp)
ReadLibelle (GetWorld(), false, true);
else
ReadLibelle (GetWorld() + 2, false, false);
}
}
}
if (m_phase == WM_PHASE_BUILD)
{
if (event.type == SDL_MOUSEBUTTONDOWN
&& (event.button.button == SDL_BUTTON_LEFT
|| event.button.button == SDL_BUTTON_RIGHT))
{
m_pDecor->HideTooltips (true); // plus de tooltips pour décor
}
if (event.type == SDL_MOUSEBUTTONUP
&& (event.button.button == SDL_BUTTON_LEFT
|| event.button.button == SDL_BUTTON_RIGHT))
m_pDecor->HideTooltips (false);
}
int i = 0;
assert (m_index >= 0);
while (table[m_index].buttons[i].message != 0)
{
if (m_buttons[i].TreatEvent (event))
return true;
i ++;
}
if (m_phase == WM_PHASE_PLAY)
{
if (m_menu.TreatEvent (event))
return true;
}
return false;
}
// Indique si la souris est sur un bouton.
bool CEvent::MouseOnButton (POINT pos)
{
Sint32 i;
if (m_index < 0)
return false;
i = 0;
while (table[m_index].buttons[i].message != 0)
{
if (m_buttons[i].MouseOnButton (pos))
return true;
i ++;
}
return false;
}
// Retourne l'index dans table pour une phase donnée.
Sint32 CEvent::SearchPhase (Uint32 phase)
{
Sint32 i = 0;
while (table[i].phase != 0)
{
if (table[i].phase == phase)
return i;
i ++;
}
return -1;
}
// Donne le numéro du monde.
Sint32 CEvent::GetWorld()
{
if (m_bPrivate)
return m_private;
if (m_bSchool)
return m_exercice;
else
return m_mission;
}
// Donne le numéro physique du monde.
Sint32 CEvent::GetPhysicalWorld()
{
if (m_bPrivate)
return m_private + 200;
if (m_bSchool)
return m_exercice;
else
return m_mission + 100;
}
Sint32 CEvent::GetImageWorld()
{
if (m_bPrivate)
return 2;
if (m_bSchool)
return 0;
else
return 1;
}
// Indique si l'aide est disponible.
bool CEvent::IsHelpHide()
{
bool bHide = true;
if (m_bHelp || m_pDecor->GetTotalTime() > DEF_TIME_HELP)
bHide = false;
if (m_bSchool || m_bPrivate)
{
bHide = true; // pas d'aide pour les exercices
}
return bHide;
}
// Change de phase.
bool CEvent::ChangePhase (Uint32 phase)
{
Sint32 index, world, time, total, music, i, max;
POINT totalDim, iconDim;
char filename[MAX_PATH];
char *pButtonExist;
bool bEnable, bHide;
Term *pTerm;
if (phase != WM_PHASE_SETUPp &&
phase != WM_PHASE_WRITEp &&
phase != WM_PHASE_PLAY)
m_pSound->StopMusic();
if (phase == WM_PHASE_SETUPp && m_bPause)
m_pSound->StopMusic();
m_textToolTips[0] = 0;
m_posToolTips.x = -1;
m_bPause = false;
m_keymod = 0;
m_bMouseDown = false;
m_debugPos.x = 0;
m_debugPos.y = 0;
m_pDecor->SetInfoMode (false);
m_bInfoHelp = false;
m_bHiliInfoButton = false;
m_bHiliHelpButton = false;
if (phase == WM_PHASE_INTRO1 ||
phase == WM_PHASE_INTRO2)
m_introTime = 0;
if (phase == WM_PHASE_INIT)
m_demoTime = 0;
if (phase == WM_PHASE_PLAY &&
!m_bDemoPlay &&
GetPhysicalWorld() >= 150 && // mission spéciale démo ?
GetPhysicalWorld() < 200)
{
DemoRecStart(); // début enregistrement
}
if (phase != WM_PHASE_PLAY)
{
DemoRecStop(); // stoppe l'enregistrement d'une démo
}
m_pDecor->UndoClose(); // libère le buffer undo
index = SearchPhase (phase);
if (index < 0)
return false;
HideMouse (false); // montre la souris
WaitMouse (true); // met le sablier
if (m_bBuildModify)
{
m_pDecor->InitAfterBuild();
m_bBuildModify = false;
}
if (m_phase == WM_PHASE_BUILD &&
phase == WM_PHASE_INFO) // quitte construction ?
{
m_pDecor->Write (GetPhysicalWorld(), false,
GetPhysicalWorld(), 0, 0); // écrit le monde
}
// FIXME: pause is better if the game is not stop but just interrupted
if (m_phase == WM_PHASE_PLAY && m_phase != phase)
m_pSound->StopAllSounds();
m_phase = phase; // change de phase
m_index = index;
strcpy (filename, table[m_index].backName);
if (strstr (filename, "%.3d") != nullptr) // "%.3d" dans le nom ?
sprintf (filename, table[m_index].backName, GetImageWorld());
totalDim.x = LXIMAGE;
totalDim.y = LYIMAGE;
iconDim.x = 0;
iconDim.y = 0;
if (!m_pPixmap->Cache (CHBACK, filename, totalDim, iconDim))
{
WaitMouse (false); // enlève le sablier
m_tryInsertCount = 40;
m_tryPhase = m_phase;
return ChangePhase (WM_PHASE_INSERT); // insérez le CD-Rom ...
}
if (m_phase == WM_PHASE_READ ||
m_phase == WM_PHASE_WRITE ||
m_phase == WM_PHASE_WRITEp)
{
for (i = 0 ; i < 10 ; i++)
{
if (m_pDecor->FileExist (i, true, world, time, total))
{
m_fileWorld[i] = world;
m_fileTime[i] = time;
}
else
m_fileWorld[i] = -1;
}
}
if (m_phase == WM_PHASE_INFO ||
m_phase == WM_PHASE_HISTORY0 ||
m_phase == WM_PHASE_HISTORY1)
{
if (!m_pDecor->Read (GetPhysicalWorld(), false,
world, time, total) && // lit le monde
!m_bAccessBuild &&
!m_bPrivate)
{
m_tryInsertCount = 40;
m_tryPhase = m_phase;
return ChangePhase (WM_PHASE_INSERT); // insérez le CD-Rom ...
}
m_pDecor->SetTime (0);
m_pDecor->SetTotalTime (0);
m_pDecor->SetInvincible (false);
m_pDecor->SetSuper (false);
}
if (m_phase == WM_PHASE_INFO ||
m_phase == WM_PHASE_STOP ||
m_phase == WM_PHASE_HELP ||
m_phase == WM_PHASE_HISTORY0 ||
m_phase == WM_PHASE_HISTORY1)
{
if (m_bPrivate)
PrivateLibelle();
else if (m_phase == WM_PHASE_INFO ||
m_phase == WM_PHASE_STOP)
{
if (m_bSchool)
ReadLibelle (GetWorld(), m_bSchool, false);
else
ReadLibelle (GetWorld() + 2, m_bSchool, false);
}
else if (m_phase == WM_PHASE_HELP)
ReadLibelle (GetWorld(), false, true);
else
{
if (m_phase == WM_PHASE_HISTORY0)
world = 0;
else
world = 1;
ReadLibelle (world, false, false);
}
}
if (m_phase == WM_PHASE_TESTCD)
{
if (m_pDecor->Read (0, false, world, time, total)) // lit un monde
{
return ChangePhase (WM_PHASE_INIT); // ok
}
else
{
m_tryInsertCount = 40;
m_tryPhase = m_phase;
return ChangePhase (WM_PHASE_INSERT); // insérez le CD-Rom ...
}
}
m_jauges[0].SetHide (true); // cache les jauges
m_jauges[1].SetHide (true);
CreateButtons(); // crée les boutons selon la phase
m_bMenu = false;
m_pDecor->HideTooltips (false);
m_menu.Delete();
m_pDecor->BlupiSetArrow (0, false); // enlève toutes les flèches
m_pDecor->ResetHili(); // enlève les mises en évidence
if (m_phase == WM_PHASE_PLAY)
{
m_pDecor->LoadImages();
m_pDecor->SetBuild (false);
m_pDecor->EnableFog (true);
m_pDecor->NextPhase (0); // refait la carte tout de suite
m_pDecor->StatisticInit();
m_pDecor->TerminatedInit();
m_bChangeCheat = true; // affiche les cheat-codes
}
if (m_phase == WM_PHASE_BUILD)
{
m_bBuildModify = true;
SetState (WM_DECOR1, 1);
SetMenu (WM_DECOR1, 0); // herbe
SetMenu (WM_DECOR2, 2); // arbre
SetMenu (WM_DECOR3, 1); // maison
SetMenu (WM_DECOR4, 2); // blupi fort
SetMenu (WM_DECOR5, 1); // feu
m_pDecor->LoadImages();
m_pDecor->SetBuild (true);
m_pDecor->EnableFog (false);
m_pDecor->BlupiDeselect();
m_pDecor->NextPhase (0); // refait la carte tout de suite
}
if (m_phase == WM_PHASE_INFO)
{
bEnable = true;
if (GetWorld() == 0)
bEnable = false;
SetEnable (WM_PREV, bEnable);
bEnable = true;
if (m_bAllMissions)
max = 99;
else
max = m_maxMission;
if (!m_bSchool &&
GetWorld() >= max)
bEnable = false;
if (!m_pDecor->FileExist (GetPhysicalWorld() + 1, false,
world, time, total))
bEnable = false;
if (m_bAccessBuild ||
m_pDecor->GetTotalTime() > DEF_TIME_HELP * 6)
bEnable = true;
if (GetWorld() >= 99)
bEnable = false;
if (m_bPrivate)
bEnable = GetWorld() < 20 - 1;
SetEnable (WM_NEXT, bEnable);
bHide = true;
if (m_bAccessBuild || m_bPrivate)
bHide = false;
SetHide (WM_PHASE_BUILD, bHide);
if (m_bSchool)
{
SetHide (WM_PHASE_SKILL1, true);
SetHide (WM_PHASE_SKILL2, true);
}
else
{
SetState (WM_PHASE_SKILL1, m_pDecor->GetSkill() == 0 ? 1 : 0);
SetState (WM_PHASE_SKILL2, m_pDecor->GetSkill() == 1 ? 1 : 0);
}
}
if (m_phase == WM_PHASE_STOP)
SetHide (WM_PHASE_HELP, IsHelpHide());
if (m_phase == WM_PHASE_READ)
{
for (i = 0 ; i < 10 ; i++)
{
if (m_fileWorld[i] == -1)
SetEnable (WM_READ0 + i, false);
}
}
if (m_phase == WM_PHASE_BUTTON)
{
pButtonExist = m_pDecor->GetButtonExist();
for (i = 0 ; i < MAXBUTTON ; i++)
SetState (WM_BUTTON0 + i, pButtonExist[i]);
}
if (m_phase == WM_PHASE_TERM)
{
pTerm = m_pDecor->GetTerminated();
SetState (WM_BUTTON1, pTerm->bHachBlupi ? 1 : 0);
SetState (WM_BUTTON2, pTerm->bHachPlanche ? 1 : 0);
SetState (WM_BUTTON3, pTerm->bStopFire ? 1 : 0);
SetState (WM_BUTTON8, pTerm->bHomeBlupi ? 1 : 0);
SetState (WM_BUTTON9, pTerm->bKillRobots ? 1 : 0);
SetState (WM_BUTTON10, pTerm->bHachTomate ? 1 : 0);
SetState (WM_BUTTON11, pTerm->bHachMetal ? 1 : 0);
SetState (WM_BUTTON12, pTerm->bHachRobot ? 1 : 0);
}
if (m_phase == WM_PHASE_MUSIC)
{
music = m_pDecor->GetMusic();
for (i = 0 ; i < 10 ; i++)
SetState (WM_BUTTON1 + i, music == i ? 1 : 0);
}
if (m_phase == WM_PHASE_REGION)
{
music = m_pDecor->GetRegion();
for (i = 0 ; i < 4 ; i++)
SetState (WM_BUTTON1 + i, music == i ? 1 : 0);
}
if (m_phase == WM_PHASE_PLAY ||
m_phase == WM_PHASE_MUSIC)
{
if (m_pSound->IsPlayingMusic())
{
m_pSound->AdaptVolumeMusic(); // adapte le volume
}
else
{
music = m_pDecor->GetMusic();
if (music > 0)
{
sprintf (filename, "sound/music%.3d.blp", music - 1);
m_pSound->StopMusic();
m_pSound->PlayMusic (filename);
}
}
}
if (phase == WM_PHASE_H0MOVIE)
{
strcpy (m_movieToStart, "movie/history0.mkv");
m_phaseAfterMovie = WM_PHASE_HISTORY0;
}
if (phase == WM_PHASE_H1MOVIE)
{
strcpy (m_movieToStart, "movie/history1.mkv");
m_phaseAfterMovie = WM_PHASE_HISTORY1;
}
if (phase == WM_PHASE_H2MOVIE)
{
strcpy (m_movieToStart, "movie/history2.mkv");
m_phaseAfterMovie = WM_PHASE_INFO;
}
if (phase == WM_PHASE_PLAYMOVIE)
{
sprintf (m_movieToStart, "movie/play%.3d.mkv", GetPhysicalWorld());
m_phaseAfterMovie = WM_PHASE_PLAY;
}
if (phase == WM_PHASE_WINMOVIE)
{
sprintf (m_movieToStart, "movie/win%.3d.mkv", GetPhysicalWorld());
m_phaseAfterMovie = WM_PHASE_WIN;
if (!m_bPrivate &&
m_pDecor->FileExist (GetPhysicalWorld(),
false, world, time, total) &&
!m_pDecor->FileExist (GetPhysicalWorld() + 1,
false, world, time, total))
m_phaseAfterMovie = WM_PHASE_LASTWIN;
}
WaitMouse (false); // enlève le sablier
return true;
}
// Retourne la phase en cours.
Uint32 CEvent::GetPhase()
{
return m_phase;
}
// Essaye de lire le CD-Rom.
void CEvent::TryInsert()
{
if (m_tryInsertCount == 0)
ChangePhase (m_tryPhase);
else
m_tryInsertCount --;
}
// Fait démarrer un film si nécessaire.
void CEvent::MovieToStart()
{
if (m_movieToStart[0] != 0) // y a-t-il un film à démarrer ?
{
HideMouse (true); // cache la souris
if (StartMovie (m_movieToStart))
{
m_phase = m_phaseAfterMovie; // prochaine phase normale
}
else
ChangePhase (m_phaseAfterMovie);
m_movieToStart[0] = 0;
}
}
// Décale le décor.
void CEvent::DecorShift (Sint32 dx, Sint32 dy)
{
POINT coin;
if (m_phase != WM_PHASE_PLAY &&
m_phase != WM_PHASE_BUILD)
return;
coin = m_pDecor->GetCoin();
coin.x += dx;
coin.y += dy;
m_pDecor->SetCoin (coin);
//? m_pDecor->NextPhase(0); // faudra refaire la carte tout de suite
}
// Décale le décor lorsque la souris touche un bord.
void CEvent::DecorAutoShift (POINT pos)
{
Sint32 max;
POINT offset;
m_bShift = false;
if (!m_bFullScreen ||
m_bDemoRec ||
m_bDemoPlay ||
m_scrollSpeed == 0)
return;
max = 4 - m_scrollSpeed; // max <- 3..1
if (m_phase == WM_PHASE_PLAY ||
m_phase == WM_PHASE_BUILD)
{
if (m_shiftPhase == 0) // début du shift ?
{
m_shiftOffset.x = 0;
m_shiftOffset.y = 0;
m_shiftVector.x = 0;
m_shiftVector.y = 0;
if (m_mouseSprite == SPRITE_ARROWL)
{
m_shiftOffset.x = +2;
m_shiftOffset.y = 0;
m_shiftVector.x = -1;
m_shiftVector.y = +1;
}
if (m_mouseSprite == SPRITE_ARROWR)
{
m_shiftOffset.x = -2;
m_shiftOffset.y = 0;
m_shiftVector.x = +1;
m_shiftVector.y = -1;
}
if (m_mouseSprite == SPRITE_ARROWU)
{
m_shiftOffset.x = 0;
m_shiftOffset.y = +2;
m_shiftVector.x = -1;
m_shiftVector.y = -1;
}
if (m_mouseSprite == SPRITE_ARROWD)
{
m_shiftOffset.x = 0;
m_shiftOffset.y = -2;
m_shiftVector.x = +1;
m_shiftVector.y = +1;
}
if (m_mouseSprite == SPRITE_ARROWUL)
{
m_shiftOffset.x = +1;
m_shiftOffset.y = +1;
m_shiftVector.x = -1;
m_shiftVector.y = 0;
}
if (m_mouseSprite == SPRITE_ARROWUR)
{
m_shiftOffset.x = -1;
m_shiftOffset.y = +1;
m_shiftVector.x = 0;
m_shiftVector.y = -1;
}
if (m_mouseSprite == SPRITE_ARROWDL)
{
m_shiftOffset.x = +1;
m_shiftOffset.y = -1;
m_shiftVector.x = 0;
m_shiftVector.y = +1;
}
if (m_mouseSprite == SPRITE_ARROWDR)
{
m_shiftOffset.x = -1;
m_shiftOffset.y = -1;
m_shiftVector.x = +1;
m_shiftVector.y = 0;
}
if (m_shiftVector.x != 0 ||
m_shiftVector.y != 0)
m_shiftPhase = max;
}
if (m_shiftPhase > 0)
{
m_bShift = true;
m_shiftPhase --;
offset.x = m_shiftOffset.x * (max - m_shiftPhase) * (DIMCELX / 2 / max);
offset.y = m_shiftOffset.y * (max - m_shiftPhase) * (DIMCELY / 2 / max);
m_pDecor->SetShiftOffset (offset);
if (m_shiftPhase == 0) // dernière phase ?
{
offset.x = 0;
offset.y = 0;
m_pDecor->SetShiftOffset (offset);
DecorShift (m_shiftVector.x, m_shiftVector.y);
}
}
}
}
// Indique su un shift est en cours.
bool CEvent::IsShift()
{
return m_bShift;
}
// Modifie le décor lorsque le bouton de la souris est pressé.
bool CEvent::PlayDown (POINT pos, const SDL_Event &event)
{
bool bDecor = false;
bool bMap = false;
Sint32 rank, button, h;
POINT cel;
m_pDecor->BlupiSetArrow (0, false); // enlève toutes les flèches
m_bMouseDown = false;
if (m_bMenu)
{
m_menu.Message();
m_bMenu = false;
m_pDecor->HideTooltips (false);
m_menu.Delete();
return true;
}
m_pDecor->StatisticDown (pos);
if (pos.x >= POSMAPX && pos.x <= POSMAPX + DIMMAPX &&
pos.y >= POSMAPY && pos.y <= POSMAPY + DIMMAPY)
bMap = true;
h = m_pDecor->GetInfoHeight() + POSDRAWY;
if (pos.x >= POSDRAWX && pos.x <= POSDRAWX + DIMDRAWX &&
pos.y >= h && pos.y <= h + DIMDRAWY)
bDecor = true;
if (!bDecor && !bMap)
return false;
cel = m_pDecor->ConvPosToCel (pos, true);
if (event.button.button == SDL_BUTTON_RIGHT)
{
if (bMap)
button = BUTTON_GO;
else
button = m_pDecor->GetDefButton (cel);
m_pDecor->BlupiGoal (cel, button);
return true;
}
if (bMap)
{
m_pDecor->SetCoin (cel, true);
m_pDecor->NextPhase (0); // faudra refaire la carte tout de suite
return true;
}
rank = m_pDecor->GetTargetBlupi (pos);
if (rank >= 0 &&
!m_pDecor->IsWorkBlupi (rank))
{
m_bHili = true;
m_bMouseDown = true;
m_pDecor->BlupiHiliDown (pos, !! (m_keymod & KMOD_SHIFT));
}
else
{
m_bHili = false;
m_bMouseDown = true;
}
return true;
}
// Modifie le décor lorsque la souris est déplacée.
bool CEvent::PlayMove (POINT pos, Uint16 mod)
{
if (m_bMenu)
{
if (!m_menu.IsExist())
{
m_bMenu = false;
m_pDecor->HideTooltips (false);
m_menu.Delete();
}
return true;
}
m_pDecor->StatisticMove (pos);
if (m_bMouseDown) // bouton souris pressé ?
{
if (m_bHili)
m_pDecor->BlupiHiliMove (pos);
else
m_pDecor->CelHili (pos, 0);
}
else
m_pDecor->CelHili (pos, 0);
return true;
}
// Modifie le décor lorsque le bouton de la souris est relâché.
bool CEvent::PlayUp (POINT pos, Uint16 mod)
{
static Sint32 table_sound_boing[3] =
{
SOUND_BOING1,
SOUND_BOING2,
SOUND_BOING3,
};
m_pDecor->StatisticUp (pos);
if (m_bMouseDown) // bouton souris pressé ?
{
if (m_bHili)
m_pDecor->BlupiHiliUp (pos);
else
{
m_pDecor->BlupiGetButtons (pos, m_menuNb, m_menuButtons,
m_menuErrors, m_menuTexts, m_menuPerso);
if (m_menuNb == 0)
m_pDecor->BlupiSound (-1, table_sound_boing[Random (0, 2)], pos);
else
{
m_menuCel = m_pDecor->ConvPosToCel (pos);
m_menuPos = pos;
m_menu.Create (m_pPixmap, m_pSound,
pos, m_menuNb, m_menuButtons, m_menuErrors,
m_menuTexts, m_menuPerso);
m_bMenu = true;
m_pDecor->HideTooltips (true); // plus de tooltips pour décor
}
}
}
m_bMouseDown = false;
return true;
}
// Clic dans un bouton.
// Message = WM_BUTTON0..WM_BUTTON39
void CEvent::ChangeButtons (Sint32 message)
{
Sint32 button, state, volume, max;
char *pButtonExist;
Term *pTerm;
if (m_phase == WM_PHASE_PLAY)
{
button = m_menuButtons[message - WM_BUTTON0];
m_pDecor->BlupiGoal (m_menuCel, button);
}
if (m_phase == WM_PHASE_BUTTON)
{
pButtonExist = m_pDecor->GetButtonExist();
state = GetState (message);
if (state == 0)
state = 1;
else
state = 0;
SetState (message, state); // pressé <-> relâché
pButtonExist[message - WM_BUTTON0] = state;
pButtonExist[BUTTON_DJEEP] = true;
pButtonExist[BUTTON_DARMURE] = true;
}
if (m_phase == WM_PHASE_TERM)
{
pTerm = m_pDecor->GetTerminated();
if (message == WM_BUTTON1 ||
message == WM_BUTTON2 ||
message == WM_BUTTON3 ||
message == WM_BUTTON8 ||
message == WM_BUTTON9 ||
message == WM_BUTTON10 ||
message == WM_BUTTON11 ||
message == WM_BUTTON12)
{
state = GetState (message);
if (state == 0)
state = 1;
else
state = 0;
SetState (message, state); // pressé <-> relâché
if (message == WM_BUTTON1)
pTerm->bHachBlupi = state;
if (message == WM_BUTTON2)
pTerm->bHachPlanche = state;
if (message == WM_BUTTON3)
pTerm->bStopFire = state;
if (message == WM_BUTTON8)
pTerm->bHomeBlupi = state;
if (message == WM_BUTTON9)
pTerm->bKillRobots = state;
if (message == WM_BUTTON10)
pTerm->bHachTomate = state;
if (message == WM_BUTTON11)
pTerm->bHachMetal = state;
if (message == WM_BUTTON12)
pTerm->bHachRobot = state;
}
if (message == WM_BUTTON4)
{
if (pTerm->nbMinBlupi > 1)
pTerm->nbMinBlupi --;
}
if (message == WM_BUTTON5)
{
if (pTerm->nbMinBlupi < 100)
pTerm->nbMinBlupi ++;
}
if (message == WM_BUTTON6)
{
if (pTerm->nbMaxBlupi > 1)
pTerm->nbMaxBlupi --;
}
if (message == WM_BUTTON7)
{
if (pTerm->nbMaxBlupi < 100)
pTerm->nbMaxBlupi ++;
}
}
if (m_phase == WM_PHASE_MUSIC)
{
m_pDecor->SetMusic (message - WM_BUTTON1);
ChangePhase (m_phase);
}
if (m_phase == WM_PHASE_REGION)
{
m_pDecor->SetRegion (message - WM_BUTTON1);
ChangePhase (WM_PHASE_BUILD);
}
if (m_phase == WM_PHASE_SETUP ||
m_phase == WM_PHASE_SETUPp)
{
if (message == WM_BUTTON1)
{
if (m_speed > 1)
m_speed = m_speed >> 1;
}
if (message == WM_BUTTON2)
{
if (m_bSpeed)
max = 8;
else
max = 2;
if (m_speed < max)
m_speed = m_speed << 1;
}
if (message == WM_BUTTON3)
{
volume = m_pSound->GetAudioVolume();
if (volume > 0)
m_pSound->SetAudioVolume (volume - 1);
}
if (message == WM_BUTTON4)
{
volume = m_pSound->GetAudioVolume();
if (volume < MAXVOLUME)
m_pSound->SetAudioVolume (volume + 1);
}
if (message == WM_BUTTON5)
{
volume = m_pSound->GetMidiVolume();
if (volume > 0)
{
m_pSound->SetMidiVolume (volume - 1);
m_pSound->AdaptVolumeMusic();
}
}
if (message == WM_BUTTON6)
{
volume = m_pSound->GetMidiVolume();
if (volume < MAXVOLUME)
{
m_pSound->SetMidiVolume (volume + 1);
m_pSound->AdaptVolumeMusic();
}
}
if (message == WM_BUTTON7)
m_bMovie = false;
if (message == WM_BUTTON8)
m_bMovie = true;
if (message == WM_BUTTON9)
{
if (m_scrollSpeed > 0)
m_scrollSpeed --;
}
if (message == WM_BUTTON10)
{
if (m_scrollSpeed < 3)
m_scrollSpeed ++;
}
}
}
// Met un sol si nécessaire sous un objet.
void CEvent::BuildFloor (POINT cel, Sint32 insIcon)
{
Sint32 iFloor, channel, icon;
if (insIcon == -1)
return; // supprime ?
if (insIcon < 6 || // petite plante ?
insIcon == 117) // bateau ?
return;
iFloor = 1; // herbe
if (insIcon == 28 || // laboratoire ?
insIcon == 61 || // cabane de jardin ?
insIcon == 113 || // maison ?
insIcon == 120) // usine ?
{
iFloor = 16; // sol brun foncé
}
if (insIcon == 122) // mine de fer ?
{
iFloor = 71; // sol avec minerai
}
if (insIcon == 99 || // station de recharge ?
insIcon == 100 || // usine ennemie ?
insIcon == 102 || // usine ennemie ?
insIcon == 104 || // usine ennemie ?
(insIcon >= 106 && insIcon <= 112) || // barrière ?
insIcon == 115 || // usine ennemie ?
insIcon == 17 || // usine ennemie ?
insIcon == 12) // fusée ?
{
iFloor = 67; // sol bleu ennemi
}
m_pDecor->GetFloor (cel, channel, icon);
if ((channel == CHFLOOR &&
icon >= 2 && icon <= 14) || // eau ou rive ?
iFloor != 1)
{
m_pDecor->PutFloor (cel, CHFLOOR, iFloor); // met un sol
m_pDecor->ArrangeFloor (cel);
}
}
// Enlève si nécessaire un objet sur l'eau.
void CEvent::BuildWater (POINT cel, Sint32 insIcon)
{
Sint32 channel, icon;
if (insIcon != 14)
return; // rien à faire si pas eau
m_pDecor->GetObject (cel, channel, icon);
if (channel == CHOBJECT &&
icon >= 6 && // objet (pas petite plante) ?
icon != 117) // pas bateau ?
{
m_pDecor->PutObject (cel, -1, -1); // enlève l'objet
m_pDecor->ArrangeObject (cel);
}
}
// Cette table donne les objets à construire en fonction
// du choix dans le menu.
static Sint32 tableFloor[] =
{
1, 49, 50, 51, 0, 0, 0, 0, 0, 0, // 0 herbe
20, 66, 79, 0, 0, 0, 0, 0, 0, 0, // 1 foncé
33, 46, 47, 48, 71, 0, 0, 0, 0, 0, // 2 terre
14, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 mer
15, 16, 17, 18, 19, 65, 67, 0, 0, 0, // 4 dalles
52, 80, 0, 0, 0, 0, 0, 0, 0, 0, // 5 couveuse
};
static Sint32 tableObject[] =
{
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 détruit
0, 4, 1, 2, 3, 5, 0, 0, 0, 0, // 1 plantes
6, 7, 8, 9, 10, 11, 0, 0, 0, 0, // 2 arbres
81, 83, 94, 0, 0, 0, 0, 0, 0, 0, // 5 fleurs
};
static Sint32 tableHome[] =
{
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 détruit
113, 61, 28, 120, 0, 0, 0, 0, 0, 0, // 1 maison
27, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 tour de protection
122, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 mine de fer
99, 100, 102, 104, 115, 17, 12, 0, 0, 0, // 4 ennemi
112, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5 barrière
26, 71, 0, 0, 0, 0, 0, 0, 0, 0, // 6 palissade
37, 38, 39, 40, 41, 42, 43, 0, 0, 0, // 7 rochers
36, 44, 60, 63, 80, 123, 14, 0, 0, 0, // 8 matières
85, 125, 93, 92, 0, 0, 0, 0, 0, 0, // 9 pièges
117, 118, 16, 0, 0, 0, 0, 0, 0, 0, // 10 véhicules
};
// Modifie le décor lorsque le bouton de la souris est pressé.
bool CEvent::BuildDown (POINT pos, Uint16 mod, bool bMix)
{
POINT cel;
Sint32 menu, channel, icon;
if (bMix && m_pDecor->MapMove (pos))
return true;
if (pos.x < POSDRAWX || pos.x > POSDRAWX + DIMDRAWX ||
pos.y < POSDRAWY || pos.y > POSDRAWY + DIMDRAWY)
return false;
if (bMix)
{
m_pDecor->UndoCopy(); // copie le décor pour undo év.
}
if (GetState (WM_DECOR1) == 1) // pose d'un sol
{
cel = m_pDecor->ConvPosToCel2 (pos);
menu = GetMenu (WM_DECOR1);
if (!m_pDecor->GetFloor (cel, channel, icon))
return false;
if (bMix && tableFloor[menu * 10 + m_lastFloor[menu]] == icon)
{
m_lastFloor[menu] ++;
if (tableFloor[menu * 10 + m_lastFloor[menu]] == 0)
m_lastFloor[menu] = 0;
}
if (mod & KMOD_CTRL) // touche Ctrl enfoncée ?
{
WaitMouse (true);
m_pDecor->ArrangeFill (cel, CHFLOOR, tableFloor[menu * 10 + m_lastFloor[menu]],
true);
WaitMouse (false);
}
else
{
icon = tableFloor[menu * 10 + m_lastFloor[menu]];
if (menu >= 1) // met un sol ?
{
BuildWater (cel, icon); // enlève les objets
}
m_pDecor->PutFloor (cel, CHFLOOR, icon);
m_pDecor->ArrangeFloor (cel);
}
}
if (GetState (WM_DECOR2) == 1) // pose d'un objet
{
cel = m_pDecor->ConvPosToCel2 (pos);
menu = GetMenu (WM_DECOR2);
if (!m_pDecor->GetObject (cel, channel, icon))
return false;
if (bMix && tableObject[menu * 10 + m_lastObject[menu]] == icon)
{
m_lastObject[menu] ++;
if (tableObject[menu * 10 + m_lastObject[menu]] == 0)
m_lastObject[menu] = 0;
}
if (mod & KMOD_CTRL) // touche Ctrl enfoncée ?
{
WaitMouse (true);
m_pDecor->ArrangeFill (cel, CHOBJECT,
tableObject[menu * 10 + m_lastObject[menu]], false);
WaitMouse (false);
}
else
{
icon = tableObject[menu * 10 + m_lastObject[menu]];
BuildFloor (cel, icon); // met un sol si nécessaire
m_pDecor->PutObject (cel, CHOBJECT, icon);
m_pDecor->ArrangeObject (cel);
}
}
if (GetState (WM_DECOR3) == 1) // pose d'un batiment
{
cel = m_pDecor->ConvPosToCel2 (pos);
menu = GetMenu (WM_DECOR3);
if (!m_pDecor->GetObject (cel, channel, icon))
return false;
if (bMix && tableHome[menu * 10 + m_lastHome[menu]] == icon)
{
m_lastHome[menu] ++;
if (tableHome[menu * 10 + m_lastHome[menu]] == 0)
m_lastHome[menu] = 0;
}
if (mod & KMOD_CTRL) // touche Ctrl enfoncée ?
{
WaitMouse (true);
m_pDecor->ArrangeFill (cel, CHOBJECT, tableHome[menu * 10 + m_lastHome[menu]],
false);
WaitMouse (false);
}
else
{
icon = tableHome[menu * 10 + m_lastHome[menu]];
BuildFloor (cel, icon); // met un sol si nécessaire
m_pDecor->PutObject (cel, CHOBJECT, icon);
m_pDecor->ArrangeObject (cel);
}
}
if (GetState (WM_DECOR4) == 1) // pose d'un blupi
{
cel = m_pDecor->ConvPosToCel (pos);
menu = GetMenu (WM_DECOR4);
if (menu == 0) // supprime ?
m_pDecor->BlupiDelete (cel);
if (menu == 1) // ajoute blupi-fatigué ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 0, MAXENERGY / 4);
if (menu == 2) // ajoute blupi-énergique ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 0, MAXENERGY);
if (menu == 3) // ajoute assistant ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 8, MAXENERGY);
if (menu == 4) // ajoute araignée ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 1, MAXENERGY);
if (menu == 5) // ajoute virus ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 2, MAXENERGY);
if (menu == 6) // ajoute tracks ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 3, MAXENERGY);
if (menu == 7) // ajoute bombe ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 5, MAXENERGY);
if (menu == 8) // ajoute électro ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 7, MAXENERGY);
if (menu == 9) // ajoute robot ?
m_pDecor->BlupiCreate (cel, ACTION_STOP, DIRECT_S, 4, MAXENERGY);
}
if (GetState (WM_DECOR5) == 1) // pose d'une cata
{
cel = m_pDecor->ConvPosToCel2 (pos);
menu = GetMenu (WM_DECOR5);
if (menu == 0) // supprime ?
m_pDecor->SetFire (cel, false);
if (menu == 1) // ajoute ?
m_pDecor->SetFire (cel, true);
}
m_pDecor->ArrangeBlupi(); // supprime les blupi bloqués
return true;
}
// Modifie le décor lorsque la souris est déplacée.
bool CEvent::BuildMove (POINT pos, Uint16 mod, const SDL_Event &event)
{
if (event.motion.state & SDL_BUTTON (
SDL_BUTTON_LEFT)) // bouton souris pressé ?
BuildDown (pos, mod, false);
if (GetState (WM_DECOR4) == 1) // pose d'un blupi
m_pDecor->CelHili (pos, 1);
else
m_pDecor->CelHili (pos, 2);
return true;
}
// Modifie le décor lorsque le bouton de la souris est relâché.
bool CEvent::BuildUp (POINT pos)
{
return true;
}
// Démarre un film non interractif.
bool CEvent::StartMovie (const char *pFilename)
{
RECT rect;
if (!m_pMovie->GetEnable())
return false;
if (!m_bMovie)
return false;
if (!m_pMovie->IsExist (pFilename))
return false;
rect.left = 1; // mystère: plante avec 0,0,LXIMAGE,LYIMAGE !!!
rect.top = 1;
rect.right = LXIMAGE - 2;
rect.bottom = LYIMAGE - 2;
m_pSound->StopMusic();
if (!m_pMovie->Play (rect, pFilename))
return false;
m_bRunMovie = true;
return true;
}
// Stoppe un film non interractif.
void CEvent::StopMovie()
{
m_pMovie->Stop();
ChangePhase (m_phase);
m_bRunMovie = false;
}
// Indique s'il y a un film en cours.
bool CEvent::IsMovie()
{
return m_bRunMovie;
}
// Lit une partie (user000.blp).
void CEvent::Read (Sint32 message)
{
Sint32 world, time, total;
m_pDecor->Read (message - WM_READ0, true, world, time, total);
m_pDecor->SetTime (time);
m_pDecor->SetTotalTime (total);
if (world >= 200)
{
m_private = world - 200;
m_bSchool = false;
m_bPrivate = true;
}
else if (world >= 100)
{
m_mission = world - 100;
m_bSchool = false;
m_bPrivate = false;
}
else
{
m_exercice = world;
m_bSchool = true;
m_bPrivate = false;
}
}
// Ecrit une partie (user000.blp).
void CEvent::Write (Sint32 message)
{
Sint32 time, total;
time = m_pDecor->GetTime();
total = m_pDecor->GetTotalTime();
m_pDecor->Write (message - WM_WRITE0, true,
GetPhysicalWorld(), time, total);
}
// Initialise le libellé d'une mission privée.
void CEvent::PrivateLibelle()
{
Sint32 i, nb, h1, h2;
Term term;
char string[100];
char buffer[100];
const char *text = nullptr;
snprintf (m_libelle, sizeof (m_libelle), "%s", "1|Goal :");
memcpy (&term, m_pDecor->GetTerminated(), sizeof (Term));
nb = 0;
for (i = 0 ; i < 2 ; i++) // 2 objectifs au maximum !
{
text = nullptr;
if (term.bKillRobots)
{
term.bKillRobots = false;
text = gettext ("1|Kill all\n1|enemies !");
}
else if (term.bHachBlupi)
{
term.bHachBlupi = false;
text = gettext ("1|Go on striped\n1| paving stones.");
}
else if (term.bHachPlanche)
{
term.bHachPlanche = false;
text = gettext ("1|Drop planks on striped \n1|paving stones.");
}
else if (term.bHachTomate)
{
term.bHachTomate = false;
text = gettext ("1|Drop tomatoes on striped \n1|paving stones.");
}
else if (term.bHachMetal)
{
term.bHachMetal = false;
text = gettext ("1|Drop platinium on striped \n1|paving stones.");
}
else if (term.bHachRobot)
{
term.bHachRobot = false;
text = gettext ("1|The robot must reach\n1|the striped paving stones.");
}
else if (term.bHomeBlupi)
{
term.bHomeBlupi = false;
text = gettext ("1|Each Blupi in\n1|his house.");
}
else if (term.bStopFire)
{
term.bStopFire = false;
text = gettext ("1|Resist until\n1|fire extinction ...");
}
if (!text)
break;
strcat (m_libelle, "\n1|\n");
strcat (m_libelle, text);
nb ++;
}
if (nb == 0 || term.nbMaxBlupi > 1)
{
snprintf (buffer, sizeof (buffer),
"%s", "1|The Blupi population must \n1|be of at least %d Blupis.");
sprintf (string, buffer, term.nbMaxBlupi);
strcat (m_libelle, "\n1|\n");
strcat (m_libelle, string);
}
h1 = GetTextHeight (m_libelle, FONTLITTLE, 1);
h2 = GetTextHeight (m_libelle, FONTLITTLE, 2);
if (h2 > h1)
h1 = h2;
m_pDecor->SetInfoHeight (POSDRAWY + h1 + 10);
}
// Lit le libellé d'un monde.
bool CEvent::ReadLibelle (Sint32 world, bool bSchool, bool bHelp)
{
FILE *file = nullptr;
char *pBuffer = nullptr;
char *pText;
char *pDest;
char indic;
Sint32 h1, h2;
size_t nb;
if (bSchool)
indic = '$';
else
indic = '#';
if (bHelp)
indic = '@';
pBuffer = (char *)malloc (sizeof (char) * 50000);
if (pBuffer == nullptr)
goto error;
memset (pBuffer, 0, sizeof (char) * 50000);
file = fopen ((GetBaseDir() + "data/enigmes.blp").c_str(), "rb");
if (file == nullptr)
goto error;
nb = fread (pBuffer, sizeof (char), 50000 - 1, file);
pBuffer[nb] = 0;
pText = pBuffer;
while (world >= 0)
{
while (*pText != 0 && *pText != indic)
pText++;
if (*pText == indic)
pText++;
world --;
}
while (*pText != 0 && *pText != '\n')
pText++;
if (*pText == '\n')
pText++;
pDest = m_libelle;
while (*pText != 0 && *pText != indic &&
*pText != '$' && *pText != '#' && *pText != '@')
*pDest++ = *pText++;
*pDest = 0;
h1 = GetTextHeight (m_libelle, FONTLITTLE, 1);
h2 = GetTextHeight (m_libelle, FONTLITTLE, 2);
if (h2 > h1)
h1 = h2;
m_pDecor->SetInfoHeight (POSDRAWY + h1 + 10);
free (pBuffer);
fclose (file);
return true;
error:
if (pBuffer != nullptr)
free (pBuffer);
if (file != nullptr)
fclose (file);
return false;
}
// Sauve les informations sur disque.
bool CEvent::WriteInfo()
{
char filename[MAX_PATH];
FILE *file = nullptr;
DescInfo info;
size_t nb;
strcpy (filename, "data/info.blp");
AddUserPath (filename);
file = fopen (filename, "wb");
if (file == nullptr)
goto error;
info.majRev = 1;
info.minRev = 0;
info.prive = m_private;
info.exercice = m_exercice;
info.mission = m_mission;
info.maxMission = m_maxMission;
info.speed = m_speed;
info.bMovie = m_bMovie;
info.scrollSpeed = m_scrollSpeed;
info.bAccessBuild = m_bAccessBuild;
info.skill = m_pDecor->GetSkill();
info.audioVolume = m_pSound->GetAudioVolume();
info.midiVolume = m_pSound->GetMidiVolume();
nb = fwrite (&info, sizeof (DescInfo), 1, file);
if (nb < 1)
goto error;
fclose (file);
return true;
error:
if (file != nullptr)
fclose (file);
return false;
}
// Lit les informations sur disque.
bool CEvent::ReadInfo()
{
char filename[MAX_PATH];
FILE *file = nullptr;
DescInfo info;
size_t nb;
strcpy (filename, "data/info.blp");
AddUserPath (filename);
file = fopen (filename, "rb");
if (file == nullptr)
goto error;
nb = fread (&info, sizeof (DescInfo), 1, file);
if (nb < 1)
goto error;
m_private = info.prive;
m_exercice = info.exercice;
m_mission = info.mission;
m_maxMission = info.maxMission;
m_speed = info.speed;
m_bMovie = !!info.bMovie;
m_scrollSpeed = info.scrollSpeed;
m_bAccessBuild = !!info.bAccessBuild;
m_pDecor->SetSkill (info.skill);
m_pSound->SetAudioVolume (info.audioVolume);
m_pSound->SetMidiVolume (info.midiVolume);
fclose (file);
return true;
error:
if (file != nullptr)
fclose (file);
return false;
}
// Modifie la vitesse du jeu.
void CEvent::SetSpeed (Sint32 speed)
{
Sint32 max;
if (m_bSpeed)
max = 8;
else
max = 2;
if (speed > max)
speed = max;
m_speed = speed;
}
Sint32 CEvent::GetSpeed()
{
return m_speed;
}
bool CEvent::GetPause()
{
return m_bPause;
}
// Début de l'enregistrement d'une démo.
void CEvent::DemoRecStart()
{
m_pDemoBuffer = (DemoEvent *)malloc (MAXDEMO * sizeof (DemoEvent));
if (m_pDemoBuffer == nullptr)
return;
memset (m_pDemoBuffer, 0, MAXDEMO * sizeof (DemoEvent));
m_demoTime = 0;
m_demoIndex = 0;
m_bDemoRec = true;
m_bDemoPlay = false;
InitRandom();
m_pDecor->SetTime (0);
m_speed = 1;
}
// Fin de l'enregistrement d'une démo.
// Sauve le fichier sur disque.
void CEvent::DemoRecStop()
{
FILE *file = nullptr;
DemoHeader header;
if (m_bDemoPlay)
return;
if (m_pDemoBuffer != nullptr)
{
unlink ("data/demo.blp");
file = fopen ("data/demo.blp", "wb");
if (file != nullptr)
{
memset (&header, 0, sizeof (DemoHeader));
header.majRev = 1;
header.minRev = 0;
header.bSchool = m_bSchool;
header.bPrivate = m_bPrivate;
header.world = GetPhysicalWorld();
header.skill = m_pDecor->GetSkill();
fwrite (&header, sizeof (DemoHeader), 1, file);
fwrite (m_pDemoBuffer, sizeof (DemoEvent), m_demoIndex, file);
fclose (file);
}
free (m_pDemoBuffer);
m_pDemoBuffer = nullptr;
}
m_bDemoRec = false;
m_demoTime = 0;
}
// Début de la reproduction d'une démo.
// Lit le fichier sur disque.
bool CEvent::DemoPlayStart()
{
char filename[MAX_PATH];
FILE *file = nullptr;
DemoHeader header;
Sint32 world, time, total;
size_t nb;
m_pDemoBuffer = (DemoEvent *)malloc (MAXDEMO * sizeof (DemoEvent));
if (m_pDemoBuffer == nullptr)
return false;
memset (m_pDemoBuffer, 0, MAXDEMO * sizeof (DemoEvent));
sprintf (filename, (GetBaseDir() + "data/demo%.3d.blp").c_str(), m_demoNumber);
file = fopen (filename, "rb");
if (file == nullptr)
{
DemoPlayStop();
return false;
}
nb = fread (&header, sizeof (DemoHeader), 1, file);
if (nb < 1)
{
DemoPlayStop();
return false;
}
m_bSchool = !!header.bSchool;
m_bPrivate = !!header.bPrivate;
m_pDecor->SetSkill (header.skill);
m_demoEnd = fread (m_pDemoBuffer, sizeof (DemoEvent), MAXDEMO, file);
fclose (file);
m_demoTime = 0;
m_demoIndex = 0;
m_bDemoPlay = true;
m_bDemoRec = false;
if (!m_pDecor->Read (header.world, false, world, time, total))
{
DemoPlayStop();
return false;
}
ChangePhase (WM_PHASE_PLAY);
InitRandom();
m_pDecor->SetTime (0);
m_speed = 1;
return true;
}
// Fin de la reproduction d'une démo.
void CEvent::DemoPlayStop()
{
if (m_pDemoBuffer != nullptr)
{
free (m_pDemoBuffer);
m_pDemoBuffer = nullptr;
}
m_bDemoPlay = false;
m_bDemoRec = false;
m_demoTime = 0;
ChangePhase (WM_PHASE_INIT);
}
void CEvent::WinToSDLEvent (Uint32 msg, WPARAM wParam, LPARAM lParam,
SDL_Event &event)
{
#define GET_X_LPARAM(lp) ((Sint32) (Sint16) LOWORD (lp))
#define GET_Y_LPARAM(lp) ((Sint32) (Sint16) HIWORD (lp))
static const std::unordered_map<Uint32, SDL_Keysym> keycodes = {
{ '0', { SDL_SCANCODE_0, SDLK_0, 0, 0 } },
{ '1', { SDL_SCANCODE_1, SDLK_1, 0, 0 } },
{ '2', { SDL_SCANCODE_2, SDLK_2, 0, 0 } },
{ '3', { SDL_SCANCODE_3, SDLK_3, 0, 0 } },
{ '4', { SDL_SCANCODE_4, SDLK_4, 0, 0 } },
{ '5', { SDL_SCANCODE_5, SDLK_5, 0, 0 } },
{ '6', { SDL_SCANCODE_6, SDLK_6, 0, 0 } },
{ '7', { SDL_SCANCODE_7, SDLK_7, 0, 0 } },
{ '8', { SDL_SCANCODE_8, SDLK_8, 0, 0 } },
{ '9', { SDL_SCANCODE_9, SDLK_9, 0, 0 } },
{ 'A', { SDL_SCANCODE_A, SDLK_a, 0, 0 } },
{ 'B', { SDL_SCANCODE_B, SDLK_b, 0, 0 } },
{ 'C', { SDL_SCANCODE_C, SDLK_c, 0, 0 } },
{ 'D', { SDL_SCANCODE_D, SDLK_d, 0, 0 } },
{ 'E', { SDL_SCANCODE_E, SDLK_e, 0, 0 } },
{ 'F', { SDL_SCANCODE_F, SDLK_f, 0, 0 } },
{ 'G', { SDL_SCANCODE_G, SDLK_g, 0, 0 } },
{ 'H', { SDL_SCANCODE_H, SDLK_h, 0, 0 } },
{ 'I', { SDL_SCANCODE_I, SDLK_i, 0, 0 } },
{ 'J', { SDL_SCANCODE_J, SDLK_j, 0, 0 } },
{ 'K', { SDL_SCANCODE_K, SDLK_k, 0, 0 } },
{ 'L', { SDL_SCANCODE_L, SDLK_l, 0, 0 } },
{ 'M', { SDL_SCANCODE_M, SDLK_m, 0, 0 } },
{ 'N', { SDL_SCANCODE_N, SDLK_n, 0, 0 } },
{ 'O', { SDL_SCANCODE_O, SDLK_o, 0, 0 } },
{ 'P', { SDL_SCANCODE_P, SDLK_p, 0, 0 } },
{ 'Q', { SDL_SCANCODE_Q, SDLK_q, 0, 0 } },
{ 'R', { SDL_SCANCODE_R, SDLK_r, 0, 0 } },
{ 'S', { SDL_SCANCODE_S, SDLK_0, 0, 0 } },
{ 'T', { SDL_SCANCODE_T, SDLK_t, 0, 0 } },
{ 'U', { SDL_SCANCODE_U, SDLK_u, 0, 0 } },
{ 'V', { SDL_SCANCODE_V, SDLK_v, 0, 0 } },
{ 'W', { SDL_SCANCODE_W, SDLK_w, 0, 0 } },
{ 'X', { SDL_SCANCODE_X, SDLK_x, 0, 0 } },
{ 'Y', { SDL_SCANCODE_Y, SDLK_y, 0, 0 } },
{ 'Z', { SDL_SCANCODE_Z, SDLK_z, 0, 0 } },
{ VK_LEFT, { SDL_SCANCODE_LEFT, SDLK_LEFT, 0, 0 } },
{ VK_UP, { SDL_SCANCODE_UP, SDLK_UP, 0, 0 } },
{ VK_RIGHT, { SDL_SCANCODE_RIGHT, SDLK_RIGHT, 0, 0 } },
{ VK_DOWN, { SDL_SCANCODE_DOWN, SDLK_DOWN, 0, 0 } },
{ VK_END, { SDL_SCANCODE_END, SDLK_END, 0, 0 } },
};
try
{
switch (msg)
{
case WM_KEYUP:
case WM_KEYDOWN:
event.type = msg == WM_KEYDOWN ? SDL_KEYDOWN : SDL_KEYUP;
event.key.keysym = keycodes.at (wParam);
// TODO: lParam
break;
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
event.type = msg == WM_LBUTTONDOWN ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
event.button.button = SDL_BUTTON_LEFT;
// TODO: wParam CTRL or SHIFT
event.button.x = GET_X_LPARAM (lParam);
event.button.y = GET_Y_LPARAM (lParam);
break;
case WM_RBUTTONUP:
case WM_RBUTTONDOWN:
event.type = msg == WM_RBUTTONDOWN ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
event.button.button = SDL_BUTTON_RIGHT;
// TODO: wParam CTRL or SHIFT
event.button.x = GET_X_LPARAM (lParam);
event.button.y = GET_Y_LPARAM (lParam);
break;
case WM_MOUSEMOVE:
event.type = SDL_MOUSEMOTION;
// TODO: wParam CTRL or SHIFT
event.motion.x = GET_X_LPARAM (lParam);
event.motion.y = GET_Y_LPARAM (lParam);
break;
}
}
catch (...)
{
SDL_LogError (SDL_LOG_CATEGORY_APPLICATION, "unsupported keycode");
}
}
// Avance l'index d'enregistrement ou de reproduction.
void CEvent::DemoStep()
{
Sint32 time;
Uint32 message;
WPARAM wParam;
LPARAM lParam;
if (m_phase == WM_PHASE_INIT)
{
if (m_demoTime > DEF_TIME_DEMO) // ~30 secondes écoulées ?
{
m_demoNumber = 0;
DemoPlayStart(); // démarre une démo automatique
}
}
if (m_bDemoPlay && // démo en lecture ?
m_pDemoBuffer != nullptr)
{
while (true)
{
time = m_pDemoBuffer[m_demoIndex].time;
if (time > m_demoTime)
break;
message = m_pDemoBuffer[m_demoIndex].message;
wParam = m_pDemoBuffer[m_demoIndex].wParam;
lParam = m_pDemoBuffer[m_demoIndex].lParam;
m_demoIndex ++;
if (message == WM_MOUSEMOVE)
{
POINT pos = ConvLongToPos (lParam);
SDL_WarpMouseInWindow (g_window, pos.x, pos.y);
}
SDL_Event event = { 0 };
CEvent::WinToSDLEvent (message, wParam, lParam, event);
TreatEventBase (event);
if (m_demoIndex >= m_demoEnd)
{
m_demoNumber ++; // démo suivante
if (!DemoPlayStart()) // démarre la démo suivante
{
m_demoNumber = 0; // première démo
DemoPlayStart(); // démarre la démo
}
return;
}
}
}
m_demoTime ++;
}
// Mémorise un événement.
void CEvent::DemoRecEvent (Uint32 message, WPARAM wParam, LPARAM lParam)
{
if (m_bDemoRec && m_pDemoBuffer != nullptr &&
(message == WM_KEYDOWN ||
message == WM_KEYUP ||
message == WM_LBUTTONDOWN ||
message == WM_RBUTTONDOWN ||
message == WM_MOUSEMOVE ||
message == WM_LBUTTONUP ||
message == WM_RBUTTONUP))
{
if (m_demoIndex > 0 &&
message == WM_MOUSEMOVE &&
m_pDemoBuffer[m_demoIndex - 1].time == m_demoTime &&
m_pDemoBuffer[m_demoIndex - 1].message == message)
{
m_pDemoBuffer[m_demoIndex - 1].wParam = static_cast<Uint32> (wParam);
m_pDemoBuffer[m_demoIndex - 1].lParam = static_cast<Uint32> (lParam);
}
else
{
m_pDemoBuffer[m_demoIndex].time = m_demoTime;
m_pDemoBuffer[m_demoIndex].message = message;
m_pDemoBuffer[m_demoIndex].wParam = static_cast<Uint32> (wParam);
m_pDemoBuffer[m_demoIndex].lParam = static_cast<Uint32> (lParam);
m_demoIndex ++;
if (m_demoIndex >= MAXDEMO)
DemoRecStop();
}
}
}
// Retourne la dernière position de la souris.
POINT CEvent::GetLastMousePos()
{
return m_oldMousePos;
}
// Traitement d'un événement.
bool CEvent::TreatEvent (const SDL_Event &event)
{
if (m_bDemoPlay)
{
if (event.type == SDL_KEYDOWN ||
event.type == SDL_KEYUP ||
event.type == SDL_MOUSEBUTTONUP) // is the user clicking?
{
DemoPlayStop();
return true;
}
if (event.type == SDL_MOUSEMOTION) // is the user moving?
return true;
}
return TreatEventBase (event);
}
// Traitement d'un événement.
bool CEvent::TreatEventBase (const SDL_Event &event)
{
POINT pos;
Sint32 i, sound;
char c;
bool bEnable;
//DemoRecEvent(message, wParam, lParam); XXX: use SDL_Event
switch (event.type)
{
case SDL_KEYDOWN:
if (event.key.keysym.sym >= SDLK_a && event.key.keysym.sym <= SDLK_z)
{
if (m_posCheat == 0) // première lettre ?
{
m_rankCheat = -1;
for (i = 0 ; i < 9 ; i++)
{
if ((char) event.key.keysym.sym == cheat_code[i][0])
{
m_rankCheat = i;
break;
}
}
}
if (m_rankCheat != -1)
{
c = cheat_code[m_rankCheat][m_posCheat];
if (m_posCheat != 0 && m_rankCheat == 8)
c++; // CONSTRUIRE ?
if ((char) event.key.keysym.sym == c)
{
m_posCheat ++;
if (cheat_code[m_rankCheat][m_posCheat] == 0)
{
bEnable = true;
if (m_phase == WM_PHASE_PLAY)
{
if (m_rankCheat == 0) // vision ?
m_pDecor->EnableFog (false);
if (m_rankCheat == 1 || // power ?
m_rankCheat == 2) // lonesome ?
m_pDecor->BlupiCheat (m_rankCheat);
}
if (m_rankCheat == 3) // allmissions ?
{
m_bAllMissions = !m_bAllMissions;
bEnable = m_bAllMissions;
m_bChangeCheat = true;
}
if (m_rankCheat == 4) // quick ?
{
m_bSpeed = !m_bSpeed;
bEnable = m_bSpeed;
m_bChangeCheat = true;
}
if (m_rankCheat == 5) // helpme ?
{
m_bHelp = !m_bHelp;
bEnable = m_bHelp;
m_bChangeCheat = true;
}
if (m_rankCheat == 6) // invincible ?
{
m_pDecor->SetInvincible (!m_pDecor->GetInvincible());
bEnable = m_pDecor->GetInvincible();
m_bChangeCheat = true;
}
if (m_rankCheat == 7) // superblupi ?
{
m_pDecor->SetSuper (!m_pDecor->GetSuper());
bEnable = m_pDecor->GetSuper();
m_bChangeCheat = true;
}
if (m_rankCheat == 8) // construire ?
{
m_bAccessBuild = !m_bAccessBuild;
bEnable = m_bAccessBuild;
m_bChangeCheat = true;
}
if (m_phase != WM_PHASE_PLAY)
ChangePhase (m_phase);
pos.x = LXIMAGE / 2;
pos.y = LYIMAGE / 2;
if (bEnable)
m_pSound->PlayImage (SOUND_BUT, pos);
else
m_pSound->PlayImage (SOUND_BOING, pos);
m_rankCheat = -1;
m_posCheat = 0;
}
return true;
}
}
}
m_rankCheat = -1;
m_posCheat = 0;
if (m_phase == WM_PHASE_INTRO1)
{
ChangePhase (WM_PHASE_INTRO2);
return true;
}
if (m_phase == WM_PHASE_INTRO2)
{
ChangePhase (WM_PHASE_INIT);
return true;
}
if (m_phase == WM_PHASE_BYE)
{
SDL_Event ev;
ev.type = SDL_QUIT;
SDL_PushEvent (&ev);
}
switch (event.key.keysym.sym)
{
case SDLK_END:
DemoRecStop();
return true;
case SDLK_ESCAPE:
if (m_bRunMovie)
{
StopMovie();
m_pSound->SetSuspendSkip (1);
return true;
}
if (m_phase == WM_PHASE_PLAY ||
m_phase == WM_PHASE_SETUP ||
m_phase == WM_PHASE_SETUPp ||
m_phase == WM_PHASE_READ ||
m_phase == WM_PHASE_WRITE ||
m_phase == WM_PHASE_WRITEp ||
m_phase == WM_PHASE_HELP)
{
ChangePhase (WM_PHASE_STOP);
return true;
}
if (m_phase == WM_PHASE_STOP ||
m_phase == WM_PHASE_LOST ||
m_phase == WM_PHASE_BUILD)
{
ChangePhase (WM_PHASE_INFO);
return true;
}
if (m_phase == WM_PHASE_INFO)
{
ChangePhase (WM_PHASE_INIT);
return true;
}
if (m_phase == WM_PHASE_BUTTON ||
m_phase == WM_PHASE_TERM ||
m_phase == WM_PHASE_MUSIC ||
m_phase == WM_PHASE_REGION)
{
ChangePhase (WM_PHASE_BUILD);
return true;
}
if (m_phase == WM_PHASE_INIT)
{
ChangePhase (WM_PHASE_BYE);
return true;
}
if (m_phase == WM_PHASE_BYE)
{
SDL_Event ev;
ev.type = SDL_QUIT;
SDL_PushEvent (&ev);
break;
}
return true;
case SDLK_RETURN:
if (m_phase == WM_PHASE_PLAY ||
m_phase == WM_PHASE_READ ||
m_phase == WM_PHASE_WRITE ||
m_phase == WM_PHASE_SETUP)
{
ChangePhase (WM_PHASE_STOP);
return true;
}
if (m_phase == WM_PHASE_INIT ||
m_phase == WM_PHASE_LOST ||
m_phase == WM_PHASE_BUILD)
{
ChangePhase (WM_PHASE_INFO);
return true;
}
if (m_phase == WM_PHASE_INFO ||
m_phase == WM_PHASE_STOP ||
m_phase == WM_PHASE_HELP ||
m_phase == WM_PHASE_SETUPp ||
m_phase == WM_PHASE_WRITEp)
{
ChangePhase (WM_PHASE_PLAY);
return true;
}
if (m_phase == WM_PHASE_BUTTON ||
m_phase == WM_PHASE_TERM ||
m_phase == WM_PHASE_MUSIC ||
m_phase == WM_PHASE_REGION)
{
ChangePhase (WM_PHASE_BUILD);
return true;
}
return true;
case SDLK_LEFT:
DecorShift (-2, 2);
return true;
case SDLK_RIGHT:
DecorShift (2, -2);
return true;
case SDLK_UP:
DecorShift (-3, -3);
return true;
case SDLK_DOWN:
DecorShift (3, 3);
return true;
case SDLK_HOME:
pos = m_pDecor->GetHome();
m_pDecor->SetCoin (pos);
return true;
case SDLK_SPACE:
if (m_bRunMovie)
{
StopMovie();
m_pSound->SetSuspendSkip (1);
return true;
}
m_pDecor->FlipOutline();
return true;
case SDLK_PAUSE:
m_bPause = !m_bPause;
if (m_phase == WM_PHASE_PLAY)
{
if (m_bPause)
m_pSound->SuspendMusic();
else
m_pSound->RestartMusic();
}
return true;
case SDLK_LSHIFT:
case SDLK_RSHIFT:
m_keymod |= KMOD_SHIFT;
break;
case SDLK_LCTRL:
case SDLK_RCTRL:
m_keymod |= KMOD_CTRL;
if (m_phase == WM_PHASE_BUILD)
{
m_bFillMouse = true;
MouseSprite (GetMousePos());
}
else
m_bFillMouse = false;
return true;
case SDLK_F1:
if (m_phase == WM_PHASE_PLAY)
{
// Montre ou cache les infos tout en haut.
if (m_pDecor->GetInfoMode())
sound = SOUND_CLOSE;
else
sound = SOUND_OPEN;
pos.x = LXIMAGE / 2;
pos.y = LYIMAGE / 2;
m_pSound->PlayImage (sound, pos);
m_pDecor->SetInfoMode (!m_pDecor->GetInfoMode());
}
return true;
case SDLK_F8:
if (m_phase == WM_PHASE_PLAY)
m_pDecor->MemoPos (0, !! (m_keymod & KMOD_CTRL));
return true;
case SDLK_F10:
if (m_phase == WM_PHASE_PLAY)
m_pDecor->MemoPos (1, !! (m_keymod & KMOD_CTRL));
return true;
case SDLK_F11:
if (m_phase == WM_PHASE_PLAY)
m_pDecor->MemoPos (2, !! (m_keymod & KMOD_CTRL));
return true;
case SDLK_F12:
if (m_phase == WM_PHASE_PLAY)
m_pDecor->MemoPos (3, !! (m_keymod & KMOD_CTRL));
return true;
}
break;
case SDL_KEYUP:
switch (event.key.keysym.sym)
{
case SDLK_LSHIFT:
case SDLK_RSHIFT:
m_keymod &= ~KMOD_SHIFT;
break;
case SDLK_LCTRL:
case SDLK_RCTRL:
m_keymod &= ~KMOD_CTRL;
m_bFillMouse = false;
MouseSprite (GetMousePos());
return true;
}
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button != SDL_BUTTON_LEFT
&& event.button.button != SDL_BUTTON_RIGHT)
break;
pos.x = event.button.x;
pos.y = event.button.y;
MouseSprite (pos);
//? DecorAutoShift(pos);
if (EventButtons (event, pos))
return true;
if (m_phase == WM_PHASE_BUILD)
{
if (BuildDown (pos, m_keymod))
return true;
}
if (m_phase == WM_PHASE_PLAY)
{
if (PlayDown (pos, event))
return true;
}
break;
case SDL_MOUSEMOTION:
pos.x = event.motion.x;
pos.y = event.motion.y;
m_oldMousePos = pos;
MouseSprite (pos);
if (EventButtons (event, pos))
return true;
if (m_phase == WM_PHASE_BUILD)
{
if (BuildMove (pos, m_keymod, event))
return true;
}
if (m_phase == WM_PHASE_PLAY)
{
if (PlayMove (pos, m_keymod))
return true;
}
break;
case SDL_MOUSEBUTTONUP:
if (event.button.button != SDL_BUTTON_LEFT
&& event.button.button != SDL_BUTTON_RIGHT)
break;
pos.x = event.button.x;
pos.y = event.button.y;
if (EventButtons (event, pos))
return true;
if (m_phase == WM_PHASE_BUILD)
{
if (BuildUp (pos))
return true;
}
if (m_phase == WM_PHASE_PLAY)
{
if (PlayUp (pos, m_keymod))
return true;
}
if (m_phase == WM_PHASE_BYE)
{
SDL_Event ev;
ev.type = SDL_QUIT;
SDL_PushEvent (&ev);
}
break;
case SDL_USEREVENT:
switch (event.user.code)
{
case WM_PHASE_DEMO:
m_demoNumber = 0;
DemoPlayStart();
break;
case WM_PHASE_SCHOOL:
m_bSchool = true;
m_bPrivate = false;
if (ChangePhase (WM_PHASE_INFO))
return true;
break;
case WM_PHASE_MISSION:
m_bSchool = false;
m_bPrivate = false;
if (m_mission == 0) // première mission ?
{
if (ChangePhase (WM_PHASE_H0MOVIE))
return true;
}
else
{
if (ChangePhase (WM_PHASE_INFO))
return true;
}
break;
case WM_PHASE_PRIVATE:
m_bSchool = false;
m_bPrivate = true;
if (ChangePhase (WM_PHASE_INFO))
return true;
break;
case WM_PHASE_INTRO1:
case WM_PHASE_INTRO2:
case WM_PHASE_INIT:
case WM_PHASE_HISTORY0:
case WM_PHASE_HISTORY1:
case WM_PHASE_INFO:
case WM_PHASE_PLAY:
case WM_PHASE_READ:
case WM_PHASE_WRITE:
case WM_PHASE_WRITEp:
case WM_PHASE_BUILD:
case WM_PHASE_BUTTON:
case WM_PHASE_TERM:
case WM_PHASE_STOP:
case WM_PHASE_HELP:
case WM_PHASE_MUSIC:
case WM_PHASE_REGION:
case WM_PHASE_SETUP:
case WM_PHASE_SETUPp:
case WM_PHASE_PLAYMOVIE:
case WM_PHASE_H0MOVIE:
case WM_PHASE_H1MOVIE:
case WM_PHASE_H2MOVIE:
case WM_PHASE_WINMOVIE:
case WM_PHASE_BYE:
if (ChangePhase (event.user.code))
return true;
break;
case WM_PHASE_UNDO:
m_pDecor->UndoBack(); // revient en arrière
break;
case WM_PREV:
m_pDecor->SetInvincible (false);
m_pDecor->SetSuper (false);
if (m_bPrivate)
{
if (m_private > 0)
{
m_private --;
if (ChangePhase (WM_PHASE_INFO))
return true;
}
}
else if (m_bSchool)
{
if (m_exercice > 0)
{
m_exercice --;
if (ChangePhase (WM_PHASE_INFO))
return true;
}
}
else
{
if (m_mission > 0)
{
m_mission --;
if (ChangePhase (WM_PHASE_INFO))
return true;
}
}
break;
case WM_NEXT:
m_pDecor->SetInvincible (false);
m_pDecor->SetSuper (false);
if (m_bPrivate)
{
if (m_private < 20 - 1)
{
m_private ++;
if (ChangePhase (WM_PHASE_INFO))
return true;
}
}
else if (m_bSchool)
{
if (m_exercice < 99)
{
m_exercice ++;
if (ChangePhase (WM_PHASE_INFO))
return true;
}
}
else
{
if (m_mission < 99)
{
m_mission ++;
if (m_maxMission < m_mission)
m_maxMission = m_mission;
if (ChangePhase (WM_PHASE_INFO))
return true;
}
}
break;
case WM_DECOR1:
SetState (WM_DECOR1, 1);
SetState (WM_DECOR2, 0);
SetState (WM_DECOR3, 0);
SetState (WM_DECOR4, 0);
SetState (WM_DECOR5, 0);
break;
case WM_DECOR2:
SetState (WM_DECOR1, 0);
SetState (WM_DECOR2, 1);
SetState (WM_DECOR3, 0);
SetState (WM_DECOR4, 0);
SetState (WM_DECOR5, 0);
break;
case WM_DECOR3:
SetState (WM_DECOR1, 0);
SetState (WM_DECOR2, 0);
SetState (WM_DECOR3, 1);
SetState (WM_DECOR4, 0);
SetState (WM_DECOR5, 0);
break;
case WM_DECOR4:
SetState (WM_DECOR1, 0);
SetState (WM_DECOR2, 0);
SetState (WM_DECOR3, 0);
SetState (WM_DECOR4, 1);
SetState (WM_DECOR5, 0);
break;
case WM_DECOR5:
SetState (WM_DECOR1, 0);
SetState (WM_DECOR2, 0);
SetState (WM_DECOR3, 0);
SetState (WM_DECOR4, 0);
SetState (WM_DECOR5, 1);
break;
case WM_PHASE_SKILL1:
m_pDecor->SetSkill (0);
SetState (WM_PHASE_SKILL1, true);
SetState (WM_PHASE_SKILL2, false);
break;
case WM_PHASE_SKILL2:
m_pDecor->SetSkill (1);
SetState (WM_PHASE_SKILL1, false);
SetState (WM_PHASE_SKILL2, true);
break;
case WM_BUTTON0:
case WM_BUTTON1:
case WM_BUTTON2:
case WM_BUTTON3:
case WM_BUTTON4:
case WM_BUTTON5:
case WM_BUTTON6:
case WM_BUTTON7:
case WM_BUTTON8:
case WM_BUTTON9:
case WM_BUTTON10:
case WM_BUTTON11:
case WM_BUTTON12:
case WM_BUTTON13:
case WM_BUTTON14:
case WM_BUTTON15:
case WM_BUTTON16:
case WM_BUTTON17:
case WM_BUTTON18:
case WM_BUTTON19:
case WM_BUTTON20:
case WM_BUTTON21:
case WM_BUTTON22:
case WM_BUTTON23:
case WM_BUTTON24:
case WM_BUTTON25:
case WM_BUTTON26:
case WM_BUTTON27:
case WM_BUTTON28:
case WM_BUTTON29:
case WM_BUTTON30:
case WM_BUTTON31:
case WM_BUTTON32:
case WM_BUTTON33:
case WM_BUTTON34:
case WM_BUTTON35:
case WM_BUTTON36:
case WM_BUTTON37:
case WM_BUTTON38:
case WM_BUTTON39:
ChangeButtons (event.user.code);
break;
case WM_READ0:
case WM_READ1:
case WM_READ2:
case WM_READ3:
case WM_READ4:
case WM_READ5:
case WM_READ6:
case WM_READ7:
case WM_READ8:
case WM_READ9:
Read (event.user.code);
ChangePhase (WM_PHASE_PLAY); // joue
break;
case WM_WRITE0:
case WM_WRITE1:
case WM_WRITE2:
case WM_WRITE3:
case WM_WRITE4:
case WM_WRITE5:
case WM_WRITE6:
case WM_WRITE7:
case WM_WRITE8:
case WM_WRITE9:
Write (event.user.code);
if (m_phase == WM_PHASE_WRITEp)
{
ChangePhase (WM_PHASE_PLAY); // joue
}
else
{
ChangePhase (WM_PHASE_STOP); // pause
}
break;
case WM_MOVIE:
StartMovie ("movie/essai.avi");
ChangePhase (WM_PHASE_INIT);
break;
}
}
return false;
}
// Passe les images d'introduction.
void CEvent::IntroStep()
{
m_introTime ++;
if (m_introTime > 20 * 3)
{
if (m_phase == WM_PHASE_INTRO1)
{
ChangePhase (WM_PHASE_INTRO2);
return;
}
if (m_phase == WM_PHASE_INTRO2)
{
ChangePhase (WM_PHASE_INIT);
return;
}
}
}
void CEvent::PushUserEvent (Sint32 code)
{
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = code;
event.user.data1 = nullptr;
event.user.data2 = nullptr;
SDL_PushEvent (&event);
}