initial version ( megaglest 3.2.3-beta3 )

This commit is contained in:
Titus Tscharntke
2010-01-22 01:45:58 +00:00
commit 0ce9b5fcac
311 changed files with 49528 additions and 0 deletions

View File

@@ -0,0 +1,326 @@
//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 "socket.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
#include <sstream>
#if defined(HAVE_SYS_IOCTL_H)
#define BSD_COMP /* needed for FIONREAD on Solaris2 */
#include <sys/ioctl.h>
#endif
#if defined(HAVE_SYS_FILIO_H) /* needed for FIONREAD on Solaris 2.5 */
#include <sys/filio.h>
#endif
#include "conversion.h"
using namespace std;
using namespace Shared::Util;
namespace Shared{ namespace Platform{
// =====================================================
// class Ip
// =====================================================
Ip::Ip(){
bytes[0]= 0;
bytes[1]= 0;
bytes[2]= 0;
bytes[3]= 0;
}
Ip::Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3){
bytes[0]= byte0;
bytes[1]= byte1;
bytes[2]= byte2;
bytes[3]= byte3;
}
Ip::Ip(const string& ipString){
int offset= 0;
int byteIndex= 0;
for(byteIndex= 0; byteIndex<4; ++byteIndex){
int dotPos= ipString.find_first_of('.', offset);
bytes[byteIndex]= atoi(ipString.substr(offset, dotPos-offset).c_str());
offset= dotPos+1;
}
}
string Ip::getString() const{
return intToStr(bytes[0]) + "." + intToStr(bytes[1]) + "." + intToStr(bytes[2]) + "." + intToStr(bytes[3]);
}
// ===============================================
// class Socket
// ===============================================
Socket::Socket(int sock){
this->sock= sock;
}
Socket::Socket(){
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock<0) {
throwException("Error creating socket");
}
}
Socket::~Socket() {
::close(sock);
}
int Socket::getDataToRead(){
unsigned long size;
/* ioctl isn't posix, but the following seems to work on all modern
* unixes */
int err= ioctl(sock, FIONREAD, &size);
if(err < 0 && errno != EAGAIN){
throwException("Can not get data to read");
}
return static_cast<int>(size);
}
int Socket::send(const void *data, int dataSize) {
ssize_t bytesSent= ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
if(bytesSent<0 && errno != EAGAIN) {
throwException("error while receiving socket data");
}
return static_cast<int>(bytesSent);
}
int Socket::receive(void *data, int dataSize) {
ssize_t bytesReceived= recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
if(bytesReceived<0 && errno != EAGAIN) {
throwException("error while receiving socket data");
}
return static_cast<int>(bytesReceived);
}
int Socket::peek(void *data, int dataSize){
ssize_t err= recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
if(err<0 && errno != EAGAIN){
throwException("Can not receive data");
}
return static_cast<int>(err);
}
void Socket::setBlock(bool block){
int err= fcntl(sock, F_SETFL, block ? 0 : O_NONBLOCK);
if(err<0){
throwException("Error setting I/O mode for socket");
}
}
bool Socket::isReadable(){
struct timeval tv;
tv.tv_sec= 0;
tv.tv_usec= 10;
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
int i= select(sock+1, &set, NULL, NULL, &tv);
if(i<0){
throwException("Error selecting socket");
}
return i==1;
}
bool Socket::isWritable(){
struct timeval tv;
tv.tv_sec= 0;
tv.tv_usec= 10;
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
int i= select(sock+1, NULL, &set, NULL, &tv);
if(i<0){
throwException("Error selecting socket");
}
return i==1;
}
bool Socket::isConnected(){
//if the socket is not writable then it is not conencted
if(!isWritable()){
return false;
}
//if the socket is readable it is connected if we can read a byte from it
if(isReadable()){
char tmp;
return recv(sock, &tmp, sizeof(tmp), MSG_PEEK) > 0;
}
//otherwise the socket is connected
return true;
}
string Socket::getHostName() const {
const int strSize= 256;
char hostname[strSize];
gethostname(hostname, strSize);
return hostname;
}
string Socket::getIp() const{
hostent* info= gethostbyname(getHostName().c_str());
unsigned char* address;
if(info==NULL){
throw runtime_error("Error getting host by name");
}
address= reinterpret_cast<unsigned char*>(info->h_addr_list[0]);
if(address==NULL){
throw runtime_error("Error getting host ip");
}
return
intToStr(address[0]) + "." +
intToStr(address[1]) + "." +
intToStr(address[2]) + "." +
intToStr(address[3]);
}
void Socket::throwException(const string &str){
std::stringstream msg;
msg << str << " (Error: " << strerror(errno) << ")";
throw runtime_error(msg.str());
}
// ===============================================
// class ClientSocket
// ===============================================
void ClientSocket::connect(const Ip &ip, int port){
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family= AF_INET;
addr.sin_addr.s_addr= inet_addr(ip.getString().c_str());
addr.sin_port= htons(port);
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if(err < 0) {
char szBuf[1024]="";
sprintf(szBuf,"#2 Error connecting socket for IP: %s for Port: %d err = %d errno = %d [%s]",ip.getString().c_str(),port,err,errno,strerror(errno));
fprintf(stderr, "%s", szBuf);
if (errno == EINPROGRESS) {
fd_set myset;
struct timeval tv;
int valopt;
socklen_t lon;
fprintf(stderr, "EINPROGRESS in connect() - selecting\n");
do {
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_ZERO(&myset);
FD_SET(sock, &myset);
err = select(sock+1, NULL, &myset, NULL, &tv);
if (err < 0 && errno != EINTR) {
sprintf(szBuf, "Error connecting %d - %s\n", errno, strerror(errno));
throwException(szBuf);
}
else if (err > 0) {
// Socket selected for write
lon = sizeof(int);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
sprintf(szBuf, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
throwException(szBuf);
}
// Check the value returned...
if (valopt) {
sprintf(szBuf, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt));
throwException(szBuf);
}
errno = 0;
fprintf(stderr, "Apparent recovery for connection sock = %d, err = %d, errno = %d\n",sock,err,errno);
break;
}
else {
sprintf(szBuf, "Timeout in select() - Cancelling!\n");
throwException(szBuf);
}
} while (1);
}
if(err < 0)
{
throwException(szBuf);
}
fprintf(stderr, "Valid recovery for connection sock = %d, err = %d, errno = %d\n",sock,err,errno);
}
}
// ===============================================
// class ServerSocket
// ===============================================
void ServerSocket::bind(int port){
//sockaddr structure
sockaddr_in addr;
addr.sin_family= AF_INET;
addr.sin_addr.s_addr= INADDR_ANY;
addr.sin_port= htons(port);
int val = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
if(err < 0) {
throwException("Error binding socket");
}
}
void ServerSocket::listen(int connectionQueueSize){
int err= ::listen(sock, connectionQueueSize);
if(err < 0) {
throwException("Error listening socket");
}
}
Socket *ServerSocket::accept(){
int newSock= ::accept(sock, NULL, NULL);
if(newSock < 0) {
if(errno == EAGAIN)
return NULL;
throwException("Error accepting socket connection");
}
return new Socket(newSock);
}
}}//end namespace

