Added camera zoom (from GAE) into mega-glest (middle mouse button zooms in and out like in GAE)
This commit is contained in:
parent
397fe3dc41
commit
5b713bd785
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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__);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue