mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
Add translations (#153)
* Add translations from v1 * Add font configuration (to be able to use non-latin languages) * translations: remove includes that are already in pch.h * translations: rename enums and avoid macros * Fix crash when the font file doesn't exist * translations: avoid u8 to avoid reencoding by MSVC MSVC will read the file as ASCII and reconvert characters as UTF-8, this will corrupt characters as the file is in fact already in UTF-8. * translations: remove NUMBER in enums * translations: handle non existing translations gracefuly (don't crash) Fallback to english if available, else return empty string * Testing pull collaboration. * Rollback: remove NUMBER in enums. * Get rid of namespace, use header instead. * Collapsed translated text struct and array. * Fixed build errors and warnings. * Simplified language list. * All new types, locals and globals should use CamelCase. * Removed unnecessary ImGui patch. * Rearranged TTextBox immediate mode draw. * Final touches: removed unused declaration in gdrv. Removed unused Msg entries and added new check. * Remove placeholder english texts from missing translations Co-authored-by: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com>
This commit is contained in:
parent
c1c74878df
commit
66a868083a
@ -38,6 +38,8 @@ set(SOURCE_FILES
|
||||
SpaceCadetPinball/control.h
|
||||
SpaceCadetPinball/EmbeddedData.cpp
|
||||
SpaceCadetPinball/EmbeddedData.h
|
||||
SpaceCadetPinball/font_selection.cpp
|
||||
SpaceCadetPinball/font_selection.h
|
||||
SpaceCadetPinball/fullscrn.cpp
|
||||
SpaceCadetPinball/fullscrn.h
|
||||
SpaceCadetPinball/gdrv.cpp
|
||||
@ -131,6 +133,8 @@ set(SOURCE_FILES
|
||||
SpaceCadetPinball/TPopupTarget.h
|
||||
SpaceCadetPinball/TRamp.cpp
|
||||
SpaceCadetPinball/TRamp.h
|
||||
SpaceCadetPinball/translations.cpp
|
||||
SpaceCadetPinball/translations.h
|
||||
SpaceCadetPinball/TRollover.cpp
|
||||
SpaceCadetPinball/TRollover.h
|
||||
SpaceCadetPinball/TSink.cpp
|
||||
|
@ -290,7 +290,7 @@ void TPinballTable::tilt(float time)
|
||||
{
|
||||
pinball::InfoTextBox->Clear();
|
||||
pinball::MissTextBox->Clear();
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(35, 0), -1.0);
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(Msg::STRING136), -1.0);
|
||||
loader::play_sound(SoundIndex3, nullptr, "TPinballTable1");
|
||||
TiltTimeoutTimer = timer::set(30.0, this, tilt_timeout);
|
||||
|
||||
@ -315,7 +315,7 @@ void TPinballTable::port_draw()
|
||||
|
||||
int TPinballTable::Message(int code, float value)
|
||||
{
|
||||
LPSTR rc_text;
|
||||
const char* rc_text;
|
||||
switch (code)
|
||||
{
|
||||
case 1000:
|
||||
@ -369,9 +369,9 @@ int TPinballTable::Message(int code, float value)
|
||||
LightGroup->Message(20, 0.0);
|
||||
Plunger->Message(1016, 0.0);
|
||||
if (Demo && Demo->ActiveFlag)
|
||||
rc_text = pinball::get_rc_string(30, 0);
|
||||
rc_text = pinball::get_rc_string(Msg::STRING131);
|
||||
else
|
||||
rc_text = pinball::get_rc_string(26, 0);
|
||||
rc_text = pinball::get_rc_string(Msg::STRING127);
|
||||
pinball::InfoTextBox->Display(rc_text, -1.0);
|
||||
if (Demo)
|
||||
Demo->Message(1014, 0.0);
|
||||
@ -466,11 +466,11 @@ int TPinballTable::Message(int code, float value)
|
||||
{
|
||||
if (PlayerCount <= 1)
|
||||
{
|
||||
char* textboxText;
|
||||
const char* textboxText;
|
||||
if (Demo->ActiveFlag)
|
||||
textboxText = pinball::get_rc_string(30, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING131);
|
||||
else
|
||||
textboxText = pinball::get_rc_string(26, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING127);
|
||||
pinball::InfoTextBox->Display(textboxText, -1.0);
|
||||
break;
|
||||
}
|
||||
@ -507,32 +507,32 @@ int TPinballTable::Message(int code, float value)
|
||||
component->Message(1020, static_cast<float>(nextPlayer));
|
||||
}
|
||||
|
||||
char* textboxText = nullptr;
|
||||
const char* textboxText = nullptr;
|
||||
switch (nextPlayer)
|
||||
{
|
||||
case 0:
|
||||
if (Demo->ActiveFlag)
|
||||
textboxText = pinball::get_rc_string(30, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING131);
|
||||
else
|
||||
textboxText = pinball::get_rc_string(26, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING127);
|
||||
break;
|
||||
case 1:
|
||||
if (Demo->ActiveFlag)
|
||||
textboxText = pinball::get_rc_string(31, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING132);
|
||||
else
|
||||
textboxText = pinball::get_rc_string(27, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING128);
|
||||
break;
|
||||
case 2:
|
||||
if (Demo->ActiveFlag)
|
||||
textboxText = pinball::get_rc_string(32, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING133);
|
||||
else
|
||||
textboxText = pinball::get_rc_string(28, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING129);
|
||||
break;
|
||||
case 3:
|
||||
if (Demo->ActiveFlag)
|
||||
textboxText = pinball::get_rc_string(33, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING134);
|
||||
else
|
||||
textboxText = pinball::get_rc_string(29, 0);
|
||||
textboxText = pinball::get_rc_string(Msg::STRING130);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -549,7 +549,7 @@ int TPinballTable::Message(int code, float value)
|
||||
case 1022:
|
||||
loader::play_sound(SoundIndex2, nullptr, "TPinballTable3");
|
||||
pinball::MissTextBox->Clear();
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(34, 0), -1.0);
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(Msg::STRING135), -1.0);
|
||||
EndGameTimeoutTimer = timer::set(3.0, this, EndGame_timeout);
|
||||
break;
|
||||
case 1024:
|
||||
@ -661,7 +661,7 @@ void TPinballTable::EndGame_timeout(int timerId, void* caller)
|
||||
if (table->Demo)
|
||||
table->Demo->Message(1022, 0.0);
|
||||
control::handler(67, pinball::MissTextBox);
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(24, 0), -1.0);
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(Msg::STRING125), -1.0);
|
||||
}
|
||||
|
||||
void TPinballTable::LightShow_timeout(int timerId, void* caller)
|
||||
|
@ -145,6 +145,43 @@ void TTextBox::Display(const char* text, float time)
|
||||
}
|
||||
}
|
||||
|
||||
void TTextBox::DrawImGui()
|
||||
{
|
||||
// Do nothing when using a font (the text will be rendered to VScreen in TTextBox::Draw)
|
||||
if (Font || !Message1)
|
||||
return;
|
||||
|
||||
char windowName[64];
|
||||
SDL_Rect rect;
|
||||
ImGuiWindowFlags window_flags =
|
||||
ImGuiWindowFlags_NoBackground |
|
||||
ImGuiWindowFlags_NoDecoration |
|
||||
ImGuiWindowFlags_NoSavedSettings |
|
||||
ImGuiWindowFlags_NoFocusOnAppearing |
|
||||
ImGuiWindowFlags_NoInputs;
|
||||
|
||||
rect.x = OffsetX;
|
||||
rect.y = OffsetY;
|
||||
rect.w = Width;
|
||||
rect.h = Height;
|
||||
|
||||
rect = fullscrn::GetScreenRectFromPinballRect(rect);
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(rect.x, rect.y));
|
||||
ImGui::SetNextWindowSize(ImVec2(rect.w, rect.h));
|
||||
|
||||
// Use the pointer to generate a window unique name per text box
|
||||
snprintf(windowName, sizeof(windowName), "TTextBox_%p", this);
|
||||
if (ImGui::Begin(windowName, nullptr, window_flags))
|
||||
{
|
||||
ImGui::SetWindowFontScale(fullscrn::GetScreenToPinballRatio());
|
||||
|
||||
// ToDo: centered text in FT
|
||||
ImGui::TextWrapped("%s", Message1->Text);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void TTextBox::Draw()
|
||||
{
|
||||
auto bmp = BgBmp;
|
||||
@ -189,13 +226,7 @@ void TTextBox::Draw()
|
||||
{
|
||||
if (!Font)
|
||||
{
|
||||
gdrv::grtext_draw_ttext_in_box(
|
||||
Message1->Text,
|
||||
render::vscreen->XPosition + OffsetX,
|
||||
render::vscreen->YPosition + OffsetY,
|
||||
Width,
|
||||
Height,
|
||||
255);
|
||||
// Immediate mode drawing using system font is handled by TTextBox::DrawImGui
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ public:
|
||||
int Message(int code, float value) override;
|
||||
void Clear();
|
||||
void Display(const char* text, float time);
|
||||
void DrawImGui();
|
||||
|
||||
private:
|
||||
struct LayoutResult
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "translations.h"
|
||||
|
||||
class TLight;
|
||||
class TSound;
|
||||
class TPinballTable;
|
||||
@ -66,7 +68,8 @@ public:
|
||||
static component_tag_base* simple_components[145];
|
||||
static int waiting_deployment_flag;
|
||||
static bool table_unlimited_balls;
|
||||
static int RankRcArray[9], MissionRcArray[17], mission_select_scores[17];
|
||||
static Msg RankRcArray[9], MissionRcArray[17];
|
||||
static int mission_select_scores[17];
|
||||
static component_tag_base *wormhole_tag_array1[3], *wormhole_tag_array2[3], *wormhole_tag_array3[3];
|
||||
|
||||
static void make_links(TPinballTable* table);
|
||||
|
50
SpaceCadetPinball/font_selection.cpp
Normal file
50
SpaceCadetPinball/font_selection.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "pch.h"
|
||||
#include "font_selection.h"
|
||||
|
||||
#include "options.h"
|
||||
#include "pinball.h"
|
||||
#include "score.h"
|
||||
#include "winmain.h"
|
||||
|
||||
static const char* popupName = "Font Selection";
|
||||
bool font_selection::ShowDialogFlag = false;
|
||||
char font_selection::DialogInputBuffer[512];
|
||||
|
||||
void font_selection::ShowDialog()
|
||||
{
|
||||
ShowDialogFlag = true;
|
||||
}
|
||||
|
||||
void font_selection::RenderDialog()
|
||||
{
|
||||
if (ShowDialogFlag == true)
|
||||
{
|
||||
strncpy(DialogInputBuffer, options::Options.FontFileName.c_str(), sizeof(DialogInputBuffer));
|
||||
ShowDialogFlag = false;
|
||||
if (!ImGui::IsPopupOpen(popupName))
|
||||
{
|
||||
ImGui::OpenPopup(popupName);
|
||||
}
|
||||
}
|
||||
|
||||
bool unused_open = true;
|
||||
if (ImGui::BeginPopupModal(popupName, &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
ImGui::Text("Font file to use: ");
|
||||
ImGui::SameLine();
|
||||
ImGui::InputText("", DialogInputBuffer, IM_ARRAYSIZE(DialogInputBuffer));
|
||||
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::HIGHSCORES_Ok)))
|
||||
{
|
||||
options::Options.FontFileName = DialogInputBuffer;
|
||||
ImGui::CloseCurrentPopup();
|
||||
winmain::Restart();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::HIGHSCORES_Cancel)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
11
SpaceCadetPinball/font_selection.h
Normal file
11
SpaceCadetPinball/font_selection.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
class font_selection
|
||||
{
|
||||
public:
|
||||
static void ShowDialog();
|
||||
static void RenderDialog();
|
||||
private:
|
||||
static bool ShowDialogFlag;
|
||||
static char DialogInputBuffer[512];
|
||||
};
|
@ -140,3 +140,21 @@ void fullscrn::window_size_changed()
|
||||
width - offset2X, height - offset2Y
|
||||
};
|
||||
}
|
||||
|
||||
SDL_Rect fullscrn::GetScreenRectFromPinballRect(SDL_Rect rect)
|
||||
{
|
||||
SDL_Rect converted_rect;
|
||||
|
||||
converted_rect.x = rect.x * render::DestinationRect.w / render::vscreen->Width + render::DestinationRect.x;
|
||||
converted_rect.y = rect.y * render::DestinationRect.h / render::vscreen->Height + render::DestinationRect.y;
|
||||
|
||||
converted_rect.w = rect.w * render::DestinationRect.w / render::vscreen->Width;
|
||||
converted_rect.h = rect.h * render::DestinationRect.h / render::vscreen->Height;
|
||||
|
||||
return converted_rect;
|
||||
}
|
||||
|
||||
float fullscrn::GetScreenToPinballRatio()
|
||||
{
|
||||
return (float) render::DestinationRect.w / render::vscreen->Width;
|
||||
}
|
@ -28,6 +28,8 @@ public:
|
||||
static void SetResolution(int value);
|
||||
static int GetMaxResolution();
|
||||
static void window_size_changed();
|
||||
static SDL_Rect GetScreenRectFromPinballRect(SDL_Rect rect);
|
||||
static float GetScreenToPinballRatio();
|
||||
private :
|
||||
static int resolution;
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
#include "pb.h"
|
||||
#include "score.h"
|
||||
#include "winmain.h"
|
||||
#include "TTextBox.h"
|
||||
#include "fullscrn.h"
|
||||
#include "pinball.h"
|
||||
|
||||
ColorRgba gdrv::current_palette[256]{};
|
||||
|
||||
@ -269,8 +272,15 @@ void gdrv::ScrollBitmapHorizontal(gdrv_bitmap8* bmp, int xStart)
|
||||
}
|
||||
|
||||
|
||||
void gdrv::grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6)
|
||||
void gdrv::grtext_draw_ttext_in_box()
|
||||
{
|
||||
for (const auto textBox : { pinball::InfoTextBox, pinball::MissTextBox })
|
||||
{
|
||||
if (textBox)
|
||||
{
|
||||
textBox->DrawImGui();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gdrv::ApplyPalette(gdrv_bitmap8& bmp)
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
|
||||
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff);
|
||||
static void ScrollBitmapHorizontal(gdrv_bitmap8* bmp, int xStart);
|
||||
static void grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6);
|
||||
static void grtext_draw_ttext_in_box();
|
||||
static void ApplyPalette(gdrv_bitmap8& bmp);
|
||||
static void CreatePreview(gdrv_bitmap8& bmp);
|
||||
private:
|
||||
|
@ -121,7 +121,7 @@ void high_score::RenderHighScoreDialog()
|
||||
if (ShowDialog == true)
|
||||
{
|
||||
ShowDialog = false;
|
||||
if (!ImGui::IsPopupOpen("High Scores"))
|
||||
if (!ImGui::IsPopupOpen(pinball::get_rc_string(Msg::HIGHSCORES_Caption)))
|
||||
{
|
||||
dlg_enter_name = false;
|
||||
while (!ScoreQueue.empty())
|
||||
@ -140,19 +140,19 @@ void high_score::RenderHighScoreDialog()
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::OpenPopup("High Scores");
|
||||
ImGui::OpenPopup(pinball::get_rc_string(Msg::HIGHSCORES_Caption));
|
||||
}
|
||||
}
|
||||
|
||||
bool unused_open = true;
|
||||
if (ImGui::BeginPopupModal("High Scores", &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
if (ImGui::BeginPopupModal(pinball::get_rc_string(Msg::HIGHSCORES_Caption), &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
if (ImGui::BeginTable("table1", 3, ImGuiTableFlags_Borders))
|
||||
{
|
||||
char buf[36];
|
||||
ImGui::TableSetupColumn("Rank");
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableSetupColumn("Score");
|
||||
ImGui::TableSetupColumn(pinball::get_rc_string(Msg::HIGHSCORES_Rank));
|
||||
ImGui::TableSetupColumn(pinball::get_rc_string(Msg::HIGHSCORES_Name));
|
||||
ImGui::TableSetupColumn(pinball::get_rc_string(Msg::HIGHSCORES_Score));
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (int offset = 0, row = 0; row < 5; row++)
|
||||
@ -184,7 +184,7 @@ void high_score::RenderHighScoreDialog()
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Ok"))
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::HIGHSCORES_Ok)))
|
||||
{
|
||||
if (dlg_enter_name)
|
||||
{
|
||||
@ -194,23 +194,23 @@ void high_score::RenderHighScoreDialog()
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel"))
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::HIGHSCORES_Cancel)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Clear"))
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::HIGHSCORES_Clear)))
|
||||
ImGui::OpenPopup("Confirm");
|
||||
if (ImGui::BeginPopupModal("Confirm", nullptr, ImGuiWindowFlags_MenuBar))
|
||||
{
|
||||
ImGui::TextUnformatted(pinball::get_rc_string(40, 0));
|
||||
if (ImGui::Button("OK", ImVec2(120, 0)))
|
||||
ImGui::TextUnformatted(pinball::get_rc_string(Msg::STRING141));
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::HIGHSCORES_Ok), ImVec2(120, 0)))
|
||||
{
|
||||
clear_table();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SetItemDefaultFocus();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel", ImVec2(120, 0)))
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::HIGHSCORES_Cancel), ImVec2(120, 0)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
@ -220,7 +220,7 @@ void high_score::RenderHighScoreDialog()
|
||||
ImGui::EndPopup();
|
||||
|
||||
// Reenter dialog for the next score in the queue
|
||||
if (!ImGui::IsPopupOpen("High Scores") && !ScoreQueue.empty())
|
||||
if (!ImGui::IsPopupOpen(pinball::get_rc_string(Msg::HIGHSCORES_Caption)) && !ScoreQueue.empty())
|
||||
{
|
||||
ShowDialog = true;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "fullscrn.h"
|
||||
#include "midi.h"
|
||||
#include "pinball.h"
|
||||
#include "render.h"
|
||||
#include "Sound.h"
|
||||
#include "winmain.h"
|
||||
@ -18,12 +19,12 @@ bool options::ShowDialog = false;
|
||||
GameInput* options::ControlWaitingForInput = nullptr;
|
||||
const ControlRef options::Controls[6]
|
||||
{
|
||||
{"Left Flipper", RebindControls.LeftFlipper},
|
||||
{"Right Flipper", RebindControls.RightFlipper},
|
||||
{"Left Table Bump", RebindControls.LeftTableBump},
|
||||
{"Right Table Bump", RebindControls.RightTableBump},
|
||||
{"Bottom Table Bump", RebindControls.BottomTableBump},
|
||||
{"Plunger", RebindControls.Plunger},
|
||||
{Msg::KEYMAPPER_FlipperL, RebindControls.LeftFlipper},
|
||||
{Msg::KEYMAPPER_FlipperR, RebindControls.RightFlipper},
|
||||
{Msg::KEYMAPPER_BumpLeft, RebindControls.LeftTableBump},
|
||||
{Msg::KEYMAPPER_BumpRight, RebindControls.RightTableBump},
|
||||
{Msg::KEYMAPPER_BumpBottom, RebindControls.BottomTableBump},
|
||||
{Msg::KEYMAPPER_Plunger, RebindControls.Plunger},
|
||||
};
|
||||
|
||||
|
||||
@ -113,6 +114,8 @@ void options::InitPrimary()
|
||||
Options.DebugOverlayCollisionMask = get_int("Debug Overlay Collision Mask", true);
|
||||
Options.DebugOverlaySprites = get_int("Debug Overlay Sprites", true);
|
||||
Options.DebugOverlaySounds = get_int("Debug Overlay Sounds", true);
|
||||
translations::SetCurrentLanguage(get_string("Language", translations::GetCurrentLanguage()->ShortName).c_str());
|
||||
Options.FontFileName = get_string("FontFileName", "");
|
||||
}
|
||||
|
||||
void options::InitSecondary()
|
||||
@ -160,7 +163,9 @@ void options::uninit()
|
||||
set_int("Debug Overlay Ball Edges", Options.DebugOverlayBallEdges);
|
||||
set_int("Debug Overlay Collision Mask", Options.DebugOverlayCollisionMask);
|
||||
set_int("Debug Overlay Sprites", Options.DebugOverlaySprites);
|
||||
get_int("Debug Overlay Sounds", Options.DebugOverlaySounds);
|
||||
set_int("Debug Overlay Sounds", Options.DebugOverlaySounds);
|
||||
set_string("Language", translations::GetCurrentLanguage()->ShortName);
|
||||
set_string("FontFileName", Options.FontFileName.c_str());
|
||||
}
|
||||
|
||||
|
||||
@ -339,18 +344,16 @@ void options::RenderControlDialog()
|
||||
return;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2{550, 450});
|
||||
if (ImGui::Begin("3D Pinball: Player Controls", &ShowDialog))
|
||||
if (ImGui::Begin(pinball::get_rc_string(Msg::KEYMAPPER_Caption), &ShowDialog))
|
||||
{
|
||||
ImGui::TextUnformatted("Instructions");
|
||||
ImGui::TextUnformatted(pinball::get_rc_string(Msg::KEYMAPPER_Groupbox2));
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::TextWrapped(
|
||||
"To change game controls, click the control button, press the new key, and then choose OK.");
|
||||
ImGui::TextWrapped(
|
||||
"To restore 3D Pinball to its original settings, choose Default, and then choose OK.");
|
||||
ImGui::TextWrapped("%s", pinball::get_rc_string(Msg::KEYMAPPER_Help1));
|
||||
ImGui::TextWrapped("%s", pinball::get_rc_string(Msg::KEYMAPPER_Help2));
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::TextUnformatted("Control Options");
|
||||
ImGui::TextUnformatted(pinball::get_rc_string(Msg::KEYMAPPER_Groupbox1));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{5, 10});
|
||||
if (ImGui::BeginTable("Controls", 4, ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders))
|
||||
@ -366,7 +369,7 @@ void options::RenderControlDialog()
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{0.5, 0, 0, 1});
|
||||
if (ImGui::Button(row.Name))
|
||||
if (ImGui::Button(pinball::get_rc_string(row.NameStringId)))
|
||||
{
|
||||
for (auto i = 0u; i <= 2; i++)
|
||||
row.Option[i] = {};
|
||||
@ -419,20 +422,20 @@ void options::RenderControlDialog()
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("OK"))
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::KEYMAPPER_Ok)))
|
||||
{
|
||||
Options.Key = RebindControls;
|
||||
ShowDialog = false;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel"))
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::KEYMAPPER_Cancel)))
|
||||
{
|
||||
ShowDialog = false;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Default"))
|
||||
if (ImGui::Button(pinball::get_rc_string(Msg::KEYMAPPER_Default)))
|
||||
{
|
||||
RebindControls = Options.KeyDft;
|
||||
ControlWaitingForInput = nullptr;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "translations.h"
|
||||
|
||||
enum class Menu1:int
|
||||
{
|
||||
New_Game = 101,
|
||||
@ -90,11 +92,12 @@ struct optionsStruct
|
||||
bool DebugOverlayCollisionMask;
|
||||
bool DebugOverlaySprites;
|
||||
bool DebugOverlaySounds;
|
||||
std::string FontFileName;
|
||||
};
|
||||
|
||||
struct ControlRef
|
||||
{
|
||||
const char* Name;
|
||||
Msg NameStringId;
|
||||
GameInput (&Option)[3];
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ int pb::init()
|
||||
record_table = partman::load_records(dataFilePath.c_str(), FullTiltMode);
|
||||
|
||||
auto useBmpFont = 0;
|
||||
pinball::get_rc_int(158, &useBmpFont);
|
||||
pinball::get_rc_int(Msg::STRING258, &useBmpFont);
|
||||
if (useBmpFont)
|
||||
score::load_msg_font("pbmsg_ft");
|
||||
|
||||
@ -124,7 +124,7 @@ void pb::SelectDatFile(const std::vector<const char*>& dataSearchPaths)
|
||||
std::string datFileNames[3]
|
||||
{
|
||||
"CADET.DAT",
|
||||
options::get_string("Pinball Data", pinball::get_rc_string(168, 0)),
|
||||
options::get_string("Pinball Data", pinball::get_rc_string(Msg::STRING268)),
|
||||
"DEMO.DAT",
|
||||
};
|
||||
|
||||
@ -219,7 +219,7 @@ void pb::toggle_demo()
|
||||
MainTable->Message(1024, 0.0);
|
||||
mode_change(GameModes::GameOver);
|
||||
pinball::MissTextBox->Clear();
|
||||
auto text = pinball::get_rc_string(24, 0);
|
||||
auto text = pinball::get_rc_string(Msg::STRING125);
|
||||
pinball::InfoTextBox->Display(text, -1.0);
|
||||
}
|
||||
else
|
||||
@ -288,7 +288,7 @@ void pb::frame(float dtMilliSec)
|
||||
{
|
||||
if (nudge::nudge_count > 0.5f)
|
||||
{
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(25, 0), 2.0);
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(Msg::STRING126), 2.0);
|
||||
}
|
||||
if (nudge::nudge_count > 1.0f)
|
||||
MainTable->tilt(time_now);
|
||||
@ -366,7 +366,7 @@ void pb::pause_continue()
|
||||
{
|
||||
if (MainTable)
|
||||
MainTable->Message(1008, time_now);
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(22, 0), -1.0);
|
||||
pinball::InfoTextBox->Display(pinball::get_rc_string(Msg::STRING123), -1.0);
|
||||
midi::music_stop();
|
||||
Sound::Deactivate();
|
||||
}
|
||||
@ -376,17 +376,17 @@ void pb::pause_continue()
|
||||
MainTable->Message(1009, 0.0);
|
||||
if (!demo_mode)
|
||||
{
|
||||
char* text;
|
||||
const char* text;
|
||||
float textTime;
|
||||
if (game_mode == GameModes::GameOver)
|
||||
{
|
||||
textTime = -1.0;
|
||||
text = pinball::get_rc_string(24, 0);
|
||||
text = pinball::get_rc_string(Msg::STRING125);
|
||||
}
|
||||
else
|
||||
{
|
||||
textTime = 5.0;
|
||||
text = pinball::get_rc_string(23, 0);
|
||||
text = pinball::get_rc_string(Msg::STRING124);
|
||||
}
|
||||
pinball::InfoTextBox->Display(text, textTime);
|
||||
}
|
||||
@ -481,7 +481,7 @@ void pb::InputDown(GameInput input)
|
||||
case 'h':
|
||||
{
|
||||
high_score_struct entry{ {0}, 1000000000 };
|
||||
strncpy(entry.Name, pinball::get_rc_string(26, 0), sizeof entry.Name - 1);
|
||||
strncpy(entry.Name, pinball::get_rc_string(Msg::STRING127), sizeof entry.Name - 1);
|
||||
high_score::show_and_set_high_score_dialog({ entry, 1 });
|
||||
break;
|
||||
}
|
||||
@ -550,7 +550,16 @@ void pb::end_game()
|
||||
if (position >= 0)
|
||||
{
|
||||
high_score_struct entry{ {0}, scores[i] };
|
||||
strncpy(entry.Name, pinball::get_rc_string(scoreIndex[i] + 26, 0), sizeof entry.Name - 1);
|
||||
const char* playerName = "Player";
|
||||
|
||||
switch(scoreIndex[i]) {
|
||||
case 0: playerName = pinball::get_rc_string(Msg::STRING127); break;
|
||||
case 1: playerName = pinball::get_rc_string(Msg::STRING128); break;
|
||||
case 2: playerName = pinball::get_rc_string(Msg::STRING129); break;
|
||||
case 3: playerName = pinball::get_rc_string(Msg::STRING130); break;
|
||||
}
|
||||
|
||||
strncpy(entry.Name, playerName, sizeof entry.Name - 1);
|
||||
high_score::show_and_set_high_score_dialog({ entry, -1 });
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
#include <initializer_list>
|
||||
//#include <array>
|
||||
|
||||
#define SDL_MAIN_HANDLED
|
||||
|
@ -1,219 +1,13 @@
|
||||
#include "pch.h"
|
||||
#include "pinball.h"
|
||||
#include "translations.h"
|
||||
#include "winmain.h"
|
||||
|
||||
// Todo: load translations from file
|
||||
std::map<uint32_t, LPCSTR> rc_strings
|
||||
int LoadStringAlt(Msg uID, LPSTR lpBuffer, int cchBufferMax)
|
||||
{
|
||||
{0, "Replay Awarded"},
|
||||
{1, "Ball Locked"},
|
||||
{2, "Center Post\n%ld"},
|
||||
{3, "Bonus Awarded\n%ld"},
|
||||
{4, "Bonus Activated"},
|
||||
{5, "Weapons Upgraded"},
|
||||
{6, "Engine Upgraded"},
|
||||
{7, "Bonus up 1 Million"},
|
||||
{8, "Extra Ball Available\n%ld"},
|
||||
{9, "Extra Ball"},
|
||||
{10, "Reflex Shot Award\n%ld"},
|
||||
{11, "Final Battle Won"},
|
||||
{12, "Hyperspace Bonus\n%ld"},
|
||||
{13, "Hyperspace Bonus Available"},
|
||||
{14, "Jackpot Awarded\n%ld"},
|
||||
{15, "Jackpot Activated"},
|
||||
{16, "Multiball"},
|
||||
{17, "Ramp Bonus Awarded"},
|
||||
{18, "Light Added"},
|
||||
{19, "Ramp Bonus On"},
|
||||
{20, "Light Reset Off"},
|
||||
{21, "Skill Shot\n%ld"},
|
||||
{22, "Game Paused\nF3 to Resume"},
|
||||
{23, "Continue Play"},
|
||||
{24, "F2 Starts New Game"},
|
||||
{25, "Careful..."},
|
||||
{26, "Player 1"},
|
||||
{27, "Player 2"},
|
||||
{28, "Player 3"},
|
||||
{29, "Player 4"},
|
||||
{30, "Demo\nPlayer 1"},
|
||||
{31, "Demo\nPlayer 2"},
|
||||
{32, "Demo\nPlayer 3"},
|
||||
{33, "Demo\nPlayer 4"},
|
||||
{34, "Game Over"},
|
||||
{35, "TILT!"},
|
||||
{36, "This program requires an 80386 or later CPU."},
|
||||
{37, "80386 Required"},
|
||||
{38, "3D Pinball for Windows - Space Cadet"},
|
||||
{
|
||||
39,
|
||||
"One or more of the player controls is set to the same key,\nfor best performance use unique keys for each control."
|
||||
},
|
||||
{40, "Clear High Scores?"},
|
||||
{41, "Confirm"},
|
||||
{42, "WAVEMIX.INF is missing - it must be in the pinball directory!"},
|
||||
{43, "Warning:"},
|
||||
{44, "Ship Re-Fueled"},
|
||||
{45, "Gravity Well"},
|
||||
{46, "Time Warp Forward"},
|
||||
{47, "Time Warp Backward"},
|
||||
{48, "Maelstrom!"},
|
||||
{49, "Wormhole"},
|
||||
{50, "Awaiting Deployment"},
|
||||
{51, "Flags Upgraded"},
|
||||
{52, "Bonus Hold"},
|
||||
{53, "Level One Commendation"},
|
||||
{54, "Level Two Commendation"},
|
||||
{55, "Level Three Commendation"},
|
||||
{56, "Field Multiplier 2x"},
|
||||
{57, "Field Multiplier 3x"},
|
||||
{58, "Field Multiplier 5x"},
|
||||
{59, "Field Multiplier 10x"},
|
||||
{60, "Target Practice"},
|
||||
{61, "Launch Training"},
|
||||
{62, "Re-Entry Training"},
|
||||
{63, "Science"},
|
||||
{64, "Stray Comet"},
|
||||
{65, "Black Hole"},
|
||||
{66, "Space Radiation"},
|
||||
{67, "Bug Hunt"},
|
||||
{68, "Alien Menace"},
|
||||
{69, "Rescue"},
|
||||
{70, "Satellite Retrieval"},
|
||||
{71, "Recon"},
|
||||
{72, "Doomsday Machine"},
|
||||
{73, "Cosmic Plague"},
|
||||
{74, "Secret"},
|
||||
{75, "Time Warp"},
|
||||
{76, "Maelstrom"},
|
||||
{77, "Mission Accepted\n%ld"},
|
||||
{78, "Mission Completed\n%ld"},
|
||||
{79, "%s Mission Selected"},
|
||||
{80, "Black Hole\n%ld"},
|
||||
{81, "Gravity Normalized\n%ld"},
|
||||
{82, "Gravity Well\n%ld"},
|
||||
{83, "Promotion to %s"},
|
||||
{84, "Cadet"},
|
||||
{85, "Ensign"},
|
||||
{86, "Lieutenant"},
|
||||
{87, "Captain"},
|
||||
{88, "Lt Commander"},
|
||||
{89, "Commander"},
|
||||
{90, "Commodore"},
|
||||
{91, "Admiral"},
|
||||
{92, "Fleet Admiral"},
|
||||
{93, "Wormhole Opened"},
|
||||
{94, "Crash Bonus\n%ld"},
|
||||
{95, "Replay Ball"},
|
||||
{96, "Re-Deploy"},
|
||||
{97, "Player 1 Shoot Again"},
|
||||
{98, "Player 2 Shoot Again"},
|
||||
{99, "Player 3 Shoot Again"},
|
||||
{100, "Player 4 Shoot Again"},
|
||||
{
|
||||
101,
|
||||
"This 3D Pinball Table was created for Microsoft by Maxis.\nFor more information call (800)-336-2947\n(US and Canadian customers only).\nCopyright (c) 1995 Maxis."
|
||||
},
|
||||
{102, "3D Pinball Table created for Microsoft by Maxis. Copyright (c) 1995 Maxis."},
|
||||
{103, "About 3D Pinball"},
|
||||
{104, "Hit Mission Targets To Select Mission"},
|
||||
{105, "Re-Fuel Ship"},
|
||||
{106, "Launch Ramp To Accept %s Mission"},
|
||||
{107, "Attack Bumpers Hits\nLeft: %d"},
|
||||
{108, "Target Training Passed"},
|
||||
{109, "Mission Aborted"},
|
||||
{110, "Launches Left: %d"},
|
||||
{111, "Launch Training Passed"},
|
||||
{112, "Re-Entries Left: %d"},
|
||||
{113, "Re-Entry Training Passed"},
|
||||
{114, "Drop Targets\nLeft: %d"},
|
||||
{115, "Science Mission Completed"},
|
||||
{116, "Warning -- Low Fuel"},
|
||||
{117, "Fill Right Hazard Banks"},
|
||||
{118, "Hyperspace Launch"},
|
||||
{119, "Comet Destroyed"},
|
||||
{120, "Enter Wormhole"},
|
||||
{121, "Radiation Eliminated"},
|
||||
{122, "Upgrade Launch Bumpers"},
|
||||
{123, "Enter Black Hole"},
|
||||
{124, "Black Hole Eliminated"},
|
||||
{125, "Targets\nLeft: %d"},
|
||||
{126, "Xenomorphs Destroyed"},
|
||||
{127, "Upgrade Flags"},
|
||||
{128, "Hyperspace Launch"},
|
||||
{129, "Survivors Rescued"},
|
||||
{130, "Aliens Repelled"},
|
||||
{131, "Hit Fuel Targets"},
|
||||
{132, "Remote Attack Bumper Hits\nLeft: %d"},
|
||||
{133, "Satellite Repaired"},
|
||||
{134, "Lane Passes\nLeft: %d"},
|
||||
{135, "Shoot Ball Up Fuel Chute"},
|
||||
{136, "Survey Complete"},
|
||||
{137, "Out Lane Passes\nLeft: %d"},
|
||||
{138, "Doomsday Machine Destroyed"},
|
||||
{139, "Roll Flags: %d"},
|
||||
{140, "Hit Space Warp Rollover"},
|
||||
{141, "Plague Eliminated"},
|
||||
{142, "Hit Yellow Wormhole"},
|
||||
{143, "Hit Red Wormhole"},
|
||||
{144, "Hit Green Wormhole"},
|
||||
{145, "Plans Recovered"},
|
||||
{146, "Rebound Hits\nLeft: %d"},
|
||||
{147, "Hit Hyperspace Chute or Launch Ramp"},
|
||||
{148, "Drop Target Hits\nLeft: %d"},
|
||||
{149, "Spot Target Hits\nLeft: %d"},
|
||||
{150, "Lanes Passes\nLeft: %d"},
|
||||
{151, "Shoot Ball Up Fuel Chute"},
|
||||
{152, "Hit Launch Ramp"},
|
||||
{153, "Hit Flags"},
|
||||
{154, "Hit Worm Hole"},
|
||||
{155, "Hyperspace Chute to Maelstrom"},
|
||||
{156, "pinball.mid"},
|
||||
{158, "1 UseBitmapFont"},
|
||||
{159, "90 Left Flipper Key"},
|
||||
{160, "191 Right Flipper Key"},
|
||||
{161, "32 Plunger Key"},
|
||||
{162, "88 Bump Left Key"},
|
||||
{163, "190 Bump Right Key"},
|
||||
{164, "38 Bump Bottom Key"},
|
||||
{165, "Software\\Microsoft\\Plus!\\Pinball"},
|
||||
{166, "SpaceCadet"},
|
||||
{167, "1c7c22a0-9576-11ce-bf80-444553540000"},
|
||||
{168, "PINBALL.DAT"},
|
||||
{169, "Space Cadet"},
|
||||
{170, "Error:"},
|
||||
{171, "Unable to find other tables."},
|
||||
{172, "3D Pinball\nSpace Cadet"},
|
||||
{173, "Promotion to %s"},
|
||||
{174, "Demotion to %s"},
|
||||
{175, "Upgrade Attack Bumpers"},
|
||||
{176, "Fill Left Hazard Banks"},
|
||||
{177, "HIGH SCORE"},
|
||||
{178, "pinball.chm"},
|
||||
{179, "Not enough memory to run 3D Pinball."},
|
||||
{180, "Player 1's Score\n%ld"},
|
||||
{181, "Player 2's Score\n%ld"},
|
||||
{182, "Player 3's Score\n%ld"},
|
||||
{183, "Player 4's Score\n%ld"},
|
||||
{184, "High Score 1\n%ld"},
|
||||
{185, "High Score 2\n%ld"},
|
||||
{186, "High Score 3\n%ld"},
|
||||
{187, "High Score 4\n%ld"},
|
||||
{188, "High Score 5\n%ld"},
|
||||
{189, "255 255 255 (R G B default font color)"},
|
||||
{2030, "Use Maximum Resolution (640 x 480)"},
|
||||
{2031, "Use Maximum Resolution (800 x 600)"},
|
||||
{2032, "Use Maximum Resolution (1024 x 768)"}
|
||||
};
|
||||
const char* text = translations::GetTranslation(uID);
|
||||
|
||||
int LoadStringAlt(uint32_t uID, LPSTR lpBuffer, int cchBufferMax)
|
||||
{
|
||||
auto str = rc_strings.find(uID);
|
||||
if (str == rc_strings.end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy(lpBuffer, str->second, cchBufferMax);
|
||||
strncpy(lpBuffer, text, cchBufferMax);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -226,17 +20,18 @@ int pinball::LeftShift = -1;
|
||||
int pinball::RightShift = -1;
|
||||
std::string pinball::BasePath;
|
||||
|
||||
char* pinball::get_rc_string(int uID, int a2)
|
||||
char* pinball::get_rc_string(Msg uID)
|
||||
{
|
||||
char* result = &getRcBuffer[256 * rc_string_slot];
|
||||
if (!LoadStringAlt(uID, &getRcBuffer[256 * rc_string_slot], 255))
|
||||
*result = 0;
|
||||
|
||||
if (++rc_string_slot >= 6)
|
||||
rc_string_slot = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int pinball::get_rc_int(int uID, int* dst)
|
||||
int pinball::get_rc_int(Msg uID, int* dst)
|
||||
{
|
||||
char buffer[255];
|
||||
int result = LoadStringAlt(uID, buffer, 255);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "translations.h"
|
||||
|
||||
class TTextBox;
|
||||
|
||||
class pinball
|
||||
@ -12,8 +14,8 @@ public:
|
||||
static int LeftShift;
|
||||
static std::string BasePath;
|
||||
|
||||
static char* get_rc_string(int uID, int a2);
|
||||
static int get_rc_int(int uID, int* dst);
|
||||
static char* get_rc_string(Msg uID);
|
||||
static int get_rc_int(Msg uID, int* dst);
|
||||
static std::string make_path_name(const std::string& fileName);
|
||||
private:
|
||||
static char getRcBuffer[256 * 6];
|
||||
|
7100
SpaceCadetPinball/translations.cpp
Normal file
7100
SpaceCadetPinball/translations.cpp
Normal file
File diff suppressed because it is too large
Load Diff
361
SpaceCadetPinball/translations.h
Normal file
361
SpaceCadetPinball/translations.h
Normal file
@ -0,0 +1,361 @@
|
||||
#pragma once
|
||||
|
||||
enum class Msg : int
|
||||
{
|
||||
Min = 0,
|
||||
STRING101 = 0,
|
||||
STRING102,
|
||||
STRING103,
|
||||
STRING104,
|
||||
STRING105,
|
||||
STRING106,
|
||||
STRING107,
|
||||
STRING108,
|
||||
STRING109,
|
||||
STRING110,
|
||||
STRING111,
|
||||
STRING112,
|
||||
STRING113,
|
||||
STRING114,
|
||||
STRING115,
|
||||
STRING116,
|
||||
STRING117,
|
||||
STRING118,
|
||||
STRING119,
|
||||
STRING120,
|
||||
STRING121,
|
||||
STRING122,
|
||||
STRING123,
|
||||
STRING124,
|
||||
STRING125,
|
||||
STRING126,
|
||||
STRING127,
|
||||
STRING128,
|
||||
STRING129,
|
||||
STRING130,
|
||||
STRING131,
|
||||
STRING132,
|
||||
STRING133,
|
||||
STRING134,
|
||||
STRING135,
|
||||
STRING136,
|
||||
STRING137,
|
||||
STRING138,
|
||||
STRING139,
|
||||
STRING140,
|
||||
STRING141,
|
||||
STRING142,
|
||||
STRING143,
|
||||
STRING144,
|
||||
STRING145,
|
||||
STRING146,
|
||||
STRING147,
|
||||
STRING148,
|
||||
STRING149,
|
||||
STRING150,
|
||||
STRING151,
|
||||
STRING152,
|
||||
STRING153,
|
||||
STRING154,
|
||||
STRING155,
|
||||
STRING156,
|
||||
STRING157,
|
||||
STRING158,
|
||||
STRING159,
|
||||
STRING160,
|
||||
STRING161,
|
||||
STRING162,
|
||||
STRING163,
|
||||
STRING164,
|
||||
STRING165,
|
||||
STRING166,
|
||||
STRING167,
|
||||
STRING168,
|
||||
STRING169,
|
||||
STRING170,
|
||||
STRING171,
|
||||
STRING172,
|
||||
STRING173,
|
||||
STRING174,
|
||||
STRING175,
|
||||
STRING176,
|
||||
STRING177,
|
||||
STRING178,
|
||||
STRING179,
|
||||
STRING180,
|
||||
STRING181,
|
||||
STRING182,
|
||||
STRING183,
|
||||
STRING184,
|
||||
STRING185,
|
||||
STRING186,
|
||||
STRING187,
|
||||
STRING188,
|
||||
STRING189,
|
||||
STRING190,
|
||||
STRING191,
|
||||
STRING192,
|
||||
STRING193,
|
||||
STRING194,
|
||||
STRING195,
|
||||
STRING196,
|
||||
STRING197,
|
||||
STRING198,
|
||||
STRING199,
|
||||
STRING200,
|
||||
STRING201,
|
||||
STRING202,
|
||||
STRING203,
|
||||
STRING204,
|
||||
STRING205,
|
||||
STRING206,
|
||||
STRING207,
|
||||
STRING208,
|
||||
STRING209,
|
||||
STRING210,
|
||||
STRING211,
|
||||
STRING212,
|
||||
STRING213,
|
||||
STRING214,
|
||||
STRING215,
|
||||
STRING216,
|
||||
STRING217,
|
||||
STRING218,
|
||||
STRING219,
|
||||
STRING220,
|
||||
STRING221,
|
||||
STRING222,
|
||||
STRING223,
|
||||
STRING224,
|
||||
STRING225,
|
||||
STRING226,
|
||||
STRING227,
|
||||
STRING228,
|
||||
STRING229,
|
||||
STRING230,
|
||||
STRING231,
|
||||
STRING232,
|
||||
STRING233,
|
||||
STRING234,
|
||||
STRING235,
|
||||
STRING236,
|
||||
STRING237,
|
||||
STRING238,
|
||||
STRING239,
|
||||
STRING240,
|
||||
STRING241,
|
||||
STRING242,
|
||||
STRING243,
|
||||
STRING244,
|
||||
STRING245,
|
||||
STRING246,
|
||||
STRING247,
|
||||
STRING248,
|
||||
STRING249,
|
||||
STRING250,
|
||||
STRING251,
|
||||
STRING252,
|
||||
STRING253,
|
||||
STRING254,
|
||||
STRING255,
|
||||
STRING256,
|
||||
STRING257,
|
||||
STRING258,
|
||||
STRING259,
|
||||
STRING260,
|
||||
STRING261,
|
||||
STRING262,
|
||||
STRING263,
|
||||
STRING264,
|
||||
STRING265,
|
||||
STRING266,
|
||||
STRING267,
|
||||
STRING268,
|
||||
STRING269,
|
||||
STRING270,
|
||||
STRING271,
|
||||
STRING272,
|
||||
STRING273,
|
||||
STRING274,
|
||||
STRING275,
|
||||
STRING276,
|
||||
STRING277,
|
||||
STRING278,
|
||||
STRING279,
|
||||
STRING280,
|
||||
STRING281,
|
||||
STRING282,
|
||||
STRING283,
|
||||
STRING284,
|
||||
STRING285,
|
||||
STRING286,
|
||||
STRING287,
|
||||
STRING288,
|
||||
STRING289,
|
||||
|
||||
HIGHSCORES_Caption,
|
||||
HIGHSCORES_Ok,
|
||||
HIGHSCORES_Cancel,
|
||||
HIGHSCORES_Clear,
|
||||
HIGHSCORES_Name,
|
||||
HIGHSCORES_Score,
|
||||
HIGHSCORES_Rank,
|
||||
HIGHSCORES_Rank1,
|
||||
HIGHSCORES_Rank2,
|
||||
HIGHSCORES_Rank3,
|
||||
HIGHSCORES_Rank4,
|
||||
HIGHSCORES_Rank5,
|
||||
KEYMAPPER_Caption,
|
||||
KEYMAPPER_Ok,
|
||||
KEYMAPPER_Cancel,
|
||||
KEYMAPPER_FlipperL,
|
||||
KEYMAPPER_FlipperR,
|
||||
KEYMAPPER_Plunger,
|
||||
KEYMAPPER_BumpLeft,
|
||||
KEYMAPPER_BumpRight,
|
||||
KEYMAPPER_BumpBottom,
|
||||
KEYMAPPER_Default,
|
||||
KEYMAPPER_Help1,
|
||||
KEYMAPPER_Help2,
|
||||
KEYMAPPER_Groupbox1,
|
||||
KEYMAPPER_Groupbox2,
|
||||
Menu1_New_Game,
|
||||
Menu1_About_Pinball,
|
||||
Menu1_High_Scores,
|
||||
Menu1_Exit,
|
||||
Menu1_Sounds,
|
||||
Menu1_Music,
|
||||
Menu1_Help_Topics,
|
||||
Menu1_Launch_Ball,
|
||||
Menu1_Pause_Resume_Game,
|
||||
Menu1_Full_Screen,
|
||||
Menu1_Demo,
|
||||
Menu1_Select_Table,
|
||||
Menu1_Player_Controls,
|
||||
Menu1_1Player,
|
||||
Menu1_2Players,
|
||||
Menu1_3Players,
|
||||
Menu1_4Players,
|
||||
Menu1_MaximumResolution,
|
||||
Menu1_640x480,
|
||||
Menu1_800x600,
|
||||
Menu1_1024x768,
|
||||
Menu1_WindowUniformScale,
|
||||
Menu1_AlternativeRender,
|
||||
Menu1_Game,
|
||||
Menu1_Options,
|
||||
Menu1_Select_Players,
|
||||
Menu1_Table_Resolution,
|
||||
Menu1_Window,
|
||||
Menu1_Help,
|
||||
|
||||
Menu1_UseMaxResolution_640x480,
|
||||
Menu1_UseMaxResolution_800x600,
|
||||
Menu1_UseMaxResolution_1024x768,
|
||||
|
||||
Max,
|
||||
};
|
||||
|
||||
enum class Lang : int
|
||||
{
|
||||
Min = 0,
|
||||
Arabic = 0,
|
||||
Czech,
|
||||
Danish,
|
||||
German,
|
||||
Greek,
|
||||
English,
|
||||
Spanish,
|
||||
Finnish,
|
||||
French,
|
||||
Hebrew,
|
||||
Hungarian,
|
||||
Italian,
|
||||
Japanese,
|
||||
Korean,
|
||||
Norwegian,
|
||||
Dutch,
|
||||
Polish,
|
||||
BrazilianPortuguese,
|
||||
Portuguese,
|
||||
Russian,
|
||||
Swedish,
|
||||
Turkish,
|
||||
SimplifiedChinese,
|
||||
TraditionalChinese,
|
||||
Max
|
||||
};
|
||||
|
||||
struct TextArray
|
||||
{
|
||||
TextArray(const std::initializer_list<std::pair<Msg, std::initializer_list<std::pair<Lang, LPCSTR>>>>& iList)
|
||||
{
|
||||
for (const auto& msgPair : iList)
|
||||
{
|
||||
for (const auto& languagePair : msgPair.second)
|
||||
{
|
||||
assertm(!contains(msgPair.first, languagePair.first), "Key redefinition");
|
||||
Set(msgPair.first, languagePair.first, languagePair.second);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = Msg::Min; i < Msg::Max; i = static_cast<Msg>(static_cast<int>(i) + 1))
|
||||
{
|
||||
assertm(contains(i, Lang::English), "English text is mandatory for all keys");
|
||||
}
|
||||
}
|
||||
|
||||
LPCSTR Get(Msg msgId, Lang langId) const
|
||||
{
|
||||
assertm(TextArray::contains(msgId), "Message Id out of bounds");
|
||||
assertm(TextArray::contains(langId), "Language Id out of bounds");
|
||||
return Store[static_cast<int>(msgId)][static_cast<int>(langId)];
|
||||
}
|
||||
|
||||
bool contains(Msg msgId, Lang langId) const
|
||||
{
|
||||
return contains(msgId) && Get(msgId, langId) != nullptr;
|
||||
}
|
||||
|
||||
static bool contains(Msg msgId)
|
||||
{
|
||||
return msgId >= Msg::Min && msgId < Msg::Max;
|
||||
}
|
||||
|
||||
static bool contains(Lang langId)
|
||||
{
|
||||
return langId >= Lang::Min && langId < Lang::Max;
|
||||
}
|
||||
|
||||
private:
|
||||
LPCSTR Store[static_cast<int>(Msg::Max )][static_cast<int>(Lang::Max)]{ nullptr };
|
||||
|
||||
void Set(Msg msgId, Lang langId, LPCSTR value)
|
||||
{
|
||||
assertm(TextArray::contains(msgId), "Message Id out of bounds");
|
||||
assertm(TextArray::contains(langId), "Language Id out of bounds");
|
||||
Store[static_cast<int>(msgId)][static_cast<int>(langId)] = value;
|
||||
}
|
||||
};
|
||||
|
||||
struct LanguageInfo
|
||||
{
|
||||
const Lang Language;
|
||||
const char* ShortName;
|
||||
const char* DisplayName;
|
||||
};
|
||||
|
||||
class translations
|
||||
{
|
||||
public:
|
||||
static const LanguageInfo Languages[static_cast<int>(Lang::Max)];
|
||||
|
||||
static const char* GetTranslation(Msg id);
|
||||
static void SetCurrentLanguage(const char* short_name);
|
||||
static const LanguageInfo* GetCurrentLanguage();
|
||||
static void GetGlyphRange(ImVector<ImWchar>* ranges);
|
||||
|
||||
private:
|
||||
static const TextArray Translations;
|
||||
static Lang CurrentLanguage;
|
||||
};
|
@ -9,6 +9,8 @@
|
||||
#include "pb.h"
|
||||
#include "render.h"
|
||||
#include "Sound.h"
|
||||
#include "translations.h"
|
||||
#include "font_selection.h"
|
||||
|
||||
SDL_Window* winmain::MainWindow = nullptr;
|
||||
SDL_Renderer* winmain::Renderer = nullptr;
|
||||
@ -64,7 +66,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||
// SDL window
|
||||
SDL_Window* window = SDL_CreateWindow
|
||||
(
|
||||
pinball::get_rc_string(38, 0),
|
||||
pinball::get_rc_string(Msg::STRING139),
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
800, 556,
|
||||
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE
|
||||
@ -106,9 +108,6 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||
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);
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
|
||||
|
||||
auto prefPath = SDL_GetPrefPath(nullptr, "SpaceCadetPinball");
|
||||
auto iniPath = std::string(prefPath) + "imgui_pb.ini";
|
||||
@ -117,6 +116,40 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||
// First step: just load the options
|
||||
options::InitPrimary();
|
||||
|
||||
if(!Options.FontFileName.empty())
|
||||
{
|
||||
ImGuiSDL::Deinitialize();
|
||||
io.Fonts->Clear();
|
||||
ImVector<ImWchar> ranges;
|
||||
translations::GetGlyphRange(&ranges);
|
||||
ImFontConfig fontConfig{};
|
||||
|
||||
// ToDo: further tweak font options, maybe try imgui_freetype
|
||||
fontConfig.OversampleV = 2;
|
||||
fontConfig.OversampleH = 4;
|
||||
|
||||
// ToDo: improve font file test, checking if file exists is not enough
|
||||
auto fileName = Options.FontFileName.c_str();
|
||||
auto fileHandle = fopenu(fileName, "rb");
|
||||
if (fileHandle)
|
||||
{
|
||||
fclose(fileHandle);
|
||||
|
||||
// ToDo: Bind font size to UI scale
|
||||
if (!io.Fonts->AddFontFromFileTTF(fileName, 13.f, &fontConfig, ranges.Data))
|
||||
io.Fonts->AddFontDefault();
|
||||
}
|
||||
else
|
||||
io.Fonts->AddFontDefault();
|
||||
|
||||
io.Fonts->Build();
|
||||
ImGuiSDL::Initialize(renderer, 0, 0);
|
||||
}
|
||||
|
||||
// ImGui_ImplSDL2_Init is private, we are not actually using ImGui OpenGl backend
|
||||
ImGui_ImplSDL2_InitForOpenGL(window, nullptr);
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
|
||||
|
||||
// Data search order: WD, executable path, user pref path, platform specific paths.
|
||||
auto basePath = SDL_GetBasePath();
|
||||
std::vector<const char*> searchPaths
|
||||
@ -372,34 +405,34 @@ void winmain::RenderUi()
|
||||
fullscrn::window_size_changed();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Game"))
|
||||
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Game)))
|
||||
{
|
||||
if (ImGui::MenuItem("New Game", "F2"))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_New_Game), "F2"))
|
||||
{
|
||||
new_game();
|
||||
}
|
||||
if (ImGui::MenuItem("Launch Ball", nullptr, false, LaunchBallEnabled))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Launch_Ball), nullptr, false, LaunchBallEnabled))
|
||||
{
|
||||
end_pause();
|
||||
pb::launch_ball();
|
||||
}
|
||||
if (ImGui::MenuItem("Pause/Resume Game", "F3"))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Pause_Resume_Game), "F3"))
|
||||
{
|
||||
pause();
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("High Scores...", nullptr, false, HighScoresEnabled))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_High_Scores), nullptr, false, HighScoresEnabled))
|
||||
{
|
||||
pause(false);
|
||||
pb::high_scores();
|
||||
}
|
||||
if (ImGui::MenuItem("Demo", nullptr, DemoActive))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Demo), nullptr, DemoActive))
|
||||
{
|
||||
end_pause();
|
||||
pb::toggle_demo();
|
||||
}
|
||||
if (ImGui::MenuItem("Exit"))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Exit)))
|
||||
{
|
||||
SDL_Event event{SDL_QUIT};
|
||||
SDL_PushEvent(&event);
|
||||
@ -407,45 +440,58 @@ void winmain::RenderUi()
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Options)))
|
||||
{
|
||||
if (ImGui::MenuItem("Show Menu", "F9", Options.ShowMenu))
|
||||
{
|
||||
options::toggle(Menu1::Show_Menu);
|
||||
}
|
||||
if (ImGui::MenuItem("Full Screen", "F4", Options.FullScreen))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Full_Screen), "F4", Options.FullScreen))
|
||||
{
|
||||
options::toggle(Menu1::Full_Screen);
|
||||
}
|
||||
if (ImGui::BeginMenu("Select Players"))
|
||||
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Select_Players)))
|
||||
{
|
||||
if (ImGui::MenuItem("1 Player", nullptr, Options.Players == 1))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_1Player), nullptr, Options.Players == 1))
|
||||
{
|
||||
options::toggle(Menu1::OnePlayer);
|
||||
new_game();
|
||||
}
|
||||
if (ImGui::MenuItem("2 Players", nullptr, Options.Players == 2))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_2Players), nullptr, Options.Players == 2))
|
||||
{
|
||||
options::toggle(Menu1::TwoPlayers);
|
||||
new_game();
|
||||
}
|
||||
if (ImGui::MenuItem("3 Players", nullptr, Options.Players == 3))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_3Players), nullptr, Options.Players == 3))
|
||||
{
|
||||
options::toggle(Menu1::ThreePlayers);
|
||||
new_game();
|
||||
}
|
||||
if (ImGui::MenuItem("4 Players", nullptr, Options.Players == 4))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_4Players), nullptr, Options.Players == 4))
|
||||
{
|
||||
options::toggle(Menu1::FourPlayers);
|
||||
new_game();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::MenuItem("Player Controls...", "F8"))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Player_Controls), "F8"))
|
||||
{
|
||||
pause(false);
|
||||
options::ShowControlDialog();
|
||||
}
|
||||
if (ImGui::BeginMenu("Language"))
|
||||
{
|
||||
auto currentLanguage = translations::GetCurrentLanguage();
|
||||
for (auto &item : translations::Languages)
|
||||
{
|
||||
if (ImGui::MenuItem(item.DisplayName, nullptr, currentLanguage->Language == item.Language))
|
||||
{
|
||||
translations::SetCurrentLanguage(item.ShortName);
|
||||
winmain::Restart();
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::BeginMenu("Audio"))
|
||||
@ -472,7 +518,7 @@ void winmain::RenderUi()
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Music", "F6", Options.Music))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Music), "F6", Options.Music))
|
||||
{
|
||||
options::toggle(Menu1::Music);
|
||||
}
|
||||
@ -487,6 +533,10 @@ void winmain::RenderUi()
|
||||
|
||||
if (ImGui::BeginMenu("Graphics"))
|
||||
{
|
||||
if (ImGui::MenuItem("Change Font"))
|
||||
{
|
||||
font_selection::ShowDialog();
|
||||
}
|
||||
if (ImGui::MenuItem("Uniform Scaling", nullptr, Options.UniformScaling))
|
||||
{
|
||||
options::toggle(Menu1::WindowUniformScale);
|
||||
@ -543,10 +593,18 @@ void winmain::RenderUi()
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Table Resolution"))
|
||||
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Table_Resolution)))
|
||||
{
|
||||
char buffer[20]{};
|
||||
auto maxResText = pinball::get_rc_string(fullscrn::GetMaxResolution() + 2030, 0);
|
||||
Msg resolutionStringId = Msg::Menu1_UseMaxResolution_640x480;
|
||||
|
||||
switch(fullscrn::GetMaxResolution()) {
|
||||
case 0: resolutionStringId = Msg::Menu1_UseMaxResolution_640x480; break;
|
||||
case 1: resolutionStringId = Msg::Menu1_UseMaxResolution_800x600; break;
|
||||
case 2: resolutionStringId = Msg::Menu1_UseMaxResolution_1024x768; break;
|
||||
}
|
||||
|
||||
auto maxResText = pinball::get_rc_string(resolutionStringId);
|
||||
if (ImGui::MenuItem(maxResText, nullptr, Options.Resolution == -1))
|
||||
{
|
||||
options::toggle(Menu1::MaximumResolution);
|
||||
@ -574,7 +632,7 @@ void winmain::RenderUi()
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Help"))
|
||||
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Help)))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (ImGui::MenuItem("ImGui Demo", nullptr, ShowImGuiDemo))
|
||||
@ -633,7 +691,7 @@ void winmain::RenderUi()
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("About Pinball"))
|
||||
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_About_Pinball)))
|
||||
{
|
||||
pause(false);
|
||||
ShowAboutDialog = true;
|
||||
@ -648,11 +706,15 @@ void winmain::RenderUi()
|
||||
|
||||
a_dialog();
|
||||
high_score::RenderHighScoreDialog();
|
||||
font_selection::RenderDialog();
|
||||
if (ShowSpriteViewer)
|
||||
render::SpriteViewer(&ShowSpriteViewer);
|
||||
options::RenderControlDialog();
|
||||
if (DispGRhistory)
|
||||
RenderFrameTimeDialog();
|
||||
|
||||
// Print game texts on the sidebar
|
||||
gdrv::grtext_draw_ttext_in_box();
|
||||
}
|
||||
|
||||
int winmain::event_handler(const SDL_Event* event)
|
||||
@ -924,8 +986,8 @@ void winmain::memalloc_failure()
|
||||
{
|
||||
midi::music_stop();
|
||||
Sound::Close();
|
||||
char* caption = pinball::get_rc_string(170, 0);
|
||||
char* text = pinball::get_rc_string(179, 0);
|
||||
const char* caption = pinball::get_rc_string(Msg::STRING270);
|
||||
const char* text = pinball::get_rc_string(Msg::STRING279);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, caption, text, MainWindow);
|
||||
std::exit(1);
|
||||
}
|
||||
@ -935,13 +997,13 @@ void winmain::a_dialog()
|
||||
if (ShowAboutDialog == true)
|
||||
{
|
||||
ShowAboutDialog = false;
|
||||
ImGui::OpenPopup("About");
|
||||
ImGui::OpenPopup(pinball::get_rc_string(Msg::STRING204));
|
||||
}
|
||||
|
||||
bool unused_open = true;
|
||||
if (ImGui::BeginPopupModal("About", &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
if (ImGui::BeginPopupModal(pinball::get_rc_string(Msg::STRING204), &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
ImGui::TextUnformatted("3D Pinball for Windows - Space Cadet");
|
||||
ImGui::TextUnformatted(pinball::get_rc_string(Msg::STRING139));
|
||||
ImGui::TextUnformatted("Original game by Cinematronics, Microsoft");
|
||||
ImGui::Separator();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user