View File

@@ -0,0 +1,41 @@
// ==============================================================
// 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 "factory_repository.h"
namespace Shared{ namespace Platform{
// =====================================================
// class FactoryRepository
// =====================================================
FactoryRepository &FactoryRepository::getInstance() {
static FactoryRepository factoryRepository;
return factoryRepository;
}
GraphicsFactory *FactoryRepository::getGraphicsFactory(const string &name) {
if(name == "OpenGL") {
return &graphicsFactoryGl;
}
throw runtime_error("Unknown graphics factory: " + name);
}
SoundFactory *FactoryRepository::getSoundFactory(const string &name) {
if(name == "OpenAL") {
return &soundFactoryOpenAL;
}
throw runtime_error("Unknown sound factory: " + name);
}
}}//end namespace

View File

@@ -0,0 +1,122 @@
//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 "gl_wrap.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <cassert>
#include <SDL.h>
#ifdef X11_AVAILABLE
#include <GL/glx.h>
#endif
#include "opengl.h"
#include "sdl_private.h"
#include "leak_dumper.h"
#include "noimpl.h"
using namespace Shared::Graphics::Gl;
namespace Shared{ namespace Platform{
// ======================================
// class PlatformContextGl
// ======================================
void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits) {
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);
int flags = SDL_OPENGL;
if(Private::shouldBeFullscreen)
flags |= SDL_FULLSCREEN;
int resW = Private::ScreenWidth;
int resH = Private::ScreenHeight;
SDL_Surface* screen = SDL_SetVideoMode(resW, resH, colorBits, flags);
if(screen == 0) {
std::ostringstream msg;
msg << "Couldn't set video mode "
<< resW << "x" << resH << " (" << colorBits
<< "bpp " << stencilBits << " stencil "
<< depthBits << " depth-buffer). SDL Error is: " << SDL_GetError();
throw std::runtime_error(msg.str());
}
}
void PlatformContextGl::end() {
}
void PlatformContextGl::makeCurrent() {
}
void PlatformContextGl::swapBuffers() {
SDL_GL_SwapBuffers();
}
// ======================================
// Global Fcs
// ======================================
void createGlFontBitmaps(uint32 &base, const string &type, int size, int width,
int charCount, FontMetrics &metrics) {
#ifdef X11_AVAILABLE
Display* display = glXGetCurrentDisplay();
if(display == 0) {
throw std::runtime_error("Couldn't create font: display is 0");
}
XFontStruct* fontInfo = XLoadQueryFont(display, type.c_str());
if(!fontInfo) {
throw std::runtime_error("Font not found.");
}
// we need the height of 'a' which sould ~ be half ascent+descent
metrics.setHeight(static_cast<float>
(fontInfo->ascent + fontInfo->descent) / 2);
for(unsigned int i = 0; i < static_cast<unsigned int> (charCount); ++i) {
if(i < fontInfo->min_char_or_byte2 ||
i > fontInfo->max_char_or_byte2) {
metrics.setWidth(i, static_cast<float>(6));
} else {
int p = i - fontInfo->min_char_or_byte2;
metrics.setWidth(i, static_cast<float> (
fontInfo->per_char[p].rbearing
- fontInfo->per_char[p].lbearing));
}
}
glXUseXFont(fontInfo->fid, 0, charCount, base);
XFreeFont(display, fontInfo);
#else
// we badly need a solution portable to more than just glx
NOIMPL;
#endif
}
void createGlFontOutlines(uint32 &base, const string &type, int width,
float depth, int charCount, FontMetrics &metrics) {
NOIMPL;
}
const char *getPlatformExtensions(const PlatformContextGl *pcgl) {
return "";
}
void *getGlProcAddress(const char *procName) {
void* proc = SDL_GL_GetProcAddress(procName);
assert(proc!=NULL);
return proc;
}
}}//end namespace

