2020-11-05 16:44:34 +01:00
|
|
|
#include "pch.h"
|
|
|
|
#include "winmain.h"
|
2020-11-06 14:56:32 +01:00
|
|
|
|
2021-10-05 15:48:13 +02:00
|
|
|
#include "control.h"
|
2020-11-06 14:56:32 +01:00
|
|
|
#include "fullscrn.h"
|
2020-12-02 18:12:34 +01:00
|
|
|
#include "midi.h"
|
2020-11-05 16:44:34 +01:00
|
|
|
#include "pinball.h"
|
|
|
|
#include "options.h"
|
2020-11-06 14:56:32 +01:00
|
|
|
#include "pb.h"
|
2021-09-21 12:14:39 +02:00
|
|
|
#include "render.h"
|
2020-11-29 16:50:49 +01:00
|
|
|
#include "Sound.h"
|
2020-11-05 16:44:34 +01:00
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
SDL_Window* winmain::MainWindow = nullptr;
|
2021-09-01 10:02:57 +02:00
|
|
|
SDL_Renderer* winmain::Renderer = nullptr;
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGuiIO* winmain::ImIO = nullptr;
|
2020-12-03 15:47:36 +01:00
|
|
|
|
|
|
|
int winmain::return_value = 0;
|
2021-10-23 08:02:51 +02:00
|
|
|
bool winmain::bQuit = false;
|
|
|
|
bool winmain::activated = false;
|
2021-01-16 15:45:29 +01:00
|
|
|
int winmain::DispFrameRate = 0;
|
2021-11-11 12:30:56 +01:00
|
|
|
bool winmain::DispGRhistory = false;
|
2021-10-23 08:02:51 +02:00
|
|
|
bool winmain::single_step = false;
|
|
|
|
bool winmain::has_focus = true;
|
2020-12-03 15:47:36 +01:00
|
|
|
int winmain::last_mouse_x;
|
|
|
|
int winmain::last_mouse_y;
|
|
|
|
int winmain::mouse_down;
|
2021-10-23 08:02:51 +02:00
|
|
|
bool winmain::no_time_loss = false;
|
2020-12-03 15:47:36 +01:00
|
|
|
|
2021-02-06 14:53:47 +01:00
|
|
|
bool winmain::restart = false;
|
2020-12-03 15:47:36 +01:00
|
|
|
|
2021-10-02 16:45:31 +02:00
|
|
|
gdrv_bitmap8* winmain::gfr_display = nullptr;
|
2021-09-16 09:57:46 +02:00
|
|
|
std::string winmain::DatFileName;
|
2021-09-05 09:47:05 +02:00
|
|
|
bool winmain::ShowAboutDialog = false;
|
|
|
|
bool winmain::ShowImGuiDemo = false;
|
2021-09-21 12:14:39 +02:00
|
|
|
bool winmain::ShowSpriteViewer = false;
|
2021-09-06 15:27:58 +02:00
|
|
|
bool winmain::LaunchBallEnabled = true;
|
|
|
|
bool winmain::HighScoresEnabled = true;
|
|
|
|
bool winmain::DemoActive = false;
|
2021-11-05 08:16:27 +01:00
|
|
|
std::string winmain::BasePath;
|
2021-10-30 09:12:30 +02:00
|
|
|
int winmain::MainMenuHeight = 0;
|
2021-09-23 11:16:58 +02:00
|
|
|
std::string winmain::FpsDetails;
|
2021-09-28 07:14:18 +02:00
|
|
|
double winmain::UpdateToFrameRatio;
|
|
|
|
winmain::DurationMs winmain::TargetFrameTime;
|
2021-10-09 16:28:30 +02:00
|
|
|
optionsStruct& winmain::Options = options::Options;
|
2021-08-27 12:29:41 +02:00
|
|
|
|
2021-09-01 10:02:57 +02:00
|
|
|
int winmain::WinMain(LPCSTR lpCmdLine)
|
2020-11-05 16:44:34 +01:00
|
|
|
{
|
2021-09-22 14:50:07 +02:00
|
|
|
restart = false;
|
|
|
|
bQuit = false;
|
|
|
|
|
2021-10-02 16:45:31 +02:00
|
|
|
std::set_new_handler(memalloc_failure);
|
2020-11-05 16:44:34 +01:00
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
// SDL init
|
|
|
|
SDL_SetMainReady();
|
2021-10-26 16:11:53 +02:00
|
|
|
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO |
|
|
|
|
SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0)
|
2020-11-05 16:44:34 +01:00
|
|
|
{
|
2021-08-27 12:29:41 +02:00
|
|
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not initialize SDL2", SDL_GetError(), nullptr);
|
|
|
|
return 1;
|
2021-09-05 09:47:05 +02:00
|
|
|
}
|
2020-11-05 16:44:34 +01:00
|
|
|
|
2020-11-06 14:56:32 +01:00
|
|
|
pinball::quickFlag = strstr(lpCmdLine, "-quick") != nullptr;
|
2020-11-05 16:44:34 +01:00
|
|
|
|
2021-11-05 08:16:27 +01:00
|
|
|
// Search for game data in: game folder, user folder
|
|
|
|
// Game data test order: CADET.DAT, PINBALL.DAT
|
|
|
|
char* dataSearchPaths[2]
|
2021-02-06 14:53:47 +01:00
|
|
|
{
|
2021-11-05 08:16:27 +01:00
|
|
|
SDL_GetBasePath(),
|
|
|
|
SDL_GetPrefPath(nullptr, "SpaceCadetPinball")
|
|
|
|
};
|
|
|
|
std::string datFileNames[2]
|
|
|
|
{
|
|
|
|
"CADET.DAT",
|
|
|
|
options::get_string("Pinball Data", pinball::get_rc_string(168, 0))
|
|
|
|
};
|
|
|
|
for (auto path : dataSearchPaths)
|
|
|
|
{
|
|
|
|
if (DatFileName.empty() && path)
|
|
|
|
{
|
|
|
|
BasePath = path;
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
{
|
|
|
|
auto datFileName = datFileNames[i];
|
|
|
|
auto datFilePath = pinball::make_path_name(datFileName);
|
2021-11-06 17:22:56 +01:00
|
|
|
auto datFile = fopenu(datFilePath.c_str(), "r");
|
2021-11-05 08:16:27 +01:00
|
|
|
if (datFile)
|
|
|
|
{
|
|
|
|
fclose(datFile);
|
|
|
|
DatFileName = datFileName;
|
|
|
|
if (i == 0)
|
|
|
|
pb::FullTiltMode = true;
|
|
|
|
printf("Loading game from: %s\n", datFilePath.c_str());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_free(path);
|
2021-02-06 14:53:47 +01:00
|
|
|
}
|
2021-09-06 15:27:58 +02:00
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
// SDL window
|
|
|
|
SDL_Window* window = SDL_CreateWindow
|
|
|
|
(
|
|
|
|
pinball::get_rc_string(38, 0),
|
|
|
|
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
2021-09-05 09:47:05 +02:00
|
|
|
800, 556,
|
2021-08-27 12:29:41 +02:00
|
|
|
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE
|
|
|
|
);
|
|
|
|
MainWindow = window;
|
|
|
|
if (!window)
|
2020-11-06 14:56:32 +01:00
|
|
|
{
|
2021-08-27 12:29:41 +02:00
|
|
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not create window", SDL_GetError(), nullptr);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2021-10-30 09:12:30 +02:00
|
|
|
// If HW fails, fallback to SW SDL renderer.
|
|
|
|
SDL_Renderer* renderer = nullptr;
|
|
|
|
for (int i = 0; i < 2 && !renderer; i++)
|
|
|
|
{
|
|
|
|
Renderer = renderer = SDL_CreateRenderer
|
|
|
|
(
|
|
|
|
window,
|
|
|
|
-1,
|
|
|
|
i == 0 ? SDL_RENDERER_ACCELERATED : SDL_RENDERER_SOFTWARE
|
|
|
|
);
|
|
|
|
}
|
2021-08-27 12:29:41 +02:00
|
|
|
if (!renderer)
|
|
|
|
{
|
|
|
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not create renderer", SDL_GetError(), window);
|
|
|
|
return 1;
|
|
|
|
}
|
2021-10-30 09:12:30 +02:00
|
|
|
SDL_RendererInfo rendererInfo{};
|
|
|
|
if (!SDL_GetRendererInfo(renderer, &rendererInfo))
|
|
|
|
printf("Using SDL renderer: %s\n", rendererInfo.name);
|
2021-09-22 14:50:07 +02:00
|
|
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
2021-09-23 11:16:58 +02:00
|
|
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
|
2021-08-27 12:29:41 +02:00
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
// ImGui init
|
|
|
|
IMGUI_CHECKVERSION();
|
|
|
|
ImGui::CreateContext();
|
|
|
|
ImGuiSDL::Initialize(renderer, 0, 0);
|
|
|
|
ImGui::StyleColorsDark();
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
ImIO = &io;
|
|
|
|
// ImGui_ImplSDL2_Init is private, we are not actually using ImGui OpenGl backend
|
|
|
|
ImGui_ImplSDL2_InitForOpenGL(window, nullptr);
|
2021-11-15 15:32:18 +01:00
|
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
|
2021-09-05 09:47:05 +02:00
|
|
|
|
2021-09-16 09:57:46 +02:00
|
|
|
auto prefPath = SDL_GetPrefPath(nullptr, "SpaceCadetPinball");
|
|
|
|
auto iniPath = std::string(prefPath) + "imgui_pb.ini";
|
|
|
|
io.IniFilename = iniPath.c_str();
|
|
|
|
SDL_free(prefPath);
|
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
// PB init from message handler
|
|
|
|
{
|
2021-09-06 15:27:58 +02:00
|
|
|
options::init();
|
2021-10-09 16:28:30 +02:00
|
|
|
if (!Sound::Init(Options.SoundChannels, Options.Sounds))
|
|
|
|
Options.Sounds = false;
|
2021-08-27 12:29:41 +02:00
|
|
|
|
2021-09-01 10:02:57 +02:00
|
|
|
if (!pinball::quickFlag && !midi::music_init())
|
2021-10-09 16:28:30 +02:00
|
|
|
Options.Music = false;
|
2021-08-27 12:29:41 +02:00
|
|
|
|
2021-09-06 15:27:58 +02:00
|
|
|
if (pb::init())
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-06 15:27:58 +02:00
|
|
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not load game data",
|
2021-09-21 12:14:39 +02:00
|
|
|
"The .dat file is missing", window);
|
2021-09-05 09:47:05 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2021-09-06 15:27:58 +02:00
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
fullscrn::init();
|
2020-11-06 14:56:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pb::reset_table();
|
|
|
|
pb::firsttime_setup();
|
|
|
|
|
|
|
|
if (strstr(lpCmdLine, "-fullscreen"))
|
|
|
|
{
|
2021-10-09 16:28:30 +02:00
|
|
|
Options.FullScreen = true;
|
2020-11-06 14:56:32 +01:00
|
|
|
}
|
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
SDL_ShowWindow(window);
|
2021-10-09 16:28:30 +02:00
|
|
|
fullscrn::set_screen_mode(Options.FullScreen);
|
2020-11-07 16:41:14 +01:00
|
|
|
|
2020-11-29 16:50:49 +01:00
|
|
|
if (strstr(lpCmdLine, "-demo"))
|
|
|
|
pb::toggle_demo();
|
|
|
|
else
|
|
|
|
pb::replay_level(0);
|
|
|
|
|
2021-11-11 12:30:56 +01:00
|
|
|
unsigned updateCounter = 0, frameCounter = 0;
|
2021-08-27 12:29:41 +02:00
|
|
|
|
2021-09-28 07:14:18 +02:00
|
|
|
auto frameStart = Clock::now();
|
2021-10-03 17:06:19 +02:00
|
|
|
double UpdateToFrameCounter = 0;
|
|
|
|
DurationMs sleepRemainder(0), frameDuration(TargetFrameTime);
|
2021-09-28 07:14:18 +02:00
|
|
|
auto prevTime = frameStart;
|
2020-11-06 14:56:32 +01:00
|
|
|
while (true)
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-28 07:14:18 +02:00
|
|
|
if (DispFrameRate)
|
|
|
|
{
|
|
|
|
auto curTime = Clock::now();
|
|
|
|
if (curTime - prevTime > DurationMs(1000))
|
|
|
|
{
|
|
|
|
char buf[60];
|
|
|
|
auto elapsedSec = DurationMs(curTime - prevTime).count() * 0.001;
|
|
|
|
snprintf(buf, sizeof buf, "Updates/sec = %02.02f Frames/sec = %02.02f ",
|
|
|
|
updateCounter / elapsedSec, frameCounter / elapsedSec);
|
|
|
|
SDL_SetWindowTitle(window, buf);
|
|
|
|
FpsDetails = buf;
|
|
|
|
frameCounter = updateCounter = 0;
|
|
|
|
prevTime = curTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-06 14:56:32 +01:00
|
|
|
if (!ProcessWindowMessages() || bQuit)
|
|
|
|
break;
|
2020-11-29 16:50:49 +01:00
|
|
|
|
|
|
|
if (has_focus)
|
|
|
|
{
|
|
|
|
if (mouse_down)
|
|
|
|
{
|
2021-10-10 16:13:43 +02:00
|
|
|
int x, y, w, h;
|
2021-09-28 07:14:18 +02:00
|
|
|
SDL_GetMouseState(&x, &y);
|
2021-10-10 16:13:43 +02:00
|
|
|
SDL_GetWindowSize(window, &w, &h);
|
2021-10-23 06:33:04 +02:00
|
|
|
float dx = static_cast<float>(last_mouse_x - x) / static_cast<float>(w);
|
|
|
|
float dy = static_cast<float>(y - last_mouse_y) / static_cast<float>(h);
|
2021-10-10 16:13:43 +02:00
|
|
|
pb::ballset(dx, dy);
|
2021-10-17 17:18:29 +02:00
|
|
|
|
2021-09-28 07:14:18 +02:00
|
|
|
SDL_WarpMouseInWindow(window, last_mouse_x, last_mouse_y);
|
2021-10-10 16:13:43 +02:00
|
|
|
|
|
|
|
// Mouse warp does not work over remote desktop or in some VMs
|
|
|
|
//last_mouse_x = x;
|
|
|
|
//last_mouse_y = y;
|
2020-11-29 16:50:49 +01:00
|
|
|
}
|
2021-10-23 08:02:51 +02:00
|
|
|
if (!single_step && !no_time_loss)
|
2020-11-29 16:50:49 +01:00
|
|
|
{
|
2021-10-03 17:06:19 +02:00
|
|
|
auto dt = static_cast<float>(frameDuration.count());
|
|
|
|
pb::frame(dt);
|
2021-11-11 12:30:56 +01:00
|
|
|
if (DispGRhistory)
|
2020-11-29 16:50:49 +01:00
|
|
|
{
|
2021-11-11 12:30:56 +01:00
|
|
|
auto width = 300;
|
2021-11-18 10:11:25 +01:00
|
|
|
auto height = 64, halfHeight = height / 2;
|
2021-11-11 12:30:56 +01:00
|
|
|
if (!gfr_display)
|
2020-11-29 16:50:49 +01:00
|
|
|
{
|
2021-11-11 12:30:56 +01:00
|
|
|
gfr_display = new gdrv_bitmap8(width, height, false);
|
|
|
|
gfr_display->CreateTexture("nearest", SDL_TEXTUREACCESS_STREAMING);
|
2020-11-29 16:50:49 +01:00
|
|
|
}
|
2021-11-11 12:30:56 +01:00
|
|
|
|
|
|
|
gdrv::ScrollBitmapHorizontal(gfr_display, -1);
|
2021-11-18 10:11:25 +01:00
|
|
|
gdrv::fill_bitmap(gfr_display, 1, halfHeight, width - 1, 0, ColorRgba::Black()); // Background
|
|
|
|
gdrv::fill_bitmap(gfr_display, 1, halfHeight, width - 1, halfHeight, ColorRgba::White()); // Target
|
2021-11-11 12:30:56 +01:00
|
|
|
|
|
|
|
auto target = static_cast<float>(TargetFrameTime.count());
|
2021-11-18 10:11:25 +01:00
|
|
|
auto scale = halfHeight / target;
|
|
|
|
auto diffHeight = std::min(static_cast<int>(std::round(std::abs(target - dt) * scale)), halfHeight);
|
|
|
|
auto yOffset = dt < target ? halfHeight : halfHeight - diffHeight;
|
|
|
|
gdrv::fill_bitmap(gfr_display, 1, diffHeight, width - 1, yOffset, ColorRgba::Red()); // Target diff
|
2020-11-29 16:50:49 +01:00
|
|
|
}
|
2021-09-28 07:14:18 +02:00
|
|
|
updateCounter++;
|
2020-11-29 16:50:49 +01:00
|
|
|
}
|
2021-10-23 08:02:51 +02:00
|
|
|
no_time_loss = false;
|
2021-09-01 10:02:57 +02:00
|
|
|
|
2021-09-28 07:14:18 +02:00
|
|
|
if (UpdateToFrameCounter >= UpdateToFrameRatio)
|
2021-09-01 10:02:57 +02:00
|
|
|
{
|
2021-09-29 16:53:49 +02:00
|
|
|
ImGui_ImplSDL2_NewFrame();
|
|
|
|
ImGui::NewFrame();
|
|
|
|
RenderUi();
|
2021-09-05 09:47:05 +02:00
|
|
|
|
2021-09-01 10:02:57 +02:00
|
|
|
SDL_RenderClear(renderer);
|
2021-09-25 15:52:19 +02:00
|
|
|
render::PresentVScreen();
|
2021-09-05 09:47:05 +02:00
|
|
|
|
2021-09-29 16:53:49 +02:00
|
|
|
ImGui::Render();
|
|
|
|
ImGuiSDL::Render(ImGui::GetDrawData());
|
2021-09-05 09:47:05 +02:00
|
|
|
|
2021-09-01 10:02:57 +02:00
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
frameCounter++;
|
2021-09-29 16:53:49 +02:00
|
|
|
UpdateToFrameCounter -= UpdateToFrameRatio;
|
2021-09-01 10:02:57 +02:00
|
|
|
}
|
2021-09-22 14:50:07 +02:00
|
|
|
|
|
|
|
auto sdlError = SDL_GetError();
|
|
|
|
if (sdlError[0])
|
|
|
|
{
|
|
|
|
SDL_ClearError();
|
|
|
|
printf("SDL Error: %s\n", sdlError);
|
|
|
|
}
|
2021-09-28 07:14:18 +02:00
|
|
|
|
|
|
|
auto updateEnd = Clock::now();
|
|
|
|
auto targetTimeDelta = TargetFrameTime - DurationMs(updateEnd - frameStart) - sleepRemainder;
|
|
|
|
|
|
|
|
TimePoint frameEnd;
|
2021-10-09 16:28:30 +02:00
|
|
|
if (targetTimeDelta > DurationMs::zero() && !Options.UncappedUpdatesPerSecond)
|
2021-09-28 07:14:18 +02:00
|
|
|
{
|
|
|
|
std::this_thread::sleep_for(targetTimeDelta);
|
|
|
|
frameEnd = Clock::now();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
frameEnd = updateEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Limit duration to 2 * target time
|
2021-11-18 10:11:25 +01:00
|
|
|
sleepRemainder = std::max(std::min(DurationMs(frameEnd - updateEnd) - targetTimeDelta, TargetFrameTime), -TargetFrameTime);
|
2021-10-03 17:06:19 +02:00
|
|
|
frameDuration = std::min<DurationMs>(DurationMs(frameEnd - frameStart), 2 * TargetFrameTime);
|
2021-09-28 07:14:18 +02:00
|
|
|
frameStart = frameEnd;
|
|
|
|
UpdateToFrameCounter++;
|
2020-11-29 16:50:49 +01:00
|
|
|
}
|
2020-11-06 14:56:32 +01:00
|
|
|
}
|
|
|
|
|
2021-10-02 16:45:31 +02:00
|
|
|
delete gfr_display;
|
2021-11-11 12:30:56 +01:00
|
|
|
gfr_display = nullptr;
|
2020-12-04 16:35:47 +01:00
|
|
|
options::uninit();
|
|
|
|
midi::music_shutdown();
|
|
|
|
pb::uninit();
|
|
|
|
Sound::Close();
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGuiSDL::Deinitialize();
|
|
|
|
ImGui_ImplSDL2_Shutdown();
|
2021-09-01 10:02:57 +02:00
|
|
|
SDL_DestroyRenderer(renderer);
|
|
|
|
SDL_DestroyWindow(window);
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::DestroyContext();
|
2021-09-01 10:02:57 +02:00
|
|
|
SDL_Quit();
|
2021-02-06 14:53:47 +01:00
|
|
|
|
2020-11-06 14:56:32 +01:00
|
|
|
return return_value;
|
|
|
|
}
|
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
void winmain::RenderUi()
|
2020-11-06 14:56:32 +01:00
|
|
|
{
|
2021-09-29 16:53:49 +02:00
|
|
|
// A minimal window with a button to prevent menu lockout.
|
2021-10-09 16:28:30 +02:00
|
|
|
if (!Options.ShowMenu)
|
2021-09-29 16:53:49 +02:00
|
|
|
{
|
|
|
|
ImGui::SetNextWindowPos(ImVec2{});
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{10, 0});
|
|
|
|
if (ImGui::Begin("main", nullptr,
|
|
|
|
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground |
|
|
|
|
ImGuiWindowFlags_AlwaysAutoResize |
|
2021-11-15 15:32:18 +01:00
|
|
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoFocusOnAppearing))
|
2021-09-29 16:53:49 +02:00
|
|
|
{
|
|
|
|
ImGui::PushID(1);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{});
|
|
|
|
if (ImGui::Button("Menu"))
|
|
|
|
{
|
|
|
|
options::toggle(Menu1::Show_Menu);
|
|
|
|
}
|
|
|
|
ImGui::PopStyleColor(1);
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
2021-10-01 08:05:38 +02:00
|
|
|
ImGui::End();
|
2021-09-29 16:53:49 +02:00
|
|
|
ImGui::PopStyleVar();
|
2021-11-15 15:32:18 +01:00
|
|
|
|
|
|
|
// This window can not loose nav focus for some reason, clear it manually.
|
|
|
|
if (ImGui::IsNavInputDown(ImGuiNavInput_Cancel))
|
|
|
|
ImGui::FocusWindow(NULL);
|
2021-09-29 16:53:49 +02:00
|
|
|
}
|
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
// No demo window in release to save space
|
|
|
|
#ifndef NDEBUG
|
|
|
|
if (ShowImGuiDemo)
|
2021-09-21 12:14:39 +02:00
|
|
|
ImGui::ShowDemoWindow(&ShowImGuiDemo);
|
2021-09-05 09:47:05 +02:00
|
|
|
#endif
|
2021-01-29 14:42:05 +01:00
|
|
|
|
2021-10-30 11:34:17 +02:00
|
|
|
if (Options.ShowMenu && ImGui::BeginMainMenuBar())
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-10-24 17:38:23 +02:00
|
|
|
int currentMenuHeight = static_cast<int>(ImGui::GetWindowSize().y);
|
|
|
|
if (MainMenuHeight != currentMenuHeight)
|
|
|
|
{
|
|
|
|
// Get the height of the main menu bar and update screen coordinates
|
|
|
|
MainMenuHeight = currentMenuHeight;
|
|
|
|
fullscrn::window_size_changed();
|
|
|
|
}
|
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
if (ImGui::BeginMenu("Game"))
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
if (ImGui::MenuItem("New Game", "F2"))
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
new_game();
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
2021-09-06 15:27:58 +02:00
|
|
|
if (ImGui::MenuItem("Launch Ball", nullptr, false, LaunchBallEnabled))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
|
|
|
end_pause();
|
|
|
|
pb::launch_ball();
|
|
|
|
}
|
|
|
|
if (ImGui::MenuItem("Pause/ Resume Game", "F3"))
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
pause();
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::Separator();
|
2020-12-02 18:12:34 +01:00
|
|
|
|
2021-09-06 15:27:58 +02:00
|
|
|
if (ImGui::MenuItem("High Scores...", nullptr, false, HighScoresEnabled))
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
if (!single_step)
|
|
|
|
pause();
|
|
|
|
pb::high_scores();
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
2021-09-06 15:27:58 +02:00
|
|
|
if (ImGui::MenuItem("Demo", nullptr, DemoActive))
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
end_pause();
|
|
|
|
pb::toggle_demo();
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
if (ImGui::MenuItem("Exit"))
|
|
|
|
{
|
|
|
|
SDL_Event event{SDL_QUIT};
|
|
|
|
SDL_PushEvent(&event);
|
|
|
|
}
|
|
|
|
ImGui::EndMenu();
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
if (ImGui::BeginMenu("Options"))
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("Show Menu", "F9", Options.ShowMenu))
|
2021-09-29 02:21:21 +02:00
|
|
|
{
|
|
|
|
options::toggle(Menu1::Show_Menu);
|
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("Full Screen", "F4", Options.FullScreen))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::Full_Screen);
|
2021-09-05 09:47:05 +02:00
|
|
|
}
|
|
|
|
if (ImGui::BeginMenu("Select Players"))
|
|
|
|
{
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("1 Player", nullptr, Options.Players == 1))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::OnePlayer);
|
2021-09-05 09:47:05 +02:00
|
|
|
new_game();
|
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("2 Players", nullptr, Options.Players == 2))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::TwoPlayers);
|
2021-09-05 09:47:05 +02:00
|
|
|
new_game();
|
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("3 Players", nullptr, Options.Players == 3))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::ThreePlayers);
|
2021-09-05 09:47:05 +02:00
|
|
|
new_game();
|
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("4 Players", nullptr, Options.Players == 4))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::FourPlayers);
|
2021-09-05 09:47:05 +02:00
|
|
|
new_game();
|
|
|
|
}
|
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("Sound", "F5", Options.Sounds))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::Sounds);
|
2021-09-05 09:47:05 +02:00
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("Music", "F6", Options.Music))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::Music);
|
2021-09-05 09:47:05 +02:00
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
ImGui::TextUnformatted("Sound Channels");
|
|
|
|
if (ImGui::SliderInt("##Sound Channels", &Options.SoundChannels, options::MinSoundChannels,
|
|
|
|
options::MaxSoundChannels, "%d", ImGuiSliderFlags_AlwaysClamp))
|
|
|
|
{
|
|
|
|
Options.SoundChannels = std::min(options::MaxSoundChannels,
|
|
|
|
std::max(options::MinSoundChannels, Options.SoundChannels));
|
|
|
|
Sound::SetChannels(Options.SoundChannels);
|
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
if (ImGui::MenuItem("Player Controls...", "F8"))
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-01-06 15:06:13 +01:00
|
|
|
if (!single_step)
|
|
|
|
pause();
|
2021-10-01 08:05:38 +02:00
|
|
|
options::ShowControlDialog();
|
2021-09-05 09:47:05 +02:00
|
|
|
}
|
|
|
|
if (ImGui::BeginMenu("Table Resolution"))
|
|
|
|
{
|
2021-09-22 14:50:07 +02:00
|
|
|
char buffer[20]{};
|
|
|
|
auto maxResText = pinball::get_rc_string(fullscrn::GetMaxResolution() + 2030, 0);
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem(maxResText, nullptr, Options.Resolution == -1))
|
2021-09-22 14:50:07 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::MaximumResolution);
|
2021-09-22 14:50:07 +02:00
|
|
|
}
|
|
|
|
for (auto i = 0; i <= fullscrn::GetMaxResolution(); i++)
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-09-22 14:50:07 +02:00
|
|
|
auto& res = fullscrn::resolution_array[i];
|
|
|
|
snprintf(buffer, sizeof buffer - 1, "%d x %d", res.ScreenWidth, res.ScreenHeight);
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem(buffer, nullptr, Options.Resolution == i))
|
2021-09-22 14:50:07 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(static_cast<Menu1>(static_cast<int>(Menu1::R640x480) + i));
|
2021-09-22 14:50:07 +02:00
|
|
|
}
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::EndMenu();
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
2021-09-28 07:14:18 +02:00
|
|
|
if (ImGui::BeginMenu("Graphics"))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("Uniform Scaling", nullptr, Options.UniformScaling))
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::WindowUniformScale);
|
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem("Linear Filtering", nullptr, Options.LinearFiltering))
|
2021-09-23 11:16:58 +02:00
|
|
|
{
|
|
|
|
options::toggle(Menu1::WindowLinearFilter);
|
2021-09-05 09:47:05 +02:00
|
|
|
}
|
2021-09-28 07:14:18 +02:00
|
|
|
ImGui::DragFloat("UI Scale", &ImIO->FontGlobalScale, 0.005f, 0.8f, 5,
|
|
|
|
"%.2f", ImGuiSliderFlags_AlwaysClamp);
|
|
|
|
ImGui::Separator();
|
|
|
|
|
2021-10-02 06:42:08 +02:00
|
|
|
char buffer[80]{};
|
2021-09-28 07:14:18 +02:00
|
|
|
auto changed = false;
|
|
|
|
if (ImGui::MenuItem("Set Default UPS/FPS"))
|
|
|
|
{
|
|
|
|
changed = true;
|
2021-10-09 16:28:30 +02:00
|
|
|
Options.UpdatesPerSecond = options::DefUps;
|
|
|
|
Options.FramesPerSecond = options::DefFps;
|
2021-09-28 07:14:18 +02:00
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::SliderInt("UPS", &Options.UpdatesPerSecond, options::MinUps, options::MaxUps, "%d",
|
|
|
|
ImGuiSliderFlags_AlwaysClamp))
|
2021-09-28 07:14:18 +02:00
|
|
|
{
|
|
|
|
changed = true;
|
2021-10-09 16:28:30 +02:00
|
|
|
Options.FramesPerSecond = std::min(Options.UpdatesPerSecond, Options.FramesPerSecond);
|
2021-09-28 07:14:18 +02:00
|
|
|
}
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::SliderInt("FPS", &Options.FramesPerSecond, options::MinFps, options::MaxFps, "%d",
|
|
|
|
ImGuiSliderFlags_AlwaysClamp))
|
2021-09-28 07:14:18 +02:00
|
|
|
{
|
|
|
|
changed = true;
|
2021-10-09 16:28:30 +02:00
|
|
|
Options.UpdatesPerSecond = std::max(Options.UpdatesPerSecond, Options.FramesPerSecond);
|
2021-09-28 07:14:18 +02:00
|
|
|
}
|
2021-10-02 06:42:08 +02:00
|
|
|
snprintf(buffer, sizeof buffer - 1, "Uncapped UPS (FPS ratio %02.02f)", UpdateToFrameRatio);
|
2021-10-09 16:28:30 +02:00
|
|
|
if (ImGui::MenuItem(buffer, nullptr, Options.UncappedUpdatesPerSecond))
|
2021-10-02 06:42:08 +02:00
|
|
|
{
|
2021-10-09 16:28:30 +02:00
|
|
|
Options.UncappedUpdatesPerSecond ^= true;
|
2021-10-02 06:42:08 +02:00
|
|
|
}
|
|
|
|
|
2021-09-28 07:14:18 +02:00
|
|
|
if (changed)
|
|
|
|
{
|
|
|
|
UpdateFrameRate();
|
|
|
|
}
|
2021-09-22 14:50:07 +02:00
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
ImGui::EndMenu();
|
2021-01-06 15:06:13 +01:00
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
|
|
|
|
if (ImGui::BeginMenu("Help"))
|
2021-01-06 15:06:13 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
#ifndef NDEBUG
|
2021-09-09 10:40:54 +02:00
|
|
|
if (ImGui::MenuItem("ImGui Demo", nullptr, ShowImGuiDemo))
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
ShowImGuiDemo ^= true;
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
#endif
|
2021-09-21 12:14:39 +02:00
|
|
|
if (ImGui::MenuItem("Sprite Viewer", nullptr, ShowSpriteViewer))
|
|
|
|
{
|
|
|
|
if (!ShowSpriteViewer && !single_step)
|
|
|
|
pause();
|
|
|
|
ShowSpriteViewer ^= true;
|
|
|
|
}
|
2021-11-11 12:30:56 +01:00
|
|
|
if (pb::cheat_mode && ImGui::MenuItem("Frame Times", nullptr, DispGRhistory))
|
|
|
|
{
|
|
|
|
DispGRhistory ^= true;
|
|
|
|
}
|
2021-10-05 15:48:13 +02:00
|
|
|
if (ImGui::BeginMenu("Cheats"))
|
|
|
|
{
|
|
|
|
if (ImGui::MenuItem("hidden test", nullptr, pb::cheat_mode))
|
|
|
|
pb::PushCheat("hidden test");
|
|
|
|
if (ImGui::MenuItem("1max"))
|
|
|
|
pb::PushCheat("1max");
|
|
|
|
if (ImGui::MenuItem("bmax", nullptr, control::table_unlimited_balls))
|
|
|
|
pb::PushCheat("bmax");
|
|
|
|
if (ImGui::MenuItem("gmax"))
|
|
|
|
pb::PushCheat("gmax");
|
|
|
|
if (ImGui::MenuItem("rmax"))
|
|
|
|
pb::PushCheat("rmax");
|
|
|
|
if (pb::FullTiltMode && ImGui::MenuItem("quote"))
|
|
|
|
pb::PushCheat("quote");
|
|
|
|
|
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::Separator();
|
2021-02-09 16:09:44 +01:00
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
if (ImGui::MenuItem("About Pinball"))
|
|
|
|
{
|
|
|
|
if (!single_step)
|
|
|
|
pause();
|
|
|
|
ShowAboutDialog = true;
|
|
|
|
}
|
|
|
|
ImGui::EndMenu();
|
2021-01-06 15:06:13 +01:00
|
|
|
}
|
2021-09-23 11:16:58 +02:00
|
|
|
if (DispFrameRate && !FpsDetails.empty())
|
|
|
|
if (ImGui::BeginMenu(FpsDetails.c_str()))
|
|
|
|
ImGui::EndMenu();
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::EndMainMenuBar();
|
|
|
|
}
|
|
|
|
|
|
|
|
a_dialog();
|
|
|
|
high_score::RenderHighScoreDialog();
|
2021-09-21 12:14:39 +02:00
|
|
|
if (ShowSpriteViewer)
|
|
|
|
render::SpriteViewer(&ShowSpriteViewer);
|
2021-10-01 08:05:38 +02:00
|
|
|
options::RenderControlDialog();
|
2021-11-11 12:30:56 +01:00
|
|
|
if (DispGRhistory)
|
|
|
|
RenderFrameTimeDialog();
|
2021-09-05 09:47:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int winmain::event_handler(const SDL_Event* event)
|
|
|
|
{
|
|
|
|
ImGui_ImplSDL2_ProcessEvent(event);
|
|
|
|
|
2021-10-17 17:18:29 +02:00
|
|
|
if (ImIO->WantCaptureMouse && !options::WaitingForInput())
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
2021-01-06 15:06:13 +01:00
|
|
|
if (mouse_down)
|
|
|
|
{
|
|
|
|
mouse_down = 0;
|
2021-09-05 09:47:05 +02:00
|
|
|
SDL_SetWindowGrab(MainWindow, SDL_FALSE);
|
2021-01-06 15:06:13 +01:00
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
switch (event->type)
|
2021-01-06 15:06:13 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
case SDL_MOUSEMOTION:
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
case SDL_MOUSEWHEEL:
|
|
|
|
return 1;
|
|
|
|
default: ;
|
|
|
|
}
|
|
|
|
}
|
2021-11-15 15:32:18 +01:00
|
|
|
if (ImIO->WantCaptureKeyboard && !options::WaitingForInput())
|
2021-09-05 09:47:05 +02:00
|
|
|
{
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
case SDL_KEYUP:
|
2021-11-15 15:32:18 +01:00
|
|
|
case SDL_CONTROLLERBUTTONDOWN:
|
|
|
|
case SDL_CONTROLLERBUTTONUP:
|
2021-09-05 09:47:05 +02:00
|
|
|
return 1;
|
|
|
|
default: ;
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
switch (event->type)
|
2020-11-06 14:56:32 +01:00
|
|
|
{
|
2021-08-27 12:29:41 +02:00
|
|
|
case SDL_QUIT:
|
|
|
|
end_pause();
|
2021-10-23 08:02:51 +02:00
|
|
|
bQuit = true;
|
2021-08-27 12:29:41 +02:00
|
|
|
fullscrn::shutdown();
|
|
|
|
return_value = 0;
|
|
|
|
return 0;
|
|
|
|
case SDL_KEYUP:
|
2021-10-17 17:18:29 +02:00
|
|
|
pb::InputUp({InputTypes::Keyboard, event->key.keysym.sym});
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
if (!event->key.repeat)
|
2021-10-17 17:18:29 +02:00
|
|
|
pb::InputDown({InputTypes::Keyboard, event->key.keysym.sym});
|
2021-08-27 12:29:41 +02:00
|
|
|
switch (event->key.keysym.sym)
|
|
|
|
{
|
|
|
|
case SDLK_ESCAPE:
|
2021-10-09 16:28:30 +02:00
|
|
|
if (Options.FullScreen)
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::Full_Screen);
|
2021-08-27 12:29:41 +02:00
|
|
|
SDL_MinimizeWindow(MainWindow);
|
|
|
|
break;
|
|
|
|
case SDLK_F2:
|
|
|
|
new_game();
|
|
|
|
break;
|
|
|
|
case SDLK_F3:
|
|
|
|
pause();
|
|
|
|
break;
|
|
|
|
case SDLK_F4:
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::Full_Screen);
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
|
|
|
case SDLK_F5:
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::Sounds);
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
|
|
|
case SDLK_F6:
|
2021-09-23 11:16:58 +02:00
|
|
|
options::toggle(Menu1::Music);
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
|
|
|
case SDLK_F8:
|
|
|
|
if (!single_step)
|
|
|
|
pause();
|
2021-10-01 08:05:38 +02:00
|
|
|
options::ShowControlDialog();
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
2021-09-29 06:09:16 +02:00
|
|
|
case SDLK_F9:
|
2021-09-29 03:17:05 +02:00
|
|
|
options::toggle(Menu1::Show_Menu);
|
|
|
|
break;
|
2021-08-27 12:29:41 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pb::cheat_mode)
|
|
|
|
break;
|
|
|
|
|
|
|
|
switch (event->key.keysym.sym)
|
|
|
|
{
|
2021-09-21 12:14:39 +02:00
|
|
|
case SDLK_g:
|
2021-11-11 12:30:56 +01:00
|
|
|
DispGRhistory ^= true;
|
|
|
|
break;
|
|
|
|
case SDLK_o:
|
|
|
|
{
|
|
|
|
auto plt = new ColorRgba[4 * 256];
|
|
|
|
auto pltPtr = &plt[10]; // first 10 entries are system colors hardcoded in display_palette()
|
|
|
|
for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8)
|
|
|
|
{
|
|
|
|
unsigned char blue = i2, redGreen = i2;
|
|
|
|
if (i2 > 255)
|
|
|
|
{
|
|
|
|
blue = 255;
|
|
|
|
redGreen = i1;
|
|
|
|
}
|
|
|
|
|
2021-11-13 07:00:58 +01:00
|
|
|
*pltPtr++ = ColorRgba{ blue, redGreen, redGreen, 0 };
|
2021-11-11 12:30:56 +01:00
|
|
|
}
|
|
|
|
gdrv::display_palette(plt);
|
|
|
|
delete[] plt;
|
|
|
|
}
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
|
|
|
case SDLK_y:
|
|
|
|
SDL_SetWindowTitle(MainWindow, "Pinball");
|
|
|
|
DispFrameRate = DispFrameRate == 0;
|
|
|
|
break;
|
|
|
|
case SDLK_F1:
|
|
|
|
pb::frame(10);
|
|
|
|
break;
|
|
|
|
case SDLK_F10:
|
2021-10-23 08:02:51 +02:00
|
|
|
single_step ^= true;
|
|
|
|
if (!single_step)
|
|
|
|
no_time_loss = true;
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
2020-11-06 14:56:32 +01:00
|
|
|
{
|
2021-10-17 17:18:29 +02:00
|
|
|
bool noInput = false;
|
|
|
|
switch (event->button.button)
|
2020-11-06 14:56:32 +01:00
|
|
|
{
|
2021-10-17 17:18:29 +02:00
|
|
|
case SDL_BUTTON_LEFT:
|
|
|
|
if (pb::cheat_mode)
|
|
|
|
{
|
|
|
|
mouse_down = 1;
|
|
|
|
last_mouse_x = event->button.x;
|
|
|
|
last_mouse_y = event->button.y;
|
|
|
|
SDL_SetWindowGrab(MainWindow, SDL_TRUE);
|
|
|
|
noInput = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2020-11-06 14:56:32 +01:00
|
|
|
}
|
2021-10-17 17:18:29 +02:00
|
|
|
|
|
|
|
if (!noInput)
|
|
|
|
pb::InputDown({InputTypes::Mouse, event->button.button});
|
2020-11-06 14:56:32 +01:00
|
|
|
}
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
{
|
2021-10-17 17:18:29 +02:00
|
|
|
bool noInput = false;
|
|
|
|
switch (event->button.button)
|
2021-08-27 12:29:41 +02:00
|
|
|
{
|
2021-10-17 17:18:29 +02:00
|
|
|
case SDL_BUTTON_LEFT:
|
|
|
|
if (mouse_down)
|
|
|
|
{
|
|
|
|
mouse_down = 0;
|
|
|
|
SDL_SetWindowGrab(MainWindow, SDL_FALSE);
|
|
|
|
noInput = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2021-08-27 12:29:41 +02:00
|
|
|
}
|
2021-10-17 17:18:29 +02:00
|
|
|
|
|
|
|
if (!noInput)
|
|
|
|
pb::InputUp({InputTypes::Mouse, event->button.button});
|
2021-08-27 12:29:41 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_WINDOWEVENT:
|
|
|
|
switch (event->window.event)
|
|
|
|
{
|
|
|
|
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
|
|
|
case SDL_WINDOWEVENT_TAKE_FOCUS:
|
|
|
|
case SDL_WINDOWEVENT_SHOWN:
|
2021-10-23 08:02:51 +02:00
|
|
|
activated = true;
|
2021-08-27 12:29:41 +02:00
|
|
|
Sound::Activate();
|
2021-10-09 16:28:30 +02:00
|
|
|
if (Options.Music && !single_step)
|
2021-09-29 16:53:49 +02:00
|
|
|
midi::play_pb_theme();
|
2021-10-23 08:02:51 +02:00
|
|
|
no_time_loss = true;
|
|
|
|
has_focus = true;
|
2021-08-27 12:29:41 +02:00
|
|
|
break;
|
|
|
|
case SDL_WINDOWEVENT_FOCUS_LOST:
|
|
|
|
case SDL_WINDOWEVENT_HIDDEN:
|
2021-10-23 08:02:51 +02:00
|
|
|
activated = false;
|
2021-08-27 12:29:41 +02:00
|
|
|
fullscrn::activate(0);
|
2021-10-09 16:28:30 +02:00
|
|
|
Options.FullScreen = false;
|
2021-08-27 12:29:41 +02:00
|
|
|
Sound::Deactivate();
|
|
|
|
midi::music_stop();
|
2021-10-23 08:02:51 +02:00
|
|
|
has_focus = false;
|
2021-08-27 12:29:41 +02:00
|
|
|
pb::loose_focus();
|
|
|
|
break;
|
2021-09-05 09:47:05 +02:00
|
|
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
2021-09-01 10:02:57 +02:00
|
|
|
case SDL_WINDOWEVENT_RESIZED:
|
|
|
|
fullscrn::window_size_changed();
|
|
|
|
break;
|
2021-08-27 12:29:41 +02:00
|
|
|
default: ;
|
|
|
|
}
|
|
|
|
break;
|
2021-10-17 17:18:29 +02:00
|
|
|
case SDL_JOYDEVICEADDED:
|
|
|
|
if (SDL_IsGameController(event->jdevice.which))
|
|
|
|
{
|
|
|
|
SDL_GameControllerOpen(event->jdevice.which);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_JOYDEVICEREMOVED:
|
|
|
|
{
|
|
|
|
SDL_GameController* controller = SDL_GameControllerFromInstanceID(event->jdevice.which);
|
|
|
|
if (controller)
|
|
|
|
{
|
|
|
|
SDL_GameControllerClose(controller);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_CONTROLLERBUTTONDOWN:
|
|
|
|
pb::InputDown({InputTypes::GameController, event->cbutton.button});
|
|
|
|
switch (event->cbutton.button)
|
|
|
|
{
|
|
|
|
case SDL_CONTROLLER_BUTTON_START:
|
|
|
|
pause();
|
|
|
|
break;
|
2021-11-01 07:09:19 +01:00
|
|
|
case SDL_CONTROLLER_BUTTON_BACK:
|
|
|
|
if (single_step)
|
|
|
|
{
|
|
|
|
SDL_Event event{ SDL_QUIT };
|
|
|
|
SDL_PushEvent(&event);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:;
|
2021-10-17 17:18:29 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_CONTROLLERBUTTONUP:
|
|
|
|
pb::InputUp({InputTypes::GameController, event->cbutton.button});
|
|
|
|
break;
|
2021-08-27 12:29:41 +02:00
|
|
|
default: ;
|
2020-11-06 14:56:32 +01:00
|
|
|
}
|
2021-08-27 12:29:41 +02:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int winmain::ProcessWindowMessages()
|
|
|
|
{
|
2021-09-29 16:53:49 +02:00
|
|
|
static auto idleWait = 0;
|
2021-08-27 12:29:41 +02:00
|
|
|
SDL_Event event;
|
|
|
|
if (has_focus && !single_step)
|
2020-11-06 14:56:32 +01:00
|
|
|
{
|
2021-09-29 16:53:49 +02:00
|
|
|
idleWait = static_cast<int>(TargetFrameTime.count());
|
2021-08-27 12:29:41 +02:00
|
|
|
while (SDL_PollEvent(&event))
|
|
|
|
{
|
|
|
|
if (!event_handler(&event))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2020-11-06 14:56:32 +01:00
|
|
|
}
|
2021-08-27 12:29:41 +02:00
|
|
|
|
2021-09-29 16:53:49 +02:00
|
|
|
// Progressively wait longer when transitioning to idle
|
|
|
|
idleWait = std::min(idleWait + static_cast<int>(TargetFrameTime.count()), 500);
|
|
|
|
if (SDL_WaitEventTimeout(&event, idleWait))
|
|
|
|
{
|
|
|
|
idleWait = static_cast<int>(TargetFrameTime.count());
|
|
|
|
return event_handler(&event);
|
|
|
|
}
|
|
|
|
return 1;
|
2020-11-05 16:44:34 +01:00
|
|
|
}
|
|
|
|
|
2020-11-07 16:41:14 +01:00
|
|
|
void winmain::memalloc_failure()
|
2020-11-05 16:44:34 +01:00
|
|
|
{
|
2020-12-02 18:12:34 +01:00
|
|
|
midi::music_stop();
|
|
|
|
Sound::Close();
|
2020-11-05 16:44:34 +01:00
|
|
|
char* caption = pinball::get_rc_string(170, 0);
|
|
|
|
char* text = pinball::get_rc_string(179, 0);
|
2021-09-06 15:27:58 +02:00
|
|
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, caption, text, MainWindow);
|
2021-09-09 10:40:54 +02:00
|
|
|
std::exit(1);
|
2020-11-05 16:44:34 +01:00
|
|
|
}
|
2020-11-07 16:41:14 +01:00
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
void winmain::a_dialog()
|
2020-11-07 16:41:14 +01:00
|
|
|
{
|
2021-09-05 09:47:05 +02:00
|
|
|
if (ShowAboutDialog == true)
|
|
|
|
{
|
|
|
|
ShowAboutDialog = false;
|
|
|
|
ImGui::OpenPopup("About");
|
|
|
|
}
|
2020-11-07 16:41:14 +01:00
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
bool unused_open = true;
|
|
|
|
if (ImGui::BeginPopupModal("About", &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted("3D Pinball for Windows - Space Cadet");
|
2021-09-23 11:16:58 +02:00
|
|
|
ImGui::TextUnformatted("Original game by Cinematronics, Microsoft");
|
|
|
|
ImGui::Separator();
|
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::TextUnformatted("Decompiled -> Ported to SDL");
|
2021-10-09 16:28:30 +02:00
|
|
|
ImGui::TextUnformatted("Version 2.0");
|
2021-09-23 11:16:58 +02:00
|
|
|
if (ImGui::SmallButton("Project home: https://github.com/k4zmu2a/SpaceCadetPinball"))
|
|
|
|
{
|
2021-09-25 15:52:19 +02:00
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
|
|
|
// Relatively new feature, skip with older SDL
|
2021-09-23 11:16:58 +02:00
|
|
|
SDL_OpenURL("https://github.com/k4zmu2a/SpaceCadetPinball");
|
2021-09-25 15:52:19 +02:00
|
|
|
#endif
|
2021-09-23 11:16:58 +02:00
|
|
|
}
|
2021-09-05 09:47:05 +02:00
|
|
|
ImGui::Separator();
|
2020-11-07 16:41:14 +01:00
|
|
|
|
2021-09-05 09:47:05 +02:00
|
|
|
if (ImGui::Button("Ok"))
|
|
|
|
{
|
|
|
|
ImGui::CloseCurrentPopup();
|
|
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
|
|
}
|
2020-11-07 16:41:14 +01:00
|
|
|
}
|
2020-12-02 18:12:34 +01:00
|
|
|
|
|
|
|
void winmain::end_pause()
|
|
|
|
{
|
|
|
|
if (single_step)
|
|
|
|
{
|
|
|
|
pb::pause_continue();
|
2021-10-23 08:02:51 +02:00
|
|
|
no_time_loss = true;
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void winmain::new_game()
|
|
|
|
{
|
|
|
|
end_pause();
|
|
|
|
pb::replay_level(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void winmain::pause()
|
|
|
|
{
|
|
|
|
pb::pause_continue();
|
2021-10-23 08:02:51 +02:00
|
|
|
no_time_loss = true;
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
|
|
|
|
2021-02-06 14:53:47 +01:00
|
|
|
void winmain::Restart()
|
|
|
|
{
|
|
|
|
restart = true;
|
2021-09-01 10:02:57 +02:00
|
|
|
SDL_Event event{SDL_QUIT};
|
|
|
|
SDL_PushEvent(&event);
|
2021-02-06 14:53:47 +01:00
|
|
|
}
|
2021-09-28 07:14:18 +02:00
|
|
|
|
|
|
|
void winmain::UpdateFrameRate()
|
|
|
|
{
|
|
|
|
// UPS >= FPS
|
2021-10-09 16:28:30 +02:00
|
|
|
auto fps = Options.FramesPerSecond, ups = Options.UpdatesPerSecond;
|
2021-09-28 07:14:18 +02:00
|
|
|
UpdateToFrameRatio = static_cast<double>(ups) / fps;
|
|
|
|
TargetFrameTime = DurationMs(1000.0 / ups);
|
|
|
|
}
|
2021-11-11 12:30:56 +01:00
|
|
|
|
|
|
|
void winmain::RenderFrameTimeDialog()
|
|
|
|
{
|
|
|
|
if (!gfr_display)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2{ 300, 70 });
|
|
|
|
if (ImGui::Begin("Frame Times", &DispGRhistory, ImGuiWindowFlags_NoScrollbar))
|
|
|
|
{
|
|
|
|
auto target = static_cast<float>(TargetFrameTime.count());
|
|
|
|
auto scale = 1 / (64 / 2 / target);
|
|
|
|
|
|
|
|
ImGui::Text("Target frame time:%03.04fms, 1px:%03.04fms", target, scale);
|
|
|
|
gfr_display->BlitToTexture();
|
|
|
|
auto region = ImGui::GetContentRegionAvail();
|
|
|
|
ImGui::Image(gfr_display->Texture, region);
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
ImGui::PopStyleVar();
|
|
|
|
}
|