Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions CGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
#include "CIO/CWindow.h"
#include "CMap.h"
#include "RttrConfig.h"
#include "TerrainRenderer.h"
#include "files.h"
#include "globals.h"
#include "s25util/file_handle.h"
#include <glad/glad.h>
#include <boost/filesystem.hpp>
#include <boost/nowide/cstdio.hpp>
#include <boost/program_options.hpp>
Expand Down Expand Up @@ -41,6 +43,11 @@ CGame::CGame(Extent GameResolution_, bool fullscreen_)

CGame::~CGame()
{
if(glContext_)
{
SDL_GL_DeleteContext(static_cast<SDL_GLContext>(glContext_));
glContext_ = nullptr;
}
global::s2 = nullptr;
}

Expand All @@ -67,12 +74,21 @@ int CGame::Execute()
return 0;
}

void CGame::RenderPresent() const
void CGame::RenderPresent()
{
// Upload Surf_Display to GL and draw (used by loading screen and callbacks)
if(uiOverlayTex_.valid())
uiOverlayTex_.updateFromSurface(Surf_Display.get());
else
uiOverlayTex_.createFromSurface(Surf_Display.get());
if(uiOverlayTex_.valid())
uiOverlayTex_.draw(0, 0);
SDL_GL_SwapWindow(window_.get());
}

void CGame::FlushSurfaceToGL()
{
SDL_UpdateTexture(displayTexture_.get(), nullptr, Surf_Display->pixels, Surf_Display->w * sizeof(Uint32));
SDL_RenderClear(renderer_.get());
SDL_RenderCopy(renderer_.get(), displayTexture_.get(), nullptr, nullptr);
SDL_RenderPresent(renderer_.get());
RenderPresent();
}

CMenu* CGame::RegisterMenu(std::unique_ptr<CMenu> Menu)
Expand All @@ -82,6 +98,7 @@ CMenu* CGame::RegisterMenu(std::unique_ptr<CMenu> Menu)

Menu->setActive();
Menus.emplace_back(std::move(Menu));
uiDirty_ = true;

return Menus.back().get();
}
Expand All @@ -94,6 +111,7 @@ bool CGame::UnregisterMenu(CMenu* Menu)
if(it != Menus.begin())
it[-1]->setActive();
Menus.erase(it);
uiDirty_ = true;
return true;
}

Expand All @@ -111,6 +129,7 @@ CWindow* CGame::RegisterWindow(std::unique_ptr<CWindow> Window)
Window->setActive();
Window->setPriority(highestPriority + 1);
Windows.emplace_back(std::move(Window));
uiDirty_ = true;

return Windows.back().get();
}
Expand All @@ -123,6 +142,7 @@ bool CGame::UnregisterWindow(CWindow* Window)
if(it != Windows.begin())
it[-1]->setActive();
Windows.erase(it);
uiDirty_ = true;
return true;
}

Expand All @@ -141,9 +161,12 @@ bool CGame::UnregisterCallback(void (*callback)(int))
return true;
}

void CGame::setMapObj(std::unique_ptr<CMap> MapObj)
void CGame::setMapObj(std::unique_ptr<CMap> map)
{
this->MapObj = std::move(MapObj);
this->MapObj = std::move(map);
// Force terrain regeneration on new map. CMap::Draw will call
// GenerateOpenGL on the next frame when it sees the terrain is invalid.
TerrainRenderer::invalidateTerrain();
}

CMap* CGame::getMapObj()
Expand Down
16 changes: 13 additions & 3 deletions CGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#pragma once

#include "CIO/CFont.h"
#include "CSurfaceGL.h"
#include "SdlSurface.h"
#include <Point.h>
#include <memory>
Expand All @@ -26,9 +27,12 @@ class CGame
bool Running;
bool showLoadScreen;
SdlSurface Surf_Display;
SdlTexture displayTexture_;
SdlRenderer renderer_;
SdlWindow window_;
void* glContext_;
/// Persistent OpenGL texture for uploading the software overlay surface
EditorGLTexture displayGLTex_;
/// Persistent OpenGL texture for the final UI overlay (used by RenderPresent)
EditorGLTexture uiOverlayTex_;

private:
#ifdef _ADMINMODE
Expand All @@ -42,6 +46,8 @@ class CGame
CFont lastFps;

Uint32 lastFrameTime = 0;
/// Does the composited UI surface (Surf_Display) need re-uploading?
bool uiDirty_ = true;

// structure for mouse cursor
struct
Expand Down Expand Up @@ -81,7 +87,10 @@ class CGame

void Render();

void RenderPresent() const;
void RenderPresent();
/// Upload Surf_Display content to OpenGL and present it.
/// Used by callbacks that render to Surf_Display directly (e.g. "Please wait").
void FlushSurfaceToGL();

