- added support for proper quiting and console input/output in headless mode. Type: quit followed by return into the console to properly shutdown in headless mode.
This commit is contained in:
parent
9caff9dac3
commit
2a86cb4f7d
|
@ -106,6 +106,11 @@ Game::Game(Program *program, const GameSettings *gameSettings,bool masterserverM
|
|||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
this->masterserverMode = masterserverMode;
|
||||
|
||||
if(this->masterserverMode == true) {
|
||||
printf("Starting a new game...\n");
|
||||
}
|
||||
|
||||
this->program = program;
|
||||
Unit::setGame(this);
|
||||
gameStarted = false;
|
||||
|
@ -930,6 +935,10 @@ void Game::init(bool initForPreviewOnly)
|
|||
|
||||
gameStarted = true;
|
||||
|
||||
if(this->masterserverMode == true) {
|
||||
printf("New game has started...\n");
|
||||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ==== START GAME ==== getCurrentPixelByteCount() = %llu\n",__FILE__,__FUNCTION__,__LINE__,(long long unsigned int)renderer.getCurrentPixelByteCount());
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled) SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"==== START GAME ====\n");
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ CoreData &CoreData::getInstance() {
|
|||
}
|
||||
|
||||
CoreData::~CoreData() {
|
||||
deleteValues(waterSounds.getSounds().begin(), waterSounds.getSounds().end());
|
||||
deleteValues(waterSounds.getSoundsPtr()->begin(), waterSounds.getSoundsPtr()->end());
|
||||
waterSounds.getSoundsPtr()->clear();
|
||||
}
|
||||
|
||||
void CoreData::load() {
|
||||
|
|
|
@ -5108,104 +5108,109 @@ void Renderer::renderShadowsToTexture(const int renderFps){
|
|||
// ==================== gl wrap ====================
|
||||
|
||||
string Renderer::getGlInfo(){
|
||||
string infoStr;
|
||||
string infoStr="";
|
||||
Lang &lang= Lang::getInstance();
|
||||
|
||||
infoStr+= lang.get("OpenGlInfo")+":\n";
|
||||
infoStr+= " "+lang.get("OpenGlVersion")+": ";
|
||||
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlRenderer")+": ";
|
||||
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlVendor")+": ";
|
||||
infoStr+= string((getGlVendor() != NULL ? getGlVendor() : "?"))+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlMaxLights")+": ";
|
||||
infoStr+= intToStr(getGlMaxLights())+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlMaxTextureSize")+": ";
|
||||
infoStr+= intToStr(getGlMaxTextureSize())+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlMaxTextureUnits")+": ";
|
||||
infoStr+= intToStr(getGlMaxTextureUnits())+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlModelviewStack")+": ";
|
||||
infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlProjectionStack")+": ";
|
||||
infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n";
|
||||
|
||||
if(this->masterserverMode == false) {
|
||||
infoStr+= lang.get("OpenGlInfo")+":\n";
|
||||
infoStr+= " "+lang.get("OpenGlVersion")+": ";
|
||||
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlRenderer")+": ";
|
||||
infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlVendor")+": ";
|
||||
infoStr+= string((getGlVendor() != NULL ? getGlVendor() : "?"))+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlMaxLights")+": ";
|
||||
infoStr+= intToStr(getGlMaxLights())+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlMaxTextureSize")+": ";
|
||||
infoStr+= intToStr(getGlMaxTextureSize())+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlMaxTextureUnits")+": ";
|
||||
infoStr+= intToStr(getGlMaxTextureUnits())+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlModelviewStack")+": ";
|
||||
infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n";
|
||||
infoStr+= " "+lang.get("OpenGlProjectionStack")+": ";
|
||||
infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n";
|
||||
}
|
||||
return infoStr;
|
||||
}
|
||||
|
||||
string Renderer::getGlMoreInfo(){
|
||||
string infoStr;
|
||||
string infoStr="";
|
||||
Lang &lang= Lang::getInstance();
|
||||
|
||||
//gl extensions
|
||||
infoStr+= lang.get("OpenGlExtensions")+":\n ";
|
||||
if(this->masterserverMode == false) {
|
||||
//gl extensions
|
||||
infoStr+= lang.get("OpenGlExtensions")+":\n ";
|
||||
|
||||
string extensions= getGlExtensions();
|
||||
int charCount= 0;
|
||||
for(int i=0; i<extensions.size(); ++i){
|
||||
infoStr+= extensions[i];
|
||||
if(charCount>120 && extensions[i]==' '){
|
||||
infoStr+= "\n ";
|
||||
charCount= 0;
|
||||
string extensions= getGlExtensions();
|
||||
int charCount= 0;
|
||||
for(int i=0; i<extensions.size(); ++i){
|
||||
infoStr+= extensions[i];
|
||||
if(charCount>120 && extensions[i]==' '){
|
||||
infoStr+= "\n ";
|
||||
charCount= 0;
|
||||
}
|
||||
++charCount;
|
||||
}
|
||||
++charCount;
|
||||
}
|
||||
|
||||
//platform extensions
|
||||
infoStr+= "\n\n";
|
||||
infoStr+= lang.get("OpenGlPlatformExtensions")+":\n ";
|
||||
//platform extensions
|
||||
infoStr+= "\n\n";
|
||||
infoStr+= lang.get("OpenGlPlatformExtensions")+":\n ";
|
||||
|
||||
charCount= 0;
|
||||
string platformExtensions= getGlPlatformExtensions();
|
||||
for(int i=0; i<platformExtensions.size(); ++i){
|
||||
infoStr+= platformExtensions[i];
|
||||
if(charCount>120 && platformExtensions[i]==' '){
|
||||
infoStr+= "\n ";
|
||||
charCount= 0;
|
||||
charCount= 0;
|
||||
string platformExtensions= getGlPlatformExtensions();
|
||||
for(int i=0; i<platformExtensions.size(); ++i){
|
||||
infoStr+= platformExtensions[i];
|
||||
if(charCount>120 && platformExtensions[i]==' '){
|
||||
infoStr+= "\n ";
|
||||
charCount= 0;
|
||||
}
|
||||
++charCount;
|
||||
}
|
||||
++charCount;
|
||||
}
|
||||
|
||||
return infoStr;
|
||||
}
|
||||
|
||||
void Renderer::autoConfig(){
|
||||
void Renderer::autoConfig() {
|
||||
if(this->masterserverMode == false) {
|
||||
Config &config= Config::getInstance();
|
||||
|
||||
Config &config= Config::getInstance();
|
||||
bool nvidiaCard= toLower(getGlVendor()).find("nvidia")!=string::npos;
|
||||
bool atiCard= toLower(getGlVendor()).find("ati")!=string::npos;
|
||||
//bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow") && isGlExtensionSupported("GL_ARB_shadow_ambient");
|
||||
bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow");
|
||||
bool nvidiaCard= toLower(getGlVendor()).find("nvidia")!=string::npos;
|
||||
bool atiCard= toLower(getGlVendor()).find("ati")!=string::npos;
|
||||
//bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow") && isGlExtensionSupported("GL_ARB_shadow_ambient");
|
||||
bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow");
|
||||
|
||||
//3D textures
|
||||
config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D"));
|
||||
//3D textures
|
||||
config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D"));
|
||||
|
||||
//shadows
|
||||
string shadows;
|
||||
if(getGlMaxTextureUnits()>=3){
|
||||
if(nvidiaCard && shadowExtensions){
|
||||
shadows= shadowsToStr(sShadowMapping);
|
||||
//shadows
|
||||
string shadows="";
|
||||
if(getGlMaxTextureUnits()>=3){
|
||||
if(nvidiaCard && shadowExtensions){
|
||||
shadows= shadowsToStr(sShadowMapping);
|
||||
}
|
||||
else{
|
||||
shadows= shadowsToStr(sProjected);
|
||||
}
|
||||
}
|
||||
else{
|
||||
shadows= shadowsToStr(sProjected);
|
||||
shadows=shadowsToStr(sDisabled);
|
||||
}
|
||||
}
|
||||
else{
|
||||
shadows=shadowsToStr(sDisabled);
|
||||
}
|
||||
config.setString("Shadows", shadows);
|
||||
config.setString("Shadows", shadows);
|
||||
|
||||
//lights
|
||||
config.setInt("MaxLights", atiCard? 1: 4);
|
||||
//lights
|
||||
config.setInt("MaxLights", atiCard? 1: 4);
|
||||
|
||||
//filter
|
||||
config.setString("Filter", "Bilinear");
|
||||
//filter
|
||||
config.setString("Filter", "Bilinear");
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::clearBuffers(){
|
||||
void Renderer::clearBuffers() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void Renderer::clearZBuffer(){
|
||||
void Renderer::clearZBuffer() {
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
#include "leak_dumper.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#include <poll.h>
|
||||
|
||||
#define stricmp strcasecmp
|
||||
#define strnicmp strncasecmp
|
||||
#define _strnicmp strncasecmp
|
||||
|
@ -623,7 +625,7 @@ void handleSIGSEGV(int sig) {
|
|||
// class MainWindow
|
||||
// =====================================================
|
||||
|
||||
MainWindow::MainWindow(Program *program){
|
||||
MainWindow::MainWindow(Program *program) : WindowGl() {
|
||||
this->program= program;
|
||||
}
|
||||
|
||||
|
@ -3450,8 +3452,47 @@ int glestMain(int argc, char** argv) {
|
|||
//printf("[%s]",test.c_str());
|
||||
|
||||
//time_t lastTextureLoadEvent = time(NULL);
|
||||
|
||||
// Check for commands being input from stdin
|
||||
string command="";
|
||||
#ifndef WIN32
|
||||
pollfd cinfd[1];
|
||||
// Theoretically this should always be 0, but one fileno call isn't going to hurt, and if
|
||||
// we try to run somewhere that stdin isn't fd 0 then it will still just work
|
||||
cinfd[0].fd = fileno(stdin);
|
||||
cinfd[0].events = POLLIN;
|
||||
#else
|
||||
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
|
||||
#endif
|
||||
|
||||
if(isMasterServerModeEnabled == true) {
|
||||
printf("Headless server is now running...\n");
|
||||
}
|
||||
|
||||
//main loop
|
||||
while(Window::handleEvent()) {
|
||||
if(isMasterServerModeEnabled == true) {
|
||||
#ifndef WIN32
|
||||
if(poll(cinfd, 1, 0))
|
||||
#else
|
||||
// This is problematic because input on Windows is not line-buffered so this will return
|
||||
// even if getline may block. I haven't found a good way to fix it, so for the moment
|
||||
// I just strongly suggest only running the server from the Python frontend, which does
|
||||
// line buffer input. This does work okay as long as the user doesn't enter characters
|
||||
// without pressing enter, and then try to end the server another way (say a remote
|
||||
// console command), in which case we'll still be waiting for the stdin EOL and hang.
|
||||
if (WaitForSingleObject(h, 0) == WAIT_OBJECT_0)
|
||||
#endif
|
||||
{
|
||||
getline(cin, command);
|
||||
printf("server command [%s]\n",command.c_str());
|
||||
if(command == "quit") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//printf("looping\n");
|
||||
}
|
||||
|
||||
program->loop();
|
||||
// Because OpenGL really doesn't do multi-threading well
|
||||
// if(difftime(time(NULL),lastTextureLoadEvent) >= 3) {
|
||||
|
@ -3468,6 +3509,10 @@ int glestMain(int argc, char** argv) {
|
|||
// }
|
||||
}
|
||||
|
||||
if(isMasterServerModeEnabled == true) {
|
||||
printf("\nHeadless server is about to quit...\n");
|
||||
}
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] starting normal application shutdown\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
cleanupCRCThread();
|
||||
|
|
|
@ -84,11 +84,13 @@ void ProgramState::render() {
|
|||
canRender();
|
||||
incrementFps();
|
||||
|
||||
renderer.clearBuffers();
|
||||
renderer.reset2d();
|
||||
renderer.renderMessageBox(program->getMsgBox());
|
||||
renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
|
||||
renderer.swapBuffers();
|
||||
if(renderer.isMasterserverMode() == false) {
|
||||
renderer.clearBuffers();
|
||||
renderer.reset2d();
|
||||
renderer.renderMessageBox(program->getMsgBox());
|
||||
renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
|
||||
renderer.swapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramState::update() {
|
||||
|
@ -419,7 +421,7 @@ void Program::renderProgramMsgBox() {
|
|||
}
|
||||
}
|
||||
|
||||
void Program::setState(ProgramState *programState, bool cleanupOldState)
|
||||
void Program::setState(ProgramState *programStateNew, bool cleanupOldState)
|
||||
{
|
||||
try {
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
@ -427,13 +429,13 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
|
|||
bool msgBoxEnabled = msgBox.getEnabled();
|
||||
|
||||
bool showingOSCursor = isCursorShowing();
|
||||
if(dynamic_cast<Game *>(programState) != NULL) {
|
||||
if(dynamic_cast<Game *>(programStateNew) != NULL) {
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
int X = 0;
|
||||
int Y = 0;
|
||||
SDL_GetMouseState(&X,&Y);
|
||||
programState->setStartXY(X,Y);
|
||||
programStateNew->setStartXY(X,Y);
|
||||
Logger::getInstance().setProgress(0);
|
||||
Logger::getInstance().setState("");
|
||||
|
||||
|
@ -447,7 +449,7 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
|
|||
}
|
||||
|
||||
if(cleanupOldState == true) {
|
||||
if(this->programState != programState) {
|
||||
if(this->programState != programStateNew) {
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
delete this->programState;
|
||||
|
@ -471,13 +473,13 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
|
|||
updateTimer.init(GameConstants::updateFps, maxTimes);
|
||||
updateCameraTimer.init(GameConstants::cameraFps, maxTimes);
|
||||
|
||||
this->programState= programState;
|
||||
assert(programState != NULL);
|
||||
programState->load();
|
||||
this->programState= programStateNew;
|
||||
assert(programStateNew != NULL);
|
||||
programStateNew->load();
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
programState->init();
|
||||
programStateNew->init();
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
|
@ -492,7 +494,7 @@ void Program::setState(ProgramState *programState, bool cleanupOldState)
|
|||
}
|
||||
sleep(0);
|
||||
|
||||
if(dynamic_cast<Intro *>(programState) != NULL && msgBoxEnabled == true) {
|
||||
if(dynamic_cast<Intro *>(programStateNew) != NULL && msgBoxEnabled == true) {
|
||||
showCursor(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ public:
|
|||
bool isMessageShowing();
|
||||
|
||||
//misc
|
||||
void setState(ProgramState *programState,bool cleanupOldState=true);
|
||||
void setState(ProgramState *programStateNew,bool cleanupOldState=true);
|
||||
ProgramState * getState() { return programState;}
|
||||
WindowGl * getWindow() { return window; }
|
||||
void init(WindowGl *window, bool initSound=true, bool toggleFullScreen=false);
|
||||
|
|
|
@ -53,6 +53,10 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu,
|
|||
MenuState(program, mainMenu, "new-game")
|
||||
{
|
||||
this->masterserverMode = masterserverMode;
|
||||
if(this->masterserverMode == true) {
|
||||
printf("Waiting for players to join and start a game...\n");
|
||||
}
|
||||
|
||||
this->lastMasterServerSettingsUpdateCount = 0;
|
||||
this->masterserverModeMinimalResources = true;
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
StaticSound *&operator[](int i) {return sounds[i];}
|
||||
|
||||
const Sounds &getSounds() const {return sounds;}
|
||||
Sounds *getSoundsPtr() {return &sounds;}
|
||||
StaticSound *getRandSound() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace Glest{ namespace Game{
|
|||
|
||||
const int UnitPathBasic::maxBlockCount= GameConstants::updateFps / 2;
|
||||
|
||||
UnitPathBasic::UnitPathBasic() {
|
||||
UnitPathBasic::UnitPathBasic() : UnitPathInterface() {
|
||||
this->blockCount = 0;
|
||||
this->pathQueue.clear();
|
||||
this->lastPathCacheQueue.clear();
|
||||
|
@ -249,6 +249,7 @@ set<Unit*> Unit::livingUnitsp;
|
|||
Game *Unit::game = NULL;
|
||||
|
||||
Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) {
|
||||
lastSynchDataString="";
|
||||
modelFacing = CardinalDir::NORTH;
|
||||
lastStuckFrame = 0;
|
||||
lastStuckPos = Vec2i(0,0);
|
||||
|
|
|
@ -207,6 +207,7 @@ private:
|
|||
|
||||
public:
|
||||
BroadCastSocketThread();
|
||||
virtual ~BroadCastSocketThread();
|
||||
virtual void execute();
|
||||
virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false);
|
||||
};
|
||||
|
|
|
@ -2288,6 +2288,10 @@ BroadCastSocketThread::BroadCastSocketThread() : BaseThread() {
|
|||
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
BroadCastSocketThread::~BroadCastSocketThread() {
|
||||
|
||||
}
|
||||
|
||||
bool BroadCastSocketThread::canShutdown(bool deleteSelfIfShutdownDelayed) {
|
||||
bool ret = (getExecutingTask() == false);
|
||||
if(ret == false && deleteSelfIfShutdownDelayed == true) {
|
||||
|
|
Loading…
Reference in New Issue