View File

@@ -0,0 +1,244 @@
//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 "platform_util.h"
#include <iostream>
#include <sstream>
#include <cassert>
#include <glob.h>
#include <errno.h>
#include <string.h>
#include <SDL.h>
#include "util.h"
#include "conversion.h"
#include "leak_dumper.h"
#include "sdl_private.h"
#include "window.h"
#include "noimpl.h"
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
namespace Private{
bool shouldBeFullscreen = false;
int ScreenWidth;
int ScreenHeight;
}
// =====================================
// PerformanceTimer
// =====================================
void PerformanceTimer::init(float fps, int maxTimes){
times= 0;
this->maxTimes= maxTimes;
lastTicks= SDL_GetTicks();
updateTicks= static_cast<int>(1000./fps);
}
bool PerformanceTimer::isTime(){
Uint32 thisTicks = SDL_GetTicks();
if((thisTicks-lastTicks)>=updateTicks && times<maxTimes){
lastTicks+= updateTicks;
times++;
return true;
}
times= 0;
return false;
}
void PerformanceTimer::reset(){
lastTicks= SDL_GetTicks();
}
// =====================================
// Chrono
// =====================================
Chrono::Chrono() {
freq = 1000;
stopped= true;
accumCount= 0;
}
void Chrono::start() {
stopped= false;
startCount = SDL_GetTicks();
}
void Chrono::stop() {
Uint32 endCount;
endCount = SDL_GetTicks();
accumCount += endCount-startCount;
stopped= true;
}
int64 Chrono::getMicros() const {
return queryCounter(1000000);
}
int64 Chrono::getMillis() const {
return queryCounter(1000);
}
int64 Chrono::getSeconds() const {
return queryCounter(1);
}
int64 Chrono::queryCounter(int multiplier) const {
if(stopped) {
return multiplier*accumCount/freq;
} else {
Uint32 endCount;
endCount = SDL_GetTicks();
return multiplier*(accumCount+endCount-startCount)/freq;
}
}
// =====================================
// Misc
// =====================================
//finds all filenames like path and stores them in resultys
void findAll(const string &path, vector<string> &results, bool cutExtension) {
results.clear();
std::string mypath = path;
/** Stupid win32 is searching for all files without extension when *. is
* specified as wildcard
*/
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
results.push_back(begin);
}
globfree(&globbuf);
if(results.size() == 0) {
throw runtime_error("No files found in: " + mypath);
}
if(cutExtension) {
for (size_t i=0; i<results.size(); ++i){
results.at(i)=cutLastExt(results.at(i));
}
}
}
bool changeVideoMode(int resW, int resH, int colorBits, int ) {
Private::shouldBeFullscreen = true;
return true;
}
void restoreVideoMode() {
}
void message(string message) {
std::cerr << "******************************************************\n";
std::cerr << " " << message << "\n";
std::cerr << "******************************************************\n";
}
bool ask(string message) {
std::cerr << "Confirmation: " << message << "\n";
int res;
std::cin >> res;
return res != 0;
}
void exceptionMessage(const exception &excp) {
std::cerr << "Exception: " << excp.what() << std::endl;
}
int getScreenW() {
return SDL_GetVideoSurface()->w;
}
int getScreenH() {
return SDL_GetVideoSurface()->h;
}
void sleep(int millis) {
SDL_Delay(millis);
}
void showCursor(bool b) {
SDL_ShowCursor(b ? SDL_ENABLE : SDL_DISABLE);
}
bool isKeyDown(int virtualKey) {
char key = static_cast<char> (virtualKey);
const Uint8* keystate = SDL_GetKeyState(0);
// kinda hack and wrong...
if(key >= 0) {
return keystate[key];
}
switch(key) {
case vkAdd:
return keystate[SDLK_PLUS] | keystate[SDLK_KP_PLUS];
case vkSubtract:
return keystate[SDLK_MINUS] | keystate[SDLK_KP_MINUS];
case vkAlt:
return keystate[SDLK_LALT] | keystate[SDLK_RALT];
case vkControl:
return keystate[SDLK_LCTRL] | keystate[SDLK_RCTRL];
case vkShift:
return keystate[SDLK_LSHIFT] | keystate[SDLK_RSHIFT];
case vkEscape:
return keystate[SDLK_ESCAPE];
case vkUp:
return keystate[SDLK_UP];
case vkLeft:
return keystate[SDLK_LEFT];
case vkRight:
return keystate[SDLK_RIGHT];
case vkDown:
return keystate[SDLK_DOWN];
case vkReturn:
return keystate[SDLK_RETURN] | keystate[SDLK_KP_ENTER];
case vkBack:
return keystate[SDLK_BACKSPACE];
default:
std::cerr << "isKeyDown called with unknown key.\n";
break;
}
return false;
}
}}//end namespace

