Skip to content

Instantly share code, notes, and snippets.

@stevetranby
Created December 27, 2020 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevetranby/b4a5547193462d56b43d9d1dd4098bb7 to your computer and use it in GitHub Desktop.
Save stevetranby/b4a5547193462d56b43d9d1dd4098bb7 to your computer and use it in GitHub Desktop.
Cocos2d-x Desktop Game Change Resolution Menu Scene
//
// OptionsResolutionMenu.cpp
// scgamex
//
// Created by Steve Tranby on 9/14/14.
//
//
#include "stdafx.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#include "OptionsResolutionMenu.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include <glfw3\include\win32\glfw3.h>
#else
#include "glfw3.h"
#endif
#include "managers/GameManager.h"
#include "helpers/GUIHelper.h"
#include <ui/UIText.h>
#include <ui/UIListView.h>
#include <ui/UIScrollView.h>
#include <ui/UIButton.h>
USING_NS_CC;
using namespace ui;
OptionsResolutionMenu::OptionsResolutionMenu() {}
OptionsResolutionMenu::~OptionsResolutionMenu() {}
Scene* OptionsResolutionMenu::scene()
{
Scene* scene = Scene::create();
OptionsResolutionMenu* layer = OptionsResolutionMenu::create();
layer->setTag(kTagSceneBaseLayer);
scene->addChild(layer);
return scene;
}
bool OptionsResolutionMenu::init()
{
if (!SCLayer::init()) {
return false;
}
auto ws = Director::getInstance()->getWinSize();
Vec2 screenCenter = Vec2(ws * 0.5f);
setupBackground();
auto fontSize = 20 * SCALE_LARGE_UI;
#if ((CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX))
auto lbl = Label::createWithTTF("Change Resolution", kFontVisitor, fontSize);
CCASSERT(lbl, "lbl was null, PANIC!");
lbl->setNormalizedPosition(Vec2(0.5f,0.95f));
addChild(lbl);
// TODO: get list of resolutions from STDevice -> from glfw supported video modes
addResolutionButton(cocos2d::Size(960,640));
addResolutionButton(cocos2d::Size(1024,768));
addResolutionButton(cocos2d::Size(1440,900));
// iPad 10.5 (landscape) points/pixels
addResolutionButton(cocos2d::Size(1112,834));
//addResolutionButton(cocos2d::Size(2224,1668));
// iPad Pro (landscape) points/pixels
addResolutionButton(cocos2d::Size(1366,1024));
//addResolutionButton(cocos2d::Size(2732,2048));
// iPhoneX (landscape) points/pixels
//addResolutionButton(cocos2d::Size(2436,1125));
addResolutionButton(cocos2d::Size(2436.f * .5f, 1125.f * .5f));
addResolutionButton(cocos2d::Size(-1,-1));
#else
dinfo("[non-desktop] no need for change resolution");
#endif
ListView* container = static_cast<ListView*>(getChildByName("container"));
if (container) {
auto lbl2 = Text::create("Other Resolutions", kFontVisitor, int(fontSize));
container->pushBackCustomItem(lbl2);
addResolutionButton(cocos2d::Size(480, 320));
addResolutionButton(cocos2d::Size(738, 415));
addResolutionButton(cocos2d::Size(800, 480));
addResolutionButton(cocos2d::Size(1136, 640));
addResolutionButton(cocos2d::Size(1280, 1048));
addResolutionButton(cocos2d::Size(1600, 1080));
addResolutionButton(cocos2d::Size(1920, 1080));
}
return true;
}
void OptionsResolutionMenu::onEnter()
{
SCLayer::onEnter();
showAccept(false);
}
void OptionsResolutionMenu::decline()
{
dinfo("enter");
// TODO: would be nice to detect the previous scene
//GameManager::get()->runSceneWithID(SceneType::GameMode);
GameManager::get()->runSceneWithID(SceneType::MainMenu);
}
void OptionsResolutionMenu::addResolutionButton(cocos2d::Size size)
{
auto ws = Director::getInstance()->getWinSize();
Vec2 screenCenter = Vec2(ws * 0.5f);
// create layout if not yet
ListView* container = static_cast<ListView*>(getChildByName("container"));
if(! container)
{
container = ListView::create();
container->setContentSize(cocos2d::Size(ws.width * 0.5f, ws.height * 0.8f));
container->setDirection(cocos2d::ui::ScrollView::Direction::VERTICAL);
container->setName("container");
container->setItemsMargin(ws.width * 0.014f);
// .15f half button width - half margin
container->setPosition(Vec2(ws.width * (0.5f - 0.15f), ws.height * 0.05f));
addChild(container);
}
auto b = GUIHelper::buttonWithText(kSpriteButtonPurplePrefix, "_on", "_hl", "_on", "New Game");
b->setTouchEnabled(true);
b->setScale9Enabled(true);
b->setTitleFontName(kFontVisitor.c_str());
b->setTitleFontSize(20.f * SCALE_LARGE_EXACT);
b->setContentSize(cocos2d::Size(ws.width * 0.3f, ws.height * 0.1f));
if(size.width < 0 || size.height < 0) {
b->setTitleText("Fill Screen");
} else {
b->setTitleText(stdstr("%d x %d", (int)size.width, (int)size.height));
}
b->addTouchEventListener([this,size](Ref*, ui::Widget::TouchEventType eventType) {
if(eventType == ui::Widget::TouchEventType::ENDED) {
changeResolution(size);
}
});
container->pushBackCustomItem(b);
}
void OptionsResolutionMenu::GetMaxMonitorResolution(int* w, int* h)
{
int count;
const GLFWvidmode* modes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count);
int maxWidth = 0;
int maxHeight = 0;
for (int i = 0; i < count; i++)
{
if (modes[i].width > maxWidth)
maxWidth = modes[i].width;
if (modes[i].height > maxHeight)
maxHeight = modes[i].height;
}
*w = maxWidth;
*h = maxHeight;
}
void OptionsResolutionMenu::changeResolution(cocos2d::Size frameSize)
{
auto glviewimpl = dynamic_cast<GLViewImpl*>(Director::getInstance()->getOpenGLView());
if(glviewimpl) {
OptionsResolutionMenu::static_changeResolution(glviewimpl, frameSize);
STDevice::get()->refreshDesignScaleFactors(glviewimpl);
STDevice::get()->addMainMenu(glviewimpl);
UserDefault::getInstance()->setIntegerForKey(kPrefDesktopResolutionWidth.c_str(), (int)frameSize.width);
UserDefault::getInstance()->setIntegerForKey(kPrefDesktopResolutionHeight.c_str(), (int)frameSize.height);
UserDefault::getInstance()->flush();
GameManager::get()->runSceneWithID(SceneType::OptionsResolution, 0);
}
}
void OptionsResolutionMenu::static_changeResolution(GLViewImpl* glview, cocos2d::Size frameSize)
{
auto glfwindow = glview->getWindow();
auto fsize = glview->getFrameSize();
// win position
int winx = 0, winy = 0;
glfwGetWindowPos(glfwindow, &winx, &winy);
cocos2d::Rect viewport = glview->getViewPortRect();
Vec2 viewcenter = Vec2(viewport.getMidX(), viewport.getMidY());
CCLOG("framesize = %s, viewcenter = %s", CStrFromSize(frameSize), CStrFromPoint(viewcenter));
int cx = int(winx + fsize.width/2); CC_UNUSED_PARAM(cx);
int cy = int(winy + fsize.height/2); CC_UNUSED_PARAM(cy);
dinfo("screen rect = %d,%d", cx, cy);
auto screenSize = glview->getMonitorSize();
int sw = screenSize.width > 0 ? (int)screenSize.width : 960;
int sh = screenSize.height > 0 ? (int)screenSize.height : 640;
if(frameSize.width < 0 || frameSize.height < 0) {
frameSize = screenSize;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
auto kOSXMainMenuHeight = 44.f;
frameSize.height -= kOSXMainMenuHeight;
#endif
}
glview->setFrameSize(frameSize.width, frameSize.height);
int x = int(sw - frameSize.width)/2;
int y = int(sh - frameSize.height)/2;
glfwSetWindowPos(glfwindow, x, y);
}
#endif
//
// OptionsResolutionMenu.h
// scgamex
//
// Created by Steve Tranby on 9/14/14.
//
//
#pragma once
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#include "layers/SCLayer.h"
class OptionsResolutionMenu
: public SCLayer
{
public:
CREATE_FUNC(OptionsResolutionMenu);
OptionsResolutionMenu();
virtual ~OptionsResolutionMenu();
bool init() override;
static cocos2d::Scene* scene();
void onEnter() override;
void decline() override;
void GetMaxMonitorResolution(int* w, int* h);
void addResolutionButton(cocos2d::Size size);
void changeResolution(cocos2d::Size size);
static void static_changeResolution(cocos2d::GLViewImpl* glview, cocos2d::Size frameSize);
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment