Added camera zoom (from GAE) into mega-glest (middle mouse button zooms in and out like in GAE)

This commit is contained in:
Mark Vejvoda 2010-03-23 02:35:55 +00:00
parent 397fe3dc41
commit 5b713bd785
13 changed files with 1988 additions and 75 deletions

View File

@ -42,6 +42,7 @@ Game::Game(Program *program, const GameSettings *gameSettings):
ProgramState(program)
{
this->gameSettings= *gameSettings;
scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed","1.5");
mouseX=0;
mouseY=0;
@ -415,49 +416,69 @@ void Game::mouseDoubleClickLeft(int x, int y){
void Game::mouseMove(int x, int y, const MouseState *ms){
const Metrics &metrics= Metrics::getInstance();
const Metrics &metrics = Metrics::getInstance();
mouseX= x;
mouseY= y;
mouseX = x;
mouseY = y;
//main window
if(y<10){
gameCamera.setMoveZ(-1);
}
else if(y> metrics.getVirtualH()-10){
gameCamera.setMoveZ(1);
}
else{
gameCamera.stopMoveZ();
/*
if (ms.get(mbCenter)) {
if (input.isCtrlDown()) {
float speed = input.isShiftDown() ? 1.f : 0.125f;
float response = input.isShiftDown() ? 0.1875f : 0.0625f;
gameCamera.moveForwardH((y - lastMousePos.y) * speed, response);
gameCamera.moveSideH((x - lastMousePos.x) * speed, response);
} else {
//float ymult = Config::getInstance().getCameraInvertYAxis() ? -0.2f : 0.2f;
//float xmult = Config::getInstance().getCameraInvertXAxis() ? -0.2f : 0.2f;
float ymult = 0.2f;
float xmult = 0.2f;
gameCamera.transitionVH(-(y - lastMousePos.y) * ymult, (lastMousePos.x - x) * xmult);
}
} else */
{
//main window
if (y < 10) {
gameCamera.setMoveZ(-scrollSpeed);
} else if (y > metrics.getVirtualH() - 10) {
gameCamera.setMoveZ(scrollSpeed);
} else {
gameCamera.setMoveZ(0);
}
if (x < 10) {
gameCamera.setMoveX(-scrollSpeed);
} else if (x > metrics.getVirtualW() - 10) {
gameCamera.setMoveX(scrollSpeed);
} else {
gameCamera.setMoveX(0);
}
if (mainMessageBox.getEnabled()) {
mainMessageBox.mouseMove(x, y);
} else if (ScriptManager::getMessageBox()->getEnabled()) {
ScriptManager::getMessageBox()->mouseMove(x, y);
//} else if (saveBox) {
// saveBox->mouseMove(x, y);
} else {
//graphics
gui.mouseMoveGraphics(x, y);
}
}
if(x<10){
gameCamera.setMoveX(-1);
}
else if(x> metrics.getVirtualW()-10){
gameCamera.setMoveX(1);
}
else{
gameCamera.stopMoveX();
}
if(mainMessageBox.getEnabled()){
mainMessageBox.mouseMove(x, y);
}
if(scriptManager.getMessageBox()->getEnabled()){
scriptManager.getMessageBox()->mouseMove(x, y);
}
//graphics
gui.mouseMoveGraphics(x, y);
//display
if(metrics.isInDisplay(x, y) && !gui.isSelecting() && !gui.isSelectingPos()){
if(!gui.isSelectingPos()){
//display
if (metrics.isInDisplay(x, y) && !gui.isSelecting() && !gui.isSelectingPos()) {
if (!gui.isSelectingPos()) {
gui.mouseMoveDisplay(x - metrics.getDisplayX(), y - metrics.getDisplayY());
}
}
}
}
}
void Game::eventMouseWheel(int x, int y, int zDelta) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//gameCamera.transitionXYZ(0.0f, -(float)zDelta / 30.0f, 0.0f);
gameCamera.zoom((float)zDelta / 30.0f);
}
void Game::keyDown(char key){
@ -595,17 +616,17 @@ void Game::keyUp(char key){
case 'W':
case 'S':
gameCamera.stopMoveY();
gameCamera.setMoveY(0);
break;
case vkUp:
case vkDown:
gameCamera.stopMoveZ();
gameCamera.setMoveZ(0);
break;
case vkLeft:
case vkRight:
gameCamera.stopMoveX();
gameCamera.setMoveX(0);
break;
}
}

View File

@ -0,0 +1,137 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_GAME_H_
#define _GLEST_GAME_GAME_H_
#include <vector>
#include "gui.h"
#include "game_camera.h"
#include "world.h"
#include "ai_interface.h"
#include "program.h"
#include "chat_manager.h"
#include "script_manager.h"
#include "game_settings.h"
using std::vector;
namespace Glest{ namespace Game{
class GraphicMessageBox;
// =====================================================
// class Game
//
// Main game class
// =====================================================
class Game: public ProgramState{
public:
enum Speed{
sFast,
sNormal,
sSlow
};
private:
typedef vector<Ai*> Ais;
typedef vector<AiInterface*> AiInterfaces;
private:
//main data
World world;
AiInterfaces aiInterfaces;
Gui gui;
GameCamera gameCamera;
Commander commander;
Console console;
ChatManager chatManager;
ScriptManager scriptManager;
//misc
Checksum checksum;
string loadingText;
int mouse2d;
int mouseX, mouseY; //coords win32Api
int updateFps, lastUpdateFps;
int renderFps, lastRenderFps;
bool paused;
bool gameOver;
bool renderNetworkStatus;
float scrollSpeed;
Speed speed;
GraphicMessageBox mainMessageBox;
//misc ptr
ParticleSystem *weatherParticleSystem;
GameSettings gameSettings;
public:
Game(Program *program, const GameSettings *gameSettings);
~Game();
//get
GameSettings *getGameSettings() {return &gameSettings;}
const GameCamera *getGameCamera() const {return &gameCamera;}
GameCamera *getGameCamera() {return &gameCamera;}
const Commander *getCommander() const {return &commander;}
Gui *getGui() {return &gui;}
const Gui *getGui() const {return &gui;}
Commander *getCommander() {return &commander;}
Console *getConsole() {return &console;}
ScriptManager *getScriptManager() {return &scriptManager;}
World *getWorld() {return &world;}
const World *getWorld() const {return &world;}
//init
virtual void load();
virtual void init();
virtual void update();
virtual void updateCamera();
virtual void render();
virtual void tick();
//event managing
virtual void keyDown(char key);
virtual void keyUp(char key);
virtual void keyPress(char c);
virtual void mouseDownLeft(int x, int y);
virtual void mouseDownRight(int x, int y);
virtual void mouseUpLeft(int x, int y);
virtual void mouseDoubleClickLeft(int x, int y);
virtual void eventMouseWheel(int x, int y, int zDelta);
virtual void mouseMove(int x, int y, const MouseState *mouseState);
void quitGame();
private:
//render
void render3d();
void render2d();
//misc
void checkWinner();
void checkWinnerStandard();
void checkWinnerScripted();
bool hasBuilding(const Faction *faction);
void incSpeed();
void decSpeed();
int getUpdateLoops();
void showLoseMessageBox();
void showWinMessageBox();
void showMessageBox(const string &text, const string &header, bool toggle);
};
}}//end namespace
#endif

View File

@ -0,0 +1,329 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "game_camera.h"
#include <cstdlib>
#include "config.h"
#include "game_constants.h"
#include "xml_parser.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
using Shared::Xml::XmlNode;
namespace Glest { namespace Game {
// =====================================================
// class GameCamera
// =====================================================
// ================== PUBLIC =====================
const float GameCamera::startingVAng= -60.f;
const float GameCamera::startingHAng= 0.f;
const float GameCamera::vTransitionMult= 0.125f;
const float GameCamera::hTransitionMult= 0.125f;
const float GameCamera::defaultHeight= 20.f;
const float GameCamera::centerOffsetZ= 8.0f;
// ================= Constructor =================
GameCamera::GameCamera() : pos(0.f, defaultHeight, 0.f),
destPos(0.f, defaultHeight, 0.f), destAng(startingVAng, startingHAng) {
Config &config = Config::getInstance();
state= sGame;
//config
speed= 15.f / GameConstants::cameraFps;
clampBounds= !Config::getInstance().getBool("PhotoMode");
vAng= startingVAng;
hAng= startingHAng;
rotate=0;
move= Vec3f(0.f);
maxRenderDistance = Config::getInstance().getFloat("RenderDistanceMax","64");
maxHeight = Config::getInstance().getFloat("CameraMaxDistance","35");
minHeight = Config::getInstance().getFloat("CameraMinDistance","8");
maxCameraDist = maxHeight;
minCameraDist = minHeight;
minVAng = -Config::getInstance().getFloat("CameraMaxYaw","77.5");
maxVAng = -Config::getInstance().getFloat("CameraMinYaw","20");
fov = Config::getInstance().getFloat("CameraFov","45");
}
void GameCamera::init(int limitX, int limitY){
this->limitX= limitX;
this->limitY= limitY;
}
// ==================== Misc =====================
void GameCamera::setPos(Vec2f pos){
this->pos= Vec3f(pos.x, this->pos.y, pos.y);
clampPosXZ(0.0f, (float)limitX, 0.0f, (float)limitY);
destPos.x = pos.x;
destPos.z = pos.y;
}
void GameCamera::update(){
//move XZ
if(move.z){
moveForwardH(speed * move.z, 0.9f);
}
if(move.x){
moveSideH(speed * move.x, 0.9f);
}
//free state
if(state==sFree){
if(fabs(rotate) == 1){
rotateHV(speed*5*rotate, 0);
}
if(move.y>0){
moveUp(speed * move.y);
if(clampBounds && pos.y<maxHeight){
rotateHV(0.f, -speed * 1.7f * move.y);
}
}
if(move.y<0){
moveUp(speed * move.y);
if(clampBounds && pos.y>minHeight){
rotateHV(0.f, -speed * 1.7f * move.y);
}
}
}
//game state
if(abs(destAng.x - vAng) > 0.01f) {
vAng+= (destAng.x - vAng) * hTransitionMult;
}
if(abs(destAng.y - hAng) > 0.01f) {
if(abs(destAng.y - hAng) > 180) {
if(destAng.y > hAng) {
hAng+= (destAng.y - hAng - 360) * vTransitionMult;
} else {
hAng+= (destAng.y - hAng + 360) * vTransitionMult;
}
} else {
hAng+= (destAng.y - hAng) * vTransitionMult;
}
}
if(abs(destPos.x - pos.x) > 0.01f) {
pos.x += (destPos.x - pos.x) / 32.0f;
}
if(abs(destPos.y - pos.y) > 0.01f) {
pos.y += (destPos.y - pos.y) / 32.0f;
}
if(abs(destPos.z - pos.z) > 0.01f) {
pos.z += (destPos.z - pos.z) / 32.0f;
}
clampAng();
if(clampBounds){
clampPosXYZ(0.0f, (float)limitX, minHeight, maxHeight, 0.0f, (float)limitY);
}
}
Quad2i GameCamera::computeVisibleQuad() const{
/*
//maxRenderDistance
float flatDist = maxRenderDistance * -cos(degToRad(vAng + fov / 2.f));
Vec3f p1(flatDist * sin(degToRad(hAng + fov / 2.f)), maxRenderDistance * sin(degToRad(vAng + fov / 2.f)), flatDist * -cos(degToRad(hAng + fov / 2.f)));
Vec3f p2(flatDist * sin(degToRad(hAng - fov / 2.f)), maxRenderDistance * sin(degToRad(vAng + fov / 2.f)), flatDist * -cos(degToRad(hAng - fov / 2.f)));
flatDist = maxRenderDistance * -cos(degToRad(vAng - fov / 2.f));
Vec3f p3(flatDist * sin(degToRad(hAng + fov / 2.f)), maxRenderDistance * sin(degToRad(vAng - fov / 2.f)), flatDist * -cos(degToRad(hAng + fov / 2.f)));
Vec3f p4(flatDist * sin(degToRad(hAng - fov / 2.f)), maxRenderDistance * sin(degToRad(vAng - fov / 2.f)), flatDist * -cos(degToRad(hAng - fov / 2.f)));
// find the floor
if(-p1.y > pos.y) {
p1 = p1 * pos.y / abs(p1.y);
}
if(-p2.y > pos.y) {
p2 = p2 * pos.y / abs(p2.y);
}
if(-p3.y > pos.y) {
p3 = p3 * pos.y / abs(p3.y);
}
if(-p4.y > pos.y) {
p4 = p4 * pos.y / abs(p4.y);
}
Vec2i pi1(p1.x, p1.z), pi2(p2.x, p2.z), pi3(p3.x, p3.z), pi4(p4.x, p4.z);
if(hAng>=135 && hAng<=225){
return Quad2i(pi1, pi2, pi3, pi4);
}
if(hAng>=45 && hAng<=135){
return Quad2i(pi3, pi1, pi4, pi2);
}
if(hAng>=225 && hAng<=315) {
return Quad2i(pi2, pi4, pi1, pi3);
}
return Quad2i(pi4, pi3, pi2, pi1);
*/
float nearDist = 20.f;
float dist = pos.y > 20.f ? pos.y * 1.2f : 20.f;
float farDist = 90.f * (pos.y > 20.f ? pos.y / 15.f : 1.f);
float fov = Config::getInstance().getFloat("CameraFov","45");
Vec2f v(sinf(degToRad(180 - hAng)), cosf(degToRad(180 - hAng)));
Vec2f v1(sinf(degToRad(180 - hAng - fov)), cosf(degToRad(180 - hAng - fov)));
Vec2f v2(sinf(degToRad(180 - hAng + fov)), cosf(degToRad(180 - hAng + fov)));
v.normalize();
v1.normalize();
v2.normalize();
Vec2f p = Vec2f(pos.x, pos.z) - v * dist;
Vec2i p1(static_cast<int>(p.x + v1.x * nearDist), static_cast<int>(p.y + v1.y * nearDist));
Vec2i p2(static_cast<int>(p.x + v1.x * farDist), static_cast<int>(p.y + v1.y * farDist));
Vec2i p3(static_cast<int>(p.x + v2.x * nearDist), static_cast<int>(p.y + v2.y * nearDist));
Vec2i p4(static_cast<int>(p.x + v2.x * farDist), static_cast<int>(p.y + v2.y * farDist));
if (hAng >= 135 && hAng <= 225) {
return Quad2i(p1, p2, p3, p4);
}
if (hAng >= 45 && hAng <= 135) {
return Quad2i(p3, p1, p4, p2);
}
if (hAng >= 225 && hAng <= 315) {
return Quad2i(p2, p4, p1, p3);
}
return Quad2i(p4, p3, p2, p1);
}
void GameCamera::switchState(){
if(state==sGame){
state= sFree;
}
else{
state= sGame;
destAng.x = startingVAng;
destAng.y = startingHAng;
destPos.y = defaultHeight;
}
}
void GameCamera::centerXZ(float x, float z){
destPos.x = pos.x= x;
destPos.z = pos.z= z+centerOffsetZ;
}
void GameCamera::transitionXYZ(float x, float y, float z) {
destPos.x += x;
destPos.y += y;
destPos.z += z;
clampPosXYZ(0.0f, (float)limitX, minHeight, maxHeight, 0.0f, (float)limitY);
}
void GameCamera::transitionVH(float v, float h) {
destAng.x += v;
destPos.y -= v * destPos.y / 100.f;
destAng.y += h;
clampAng();
}
void GameCamera::zoom(float dist) {
float flatDist = dist * cosf(degToRad(vAng));
Vec3f offset(flatDist * sinf(degToRad(hAng)), dist * sinf(degToRad(vAng)), flatDist * -cosf(degToRad(hAng)));
float mult = 1.f;
if(destPos.y + offset.y < minHeight) {
mult = abs((destPos.y - minHeight) / offset.y);
} else if(destPos.y + offset.y > maxHeight) {
mult = abs((maxHeight - destPos.y) / offset.y);
}
destPos += offset * mult;
}
void GameCamera::load(const XmlNode *node) {
//destPos = node->getChildVec3fValue("pos");
//destAng = node->getChildVec2fValue("angle");
}
void GameCamera::save(XmlNode *node) const {
//node->addChild("pos", pos);
//node->addChild("angle", Vec2f(vAng, hAng));
}
// ==================== PRIVATE ====================
void GameCamera::clampPosXZ(float x1, float x2, float z1, float z2){
if(pos.x < x1) pos.x = x1;
if(destPos.x < x1) destPos.x = x1;
if(pos.z < z1) pos.z = z1;
if(destPos.z < z1) destPos.z = z1;
if(pos.x > x2) pos.x = x2;
if(destPos.x > x2) destPos.x = x2;
if(pos.z > z2) pos.z = z2;
if(destPos.z > z2) destPos.z = z2;
}
void GameCamera::clampPosXYZ(float x1, float x2, float y1, float y2, float z1, float z2){
if(pos.x < x1) pos.x = x1;
if(destPos.x < x1) destPos.x = x1;
if(pos.y < y1) pos.y = y1;
if(destPos.y < y1) destPos.y = y1;
if(pos.z < z1) pos.z = z1;
if(destPos.z < z1) destPos.z = z1;
if(pos.x > x2) pos.x = x2;
if(destPos.x > x2) destPos.x = x2;
if(pos.y > y2) pos.y = y2;
if(destPos.y > y2) destPos.y = y2;
if(pos.z > z2) pos.z = z2;
if(destPos.z > z2) destPos.z = z2;
}
void GameCamera::rotateHV(float h, float v){
destAng.x = vAng += v;
destAng.y = hAng += h;
clampAng();
}
void GameCamera::clampAng() {
if(vAng > maxVAng) vAng = maxVAng;
if(destAng.x > maxVAng) destAng.x = maxVAng;
if(vAng < minVAng) vAng = minVAng;
if(destAng.x < minVAng) destAng.x = minVAng;
if(hAng > 360.f) hAng -= 360.f;
if(destAng.y > 360.f) destAng.y -= 360.f;
if(hAng < 0.f) hAng += 360.f;
if(destAng.y < 0.f) destAng.y = 360.f;
}
//move camera forwad but never change heightFactor
void GameCamera::moveForwardH(float d, float response) {
Vec3f offset(sinf(degToRad(hAng)) * d, 0.f, -cosf(degToRad(hAng)) * d);
destPos += offset;
pos.x += offset.x * response;
pos.z += offset.z * response;
}
//move camera to a side but never change heightFactor
void GameCamera::moveSideH(float d, float response){
Vec3f offset(sinf(degToRad(hAng+90)) * d, 0.f, -cosf(degToRad(hAng+90)) * d);
destPos += offset;
pos.x += (destPos.x - pos.x) * response;
pos.z += (destPos.z - pos.z) * response;
}
void GameCamera::moveUp(float d){
// pos.y+= d;
destPos.y += d;
}
}}//end namespace

View File

@ -0,0 +1,133 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_GAMECAMERA_H_
#define _GLEST_GAME_GAMECAMERA_H_
#include "vec.h"
#include "math_util.h"
namespace Shared { namespace Xml {
class XmlNode;
}}
namespace Glest{ namespace Game{
using Shared::Graphics::Quad2i;
using Shared::Graphics::Vec3f;
using Shared::Graphics::Vec2f;
using Shared::Xml::XmlNode;
class Config;
// =====================================================
// class GameCamera
//
/// A basic camera that holds information about the game view
// =====================================================
class GameCamera{
public:
static const float startingVAng;
static const float startingHAng;
static const float vTransitionMult;
static const float hTransitionMult;
static const float defaultHeight;
static const float centerOffsetZ;
public:
enum State{
sGame,
sFree
};
private:
Vec3f pos;
Vec3f destPos;
float hAng; //YZ plane positive -Z axis
float vAng; //XZ plane positive +Z axis
float lastHAng;
float lastVAng;
Vec2f destAng;
float rotate;
Vec3f move;
State state;
int limitX;
int limitY;
//config
float speed;
bool clampBounds;
float maxRenderDistance;
float maxHeight;
float minHeight;
float maxCameraDist;
float minCameraDist;
float minVAng;
float maxVAng;
float fov;
public:
GameCamera();
void init(int limitX, int limitY);
//get
float getHAng() const {return hAng;};
float getVAng() const {return vAng;}
State getState() const {return state;}
const Vec3f &getPos() const {return pos;}
//set
void setRotate(float rotate){this->rotate= rotate;}
void setPos(Vec2f pos);
void setMoveX(float f) {this->move.x= f;}
void setMoveY(float f) {this->move.y= f;}
void setMoveZ(float f) {this->move.z= f;}
void stop() {
destPos = pos;
destAng.x = vAng;
destAng.y = hAng;
}
//other
void update();
Quad2i computeVisibleQuad() const;
void switchState();
void centerXZ(float x, float z);
void rotateHV(float h, float v);
void transitionXYZ(float x, float y, float z);
void transitionVH(float v, float h);
void zoom(float dist);
void moveForwardH(float dist, float response); // response: 1.0 for immediate, 0 for full inertia
void moveSideH(float dist, float response);
void load(const XmlNode *node);
void save(XmlNode *node) const;
private:
void clampPosXYZ(float x1, float x2, float y1, float y2, float z1, float z2);
void clampPosXZ(float x1, float x2, float z1, float z2);
void clampAng();
void moveUp(float dist);
};
}} //end namespace
#endif

View File

@ -0,0 +1,402 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2005 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "script_manager.h"
#include "world.h"
#include "lang.h"
#include "game_camera.h"
#include "leak_dumper.h"
using namespace Shared::Platform;
using namespace Shared::Lua;
namespace Glest{ namespace Game{
// =====================================================
// class PlayerModifiers
// =====================================================
PlayerModifiers::PlayerModifiers(){
winner= false;
aiEnabled= true;
}
// =====================================================
// class ScriptManager
// =====================================================
GraphicMessageBox ScriptManager::messageBox;
ScriptManager* ScriptManager::thisScriptManager= NULL;
const int ScriptManager::messageWrapCount= 30;
const int ScriptManager::displayTextWrapCount= 64;
void ScriptManager::init(World* world, GameCamera *gameCamera){
const Scenario* scenario= world->getScenario();
this->world= world;
this->gameCamera= gameCamera;
//set static instance
thisScriptManager= this;
//register functions
luaScript.registerFunction(showMessage, "showMessage");
luaScript.registerFunction(setDisplayText, "setDisplayText");
luaScript.registerFunction(clearDisplayText, "clearDisplayText");
luaScript.registerFunction(setCameraPosition, "setCameraPosition");
luaScript.registerFunction(createUnit, "createUnit");
luaScript.registerFunction(giveResource, "giveResource");
luaScript.registerFunction(givePositionCommand, "givePositionCommand");
luaScript.registerFunction(giveProductionCommand, "giveProductionCommand");
luaScript.registerFunction(giveUpgradeCommand, "giveUpgradeCommand");
luaScript.registerFunction(disableAi, "disableAi");
luaScript.registerFunction(setPlayerAsWinner, "setPlayerAsWinner");
luaScript.registerFunction(endGame, "endGame");
luaScript.registerFunction(getStartLocation, "startLocation");
luaScript.registerFunction(getUnitPosition, "unitPosition");
luaScript.registerFunction(getUnitFaction, "unitFaction");
luaScript.registerFunction(getResourceAmount, "resourceAmount");
luaScript.registerFunction(getLastCreatedUnitName, "lastCreatedUnitName");
luaScript.registerFunction(getLastCreatedUnitId, "lastCreatedUnit");
luaScript.registerFunction(getLastDeadUnitName, "lastDeadUnitName");
luaScript.registerFunction(getLastDeadUnitId, "lastDeadUnit");
luaScript.registerFunction(getUnitCount, "unitCount");
luaScript.registerFunction(getUnitCountOfType, "unitCountOfType");
//load code
for(int i= 0; i<scenario->getScriptCount(); ++i){
const Script* script= scenario->getScript(i);
luaScript.loadCode("function " + script->getName() + "()" + script->getCode() + "end\n", script->getName());
}
//setup message box
messageBox.init( Lang::getInstance().get("Ok") );
messageBox.setEnabled(false);
//last created unit
lastCreatedUnitId= -1;
lastDeadUnitId= -1;
gameOver= false;
//call startup function
luaScript.beginCall("startup");
luaScript.endCall();
}
// ========================== events ===============================================
void ScriptManager::onMessageBoxOk(){
Lang &lang= Lang::getInstance();
if(!messageQueue.empty()){
messageQueue.pop();
if(!messageQueue.empty()){
messageBox.setText(wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount));
messageBox.setHeader(lang.getScenarioString(messageQueue.front().getHeader()));
}
}
}
void ScriptManager::onResourceHarvested(){
luaScript.beginCall("resourceHarvested");
luaScript.endCall();
}
void ScriptManager::onUnitCreated(const Unit* unit){
lastCreatedUnitName= unit->getType()->getName();
lastCreatedUnitId= unit->getId();
luaScript.beginCall("unitCreated");
luaScript.endCall();
luaScript.beginCall("unitCreatedOfType_"+unit->getType()->getName());
luaScript.endCall();
}
void ScriptManager::onUnitDied(const Unit* unit){
lastDeadUnitName= unit->getType()->getName();
lastDeadUnitId= unit->getId();
luaScript.beginCall("unitDied");
luaScript.endCall();
}
// ========================== lua wrappers ===============================================
string ScriptManager::wrapString(const string &str, int wrapCount){
string returnString;
int letterCount= 0;
for(int i= 0; i<str.size(); ++i){
if(letterCount>wrapCount && str[i]==' '){
returnString+= '\n';
letterCount= 0;
}
else
{
returnString+= str[i];
}
++letterCount;
}
return returnString;
}
void ScriptManager::showMessage(const string &text, const string &header){
Lang &lang= Lang::getInstance();
messageQueue.push(ScriptManagerMessage(text, header));
messageBox.setEnabled(true);
messageBox.setText(wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount));
messageBox.setHeader(lang.getScenarioString(messageQueue.front().getHeader()));
}
void ScriptManager::clearDisplayText(){
displayText= "";
}
void ScriptManager::setDisplayText(const string &text){
displayText= wrapString(Lang::getInstance().getScenarioString(text), displayTextWrapCount);
}
void ScriptManager::setCameraPosition(const Vec2i &pos){
gameCamera->centerXZ(pos.x, pos.y);
}
void ScriptManager::createUnit(const string &unitName, int factionIndex, Vec2i pos){
world->createUnit(unitName, factionIndex, pos);
}
void ScriptManager::giveResource(const string &resourceName, int factionIndex, int amount){
world->giveResource(resourceName, factionIndex, amount);
}
void ScriptManager::givePositionCommand(int unitId, const string &commandName, const Vec2i &pos){
world->givePositionCommand(unitId, commandName, pos);
}
void ScriptManager::giveProductionCommand(int unitId, const string &producedName){
world->giveProductionCommand(unitId, producedName);
}
void ScriptManager::giveUpgradeCommand(int unitId, const string &producedName){
world->giveUpgradeCommand(unitId, producedName);
}
void ScriptManager::disableAi(int factionIndex){
if(factionIndex<GameConstants::maxPlayers){
playerModifiers[factionIndex].disableAi();
}
}
void ScriptManager::setPlayerAsWinner(int factionIndex){
if(factionIndex<GameConstants::maxPlayers){
playerModifiers[factionIndex].setAsWinner();
}
}
void ScriptManager::endGame(){
gameOver= true;
}
Vec2i ScriptManager::getStartLocation(int factionIndex){
return world->getStartLocation(factionIndex);
}
Vec2i ScriptManager::getUnitPosition(int unitId){
return world->getUnitPosition(unitId);
}
int ScriptManager::getUnitFaction(int unitId){
return world->getUnitFactionIndex(unitId);
}
int ScriptManager::getResourceAmount(const string &resourceName, int factionIndex){
return world->getResourceAmount(resourceName, factionIndex);
}
const string &ScriptManager::getLastCreatedUnitName(){
return lastCreatedUnitName;
}
int ScriptManager::getLastCreatedUnitId(){
return lastCreatedUnitId;
}
const string &ScriptManager::getLastDeadUnitName(){
return lastDeadUnitName;
}
int ScriptManager::getLastDeadUnitId(){
return lastDeadUnitId;
}
int ScriptManager::getUnitCount(int factionIndex){
return world->getUnitCount(factionIndex);
}
int ScriptManager::getUnitCountOfType(int factionIndex, const string &typeName){
return world->getUnitCountOfType(factionIndex, typeName);
}
// ========================== lua callbacks ===============================================
int ScriptManager::showMessage(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->showMessage(luaArguments.getString(-2), luaArguments.getString(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::setDisplayText(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->setDisplayText(luaArguments.getString(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::clearDisplayText(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->clearDisplayText();
return luaArguments.getReturnCount();
}
int ScriptManager::setCameraPosition(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->setCameraPosition(Vec2i(luaArguments.getVec2i(-1)));
return luaArguments.getReturnCount();
}
int ScriptManager::createUnit(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->createUnit(
luaArguments.getString(-3),
luaArguments.getInt(-2),
luaArguments.getVec2i(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::giveResource(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->giveResource(luaArguments.getString(-3), luaArguments.getInt(-2), luaArguments.getInt(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::givePositionCommand(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->givePositionCommand(
luaArguments.getInt(-3),
luaArguments.getString(-2),
luaArguments.getVec2i(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::giveProductionCommand(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->giveProductionCommand(
luaArguments.getInt(-2),
luaArguments.getString(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::giveUpgradeCommand(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->giveUpgradeCommand(
luaArguments.getInt(-2),
luaArguments.getString(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::disableAi(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->disableAi(luaArguments.getInt(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::setPlayerAsWinner(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->setPlayerAsWinner(luaArguments.getInt(-1));
return luaArguments.getReturnCount();
}
int ScriptManager::endGame(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
thisScriptManager->endGame();
return luaArguments.getReturnCount();
}
int ScriptManager::getStartLocation(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
Vec2i pos= thisScriptManager->getStartLocation(luaArguments.getInt(-1));
luaArguments.returnVec2i(pos);
return luaArguments.getReturnCount();
}
int ScriptManager::getUnitPosition(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
Vec2i pos= thisScriptManager->getUnitPosition(luaArguments.getInt(-1));
luaArguments.returnVec2i(pos);
return luaArguments.getReturnCount();
}
int ScriptManager::getUnitFaction(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
int factionIndex= thisScriptManager->getUnitFaction(luaArguments.getInt(-1));
luaArguments.returnInt(factionIndex);
return luaArguments.getReturnCount();
}
int ScriptManager::getResourceAmount(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
luaArguments.returnInt(thisScriptManager->getResourceAmount(luaArguments.getString(-2), luaArguments.getInt(-1)));
return luaArguments.getReturnCount();
}
int ScriptManager::getLastCreatedUnitName(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
luaArguments.returnString(thisScriptManager->getLastCreatedUnitName());
return luaArguments.getReturnCount();
}
int ScriptManager::getLastCreatedUnitId(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
luaArguments.returnInt(thisScriptManager->getLastCreatedUnitId());
return luaArguments.getReturnCount();
}
int ScriptManager::getLastDeadUnitName(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
luaArguments.returnString(thisScriptManager->getLastDeadUnitName());
return luaArguments.getReturnCount();
}
int ScriptManager::getLastDeadUnitId(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
luaArguments.returnInt(thisScriptManager->getLastDeadUnitId());
return luaArguments.getReturnCount();
}
int ScriptManager::getUnitCount(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
luaArguments.returnInt(thisScriptManager->getUnitCount(luaArguments.getInt(-1)));
return luaArguments.getReturnCount();
}
int ScriptManager::getUnitCountOfType(LuaHandle* luaHandle){
LuaArguments luaArguments(luaHandle);
luaArguments.returnInt(thisScriptManager->getUnitCountOfType(luaArguments.getInt(-2), luaArguments.getString(-1)));
return luaArguments.getReturnCount();
}
}}//end namespace

View File

@ -0,0 +1,183 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2005 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_SCRIPT_MANAGER_H_
#define _GLEST_GAME_SCRIPT_MANAGER_H_
#include <string>
#include <queue>
#include "lua_script.h"
#include "vec.h"
#include "components.h"
#include "game_constants.h"
using std::string;
using std::queue;
using Shared::Graphics::Vec2i;
using Shared::Lua::LuaScript;
using Shared::Lua::LuaHandle;
namespace Glest{ namespace Game{
class World;
class Unit;
class GameCamera;
// =====================================================
// class ScriptManagerMessage
// =====================================================
class ScriptManagerMessage{
private:
string text;
string header;
public:
ScriptManagerMessage(string text, string header) {this->text= text, this->header= header;}
const string &getText() const {return text;}
const string &getHeader() const {return header;}
};
class PlayerModifiers{
public:
PlayerModifiers();
void disableAi() {aiEnabled= false;}
void setAsWinner() {winner= true;}
bool getWinner() const {return winner;}
bool getAiEnabled() const {return aiEnabled;}
private:
bool winner;
bool aiEnabled;
};
// =====================================================
// class ScriptManager
// =====================================================
class ScriptManager{
private:
typedef queue<ScriptManagerMessage> MessageQueue;
private:
//lua
string code;
LuaScript luaScript;
//world
World *world;
GameCamera *gameCamera;
//misc
MessageQueue messageQueue;
static GraphicMessageBox messageBox;
string displayText;
//last created unit
string lastCreatedUnitName;
int lastCreatedUnitId;
//last dead unit
string lastDeadUnitName;
int lastDeadUnitId;
// end game state
bool gameOver;
PlayerModifiers playerModifiers[GameConstants::maxPlayers];
private:
static ScriptManager* thisScriptManager;
private:
static const int messageWrapCount;
static const int displayTextWrapCount;
public:
void init(World* world, GameCamera *gameCamera);
//message box functions
bool getMessageBoxEnabled() const {return !messageQueue.empty();}
static GraphicMessageBox* getMessageBox() {return &messageBox;}
string getDisplayText() const {return displayText;}
bool getGameOver() const {return gameOver;}
const PlayerModifiers *getPlayerModifiers(int factionIndex) const {return &playerModifiers[factionIndex];}
//events
void onMessageBoxOk();
void onResourceHarvested();
void onUnitCreated(const Unit* unit);
void onUnitDied(const Unit* unit);
private:
string wrapString(const string &str, int wrapCount);
//wrappers, commands
void showMessage(const string &text, const string &header);
void clearDisplayText();
void setDisplayText(const string &text);
void setCameraPosition(const Vec2i &pos);
void createUnit(const string &unitName, int factionIndex, Vec2i pos);
void giveResource(const string &resourceName, int factionIndex, int amount);
void givePositionCommand(int unitId, const string &producedName, const Vec2i &pos);
void giveProductionCommand(int unitId, const string &producedName);
void giveUpgradeCommand(int unitId, const string &upgradeName);
void disableAi(int factionIndex);
void setPlayerAsWinner(int factionIndex);
void endGame();
//wrappers, queries
Vec2i getStartLocation(int factionIndex);
Vec2i getUnitPosition(int unitId);
int getUnitFaction(int unitId);
int getResourceAmount(const string &resourceName, int factionIndex);
const string &getLastCreatedUnitName();
int getLastCreatedUnitId();
const string &getLastDeadUnitName();
int getLastDeadUnitId();
int getUnitCount(int factionIndex);
int getUnitCountOfType(int factionIndex, const string &typeName);
//callbacks, commands
static int showMessage(LuaHandle* luaHandle);
static int setDisplayText(LuaHandle* luaHandle);
static int clearDisplayText(LuaHandle* luaHandle);
static int setCameraPosition(LuaHandle* luaHandle);
static int createUnit(LuaHandle* luaHandle);
static int giveResource(LuaHandle* luaHandle);
static int givePositionCommand(LuaHandle* luaHandle);
static int giveProductionCommand(LuaHandle* luaHandle);
static int giveUpgradeCommand(LuaHandle* luaHandle);
static int disableAi(LuaHandle* luaHandle);
static int setPlayerAsWinner(LuaHandle* luaHandle);
static int endGame(LuaHandle* luaHandle);
//callbacks, queries
static int getStartLocation(LuaHandle* luaHandle);
static int getUnitPosition(LuaHandle* luaHandle);
static int getUnitFaction(LuaHandle* luaHandle);
static int getResourceAmount(LuaHandle* luaHandle);
static int getLastCreatedUnitName(LuaHandle* luaHandle);
static int getLastCreatedUnitId(LuaHandle* luaHandle);
static int getLastDeadUnitName(LuaHandle* luaHandle);
static int getLastDeadUnitId(LuaHandle* luaHandle);
static int getUnitCount(LuaHandle* luaHandle);
static int getUnitCountOfType(LuaHandle* luaHandle);
};
}}//end namespace
#endif

View File

@ -90,16 +90,22 @@ MainWindow::~MainWindow(){
delete program;
}
void MainWindow::eventMouseWheel(int x, int y, int zDelta) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
program->eventMouseWheel(x, y, zDelta);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MainWindow::eventMouseDown(int x, int y, MouseButton mouseButton){
switch(mouseButton){
case mbLeft:
program->mouseDownLeft(x, getH() - y);
break;
case mbRight:
program->mouseDownRight(x, getH() - y);
break;
default:
break;
case mbLeft:
program->mouseDownLeft(x, getH() - y);
break;
case mbRight:
program->mouseDownRight(x, getH() - y);
break;
default:
break;
}
}

View File

@ -0,0 +1,56 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_MAIN_H_
#define _GLEST_GAME_MAIN_H_
#include <ctime>
#include "program.h"
#include "window_gl.h"
using Shared::Platform::MouseButton;
using Shared::Platform::MouseState;
namespace Glest{ namespace Game{
// =====================================================
// class MainWindow
//
/// Main program window
// =====================================================
class MainWindow: public WindowGl{
private:
Program* program;
public:
MainWindow(Program *program);
~MainWindow();
void setProgram(Program *program) {this->program= program;}
virtual void eventMouseDown(int x, int y, MouseButton mouseButton);
virtual void eventMouseUp(int x, int y, MouseButton mouseButton);
virtual void eventMouseDoubleClick(int x, int y, MouseButton mouseButton);
virtual void eventMouseMove(int x, int y, const MouseState *mouseState);
virtual void eventKeyDown(char key);
virtual void eventMouseWheel(int x, int y, int zDelta);
virtual void eventKeyUp(char key);
virtual void eventKeyPress(char c);
virtual void eventActivate(bool active);
virtual void eventResize(SizeState sizeState);
virtual void eventClose();
};
}}//end namespace
#endif

View File

@ -49,11 +49,11 @@ Program *Program::singleton = NULL;
Program::ShowMessageProgramState::ShowMessageProgramState(Program *program, const char *msg) :
ProgramState(program) {
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
userWantsExit = false;
msgBox.init("Ok");
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(msg) {
fprintf(stderr, "%s\n", msg);
@ -61,12 +61,12 @@ Program::ShowMessageProgramState::ShowMessageProgramState(Program *program, cons
} else {
msgBox.setText("Mega-Glest has crashed.");
}
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
mouse2dAnim = mouseY = mouseX = 0;
this->msg = (msg ? msg : "");
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void Program::ShowMessageProgramState::render() {
@ -79,16 +79,16 @@ void Program::ShowMessageProgramState::render() {
}
void Program::ShowMessageProgramState::mouseDownLeft(int x, int y) {
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(msgBox.mouseClick(x,y)) {
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
program->exit();
userWantsExit = true;
}
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void Program::ShowMessageProgramState::mouseMove(int x, int y, const MouseState &mouseState) {
@ -162,6 +162,17 @@ void Program::mouseDoubleClickLeft(int x, int y){
programState->mouseDoubleClickLeft(metrics.toVirtualX(x), metrics.toVirtualY(y));
}
void Program::eventMouseWheel(int x, int y, int zDelta) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
const Metrics &metrics= Metrics::getInstance();
int vx = metrics.toVirtualX(x);
int vy = metrics.toVirtualY(window->getH() - y);
programState->eventMouseWheel(vx, vy, zDelta);
}
void Program::mouseMove(int x, int y, const MouseState *ms){
const Metrics &metrics= Metrics::getInstance();
programState->mouseMove(metrics.toVirtualX(x), metrics.toVirtualY(y), ms);
@ -223,35 +234,35 @@ void Program::resize(SizeState sizeState){
void Program::setState(ProgramState *programState)
{
//if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
delete this->programState;
//if(Socket::enableDebugText) printf("In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
this->programState= programState;
programState->load();
//if(Socket::enableDebugText) printf("In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
programState->init();
//if(Socket::enableDebugText) printf("In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
updateTimer.reset();
updateCameraTimer.reset();
fpsTimer.reset();
//if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
}
void Program::exit() {
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
window->destroy();
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
// ==================== PRIVATE ====================
@ -349,7 +360,7 @@ void Program::restoreDisplaySettings(){
}
void Program::showMessage(const char *msg) {
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
ProgramState *originalState = NULL;
if(this->programState) {
@ -357,7 +368,7 @@ void Program::showMessage(const char *msg) {
originalState = this->programState;
}
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
showCursor(true);
@ -368,18 +379,18 @@ void Program::showMessage(const char *msg) {
this->programState = NULL;
setState(showMsg);
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
while(Window::handleEvent() && showMsg->wantExit() == false) {
loop();
}
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete this->programState;
this->programState = NULL;
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
showCursor(Config::getInstance().getBool("Windowed"));
@ -387,20 +398,20 @@ void Program::showMessage(const char *msg) {
init(this->window,false);
//setState(originalState);
//if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
delete this->programState;
//if(Socket::enableDebugText) printf("In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
this->programState= originalState;
//programState->load();
//if(Socket::enableDebugText) printf("In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
//programState->init();
//if(Socket::enableDebugText) printf("In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
//updateTimer.reset();
//updateCameraTimer.reset();
@ -409,7 +420,7 @@ void Program::showMessage(const char *msg) {
//this->programState = originalState;
//if(Socket::enableDebugText) printf("In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
}

View File

@ -55,7 +55,8 @@ public:
virtual void mouseDownLeft(int x, int y){};
virtual void mouseUpLeft(int x, int y){};
virtual void mouseDownRight(int x, int y){};
virtual void mouseDoubleClickLeft(int x, int y){};
virtual void mouseDoubleClickLeft(int x, int y){};
virtual void eventMouseWheel(int x, int y, int zDelta){}
virtual void mouseMove(int x, int y, const MouseState *mouseState) {};
virtual void keyDown(char key){};
virtual void keyUp(char key){};
@ -113,7 +114,9 @@ public:
void mouseDownLeft(int x, int y);
void mouseUpLeft(int x, int y);
void mouseDownRight(int x, int y);
void mouseDoubleClickLeft(int x, int y);
void mouseDoubleClickLeft(int x, int y);
void eventMouseWheel(int x, int y, int zDelta);
void mouseMove(int x, int y, const MouseState *mouseState);
void keyDown(char key);
void keyUp(char key);

View File

@ -0,0 +1,148 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_PLATFORM_WINDOW_H_
#define _SHARED_PLATFORM_WINDOW_H_
#include <map>
#include <string>
#include <SDL.h>
#include "types.h"
using std::map;
using std::string;
namespace Shared{ namespace Platform{
class Timer;
class PlatformContextGl;
enum MouseButton{
mbLeft,
mbRight,
mbCenter,
mbWheelUp,
mbWheelDown
};
enum SizeState{
ssMaximized,
ssMinimized,
ssRestored
};
// keycode constants (unfortunately designed after DirectInput and therefore not
// very specific)
// They also have to fit into a char. The positive numbers seem to be equal
// to ascii, for the rest we have to find sensefull mappings from SDL (which is
// alot more fine grained like left/right control instead of just control...)
const char vkAdd = -1;
const char vkSubtract = -2;
const char vkAlt = -3;
const char vkControl = -4;
const char vkShift = -5;
const char vkEscape = -6;
const char vkUp = -7;
const char vkLeft = -8;
const char vkRight = -9;
const char vkDown = -10;
const char vkReturn = -11;
const char vkBack = -12;
struct MouseState{
bool leftMouse;
bool rightMouse;
bool centerMouse;
};
enum WindowStyle{
wsFullscreen,
wsWindowedFixed,
wsWindowedResizable
};
// =====================================================
// class Window
// =====================================================
class Window {
private:
Uint32 lastMouseDown[3];
int lastMouseX[3];
int lastMouseY[3];
protected:
int w, h;
public:
static bool handleEvent();
Window();
virtual ~Window();
WindowHandle getHandle() {return 0;}
string getText();
int getX() { return 0; }
int getY() { return 0; }
int getW() { return w; }
int getH() { return h; }
//component state
int getClientW() { return getW(); }
int getClientH() { return getH(); }
float getAspect();
//object state
void setText(string text);
void setStyle(WindowStyle windowStyle);
void setSize(int w, int h);
void setPos(int x, int y);
void setEnabled(bool enabled);
void setVisible(bool visible);
//misc
void create();
void destroy();
void minimize();
protected:
virtual void eventCreate(){}
virtual void eventMouseDown(int x, int y, MouseButton mouseButton){}
virtual void eventMouseUp(int x, int y, MouseButton mouseButton){}
virtual void eventMouseMove(int x, int y, const MouseState* mouseState){}
virtual void eventMouseDoubleClick(int x, int y, MouseButton mouseButton){}
virtual void eventMouseWheel(int x, int y, int zDelta) {}
virtual void eventKeyDown(char key){}
virtual void eventKeyUp(char key){}
virtual void eventKeyPress(char c){}
virtual void eventResize(){};
virtual void eventPaint(){}
virtual void eventTimer(int timerId){}
virtual void eventActivate(bool activated){};
virtual void eventResize(SizeState sizeState){};
virtual void eventMenu(int menuId){}
virtual void eventClose(){};
virtual void eventDestroy(){};
private:
/// needed to detect double clicks
void handleMouseDown(SDL_Event event);
static MouseButton getMouseButton(int sdlButton);
static char getKey(SDL_keysym keysym);
static void toggleFullscreen();
};
}}//end namespace
#endif

View File

@ -0,0 +1,159 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_PLATFORM_WINDOW_H_
#define _SHARED_PLATFORM_WINDOW_H_
#include <map>
#include <string>
#include "types.h"
#include "platform_menu.h"
using std::map;
using std::string;
namespace Shared{ namespace Platform{
class Timer;
class PlatformContextGl;
enum MouseButton{
mbLeft,
mbRight,
mbCenter
};
enum SizeState{
ssMaximized,
ssMinimized,
ssRestored
};
const int vkAdd= VK_ADD;
const int vkSubtract= VK_SUBTRACT;
const int vkAlt= VK_MENU;
const int vkControl= VK_CONTROL;
const int vkShift= VK_SHIFT;
const int vkEscape= VK_ESCAPE;
const int vkUp= VK_UP;
const int vkLeft= VK_LEFT;
const int vkRight= VK_RIGHT;
const int vkDown= VK_DOWN;
const int vkReturn= VK_RETURN;
const int vkBack= VK_BACK;
const int vkDelete= VK_DELETE;
const int vkF1= VK_F1;
struct MouseState{
bool leftMouse;
bool rightMouse;
bool centerMouse;
};
enum WindowStyle{
wsFullscreen,
wsWindowedFixed,
wsWindowedResizeable
};
// =====================================================
// class Window
// =====================================================
class Window{
private:
typedef map<WindowHandle, Window*> WindowMap;
private:
static const DWORD fullscreenStyle;
static const DWORD windowedFixedStyle;
static const DWORD windowedResizeableStyle;
static int nextClassName;
static WindowMap createdWindows;
protected:
WindowHandle handle;
WindowStyle windowStyle;
string text;
int x;
int y;
int w;
int h;
string className;
DWORD style;
DWORD exStyle;
bool ownDc;
public:
static bool handleEvent();
//contructor & destructor
Window();
virtual ~Window();
WindowHandle getHandle() {return handle;}
string getText();
int getX() {return x;}
int getY() {return y;}
int getW() {return w;}
int getH() {return h;}
//component state
int getClientW();
int getClientH();
float getAspect();
//object state
void setText(string text);
void setStyle(WindowStyle windowStyle);
void setSize(int w, int h);
void setPos(int x, int y);
void setEnabled(bool enabled);
void setVisible(bool visible);
//misc
void create();
void minimize();
void maximize();
void restore();
void showPopupMenu(Menu *menu, int x, int y);
void destroy();
protected:
virtual void eventCreate(){}
virtual void eventMouseDown(int x, int y, MouseButton mouseButton){}
virtual void eventMouseUp(int x, int y, MouseButton mouseButton){}
virtual void eventMouseMove(int x, int y, const MouseState *mouseState){}
virtual void eventMouseDoubleClick(int x, int y, MouseButton mouseButton){}
virtual void eventKeyDown(char key){}
virtual void eventMouseWheel(int x, int y, int zDelta){}
virtual void eventKeyUp(char key){}
virtual void eventKeyPress(char c){};
virtual void eventResize(){};
virtual void eventPaint(){}
virtual void eventActivate(bool activated){};
virtual void eventResize(SizeState sizeState){};
virtual void eventMenu(int menuId){}
virtual void eventClose(){};
virtual void eventDestroy(){};
private:
static LRESULT CALLBACK eventRouter(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static int getNextClassName();
void registerWindow(WNDPROC wndProc= NULL);
void createWindow(LPVOID creationData= NULL);
};
}}//end namespace
#endif

View File

@ -0,0 +1,325 @@
//This file is part of Glest Shared Library (www.glest.org)
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//You can redistribute this code and/or modify it under
//the terms of the GNU General Public License as published by the Free Software
//Foundation; either version 2 of the License, or (at your option) any later
//version.
#include "window.h"
#include <iostream>
#include <stdexcept>
#include <cassert>
#include <cctype>
#include "conversion.h"
#include "platform_util.h"
#include "leak_dumper.h"
#include "sdl_private.h"
#include "noimpl.h"
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
// =======================================
// WINDOW
// =======================================
// ========== STATIC INICIALIZATIONS ==========
// Matze: hack for now...
static Window* global_window = 0;
// ========== PUBLIC ==========
Window::Window() {
memset(lastMouseDown, 0, sizeof(lastMouseDown));
assert(global_window == 0);
global_window = this;
}
Window::~Window() {
assert(global_window == this);
global_window = 0;
}
bool Window::handleEvent() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
try {
//printf("[%d]\n",event.type);
switch(event.type) {
case SDL_QUIT:
return false;
case SDL_MOUSEBUTTONDOWN:
global_window->handleMouseDown(event);
break;
case SDL_MOUSEBUTTONUP: {
global_window->eventMouseUp(event.button.x,
event.button.y,getMouseButton(event.button.button));
break;
}
case SDL_MOUSEMOTION: {
MouseState ms;
ms.leftMouse = (event.motion.state & SDL_BUTTON_LMASK) != 0;
ms.rightMouse = (event.motion.state & SDL_BUTTON_RMASK) != 0;
ms.centerMouse = (event.motion.state & SDL_BUTTON_MMASK) != 0;
global_window->eventMouseMove(event.motion.x, event.motion.y, &ms);
break;
}
case SDL_KEYDOWN:
/* handle ALT+Return */
if(event.key.keysym.sym == SDLK_RETURN
&& (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) {
toggleFullscreen();
}
global_window->eventKeyDown(getKey(event.key.keysym));
global_window->eventKeyPress(static_cast<char>(event.key.keysym.unicode));
break;
case SDL_KEYUP:
global_window->eventKeyUp(getKey(event.key.keysym));
break;
}
} catch(std::exception& e) {
std::cerr << "Couldn't process event: " << e.what() << "\n";
}
}
return true;
}
string Window::getText() {
char* c = 0;
SDL_WM_GetCaption(&c, 0);
return string(c);
}
float Window::getAspect() {
return static_cast<float>(getClientH())/getClientW();
}
void Window::setText(string text) {
SDL_WM_SetCaption(text.c_str(), 0);
}
void Window::setSize(int w, int h) {
this->w = w;
this->h = h;
Private::ScreenWidth = w;
Private::ScreenHeight = h;
}
void Window::setPos(int x, int y) {
if(x != 0 || y != 0) {
NOIMPL;
return;
}
}
void Window::minimize() {
NOIMPL;
}
void Window::setEnabled(bool enabled) {
NOIMPL;
}
void Window::setVisible(bool visible) {
NOIMPL;
}
void Window::setStyle(WindowStyle windowStyle) {
if(windowStyle == wsFullscreen)
return;
// NOIMPL;
}
void Window::create() {
// nothing here
}
void Window::destroy() {
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
void Window::toggleFullscreen() {
SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
}
void Window::handleMouseDown(SDL_Event event) {
static const Uint32 DOUBLECLICKTIME = 500;
static const int DOUBLECLICKDELTA = 5;
MouseButton button = getMouseButton(event.button.button);
// windows implementation uses 120 for the resolution of a standard mouse
// wheel notch. However, newer mice have finer resolutions. I dunno if SDL
// handles those, but for now we're going to say that each mouse wheel
// movement is 120.
if(button == mbWheelUp) {
//printf("button == mbWheelUp\n");
eventMouseWheel(event.button.x, event.button.y, 120);
return;
} else if(button == mbWheelDown) {
//printf("button == mbWheelDown\n");
eventMouseWheel(event.button.x, event.button.y, -120);
return;
}
Uint32 ticks = SDL_GetTicks();
int n = (int) button;
if(ticks - lastMouseDown[n] < DOUBLECLICKTIME
&& abs(lastMouseX[n] - event.button.x) < DOUBLECLICKDELTA
&& abs(lastMouseY[n] - event.button.y) < DOUBLECLICKDELTA) {
eventMouseDown(event.button.x, event.button.y, button);
eventMouseDoubleClick(event.button.x, event.button.y, button);
} else {
eventMouseDown(event.button.x, event.button.y, button);
}
lastMouseDown[n] = ticks;
lastMouseX[n] = event.button.x;
lastMouseY[n] = event.button.y;
}
MouseButton Window::getMouseButton(int sdlButton) {
switch(sdlButton) {
case SDL_BUTTON_LEFT:
return mbLeft;
case SDL_BUTTON_RIGHT:
return mbRight;
case SDL_BUTTON_MIDDLE:
return mbCenter;
case SDL_BUTTON_WHEELUP:
return mbWheelUp;
case SDL_BUTTON_WHEELDOWN:
return mbWheelDown;
default:
throw std::runtime_error("Mouse Button > 3 not handled.");
}
}
char Window::getKey(SDL_keysym keysym) {
switch(keysym.sym) {
case SDLK_PLUS:
case SDLK_KP_PLUS:
return vkAdd;
case SDLK_MINUS:
case SDLK_KP_MINUS:
return vkSubtract;
case SDLK_LALT:
case SDLK_RALT:
return vkAlt;
case SDLK_LCTRL:
case SDLK_RCTRL:
return vkControl;
case SDLK_LSHIFT:
case SDLK_RSHIFT:
return vkShift;
case SDLK_ESCAPE:
return vkEscape;
case SDLK_UP:
return vkUp;
case SDLK_LEFT:
return vkLeft;
case SDLK_RIGHT:
return vkRight;
case SDLK_DOWN:
return vkDown;
case SDLK_RETURN:
case SDLK_KP_ENTER:
return vkReturn;
case SDLK_BACKSPACE:
return vkBack;
case SDLK_0:
return '0';
case SDLK_1:
return '1';
case SDLK_2:
return '2';
case SDLK_3:
return '3';
case SDLK_4:
return '4';
case SDLK_5:
return '5';
case SDLK_6:
return '6';
case SDLK_7:
return '7';
case SDLK_8:
return '8';
case SDLK_9:
return '9';
case SDLK_a:
return 'A';
case SDLK_b:
return 'B';
case SDLK_c:
return 'C';
case SDLK_d:
return 'D';
case SDLK_e:
return 'E';
case SDLK_f:
return 'F';
case SDLK_g:
return 'G';
case SDLK_h:
return 'H';
case SDLK_i:
return 'I';
case SDLK_j:
return 'J';
case SDLK_k:
return 'K';
case SDLK_l:
return 'L';
case SDLK_m:
return 'M';
case SDLK_n:
return 'N';
case SDLK_o:
return 'O';
case SDLK_p:
return 'P';
case SDLK_q:
return 'Q';
case SDLK_r:
return 'R';
case SDLK_s:
return 'S';
case SDLK_t:
return 'T';
case SDLK_u:
return 'U';
case SDLK_v:
return 'V';
case SDLK_w:
return 'W';
case SDLK_x:
return 'X';
case SDLK_y:
return 'Y';
case SDLK_z:
return 'Z';
default:
Uint16 c = keysym.unicode;
if((c & 0xFF80) == 0) {
return toupper(c);
}
break;
}
return 0;
}
}}//end namespace