View File

@@ -0,0 +1,67 @@
//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 "thread.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#include "noimpl.h"
namespace Shared{ namespace Platform{
// =====================================
// Threads
// =====================================
void Thread::start() {
thread = SDL_CreateThread(beginExecution, this);
}
void Thread::setPriority(Thread::Priority threadPriority) {
NOIMPL;
}
int Thread::beginExecution(void* data) {
Thread* thread = static_cast<Thread*> (data);
thread->execute();
return 0;
}
void Thread::suspend() {
NOIMPL;
}
void Thread::resume() {
NOIMPL;
}
// =====================================
// Mutex
// =====================================
Mutex::Mutex() {
mutex = SDL_CreateMutex();
if(mutex == 0)
throw std::runtime_error("Couldn't initialize mutex");
}
Mutex::~Mutex() {
SDL_DestroyMutex(mutex);
}
void Mutex::p() {
SDL_mutexP(mutex);
}
void Mutex::v() {
SDL_mutexV(mutex);
}
}}//end namespace

View File

@@ -0,0 +1,303 @@
//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 {
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);
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;
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

View File

@@ -0,0 +1,42 @@
// ==============================================================
// 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_gl.h"
#include "gl_wrap.h"
#include "graphics_interface.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
namespace Shared{ namespace Platform{
// =====================================================
// class WindowGl
// =====================================================
void WindowGl::initGl(int colorBits, int depthBits, int stencilBits){
context.setColorBits(colorBits);
context.setDepthBits(depthBits);
context.setStencilBits(stencilBits);
context.init();
}
void WindowGl::makeCurrentGl() {
GraphicsInterface::getInstance().setCurrentContext(&context);
context.makeCurrent();
}
void WindowGl::swapBuffersGl(){
context.swapBuffers();
}
}}//end namespace

View File

