mirror of
https://github.com/blupi-games/planetblupi
synced 2024-12-30 10:15:36 +01:00
6425 lines
152 KiB
C++
6425 lines
152 KiB
C++
/*
|
|
* This file is part of the planetblupi source code
|
|
* Copyright (C) 1997, Daniel Roux & EPSITEC SA
|
|
* Copyright (C) 2017-2019, Mathieu Schroeter
|
|
* http://epsitec.ch; http://www.blupi.org; http://github.com/blupi-games
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see http://gnu.org/licenses
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <ctime>
|
|
#include <set>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unordered_map>
|
|
|
|
#include "action.h"
|
|
#include "blupi.h"
|
|
#include "button.h"
|
|
#include "config.h"
|
|
#include "decor.h"
|
|
#include "def.h"
|
|
#include "event.h"
|
|
#include "gettext.h"
|
|
#include "menu.h"
|
|
#include "misc.h"
|
|
#include "movie.h"
|
|
#include "pixmap.h"
|
|
#include "platform.h"
|
|
#include "progress.h"
|
|
#include "sound.h"
|
|
#include "text.h"
|
|
|
|
#ifdef _WIN32
|
|
#define unlink _unlink
|
|
#define putenv _putenv
|
|
#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 {
|
|
// v1.0
|
|
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;
|
|
// v1.1
|
|
Sint16 language;
|
|
// v1.2
|
|
Sint16 musicMidi;
|
|
Sint16 fullScreen;
|
|
Sint16 zoom;
|
|
// v1.3
|
|
Sint16 renderQuality;
|
|
|
|
Sint16 reserve2[88];
|
|
} 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)
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// clang-format off
|
|
static Phase table[] =
|
|
{
|
|
{
|
|
EV_PHASE_TESTCD,
|
|
"init.png",
|
|
"back-stars.png",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_INTRO1,
|
|
"intro1.png",
|
|
"",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_INIT,
|
|
"init.png",
|
|
"back-stars.png",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
EV_PHASE_DEMO,
|
|
0, {1, 108},
|
|
16, 424 - 60 - 42 * 4 - 18,
|
|
{ translate ("Demo") },
|
|
},
|
|
{
|
|
EV_PHASE_SCHOOL,
|
|
0, {1, 79},
|
|
16, 424 - 60 - 42 * 3,
|
|
{ translate ("Training") },
|
|
},
|
|
{
|
|
EV_PHASE_MISSION,
|
|
0, {1, 80},
|
|
16, 424 - 60 - 42 * 2,
|
|
{ translate ("Missions") },
|
|
},
|
|
{
|
|
EV_PHASE_PRIVATE,
|
|
0, {1, 49},
|
|
16, 424 - 60 - 42 * 1,
|
|
{ translate ("Construction") },
|
|
},
|
|
{
|
|
EV_PHASE_SETTINGS,
|
|
0, {1, 47},
|
|
16, 424 - 60 - 42 * 0,
|
|
{ translate ("Global settings") }
|
|
},
|
|
{
|
|
EV_PHASE_BYE,
|
|
0, {1, 36},
|
|
16, 424,
|
|
{ translate ("Quit Planet Blupi") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_HISTORY0,
|
|
"history0.png",
|
|
"back-book.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
true,
|
|
{
|
|
{
|
|
EV_PHASE_INIT,
|
|
0, {1, 50},
|
|
42 + 42 * 0, 433,
|
|
{ translate ("Previous page") },
|
|
},
|
|
{
|
|
EV_PHASE_H1MOVIE,
|
|
0, {1, 51},
|
|
558 - 42 * 0, 433,
|
|
{ translate ("Next page") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_HISTORY1,
|
|
"history1.png",
|
|
"back-book.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
true,
|
|
{
|
|
{
|
|
EV_PHASE_HISTORY0,
|
|
0, {1, 50},
|
|
42 + 42 * 0, 433,
|
|
{ translate ("Previous page") },
|
|
},
|
|
{
|
|
EV_PHASE_H2MOVIE,
|
|
0, {1, 51},
|
|
558 - 42 * 0, 433,
|
|
{ translate ("Next page") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_INFO,
|
|
"info%.3d.png",
|
|
"back-book.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
false,
|
|
{
|
|
{
|
|
EV_PREV,
|
|
0, {1, 50},
|
|
558 - 42 * 2, 433,
|
|
{ translate ("Previous game") },
|
|
},
|
|
{
|
|
EV_PHASE_PLAYMOVIE,
|
|
0, {1, 48},
|
|
558 - 42 * 1, 433,
|
|
{ translate ("Play this game") },
|
|
},
|
|
{
|
|
EV_NEXT,
|
|
0, {1, 51},
|
|
558 - 42 * 0, 433,
|
|
{ translate ("Next game") },
|
|
},
|
|
{
|
|
EV_PHASE_READ,
|
|
0, {1, 52},
|
|
42 + 42 * 4, 433,
|
|
{ translate ("Open another game") },
|
|
},
|
|
{
|
|
EV_PHASE_SETUP,
|
|
0, {1, 47},
|
|
42 + 42 * 7, 433,
|
|
{ translate ("Settings") },
|
|
},
|
|
{
|
|
EV_PHASE_BUILD,
|
|
0, {1, 49},
|
|
42 + 42 * 8, 433,
|
|
{ translate ("Construct this game") },
|
|
},
|
|
{
|
|
EV_PHASE_SKILL1,
|
|
0, {1, 94},
|
|
150, 230,
|
|
{ translate ("Skill level") },
|
|
},
|
|
{
|
|
EV_PHASE_SKILL2,
|
|
0, {1, 95},
|
|
150, 230 + 42,
|
|
{ translate ("Skill level") },
|
|
},
|
|
{
|
|
EV_PHASE_INIT,
|
|
0, {1, 40},
|
|
42 + 42 * 0, 433,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_PLAY,
|
|
"play.png",
|
|
"",
|
|
CPixmap::Mode::EXPAND_REVERSABLE,
|
|
false,
|
|
{
|
|
{
|
|
EV_PHASE_STOP,
|
|
0, {1, 40},
|
|
10 + 42 * 0, 422,
|
|
{},
|
|
},
|
|
{
|
|
EV_PHASE_SETUPp,
|
|
0, {1, 47},
|
|
10 + 42 * 1, 422,
|
|
{},
|
|
},
|
|
{
|
|
EV_PHASE_WRITEp,
|
|
0, {1, 53},
|
|
10 + 42 * 2, 422,
|
|
{},
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_STOP,
|
|
"stop%.3d.png",
|
|
"back-book.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
false,
|
|
{
|
|
{
|
|
EV_PHASE_PLAY,
|
|
0, {1, 77},
|
|
558 - 42 * 1, 433,
|
|
{ translate ("Continue this game") },
|
|
},
|
|
{
|
|
EV_PHASE_READ,
|
|
0, {1, 52},
|
|
42 + 42 * 4, 433,
|
|
{ translate ("Open another game") },
|
|
},
|
|
{
|
|
EV_PHASE_WRITE,
|
|
0, {1, 53},
|
|
42 + 42 * 5, 433,
|
|
{ translate ("Save this game") },
|
|
},
|
|
{
|
|
EV_PHASE_SETUP,
|
|
0, {1, 47},
|
|
42 + 42 * 7, 433,
|
|
{ translate ("Settings") },
|
|
},
|
|
{
|
|
EV_PHASE_INFO,
|
|
0, {1, 78},
|
|
42 + 42 * 0, 433,
|
|
{ translate ("Quit this game") },
|
|
},
|
|
{
|
|
EV_PHASE_HELP,
|
|
0, {1, 86},
|
|
42 + 42 * 9, 433,
|
|
{ translate ("Help") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_HELP,
|
|
"help.png",
|
|
"back-book.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
true,
|
|
{
|
|
{
|
|
EV_PHASE_PLAY,
|
|
0, {1, 77},
|
|
558 - 42 * 1, 433,
|
|
{ translate ("Continue this game") },
|
|
},
|
|
{
|
|
EV_PHASE_READ,
|
|
0, {1, 52},
|
|
42 + 42 * 4, 433,
|
|
{ translate ("Open another game") },
|
|
},
|
|
{
|
|
EV_PHASE_WRITE,
|
|
0, {1, 53},
|
|
42 + 42 * 5, 433,
|
|
{ translate ("Save this game") },
|
|
},
|
|
{
|
|
EV_PHASE_SETUP,
|
|
0, {1, 47},
|
|
42 + 42 * 7, 433,
|
|
{ translate ("Settings") },
|
|
},
|
|
{
|
|
EV_PHASE_STOP,
|
|
0, {1, 50},
|
|
42 + 42 * 0, 433,
|
|
{ translate ("Previous page") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_SETUP,
|
|
"setup01.png",
|
|
"back-setup.png",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
EV_BUTTON1,
|
|
0, {1, 50},
|
|
54, 330,
|
|
{ translate ("Slower") },
|
|
},
|
|
{
|
|
EV_BUTTON2,
|
|
0, {1, 51},
|
|
54 + 40, 330,
|
|
{ translate ("Faster") },
|
|
},
|
|
{
|
|
EV_BUTTON3,
|
|
0, {1, 50},
|
|
284, 330,
|
|
{ translate ("Reduce volume") },
|
|
},
|
|
{
|
|
EV_BUTTON4,
|
|
0, {1, 51},
|
|
284 + 40, 330,
|
|
{ translate ("Increase volume") },
|
|
},
|
|
{
|
|
EV_BUTTON5,
|
|
0, {1, 50},
|
|
399, 330,
|
|
{ translate ("Reduce volume") },
|
|
},
|
|
{
|
|
EV_BUTTON6,
|
|
0, {1, 51},
|
|
399 + 40, 330,
|
|
{ translate ("Increase volume") },
|
|
},
|
|
{
|
|
EV_BUTTON7,
|
|
0, {1, 50},
|
|
514, 330,
|
|
{ translate ("No video") },
|
|
},
|
|
{
|
|
EV_BUTTON8,
|
|
0, {1, 51},
|
|
514 + 40, 330,
|
|
{ translate ("Show videos") },
|
|
},
|
|
{
|
|
EV_BUTTON9,
|
|
0, {1, 50},
|
|
169, 330,
|
|
{ translate ("Slower") },
|
|
},
|
|
{
|
|
EV_BUTTON10,
|
|
0, {1, 51},
|
|
169 + 40, 330,
|
|
{ translate ("Faster") },
|
|
},
|
|
{
|
|
EV_SETUP_EXIT,
|
|
0, {1, 40},
|
|
11, 424,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_SETUPp,
|
|
"setup01.png",
|
|
"back-setup.png",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
EV_BUTTON1,
|
|
0, {1, 50},
|
|
54, 330,
|
|
{ translate ("Slower") },
|
|
},
|
|
{
|
|
EV_BUTTON2,
|
|
0, {1, 51},
|
|
54 + 40, 330,
|
|
{ translate ("Faster") },
|
|
},
|
|
{
|
|
EV_BUTTON3,
|
|
0, {1, 50},
|
|
284, 330,
|
|
{ translate ("Reduce volume") },
|
|
},
|
|
{
|
|
EV_BUTTON4,
|
|
0, {1, 51},
|
|
284 + 40, 330,
|
|
{ translate ("Increase volume") },
|
|
},
|
|
{
|
|
EV_BUTTON5,
|
|
0, {1, 50},
|
|
399, 330,
|
|
{ translate ("Reduce volume") },
|
|
},
|
|
{
|
|
EV_BUTTON6,
|
|
0, {1, 51},
|
|
399 + 40, 330,
|
|
{ translate ("Increase volume") },
|
|
},
|
|
{
|
|
EV_BUTTON7,
|
|
0, {1, 50},
|
|
514, 330,
|
|
{ translate ("No video") },
|
|
},
|
|
{
|
|
EV_BUTTON8,
|
|
0, {1, 51},
|
|
514 + 40, 330,
|
|
{ translate ("Show videos") },
|
|
},
|
|
{
|
|
EV_BUTTON9,
|
|
0, {1, 50},
|
|
169, 330,
|
|
{ translate ("Slower") },
|
|
},
|
|
{
|
|
EV_BUTTON10,
|
|
0, {1, 51},
|
|
169 + 40, 330,
|
|
{ translate ("Faster") },
|
|
},
|
|
{
|
|
EV_PHASE_PLAY,
|
|
0, {1, 77},
|
|
11, 424,
|
|
{ translate ("Continue this game") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_READ,
|
|
"read.png",
|
|
"back-chest-r.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
false,
|
|
{
|
|
{
|
|
EV_READ0,
|
|
0, {0},
|
|
420, 30 + 42 * 0,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ1,
|
|
0, {0},
|
|
420, 30 + 42 * 1,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ2,
|
|
0, {0},
|
|
420, 30 + 42 * 2,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ3,
|
|
0, {0},
|
|
420, 30 + 42 * 3,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ4,
|
|
0, {0},
|
|
420, 30 + 42 * 4,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ5,
|
|
0, {0},
|
|
420, 30 + 42 * 5,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ6,
|
|
0, {0},
|
|
420, 30 + 42 * 6,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ7,
|
|
0, {0},
|
|
420, 30 + 42 * 7,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ8,
|
|
0, {0},
|
|
420, 30 + 42 * 8,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ9,
|
|
0, {0},
|
|
420, 30 + 42 * 9,
|
|
{},
|
|
},
|
|
{
|
|
EV_READ_EXIT,
|
|
0, {1, 40},
|
|
16, 424,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_WRITE,
|
|
"write.png",
|
|
"back-chest-w.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
false,
|
|
{
|
|
{
|
|
EV_WRITE0,
|
|
0, {0},
|
|
420, 30 + 42 * 0,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE1,
|
|
0, {0},
|
|
420, 30 + 42 * 1,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE2,
|
|
0, {0},
|
|
420, 30 + 42 * 2,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE3,
|
|
0, {0},
|
|
420, 30 + 42 * 3,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE4,
|
|
0, {0},
|
|
420, 30 + 42 * 4,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE5,
|
|
0, {0},
|
|
420, 30 + 42 * 5,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE6,
|
|
0, {0},
|
|
420, 30 + 42 * 6,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE7,
|
|
0, {0},
|
|
420, 30 + 42 * 7,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE8,
|
|
0, {0},
|
|
420, 30 + 42 * 8,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE9,
|
|
0, {0},
|
|
420, 30 + 42 * 9,
|
|
{},
|
|
},
|
|
{
|
|
EV_PHASE_STOP,
|
|
0, {1, 40},
|
|
16, 424,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_WRITEp,
|
|
"write.png",
|
|
"back-chest-w.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
false,
|
|
{
|
|
{
|
|
EV_WRITE0,
|
|
0, {0},
|
|
420, 30 + 42 * 0,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE1,
|
|
0, {0},
|
|
420, 30 + 42 * 1,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE2,
|
|
0, {0},
|
|
420, 30 + 42 * 2,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE3,
|
|
0, {0},
|
|
420, 30 + 42 * 3,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE4,
|
|
0, {0},
|
|
420, 30 + 42 * 4,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE5,
|
|
0, {0},
|
|
420, 30 + 42 * 5,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE6,
|
|
0, {0},
|
|
420, 30 + 42 * 6,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE7,
|
|
0, {0},
|
|
420, 30 + 42 * 7,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE8,
|
|
0, {0},
|
|
420, 30 + 42 * 8,
|
|
{},
|
|
},
|
|
{
|
|
EV_WRITE9,
|
|
0, {0},
|
|
420, 30 + 42 * 9,
|
|
{},
|
|
},
|
|
{
|
|
EV_PHASE_PLAY,
|
|
0, {1, 77},
|
|
16, 424,
|
|
{ translate ("Continue this game") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_LOST,
|
|
"lost.png",
|
|
"back-lost.png",
|
|
CPixmap::Mode::FIX,
|
|
true,
|
|
{
|
|
{
|
|
EV_PHASE_INFO,
|
|
0, {1, 50},
|
|
9, 431,
|
|
{ translate ("Restart this game") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_WIN,
|
|
"win.png",
|
|
"back-win.png",
|
|
CPixmap::Mode::FIX,
|
|
true,
|
|
{
|
|
{
|
|
EV_NEXT,
|
|
0, {1, 51},
|
|
9, 431,
|
|
{ translate ("Next game") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_LASTWIN,
|
|
"last%.3d.png",
|
|
"",
|
|
CPixmap::Mode::FIX,
|
|
true,
|
|
{
|
|
{
|
|
EV_PHASE_INIT,
|
|
0, {1, 51},
|
|
9, 431,
|
|
{ translate ("Next game") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_BUILD,
|
|
"build.png",
|
|
"",
|
|
CPixmap::Mode::EXPAND_REVERSABLE,
|
|
true,
|
|
{
|
|
{
|
|
EV_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")
|
|
},
|
|
},
|
|
{
|
|
EV_DECOR2, // pose des plantes
|
|
0, {4, 6, 7, 8, 11},
|
|
11 + 42 * 2, 190 + 42 * 1,
|
|
{
|
|
translate ("Delete item"),
|
|
translate ("Decorative plants"),
|
|
translate ("Tree"),
|
|
translate ("Flowers")
|
|
},
|
|
},
|
|
{
|
|
EV_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")
|
|
},
|
|
},
|
|
{
|
|
EV_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")
|
|
},
|
|
},
|
|
{
|
|
EV_DECOR5, // pose les catastrophes
|
|
0, {2, 36, 37},
|
|
11 + 42 * 2, 190 + 42 * 4,
|
|
{
|
|
translate ("Delete fire"),
|
|
translate ("Starting fire")
|
|
},
|
|
},
|
|
{
|
|
EV_PHASE_REGION,
|
|
0, {1, 5},
|
|
11 + 42 * 0, 190 + 42 * 1,
|
|
{ translate ("Scenery choice") },
|
|
},
|
|
{
|
|
EV_PHASE_MUSIC,
|
|
0, {1, 44},
|
|
11 + 42 * 0, 190 + 42 * 2,
|
|
{ translate ("Music choice") },
|
|
},
|
|
{
|
|
EV_PHASE_BUTTON,
|
|
0, {1, 46},
|
|
11 + 42 * 0, 190 + 42 * 3,
|
|
{ translate ("Available buttons") },
|
|
},
|
|
{
|
|
EV_PHASE_TERM,
|
|
0, {1, 45},
|
|
11 + 42 * 0, 190 + 42 * 4,
|
|
{ translate ("Ending conditions") },
|
|
},
|
|
{
|
|
EV_PHASE_INFO,
|
|
0, {1, 40},
|
|
11 + 42 * 0, 424,
|
|
{ translate ("Quit construction") },
|
|
},
|
|
{
|
|
EV_PHASE_UNDO,
|
|
0, {1, 87},
|
|
11 + 42 * 2, 424,
|
|
{ translate ("Cancel last operation") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_BUTTON,
|
|
"button.png",
|
|
"back-build.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
true,
|
|
{
|
|
{
|
|
EV_BUTTON1, // stop
|
|
0, {1, 40},
|
|
170 + 42 * 0, 30 + 52 * 0,
|
|
{ translate ("Stop") },
|
|
},
|
|
{
|
|
EV_BUTTON0, // go
|
|
0, {1, 24},
|
|
170 + 42 * 1, 30 + 52 * 0,
|
|
{ translate ("Go") },
|
|
},
|
|
{
|
|
EV_BUTTON3, // carry
|
|
0, {1, 30},
|
|
170 + 42 * 3, 30 + 52 * 0,
|
|
{ translate ("Take") },
|
|
},
|
|
{
|
|
EV_BUTTON4, // depose
|
|
0, {1, 31},
|
|
170 + 42 * 4, 30 + 52 * 0,
|
|
{ translate ("Drop") },
|
|
},
|
|
{
|
|
EV_BUTTON32, // répète
|
|
0, {1, 100},
|
|
170 + 42 * 6, 30 + 52 * 0,
|
|
{ translate ("Repeat") },
|
|
},
|
|
|
|
{
|
|
EV_BUTTON5, // abat
|
|
0, {1, 22},
|
|
170 + 42 * 0, 30 + 52 * 1,
|
|
{ translate ("Cut down a tree") },
|
|
},
|
|
{
|
|
EV_BUTTON16, // abat n
|
|
0, {1, 42},
|
|
170 + 42 * 1, 30 + 52 * 1,
|
|
{ translate ("Cut down trees") },
|
|
},
|
|
{
|
|
EV_BUTTON6, // roc
|
|
0, {1, 27},
|
|
170 + 42 * 3, 30 + 52 * 1,
|
|
{ translate ("Carve a rock") },
|
|
},
|
|
{
|
|
EV_BUTTON17, // roc n
|
|
0, {1, 43},
|
|
170 + 42 * 4, 30 + 52 * 1,
|
|
{ translate ("Carve rocks") },
|
|
},
|
|
{
|
|
EV_BUTTON22, // fleurs
|
|
0, {1, 54},
|
|
170 + 42 * 6, 30 + 52 * 1,
|
|
{ translate ("Make bunch of flowers") },
|
|
},
|
|
{
|
|
EV_BUTTON23, // fleurs n
|
|
0, {1, 55},
|
|
170 + 42 * 7, 30 + 52 * 1,
|
|
{ translate ("Make bunches of flowers") },
|
|
},
|
|
|
|
{
|
|
EV_BUTTON9, // build2 (couveuse)
|
|
0, {1, 25},
|
|
170 + 42 * 0, 30 + 52 * 2,
|
|
{ translate ("Incubator") },
|
|
},
|
|
{
|
|
EV_BUTTON15, // palis
|
|
0, {1, 26},
|
|
170 + 42 * 1, 30 + 52 * 2,
|
|
{ translate ("Palisade") },
|
|
},
|
|
{
|
|
EV_BUTTON18, // pont
|
|
0, {1, 23},
|
|
170 + 42 * 2, 30 + 52 * 2,
|
|
{ translate ("Bridge") },
|
|
},
|
|
{
|
|
EV_BUTTON25, // bateau
|
|
0, {1, 58},
|
|
170 + 42 * 3, 30 + 52 * 2,
|
|
{ translate ("Boat") },
|
|
},
|
|
{
|
|
EV_BUTTON13, // build6 (téléporteur)
|
|
0, {1, 101},
|
|
170 + 42 * 4, 30 + 52 * 2,
|
|
{ translate ("Teleporter") },
|
|
},
|
|
{
|
|
EV_BUTTON14, // mur
|
|
0, {1, 20},
|
|
170 + 42 * 6, 30 + 52 * 2,
|
|
{ translate ("Wall") },
|
|
},
|
|
{
|
|
EV_BUTTON19, // tour
|
|
0, {1, 33},
|
|
170 + 42 * 7, 30 + 52 * 2,
|
|
{ translate ("Protection tower") },
|
|
},
|
|
|
|
{
|
|
EV_BUTTON8, // build1 (cabane)
|
|
0, {1, 19},
|
|
170 + 42 * 0, 30 + 52 * 3,
|
|
{ translate ("Garden shed") },
|
|
},
|
|
{
|
|
EV_BUTTON7, // cultive
|
|
0, {1, 28},
|
|
170 + 42 * 1, 30 + 52 * 3,
|
|
{ translate ("Grow tomatoes") },
|
|
},
|
|
{
|
|
EV_BUTTON2, // mange
|
|
0, {1, 32},
|
|
170 + 42 * 2, 30 + 52 * 3,
|
|
{ translate ("Eat") },
|
|
},
|
|
|
|
{
|
|
EV_BUTTON10, // build3 (laboratoire)
|
|
0, {1, 35},
|
|
170 + 42 * 0, 30 + 52 * 4,
|
|
{ translate ("Laboratory") },
|
|
},
|
|
{
|
|
EV_BUTTON21, // laboratoire
|
|
0, {1, 39},
|
|
170 + 42 * 1, 30 + 52 * 4,
|
|
{ translate ("Transform") },
|
|
},
|
|
{
|
|
EV_BUTTON20, // boit
|
|
0, {1, 34},
|
|
170 + 42 * 2, 30 + 52 * 4,
|
|
{ translate ("Drink") },
|
|
},
|
|
{
|
|
EV_BUTTON24, // dynamite
|
|
0, {1, 41},
|
|
170 + 42 * 3, 30 + 52 * 4,
|
|
{ translate ("Blow up") },
|
|
},
|
|
|
|
{
|
|
EV_BUTTON27, // drapeau
|
|
0, {1, 64},
|
|
170 + 42 * 0, 30 + 52 * 5,
|
|
{ translate ("Prospect for iron") },
|
|
},
|
|
{
|
|
EV_BUTTON11, // build4 (mine)
|
|
0, {1, 61},
|
|
170 + 42 * 1, 30 + 52 * 5,
|
|
{ translate ("Mine") },
|
|
},
|
|
{
|
|
EV_BUTTON28, // extrait
|
|
0, {1, 62},
|
|
170 + 42 * 2, 30 + 52 * 5,
|
|
{ translate ("Extract iron") },
|
|
},
|
|
{
|
|
EV_BUTTON12, // build5 (usine)
|
|
0, {1, 59},
|
|
170 + 42 * 4, 30 + 52 * 5,
|
|
{ translate ("Workshop") },
|
|
},
|
|
{
|
|
EV_BUTTON29, // fabrique jeep
|
|
0, {1, 65},
|
|
170 + 42 * 5, 30 + 52 * 5,
|
|
{ translate ("Make a Jeep") },
|
|
},
|
|
{
|
|
EV_BUTTON30, // fabrique mine
|
|
0, {1, 63},
|
|
170 + 42 * 6, 30 + 52 * 5,
|
|
{ translate ("Make a time bomb") },
|
|
},
|
|
{
|
|
EV_BUTTON34, // fabrique armure
|
|
0, {1, 106},
|
|
170 + 42 * 7, 30 + 52 * 5,
|
|
{ translate ("Make armour") },
|
|
},
|
|
{
|
|
EV_BUTTON31, // fabrique disciple
|
|
0, {1, 83},
|
|
170 + 42 * 8, 30 + 52 * 5,
|
|
{ translate ("Make a helper robot") },
|
|
},
|
|
{
|
|
EV_PHASE_BUILD,
|
|
0, {1, 50},
|
|
11, 424,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_TERM,
|
|
"term.png",
|
|
"back-build.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
true,
|
|
{
|
|
{
|
|
EV_BUTTON8, // home blupi
|
|
0, {1, 81},
|
|
170 + 42 * 0, 30 + 42 * 0,
|
|
{ translate ("Blupi in house") },
|
|
},
|
|
{
|
|
EV_BUTTON9, // kill robots
|
|
0, {1, 57},
|
|
170 + 42 * 1, 30 + 42 * 0,
|
|
{ translate ("No more enemies") },
|
|
},
|
|
{
|
|
EV_BUTTON3, // stop fire
|
|
0, {1, 37},
|
|
170 + 42 * 2, 30 + 42 * 0,
|
|
{ translate ("Fire out") },
|
|
},
|
|
{
|
|
EV_BUTTON1, // hach blupi
|
|
0, {1, 14},
|
|
170 + 42 * 0, 30 + 42 * 2,
|
|
{ translate ("Blupi on striped paving stones") },
|
|
},
|
|
{
|
|
EV_BUTTON2, // hach planche
|
|
0, {1, 22},
|
|
170 + 42 * 1, 30 + 42 * 2,
|
|
{ translate ("Planks on striped paving stones") },
|
|
},
|
|
{
|
|
EV_BUTTON10, // hach tomate
|
|
0, {1, 28},
|
|
170 + 42 * 2, 30 + 42 * 2,
|
|
{ translate ("Tomatoes on striped paving stones") },
|
|
},
|
|
{
|
|
EV_BUTTON11, // hach métal
|
|
0, {1, 84},
|
|
170 + 42 * 3, 30 + 42 * 2,
|
|
{ translate ("Platinium on striped paving stones") },
|
|
},
|
|
{
|
|
EV_BUTTON12, // hach robot
|
|
0, {1, 94},
|
|
170 + 42 * 4, 30 + 42 * 2,
|
|
{ translate ("Robot on striped paving stones") },
|
|
},
|
|
{
|
|
EV_BUTTON4, // - min blupi
|
|
0, {1, 50},
|
|
170 + 42 * 0, 30 + 42 * 4,
|
|
{ "(-)" },
|
|
},
|
|
{
|
|
EV_BUTTON5, // + min blupi
|
|
0, {1, 51},
|
|
170 + 42 * 1, 30 + 42 * 4,
|
|
{ "(+)" },
|
|
},
|
|
{
|
|
EV_BUTTON6, // - max blupi
|
|
0, {1, 50},
|
|
170 + 42 * 0, 30 + 42 * 5,
|
|
{ "(-)" },
|
|
},
|
|
{
|
|
EV_BUTTON7, // + max blupi
|
|
0, {1, 51},
|
|
170 + 42 * 1, 30 + 42 * 5,
|
|
{ "(+)" },
|
|
},
|
|
{
|
|
EV_PHASE_BUILD,
|
|
0, {1, 50},
|
|
11, 424,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_MUSIC,
|
|
"music.png",
|
|
"back-build.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
true,
|
|
{
|
|
{
|
|
EV_BUTTON1,
|
|
0, {1, 40},
|
|
11, 101,
|
|
{ translate ("No music") },
|
|
},
|
|
{
|
|
EV_BUTTON2,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 0,
|
|
{ translate ("Music number 1") },
|
|
},
|
|
{
|
|
EV_BUTTON3,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 1,
|
|
{ translate ("Music number 2") },
|
|
},
|
|
{
|
|
EV_BUTTON4,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 2,
|
|
{ translate ("Music number 3") },
|
|
},
|
|
{
|
|
EV_BUTTON5,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 3,
|
|
{ translate ("Music number 4") },
|
|
},
|
|
{
|
|
EV_BUTTON6,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 4,
|
|
{ translate ("Music number 5") },
|
|
},
|
|
{
|
|
EV_BUTTON7,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 5,
|
|
{ translate ("Music number 6") },
|
|
},
|
|
{
|
|
EV_BUTTON8,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 6,
|
|
{ translate ("Music number 7") },
|
|
},
|
|
{
|
|
EV_BUTTON9,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 7,
|
|
{ translate ("Music number 8") },
|
|
},
|
|
{
|
|
EV_BUTTON10,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 8,
|
|
{ translate ("Music number 9") },
|
|
},
|
|
{
|
|
EV_BUTTON11,
|
|
0, {1, 44},
|
|
170 + 42 * 0, 30 + 42 * 9,
|
|
{ translate ("Music number 10") },
|
|
},
|
|
{
|
|
EV_PHASE_BUILD,
|
|
0, {1, 50},
|
|
11, 424,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_REGION,
|
|
"region.png",
|
|
"back-build.png",
|
|
CPixmap::Mode::FIX_REVERSABLE,
|
|
true,
|
|
{
|
|
{
|
|
EV_BUTTON1, // normal
|
|
0, {0},
|
|
220, 60,
|
|
{ translate ("Prairie") },
|
|
},
|
|
{
|
|
EV_BUTTON4, // sapins
|
|
0, {0},
|
|
220, 170,
|
|
{ translate ("Forest") },
|
|
},
|
|
{
|
|
EV_BUTTON2, // palmiers
|
|
0, {0},
|
|
220, 280,
|
|
{ translate ("Desert") },
|
|
},
|
|
{
|
|
EV_BUTTON3, // hivers
|
|
0, {0},
|
|
220, 390,
|
|
{ translate ("Forest under snow") },
|
|
},
|
|
{
|
|
EV_PHASE_BUILD,
|
|
0, {1, 50},
|
|
11, 424,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_PLAYMOVIE,
|
|
"movie.png",
|
|
"",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_WINMOVIE,
|
|
"movie.png",
|
|
"",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_H0MOVIE,
|
|
"movie.png",
|
|
"",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_H1MOVIE,
|
|
"movie.png",
|
|
"",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_H2MOVIE,
|
|
"movie.png",
|
|
"",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_BYE,
|
|
"bye.png",
|
|
"back-bye.png",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_INSERT,
|
|
"insert.png",
|
|
"",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
EV_PHASE_INIT,
|
|
0, {1, 40},
|
|
16, 424,
|
|
{ translate ("Quit Planet Blupi") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
EV_PHASE_SETTINGS,
|
|
"setup00.png",
|
|
"back-setup.png",
|
|
CPixmap::Mode::FIX,
|
|
false,
|
|
{
|
|
{
|
|
EV_BUTTON1,
|
|
0, {1, 50},
|
|
54, 330,
|
|
{ translate ("Previous language") },
|
|
},
|
|
{
|
|
EV_BUTTON2,
|
|
0, {1, 51},
|
|
54 + 40, 330,
|
|
{ translate ("Next language") },
|
|
},
|
|
{
|
|
EV_BUTTON3,
|
|
0, {1, 50},
|
|
169, 330,
|
|
{ translate ("Fullscreen") },
|
|
},
|
|
{
|
|
EV_BUTTON4,
|
|
0, {1, 51},
|
|
169 + 40, 330,
|
|
{ translate ("Windowed") },
|
|
},
|
|
{
|
|
EV_BUTTON5,
|
|
0, {1, 50},
|
|
284, 330,
|
|
{ "" /* dynamic */ },
|
|
},
|
|
{
|
|
EV_BUTTON6,
|
|
0, {1, 51},
|
|
284 + 40, 330,
|
|
{ "" /* dynamic */ },
|
|
},
|
|
{
|
|
EV_BUTTON7,
|
|
0, {1, 50},
|
|
399, 330,
|
|
{ translate ("Use Ogg music") },
|
|
},
|
|
{
|
|
EV_BUTTON8,
|
|
0, {1, 51},
|
|
399 + 40, 330,
|
|
{ translate ("Use Midi music (original)") },
|
|
},
|
|
{
|
|
EV_BUTTON9,
|
|
0, {1, 50},
|
|
514, 330,
|
|
{ translate ("Disable anti-aliasing") },
|
|
},
|
|
{
|
|
EV_BUTTON10,
|
|
0, {1, 51},
|
|
514 + 40, 330,
|
|
{ translate ("Enable anti-aliasing") },
|
|
},
|
|
{
|
|
EV_PHASE_INIT,
|
|
0, {1, 40},
|
|
42 + 42 * 0, 433,
|
|
{ translate ("Finish") },
|
|
},
|
|
{
|
|
0
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
0
|
|
}
|
|
};
|
|
// clang-format on
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Constructeur.
|
|
|
|
CEvent::CEvent ()
|
|
{
|
|
Sint32 i;
|
|
|
|
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_scrollSpeed = 1;
|
|
m_scrollSpeedPrev = -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_bStartRecording = false;
|
|
m_demoTime = 0;
|
|
m_keymod = 0;
|
|
m_posHelpButton = {-1, -1};
|
|
m_pPixmap = nullptr;
|
|
m_pDecor = nullptr;
|
|
m_pSound = nullptr;
|
|
m_pMovie = nullptr;
|
|
m_bMenu = false;
|
|
m_bHili = false;
|
|
m_demoIndex = 0;
|
|
m_demoEnd = 0;
|
|
m_bHiliInfoButton = false;
|
|
m_bHiliHelpButton = false;
|
|
|
|
memset (m_textToolTips, 0, sizeof (m_textToolTips));
|
|
memset (m_libelle, 0, sizeof (m_libelle));
|
|
|
|
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;
|
|
|
|
// TODO: should be dynamic by looking in the locale directory
|
|
m_Languages.push_back (Language::en);
|
|
m_Languages.push_back (Language::en_US);
|
|
m_Languages.push_back (Language::fr);
|
|
m_Languages.push_back (Language::de);
|
|
m_Languages.push_back (Language::it);
|
|
m_Languages.push_back (Language::pl);
|
|
m_Languages.push_back (Language::tr);
|
|
m_Languages.push_back (Language::pt);
|
|
m_Languages.push_back (Language::he);
|
|
|
|
this->m_LangStart = GetLocale ();
|
|
|
|
if (this->m_LangStart == "en_US")
|
|
m_Lang = m_Languages.begin () + 1;
|
|
else if (this->m_LangStart == "fr")
|
|
m_Lang = m_Languages.begin () + 2;
|
|
else if (this->m_LangStart == "de")
|
|
m_Lang = m_Languages.begin () + 3;
|
|
else if (this->m_LangStart == "it")
|
|
m_Lang = m_Languages.begin () + 4;
|
|
else if (this->m_LangStart == "pl")
|
|
m_Lang = m_Languages.begin () + 5;
|
|
else if (this->m_LangStart == "tr")
|
|
m_Lang = m_Languages.begin () + 6;
|
|
else if (this->m_LangStart == "pt")
|
|
m_Lang = m_Languages.begin () + 7;
|
|
else if (this->m_LangStart == "he")
|
|
m_Lang = m_Languages.begin () + 8;
|
|
else
|
|
m_Lang = m_Languages.begin ();
|
|
|
|
m_updateBlinking = 0;
|
|
|
|
this->shiftDirection = 0;
|
|
this->statDisabled = false;
|
|
}
|
|
|
|
// Destructeur.
|
|
|
|
CEvent::~CEvent ()
|
|
{
|
|
WriteInfo (); // lit le fichier "info.blp"
|
|
}
|
|
|
|
bool
|
|
CEvent::IsDemoPlaying ()
|
|
{
|
|
return this->m_bDemoPlay;
|
|
}
|
|
|
|
// 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, double prevScale)
|
|
{
|
|
g_bFullScreen = bFullScreen;
|
|
|
|
if (Platform::getType () == Platform::Type::JS)
|
|
return;
|
|
|
|
int x, y;
|
|
SDL_GetMouseState (&x, &y);
|
|
this->m_pPixmap->FromDisplayToGame (x, y, prevScale);
|
|
|
|
int displayIndex = SDL_GetWindowDisplayIndex (g_window);
|
|
#ifdef _WIN32
|
|
if (g_zoom == 2)
|
|
displayIndex = 0;
|
|
#endif /* _WIN32 */
|
|
|
|
SDL_RenderClear (g_renderer);
|
|
SDL_RenderPresent (g_renderer);
|
|
|
|
if (g_bFullScreen && g_zoom == 2)
|
|
{
|
|
int displays = SDL_GetNumVideoDisplays ();
|
|
|
|
std::vector<SDL_Rect> displayBounds;
|
|
for (int i = 0; i < displays; i++)
|
|
{
|
|
displayBounds.push_back (SDL_Rect ());
|
|
SDL_GetDisplayBounds (i, &displayBounds.back ());
|
|
}
|
|
|
|
/* It seems that the fullscreen switching works better when the window
|
|
* is at the top left corner of the current display.
|
|
*/
|
|
SDL_SetWindowPosition (
|
|
g_window, displayBounds[displayIndex].x, displayBounds[displayIndex].y);
|
|
}
|
|
|
|
SDL_SetWindowFullscreen (
|
|
g_window, bFullScreen ? (g_zoom == 1 ? SDL_WINDOW_FULLSCREEN_DESKTOP
|
|
: SDL_WINDOW_FULLSCREEN)
|
|
: 0);
|
|
SDL_SetWindowBordered (g_window, bFullScreen ? SDL_FALSE : SDL_TRUE);
|
|
SDL_SetWindowGrab (g_window, bFullScreen ? SDL_TRUE : SDL_FALSE);
|
|
|
|
m_pPixmap->LoadCursors ();
|
|
|
|
/* Force this update before otherwise the coordinates retrieved with
|
|
* the Warp SDL function are corresponding to the previous size.
|
|
*/
|
|
CEvent::PushUserEvent (EV_UPDATE);
|
|
|
|
auto coord = new SDL_Point; // Released by the event handler.
|
|
coord->x = x;
|
|
coord->y = y;
|
|
CEvent::PushUserEvent (EV_WARPMOUSE, coord);
|
|
}
|
|
|
|
/**
|
|
* \brief Change the size of the window.
|
|
*
|
|
* We use an integer scale to be sure that the pixels are always well formed.
|
|
*
|
|
* \param[in] newScale - The new scale.
|
|
*/
|
|
void
|
|
CEvent::SetWindowSize (Uint8 newScale)
|
|
{
|
|
auto scale = g_zoom;
|
|
g_zoom = newScale;
|
|
switch (newScale)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
SetWindowSize (scale, g_zoom);
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Change the size of the window.
|
|
*
|
|
* We use an integer scale to be sure that the pixels are always well formed.
|
|
*
|
|
* \param[in] prevScale - The current scale.
|
|
* \param[in] newScale - The new scale.
|
|
*/
|
|
void
|
|
CEvent::SetWindowSize (double prevScale, double newScale)
|
|
{
|
|
int x, y;
|
|
SDL_GetMouseState (&x, &y);
|
|
this->m_pPixmap->FromDisplayToGame (x, y, prevScale);
|
|
|
|
if (g_bFullScreen && newScale == 2)
|
|
newScale = 1;
|
|
|
|
SDL_SetWindowSize (g_window, LXIMAGE () * newScale, LYIMAGE () * newScale);
|
|
SDL_RenderClear (g_renderer);
|
|
SDL_RenderPresent (g_renderer);
|
|
|
|
int displayIndex = SDL_GetWindowDisplayIndex (g_window);
|
|
SDL_SetWindowPosition (
|
|
g_window, SDL_WINDOWPOS_CENTERED_DISPLAY (displayIndex),
|
|
SDL_WINDOWPOS_CENTERED_DISPLAY (displayIndex));
|
|
SDL_Delay (100);
|
|
|
|
m_pPixmap->LoadCursors ();
|
|
|
|
if (prevScale == newScale)
|
|
return;
|
|
|
|
/* Force this update before otherwise the coordinates retrieved with
|
|
* the Warp SDL function are corresponding to the previous size.
|
|
*/
|
|
CEvent::PushUserEvent (EV_UPDATE);
|
|
|
|
auto coord = new SDL_Point; // Released by the event handler.
|
|
coord->x = x;
|
|
coord->y = y;
|
|
CEvent::PushUserEvent (EV_WARPMOUSE, coord);
|
|
}
|
|
|
|
// 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);
|
|
|
|
pos.y += DIMJAUGEY + 2;
|
|
m_jauges[1].Create (m_pPixmap, m_pSound, pos, 3);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// Crée tous les boutons nécessaires à la phase en cours.
|
|
|
|
bool
|
|
CEvent::CreateButtons (Sint32 phase)
|
|
{
|
|
Sint32 i = 0, message;
|
|
Point pos;
|
|
|
|
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;
|
|
|
|
auto isRightReading =
|
|
((message == EV_PHASE_INIT || message == EV_PHASE_PLAY ||
|
|
message == EV_SETUP_EXIT) ||
|
|
(phase != EV_PHASE_SETTINGS && phase != EV_PHASE_SETUP &&
|
|
phase != EV_PHASE_SETUPp)) &&
|
|
IsRightReading ();
|
|
|
|
if (isRightReading)
|
|
pos.x = LXIMAGE () - pos.x - DIMBUTTONX;
|
|
|
|
if (
|
|
phase != EV_PHASE_PLAY && phase != EV_PHASE_BUILD &&
|
|
phase != EV_PHASE_INIT)
|
|
pos.x = isRightReading ? pos.x - LXOFFSET () : pos.x + LXOFFSET ();
|
|
|
|
if (m_bPrivate)
|
|
{
|
|
if (message == EV_PHASE_SKILL1)
|
|
{
|
|
pos.x = 117 + LXOFFSET ();
|
|
pos.y = 115;
|
|
if (isRightReading)
|
|
pos.x = LXIMAGE () - pos.x - DIMBUTTONX;
|
|
}
|
|
if (message == EV_PHASE_SKILL2)
|
|
{
|
|
pos.x = 117 + LXOFFSET ();
|
|
pos.y = 115 + 42;
|
|
if (isRightReading)
|
|
pos.x = LXIMAGE () - pos.x - DIMBUTTONX;
|
|
}
|
|
}
|
|
|
|
m_buttons[i].Create (
|
|
m_pPixmap, m_pSound, pos, table[m_index].buttons[i].type,
|
|
table[m_index].buttons[i].iconMenu + 1,
|
|
table[m_index].buttons[i].iconMenu[0], table[m_index].buttons[i].toolTips,
|
|
m_pDecor->GetRegion (), message, isRightReading);
|
|
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;
|
|
}
|
|
|
|
void
|
|
CEvent::SetUpdateVersion (const std::string & version)
|
|
{
|
|
this->m_updateVersion = version;
|
|
}
|
|
|
|
// 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 (
|
|
(m_phase == EV_PHASE_PLAY) ||
|
|
(m_phase != EV_PHASE_PLAY && m_phase != EV_PHASE_INSERT &&
|
|
m_phase != EV_PHASE_INTRO1 && m_phase != EV_PHASE_BYE))
|
|
{
|
|
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]);
|
|
|
|
if (text[0])
|
|
{
|
|
pos.x = 2;
|
|
pos.y = 2;
|
|
rect.left = pos.x;
|
|
rect.right = pos.x + 300;
|
|
rect.top = pos.y;
|
|
rect.bottom = pos.y + DIMLITTLEY;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, text, FONTLITTLE);
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_INIT)
|
|
{
|
|
snprintf (
|
|
res, sizeof (res), "%s %u.%u.%u%s", gettext ("Version"), PB_VERSION_MAJOR,
|
|
PB_VERSION_MINOR, PB_VERSION_PATCH, PB_VERSION_EXTRA);
|
|
pos.x = IsRightReading () ? 4 + GetTextWidth (res, FONTLITTLE)
|
|
: LXIMAGE () - GetTextWidth (res, FONTLITTLE) - 4;
|
|
pos.y = 465;
|
|
DrawText (m_pPixmap, pos, res, FONTLITTLE);
|
|
|
|
if (!this->m_updateVersion.empty () && this->m_updateBlinking++ % 80 < 40)
|
|
{
|
|
pos.x = 70 + LXOFFSET ();
|
|
pos.y = 465;
|
|
snprintf (
|
|
res, sizeof (res),
|
|
gettext ("New version available for download on www.blupi.org (v%s)"),
|
|
this->m_updateVersion.c_str ());
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, res, FONTLITTLE);
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_SETUP || m_phase == EV_PHASE_SETUPp)
|
|
{
|
|
bEnable = true;
|
|
if (m_speed == 1)
|
|
bEnable = false;
|
|
SetEnable (EV_BUTTON1, bEnable);
|
|
bEnable = true;
|
|
if (m_speed >= (m_bSpeed ? 8 : 2))
|
|
bEnable = false;
|
|
SetEnable (EV_BUTTON2, bEnable);
|
|
|
|
volume = m_pSound->GetAudioVolume ();
|
|
bEnable = true;
|
|
if (volume == 0)
|
|
bEnable = false;
|
|
SetEnable (EV_BUTTON3, bEnable);
|
|
bEnable = true;
|
|
if (volume >= MAXVOLUME)
|
|
bEnable = false;
|
|
SetEnable (EV_BUTTON4, bEnable);
|
|
|
|
volume = m_pSound->GetMidiVolume ();
|
|
bEnable = true;
|
|
if (volume == 0)
|
|
bEnable = false;
|
|
SetEnable (EV_BUTTON5, bEnable);
|
|
bEnable = true;
|
|
if (volume >= MAXVOLUME)
|
|
bEnable = false;
|
|
SetEnable (EV_BUTTON6, bEnable);
|
|
|
|
if (m_pMovie->GetEnable ())
|
|
{
|
|
SetEnable (EV_BUTTON7, m_bMovie);
|
|
SetEnable (EV_BUTTON8, !m_bMovie);
|
|
}
|
|
else
|
|
{
|
|
SetEnable (EV_BUTTON7, false);
|
|
SetEnable (EV_BUTTON8, false);
|
|
}
|
|
|
|
bEnable = true;
|
|
if (m_scrollSpeed == 0)
|
|
bEnable = false;
|
|
SetEnable (EV_BUTTON9, bEnable);
|
|
bEnable = true;
|
|
if (m_scrollSpeed >= 3)
|
|
bEnable = false;
|
|
SetEnable (EV_BUTTON10, bEnable);
|
|
}
|
|
|
|
/* Check if both music formats are available */
|
|
auto ogg = this->IsBaseMusicAvailable (1, "ogg");
|
|
auto mid = this->IsBaseMusicAvailable (1, "mid");
|
|
|
|
if (m_phase == EV_PHASE_SETTINGS)
|
|
{
|
|
SetEnable (EV_BUTTON1, m_Lang != m_Languages.begin ());
|
|
SetEnable (EV_BUTTON2, m_Lang != m_Languages.end () - 1);
|
|
|
|
SetEnable (EV_BUTTON3, !g_bFullScreen);
|
|
SetEnable (EV_BUTTON4, g_bFullScreen);
|
|
|
|
SetEnable (EV_BUTTON5, g_zoom > 1);
|
|
SetEnable (EV_BUTTON6, g_zoom < 2);
|
|
|
|
SetEnable (EV_BUTTON7, g_restoreMidi && mid && ogg);
|
|
SetEnable (EV_BUTTON8, !g_restoreMidi && mid && ogg);
|
|
|
|
SetEnable (EV_BUTTON9, g_bFullScreen && g_zoom == 1 && g_renderQuality);
|
|
SetEnable (EV_BUTTON10, g_bFullScreen && g_zoom == 1 && !g_renderQuality);
|
|
|
|
table[m_index].buttons[4].toolTips[0] =
|
|
g_bFullScreen ? gettext ("Desktop mode") : gettext ("Reduce window size");
|
|
table[m_index].buttons[5].toolTips[0] =
|
|
g_bFullScreen ? gettext ("Legacy mode (640x480)")
|
|
: gettext ("Increase window size");
|
|
}
|
|
|
|
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 == EV_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 ();
|
|
|
|
auto offset = IsRightReading () ? POSDRAWX + DIMDRAWX : 0;
|
|
|
|
// Dessine la rose des vents.
|
|
if (!m_bPause && !m_bDemoPlay)
|
|
{
|
|
DrawTextCenter (gettext ("N"), (10 + 134) / 2 + offset, 17);
|
|
DrawTextCenter (gettext ("S"), (10 + 134) / 2 + offset, 126);
|
|
DrawTextCenter (gettext ("W"), 14 + offset, 70);
|
|
DrawTextCenter (gettext ("E"), 129 + offset, 70);
|
|
}
|
|
|
|
// Dessine la pause.
|
|
if (m_bPause)
|
|
DrawTextCenter (gettext ("Game paused"), (10 + 134) / 2 + offset, 20);
|
|
else
|
|
{
|
|
if (m_bDemoRec) // recording demo ?
|
|
DrawTextCenter (gettext ("REC"), (10 + 38) / 2 + offset, 20, FONTRED);
|
|
if (m_bDemoPlay) // playing demo ?
|
|
DrawTextCenter (gettext ("Demo"), (10 + 134) / 2 + offset, 20, FONTRED);
|
|
}
|
|
|
|
// Dessine la vitesse.
|
|
pos.x = IsRightReading () ? LXIMAGE () - 64 : 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); // dessine le fond
|
|
if (m_speed > 1)
|
|
{
|
|
snprintf (res, sizeof (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);
|
|
|
|
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);
|
|
|
|
pos.x = POSDRAWX_ + 20;
|
|
pos.y = POSDRAWY + 4;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawTextRect (m_pPixmap, pos, m_libelle, 0, FONTLITTLE, 1);
|
|
pos.x = POSDRAWX_ + DIMDRAWX / 2 + 20;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
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;
|
|
if (IsRightReading ())
|
|
m_posHelpButton.x = POSDRAWX + 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;
|
|
if (IsRightReading ())
|
|
m_posHelpButton.x = POSDRAWX + 2;
|
|
m_pPixmap->DrawIcon (-1, CHBUTTON, m_bHiliInfoButton ? 75 : 74, pos);
|
|
}
|
|
m_posInfoButton = pos;
|
|
}
|
|
|
|
// Dessine les noms des fichiers.
|
|
if (
|
|
m_phase == EV_PHASE_READ || m_phase == EV_PHASE_WRITE ||
|
|
m_phase == EV_PHASE_WRITEp)
|
|
{
|
|
if (m_phase == EV_PHASE_READ)
|
|
snprintf (res, sizeof (res), "%s", gettext ("Open another game"));
|
|
else
|
|
snprintf (res, sizeof (res), "%s", gettext ("Save this game"));
|
|
|
|
pos.x = 420 + LXOFFSET ();
|
|
pos.y = 8;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, res);
|
|
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
world = m_fileWorld[i];
|
|
time = m_fileTime[i];
|
|
|
|
snprintf (text, sizeof (text), "%d", i + 1);
|
|
lg = GetTextWidth (text);
|
|
pos.x = (420 + 460) / 2 - lg / 2 + LXOFFSET ();
|
|
pos.y = 30 + 12 + 42 * i;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, text, FONTSLIM);
|
|
|
|
pos.x = 420 + 50 + LXOFFSET ();
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
|
|
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 == EV_PHASE_TERM)
|
|
{
|
|
Term * pTerm = m_pDecor->GetTerminated ();
|
|
|
|
auto x = (10 + 134) / 2 + LXOFFSET ();
|
|
if (IsRightReading ())
|
|
x = LXIMAGE () - x;
|
|
DrawTextCenter (gettext ("Ending conditions"), x, 20);
|
|
|
|
pos.x = 170 + 42 * 2 + 4 + LXOFFSET ();
|
|
pos.y = 30 + 12 + 42 * 4;
|
|
snprintf (
|
|
text, sizeof (text), gettext ("Lost if less than %d Blupi"),
|
|
pTerm->nbMinBlupi);
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, text);
|
|
|
|
pos.x = 170 + 42 * 2 + 4 + LXOFFSET ();
|
|
pos.y = 30 + 12 + 42 * 5;
|
|
snprintf (
|
|
text, sizeof (text), gettext ("Impossible to win if less than %d Blupi"),
|
|
pTerm->nbMaxBlupi);
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, text);
|
|
}
|
|
|
|
// Dessine les textes pour les choix des boutons.
|
|
if (m_phase == EV_PHASE_BUTTON)
|
|
{
|
|
auto x = (10 + 134) / 2 + LXOFFSET ();
|
|
if (IsRightReading ())
|
|
x = LXIMAGE () - x;
|
|
DrawTextCenter (gettext ("Available buttons"), x, 20);
|
|
}
|
|
|
|
// Dessine les textes pour le choix des musiques.
|
|
if (m_phase == EV_PHASE_MUSIC)
|
|
{
|
|
auto x = (10 + 134) / 2 + LXOFFSET ();
|
|
if (IsRightReading ())
|
|
x = LXIMAGE () - x;
|
|
DrawTextCenter (gettext ("Music choice"), x, 20);
|
|
}
|
|
|
|
// Dessine les textes pour le choix de la région.
|
|
if (m_phase == EV_PHASE_REGION)
|
|
{
|
|
auto x = (10 + 134) / 2 + LXOFFSET ();
|
|
if (IsRightReading ())
|
|
x = LXIMAGE () - x;
|
|
DrawTextCenter (gettext ("Scenery choice"), x, 20);
|
|
}
|
|
|
|
// Ajoute "Mission numéro".
|
|
if (m_phase == EV_PHASE_INFO)
|
|
{
|
|
if (m_bSchool)
|
|
snprintf (res, sizeof (res), "%s", gettext ("Training number"));
|
|
else
|
|
snprintf (res, sizeof (res), "%s", gettext ("Mission number"));
|
|
|
|
if (m_bPrivate)
|
|
snprintf (res, sizeof (res), "%s", gettext ("Construction number"));
|
|
|
|
lg = GetTextWidth (res);
|
|
pos.x = (140 + 270) / 2 - lg / 2 + LXOFFSET ();
|
|
pos.y = 70;
|
|
if (m_bSchool)
|
|
pos.x -= 40;
|
|
if (m_bPrivate)
|
|
pos.x -= 100;
|
|
if (m_bPrivate)
|
|
pos.y += 14;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, res, FONTSLIM);
|
|
}
|
|
|
|
// Ajoute le texte "Partie interrompue".
|
|
if (m_phase == EV_PHASE_STOP)
|
|
{
|
|
char * text = gettext ("Game paused");
|
|
lg = GetTextWidth (text);
|
|
pos.x = (140 + 270) / 2 - lg / 2 + LXOFFSET ();
|
|
pos.y = 70;
|
|
if (m_bSchool)
|
|
pos.x -= 40;
|
|
if (m_bPrivate)
|
|
pos.x -= 100;
|
|
if (m_bPrivate)
|
|
pos.y += 14;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, text, FONTRED);
|
|
}
|
|
|
|
// Ajoute le texte "Informations complémentaires".
|
|
if (m_phase == EV_PHASE_HELP)
|
|
{
|
|
char * text = gettext ("Help number");
|
|
lg = GetTextWidth (text);
|
|
pos.x = (140 + 270) / 2 - lg / 2 + LXOFFSET ();
|
|
pos.y = 70;
|
|
if (m_bSchool)
|
|
pos.x -= 40;
|
|
if (m_bPrivate)
|
|
pos.x -= 100;
|
|
if (m_bPrivate)
|
|
pos.y += 14;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, text, FONTRED);
|
|
}
|
|
|
|
// Ajoute le numéro du monde.
|
|
if (
|
|
m_phase == EV_PHASE_INFO || m_phase == EV_PHASE_STOP ||
|
|
m_phase == EV_PHASE_HELP)
|
|
{
|
|
if (m_bSchool)
|
|
world = m_exercice;
|
|
else
|
|
world = m_mission;
|
|
if (m_bPrivate)
|
|
world = m_private;
|
|
|
|
lg = GetBignumWidth (world + 1);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (140 + 270) / 2 - lg / 2 + LXOFFSET ();
|
|
pos.y = 100;
|
|
if (m_bSchool)
|
|
pos.x -= 40;
|
|
if (m_bPrivate)
|
|
pos.x -= 135;
|
|
if (m_bPrivate)
|
|
pos.y = 115;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawBignum (m_pPixmap, pos, world + 1);
|
|
}
|
|
|
|
// Affiche facile/difficile.
|
|
if (m_phase == EV_PHASE_INFO)
|
|
{
|
|
if (!m_bSchool)
|
|
{
|
|
std::string text;
|
|
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;
|
|
}
|
|
pos.x += LXOFFSET ();
|
|
text = gettext ("Easy");
|
|
}
|
|
else 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;
|
|
}
|
|
pos.x += LXOFFSET ();
|
|
text = gettext ("Difficult");
|
|
}
|
|
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, text.c_str (), FONTSLIM);
|
|
}
|
|
}
|
|
|
|
// Affiche le libellé de l'énigme.
|
|
if (
|
|
m_phase == EV_PHASE_INFO || m_phase == EV_PHASE_STOP ||
|
|
m_phase == EV_PHASE_HELP || m_phase == EV_PHASE_HISTORY0 ||
|
|
m_phase == EV_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;
|
|
pos.x += LXOFFSET ();
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawTextRect (m_pPixmap, pos, m_libelle, pente, FONTSLIM);
|
|
}
|
|
|
|
// Affiche le texte lorsque c'est raté.
|
|
if (m_phase == EV_PHASE_LOST)
|
|
{
|
|
const 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 + LXOFFSET ();
|
|
pos.y = 443;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, list[GetWorld () % 5]);
|
|
}
|
|
|
|
// Affiche le texte lorsque c'est réussi.
|
|
if (m_phase == EV_PHASE_WIN)
|
|
{
|
|
const char * list[] = {
|
|
gettext ("Well done !"), gettext ("Yes, great ..."),
|
|
gettext ("Very good."), gettext ("Excellent..."),
|
|
gettext ("Mission over..."),
|
|
};
|
|
|
|
pos.x = 60 + LXOFFSET ();
|
|
pos.y = 443;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, list[GetWorld () % 5]);
|
|
}
|
|
|
|
// Show the ending text when the game is finished.
|
|
if (m_phase == EV_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 + LXOFFSET ();
|
|
pos.y = 443;
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
DrawText (m_pPixmap, pos, text);
|
|
}
|
|
|
|
// Draw the game settings.
|
|
if (m_phase == EV_PHASE_SETUP || m_phase == EV_PHASE_SETUPp)
|
|
{
|
|
DrawTextCenter (gettext ("Global game\nspeed"), 54 + 40 + LXOFFSET (), 80);
|
|
DrawTextCenter (
|
|
gettext ("Scroll speed\nwith mouse"), 169 + 40 + LXOFFSET (), 80);
|
|
DrawTextCenter (
|
|
gettext ("Sound effect\nvolume"), 284 + 40 + LXOFFSET (), 80);
|
|
DrawTextCenter (gettext ("Music\nvolume"), 399 + 40 + LXOFFSET (), 80);
|
|
DrawTextCenter (gettext ("Video\nsequences"), 514 + 40 + LXOFFSET (), 80);
|
|
|
|
snprintf (res, sizeof (res), "x%d", m_speed);
|
|
lg = GetTextWidth (res);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (54 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, res);
|
|
|
|
snprintf (res, sizeof (res), "%d", m_pSound->GetAudioVolume ());
|
|
lg = GetTextWidth (res);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (284 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, res);
|
|
|
|
snprintf (res, sizeof (res), "%d", m_pSound->GetMidiVolume ());
|
|
lg = GetTextWidth (res);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (399 + 40) - lg / 2 + LXOFFSET ();
|
|
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);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (514 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, text);
|
|
|
|
if (!m_scrollSpeed)
|
|
snprintf (res, sizeof (res), "%s", gettext ("None"));
|
|
else
|
|
snprintf (res, sizeof (res), "%d", m_scrollSpeed);
|
|
lg = GetTextWidth (res);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (169 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, res);
|
|
}
|
|
|
|
// Draw the settings
|
|
if (m_phase == EV_PHASE_SETTINGS)
|
|
{
|
|
DrawTextCenter (
|
|
gettext ("Interface language\nand sounds"), 54 + 40 + LXOFFSET (), 80);
|
|
DrawTextCenter (
|
|
gettext ("Select the\nwindow mode"), 169 + 40 + LXOFFSET (), 80);
|
|
DrawTextCenter (
|
|
g_bFullScreen ? gettext ("Change the\ndisplay mode")
|
|
: gettext ("Change the\nwindow size"),
|
|
284 + 40 + LXOFFSET (), 80);
|
|
DrawTextCenter (
|
|
gettext ("Choose the\nmusic format"), 399 + 40 + LXOFFSET (), 80);
|
|
DrawTextCenter (
|
|
gettext ("Change the\nrender quality"), 514 + 40 + LXOFFSET (), 80);
|
|
|
|
const auto locale = GetLocale ();
|
|
std::string lang;
|
|
if (locale == "en")
|
|
lang = "English";
|
|
else if (locale == "en_US")
|
|
lang = "American english";
|
|
else if (locale == "fr")
|
|
lang = "Français";
|
|
else if (locale == "de")
|
|
lang = "Deutsch";
|
|
else if (locale == "it")
|
|
lang = "Italiano";
|
|
else if (locale == "pl")
|
|
lang = "Polski";
|
|
else if (locale == "tr")
|
|
lang = "Türkçe";
|
|
else if (locale == "pt")
|
|
lang = "Português";
|
|
else if (locale == "he")
|
|
lang = "עברית";
|
|
|
|
lg = GetTextWidth (lang.c_str ());
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (54 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, lang.c_str ());
|
|
|
|
const char * text =
|
|
g_bFullScreen ? gettext ("Fullscreen") : gettext ("Windowed");
|
|
lg = GetTextWidth (text);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (169 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, text);
|
|
|
|
if (!g_bFullScreen)
|
|
snprintf (res, sizeof (res), "%dx", g_zoom);
|
|
else
|
|
snprintf (
|
|
res, sizeof (res), "%s",
|
|
g_zoom == 2 ? gettext ("Legacy") : gettext ("Desktop"));
|
|
|
|
lg = GetTextWidth (res);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (284 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, res);
|
|
|
|
text = (g_restoreMidi && mid) || !ogg ? gettext ("Midi") : gettext ("Ogg");
|
|
lg = GetTextWidth (text);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (399 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, text);
|
|
|
|
text =
|
|
g_bFullScreen && g_zoom == 1
|
|
? (g_renderQuality ? gettext ("Anti-aliasing") : gettext ("Aliasing"))
|
|
: gettext ("Not available");
|
|
lg = GetTextWidth (text);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = (514 + 40) - lg / 2 + LXOFFSET ();
|
|
pos.y = 330 - 20;
|
|
DrawText (m_pPixmap, pos, text);
|
|
}
|
|
|
|
// Show the ending text
|
|
if (m_phase == EV_PHASE_BYE)
|
|
{
|
|
char * text;
|
|
|
|
text = gettext ("You have played Planet Blupi.");
|
|
lg = GetTextWidth (text);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
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);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = LXIMAGE () / 2 - lg / 2;
|
|
pos.y = 40;
|
|
DrawText (m_pPixmap, pos, text);
|
|
|
|
static const std::string libs[] = {
|
|
gettext (
|
|
"This game uses statically linked free and open-source libraries:"),
|
|
gettext (" - argagg (MIT)"),
|
|
gettext (" - FFmpeg (LGPLv2.1)"),
|
|
gettext (" - GNU/gettext and GNU/libiconv (GPLv3)"),
|
|
gettext (" - libasound (LGPLv2.1)"),
|
|
gettext (" - libcurl (MIT/X derivate)"),
|
|
gettext (" - libogg and libvorbis (own license)"),
|
|
gettext (" - libpng (own license)"),
|
|
gettext (" - libpulse (LGPLv2.1)"),
|
|
gettext (" - libsndfile (LGPLv3)"),
|
|
gettext (" - SDL_kitchensink (MIT)"),
|
|
gettext (" - SDL2, SDL2_image and SDL2_mixer (zlib license)"),
|
|
gettext (" - zlib (own license)"),
|
|
gettext (
|
|
"All licenses are available under share/doc/planetblupi/copyright")};
|
|
|
|
for (size_t i = 0; i < countof (libs); ++i)
|
|
{
|
|
pos.x = 30 + LXOFFSET ();
|
|
if (IsRightReading ())
|
|
pos.x = LXIMAGE () - pos.x;
|
|
pos.y = 120 + i * 20;
|
|
DrawText (m_pPixmap, pos, libs[i].c_str ());
|
|
}
|
|
|
|
text = gettext ("This game is an original creation of Epsitec SA, CH-1400 "
|
|
"Yverdon-les-Bains");
|
|
lg = GetTextWidth (text);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = LXIMAGE () / 2 - lg / 2;
|
|
pos.y = 430;
|
|
DrawText (m_pPixmap, pos, text);
|
|
|
|
text = gettext ("http://www.blupi.org info@blupi.org");
|
|
lg = GetTextWidth (text);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
pos.x = LXIMAGE () / 2 - lg / 2;
|
|
pos.y = 450;
|
|
DrawText (m_pPixmap, pos, text);
|
|
}
|
|
|
|
// Show the text when the CD-Rom must be inserted (deprecated).
|
|
if (m_phase == EV_PHASE_INSERT)
|
|
DrawTextCenter (
|
|
gettext ("Insert CD-Rom Planet Blupi and wait a few seconds..."),
|
|
LXIMAGE () / 2, 20);
|
|
|
|
if (m_phase == EV_PHASE_BUILD)
|
|
SetEnable (EV_PHASE_UNDO, m_pDecor->IsUndo ());
|
|
|
|
// Draw the tooltips.
|
|
if (m_textToolTips[0] != 0)
|
|
DrawText (m_pPixmap, m_posToolTips, m_textToolTips);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* \brief Return the mouse sprite to use for a position.
|
|
*
|
|
* \param[in] pos - The position.
|
|
* \return the sprite.
|
|
*/
|
|
MouseSprites
|
|
CEvent::MousePosToSprite (Point pos)
|
|
{
|
|
MouseSprites sprite;
|
|
bool bUp = false, bDown = false, bLeft = false, bRight = false;
|
|
|
|
sprite = SPRITE_POINTER;
|
|
|
|
if (m_phase == EV_PHASE_PLAY || m_phase == EV_PHASE_BUILD)
|
|
{
|
|
if (
|
|
pos.x >= POSMAPX && pos.x <= POSMAPX + DIMMAPX && pos.y >= POSMAPY &&
|
|
pos.y <= POSMAPY + DIMMAPY)
|
|
sprite = SPRITE_MAP;
|
|
|
|
if (g_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;
|
|
}
|
|
|
|
if (this->statDisabled)
|
|
sprite = SPRITE_ARROW;
|
|
}
|
|
else if (m_phase == EV_PHASE_INTRO1)
|
|
sprite = SPRITE_POINTER;
|
|
else if (m_phase == EV_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;
|
|
}
|
|
|
|
/**
|
|
* \brief Main mouse sprite handling.
|
|
*
|
|
* \param[in] pos - The position.
|
|
*/
|
|
void
|
|
CEvent::MouseSprite (Point pos)
|
|
{
|
|
m_mouseSprite = MousePosToSprite (pos);
|
|
m_pPixmap->ChangeSprite (m_mouseSprite);
|
|
}
|
|
|
|
/**
|
|
* \brief Set or remove the waiting mouse sprite.
|
|
*
|
|
* \param[in] bWait - If waiting.
|
|
*/
|
|
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_pPixmap->ChangeSprite (m_mouseSprite);
|
|
}
|
|
|
|
/**
|
|
* \brief Hide or show the mouse.
|
|
*
|
|
* \param[in] bHide - If hide.
|
|
*/
|
|
void
|
|
CEvent::HideMouse (bool bHide)
|
|
{
|
|
m_bHideMouse = bHide;
|
|
|
|
if (bHide)
|
|
{
|
|
m_mouseSprite = SPRITE_EMPTY;
|
|
SDL_ShowCursor (SDL_FALSE);
|
|
}
|
|
else
|
|
{
|
|
m_mouseSprite = MousePosToSprite (GetMousePos ());
|
|
SDL_ShowCursor (SDL_TRUE);
|
|
}
|
|
|
|
m_pPixmap->SetMouseSprite (m_mouseSprite);
|
|
m_pPixmap->ChangeSprite (m_mouseSprite);
|
|
}
|
|
|
|
/**
|
|
* \brief Handle events for buttons.
|
|
*
|
|
* \param[in] event - The SDL event.
|
|
* \param[in] pos - The position.
|
|
* \return true if the event is handled.
|
|
*/
|
|
bool
|
|
CEvent::EventButtons (const SDL_Event & event, Point pos)
|
|
{
|
|
Sint32 lg;
|
|
Point _pos = pos;
|
|
|
|
// Cherche le tool tips à utiliser pour la souris.
|
|
m_textToolTips[0] = 0;
|
|
m_posToolTips.x = -1;
|
|
|
|
if (IsRightReading ())
|
|
_pos.x = LXIMAGE () - _pos.x;
|
|
|
|
if (m_phase == EV_PHASE_PLAY)
|
|
{
|
|
auto progress = [&](CJauge & prog, const char * text) -> bool {
|
|
if (prog.GetHide ())
|
|
return false;
|
|
|
|
Point test = prog.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);
|
|
lg = IsRightReading () ? -lg : lg;
|
|
test.x += (DIMJAUGEX - lg) / 2;
|
|
test.y += 4;
|
|
m_posToolTips = test;
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
const auto spotted = progress (m_jauges[0], gettext ("Blupi's energy"));
|
|
if (!spotted)
|
|
progress (m_jauges[1], gettext ("Work done"));
|
|
}
|
|
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 += IsRightReading () ? 0 : 10;
|
|
pos.y += 20;
|
|
if (pos.x > LXIMAGE () + (IsRightReading () ? 0 : -lg))
|
|
pos.x = LXIMAGE () - lg;
|
|
if (pos.x < 0)
|
|
pos.x = 0;
|
|
if (pos.y > LYIMAGE () - 14)
|
|
pos.y = LYIMAGE () - 14;
|
|
m_posToolTips = pos;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_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_MOUSEBUTTONUP &&
|
|
(event.button.button == SDL_BUTTON_LEFT ||
|
|
event.button.button == SDL_BUTTON_RIGHT))
|
|
{
|
|
m_pSound->PlayImage (
|
|
m_pDecor->GetInfoMode () ? SOUND_CLOSE : SOUND_OPEN, pos);
|
|
|
|
// Show or hide the informations at the top.
|
|
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))
|
|
{
|
|
// Reverse the help mode in the informations.
|
|
m_bInfoHelp = !m_bInfoHelp;
|
|
|
|
if (m_bInfoHelp)
|
|
ReadLibelle (GetWorld (), false, true);
|
|
else
|
|
ReadLibelle (GetWorld () + 2, false, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_BUILD)
|
|
{
|
|
if (
|
|
event.type == SDL_MOUSEBUTTONDOWN &&
|
|
(event.button.button == SDL_BUTTON_LEFT ||
|
|
event.button.button == SDL_BUTTON_RIGHT))
|
|
{
|
|
m_pDecor->HideTooltips (true); // Remove tooltips for the decor.
|
|
}
|
|
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 == EV_PHASE_PLAY)
|
|
{
|
|
if (m_menu.TreatEvent (event))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* \brief Notify if the mouse is on a button.
|
|
*
|
|
* \param[in] pos - The mouse position.
|
|
* \return true if the mouse is on a button.
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* \brief Return the table index for a specific phase.
|
|
*
|
|
* \param[in] phase - The phase.
|
|
* \return the index in `table`.
|
|
*/
|
|
Sint32
|
|
CEvent::SearchPhase (Uint32 phase)
|
|
{
|
|
Sint32 i = 0;
|
|
|
|
while (table[i].phase != 0)
|
|
{
|
|
if (table[i].phase == phase)
|
|
return i;
|
|
i++;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* \brief Return the world number.
|
|
*
|
|
* \return the number.
|
|
*/
|
|
Sint32
|
|
CEvent::GetWorld ()
|
|
{
|
|
if (m_bPrivate)
|
|
return m_private;
|
|
if (m_bSchool)
|
|
return m_exercice;
|
|
else
|
|
return m_mission;
|
|
}
|
|
|
|
/**
|
|
* \brief Return the physical world number.
|
|
*
|
|
* This number should be the same as the filename.
|
|
*
|
|
* \return the number.
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Notify if the help is available.
|
|
*
|
|
* \return true if available.
|
|
*/
|
|
bool
|
|
CEvent::IsHelpHide ()
|
|
{
|
|
bool bHide = true;
|
|
|
|
if (m_bHelp || m_pDecor->GetTotalTime () > DEF_TIME_HELP)
|
|
bHide = false;
|
|
if (m_bSchool || m_bPrivate)
|
|
{
|
|
bHide = true; // No help for the exercises.
|
|
}
|
|
|
|
return bHide;
|
|
}
|
|
|
|
bool
|
|
CEvent::IsBaseMusicAvailable (Sint32 music, const std::string & format)
|
|
{
|
|
std::string absolute;
|
|
auto filename =
|
|
string_format ("music/music%.3d.%s", music - 1, format.c_str ());
|
|
return FileExists (filename, absolute, LOCATION_BASE);
|
|
}
|
|
|
|
std::string
|
|
CEvent::GetMusicLocation (Sint32 music)
|
|
{
|
|
static const std::string exts[] = {"ogg", "mid"};
|
|
static const Location locs[] = {LOCATION_USER, LOCATION_BASE};
|
|
std::string absolute;
|
|
|
|
// Look for music in the user directory, then in the game directory.
|
|
for (size_t i = 0; i < countof (locs); ++i)
|
|
{
|
|
auto filename = string_format (
|
|
"music/music%.3d.%s", music - 1, exts[g_restoreMidi ? 1 : 0].c_str ());
|
|
if (!FileExists (filename, absolute, locs[i]))
|
|
filename = string_format (
|
|
"music/music%.3d.%s", music - 1, exts[g_restoreMidi ? 0 : 1].c_str ());
|
|
|
|
if (FileExists (filename, absolute, locs[i]))
|
|
break;
|
|
|
|
absolute = "";
|
|
}
|
|
|
|
return absolute;
|
|
}
|
|
|
|
bool
|
|
CEvent::LoadBackground ()
|
|
{
|
|
Point totalDim, iconDim;
|
|
std::string filename;
|
|
auto backWideName = table[m_index].backWideName;
|
|
|
|
filename = table[m_index].backName;
|
|
if (filename.find ("%.3d") != std::string::npos)
|
|
{
|
|
auto id = GetImageWorld ();
|
|
filename = string_format (table[m_index].backName, id);
|
|
|
|
if (table[m_index].phase == EV_PHASE_LASTWIN)
|
|
{
|
|
switch (id)
|
|
{
|
|
case 0:
|
|
backWideName = "back-disco.png";
|
|
break;
|
|
case 1:
|
|
backWideName = "back-stars.png";
|
|
break;
|
|
case 2:
|
|
backWideName = "back-win.png";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
totalDim.x = LXLOGIC ();
|
|
totalDim.y = LYLOGIC ();
|
|
iconDim.x = 0;
|
|
iconDim.y = 0;
|
|
return m_pPixmap->Cache (
|
|
CHBACK, filename, totalDim, iconDim, table[m_index].mode, backWideName);
|
|
}
|
|
|
|
/**
|
|
* \brief Change the phase.
|
|
*
|
|
* \param[in] phase - The new phase.
|
|
* \return true if the phase has changed.
|
|
*/
|
|
bool
|
|
CEvent::ChangePhase (Uint32 phase)
|
|
{
|
|
Sint32 index, world, time, total, music, i, max;
|
|
char * pButtonExist;
|
|
bool bEnable, bHide;
|
|
Term * pTerm;
|
|
|
|
if (
|
|
phase != EV_PHASE_SETUPp && phase != EV_PHASE_WRITEp &&
|
|
phase != EV_PHASE_PLAY)
|
|
m_pSound->StopMusic ();
|
|
if (phase == EV_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 == EV_PHASE_INTRO1)
|
|
m_introTime = 0;
|
|
|
|
if (phase == EV_PHASE_INIT)
|
|
m_demoTime = 0;
|
|
|
|
if (phase != EV_PHASE_PLAY)
|
|
DemoRecStop (); // stop recording
|
|
|
|
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 == EV_PHASE_BUILD && phase == EV_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 == EV_PHASE_PLAY && m_phase != phase)
|
|
{
|
|
static const std::set<Sint32> except = {SOUND_WIN, SOUND_LOST};
|
|
m_pSound->StopAllSounds (false, &except);
|
|
}
|
|
|
|
m_phase = phase; // change phase
|
|
m_index = index;
|
|
|
|
if (!this->LoadBackground ())
|
|
{
|
|
WaitMouse (false);
|
|
m_tryInsertCount = 40;
|
|
m_tryPhase = m_phase;
|
|
return ChangePhase (EV_PHASE_INSERT); // insert the CD-Rom ...
|
|
}
|
|
|
|
if (
|
|
m_phase == EV_PHASE_READ || m_phase == EV_PHASE_WRITE ||
|
|
m_phase == EV_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 == EV_PHASE_INFO || m_phase == EV_PHASE_HISTORY0 ||
|
|
m_phase == EV_PHASE_HISTORY1)
|
|
{
|
|
if (
|
|
!m_pDecor->Read (
|
|
GetPhysicalWorld (), false, world, time, total) && // read the world
|
|
!m_bAccessBuild &&
|
|
!m_bPrivate)
|
|
{
|
|
m_tryInsertCount = 40;
|
|
m_tryPhase = m_phase;
|
|
return ChangePhase (EV_PHASE_INSERT); // insert the CD-Rom ...
|
|
}
|
|
m_pDecor->SetTime (0);
|
|
m_pDecor->SetTotalTime (0);
|
|
m_pDecor->SetInvincible (false);
|
|
m_pDecor->SetSuper (false);
|
|
}
|
|
|
|
if (
|
|
m_phase == EV_PHASE_INFO || m_phase == EV_PHASE_STOP ||
|
|
m_phase == EV_PHASE_HELP || m_phase == EV_PHASE_HISTORY0 ||
|
|
m_phase == EV_PHASE_HISTORY1)
|
|
{
|
|
if (m_bPrivate)
|
|
PrivateLibelle ();
|
|
else if (m_phase == EV_PHASE_INFO || m_phase == EV_PHASE_STOP)
|
|
{
|
|
if (m_bSchool)
|
|
ReadLibelle (GetWorld (), m_bSchool, false);
|
|
else
|
|
ReadLibelle (GetWorld () + 2, m_bSchool, false);
|
|
}
|
|
else if (m_phase == EV_PHASE_HELP)
|
|
ReadLibelle (GetWorld (), false, true);
|
|
else
|
|
{
|
|
if (m_phase == EV_PHASE_HISTORY0)
|
|
world = 0;
|
|
else
|
|
world = 1;
|
|
ReadLibelle (world, false, false);
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_TESTCD)
|
|
{
|
|
if (m_pDecor->Read (0, false, world, time, total)) // read the world
|
|
{
|
|
return ChangePhase (EV_PHASE_INIT); // ok
|
|
}
|
|
else
|
|
{
|
|
m_tryInsertCount = 40;
|
|
m_tryPhase = m_phase;
|
|
return ChangePhase (EV_PHASE_INSERT); // insert the CD-Rom ...
|
|
}
|
|
}
|
|
|
|
m_jauges[0].SetHide (true);
|
|
m_jauges[1].SetHide (true);
|
|
CreateButtons (phase); // create the buttons accordingly to the phase
|
|
m_bMenu = false;
|
|
m_pDecor->HideTooltips (false);
|
|
m_menu.Delete ();
|
|
m_pDecor->BlupiSetArrow (0, false); // remove all arrows
|
|
m_pDecor->ResetHili (); // remove all highlights
|
|
|
|
if (m_phase == EV_PHASE_PLAY)
|
|
{
|
|
m_pDecor->LoadImages ();
|
|
m_pDecor->SetBuild (false);
|
|
m_pDecor->EnableFog (true);
|
|
m_pDecor->NextPhase (0); // rebuild the map immediatly
|
|
m_pDecor->StatisticInit ();
|
|
m_pDecor->TerminatedInit ();
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_BUILD)
|
|
{
|
|
m_bBuildModify = true;
|
|
SetState (EV_DECOR1, 1);
|
|
SetMenu (EV_DECOR1, 0); // grass
|
|
SetMenu (EV_DECOR2, 2); // tree
|
|
SetMenu (EV_DECOR3, 1); // house
|
|
SetMenu (EV_DECOR4, 2); // strong blupi
|
|
SetMenu (EV_DECOR5, 1); // fire
|
|
m_pDecor->LoadImages ();
|
|
m_pDecor->SetBuild (true);
|
|
m_pDecor->EnableFog (false);
|
|
m_pDecor->BlupiDeselect ();
|
|
m_pDecor->NextPhase (0); // rebuild the map immediatly
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_INFO)
|
|
{
|
|
bEnable = true;
|
|
if (GetWorld () == 0)
|
|
bEnable = false;
|
|
SetEnable (EV_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 (EV_NEXT, bEnable);
|
|
|
|
bHide = true;
|
|
if (m_bAccessBuild || m_bPrivate)
|
|
bHide = false;
|
|
SetHide (EV_PHASE_BUILD, bHide);
|
|
|
|
if (m_bSchool)
|
|
{
|
|
SetHide (EV_PHASE_SKILL1, true);
|
|
SetHide (EV_PHASE_SKILL2, true);
|
|
}
|
|
else
|
|
{
|
|
SetState (EV_PHASE_SKILL1, m_pDecor->GetSkill () == 0 ? 1 : 0);
|
|
SetState (EV_PHASE_SKILL2, m_pDecor->GetSkill () == 1 ? 1 : 0);
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_STOP)
|
|
SetHide (EV_PHASE_HELP, IsHelpHide ());
|
|
|
|
if (m_phase == EV_PHASE_READ)
|
|
{
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
if (m_fileWorld[i] == -1)
|
|
SetEnable (EV_READ0 + i, false);
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_BUTTON)
|
|
{
|
|
pButtonExist = m_pDecor->GetButtonExist ();
|
|
|
|
for (i = 0; i < MAXBUTTON; i++)
|
|
SetState (EV_BUTTON0 + i, pButtonExist[i]);
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_TERM)
|
|
{
|
|
pTerm = m_pDecor->GetTerminated ();
|
|
|
|
SetState (EV_BUTTON1, pTerm->bHachBlupi ? 1 : 0);
|
|
SetState (EV_BUTTON2, pTerm->bHachPlanche ? 1 : 0);
|
|
SetState (EV_BUTTON3, pTerm->bStopFire ? 1 : 0);
|
|
SetState (EV_BUTTON8, pTerm->bHomeBlupi ? 1 : 0);
|
|
SetState (EV_BUTTON9, pTerm->bKillRobots ? 1 : 0);
|
|
SetState (EV_BUTTON10, pTerm->bHachTomate ? 1 : 0);
|
|
SetState (EV_BUTTON11, pTerm->bHachMetal ? 1 : 0);
|
|
SetState (EV_BUTTON12, pTerm->bHachRobot ? 1 : 0);
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_MUSIC)
|
|
{
|
|
music = m_pDecor->GetMusic ();
|
|
|
|
for (i = 0; i < 11; i++)
|
|
SetState (EV_BUTTON1 + i, music == i ? 1 : 0);
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_REGION)
|
|
{
|
|
music = m_pDecor->GetRegion ();
|
|
|
|
for (i = 0; i < 4; i++)
|
|
SetState (EV_BUTTON1 + i, music == i ? 1 : 0);
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_PLAY || m_phase == EV_PHASE_MUSIC)
|
|
{
|
|
if (m_pSound->IsPlayingMusic ())
|
|
{
|
|
m_pSound->AdaptVolumeMusic ();
|
|
}
|
|
else
|
|
{
|
|
music = m_pDecor->GetMusic ();
|
|
if (music > 0)
|
|
{
|
|
auto absolute = this->GetMusicLocation (music);
|
|
|
|
m_pSound->StopMusic ();
|
|
m_pSound->PlayMusic (absolute);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (phase == EV_PHASE_H0MOVIE)
|
|
{
|
|
m_movieToStart = "movie/history0.mkv";
|
|
m_phaseAfterMovie = EV_PHASE_HISTORY0;
|
|
}
|
|
|
|
if (phase == EV_PHASE_H1MOVIE)
|
|
{
|
|
m_movieToStart = "movie/history1.mkv";
|
|
m_phaseAfterMovie = EV_PHASE_HISTORY1;
|
|
}
|
|
|
|
if (phase == EV_PHASE_H2MOVIE)
|
|
{
|
|
m_movieToStart = "movie/history2.mkv";
|
|
m_phaseAfterMovie = EV_PHASE_INFO;
|
|
}
|
|
|
|
if (phase == EV_PHASE_PLAYMOVIE)
|
|
{
|
|
m_movieToStart = string_format ("movie/play%.3d.mkv", GetPhysicalWorld ());
|
|
m_phaseAfterMovie = EV_PHASE_PLAY;
|
|
}
|
|
|
|
if (phase == EV_PHASE_WINMOVIE)
|
|
{
|
|
m_movieToStart = string_format ("movie/win%.3d.mkv", GetPhysicalWorld ());
|
|
m_phaseAfterMovie = EV_PHASE_WIN;
|
|
|
|
if (
|
|
(m_bPrivate && GetPhysicalWorld () - 200 == MAX_PRIVATE_MISSIONS - 1) ||
|
|
(!m_bPrivate &&
|
|
m_pDecor->FileExist (GetPhysicalWorld (), false, world, time, total) &&
|
|
!m_pDecor->FileExist (
|
|
GetPhysicalWorld () + 1, false, world, time, total)))
|
|
m_phaseAfterMovie = EV_PHASE_LASTWIN;
|
|
}
|
|
|
|
WaitMouse (false);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* \brief Return the current phase.
|
|
*
|
|
* \return the phase number.
|
|
*/
|
|
Uint32
|
|
CEvent::GetPhase ()
|
|
{
|
|
return m_phase;
|
|
}
|
|
|
|
/**
|
|
* \brief Try to read the CD-Rom.
|
|
*/
|
|
void
|
|
CEvent::TryInsert ()
|
|
{
|
|
if (m_tryInsertCount == 0)
|
|
ChangePhase (m_tryPhase);
|
|
else
|
|
m_tryInsertCount--;
|
|
}
|
|
|
|
/**
|
|
* \brief Start a movie if necessary.
|
|
*
|
|
* \return true if the movie has started.
|
|
*/
|
|
bool
|
|
CEvent::MovieToStart ()
|
|
{
|
|
bool movie = false;
|
|
|
|
if (m_movieToStart[0] != 0) // is movie available?
|
|
{
|
|
if (StartMovie (m_movieToStart))
|
|
{
|
|
movie = true;
|
|
m_phase = m_phaseAfterMovie; // the next normal phase
|
|
}
|
|
else
|
|
ChangePhase (m_phaseAfterMovie);
|
|
|
|
m_movieToStart[0] = 0;
|
|
}
|
|
|
|
return movie;
|
|
}
|
|
|
|
/**
|
|
* \brief Shift the decor.
|
|
*
|
|
* \param[in] dx - Delta x.
|
|
* \param[in] dy - Delta y.
|
|
*/
|
|
void
|
|
CEvent::DecorShift (Sint32 dx, Sint32 dy)
|
|
{
|
|
Point corner;
|
|
|
|
if (m_phase != EV_PHASE_PLAY && m_phase != EV_PHASE_BUILD)
|
|
return;
|
|
|
|
corner = m_pDecor->GetCorner ();
|
|
|
|
corner.x += dx;
|
|
corner.y += dy;
|
|
|
|
m_pDecor->SetCorner (corner);
|
|
}
|
|
|
|
/**
|
|
* \brief Shift the decor when the mouse is on the sides.
|
|
*/
|
|
void
|
|
CEvent::DecorAutoShift ()
|
|
{
|
|
Sint32 max, maxLimit = 4, xMoveFactor = 1, yMoveFactor = 1, vectorFactor = 1;
|
|
Point offset;
|
|
Uint32 dir = 0;
|
|
|
|
bool byKeyboard = !!this->shiftDirection;
|
|
|
|
if (byKeyboard)
|
|
{
|
|
dir = this->shiftDirection;
|
|
xMoveFactor = 2;
|
|
yMoveFactor = 3;
|
|
vectorFactor = 2;
|
|
if (m_scrollSpeed == 1)
|
|
maxLimit = 5; // 4..2..1
|
|
}
|
|
else
|
|
{
|
|
if (m_bDemoRec || m_bDemoPlay)
|
|
return;
|
|
|
|
switch (m_mouseSprite)
|
|
{
|
|
case SPRITE_ARROWL:
|
|
dir = DIRECTION_LEFT;
|
|
break;
|
|
|
|
case SPRITE_ARROWR:
|
|
dir = DIRECTION_RIGHT;
|
|
break;
|
|
|
|
case SPRITE_ARROWU:
|
|
dir = DIRECTION_UP;
|
|
break;
|
|
|
|
case SPRITE_ARROWD:
|
|
dir = DIRECTION_DOWN;
|
|
break;
|
|
|
|
case SPRITE_ARROWUL:
|
|
dir = DIRECTION_UP | DIRECTION_LEFT;
|
|
break;
|
|
|
|
case SPRITE_ARROWUR:
|
|
dir = DIRECTION_UP | DIRECTION_RIGHT;
|
|
break;
|
|
|
|
case SPRITE_ARROWDL:
|
|
dir = DIRECTION_DOWN | DIRECTION_LEFT;
|
|
break;
|
|
|
|
case SPRITE_ARROWDR:
|
|
dir = DIRECTION_DOWN | DIRECTION_RIGHT;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_bShift = false;
|
|
|
|
if (!byKeyboard && (!g_bFullScreen || m_scrollSpeed == 0))
|
|
return;
|
|
|
|
max = maxLimit - m_scrollSpeed; // max <- 3..1
|
|
|
|
if (m_phase == EV_PHASE_PLAY || m_phase == EV_PHASE_BUILD)
|
|
{
|
|
if (m_shiftPhase == 0) // start shift ?
|
|
{
|
|
switch (dir)
|
|
{
|
|
case DIRECTION_LEFT:
|
|
m_shiftOffset.x = +2;
|
|
m_shiftOffset.y = 0;
|
|
m_shiftVector.x = -1;
|
|
m_shiftVector.y = +1;
|
|
break;
|
|
|
|
case DIRECTION_RIGHT:
|
|
m_shiftOffset.x = -2;
|
|
m_shiftOffset.y = 0;
|
|
m_shiftVector.x = +1;
|
|
m_shiftVector.y = -1;
|
|
break;
|
|
|
|
case DIRECTION_UP:
|
|
m_shiftOffset.x = 0;
|
|
m_shiftOffset.y = +2;
|
|
m_shiftVector.x = -1;
|
|
m_shiftVector.y = -1;
|
|
if (vectorFactor > 1)
|
|
++vectorFactor;
|
|
break;
|
|
|
|
case DIRECTION_DOWN:
|
|
m_shiftOffset.x = 0;
|
|
m_shiftOffset.y = -2;
|
|
m_shiftVector.x = +1;
|
|
m_shiftVector.y = +1;
|
|
if (vectorFactor > 1)
|
|
++vectorFactor;
|
|
break;
|
|
|
|
default:
|
|
if (dir == (DIRECTION_UP | DIRECTION_LEFT))
|
|
{
|
|
m_shiftOffset.x = +1;
|
|
m_shiftOffset.y = +1;
|
|
m_shiftVector.x = -1;
|
|
m_shiftVector.y = 0;
|
|
if (vectorFactor > 1)
|
|
++vectorFactor;
|
|
}
|
|
else if (dir == (DIRECTION_UP | DIRECTION_RIGHT))
|
|
{
|
|
m_shiftOffset.x = -1;
|
|
m_shiftOffset.y = +1;
|
|
m_shiftVector.x = 0;
|
|
m_shiftVector.y = -1;
|
|
if (vectorFactor > 1)
|
|
++vectorFactor;
|
|
}
|
|
else if (dir == (DIRECTION_DOWN | DIRECTION_LEFT))
|
|
{
|
|
m_shiftOffset.x = +1;
|
|
m_shiftOffset.y = -1;
|
|
m_shiftVector.x = 0;
|
|
m_shiftVector.y = +1;
|
|
if (vectorFactor > 1)
|
|
++vectorFactor;
|
|
}
|
|
else if (dir == (DIRECTION_DOWN | DIRECTION_RIGHT))
|
|
{
|
|
m_shiftOffset.x = -1;
|
|
m_shiftOffset.y = -1;
|
|
m_shiftVector.x = +1;
|
|
m_shiftVector.y = 0;
|
|
if (vectorFactor > 1)
|
|
++vectorFactor;
|
|
}
|
|
else
|
|
{
|
|
m_shiftOffset.x = 0;
|
|
m_shiftOffset.y = 0;
|
|
m_shiftVector.x = 0;
|
|
m_shiftVector.y = 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
m_shiftOffset.x *= xMoveFactor;
|
|
m_shiftOffset.y *= yMoveFactor;
|
|
m_shiftVector.x *= vectorFactor;
|
|
m_shiftVector.y *= vectorFactor;
|
|
|
|
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) // last phase ?
|
|
{
|
|
this->shiftDirection = 0;
|
|
offset.x = 0;
|
|
offset.y = 0;
|
|
m_pDecor->SetShiftOffset (offset);
|
|
DecorShift (m_shiftVector.x, m_shiftVector.y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Notify if a shift is doing.
|
|
*
|
|
* \return true of the shift is doing.
|
|
*/
|
|
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, h;
|
|
Buttons button;
|
|
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->SetCorner (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)
|
|
{
|
|
if (m_bMenu)
|
|
{
|
|
if (!m_menu.IsExist ())
|
|
{
|
|
m_bMenu = false;
|
|
m_pDecor->HideTooltips (false);
|
|
m_menu.Delete ();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
m_pDecor->StatisticMove (pos, this->statDisabled);
|
|
|
|
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)
|
|
{
|
|
static Sounds table_sound_boing[] = {
|
|
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, countof (table_sound_boing) - 1)],
|
|
pos);
|
|
else
|
|
{
|
|
m_menuCel = m_pDecor->ConvPosToCel (pos);
|
|
m_menuPos = pos;
|
|
m_menu.Create (
|
|
m_pPixmap, m_pSound, this, 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;
|
|
}
|
|
|
|
Language
|
|
CEvent::GetStartLanguage ()
|
|
{
|
|
if (this->m_LangStart == "en_US")
|
|
return Language::en_US;
|
|
if (this->m_LangStart == "fr")
|
|
return Language::fr;
|
|
if (this->m_LangStart == "de")
|
|
return Language::de;
|
|
if (this->m_LangStart == "it")
|
|
return Language::it;
|
|
if (this->m_LangStart == "pl")
|
|
return Language::pl;
|
|
if (this->m_LangStart == "tr")
|
|
return Language::tr;
|
|
if (this->m_LangStart == "pt")
|
|
return Language::pt;
|
|
if (this->m_LangStart == "he")
|
|
return Language::he;
|
|
return Language::en;
|
|
}
|
|
|
|
Language
|
|
CEvent::GetLanguage ()
|
|
{
|
|
return *this->m_Lang;
|
|
}
|
|
|
|
void
|
|
CEvent::SetLanguage (Language lang)
|
|
{
|
|
static char env[64];
|
|
const char * slang;
|
|
|
|
if (lang != Language::undef)
|
|
m_Lang = m_Languages.begin () + static_cast<int> (lang);
|
|
|
|
switch (*m_Lang)
|
|
{
|
|
default:
|
|
case Language::undef:
|
|
case Language::en:
|
|
slang = "C";
|
|
break;
|
|
case Language::en_US:
|
|
slang = "en_US";
|
|
break;
|
|
case Language::fr:
|
|
slang = "fr";
|
|
break;
|
|
case Language::de:
|
|
slang = "de";
|
|
break;
|
|
case Language::it:
|
|
slang = "it";
|
|
break;
|
|
case Language::pl:
|
|
slang = "pl";
|
|
break;
|
|
case Language::tr:
|
|
slang = "tr";
|
|
break;
|
|
case Language::pt:
|
|
slang = "pt";
|
|
break;
|
|
case Language::he:
|
|
slang = "he";
|
|
break;
|
|
}
|
|
|
|
snprintf (env, sizeof (env), "LANGUAGE=%s", slang);
|
|
|
|
{
|
|
putenv (env);
|
|
#ifndef EMSCRIPTEN
|
|
extern int _nl_msg_cat_cntr;
|
|
++_nl_msg_cat_cntr;
|
|
#endif /* EMSCRIPTEN */
|
|
}
|
|
|
|
SDL_SetWindowTitle (g_window, gettext ("Planet Blupi"));
|
|
|
|
m_pSound->CacheAll ();
|
|
}
|
|
|
|
// Clic dans un bouton.
|
|
// Message = EV_BUTTON0..EV_BUTTON39
|
|
|
|
void
|
|
CEvent::ChangeButtons (Sint32 message)
|
|
{
|
|
Buttons button;
|
|
Sint32 state, volume, max;
|
|
char * pButtonExist;
|
|
Term * pTerm;
|
|
|
|
if (m_phase == EV_PHASE_PLAY)
|
|
{
|
|
button = m_menuButtons[message - EV_BUTTON0];
|
|
m_pDecor->BlupiGoal (m_menuCel, button);
|
|
}
|
|
|
|
if (m_phase == EV_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 - EV_BUTTON0] = state;
|
|
pButtonExist[BUTTON_DJEEP] = true;
|
|
pButtonExist[BUTTON_DARMOR] = true;
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_TERM)
|
|
{
|
|
pTerm = m_pDecor->GetTerminated ();
|
|
|
|
if (
|
|
message == EV_BUTTON1 || message == EV_BUTTON2 || message == EV_BUTTON3 ||
|
|
message == EV_BUTTON8 || message == EV_BUTTON9 ||
|
|
message == EV_BUTTON10 || message == EV_BUTTON11 ||
|
|
message == EV_BUTTON12)
|
|
{
|
|
state = GetState (message);
|
|
if (state == 0)
|
|
state = 1;
|
|
else
|
|
state = 0;
|
|
SetState (message, state); // pressé <-> relâché
|
|
|
|
if (message == EV_BUTTON1)
|
|
pTerm->bHachBlupi = state;
|
|
if (message == EV_BUTTON2)
|
|
pTerm->bHachPlanche = state;
|
|
if (message == EV_BUTTON3)
|
|
pTerm->bStopFire = state;
|
|
if (message == EV_BUTTON8)
|
|
pTerm->bHomeBlupi = state;
|
|
if (message == EV_BUTTON9)
|
|
pTerm->bKillRobots = state;
|
|
if (message == EV_BUTTON10)
|
|
pTerm->bHachTomate = state;
|
|
if (message == EV_BUTTON11)
|
|
pTerm->bHachMetal = state;
|
|
if (message == EV_BUTTON12)
|
|
pTerm->bHachRobot = state;
|
|
}
|
|
|
|
if (message == EV_BUTTON4)
|
|
{
|
|
if (pTerm->nbMinBlupi > 1)
|
|
pTerm->nbMinBlupi--;
|
|
}
|
|
if (message == EV_BUTTON5)
|
|
{
|
|
if (pTerm->nbMinBlupi < 100)
|
|
pTerm->nbMinBlupi++;
|
|
}
|
|
|
|
if (message == EV_BUTTON6)
|
|
{
|
|
if (pTerm->nbMaxBlupi > 1)
|
|
pTerm->nbMaxBlupi--;
|
|
}
|
|
if (message == EV_BUTTON7)
|
|
{
|
|
if (pTerm->nbMaxBlupi < 100)
|
|
pTerm->nbMaxBlupi++;
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_MUSIC)
|
|
{
|
|
m_pDecor->SetMusic (message - EV_BUTTON1);
|
|
ChangePhase (m_phase);
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_REGION)
|
|
{
|
|
m_pDecor->SetRegion (message - EV_BUTTON1);
|
|
ChangePhase (EV_PHASE_BUILD);
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_SETUP || m_phase == EV_PHASE_SETUPp)
|
|
{
|
|
if (message == EV_BUTTON1)
|
|
{
|
|
if (m_speed > 1)
|
|
m_speed = m_speed >> 1;
|
|
}
|
|
if (message == EV_BUTTON2)
|
|
{
|
|
if (m_bSpeed)
|
|
max = 8;
|
|
else
|
|
max = 2;
|
|
if (m_speed < max)
|
|
m_speed = m_speed << 1;
|
|
}
|
|
|
|
if (message == EV_BUTTON3)
|
|
{
|
|
volume = m_pSound->GetAudioVolume ();
|
|
if (volume > 0)
|
|
m_pSound->SetAudioVolume (volume - 1);
|
|
}
|
|
if (message == EV_BUTTON4)
|
|
{
|
|
volume = m_pSound->GetAudioVolume ();
|
|
if (volume < MAXVOLUME)
|
|
m_pSound->SetAudioVolume (volume + 1);
|
|
}
|
|
|
|
if (message == EV_BUTTON5)
|
|
{
|
|
volume = m_pSound->GetMidiVolume ();
|
|
if (volume > 0)
|
|
{
|
|
m_pSound->SetMidiVolume (volume - 1);
|
|
m_pSound->AdaptVolumeMusic ();
|
|
}
|
|
}
|
|
if (message == EV_BUTTON6)
|
|
{
|
|
volume = m_pSound->GetMidiVolume ();
|
|
if (volume < MAXVOLUME)
|
|
{
|
|
m_pSound->SetMidiVolume (volume + 1);
|
|
m_pSound->AdaptVolumeMusic ();
|
|
}
|
|
}
|
|
|
|
if (message == EV_BUTTON7)
|
|
m_bMovie = false;
|
|
if (message == EV_BUTTON8)
|
|
m_bMovie = true;
|
|
|
|
if (message == EV_BUTTON9)
|
|
{
|
|
if (m_scrollSpeed > 0)
|
|
m_scrollSpeed--;
|
|
}
|
|
if (message == EV_BUTTON10)
|
|
{
|
|
if (m_scrollSpeed < 3)
|
|
m_scrollSpeed++;
|
|
}
|
|
}
|
|
|
|
if (m_phase == EV_PHASE_SETTINGS)
|
|
{
|
|
switch (message)
|
|
{
|
|
case EV_BUTTON1:
|
|
if (m_Lang != m_Languages.begin ())
|
|
--m_Lang;
|
|
SetLanguage ();
|
|
break;
|
|
case EV_BUTTON2:
|
|
if (m_Lang != m_Languages.end () - 1)
|
|
++m_Lang;
|
|
SetLanguage ();
|
|
break;
|
|
case EV_BUTTON3:
|
|
{
|
|
auto zoom = g_zoom;
|
|
g_zoom = g_settingsOverload & SETTING_LEGACY ? 2 : 1;
|
|
SetFullScreen (true, zoom);
|
|
break;
|
|
}
|
|
case EV_BUTTON4:
|
|
{
|
|
Sint32 w1;
|
|
SDL_GetWindowSize (g_window, &w1, nullptr);
|
|
SetFullScreen (false);
|
|
SetWindowSize (g_zoom * static_cast<double> (w1) / LXIMAGE (), g_zoom);
|
|
break;
|
|
}
|
|
case EV_BUTTON5:
|
|
{
|
|
auto scale = g_zoom;
|
|
if (g_zoom > 1)
|
|
--g_zoom;
|
|
|
|
if (g_bFullScreen && scale == 2)
|
|
{
|
|
SDL_Event ev;
|
|
ev.type = SDL_QUIT;
|
|
SDL_PushEvent (&ev);
|
|
g_restart = RestartMode::DESKTOP;
|
|
break;
|
|
}
|
|
|
|
SetWindowSize (scale, g_zoom);
|
|
if (g_bFullScreen)
|
|
SetFullScreen (g_bFullScreen);
|
|
break;
|
|
}
|
|
case EV_BUTTON6:
|
|
{
|
|
auto scale = g_zoom;
|
|
if (g_zoom < 2)
|
|
++g_zoom;
|
|
|
|
if (g_bFullScreen && g_zoom == 2)
|
|
{
|
|
SDL_Event ev;
|
|
ev.type = SDL_QUIT;
|
|
SDL_PushEvent (&ev);
|
|
g_restart = RestartMode::LEGACY;
|
|
break;
|
|
}
|
|
|
|
SetWindowSize (scale, g_zoom);
|
|
if (g_bFullScreen)
|
|
SetFullScreen (g_bFullScreen);
|
|
break;
|
|
}
|
|
case EV_BUTTON7:
|
|
g_restoreMidi = false;
|
|
break;
|
|
case EV_BUTTON8:
|
|
g_restoreMidi = true;
|
|
break;
|
|
case EV_BUTTON9:
|
|
g_renderQuality = false;
|
|
this->m_pPixmap->CreateMainTexture ();
|
|
break;
|
|
case EV_BUTTON10:
|
|
g_renderQuality = true;
|
|
this->m_pPixmap->CreateMainTexture ();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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, const SDL_Event * event, 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;
|
|
|
|
bool isRightClick = event ? event->button.button == SDL_BUTTON_RIGHT : false;
|
|
|
|
if (bMix)
|
|
{
|
|
m_pDecor->UndoCopy (); // copie le décor pour undo év.
|
|
}
|
|
|
|
if (GetState (EV_DECOR1) == 1 && !isRightClick) // pose d'un sol
|
|
{
|
|
cel = m_pDecor->ConvPosToCel2 (pos);
|
|
menu = GetMenu (EV_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 (EV_DECOR2) == 1 || isRightClick) // pose d'un objet
|
|
{
|
|
cel = m_pDecor->ConvPosToCel2 (pos);
|
|
menu = isRightClick ? 0 : GetMenu (EV_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 (EV_DECOR3) == 1 || isRightClick) // pose d'un batiment
|
|
{
|
|
cel = m_pDecor->ConvPosToCel2 (pos);
|
|
menu = isRightClick ? 0 : GetMenu (EV_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 (EV_DECOR4) == 1 || isRightClick) // pose d'un blupi
|
|
{
|
|
cel = m_pDecor->ConvPosToCel (pos);
|
|
menu = isRightClick ? 0 : GetMenu (EV_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 (EV_DECOR5) == 1 || isRightClick) // pose d'une cata
|
|
{
|
|
cel = m_pDecor->ConvPosToCel2 (pos);
|
|
menu = isRightClick ? 0 : GetMenu (EV_DECOR5);
|
|
|
|
if (menu == 0) // supprime ?
|
|
m_pDecor->SetFire (cel, false);
|
|
|
|
if (menu == 1 && (g_restoreBugs || m_pDecor->CanBurn (cel))) // 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, nullptr, false);
|
|
|
|
if (GetState (EV_DECOR4) == 1) // pose d'un blupi
|
|
m_pDecor->CelHili (pos, 1);
|
|
else
|
|
m_pDecor->CelHili (pos, 2);
|
|
|
|
return true;
|
|
}
|
|
|
|
// Démarre un film non interractif.
|
|
|
|
bool
|
|
CEvent::StartMovie (const std::string & pFilename)
|
|
{
|
|
if (!m_pMovie->GetEnable ())
|
|
return false;
|
|
if (!m_bMovie)
|
|
return false;
|
|
|
|
std::string absolute;
|
|
if (!FileExists (pFilename, absolute))
|
|
return false;
|
|
|
|
HideMouse (true);
|
|
m_pSound->StopMusic ();
|
|
|
|
if (!m_pMovie->Play (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 - EV_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 - EV_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", gettext ("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",
|
|
gettext ("1|The Blupi population must\n1|be of at least %d Blupi."));
|
|
snprintf (string, sizeof (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 = '@';
|
|
|
|
auto stories = GetBaseDir () + "data/" + GetLocale () + "/stories.blp";
|
|
|
|
pBuffer = (char *) malloc (sizeof (char) * 50000);
|
|
if (pBuffer == nullptr)
|
|
goto error;
|
|
|
|
memset (pBuffer, 0, sizeof (char) * 50000);
|
|
|
|
file = fopen (stories.c_str (), "rb");
|
|
if (file == nullptr)
|
|
{
|
|
/* Try with the fallback locale */
|
|
stories = GetBaseDir () + "data/en/stories.blp";
|
|
file = fopen (stories.c_str (), "rb");
|
|
if (!file)
|
|
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 ()
|
|
{
|
|
std::string filename;
|
|
FILE * file = nullptr;
|
|
DescInfo info = {0};
|
|
size_t nb;
|
|
|
|
filename = "data/info.blp";
|
|
AddUserPath (filename);
|
|
|
|
file = fopen (filename.c_str (), "wb");
|
|
if (file == nullptr)
|
|
goto error;
|
|
|
|
info.majRev = 1;
|
|
info.minRev = 3;
|
|
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 ();
|
|
|
|
/* Global settings */
|
|
info.language = static_cast<Sint16> (
|
|
this->GetLanguage () != this->GetStartLanguage () ? this->GetLanguage ()
|
|
: Language::undef);
|
|
info.musicMidi = g_restoreMidi;
|
|
info.fullScreen = g_bFullScreen;
|
|
info.zoom = g_zoom;
|
|
info.renderQuality = g_renderQuality;
|
|
|
|
nb = fwrite (&info, sizeof (info), 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 ()
|
|
{
|
|
std::string filename;
|
|
FILE * file = nullptr;
|
|
DescInfo info;
|
|
size_t nb;
|
|
|
|
filename = "data/info.blp";
|
|
AddUserPath (filename);
|
|
|
|
file = fopen (filename.c_str (), "rb");
|
|
if (file == nullptr)
|
|
goto error;
|
|
|
|
SDL_memset (&info, 0, sizeof (info));
|
|
|
|
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);
|
|
|
|
if ((info.majRev == 1 && info.minRev >= 1) || info.majRev >= 2)
|
|
{
|
|
if (info.language >= static_cast<int> (Language::end))
|
|
info.language = 0;
|
|
this->SetLanguage (static_cast<Language> (info.language));
|
|
}
|
|
|
|
if (((info.majRev == 1 && info.minRev >= 2) || info.majRev >= 2))
|
|
{
|
|
if (!(g_settingsOverload & SETTING_MIDI))
|
|
g_restoreMidi = !!info.musicMidi;
|
|
if (!(g_settingsOverload & SETTING_FULLSCREEN))
|
|
g_bFullScreen = !!info.fullScreen;
|
|
if (!(g_settingsOverload & SETTING_ZOOM))
|
|
g_zoom = info.zoom;
|
|
|
|
/* Prefer the desktop fullscreen mode by default. */
|
|
if (!(g_settingsOverload & SETTING_LEGACY) && g_bFullScreen && g_zoom == 2)
|
|
g_zoom = 1;
|
|
}
|
|
|
|
if (((info.majRev == 1 && info.minRev >= 3) || info.majRev >= 2))
|
|
{
|
|
if (!(g_settingsOverload & SETTING_RENDERQUALITY))
|
|
g_renderQuality = !!info.renderQuality;
|
|
}
|
|
|
|
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_pDemoSDLBuffer.clear ();
|
|
m_demoTime = 0;
|
|
m_demoIndex = 0;
|
|
m_bDemoRec = true;
|
|
m_bDemoPlay = false;
|
|
|
|
InitRandom ();
|
|
m_pDecor->SetTime (0);
|
|
m_speed = 1;
|
|
|
|
if (this->m_scrollSpeedPrev == -1)
|
|
this->m_scrollSpeedPrev = this->m_scrollSpeed;
|
|
this->m_scrollSpeed = 3;
|
|
|
|
m_bStartRecording = true;
|
|
}
|
|
|
|
// Fin de l'enregistrement d'une démo.
|
|
// Sauve le fichier sur disque.
|
|
|
|
void
|
|
CEvent::DemoRecStop ()
|
|
{
|
|
FILE * file = nullptr;
|
|
DemoHeader header;
|
|
|
|
if (m_bDemoPlay || !m_bDemoRec)
|
|
return;
|
|
|
|
std::time_t t = std::time (nullptr);
|
|
std::localtime (&t);
|
|
std::string demoPath = "demo/demo." + std::to_string (t) + ".blp";
|
|
AddUserPath (demoPath);
|
|
|
|
unlink (demoPath.c_str ());
|
|
file = fopen (demoPath.c_str (), "wb");
|
|
if (file)
|
|
{
|
|
memset (&header, 0, sizeof (DemoHeader));
|
|
header.majRev = 2;
|
|
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);
|
|
for (const auto buffer : m_pDemoSDLBuffer)
|
|
fwrite (&buffer, sizeof (DemoSDLEvent), 1, file);
|
|
fclose (file);
|
|
}
|
|
|
|
m_pDemoSDLBuffer.clear ();
|
|
m_bDemoRec = false;
|
|
m_demoTime = 0;
|
|
m_bStartRecording = false;
|
|
|
|
if (this->m_scrollSpeedPrev >= 0)
|
|
{
|
|
this->m_scrollSpeed = this->m_scrollSpeedPrev;
|
|
this->m_scrollSpeedPrev = -1;
|
|
}
|
|
}
|
|
|
|
// Début de la reproduction d'une démo.
|
|
// Lit le fichier sur disque.
|
|
|
|
bool
|
|
CEvent::DemoPlayStart (const std::string * demoFile)
|
|
{
|
|
std::string filename;
|
|
FILE * file = nullptr;
|
|
DemoHeader header;
|
|
Sint32 world, time, total;
|
|
size_t nb;
|
|
|
|
filename =
|
|
demoFile
|
|
? *demoFile
|
|
: string_format (GetBaseDir () + "data/demo%.3d.blp", m_demoNumber);
|
|
file = fopen (filename.c_str (), "rb");
|
|
if (file == nullptr)
|
|
{
|
|
DemoPlayStop ();
|
|
return false;
|
|
}
|
|
|
|
nb = fread (&header, sizeof (DemoHeader), 1, file);
|
|
if (nb < 1)
|
|
{
|
|
fclose (file);
|
|
DemoPlayStop ();
|
|
return false;
|
|
}
|
|
|
|
if (header.majRev == 1)
|
|
{
|
|
m_pDemoBuffer = (DemoEvent *) malloc (MAXDEMO * sizeof (DemoEvent));
|
|
if (m_pDemoBuffer == nullptr)
|
|
{
|
|
fclose (file);
|
|
DemoPlayStop ();
|
|
return false;
|
|
}
|
|
memset (m_pDemoBuffer, 0, MAXDEMO * sizeof (DemoEvent));
|
|
}
|
|
|
|
m_bSchool = !!header.bSchool;
|
|
m_bPrivate = !!header.bPrivate;
|
|
m_pDecor->SetSkill (header.skill);
|
|
|
|
if (header.majRev == 1)
|
|
m_demoEnd = fread (m_pDemoBuffer, sizeof (DemoEvent), MAXDEMO, file);
|
|
else if (header.majRev == 2)
|
|
{
|
|
DemoSDLEvent demoEvent;
|
|
|
|
for (;;)
|
|
{
|
|
auto res = fread (&demoEvent, sizeof (DemoSDLEvent), 1, file);
|
|
if (res != 1)
|
|
break;
|
|
|
|
m_pDemoSDLBuffer.push_back (demoEvent);
|
|
}
|
|
|
|
m_demoEnd = m_pDemoSDLBuffer.size ();
|
|
}
|
|
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;
|
|
}
|
|
|
|
if (this->m_scrollSpeedPrev == -1)
|
|
this->m_scrollSpeedPrev = this->m_scrollSpeed;
|
|
this->m_scrollSpeed = 3;
|
|
|
|
ChangePhase (EV_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_pDemoSDLBuffer.clear ();
|
|
|
|
m_bDemoPlay = false;
|
|
m_bDemoRec = false;
|
|
m_demoTime = 0;
|
|
|
|
if (this->m_scrollSpeedPrev >= 0)
|
|
{
|
|
this->m_scrollSpeed = this->m_scrollSpeedPrev;
|
|
this->m_scrollSpeedPrev = -1;
|
|
}
|
|
|
|
ChangePhase (EV_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))
|
|
|
|
// clang-format off
|
|
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 } },
|
|
};
|
|
// clang-format on
|
|
|
|
try
|
|
{
|
|
switch (msg)
|
|
{
|
|
case EV_KEYUP:
|
|
case EV_KEYDOWN:
|
|
event.type = msg == EV_KEYDOWN ? SDL_KEYDOWN : SDL_KEYUP;
|
|
event.key.keysym = keycodes.at (wParam);
|
|
// TODO: lParam
|
|
break;
|
|
|
|
case EV_LBUTTONUP:
|
|
case EV_LBUTTONDOWN:
|
|
event.type =
|
|
msg == EV_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 EV_RBUTTONUP:
|
|
case EV_RBUTTONDOWN:
|
|
event.type =
|
|
msg == EV_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 EV_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 ()
|
|
{
|
|
Uint32 time = 0;
|
|
Uint32 message = 0;
|
|
WParam wParam = 0;
|
|
LParam lParam = 0;
|
|
|
|
if (m_phase == EV_PHASE_INIT)
|
|
{
|
|
if (!g_playRecord.empty ())
|
|
{
|
|
m_demoNumber = -1;
|
|
DemoPlayStart (&g_playRecord);
|
|
g_playRecord = "";
|
|
}
|
|
else if (m_demoTime > DEF_TIME_DEMO) // ~30 secondes écoulées ?
|
|
{
|
|
m_demoNumber = 0;
|
|
DemoPlayStart (); // démarre une démo automatique
|
|
}
|
|
}
|
|
|
|
if (m_bDemoPlay)
|
|
{
|
|
while (true)
|
|
{
|
|
SDL_Event event = {0};
|
|
|
|
if (m_pDemoBuffer) // Old Win32 events format
|
|
{
|
|
time = m_pDemoBuffer[m_demoIndex].time;
|
|
message = m_pDemoBuffer[m_demoIndex].message;
|
|
wParam = m_pDemoBuffer[m_demoIndex].wParam;
|
|
lParam = m_pDemoBuffer[m_demoIndex].lParam;
|
|
|
|
if (IsRightReading ())
|
|
lParam =
|
|
(lParam & 0xFFFF0000) | ((lParam & 0xFFFF) - POSDRAWX_ + POSDRAWX);
|
|
}
|
|
else // New SDL events format
|
|
{
|
|
time = m_pDemoSDLBuffer[m_demoIndex].time;
|
|
event.type = m_pDemoSDLBuffer[m_demoIndex].type;
|
|
event.key.keysym.scancode =
|
|
static_cast<SDL_Scancode> (m_pDemoSDLBuffer[m_demoIndex].scancode);
|
|
event.key.keysym.sym = m_pDemoSDLBuffer[m_demoIndex].sym;
|
|
if (event.type == SDL_MOUSEMOTION)
|
|
{
|
|
event.motion.x = m_pDemoSDLBuffer[m_demoIndex].x;
|
|
event.motion.y = m_pDemoSDLBuffer[m_demoIndex].y;
|
|
|
|
if (IsRightReading ())
|
|
event.motion.x -= POSDRAWX_ + POSDRAWX;
|
|
}
|
|
else if (event.type != SDL_KEYUP && event.type != SDL_KEYDOWN)
|
|
{
|
|
event.button.button = m_pDemoSDLBuffer[m_demoIndex].button;
|
|
event.button.x = m_pDemoSDLBuffer[m_demoIndex].x;
|
|
event.button.y = m_pDemoSDLBuffer[m_demoIndex].y;
|
|
|
|
if (IsRightReading ())
|
|
event.button.x -= POSDRAWX_ + POSDRAWX;
|
|
}
|
|
}
|
|
|
|
if (time > m_demoTime)
|
|
break;
|
|
|
|
m_demoIndex++;
|
|
|
|
if (message == EV_MOUSEMOVE || event.type == SDL_MOUSEMOTION)
|
|
{
|
|
Point pos;
|
|
|
|
if (m_pDemoBuffer)
|
|
pos = ConvLongToPos (lParam);
|
|
else
|
|
{
|
|
pos.x = event.motion.x;
|
|
pos.y = event.motion.y;
|
|
}
|
|
|
|
this->m_pPixmap->FromGameToDisplay (pos.x, pos.y);
|
|
SDL_WarpMouseInWindow (g_window, pos.x, pos.y);
|
|
}
|
|
|
|
if (m_pDemoBuffer)
|
|
CEvent::WinToSDLEvent (message, wParam, lParam, event);
|
|
|
|
TreatEventBase (event);
|
|
|
|
if (m_demoIndex >= m_demoEnd && m_demoNumber >= 0)
|
|
{
|
|
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++;
|
|
}
|
|
|
|
/**
|
|
* \brief Store an event for the demos
|
|
*/
|
|
void
|
|
CEvent::DemoRecEvent (const SDL_Event & event)
|
|
{
|
|
if (!m_bDemoRec)
|
|
return;
|
|
|
|
DemoSDLEvent demoEvent = {0};
|
|
|
|
switch (event.type)
|
|
{
|
|
case SDL_KEYUP:
|
|
case SDL_KEYDOWN:
|
|
demoEvent.type = event.type;
|
|
demoEvent.time = m_demoTime;
|
|
demoEvent.scancode = event.key.keysym.scancode;
|
|
demoEvent.sym = event.key.keysym.sym;
|
|
break;
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
demoEvent.type = event.type;
|
|
demoEvent.time = m_demoTime;
|
|
demoEvent.button = event.button.button;
|
|
demoEvent.x = event.button.x;
|
|
demoEvent.y = event.button.y;
|
|
this->m_pPixmap->FromDisplayToGame (demoEvent.x, demoEvent.y);
|
|
break;
|
|
|
|
case SDL_MOUSEMOTION:
|
|
demoEvent.type = event.type;
|
|
demoEvent.time = m_demoTime;
|
|
demoEvent.x = event.motion.x;
|
|
demoEvent.y = event.motion.y;
|
|
this->m_pPixmap->FromDisplayToGame (demoEvent.x, demoEvent.y);
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
m_pDemoSDLBuffer.push_back (demoEvent);
|
|
|
|
m_demoIndex = m_pDemoSDLBuffer.size ();
|
|
}
|
|
|
|
// 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;
|
|
Sounds sound;
|
|
char c;
|
|
bool bEnable;
|
|
|
|
DemoRecEvent (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 == EV_PHASE_PLAY)
|
|
{
|
|
if (m_rankCheat == 0) // vision ?
|
|
m_pDecor->EnableFog (false);
|
|
else if (
|
|
m_rankCheat == 1 || // power ?
|
|
m_rankCheat == 2) // lonesome ?
|
|
m_pDecor->BlupiCheat (m_rankCheat);
|
|
}
|
|
|
|
switch (m_rankCheat)
|
|
{
|
|
case 3: // allmissions ?
|
|
{
|
|
m_bAllMissions = !m_bAllMissions;
|
|
bEnable = m_bAllMissions;
|
|
break;
|
|
}
|
|
case 4: // quick ?
|
|
{
|
|
m_bSpeed = !m_bSpeed;
|
|
bEnable = m_bSpeed;
|
|
break;
|
|
}
|
|
case 5: // helpme ?
|
|
{
|
|
m_bHelp = !m_bHelp;
|
|
bEnable = m_bHelp;
|
|
break;
|
|
}
|
|
case 6: // invincible ?
|
|
{
|
|
m_pDecor->SetInvincible (!m_pDecor->GetInvincible ());
|
|
bEnable = m_pDecor->GetInvincible ();
|
|
break;
|
|
}
|
|
case 7: // superblupi ?
|
|
{
|
|
m_pDecor->SetSuper (!m_pDecor->GetSuper ());
|
|
bEnable = m_pDecor->GetSuper ();
|
|
break;
|
|
}
|
|
case 8: // construire ?
|
|
{
|
|
m_bAccessBuild = !m_bAccessBuild;
|
|
bEnable = m_bAccessBuild;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (m_phase != EV_PHASE_PLAY)
|
|
ChangePhase (m_phase);
|
|
|
|
pos.x = LXIMAGE () / 2;
|
|
pos.y = LYIMAGE () / 2;
|
|
if (bEnable)
|
|
m_pSound->PlayImage (SOUND_GOAL, 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 == EV_PHASE_INTRO1)
|
|
{
|
|
ChangePhase (EV_PHASE_INIT);
|
|
return true;
|
|
}
|
|
|
|
if (m_phase == EV_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;
|
|
}
|
|
|
|
switch (m_phase)
|
|
{
|
|
case EV_PHASE_PLAY:
|
|
case EV_PHASE_SETUPp:
|
|
case EV_PHASE_WRITE:
|
|
case EV_PHASE_WRITEp:
|
|
case EV_PHASE_HELP:
|
|
ChangePhase (EV_PHASE_STOP);
|
|
return true;
|
|
|
|
case EV_PHASE_SETUP:
|
|
case EV_PHASE_READ:
|
|
ChangePhase (
|
|
this->m_pDecor->GetTime () ? EV_PHASE_STOP : EV_PHASE_INFO);
|
|
return true;
|
|
|
|
case EV_PHASE_STOP:
|
|
ChangePhase (EV_PHASE_PLAY);
|
|
return true;
|
|
|
|
case EV_PHASE_LOST:
|
|
case EV_PHASE_BUILD:
|
|
ChangePhase (EV_PHASE_INFO);
|
|
return true;
|
|
|
|
case EV_PHASE_INFO:
|
|
case EV_PHASE_SETTINGS:
|
|
ChangePhase (EV_PHASE_INIT);
|
|
return true;
|
|
|
|
case EV_PHASE_BUTTON:
|
|
case EV_PHASE_TERM:
|
|
case EV_PHASE_MUSIC:
|
|
case EV_PHASE_REGION:
|
|
ChangePhase (EV_PHASE_BUILD);
|
|
return true;
|
|
|
|
case EV_PHASE_INIT:
|
|
ChangePhase (EV_PHASE_BYE);
|
|
return true;
|
|
|
|
case EV_PHASE_BYE:
|
|
{
|
|
SDL_Event ev;
|
|
ev.type = SDL_QUIT;
|
|
SDL_PushEvent (&ev);
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
case SDLK_RETURN:
|
|
switch (m_phase)
|
|
{
|
|
case EV_PHASE_SETTINGS:
|
|
ChangePhase (EV_PHASE_INIT);
|
|
return true;
|
|
|
|
case EV_PHASE_PLAY:
|
|
case EV_PHASE_WRITE:
|
|
ChangePhase (EV_PHASE_STOP);
|
|
return true;
|
|
|
|
case EV_PHASE_SETUP:
|
|
case EV_PHASE_READ:
|
|
ChangePhase (
|
|
this->m_pDecor->GetTime () ? EV_PHASE_STOP : EV_PHASE_INFO);
|
|
return true;
|
|
|
|
case EV_PHASE_INIT:
|
|
case EV_PHASE_LOST:
|
|
case EV_PHASE_BUILD:
|
|
ChangePhase (EV_PHASE_INFO);
|
|
return true;
|
|
|
|
case EV_PHASE_INFO:
|
|
case EV_PHASE_STOP:
|
|
case EV_PHASE_HELP:
|
|
case EV_PHASE_SETUPp:
|
|
case EV_PHASE_WRITEp:
|
|
ChangePhase (EV_PHASE_PLAY);
|
|
return true;
|
|
|
|
case EV_PHASE_BUTTON:
|
|
case EV_PHASE_TERM:
|
|
case EV_PHASE_MUSIC:
|
|
case EV_PHASE_REGION:
|
|
ChangePhase (EV_PHASE_BUILD);
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
case SDLK_LEFT:
|
|
case SDLK_RIGHT:
|
|
case SDLK_UP:
|
|
case SDLK_DOWN:
|
|
{
|
|
if (m_phase != EV_PHASE_PLAY && m_phase != EV_PHASE_BUILD)
|
|
return true;
|
|
|
|
bool left, right, up, down;
|
|
const Uint8 * state = SDL_GetKeyboardState (nullptr);
|
|
|
|
this->shiftDirection = 0;
|
|
|
|
left = event.key.keysym.sym == SDLK_LEFT ||
|
|
(!m_bDemoRec && state[SDL_SCANCODE_LEFT]);
|
|
right = event.key.keysym.sym == SDLK_RIGHT ||
|
|
(!m_bDemoRec && state[SDL_SCANCODE_RIGHT]);
|
|
up = event.key.keysym.sym == SDLK_UP ||
|
|
(!m_bDemoRec && state[SDL_SCANCODE_UP]);
|
|
down = event.key.keysym.sym == SDLK_DOWN ||
|
|
(!m_bDemoRec && state[SDL_SCANCODE_DOWN]);
|
|
|
|
if (left)
|
|
this->shiftDirection |= DIRECTION_LEFT;
|
|
if (right)
|
|
this->shiftDirection |= DIRECTION_RIGHT;
|
|
if (up)
|
|
this->shiftDirection |= DIRECTION_UP;
|
|
if (down)
|
|
this->shiftDirection |= DIRECTION_DOWN;
|
|
return true;
|
|
}
|
|
case SDLK_HOME:
|
|
pos = m_pDecor->GetHome ();
|
|
m_pDecor->SetCorner (pos);
|
|
return true;
|
|
case SDLK_SPACE:
|
|
if (m_bRunMovie)
|
|
{
|
|
StopMovie ();
|
|
m_pSound->SetSuspendSkip (1);
|
|
return true;
|
|
}
|
|
m_pDecor->FlipOutline ();
|
|
return true;
|
|
case SDLK_PAUSE:
|
|
if (this->m_pDecor->GetSkill () >= 1)
|
|
return true;
|
|
|
|
m_bPause = !m_bPause;
|
|
if (m_phase == EV_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 == EV_PHASE_BUILD)
|
|
m_bFillMouse = true;
|
|
else
|
|
m_bFillMouse = false;
|
|
return true;
|
|
case SDLK_F1:
|
|
if (m_phase == EV_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_F3:
|
|
if (
|
|
g_enableRecorder && m_phase == EV_PHASE_PLAY && !m_bDemoPlay &&
|
|
!m_bStartRecording)
|
|
DemoRecStart (); // start recording
|
|
break;
|
|
case SDLK_F4:
|
|
if (
|
|
g_enableRecorder && m_phase == EV_PHASE_PLAY && !m_bDemoPlay &&
|
|
m_bStartRecording)
|
|
DemoRecStop (); // stop recording
|
|
else if (m_phase == EV_PHASE_PLAY && m_bDemoPlay)
|
|
{
|
|
DemoPlayStop ();
|
|
return true;
|
|
}
|
|
break;
|
|
case SDLK_F9:
|
|
if (m_phase == EV_PHASE_PLAY)
|
|
m_pDecor->MemoPos (0, !!(m_keymod & KMOD_CTRL));
|
|
return true;
|
|
case SDLK_F10:
|
|
if (m_phase == EV_PHASE_PLAY)
|
|
m_pDecor->MemoPos (1, !!(m_keymod & KMOD_CTRL));
|
|
return true;
|
|
case SDLK_F11:
|
|
if (m_phase == EV_PHASE_PLAY)
|
|
m_pDecor->MemoPos (2, !!(m_keymod & KMOD_CTRL));
|
|
return true;
|
|
case SDLK_F12:
|
|
if (m_phase == EV_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;
|
|
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;
|
|
|
|
if (EventButtons (event, pos))
|
|
return true;
|
|
if (m_phase == EV_PHASE_BUILD)
|
|
{
|
|
if (BuildDown (pos, m_keymod, &event))
|
|
return true;
|
|
}
|
|
if (m_phase == EV_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;
|
|
|
|
if (EventButtons (event, pos))
|
|
return true;
|
|
if (m_phase == EV_PHASE_BUILD)
|
|
{
|
|
if (BuildMove (pos, m_keymod, event))
|
|
return true;
|
|
}
|
|
if (m_phase == EV_PHASE_PLAY)
|
|
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 == EV_PHASE_BUILD)
|
|
return true;
|
|
if (m_phase == EV_PHASE_PLAY)
|
|
{
|
|
if (PlayUp (pos))
|
|
return true;
|
|
}
|
|
if (m_phase == EV_PHASE_BYE)
|
|
{
|
|
SDL_Event ev;
|
|
ev.type = SDL_QUIT;
|
|
SDL_PushEvent (&ev);
|
|
}
|
|
break;
|
|
|
|
case SDL_USEREVENT:
|
|
switch (event.user.code)
|
|
{
|
|
case EV_PHASE_DEMO:
|
|
m_demoNumber = 0;
|
|
DemoPlayStart ();
|
|
break;
|
|
|
|
case EV_PHASE_SCHOOL:
|
|
m_bSchool = true;
|
|
m_bPrivate = false;
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
break;
|
|
|
|
case EV_PHASE_MISSION:
|
|
m_bSchool = false;
|
|
m_bPrivate = false;
|
|
if (m_mission == 0) // première mission ?
|
|
{
|
|
if (ChangePhase (EV_PHASE_H0MOVIE))
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
}
|
|
break;
|
|
|
|
case EV_PHASE_PRIVATE:
|
|
m_bSchool = false;
|
|
m_bPrivate = true;
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
break;
|
|
|
|
case EV_PHASE_INTRO1:
|
|
case EV_PHASE_INIT:
|
|
case EV_PHASE_HISTORY0:
|
|
case EV_PHASE_HISTORY1:
|
|
case EV_PHASE_INFO:
|
|
case EV_PHASE_PLAY:
|
|
case EV_PHASE_READ:
|
|
case EV_PHASE_WRITE:
|
|
case EV_PHASE_WRITEp:
|
|
case EV_PHASE_BUILD:
|
|
case EV_PHASE_BUTTON:
|
|
case EV_PHASE_TERM:
|
|
case EV_PHASE_STOP:
|
|
case EV_PHASE_HELP:
|
|
case EV_PHASE_MUSIC:
|
|
case EV_PHASE_REGION:
|
|
case EV_PHASE_SETTINGS:
|
|
case EV_PHASE_SETUP:
|
|
case EV_PHASE_SETUPp:
|
|
case EV_PHASE_PLAYMOVIE:
|
|
case EV_PHASE_H0MOVIE:
|
|
case EV_PHASE_H1MOVIE:
|
|
case EV_PHASE_H2MOVIE:
|
|
case EV_PHASE_WINMOVIE:
|
|
case EV_PHASE_BYE:
|
|
if (ChangePhase (event.user.code))
|
|
return true;
|
|
break;
|
|
|
|
case EV_PHASE_UNDO:
|
|
m_pDecor->UndoBack (); // revient en arrière
|
|
break;
|
|
|
|
case EV_PREV:
|
|
m_pDecor->SetInvincible (false);
|
|
m_pDecor->SetSuper (false);
|
|
if (m_bPrivate)
|
|
{
|
|
if (m_private > 0)
|
|
{
|
|
m_private--;
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
}
|
|
}
|
|
else if (m_bSchool)
|
|
{
|
|
if (m_exercice > 0)
|
|
{
|
|
m_exercice--;
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_mission > 0)
|
|
{
|
|
m_mission--;
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case EV_NEXT:
|
|
m_pDecor->SetInvincible (false);
|
|
m_pDecor->SetSuper (false);
|
|
if (m_bPrivate)
|
|
{
|
|
if (m_private < MAX_PRIVATE_MISSIONS - 1)
|
|
{
|
|
m_private++;
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
}
|
|
}
|
|
else if (m_bSchool)
|
|
{
|
|
if (m_exercice < 99)
|
|
{
|
|
m_exercice++;
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_mission < 99)
|
|
{
|
|
m_mission++;
|
|
if (m_maxMission < m_mission)
|
|
m_maxMission = m_mission;
|
|
if (ChangePhase (EV_PHASE_INFO))
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case EV_DECOR1:
|
|
SetState (EV_DECOR1, 1);
|
|
SetState (EV_DECOR2, 0);
|
|
SetState (EV_DECOR3, 0);
|
|
SetState (EV_DECOR4, 0);
|
|
SetState (EV_DECOR5, 0);
|
|
break;
|
|
|
|
case EV_DECOR2:
|
|
SetState (EV_DECOR1, 0);
|
|
SetState (EV_DECOR2, 1);
|
|
SetState (EV_DECOR3, 0);
|
|
SetState (EV_DECOR4, 0);
|
|
SetState (EV_DECOR5, 0);
|
|
break;
|
|
|
|
case EV_DECOR3:
|
|
SetState (EV_DECOR1, 0);
|
|
SetState (EV_DECOR2, 0);
|
|
SetState (EV_DECOR3, 1);
|
|
SetState (EV_DECOR4, 0);
|
|
SetState (EV_DECOR5, 0);
|
|
break;
|
|
|
|
case EV_DECOR4:
|
|
SetState (EV_DECOR1, 0);
|
|
SetState (EV_DECOR2, 0);
|
|
SetState (EV_DECOR3, 0);
|
|
SetState (EV_DECOR4, 1);
|
|
SetState (EV_DECOR5, 0);
|
|
break;
|
|
|
|
case EV_DECOR5:
|
|
SetState (EV_DECOR1, 0);
|
|
SetState (EV_DECOR2, 0);
|
|
SetState (EV_DECOR3, 0);
|
|
SetState (EV_DECOR4, 0);
|
|
SetState (EV_DECOR5, 1);
|
|
break;
|
|
|
|
case EV_PHASE_SKILL1:
|
|
m_pDecor->SetSkill (0);
|
|
SetState (EV_PHASE_SKILL1, true);
|
|
SetState (EV_PHASE_SKILL2, false);
|
|
break;
|
|
case EV_PHASE_SKILL2:
|
|
m_pDecor->SetSkill (1);
|
|
SetState (EV_PHASE_SKILL1, false);
|
|
SetState (EV_PHASE_SKILL2, true);
|
|
break;
|
|
|
|
case EV_BUTTON0:
|
|
case EV_BUTTON1:
|
|
case EV_BUTTON2:
|
|
case EV_BUTTON3:
|
|
case EV_BUTTON4:
|
|
case EV_BUTTON5:
|
|
case EV_BUTTON6:
|
|
case EV_BUTTON7:
|
|
case EV_BUTTON8:
|
|
case EV_BUTTON9:
|
|
case EV_BUTTON10:
|
|
case EV_BUTTON11:
|
|
case EV_BUTTON12:
|
|
case EV_BUTTON13:
|
|
case EV_BUTTON14:
|
|
case EV_BUTTON15:
|
|
case EV_BUTTON16:
|
|
case EV_BUTTON17:
|
|
case EV_BUTTON18:
|
|
case EV_BUTTON19:
|
|
case EV_BUTTON20:
|
|
case EV_BUTTON21:
|
|
case EV_BUTTON22:
|
|
case EV_BUTTON23:
|
|
case EV_BUTTON24:
|
|
case EV_BUTTON25:
|
|
case EV_BUTTON26:
|
|
case EV_BUTTON27:
|
|
case EV_BUTTON28:
|
|
case EV_BUTTON29:
|
|
case EV_BUTTON30:
|
|
case EV_BUTTON31:
|
|
case EV_BUTTON32:
|
|
case EV_BUTTON33:
|
|
case EV_BUTTON34:
|
|
case EV_BUTTON35:
|
|
case EV_BUTTON36:
|
|
case EV_BUTTON37:
|
|
case EV_BUTTON38:
|
|
case EV_BUTTON39:
|
|
ChangeButtons (event.user.code);
|
|
break;
|
|
|
|
case EV_READ0:
|
|
case EV_READ1:
|
|
case EV_READ2:
|
|
case EV_READ3:
|
|
case EV_READ4:
|
|
case EV_READ5:
|
|
case EV_READ6:
|
|
case EV_READ7:
|
|
case EV_READ8:
|
|
case EV_READ9:
|
|
Read (event.user.code);
|
|
ChangePhase (EV_PHASE_PLAY); // joue
|
|
break;
|
|
|
|
case EV_SETUP_EXIT:
|
|
case EV_READ_EXIT:
|
|
ChangePhase (this->m_pDecor->GetTime () ? EV_PHASE_STOP : EV_PHASE_INFO);
|
|
break;
|
|
|
|
case EV_WRITE0:
|
|
case EV_WRITE1:
|
|
case EV_WRITE2:
|
|
case EV_WRITE3:
|
|
case EV_WRITE4:
|
|
case EV_WRITE5:
|
|
case EV_WRITE6:
|
|
case EV_WRITE7:
|
|
case EV_WRITE8:
|
|
case EV_WRITE9:
|
|
Write (event.user.code);
|
|
if (m_phase == EV_PHASE_WRITEp)
|
|
{
|
|
ChangePhase (EV_PHASE_PLAY); // joue
|
|
}
|
|
else
|
|
{
|
|
ChangePhase (EV_PHASE_STOP); // pause
|
|
}
|
|
break;
|
|
|
|
case EV_MOVIE:
|
|
StartMovie ("movie/essai.avi");
|
|
ChangePhase (EV_PHASE_INIT);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Passe les images d'introduction.
|
|
|
|
void
|
|
CEvent::IntroStep ()
|
|
{
|
|
m_introTime++;
|
|
|
|
if (m_introTime > 20 * 1)
|
|
{
|
|
if (m_phase == EV_PHASE_INTRO1)
|
|
{
|
|
ChangePhase (EV_PHASE_INIT);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
CEvent::PushUserEvent (Sint32 code, void * data)
|
|
{
|
|
SDL_Event event;
|
|
|
|
event.type = SDL_USEREVENT;
|
|
event.user.code = code;
|
|
event.user.data1 = data;
|
|
event.user.data2 = nullptr;
|
|
|
|
SDL_PushEvent (&event);
|
|
}
|