Converted win32 project to use SDL so that more code is shared and cross platform friendly. This fixes the issue with using the mouse to scroll the camera.

This commit is contained in:
Mark Vejvoda
2010-03-30 00:25:35 +00:00
parent dab5cb840f
commit a74fa24001
12 changed files with 455 additions and 953 deletions

View File

@@ -428,10 +428,15 @@ void Game::mouseMove(int x, int y, const MouseState *ms){
float ymult = 0.2f;
float xmult = 0.2f;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
gameCamera.transitionVH(-(y - lastMousePos.y) * ymult, (lastMousePos.x - x) * xmult);
mouseX=lastMousePos.x;
mouseY=lastMousePos.y;
Window::revertMousePos();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
return;
}
}

View File

@@ -253,12 +253,19 @@ int glestMain(int argc, char** argv){
NetworkInterface::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//showCursor(config.getBool("Windowed"));
showCursor(false);
program= new Program();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
mainWindow= new MainWindow(program);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//parse command line
if(argc==2 && string(argv[1])=="-server"){
program->initServer(mainWindow);

View File

@@ -122,8 +122,15 @@ Program::Program() {
}
void Program::initNormal(WindowGl *window){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
init(window);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
setState(new Intro(this));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void Program::initServer(WindowGl *window){
@@ -254,12 +261,18 @@ void Program::exit() {
void Program::init(WindowGl *window, bool initSound){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
this->window= window;
Config &config= Config::getInstance();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//set video mode
setDisplaySettings();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//window
window->setText("Glest");
window->setStyle(config.getBool("Windowed")? wsWindowedFixed: wsFullscreen);
@@ -267,11 +280,15 @@ void Program::init(WindowGl *window, bool initSound){
window->setSize(config.getInt("ScreenWidth"), config.getInt("ScreenHeight"));
window->create();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//timers
fpsTimer.init(1, maxTimes);
updateTimer.init(GameConstants::updateFps, maxTimes);
updateCameraTimer.init(GameConstants::cameraFps, maxTimes);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//log start
Logger &logger= Logger::getInstance();
string logFile = "glest.log";
@@ -281,23 +298,38 @@ void Program::init(WindowGl *window, bool initSound){
logger.setFile(logFile);
logger.clear();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//lang
Lang &lang= Lang::getInstance();
lang.loadStrings(config.getString("Lang"));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//render
Renderer &renderer= Renderer::getInstance();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
window->initGl(config.getInt("ColorBits"), config.getInt("DepthBits"), config.getInt("StencilBits"));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
window->makeCurrentGl();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//coreData, needs renderer, but must load before renderer init
CoreData &coreData= CoreData::getInstance();
coreData.load();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//init renderer (load global textures)
renderer.init();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//sound
if(initSound == true) {
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
@@ -306,6 +338,8 @@ void Program::init(WindowGl *window, bool initSound){
NetworkInterface::setAllowGameDataSynchCheck(Config::getInstance().getBool("AllowGameDataSynchCheck","0"));
NetworkInterface::setAllowDownloadDataSynch(Config::getInstance().getBool("AllowDownloadDataSynch","0"));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void Program::setDisplaySettings(){

View File

@@ -0,0 +1,85 @@
// ==============================================================
// 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_FACTORYREPOSITORY_H_
#define _SHARED_PLATFORM_FACTORYREPOSITORY_H_
#include <string>
#include "graphics_factory.h"
#include "sound_factory.h"
#include "graphics_factory_gl.h"
#ifdef WIN32
#include "graphics_factory_gl2.h"
#include "sound_factory_ds8.h"
#else
#include "sound_factory_openal.h"
#endif
using std::string;
using Shared::Graphics::GraphicsFactory;
using Shared::Sound::SoundFactory;
using Shared::Graphics::Gl::GraphicsFactoryGl;
#ifdef WIN32
using Shared::Graphics::Gl::GraphicsFactoryGl2;
using Shared::Sound::Ds8::SoundFactoryDs8;
#else
using Shared::Sound::OpenAL::SoundFactoryOpenAL;
#endif
namespace Shared{ namespace Platform{
// =====================================================
// class FactoryRepository
// =====================================================
class FactoryRepository{
private:
FactoryRepository(){};
FactoryRepository(const FactoryRepository& );
void operator=(const FactoryRepository& );
private:
GraphicsFactoryGl graphicsFactoryGl;
#ifdef WIN32
GraphicsFactoryGl2 graphicsFactoryGl2;
SoundFactoryDs8 soundFactoryDs8;
#else
SoundFactoryOpenAL soundFactoryOpenAL;
#endif
public:
static FactoryRepository &getInstance();
GraphicsFactory *getGraphicsFactory(const string &name);
SoundFactory *getSoundFactory(const string &name);
};
}}//end namespace
#endif

View File

@@ -11,10 +11,24 @@
#ifndef _SHARED_PLATFORM_GLWRAP_H_
#define _SHARED_PLATFORM_GLWRAP_H_
#ifdef WIN32
#include <windows.h>
#include <GL\gl.h>
#include <GL\glu.h>
#include <glprocs.h>
#define GLEST_GLPROC(X, Y) inline X( static a= wglGetProcAddress(a); return a;)
#else
#include <SDL.h>
#define GL_GLEXT_PROTOTYPES
#include <SDL_opengl.h>
#endif
#include <string>
#include "font.h"

View File

@@ -0,0 +1,15 @@
#ifndef _NOIMPL_H_
#define _NOIMPL_H_
#ifndef WIN32
#define NOIMPL std::cerr << __PRETTY_FUNCTION__ << " not implemented.\n";
#else
#define NOIMPL std::cerr << __FUNCTION__ << " not implemented.\n";
#endif
#endif

View File

@@ -0,0 +1,29 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2005 Matthias Braun
//
// 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_MAIN_H_
#define _SHARED_PLATFORM_MAIN_H_
#include <SDL.h>
#include <iostream>
#define MAIN_FUNCTION(X) int main(int argc, char **argv) \
{ std::cout << "About to init SDL..." << "\n"; \
if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { \
std::cerr << "Couldn't initialize SDL: " << SDL_GetError() << "\n"; \
return 1; \
} \
SDL_EnableUNICODE(1); \
int result = X(argc, argv); \
SDL_Quit(); \
return result; \
}
#endif

View File

@@ -1,219 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>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 <cassert>
#include "types.h"
#include "vec.h"
#include "platform_menu.h"
using std::map;
using std::string;
using Shared::Graphics::Vec2i;
namespace Shared{ namespace Platform{
class Timer;
class PlatformContextGl;
enum MouseButton{
mbUnknown,
mbLeft,
mbCenter,
mbRight,
mbWheelUp,
mbWheelDown,
mbButtonX1,
mbButtonX2,
mbCount
};
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;
class MouseState {
private:
bool states[mbCount];
public:
MouseState() {
clear();
}
//MouseState(const MouseState &);
//MouseState &operator=(const MouseState &);
void clear() { memset(this, 0, sizeof(MouseState)); }
bool get(MouseButton b) const {
assert(b > 0 && b < mbCount);
return states[b];
}
void set(MouseButton b, bool state) {
assert(b > 0 && b < mbCount);
states[b] = state;
}
};
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;
static unsigned int lastMouseEvent; /** for use in mouse hover calculations */
static MouseState mouseState;
static Vec2i mousePos;
static bool isKeyPressedDown;
static void setLastMouseEvent(unsigned int lastMouseEvent) {Window::lastMouseEvent = lastMouseEvent;}
static unsigned int getLastMouseEvent() {return Window::lastMouseEvent;}
static const MouseState &getMouseState() {return Window::mouseState;}
static void setMouseState(MouseButton b, bool state) {Window::mouseState.set(b, state);}
static const Vec2i &getMousePos() {return Window::mousePos;}
static void setMousePos(const Vec2i &mousePos) {Window::mousePos = mousePos;}
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();
static void revertMousePos();
static bool isKeyDown() { return isKeyPressedDown; }
//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);
void mouseyVent(int asdf, MouseButton mouseButton) {
const Vec2i &mousePos = getMousePos();
switch(asdf) {
case 0:
setMouseState(mouseButton, true);
eventMouseDown(mousePos.x, mousePos.y, mouseButton);
break;
case 1:
setMouseState(mouseButton, false);
eventMouseUp(mousePos.x, mousePos.y, mouseButton);
break;
case 2:
eventMouseDoubleClick(mousePos.x, mousePos.y, mouseButton);
break;
}
}
};
}}//end namespace
#endif

View File

@@ -0,0 +1,55 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>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 "context_gl.h"
#include <cassert>
#include <stdexcept>
#include "opengl.h"
#include "util.h"
#include "leak_dumper.h"
using namespace std;
using namespace Shared::Util;
namespace Shared{ namespace Graphics{ namespace Gl{
// =====================================================
// class ContextGl
// =====================================================
void ContextGl::init(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
pcgl.init(colorBits, depthBits, stencilBits);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void ContextGl::end(){
pcgl.end();
}
void ContextGl::makeCurrent(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
pcgl.makeCurrent();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void ContextGl::swapBuffers(){
pcgl.swapBuffers();
}
}}}//end namespace

View File

@@ -35,12 +35,17 @@ namespace Shared{ namespace Platform{
void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
int flags = SDL_OPENGL;
if(Private::shouldBeFullscreen)
flags |= SDL_FULLSCREEN;
@@ -106,7 +111,49 @@ void createGlFontBitmaps(uint32 &base, const string &type, int size, int width,
XFreeFont(display, fontInfo);
#else
// we badly need a solution portable to more than just glx
NOIMPL;
//NOIMPL;
HFONT font= CreateFont(
size, 0, 0, 0, width, 0, FALSE, FALSE, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
DEFAULT_PITCH, type.c_str());
assert(font!=NULL);
HDC dc= wglGetCurrentDC();
SelectObject(dc, font);
BOOL err= wglUseFontBitmaps(dc, 0, charCount, base);
FIXED one;
one.value= 1;
one.fract= 0;
FIXED zero;
zero.value= 0;
zero.fract= 0;
MAT2 mat2;
mat2.eM11= one;
mat2.eM12= zero;
mat2.eM21= zero;
mat2.eM22= one;
//metrics
GLYPHMETRICS glyphMetrics;
int errorCode= GetGlyphOutline(dc, 'a', GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
if(errorCode!=GDI_ERROR){
metrics.setHeight(static_cast<float>(glyphMetrics.gmBlackBoxY));
}
for(int i=0; i<charCount; ++i){
int errorCode= GetGlyphOutline(dc, i, GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
if(errorCode!=GDI_ERROR){
metrics.setWidth(i, static_cast<float>(glyphMetrics.gmCellIncX));
}
}
DeleteObject(font);
assert(err);
#endif
}

View File

@@ -24,6 +24,11 @@
#include <direct.h>
#include <algorithm>
#include <SDL.h>
#include "sdl_private.h"
#include "window.h"
#include "noimpl.h"
#include "leak_dumper.h"
#define S_ISDIR(mode) ((mode) & _S_IFDIR)
@@ -33,6 +38,14 @@ using namespace std;
namespace Shared{ namespace Platform{
namespace Private{
bool shouldBeFullscreen = false;
int ScreenWidth;
int ScreenHeight;
}
// =====================================================
// class PerformanceTimer
// =====================================================
@@ -492,76 +505,144 @@ void createDirectoryPaths(string Path)
_mkdir(DirName);
}
//void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight) {
// // Get the current video hardware information
// //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
// //colorBits = vidInfo->vfmt->BitsPerPixel;
// //screenWidth = vidInfo->current_w;
//
///*
// //screenHeight = vidInfo->current_h;
// int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
// // height
// int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
//
// printf("cx = %d, cy = %d\n",cx,cy);
//
// if(cx > screenWidth) {
// screenWidth = cx;
// screenHeight = cy;
// }
//*/
// int iMaxWidth = -1;
// int iMaxHeight = -1;
// int iMaxBits = -1;
//
// DEVMODE devMode;
// for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
//
// //printf("devMode.dmPelsWidth = %d, devMode.dmPelsHeight = %d, devMode.dmBitsPerPel = %d\n",devMode.dmPelsWidth,devMode.dmPelsHeight,devMode.dmBitsPerPel);
//
// if(devMode.dmPelsWidth > iMaxWidth) {
// iMaxWidth = devMode.dmPelsWidth;
// iMaxHeight = devMode.dmPelsHeight;
// iMaxBits = devMode.dmBitsPerPel;
// //devMode.dmDisplayFrequency=refreshFrequency;
// }
// }
// if(iMaxWidth > 0) {
// colorBits = iMaxBits;
// screenWidth = iMaxWidth;
// screenHeight = iMaxHeight;
// }
//}
//
//bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){
// DEVMODE devMode;
//
// for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
// if (devMode.dmPelsWidth== resW &&
// devMode.dmPelsHeight== resH &&
// devMode.dmBitsPerPel== colorBits){
//
// devMode.dmDisplayFrequency=refreshFrequency;
//
// LONG result= ChangeDisplaySettings(&devMode, 0);
// if(result == DISP_CHANGE_SUCCESSFUL){
// return true;
// }
// else{
// return false;
// }
// }
// }
//
// return false;
//}
//
//void restoreVideoMode(bool exitingApp) {
// int dispChangeErr= ChangeDisplaySettings(NULL, 0);
// assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
//}
void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight) {
// Get the current video hardware information
//const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
//colorBits = vidInfo->vfmt->BitsPerPixel;
//screenWidth = vidInfo->current_w;
/*
//screenHeight = vidInfo->current_h;
int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
// height
int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
printf("cx = %d, cy = %d\n",cx,cy);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(cx > screenWidth) {
screenWidth = cx;
screenHeight = cy;
/* Get available fullscreen/hardware modes */
SDL_Rect**modes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
/* Check if there are any modes available */
if (modes == (SDL_Rect**)0) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] no hardware modes available.\n",__FILE__,__FUNCTION__,__LINE__);
const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
colorBits = vidInfo->vfmt->BitsPerPixel;
screenWidth = vidInfo->current_w;
screenHeight = vidInfo->current_h;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
}
*/
int iMaxWidth = -1;
int iMaxHeight = -1;
int iMaxBits = -1;
/* Check if our resolution is restricted */
else if (modes == (SDL_Rect**)-1) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] all resolutions available.\n",__FILE__,__FUNCTION__,__LINE__);
DEVMODE devMode;
for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
colorBits = vidInfo->vfmt->BitsPerPixel;
screenWidth = vidInfo->current_w;
screenHeight = vidInfo->current_h;
//printf("devMode.dmPelsWidth = %d, devMode.dmPelsHeight = %d, devMode.dmBitsPerPel = %d\n",devMode.dmPelsWidth,devMode.dmPelsHeight,devMode.dmBitsPerPel);
if(devMode.dmPelsWidth > iMaxWidth) {
iMaxWidth = devMode.dmPelsWidth;
iMaxHeight = devMode.dmPelsHeight;
iMaxBits = devMode.dmBitsPerPel;
//devMode.dmDisplayFrequency=refreshFrequency;
}
}
if(iMaxWidth > 0) {
colorBits = iMaxBits;
screenWidth = iMaxWidth;
screenHeight = iMaxHeight;
}
}
bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){
DEVMODE devMode;
for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
if (devMode.dmPelsWidth== resW &&
devMode.dmPelsHeight== resH &&
devMode.dmBitsPerPel== colorBits){
devMode.dmDisplayFrequency=refreshFrequency;
LONG result= ChangeDisplaySettings(&devMode, 0);
if(result == DISP_CHANGE_SUCCESSFUL){
return true;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
}
else{
return false;
}
/* Print valid modes */
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] available Modes are:\n",__FILE__,__FUNCTION__,__LINE__);
int bestW = -1;
int bestH = -1;
for(int i=0; modes[i]; ++i) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",modes[i]->w, modes[i]->h);
if(bestW < modes[i]->w) {
bestW = modes[i]->w;
bestH = modes[i]->h;
}
}
return false;
if(bestW > screenWidth) {
screenWidth = bestW;
screenHeight = bestH;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
}
}
bool changeVideoMode(int resW, int resH, int colorBits, int ) {
Private::shouldBeFullscreen = true;
return true;
}
void restoreVideoMode(bool exitingApp) {
int dispChangeErr= ChangeDisplaySettings(NULL, 0);
assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
SDL_Quit();
}
void message(string message){
MessageBox(NULL, message.c_str(), "Message", MB_OK);
}
@@ -583,14 +664,23 @@ void exceptionMessage(const exception &excp){
MessageBox(NULL, message.c_str(), title.c_str(), MB_ICONSTOP | MB_OK | MB_TASKMODAL);
}
//int getScreenW(){
// return GetSystemMetrics(SM_CXSCREEN);
//}
//int getScreenH(){
// return GetSystemMetrics(SM_CYSCREEN);
//}
int getScreenW() {
return GetSystemMetrics(SM_CXSCREEN);
return SDL_GetVideoSurface()->w;
}
int getScreenH() {
return GetSystemMetrics(SM_CYSCREEN);
return SDL_GetVideoSurface()->h;
}
void sleep(int millis){
Sleep(millis);
}

View File

@@ -1,660 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martio 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 "window.h"
#include <cassert>
#include "control.h"
#include "conversion.h"
#include "platform_util.h"
#include "leak_dumper.h"
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
// =====================================================
// class Window
// =====================================================
const DWORD Window::fullscreenStyle= WS_POPUP | WS_OVERLAPPED;
const DWORD Window::windowedFixedStyle= WS_CAPTION | WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_SYSMENU;
const DWORD Window::windowedResizeableStyle= WS_SIZEBOX | WS_CAPTION | WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_SYSMENU;
int Window::nextClassName= 0;
Window::WindowMap Window::createdWindows;
unsigned int Window::lastMouseEvent = 0; /** for use in mouse hover calculations */
static int oldX=0,oldY=0;
Vec2i Window::mousePos;
MouseState Window::mouseState;
bool Window::isKeyPressedDown = false;
// ===================== PUBLIC ========================
Window::Window(){
handle= 0;
style= windowedFixedStyle;
exStyle= 0;
ownDc= false;
x= 0;
y= 0;
w= 100;
h= 100;
lastMouseEvent = 0;
mousePos = Vec2i(0);
mouseState.clear();
}
Window::~Window(){
if(handle!=0){
DestroyWindow(handle);
handle= 0;
BOOL b= UnregisterClass(className.c_str(), GetModuleHandle(NULL));
assert(b);
}
}
//static
bool Window::handleEvent(){
MSG msg;
POINT point;
bool ret = GetCursorPos(&point);
if(ret == true) {
oldX = point.x;
oldY = point.y;
}
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if(msg.message==WM_QUIT){
return false;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
void Window::revertMousePos() {
//SetCursorPos(oldX, oldY);
}
string Window::getText(){
if(handle==0){
return text;
}
char c[255];
SendMessage(handle, WM_GETTEXT, 255, (LPARAM) c);
return string(c);
}
int Window::getClientW(){
RECT r;
GetClientRect(handle, &r);
return r.right;
}
int Window::getClientH(){
RECT r;
GetClientRect(handle, &r);
return r.bottom;
}
float Window::getAspect(){
return static_cast<float>(getClientH())/getClientW();
}
void Window::setText(string text){
this->text= text;
if(handle!=0){
SendMessage(handle, WM_SETTEXT, 0, (LPARAM) text.c_str());
}
}
void Window::setSize(int w, int h){
if(windowStyle != wsFullscreen){
RECT rect;
rect.left= 0;
rect.top= 0;
rect.bottom= h;
rect.right= w;
AdjustWindowRect(&rect, style, FALSE);
w= rect.right-rect.left;
h= rect.bottom-rect.top;
}
this->w= w;
this->h= h;
if(handle!=0){
MoveWindow(handle, x, y, w, h, FALSE);
UpdateWindow(handle);
}
}
void Window::setPos(int x, int y){
this->x= x;
this->y= y;
if(handle!=0){
MoveWindow(handle, x, y, w, h, FALSE);
}
}
void Window::setEnabled(bool enabled){
EnableWindow(handle, static_cast<BOOL>(enabled));
}
void Window::setVisible(bool visible){
if (visible){
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
}
else{
ShowWindow(handle, SW_HIDE);
UpdateWindow(handle);
}
}
void Window::setStyle(WindowStyle windowStyle){
this->windowStyle= windowStyle;
switch(windowStyle){
case wsFullscreen:
style= fullscreenStyle;
exStyle= WS_EX_APPWINDOW;
ownDc= true;
break;
case wsWindowedFixed:
style= windowedFixedStyle;
exStyle= 0;
ownDc= false;
break;
case wsWindowedResizeable:
style= windowedResizeableStyle;
exStyle= 0;
ownDc= false;
break;
}
if(handle!=0){
setVisible(false);
int err= SetWindowLong(handle, GWL_STYLE, style);
assert(err);
setVisible(true);
UpdateWindow(handle);
}
}
void Window::create(){
registerWindow();
createWindow();
}
void Window::minimize(){
ShowWindow(getHandle(), SW_MINIMIZE);
}
void Window::maximize(){
ShowWindow(getHandle(), SW_MAXIMIZE);
}
void Window::restore(){
ShowWindow(getHandle(), SW_RESTORE);
}
void Window::showPopupMenu(Menu *menu, int x, int y){
RECT rect;
GetWindowRect(handle, &rect);
TrackPopupMenu(menu->getHandle(), TPM_LEFTALIGN | TPM_TOPALIGN, rect.left+x, rect.top+y, 0, handle, NULL);
}
void Window::destroy(){
DestroyWindow(handle);
BOOL b= UnregisterClass(className.c_str(), GetModuleHandle(NULL));
assert(b);
handle= 0;
}
// ===================== PRIVATE =======================
LRESULT CALLBACK Window::eventRouter(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
Window *eventWindow;
WindowMap::iterator it;
it = createdWindows.find(hwnd);
if (it == createdWindows.end()) {
return DefWindowProc(hwnd, msg, wParam, lParam);
}
eventWindow = it->second;
switch (msg) {
case WM_CREATE:
eventWindow->eventCreate();
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MBUTTONDBLCLK:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP:
case WM_XBUTTONDBLCLK:
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
case WM_MOUSEMOVE: {
RECT windowRect;
POINT mousePos;
GetWindowRect(eventWindow->getHandle(), &windowRect);
mousePos.x = LOWORD(lParam) - windowRect.left;
mousePos.y = HIWORD(lParam) - windowRect.top;
ClientToScreen(eventWindow->getHandle(), &mousePos);
eventWindow->setLastMouseEvent(Chrono::getCurMillis());
eventWindow->setMousePos(Vec2i(mousePos.x, mousePos.y));
switch(msg) {
case WM_LBUTTONDOWN:
eventWindow->mouseyVent(0, mbLeft);
return 0;
case WM_LBUTTONUP:
eventWindow->mouseyVent(1, mbLeft);
return 0;
case WM_LBUTTONDBLCLK:
eventWindow->mouseyVent(2, mbLeft);
return 0;
case WM_RBUTTONDOWN:
eventWindow->mouseyVent(0, mbRight);
return 0;
case WM_RBUTTONUP:
eventWindow->mouseyVent(1, mbRight);
return 0;
case WM_RBUTTONDBLCLK:
eventWindow->mouseyVent(2, mbRight);
return 0;
case WM_MBUTTONDOWN:
eventWindow->mouseyVent(0, mbCenter);
return 0;
case WM_MBUTTONUP:
eventWindow->mouseyVent(1, mbCenter);
return 0;
case WM_MBUTTONDBLCLK:
eventWindow->mouseyVent(2, mbCenter);
return 0;
case WM_XBUTTONDOWN:
// we only know about XBUTTON1 and XBUTTON2, but there may be more later, let
// DefWindowProc take these.
switch(HIWORD(wParam)) {
case XBUTTON1:
eventWindow->mouseyVent(0, mbButtonX1);
return TRUE;// don't ask me why it wants TRUE instead of zero like
// everything else
case XBUTTON2:
eventWindow->mouseyVent(0, mbButtonX2);
return TRUE;
}
break;
case WM_XBUTTONUP:
switch(HIWORD(wParam)) {
case XBUTTON1:
eventWindow->mouseyVent(1, mbButtonX1);
return TRUE;// don't ask me why it wants TRUE instead of zero like
// everything else
case XBUTTON2:
eventWindow->mouseyVent(1, mbButtonX2);
return TRUE;
}
break;
case WM_XBUTTONDBLCLK:
switch(HIWORD(wParam)) {
case XBUTTON1:
eventWindow->mouseyVent(2, mbButtonX1);
return TRUE;// don't ask me why it wants TRUE instead of zero like
// everything else
case XBUTTON2:
eventWindow->mouseyVent(2, mbButtonX2);
return TRUE;
}
break;
case WM_MOUSEWHEEL:
eventWindow->eventMouseWheel(mousePos.x, mousePos.y, GET_WHEEL_DELTA_WPARAM(wParam));
return 0;
case WM_MOUSEHWHEEL:
//eventWindow->eventMouseHWheel(mousePos.x, mousePos.y, GET_WHEEL_DELTA_WPARAM(wParam));
break; // not handled, send to DefWindowProc
case WM_MOUSEMOVE:
eventWindow->setMouseState(mbLeft, wParam & MK_LBUTTON);
eventWindow->setMouseState(mbRight, wParam & MK_RBUTTON);
eventWindow->setMouseState(mbCenter, wParam & MK_MBUTTON);
eventWindow->setMouseState(mbButtonX1, wParam & MK_XBUTTON1);
eventWindow->setMouseState(mbButtonX2, wParam & MK_XBUTTON2);
const MouseState &ms = eventWindow->getMouseState();
eventWindow->eventMouseMove(mousePos.x, mousePos.y, &ms);
//return 0;
break;
}
break;
}
case WM_KEYDOWN: {
Window::isKeyPressedDown = true;
eventWindow->eventKeyDown(static_cast<char>(wParam));
break;
/*
Key key(Input::getKeyCode(wParam), static_cast<char>(wParam));
// bottom 16 bits is repeat acount, and I only care if it's zero or non-zero
bool isRepeat = (lParam << 16);
// I don't want repeats of modifier keys posting
if(!isRepeat || !key.isModifier()) {
eventWindow->input.updateKeyModifiers(key.getCode(), true);
eventWindow->eventKeyDown(key);
}
break;
*/
}
case WM_KEYUP: {
Window::isKeyPressedDown = false;
eventWindow->eventKeyUp(static_cast<char>(wParam));
break;
/*
Key key(Input::getKeyCode(wParam), static_cast<char>(wParam));
eventWindow->input.updateKeyModifiers(key.getCode(), false);
eventWindow->eventKeyUp(key);
break;
*/
}
case WM_CHAR:
eventWindow->eventKeyPress(static_cast<char>(wParam));
break;
case WM_COMMAND:
if (HIWORD(wParam) == 0) {
eventWindow->eventMenu(LOWORD(wParam));
}
break;
case WM_ACTIVATE:
eventWindow->eventActivate(wParam != WA_INACTIVE);
break;
case WM_MOVE: {
RECT rect;
GetWindowRect(eventWindow->getHandle(), &rect);
eventWindow->x = rect.left;
eventWindow->y = rect.top;
eventWindow->w = rect.right - rect.left;
eventWindow->h = rect.bottom - rect.top;
}
break;
case WM_SIZE: {
RECT rect;
GetWindowRect(eventWindow->getHandle(), &rect);
eventWindow->x = rect.left;
eventWindow->y = rect.top;
eventWindow->w = rect.right - rect.left;
eventWindow->h = rect.bottom - rect.top;
eventWindow->eventResize(static_cast<SizeState>(wParam));
}
break;
case WM_SIZING:
eventWindow->eventResize();
break;
case WM_PAINT:
eventWindow->eventPaint();
break;
case WM_CLOSE:
eventWindow->eventClose();
break;
case WM_DESTROY:
eventWindow->eventDestroy();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
/*
Window *eventWindow;
WindowMap::iterator it;
it= createdWindows.find(hwnd);
if(it==createdWindows.end()){
return DefWindowProc(hwnd, msg, wParam, lParam);
}
eventWindow= it->second;
POINT mousePos;
RECT windowRect;
GetWindowRect(eventWindow->getHandle(), &windowRect);
mousePos.x = LOWORD(lParam) - windowRect.left;
mousePos.y = HIWORD(lParam) -windowRect.top;
ClientToScreen(eventWindow->getHandle(), &mousePos);
switch(msg){
case WM_CREATE:
eventWindow->eventCreate();
break;
case WM_LBUTTONDOWN:
eventWindow->eventMouseDown(mousePos.x, mousePos.y, mbLeft);
break;
case WM_RBUTTONDOWN:
eventWindow->eventMouseDown(mousePos.x, mousePos.y, mbRight);
break;
case WM_LBUTTONUP:
eventWindow->eventMouseUp(mousePos.x, mousePos.y, mbLeft);
break;
case WM_RBUTTONUP:
eventWindow->eventMouseUp(mousePos.x, mousePos.y, mbRight);
break;
case WM_LBUTTONDBLCLK:
eventWindow->eventMouseDoubleClick(mousePos.x, mousePos.y, mbLeft);
break;
case WM_RBUTTONDBLCLK:
eventWindow->eventMouseDoubleClick(mousePos.x, mousePos.y, mbRight);
break;
case WM_MOUSEWHEEL:
eventWindow->eventMouseWheel(mousePos.x, mousePos.y, GET_WHEEL_DELTA_WPARAM(wParam));
return 0;
case WM_MOUSEHWHEEL:
//eventWindow->eventMouseHWheel(mousePos.x, mousePos.y, GET_WHEEL_DELTA_WPARAM(wParam));
break; // not handled, send to DefWindowProc
case WM_MOUSEMOVE:
{
MouseState ms;
ms.leftMouse= (wParam & MK_LBUTTON) ? true : false;
ms.rightMouse= (wParam & MK_RBUTTON) ? true : false;
ms.centerMouse= (wParam & MK_MBUTTON) ? true : false;
eventWindow->eventMouseMove(mousePos.x, mousePos.y, &ms);
}
break;
case WM_KEYDOWN:
eventWindow->eventKeyDown(static_cast<char>(wParam));
break;
case WM_KEYUP:
eventWindow->eventKeyUp(static_cast<char>(wParam));
break;
case WM_CHAR:
eventWindow->eventKeyPress(static_cast<char>(wParam));
break;
case WM_COMMAND:
if(HIWORD(wParam)==0){
eventWindow->eventMenu(LOWORD(wParam));
}
break;
case WM_ACTIVATE:
eventWindow->eventActivate(wParam!=WA_INACTIVE);
break;
case WM_MOVE:
{
RECT rect;
GetWindowRect(eventWindow->getHandle(), &rect);
eventWindow->x= rect.left;
eventWindow->y= rect.top;
eventWindow->w= rect.right-rect.left;
eventWindow->h= rect.bottom-rect.top;
}
break;
case WM_SIZE:
{
RECT rect;
GetWindowRect(eventWindow->getHandle(), &rect);
eventWindow->x= rect.left;
eventWindow->y= rect.top;
eventWindow->w= rect.right-rect.left;
eventWindow->h= rect.bottom-rect.top;
eventWindow->eventResize(static_cast<SizeState>(wParam));
}
break;
case WM_SIZING:
eventWindow->eventResize();
break;
case WM_PAINT:
eventWindow->eventPaint();
break;
case WM_CLOSE:
eventWindow->eventClose();
break;
case WM_DESTROY:
eventWindow->eventDestroy();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
*/
}
int Window::getNextClassName(){
return ++nextClassName;
}
void Window::registerWindow(WNDPROC wndProc){
WNDCLASSEX wc;
this->className= "Window" + intToStr(Window::getNextClassName());
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS | (ownDc? CS_OWNDC : 0);
wc.lpfnWndProc = wndProc==NULL? eventRouter: wndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = this->className.c_str();
wc.hIconSm = NULL;
int registerClassErr=RegisterClassEx(&wc);
assert(registerClassErr);
}
void Window::createWindow(LPVOID creationData){
handle = CreateWindowEx(
exStyle,
className.c_str(),
text.c_str(),
style,
x, y, w, h,
NULL, NULL, GetModuleHandle(NULL), creationData);
createdWindows.insert(pair<WindowHandle, Window*>(handle, this));
eventRouter(handle, WM_CREATE, 0, 0);
assert(handle != NULL);
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
}
}}//end namespace