@@ -0,0 +1,46 @@
// ==============================================================
// 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 "factory_repository.h"
#include "leak_dumper.h"
namespace Shared{ namespace Platform{
// =====================================================
// class FactoryRepository
// =====================================================
FactoryRepository &FactoryRepository::getInstance(){
static FactoryRepository factoryRepository;
return factoryRepository;
}
GraphicsFactory *FactoryRepository::getGraphicsFactory(const string &name){
if(name == "OpenGL"){
return &graphicsFactoryGl;
}
else if(name == "OpenGL2"){
return &graphicsFactoryGl2;
}
throw runtime_error("Unknown graphics factory: " + name);
}
SoundFactory *FactoryRepository::getSoundFactory(const string &name){
if(name == "DirectSound8"){
return &soundFactoryDs8;
}
throw runtime_error("Unknown sound factory: " + name);
}
}}//end namespace

View File

@@ -0,0 +1,164 @@
// ==============================================================
// 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 "gl_wrap.h"
#include <cassert>
#include <windows.h>
#include "opengl.h"
#include "leak_dumper.h"
using namespace Shared::Graphics::Gl;
namespace Shared{ namespace Platform{
// =====================================================
// class PlatformContextGl
// =====================================================
void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits){
int iFormat;
PIXELFORMATDESCRIPTOR pfd;
BOOL err;
//Set8087CW($133F);
dch = GetDC(GetActiveWindow());
assert(dch!=NULL);
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize= sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion= 1;
pfd.dwFlags= PFD_GENERIC_ACCELERATED | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType= PFD_TYPE_RGBA;
pfd.cColorBits= colorBits;
pfd.cDepthBits= depthBits;
pfd.iLayerType= PFD_MAIN_PLANE;
pfd.cStencilBits= stencilBits;
iFormat= ChoosePixelFormat(dch, &pfd);
assert(iFormat!=0);
err= SetPixelFormat(dch, iFormat, &pfd);
assert(err);
glch= wglCreateContext(dch);
if(glch==NULL){
throw runtime_error("Error initing OpenGL device context");
}
makeCurrent();
}
void PlatformContextGl::end(){
int makeCurrentError= wglDeleteContext(glch);
assert(makeCurrentError);
}
void PlatformContextGl::makeCurrent(){
int makeCurrentError= wglMakeCurrent(dch, glch);
assert(makeCurrentError);
}
void PlatformContextGl::swapBuffers(){
int swapErr= SwapBuffers(dch);
assert(swapErr);
}
// ======================================
// Global Fcs
// ======================================
void createGlFontBitmaps(uint32 &base, const string &type, int size, int width, int charCount, FontMetrics &metrics){
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);
}
void createGlFontOutlines(uint32 &base, const string &type, int width, float depth, int charCount, FontMetrics &metrics){
HFONT font= CreateFont(
10, 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);
GLYPHMETRICSFLOAT *glyphMetrics= new GLYPHMETRICSFLOAT[charCount];
HDC dc= wglGetCurrentDC();
SelectObject(dc, font);
BOOL err= wglUseFontOutlines(dc, 0, charCount, base, 1000, depth, WGL_FONT_POLYGONS, glyphMetrics);
//load metrics
metrics.setHeight(glyphMetrics['a'].gmfBlackBoxY);
for(int i=0; i<charCount; ++i){
metrics.setWidth(i, glyphMetrics[i].gmfCellIncX);
}
DeleteObject(font);
delete [] glyphMetrics;
assert(err);
}
const char *getPlatformExtensions(const PlatformContextGl *pcgl){
typedef const char* (WINAPI * PROCTYPE) (HDC hdc);
PROCTYPE proc= reinterpret_cast<PROCTYPE>(getGlProcAddress("wglGetExtensionsStringARB"));
return proc==NULL? "": proc(pcgl->getHandle());
}
PROC getGlProcAddress(const char *procName){
PROC proc= wglGetProcAddress(procName);
assert(proc!=NULL);
return proc;
}
}}//end namespace

View File

