There seem to be alot of bad pointers, one of each i have identified
Code: Select all
#include "COptionState.h"
void COptionState::onEnter(CGame* game)
{
gui =
game->getUserInterface();
IVideoDriver* driver = game->getVideoDriver();
dimension2d<u32> screenSize =
driver->getScreenSize();
screenSize.Width /= 2;
screenSize.Height /= 2;
Layout = gui->addWindow(
rect<s32>(screenSize.Width - 100, screenSize.Height - 150,
screenSize.Width + 100, screenSize.Height + 150), true, L"Options");
Layout->grab();
// drivers
Driver =
gui->addComboBox(rect<s32>(3, 23, 197, 43), Layout, 1);
{
SVideoDriver s;
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
s.Index = Driver->addItem(L"Direct3D 9");
s.Type = video::EDT_DIRECT3D9;
Drivers.push_back(s);
#endif
#ifdef _IRR_COMPILE_WITH_OPENGL_
s.Index = Driver->addItem(L"OpenGL 1.5");
s.Type = video::EDT_OPENGL;
Drivers.push_back(s);
#endif
s.Index = Driver->addItem(L"Burning Video");
s.Type = video::EDT_BURNINGSVIDEO;
Drivers.push_back(s);
s.Index = Driver->addItem(L"Software");
s.Type = video::EDT_SOFTWARE;
Drivers.push_back(s);
// set the current driver as the default
u32 n;
for (n = 0; n < Drivers.size(); ++n)
{
if (Current.Driver == Drivers[n].Type)
{
Driver->setSelected(Drivers[n].Index);
break;
}
}
}
// resolution/bit depth
WindowMode =
gui->addComboBox(rect<s32>(3, 46, 197, 66), Layout, 2);
{
video::IVideoModeList* modes =
game->getDevice()->getVideoModeList();
s32 m;
for (m = 0; m < modes->getVideoModeCount(); ++m)
{
const dimension2d<u32> res =
modes->getVideoModeResolution(m);
if (res.Width < 640 || res.Height < 480)
continue;
const s32 bits = modes->getVideoModeDepth(m);
if (bits < 16)
continue;
wchar_t option[64];
_snwprintf(option, 64, L"%u x %u @ %u bits", res.Width, res.Height, bits);
SVideoMode s;
s.Index = WindowMode->addItem(option);
s.BitDepth = bits;
s.WindowSize = res;
Modes.push_back(s);
}
// set the current window mode as the default
u32 n;
for (n = 0; n < Modes.size(); ++n)
{
if (Current.BitDepth == Modes[n].BitDepth && Current.WindowSize == Modes[n].WindowSize)
{
WindowMode->setSelected(Modes[n].Index);
break;
}
}
}
// full screen/vsync
FullScreen=
gui->addCheckBox(Current.FullScreen, rect<s32>(3, 69, 197, 89), Layout, 3, L"Full Screen");
VertSynch =
gui->addCheckBox(Current.VertSynch, rect<s32>(3, 92, 197, 112), Layout, 4, L"Vertical Sync");
// okay/cancel
gui->addButton(rect<s32>(34, 115, 114, 135), Layout, 5, L"Okay");
gui->addButton(rect<s32>(117, 115, 197, 135), Layout, 6, L"Cancel");
}
void COptionState::onLeave(CGame* game)
{
// remove our layout
Layout->remove();
Layout->drop();
Layout = 0;
FullScreen = 0;
VertSynch = 0;
WindowMode = 0;
Driver = 0;
}
void COptionState::onUpdate(CGame* game){}
bool COptionState::onEvent(CGame* game, SEvent event)
{
switch (event.EventType)
{
case EET_GUI_EVENT:
if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
{
s32 id = event.GUIEvent.Caller->getID();
if (id == 5) // OK
{
return acceptChanges(game);
}
else if (id == 6) // cancel
{
return cancelChanges(game);
}
}
break;
case EET_KEY_INPUT_EVENT:
if (event.KeyInput.Key == KEY_ESCAPE &&
event.KeyInput.PressedDown)
{
return cancelChanges(game);
}
else if (event.KeyInput.Key == KEY_RETURN &&
event.KeyInput.PressedDown)
{
return acceptChanges(game);
}
break;
}
return false;
}
bool COptionState::acceptChanges(CGame* game)
{
SIrrlichtCreationParameters params;
params.Fullscreen = FullScreen->isChecked();
params.Vsync = VertSynch ->isChecked();
params.DriverType = Drivers[Driver->getSelected()].Type;
params.Bits = Modes[WindowMode->getSelected()].BitDepth;
params.WindowSize = Modes[WindowMode->getSelected()].WindowSize;
// leave the current state
CStateT<CGame, SEvent>* local = game->getCurrentState();
local->onLeave(game); // Leave the options menu
game->setCurrentState(0); // Go to the first screen, not actually a state
CStateT<CGame, SEvent>* global = game->getGlobalState();
global->onLeave(game); // Currently does nothing
game->setGlobalState(0); // Set Global state to be original screen
// destroy the device
IrrlichtDevice* device = game->getDevice(); // Device here is a bad ptr, how is that possible
device->closeDevice();
device->run(); // consume quit event
game->setDevice(0);
// create a new device and fallback if necessary
device = createDeviceEx(params);
if (!device)
{
params.DriverType = video::EDT_BURNINGSVIDEO;
params.Fullscreen = false;
device = createDeviceEx(params);
}
// cache flags used to create device so we can display them later
Current.BitDepth = params.Bits;
Current.Driver = params.DriverType;
Current.FullScreen = params.Fullscreen;
Current.VertSynch = params.Vsync;
Current.WindowSize = params.WindowSize;
// set the new device
game->setDevice(device);
// drop reference to device, it is now owned by the game
device->drop();
// re-enter the global state
game->setGlobalState(global);
global->onEnter(game);
// re-enter the current state
game->setCurrentState(local);
local->onEnter(game);
return true;
}
bool COptionState::cancelChanges(CGame* game)
{
game->setState( game->getPreviousState() );
return true;
}