CMenu* RegisterMenu(std::unique_ptr<CMenu> Menu);
bool UnregisterMenu(CMenu* Menu);
Expand All @@ -94,4 +103,5 @@ class CGame
void delMapObj();
SDL_Surface* getDisplaySurface() const { return Surf_Display.get(); };
auto getRes() const { return GameResolution; }
auto getCursorPos() const { return Cursor.pos; }
};
4 changes: 4 additions & 0 deletions CGame_Event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "CIO/CWindow.h"
#include "CMap.h"
#include "CSurface.h"
#include "TerrainRenderer.h"
#include "callbacks.h"
#include "globals.h"

Expand Down Expand Up @@ -146,6 +147,7 @@ void CGame::EventHandling(SDL_Event* Event)
{
Cursor.pos = Position(Event->motion.x, Event->motion.y);
}
uiDirty_ = true;
/*
//NOTE: we will now deliver the data to menus, windows, map etc., sometimes we have to break the
switch and stop
Expand Down Expand Up @@ -238,6 +240,7 @@ void CGame::EventHandling(SDL_Event* Event)
Cursor.button.left = true;
else if(Event->button.button == SDL_BUTTON_RIGHT)
Cursor.button.right = true;
uiDirty_ = true;

// clicking a mouse button will close the S2 loading screen if it is shown
if(showLoadScreen)
Expand Down Expand Up @@ -309,6 +312,7 @@ void CGame::EventHandling(SDL_Event* Event)
{
// setup mouse cursor data
Cursor.clicked = false;
uiDirty_ = true;

// NOTE: we will now deliver the data to menus, windows, map etc., sometimes we have to break the switch and
// stop
Expand Down
49 changes: 32 additions & 17 deletions CGame_Init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,52 @@
#include "CIO/CFile.h"
#include "CMap.h"
#include "CSurface.h"
#include "SGE/sge_blib.h"
#include "SGE/sge_surface.h"
#include "CSurfaceGL.h"
#include "TerrainRenderer.h"
#include "callbacks.h"
#include "globals.h"
#include "lua/GameDataLoader.h"
#include <glad/glad.h>
#include <iostream>
#include <vector>

bool CGame::ReCreateWindow()
{
displayTexture_.reset();
renderer_.reset();
displayGLTex_ = EditorGLTexture();
uiOverlayTex_ = EditorGLTexture();
window_.reset();

unsigned windowFlags = fullscreen ? SDL_WINDOW_FULLSCREEN : 0;

// Create window with OpenGL support (hard requirement, like s25client)
window_.reset(SDL_CreateWindow("Return to the Roots Map editor [BETA]", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, GameResolution.x, GameResolution.y,
fullscreen ? SDL_WINDOW_FULLSCREEN : 0));
windowFlags | SDL_WINDOW_OPENGL));
if(!window_)
return false;
renderer_.reset(SDL_CreateRenderer(window_.get(), -1, 0));
if(!renderer_)

glContext_ = SDL_GL_CreateContext(window_.get());
if(!glContext_ || !gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
{
std::cerr << "Failed to create OpenGL context!\n";
return false;
displayTexture_ = makeSdlTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, GameResolution.x,
GameResolution.y);
}

std::cout << "OpenGL " << GLVersion.major << "." << GLVersion.minor << " initialized\n";
CSurfaceGL::init(GameResolution.x, GameResolution.y); // GL state setup (once)
TerrainRenderer::Init(GameResolution); // renderer init (once)
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window_.get());

// Software surface for legacy rendering (text overlay, callbacks).
// RGBA so the UI overlay can be composited on top of the map.
Surf_Display = makeRGBSurface(GameResolution.x, GameResolution.y, true);
if(!displayTexture_ || !Surf_Display)
if(!Surf_Display)
return false;
uiDirty_ = true;

if(MapObj)
MapObj->setOverlayDirty();

SetAppIcon();
return true;
Expand All @@ -50,7 +70,6 @@ bool CGame::Init()
std::cout << "failure";
return false;
}
sge_Lock_OFF();
CFile::init();

/*NOTE: its important to load a palette at first,
Expand Down Expand Up @@ -80,12 +99,8 @@ bool CGame::Init()

// std::cout << "\nShow loading screen...";
showLoadScreen = true;
// CSurface::Draw(Surf_Display, global::bmpArray[SPLASHSCREEN_LOADING_S2SCREEN].surface, 0, 0);
auto& surfSplash = global::bmpArray[SPLASHSCREEN_LOADING_S2SCREEN].surface;
sge_TexturedRect(Surf_Display.get(), 0, 0, Surf_Display->w - 1, 0, 0, Surf_Display->h - 1, Surf_Display->w - 1,
Surf_Display->h - 1, surfSplash.get(), 0, 0, surfSplash->w - 1, 0, 0, surfSplash->h - 1,
surfSplash->w - 1, surfSplash->h - 1);
RenderPresent();
// Render the loading screen once so the user sees something during loading
Render();

GameDataLoader gdLoader(global::worldDesc);
if(!gdLoader.Load())
Expand Down
Loading