@@ -0,0 +1,75 @@
#include "platform_menu.h"
#include <cassert>
#include "leak_dumper.h"
namespace Shared{ namespace Platform{
int MenuBase::nextId= 1000;
// =====================================================
// class MenuBase
// =====================================================
void MenuBase::init(const string &text){
this->text= text;
id= nextId++;
}
// =====================================================
// class Menu
// =====================================================
void Menu::create(Menu *parent){
handle= CreatePopupMenu();
for(int i= 0; i<children.size(); ++i){
children[i]->create(this);
}
if(parent!=NULL){
BOOL result = AppendMenu(parent->getHandle(), MF_POPUP | MF_STRING, reinterpret_cast<UINT_PTR>(handle), text.c_str());
assert(result);
}
}
void Menu::destroy(){
for(int i= 0; i<children.size(); ++i){
children[i]->destroy();
}
children.clear();
BOOL result = DestroyMenu(handle);
assert(result);
}
// =====================================================
// class MenuItem
// =====================================================
void MenuItem::create(Menu *parent){
isChecked= false;
this->parent = parent;
assert(parent!=NULL);
BOOL result = AppendMenu(parent->getHandle(), MF_STRING, static_cast<UINT>(id), text.c_str());
assert(result);
}
void MenuItem::setChecked(bool checked){
isChecked= checked;
CheckMenuItem(parent->getHandle(), id, checked? MF_CHECKED: MF_UNCHECKED);
}
// =====================================================
// class MenuSeparator
// =====================================================
void MenuSeparator::create(Menu *parent){
assert(parent!=NULL);
BOOL result = AppendMenu(parent->getHandle(), MF_SEPARATOR, static_cast<UINT>(id), NULL);
assert(result);
}
}}//end namespace

View File

@@ -0,0 +1,265 @@
// ==============================================================
// 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 "platform_util.h"
#include <io.h>
#include <DbgHelp.h>
#include <cassert>
#include "util.h"
#include "conversion.h"
#include "leak_dumper.h"
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
// =====================================================
// class PerformanceTimer
// =====================================================
void PerformanceTimer::init(int fps, int maxTimes){
int64 freq;
if(QueryPerformanceFrequency((LARGE_INTEGER*) &freq)==0){
throw runtime_error("Performance counters not supported");
}
times= 0;
this->maxTimes= maxTimes;
QueryPerformanceCounter((LARGE_INTEGER*) &lastTicks);
updateTicks= freq/fps;
}
bool PerformanceTimer::isTime(){
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
if((thisTicks-lastTicks)>=updateTicks && times<maxTimes){
lastTicks+= updateTicks;
times++;
return true;
}
times= 0;
return false;
}
void PerformanceTimer::reset(){
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
lastTicks= thisTicks;
}
// =====================================================
// class Chrono
// =====================================================
Chrono::Chrono(){
if(!QueryPerformanceFrequency((LARGE_INTEGER*) &freq)){
throw runtime_error("Performance counters not supported");
}
stopped= true;
accumCount= 0;
}
void Chrono::start(){
stopped= false;
QueryPerformanceCounter((LARGE_INTEGER*) &startCount);
}
void Chrono::stop(){
int64 endCount;
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
accumCount+= endCount-startCount;
stopped= true;
}
int64 Chrono::getMicros() const{
return queryCounter(1000000);
}
int64 Chrono::getMillis() const{
return queryCounter(1000);
}
int64 Chrono::getSeconds() const{
return queryCounter(1);
}
int64 Chrono::queryCounter(int multiplier) const{
if(stopped){
return multiplier*accumCount/freq;
}
else{
int64 endCount;
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
return multiplier*(accumCount+endCount-startCount)/freq;
}
}
// =====================================================
// class PlatformExceptionHandler
// =====================================================
PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL;
LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){
HANDLE hFile = CreateFile(
thisPointer->dumpFileName.c_str(),
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation;
lExceptionInformation.ThreadId= GetCurrentThreadId();
lExceptionInformation.ExceptionPointers= pointers;
lExceptionInformation.ClientPointers= false;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&lExceptionInformation,
NULL,
NULL );
thisPointer->handle();
return EXCEPTION_EXECUTE_HANDLER;
}
void PlatformExceptionHandler::install(string dumpFileName){
thisPointer= this;
this->dumpFileName= dumpFileName;
SetUnhandledExceptionFilter(handler);
}
// =====================================================
// class Misc
// =====================================================
//finds all filenames like path and stores them in resultys
void findAll(const string &path, vector<string> &results, bool cutExtension){
int i= 0;
struct _finddata_t fi;
intptr_t handle;
char *cstr;
results.clear();
cstr= new char[path.length()+1];
strcpy(cstr, path.c_str());
if((handle=_findfirst(cstr,&fi))!=-1){
do{
if(!(strcmp(".", fi.name)==0 || strcmp("..", fi.name)==0)){
i++;
results.push_back(fi.name);
}
}
while(_findnext(handle, &fi)==0);
}
else{
throw runtime_error("Error opening files: "+ path);
}
if(i==0){
throw runtime_error("No files found: "+ path);
}
if(cutExtension){
for (int i=0; i<results.size(); ++i){
results.at(i)=cutLastExt(results.at(i));
}
}
delete [] cstr;
}
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(){
int dispChangeErr= ChangeDisplaySettings(NULL, 0);
assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
}
void message(string message){
MessageBox(NULL, message.c_str(), "Message", MB_OK);
}
bool ask(string message){
return MessageBox(NULL, message.c_str(), "Confirmation", MB_YESNO)==IDYES;
}
void exceptionMessage(const exception &excp){
string message, title;
showCursor(true);
message+= "ERROR(S):\n\n";
message+= excp.what();
title= "Error: Unhandled Exception";
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);
}
void sleep(int millis){
Sleep(millis);
}
void showCursor(bool b){
ShowCursor(b);
}
bool isKeyDown(int virtualKey){
return (GetKeyState(virtualKey) & 0x8000) != 0;
}
}}//end namespace

