Commit 5f2e9dff authored by Ian Wadham's avatar Ian Wadham

Move readLevelData to KGrGameIO. More re-factoring. Start tidying up headers...

Move readLevelData to KGrGameIO.  More re-factoring.  Start tidying up headers and controller classes.  Start re-implementing the Pause logic.

svn path=/branches/work/kgoldrunner/; revision=949354
parent 2d265207
......@@ -177,6 +177,7 @@ void KGoldrunner::KGoldrunner_2()
{
kDebug() << "Entered constructor extension ...";
// NOW paint the main widget (title, menu, status bar, blank playfield).
// TODO - Necessary? It has just been done in main.cpp ... show();
show();
kDebug() << "Main Window show() done here ...";
......@@ -418,13 +419,13 @@ void KGoldrunner::setupActions()
i18n ("Set champions' game speed (18 units)")
);
QAction * iSpeed = gameAction ("increase_speed", INC_SPEED,
a = gameAction ("increase_speed", INC_SPEED,
i18n ("Increase Speed"),
i18n ("Increase speed"),
i18n ("Increase the game speed by one unit"),
Qt::Key_Plus);
QAction * dSpeed = gameAction ("decrease_speed", DEC_SPEED,
a = gameAction ("decrease_speed", DEC_SPEED,
i18n ("Decrease Speed"),
i18n ("Decrease speed"),
i18n ("Decrease the game speed by one unit"),
......
......@@ -103,7 +103,7 @@ private slots:
void showLevel (int); // Show the current level number.
void showLives (long); // Show how many lives are remaining.
void showScore (long); // Show the player's score.
void gameFreeze (bool); // Status feedback on freeze/unfreeze.
void gameFreeze (bool); // Status feedback on Pause state.
void adjustHintAction (bool); // Enable/disable "Hint" action.
void setEditMenu (bool on_off); // Enable/disable "Save Edits" action.
......
......@@ -34,6 +34,7 @@ KGrEditor::KGrEditor (KGrCanvas * theView,
:
QObject (theView), // Destroy Editor if view closes.
view (theView),
io (new KGrGameIO (view)),
systemDataDir (theSystemDir),
userDataDir (theUserDir),
gameList (pGameList),
......@@ -155,10 +156,14 @@ void KGrEditor::updateLevel (int pGameIndex, int level)
void KGrEditor::loadEditLevel (int lev)
{
// Read the level data.
KGrLevelData d;
if (! readLevelData (lev, d)) {
return;
// If system game or ENDE screen, choose system dir, else choose user dir.
const QString dir = ((gameList.at(gameIndex)->owner == SYSTEM) ||
(lev == 0)) ? systemDataDir : userDataDir;
// Read the level data.
if (! io->readLevelData (dir, gameList.at(gameIndex), lev, d)) {
return; // If I/O failed, no load.
}
editLevel = lev;
......@@ -186,41 +191,6 @@ void KGrEditor::loadEditLevel (int lev)
view->setTitle (getTitle()); // Show the level name.
}
// TODO - Does this code really need to be duplicated in KGrGame and KGrEditor?
bool KGrEditor::readLevelData (int levelNo, KGrLevelData & d)
{
KGrGameIO io;
// If system game or ENDE screen, choose system dir, else choose user dir.
const QString dir = ((gameList.at(gameIndex)->owner == SYSTEM) ||
(levelNo == 0)) ? systemDataDir : userDataDir;
kDebug() << "Owner" << gameList.at(gameIndex)->owner << "dir" << dir
<< "Level" << gameList.at(gameIndex)->prefix << levelNo;
QString filePath;
IOStatus stat = io.fetchLevelData (dir, gameList.at(gameIndex)->prefix,
levelNo, d, filePath);
switch (stat) {
case NotFound:
KGrMessage::information (view, i18n ("Read Level Data"),
i18n ("Cannot find file '%1'.", filePath));
break;
case NoRead:
case NoWrite:
KGrMessage::information (view, i18n ("Read Level Data"),
i18n ("Cannot open file '%1' for read-only.", filePath));
break;
case UnexpectedEOF:
KGrMessage::information (view, i18n ("Read Level Data"),
i18n ("Reached end of file '%1' without finding level data.",
filePath));
break;
case OK:
break;
}
return (stat == OK);
}
void KGrEditor::editNameAndHint()
{
// Run a dialog box to create/edit the level name and hint.
......
......@@ -24,6 +24,7 @@
#include <QObject>
class KGrCanvas;
class KGrGameIO;
class QTimer;
/**
......@@ -170,6 +171,7 @@ signals:
private:
KGrCanvas * view; // The canvas on which the editor paints.
KGrGameIO * io; // I/O object for reading level-data.
QString systemDataDir;
QString userDataDir;
QList<KGrGameData *> gameList;
......@@ -211,7 +213,6 @@ private:
void loadEditLevel (int); // Load and display an existing level for edit.
void initEdit();
bool readLevelData (int levelNo, KGrLevelData & d);
void insertEditObj (int, int, char object);
char editableCell (int i, int j);
void setEditableCell (int, int, char);
......
This diff is collapsed.
......@@ -18,31 +18,23 @@
#define myStr toLatin1().constData
#define myChar(i) at((i)).toLatin1()
#include <QObject>
#include <QList>
#include <QColor>
#include <QPixmap>
#include <QLabel>
#include <QFrame>
#include <QTimer>
#include "kgrglobals.h"
#include "kgrgameio.h"
#include "kgrcanvas.h"
#include <QObject>
#include <QList>
#include <QVector>
/**
Sets up games and levels in KGoldrunner and controls the play.
@author Ian Wadham
*/
* Sets up games and levels in KGoldrunner and controls the play.
*
* @short KGoldrunner Game Controller.
*/
class KGrCanvas;
class KDialog;
class KGrSoundBank;
class KGrEditor;
class KGrLevelPlayer;
class QTimer;
class KGrGame : public QObject
{
......@@ -76,18 +68,21 @@ public:
static bool logging;
public slots:
void kbControl (int dirn);
void initGame(); // Do the game object's first painting.
void gameActions (int action);
void editActions (int action);
void editToolbarActions (int action);
void settings (int action);
void initGame(); // Do the game object's first painting.
void kbControl (int dirn);
// TODO - Only startAnyLevel() is used (from NewGame...).
void startLevelOne(); // Start any game from level 1.
void startAnyLevel(); // Start any game from any level.
void startNextLevel(); // Start next level of current game.
// TODO - startLevel should NOT be a public slot.
void startLevel (int startingAt, int requestedLevel);
void toggleSoundsOnOff(); // Set sound enabled or disabled.
......@@ -95,7 +90,6 @@ public slots:
void setControlMode (const int mode);
void setTimeScale (const int action);
void startLevel (int startingAt, int requestedLevel);
void newGame (const int lev, const int gameIndex);
void startTutorial(); // Start tutorial game.
void showHint(); // Show hint for current level.
......@@ -103,9 +97,14 @@ public slots:
void showHighScores(); // Show high scores for current game.
void incScore (int); // Update the score.
void showHiddenLadders(); // Show hidden ladders (nuggets gone).
void endLevel (const int result); // Hero completed the level or he died.
void herosDead(); // Hero was caught or he quit (key Q).
void showHiddenLadders(); // Show hidden ladders (nuggets gone).
private slots:
void finalBreath(); // Hero is dead: re-start the level.
public slots:
void levelCompleted(); // Hero completed the level.
void goUpOneLevel(); // Start next level.
......@@ -117,6 +116,7 @@ public slots:
void heroDigs(); // The hero is digging.
signals:
// These signals go to the GUI in most cases.
void showScore (long); // For main window to show the score.
void showLives (long); // For main window to show lives left.
void showLevel (int); // For main window to show the level.
......@@ -144,12 +144,10 @@ private slots:
void quickStartUseMenu();
void quickStartQuit();
private slots:
void finalBreath(); // Hero is dead: re-start the level.
private:
// TODO - Maybe call this playLevel (level, game, flavour) and pair
// it with endLevel (status).
int loadLevel (int levelNo);
bool readLevelData (int levelNo, KGrLevelData & d);
void showTutorialMessages (int levelNo);
void checkHighScore(); // Check if high score for current game.
......@@ -160,13 +158,18 @@ private:
/************************** PLAYFIELD AND GAME DATA *************************/
/******************************************************************************/
private:
KGrLevelPlayer * levelPlayer; // Where the level is played.
KGrCanvas * view; // Where the game is displayed.
QString systemDataDir; // System games are stored here.
QString userDataDir; // User games are stored here.
int timeScale; // The speed of the game (2-20).
float fTimeScale; // Speed as a float (0.2-2.0).
QList<KGrGameData *> gameList; // A list of available games.
KGrGameData * gameData; // Data for the current game.
int gameIndex; // The index in the game-list.
Owner owner; // The game's owner.
int level; // Current play/edit level.
QString levelName; // Level name (optional).
......@@ -180,8 +183,9 @@ private:
bool loading; // Stop input until it's loaded.
bool gameFrozen; // Game stopped.
bool modalFreeze; // Stop game during dialog.
bool messageFreeze; // Stop game during message.
// bool modalFreeze; // Stop game during dialog.
// bool messageFreeze; // Stop game during message.
bool programFreeze; // Stop game during dialog, etc.
QTimer * dyingTimer; // For pause when the hero dies.
......@@ -190,7 +194,7 @@ private:
/******************************************************************************/
/******************************* SOUND SUPPORT *******************************/
/******************************************************************************/
KGrSoundBank *effects;
KGrSoundBank * effects;
enum {
GoldSound,
StepSound,
......@@ -203,14 +207,15 @@ private:
VictorySound,
GameOverSound,
NumSounds };
QVector< int > fx;
QVector<int> fx;
public slots:
void dbgControl (int code); // Authors' debugging aids.
void freeze(); // Stop the gameplay action.
void unfreeze(); // Restart the gameplay action.
void setMessageFreeze (bool);
void pause (const bool userAction, const bool on_off);
// void freeze(); // Stop the gameplay action.
// void unfreeze(); // Restart the gameplay action.
// void setMessageFreeze (bool);
private:
KGrEditor * editor; // The level-editor object.
......@@ -221,13 +226,8 @@ private:
/*********************** GAME PROPERTIES AND METHODS **********************/
/******************************************************************************/
private:
QList<KGrGameData *> gameList; // A list of available games.
KGrGameData * gameData; // Data for the current game.
int gameIndex; // The index in the game-list.
Owner owner; // The game's owner.
bool loadGameData (Owner);
void loadSounds();
/******************************************************************************/
/********************** WORD-WRAPPED MESSAGE BOX ************************/
......@@ -236,4 +236,4 @@ private:
void myMessage (QWidget * parent, const QString &title, const QString &contents);
};
#endif
#endif // KGRGAME_H
......@@ -19,10 +19,14 @@
#include "kgrgameio.h"
#include <KLocale>
#include <KDebug>
#include <QDir>
KGrGameIO::KGrGameIO()
KGrGameIO::KGrGameIO (QWidget * pView)
:
view (pView)
{
}
......@@ -141,6 +145,36 @@ IOStatus KGrGameIO::fetchGameListData
return (OK);
}
bool KGrGameIO::readLevelData (const QString & dir,
const KGrGameData * gameData,
const int levelNo, KGrLevelData & d)
{
kDebug() << "dir" << dir << "Level" << gameData->prefix << levelNo;
QString filePath;
IOStatus stat = fetchLevelData
(dir, gameData->prefix, levelNo, d, filePath);
switch (stat) {
case NotFound:
KGrMessage::information (view, i18n ("Read Level Data"),
i18n ("Cannot find file '%1'.", filePath));
break;
case NoRead:
case NoWrite:
KGrMessage::information (view, i18n ("Read Level Data"),
i18n ("Cannot open file '%1' for read-only.", filePath));
break;
case UnexpectedEOF:
KGrMessage::information (view, i18n ("Read Level Data"),
i18n ("Reached end of file '%1' without finding level data.",
filePath));
break;
case OK:
break;
}
return (stat == OK);
}
IOStatus KGrGameIO::fetchLevelData
(const QString & dir, const QString & prefix,
const int level, KGrLevelData & d, QString & filePath)
......
......@@ -21,11 +21,11 @@
#ifndef _KGRGAMEIO_H_
#define _KGRGAMEIO_H_
#include <QByteArray>
#include <QFile>
#include "kgrglobals.h"
#include <QWidget>
#include <QFile>
/// Return values from I/O operations.
enum IOStatus {OK, NotFound, NoRead, NoWrite, UnexpectedEOF};
......@@ -55,15 +55,16 @@ enum IOStatus {OK, NotFound, NoRead, NoWrite, UnexpectedEOF};
*
* @short KGoldrunner Game-File IO
*/
class KGrGameIO : public QObject
{
Q_OBJECT
public:
/**
* Default constructor.
*
* @param pView The view or widget used as a parent for error messages.
*/
KGrGameIO();
KGrGameIO (QWidget * pView);
/**
* Find and read data for games, into a list of KGrGameData structures.
......@@ -71,15 +72,29 @@ public:
IOStatus fetchGameListData (Owner o, const QString & dir,
QList<KGrGameData *> & gameList,
QString & filePath);
/**
* Find and read data for a level of a game. Can display error messages.
*/
bool readLevelData (const QString & dir, const KGrGameData * gameData,
const int levelNo, KGrLevelData & d);
/**
* Find and read data for a level of a game, into a KGrLevelData structure.
* Returns an OK or error status, but does not display error messages.
*/
IOStatus fetchLevelData (const QString & dir, const QString & prefix,
const int level, KGrLevelData & d,
QString & filePath);
/*
* Rename a file, first removing any existing file that has the target name.
*/
static bool safeRename (const QString & oldName, const QString & newName);
private:
QWidget * view;
QFile openFile;
QString getFilePath (const QString & dir,
......
......@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <KDebug>
#include <KMessageBox> // TODO - Remove.
#include <QTimer>
#include <QList>
......@@ -53,11 +54,15 @@ KGrLevelPlayer::KGrLevelPlayer (QObject * parent)
t.start(); // IDW
}
int KGrLevelPlayer::playerCount = 0;
KGrLevelPlayer::~KGrLevelPlayer()
{
while (! dugBricks.isEmpty()) {
delete dugBricks.takeFirst();
}
kDebug() << "LEVEL PLAYER BEING DELETED.";
playerCount--;
// TODO - Do we need this delete?
// while (! enemies.isEmpty()) {
......@@ -68,6 +73,11 @@ KGrLevelPlayer::~KGrLevelPlayer()
void KGrLevelPlayer::init (KGrCanvas * view, const int mode,
const char rulesCode, const KGrLevelData * levelData)
{
playerCount++;
if (playerCount > 1) {
KMessageBox::information (view, QString("ERROR: KGrLevelPlayer Count = %1").arg(playerCount), "KGrLevelPlayer");
}
// Create the internal model of the level-layout.
grid = new KGrLevelGrid (this, levelData);
......@@ -300,6 +310,16 @@ void KGrLevelPlayer::prepareToPlay()
playState = Ready;
}
void KGrLevelPlayer::pause (bool stop)
{
if (stop) {
timer->pause();
}
else {
timer->resume();
}
}
void KGrLevelPlayer::setTarget (int pointerI, int pointerJ)
{
// Mouse or other pointer device (eg. laptop touchpad) controls the hero.
......@@ -332,7 +352,6 @@ void KGrLevelPlayer::doDig (int button)
return;
}
// TODO - Work this in with game-freezes.
playState = Playing;
switch (button) {
case Qt::LeftButton:
......@@ -587,16 +606,6 @@ int KGrLevelPlayer::runnerGotGold (const int spriteId,
return nuggets;
}
void KGrLevelPlayer::pause (bool stop)
{
if (stop) {
timer->pause();
}
else {
timer->resume();
}
}
void KGrLevelPlayer::makeReappearanceSequence()
{
// The idea is to make each possible x co-ord come up once per levelWidth
......@@ -703,11 +712,6 @@ void KGrLevelPlayer::dbgControl (int code)
}
}
// OBSOLESCENT - 21/1/09 Can do this just by calling tick().
void KGrLevelPlayer::restart()
{
}
void KGrLevelPlayer::bugFix()
{
// Toggle a bug fix on/off dynamically.
......
......@@ -90,19 +90,35 @@ public:
const KGrLevelData * levelData);
/**
* Indicate that setup is complete. The human player can start playing
* Indicate that setup is complete and the human player can start playing
* at any time, by moving the pointer device or pressing a key.
*/
void prepareToPlay ();
/**
* Allow the input-mode to change during play.
* Pause or resume the gameplay in this level.
*
* @param stop If true, pause: if false, resume.
*/
void pause (bool stop);
/**
* Change the input-mode during play.
*
* @param mode The new input-mode to use to control the hero: mouse,
* keyboard or hybrid touchpad and keyboard mode.
*/
inline void setControlMode (const int mode) { controlMode = mode; }
/**
* Set the overall speed of gameplay.
*
* @param timeScale Value 1.0 is for normal speed. Range is 0.2 to 2.0.
* 0.5 is for beginner speed: 1.5 for champion speed.
*/
inline void setTimeScale (const float timeScale)
{ timer->setScale (timeScale); }
/**
* Set a point for the hero to aim at when using mouse or touchpad control.
*
......@@ -219,22 +235,6 @@ public:
*/
void enemyReappear (int & gridI, int & gridJ);
/**
* Pauses or resumes the gameplay in this level.
*
* @param stop If true, pause: if false, resume.
*/
void pause (bool stop);
/**
* Sets the overall speed of gameplay.
*
* @param timeScale Value 1.0 is for normal speed. Range is 0.2 to 2.0.
* 0.5 is for beginner speed: 1.5 for champion speed.
*/
inline void setTimeScale (const float timeScale)
{ timer->setScale (timeScale); }
/**
* Implement author's debugging aids, which are activated only if the level
* is paused and the KConfig file contains group Debugging with setting
......@@ -296,9 +296,6 @@ private:
Direction direction; // Next direction for the hero to take.
KGrTimer * timer; // The time-standard for the level.
// OBSOLESCENT - 21/1/09 Can do this just by calling tick().
void restart(); // Kickstart the game action.
void startDigging (Direction diggingDirection);
void processDugBricks (const int scaledTime);
......@@ -327,6 +324,8 @@ private:
/************************** AUTHORS' DEBUGGING AIDS **************************/
/******************************************************************************/
static int playerCount;
void bugFix(); // Turn a bug fix on/off dynamically.
void startLogging(); // Turn logging on/off.
void showFigurePositions(); // Show everybody's co-ordinates.
......
......@@ -47,24 +47,12 @@ KGrSLDialog::~KGrSLDialog()
{
}
// TODO - Insert the selectLevel() procedure here.
bool KGrSLDialog::selectLevel (int & selectedGame, int & selectedLevel)
{
selectedGame = defaultGame;
selectedLevel = 0; // 0 = no selection (Cancel) or invalid.
// TODO - Put this in KGrGame?
// Halt the game during the dialog.
// modalFreeze = false;
// if (! gameFrozen) {
// modalFreeze = true;
// freeze();
// }
// Create and run a modal dialog box to select a game and level.
// TODO - Avoid using KGrGame * as parameter 5.
// KGrSLDialog * sl = new KGrSLDialog (action, requestedLevel, gameIndex,
// gameList, /* this, */ view);
// TODO - Strip out editor-related validation, etc. It's in KGrEditor now.
while (exec() == QDialog::Accepted) {
selectedGame = slGameIndex;
selectedLevel = 0; // In case the selection is invalid.
......@@ -107,23 +95,9 @@ bool KGrSLDialog::selectLevel (int & selectedGame, int & selectedLevel)
selectedLevel = 0; // Set an invalid selection.
continue; // Re-run the dialog box.
}
// If "OK", set the results.
// gameData = gameList.at (selectedGame);
// owner = gameData->owner;
// gameIndex = selectedGame;
// Set default rules for selected game.
break;
break; // Accepted and valid.
}
// TODO - Put this in KGrGame?
// Unfreeze the game, but only if it was previously unfrozen.
// if (modalFreeze) {
// unfreeze();
// modalFreeze = false;