View File

@@ -0,0 +1,290 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2007 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 "socket.h"
#include <stdexcept>
#include "conversion.h"
#include "leak_dumper.h"
using namespace std;
using namespace Shared::Util;
namespace Shared{ namespace Platform{
// =====================================================
// class Ip
// =====================================================
Ip::Ip(){
bytes[0]= 0;
bytes[1]= 0;
bytes[2]= 0;
bytes[3]= 0;
}
Ip::Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3){
bytes[0]= byte0;
bytes[1]= byte1;
bytes[2]= byte2;
bytes[3]= byte3;
}
Ip::Ip(const string& ipString){
int offset= 0;
int byteIndex= 0;
for(byteIndex= 0; byteIndex<4; ++byteIndex){
int dotPos= ipString.find_first_of('.', offset);
bytes[byteIndex]= atoi(ipString.substr(offset, dotPos-offset).c_str());
offset= dotPos+1;
}
}
string Ip::getString() const{
return intToStr(bytes[0]) + "." + intToStr(bytes[1]) + "." + intToStr(bytes[2]) + "." + intToStr(bytes[3]);
}
// =====================================================
// class Socket
// =====================================================
Socket::SocketManager Socket::socketManager;
Socket::SocketManager::SocketManager(){
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 0);
WSAStartup(wVersionRequested, &wsaData);
//dont throw exceptions here, this is a static initializacion
}
Socket::SocketManager::~SocketManager(){
WSACleanup();
}
Socket::Socket(SOCKET sock){
this->sock= sock;
}
Socket::Socket(){
sock= socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if(sock==INVALID_SOCKET){
throwException("Error creating socket");
}
}
Socket::~Socket(){
int err= closesocket(sock);
if(err==INVALID_SOCKET){
throwException("Error closing socket");
}
}
int Socket::getDataToRead(){
u_long size;
int err= ioctlsocket(sock, FIONREAD, &size);
if(err==SOCKET_ERROR){
if(WSAGetLastError()!=WSAEWOULDBLOCK){
throwException("Can not get data to read");
}
}
return static_cast<int>(size);
}
int Socket::send(const void *data, int dataSize){
int err= ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
if(err==SOCKET_ERROR){
if(WSAGetLastError()!=WSAEWOULDBLOCK){
throwException("Can not send data");
}
}
return err;
}
int Socket::receive(void *data, int dataSize){
int err= recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
if(err==SOCKET_ERROR){
if(WSAGetLastError()!=WSAEWOULDBLOCK){
throwException("Can not receive data");
}
}
return err;
}
int Socket::peek(void *data, int dataSize){
int err= recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
if(err==SOCKET_ERROR){
if(WSAGetLastError()!=WSAEWOULDBLOCK){
throwException("Can not receive data");
}
}
return err;
}
void Socket::setBlock(bool block){
u_long iMode= !
block;
int err= ioctlsocket(sock, FIONBIO, &iMode);
if(err==SOCKET_ERROR){
throwException("Error setting I/O mode for socket");
}
}
bool Socket::isReadable(){
TIMEVAL tv;
tv.tv_sec= 0;
tv.tv_usec= 10;
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
int i= select(0, &set, NULL, NULL, &tv);
if(i==SOCKET_ERROR){
throwException("Error selecting socket");
}
return i==1;
}
bool Socket::isWritable(){
TIMEVAL tv;
tv.tv_sec= 0;
tv.tv_usec= 10;
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
int i= select(0, NULL, &set, NULL, &tv);
if(i==SOCKET_ERROR){
throwException("Error selecting socket");
}
return i==1;
}
bool Socket::isConnected(){
//if the socket is not writable then it is not conencted
if(!isWritable()){
return false;
}
//if the socket is readable it is connected if we can read a byte from it
if(isReadable()){
char tmp;
return recv(sock, &tmp, sizeof(tmp), MSG_PEEK) > 0;
}
//otherwise the socket is connected
return true;
}
string Socket::getHostName() const{
const int strSize= 256;
char hostname[strSize];
gethostname(hostname, strSize);
return hostname;
}
string Socket::getIp() const{
hostent* info= gethostbyname(getHostName().c_str());
unsigned char* address;
if(info==NULL){
throwException("Error getting host by name");
}
address= reinterpret_cast<unsigned char*>(info->h_addr_list[0]);
if(address==NULL)
{
throwException("Error getting host ip");
}
return
intToStr(address[0]) + "." +
intToStr(address[1]) + "." +
intToStr(address[2]) + "." +
intToStr(address[3]);
}
void Socket::throwException(const string &str){
throw runtime_error("Network error: " + str+" (Code: " + intToStr(WSAGetLastError())+")");
}
// =====================================================
// class ClientSocket
// =====================================================
void ClientSocket::connect(const Ip &ip, int port){
sockaddr_in addr;
addr.sin_family= AF_INET;
addr.sin_addr.s_addr= inet_addr(ip.getString().c_str());
addr.sin_port= htons(port);
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if(err==SOCKET_ERROR){
int lastError= WSAGetLastError();
if(lastError!=WSAEWOULDBLOCK && lastError!=WSAEALREADY){
throwException("Can not connect");
}
}
}
// =====================================================
// class ServerSocket
// =====================================================
void ServerSocket::bind(int port){
//sockaddr structure
sockaddr_in addr;
addr.sin_family= AF_INET;
addr.sin_addr.s_addr= INADDR_ANY;
addr.sin_port= htons(port);
int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
if(err==SOCKET_ERROR){
throwException("Error binding socket");
}
}
void ServerSocket::listen(int connectionQueueSize){
int err= ::listen(sock, connectionQueueSize);
if(err==SOCKET_ERROR){
throwException("Error listening socket");
}
}
Socket *ServerSocket::accept(){
SOCKET newSock= ::accept(sock, NULL, NULL);
if(newSock==INVALID_SOCKET){
if(WSAGetLastError()==WSAEWOULDBLOCK){
return NULL;
}
throwException("Error accepting socket connection");
}
return new Socket(newSock);
}
}}//end namespace

View File

@@ -0,0 +1,66 @@
// ==============================================================
// 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 "thread.h"
#include "leak_dumper.h"
namespace Shared{ namespace Platform{
// =====================================================
// class Threads
// =====================================================
ThreadId Thread::nextThreadId= threadIdBase;
void Thread::start(){
threadHandle= CreateThread(NULL, 0, beginExecution, this, 0, &nextThreadId);
nextThreadId++;
}
void Thread::setPriority(Thread::Priority threadPriority){
SetThreadPriority(threadHandle, threadPriority);
}
DWORD WINAPI Thread::beginExecution(void *param){
static_cast<Thread*>(param)->execute();
return 0;
}
void Thread::suspend(){
SuspendThread(threadHandle);
}
void Thread::resume(){
ResumeThread(threadHandle);
}
// =====================================================
// class Mutex
// =====================================================
Mutex::Mutex(){
InitializeCriticalSection(&mutex);
}
Mutex::~Mutex(){
DeleteCriticalSection(&mutex);
}
void Mutex::p(){
EnterCriticalSection(&mutex);
}
void Mutex::v(){
LeaveCriticalSection(&mutex);
}
}}//end namespace

View File

@@ -0,0 +1,396 @@
// ==============================================================
// 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 "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;
// ===================== PUBLIC ========================
Window::Window(){
handle= 0;
style= windowedFixedStyle;
exStyle= 0;
ownDc= false;
x= 0;
y= 0;
w= 100;
h= 100;
}
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;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if(msg.message==WM_QUIT){
return false;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
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;
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_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

View File

@@ -0,0 +1,44 @@
// ==============================================================
// 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 "window_gl.h"
#include "gl_wrap.h"
#include "graphics_interface.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
namespace Shared{ namespace Platform{
// =====================================================
// class WindowGl
// =====================================================
void WindowGl::initGl(int colorBits, int depthBits, int stencilBits){
context.setColorBits(colorBits);
context.setDepthBits(depthBits);
context.setStencilBits(stencilBits);
context.init();
}
void WindowGl::makeCurrentGl(){
GraphicsInterface::getInstance().setCurrentContext(&context);
context.makeCurrent();
}
void WindowGl::swapBuffersGl(){
context.swapBuffers();
}
}}//end namespace