Added table resolution support.

Only works with FT .dat file.
FT music does not work - different format.
This commit is contained in:
Muzychenko Andrey 2021-02-06 16:53:47 +03:00
parent d594f5fdb7
commit 1c5256a4c6
20 changed files with 353 additions and 64 deletions

View file

@ -1,6 +1,8 @@
#include "pch.h" #include "pch.h"
#include "Sound.h" #include "Sound.h"
#include "pb.h"
#include "pinball.h" #include "pinball.h"
#include "WaveMix.h" #include "WaveMix.h"
#include "winmain.h" #include "winmain.h"
@ -45,6 +47,8 @@ int Sound::Init(HINSTANCE hInstance, int voices, void (* someFuncPtr)(int, MIXWA
} }
else else
{ {
/*FT does not have the file, defaults work OK*/
if (!pb::FullTiltMode)
MessageBoxA(winmain::hwnd_frame, pinball::get_rc_string(42, 0), pinball::WindowName, 0x2000u); MessageBoxA(winmain::hwnd_frame, pinball::get_rc_string(42, 0), pinball::WindowName, 0x2000u);
} }

View file

@ -88,6 +88,13 @@ BEGIN
MENUITEM "&Music", Menu1_Music MENUITEM "&Music", Menu1_Music
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "P&layer Controls...\tF8", Menu1_Player_Controls MENUITEM "P&layer Controls...\tF8", Menu1_Player_Controls
POPUP "Table &Resolution"
BEGIN
MENUITEM "Use &Maximum Resolution", Menu1_MaximumResolution
MENUITEM "&640 x 480", Menu1_640x480
MENUITEM "&800 x 600", Menu1_800x600
MENUITEM "&1024 x 768", Menu1_1024x768
END
END END
POPUP "&Help" POPUP "&Help"
BEGIN BEGIN
@ -342,7 +349,7 @@ END
// Bitmap // Bitmap
// //
splash_bitmap BITMAP "splash_bitmap.bmp" SPLASH_BITMAP BITMAP "splash_bitmap.bmp"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -587,6 +594,17 @@ BEGIN
IDS_STRING289 "255 255 255 (R G B default font color)" IDS_STRING289 "255 255 255 (R G B default font color)"
END END
STRINGTABLE
BEGIN
2030 "Use &Maximum Resolution (640 x 480)"
2031 "Use &Maximum Resolution (800 x 600)"
END
STRINGTABLE
BEGIN
2032 "Use &Maximum Resolution (1024 x 768)"
END
#endif // English (United States) resources #endif // English (United States) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -2,9 +2,11 @@
#include "TBall.h" #include "TBall.h"
#include "fullscrn.h"
#include "loader.h" #include "loader.h"
#include "maths.h" #include "maths.h"
#include "objlist_class.h" #include "objlist_class.h"
#include "pb.h"
#include "proj.h" #include "proj.h"
#include "render.h" #include "render.h"
#include "TPinballTable.h" #include "TPinballTable.h"
@ -12,6 +14,7 @@
TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false) TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
{ {
visualStruct visual{}; visualStruct visual{};
char ballGroupName[10]{"ball"};
TimeNow = 0.0; TimeNow = 0.0;
RayMaxDistance = 0.0; RayMaxDistance = 0.0;
@ -30,11 +33,12 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
Position.Y = 0.0; Position.Y = 0.0;
ListBitmap = new objlist_class<gdrv_bitmap8>(0, 4); ListBitmap = new objlist_class<gdrv_bitmap8>(0, 4);
auto groupIndex = loader::query_handle("ball");
/*Full tilt hack - ball is ball0*/ /*Full tilt: ball is ballN, where N[0,2] resolution*/
if (groupIndex < 0) if (pb::FullTiltMode)
groupIndex = loader::query_handle("ball0"); ballGroupName[4] = '0' + fullscrn::GetResolution();
auto groupIndex = loader::query_handle(ballGroupName);
Offset = *loader::query_float_attribute(groupIndex, 0, 500); Offset = *loader::query_float_attribute(groupIndex, 0, 500);
auto visualCount = loader::query_visual_states(groupIndex); auto visualCount = loader::query_visual_states(groupIndex);
auto index = 0; auto index = 0;

View file

@ -21,18 +21,16 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
Timer = 0; Timer = 0;
Smoothness = visual.Smoothness; Smoothness = visual.Smoothness;
auto floatArr = loader::query_float_attribute(groupIndex, 0, 803); auto collMult = *loader::query_float_attribute(groupIndex, 0, 803);
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 805); auto bmpCoef2 = *loader::query_float_attribute(groupIndex, 0, 805);
auto floatArr3 = loader::query_float_attribute(groupIndex, 0, 804); auto bmpCoef1 = *loader::query_float_attribute(groupIndex, 0, 804);
auto collMult = *floatArr;
auto bmpCoef2 = *floatArr2;
auto bmpCoef1 = *floatArr3;
/*Full tilt hack: different flipper speed*/ /*Full tilt hack: different flipper speed*/
if (bmpCoef2 > 1) if (pb::FullTiltMode)
{
bmpCoef2 = 0.08f; bmpCoef2 = 0.08f;
if (bmpCoef1 > 1)
bmpCoef1 = 0.04f; bmpCoef1 = 0.04f;
}
auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802)); auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802));
auto vecT1 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 801)); auto vecT1 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 801));
auto origin = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 800)); auto origin = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 800));

View file

@ -5,6 +5,7 @@
#include "control.h" #include "control.h"
#include "loader.h" #include "loader.h"
#include "objlist_class.h" #include "objlist_class.h"
#include "pb.h"
#include "TBall.h" #include "TBall.h"
#include "timer.h" #include "timer.h"
#include "TPinballTable.h" #include "TPinballTable.h"
@ -43,7 +44,7 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304))); FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304)));
/*Full tilt hack - FieldFlag should be on*/ /*Full tilt hack - FieldFlag should be on*/
if (!FieldFlag) if (pb::FullTiltMode)
FieldFlag = 1; FieldFlag = 1;
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2]; Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];

View file

@ -1,8 +1,11 @@
#include "pch.h" #include "pch.h"
#include "TTableLayer.h" #include "TTableLayer.h"
#include "fullscrn.h"
#include "loader.h" #include "loader.h"
#include "objlist_class.h" #include "objlist_class.h"
#include "pb.h"
#include "proj.h" #include "proj.h"
#include "render.h" #include "render.h"
#include "TBall.h" #include "TBall.h"
@ -19,7 +22,8 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
auto groupIndex = loader::query_handle("table"); auto groupIndex = loader::query_handle("table");
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
auto projCenter = loader::query_float_attribute(groupIndex, 0, 700); /*Full tilt: proj center first value is offset by resolution*/
auto projCenter = loader::query_float_attribute(groupIndex, 0, 700 + fullscrn::GetResolution());
proj::recenter(projCenter[0], projCenter[1]); proj::recenter(projCenter[0], projCenter[1]);
render::set_background_zmap(visual.ZMap, 0, 0); render::set_background_zmap(visual.ZMap, 0, 0);
@ -54,7 +58,7 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
auto angleMultArr = loader::query_float_attribute(groupIndex, 0, 701); auto angleMultArr = loader::query_float_attribute(groupIndex, 0, 701);
/*Full tilt hack - GraityMult should be 0.2*/ /*Full tilt hack - GraityMult should be 0.2*/
if (angleMultArr && *angleMultArr < 1) if (angleMultArr && !pb::FullTiltMode)
GraityMult = *angleMultArr; GraityMult = *angleMultArr;
else else
GraityMult = 0.2f; GraityMult = 0.2f;

View file

@ -2,7 +2,9 @@
#include "TTextBox.h" #include "TTextBox.h"
#include "control.h" #include "control.h"
#include "fullscrn.h"
#include "loader.h" #include "loader.h"
#include "pb.h"
#include "render.h" #include "render.h"
#include "score.h" #include "score.h"
#include "timer.h" #include "timer.h"
@ -22,8 +24,9 @@ TTextBox::TTextBox(TPinballTable* table, int groupIndex) : TPinballComponent(tab
if (groupIndex > 0) if (groupIndex > 0)
{ {
/*Full tilt: text box dimensions index is offset by resolution*/
int arrLength; int arrLength;
auto dimensions = loader::query_iattribute(groupIndex, 1500, &arrLength); auto dimensions = loader::query_iattribute(groupIndex + fullscrn::GetResolution(), 1500, &arrLength);
OffsetX = dimensions[0]; OffsetX = dimensions[0];
OffsetY = dimensions[1]; OffsetY = dimensions[1];
Width = dimensions[2]; Width = dimensions[2];

View file

@ -1,5 +1,7 @@
#include "pch.h" #include "pch.h"
#include "fullscrn.h" #include "fullscrn.h"
#include "pb.h"
#include "render.h" #include "render.h"
#include "winmain.h" #include "winmain.h"
@ -14,6 +16,14 @@ int fullscrn::ChangeDisplay, fullscrn::SmthFullScrnFlag2;
int fullscrn::trick = 1; int fullscrn::trick = 1;
int fullscrn::MenuEnabled; int fullscrn::MenuEnabled;
HMENU fullscrn::MenuHandle; HMENU fullscrn::MenuHandle;
int fullscrn::resolution = 0;
int fullscrn::maxResolution = 0;
const resolution_info fullscrn::resolution_array[3] =
{
{640, 480, 600, 416, 501},
{800, 600, 752, 520, 502},
{1024, 768, 960, 666, 503},
};
void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay) void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay)
{ {
@ -102,9 +112,9 @@ int fullscrn::enableFullscreen()
{ {
DevMode.dmSize = 156; DevMode.dmSize = 156;
DevMode.dmFields = 1835008; DevMode.dmFields = 1835008;
DevMode.dmPelsWidth = 640; DevMode.dmPelsWidth = resolution_array[resolution].ScreenWidth;
DevMode.dmPelsHeight = 480; DevMode.dmPelsHeight = resolution_array[resolution].ScreenHeight;
DevMode.dmBitsPerPel = 8; DevMode.dmBitsPerPel = 32;
disableWindowFlagsDisDlg(); disableWindowFlagsDisDlg();
if (trick) if (trick)
{ {
@ -360,3 +370,52 @@ void fullscrn::paint()
render::paint(); render::paint();
fullscrn_flag1 = 0; fullscrn_flag1 = 0;
} }
int fullscrn::GetResolution()
{
return resolution;
}
void fullscrn::SetResolution(int resolution)
{
if (!pb::FullTiltMode)
resolution = 0;
assertm(resolution >= 0 && resolution <= 2, "Resolution value out of bounds");
fullscrn::resolution = resolution;
}
int fullscrn::GetMaxResolution()
{
return maxResolution;
}
void fullscrn::SetMaxResolution(int resolution)
{
assertm(resolution >= 0 && resolution <= 2, "Resolution value out of bounds");
maxResolution = resolution;
}
int fullscrn::get_max_supported_resolution()
{
if (!pb::FullTiltMode)
return 0;
auto resolutionWH = get_screen_resolution();
auto width = LOWORD(resolutionWH);
auto height = HIWORD(resolutionWH);
auto result = 0;
for (auto index = 1; index < 3; ++index)
{
auto resPtr = &resolution_array[index];
if (resPtr->ScreenWidth <= width && resPtr->ScreenHeight <= height)
result = index;
}
return result;
}
int fullscrn::get_screen_resolution()
{
auto height = static_cast<unsigned __int16>(GetSystemMetrics(SM_CYSCREEN));
return static_cast<unsigned __int16>(GetSystemMetrics(SM_CXSCREEN)) | (height << 16);
}

View file

@ -5,6 +5,16 @@
#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0) #define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0)
#define BYTE2(x) BYTEn(x, 2) #define BYTE2(x) BYTEn(x, 2)
struct resolution_info
{
__int16 ScreenWidth;
__int16 ScreenHeight;
__int16 TableWidth;
__int16 TableHeight;
__int16 ResolutionMenuId;
};
class fullscrn class fullscrn
{ {
public: public:
@ -17,6 +27,7 @@ public:
static int display_changed; static int display_changed;
static int ChangeDisplay, SmthFullScrnFlag2; static int ChangeDisplay, SmthFullScrnFlag2;
static int trick; static int trick;
static const resolution_info resolution_array[3];
static void init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay); static void init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay);
static void shutdown(); static void shutdown();
@ -29,9 +40,17 @@ public:
static void getminmaxinfo(MINMAXINFO* maxMin); static void getminmaxinfo(MINMAXINFO* maxMin);
static void paint(); static void paint();
static bool set_menu_mode(int menuEnabled); static bool set_menu_mode(int menuEnabled);
static int GetResolution();
static void SetResolution(int resolution);
static int GetMaxResolution();
static void SetMaxResolution(int resolution);
static int get_max_supported_resolution();
static int get_screen_resolution();
private : private :
static int MenuEnabled; static int MenuEnabled;
static HMENU MenuHandle; static HMENU MenuHandle;
static int resolution;
static int maxResolution;
static void GetWindowCenter(); static void GetWindowCenter();
static int disableWindowFlagsDisDlg(); static int disableWindowFlagsDisDlg();

View file

@ -239,7 +239,7 @@ int gdrv::destroy_bitmap(gdrv_bitmap8* bmp)
{ {
if (!bmp) if (!bmp)
return -1; return -1;
if (bmp->BitmapType == BitmapType::RawBitmap) if (bmp->BitmapType == BitmapType::RawBitmap || bmp->BitmapType == BitmapType::Spliced)
{ {
memory::free(bmp->BmpBufPtr1); memory::free(bmp->BmpBufPtr1);
} }

View file

@ -2,6 +2,7 @@
#include "loader.h" #include "loader.h"
#include "memory.h" #include "memory.h"
#include "partman.h" #include "partman.h"
#include "pb.h"
#include "pinball.h" #include "pinball.h"
#include "Sound.h" #include "Sound.h"
#include "zdrv.h" #include "zdrv.h"
@ -142,12 +143,17 @@ int loader::get_sound_id(int groupIndex)
datFieldTypes::ShortValue)); datFieldTypes::ShortValue));
if (value && *value == 202) if (value && *value == 202)
{ {
/*FT sounds are in SOUND subfolder*/
char filePath[300]{}, fileName2[100]{};
auto fileName = partman::field(loader_table, soundGroupId, datFieldTypes::String); auto fileName = partman::field(loader_table, soundGroupId, datFieldTypes::String);
HFILE hFile = _lopen(fileName, 0); sprintf_s(fileName2, pb::FullTiltMode ? "SOUND\\%s" : "%s", fileName);
pinball::make_path_name(filePath, fileName2);
HFILE hFile = _lopen(filePath, 0);
sound_list[soundIndex].Duration = static_cast<float>(static_cast<double>(_llseek(hFile, 0, SEEK_END)) * sound_list[soundIndex].Duration = static_cast<float>(static_cast<double>(_llseek(hFile, 0, SEEK_END)) *
0.0000909090909090909); 0.0000909090909090909);
_lclose(hFile); _lclose(hFile);
sound_list[soundIndex].WavePtr = Sound::LoadWaveFile(fileName); sound_list[soundIndex].WavePtr = Sound::LoadWaveFile(filePath);
} }
} }
} }

View file

@ -4,6 +4,7 @@
#include "fullscrn.h" #include "fullscrn.h"
#include "memory.h" #include "memory.h"
#include "midi.h" #include "midi.h"
#include "pb.h"
#include "resource.h" #include "resource.h"
#include "Sound.h" #include "Sound.h"
#include "winmain.h" #include "winmain.h"
@ -128,6 +129,8 @@ void options::init(HMENU menuHandle)
} }
memory::free(tmpBuf); memory::free(tmpBuf);
} }
update_resolution_menu();
} }
void options::uninit() void options::uninit()
@ -142,6 +145,7 @@ void options::uninit()
set_int(nullptr, "Left Table Bump key", Options.LeftTableBumpKey); set_int(nullptr, "Left Table Bump key", Options.LeftTableBumpKey);
set_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey); set_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey);
set_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey); set_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey);
set_int(nullptr, "Screen Resolution", Options.Resolution);
} }
void options::path_init(LPCSTR regPath) void options::path_init(LPCSTR regPath)
@ -296,14 +300,78 @@ void options::toggle(UINT uIDCheckItem)
fullscrn::set_screen_mode(newValue); fullscrn::set_screen_mode(newValue);
menu_check(uIDCheckItem, newValue); menu_check(uIDCheckItem, newValue);
return; return;
} case Menu1_1Player:
if (uIDCheckItem > 407 && uIDCheckItem <= 411) case Menu1_2Players:
{ case Menu1_3Players:
Options.Players = uIDCheckItem - 407; case Menu1_4Players:
Options.Players = uIDCheckItem - Menu1_1Player + 1;
menu_check(Menu1_1Player, Options.Players == 1); menu_check(Menu1_1Player, Options.Players == 1);
menu_check(Menu1_2Players, Options.Players == 2); menu_check(Menu1_2Players, Options.Players == 2);
menu_check(Menu1_3Players, Options.Players == 3); menu_check(Menu1_3Players, Options.Players == 3);
menu_check(Menu1_4Players, Options.Players == 4); menu_check(Menu1_4Players, Options.Players == 4);
break;
case Menu1_MaximumResolution:
case Menu1_640x480:
case Menu1_800x600:
case Menu1_1024x768:
{
menu_check(500u, uIDCheckItem == 500);
menu_check(501u, uIDCheckItem == 501);
menu_check(502u, uIDCheckItem == 502);
menu_check(503u, uIDCheckItem == 503);
int newResolution = uIDCheckItem - Menu1_640x480;
if (uIDCheckItem == Menu1_MaximumResolution)
{
Options.Resolution = -1;
if (fullscrn::GetMaxResolution() != fullscrn::GetResolution())
winmain::Restart();
}
else if (newResolution != fullscrn::GetResolution() && newResolution <= fullscrn::GetMaxResolution())
{
Options.Resolution = newResolution;
winmain::Restart();
}
break;
}
default:
break;
}
}
void options::update_resolution_menu()
{
auto maxResolution = fullscrn::get_max_supported_resolution();
fullscrn::SetMaxResolution(maxResolution);
const CHAR* maxResText = pinball::get_rc_string(maxResolution + 2030, 0);
if (MenuHandle)
ModifyMenuA(MenuHandle, Menu1_MaximumResolution, 0, Menu1_MaximumResolution, maxResText);
for (auto resIndex = 0; resIndex < 3; resIndex++)
{
menu_set(fullscrn::resolution_array[resIndex].ResolutionMenuId, fullscrn::GetMaxResolution() >= resIndex);
}
for (auto i = Menu1_MaximumResolution; i <= Menu1_1024x768; ++i)
{
menu_check(i, 0);
}
if (Options.Resolution >= 0)
menu_check(fullscrn::resolution_array[fullscrn::GetResolution()].ResolutionMenuId, 1);
else
menu_check(Menu1_MaximumResolution, 1);
}
void options::init_resolution()
{
Options.Resolution = get_int(nullptr, "Screen Resolution", -1);
int maxRes = fullscrn::get_max_supported_resolution();
if (Options.Resolution == -1 || maxRes <= Options.Resolution)
{
fullscrn::SetMaxResolution(maxRes);
fullscrn::SetResolution(maxRes);
}
else
{
fullscrn::SetResolution(Options.Resolution);
} }
} }

View file

@ -21,6 +21,7 @@ struct optionsStruct
int LeftTableBumpKeyDft; int LeftTableBumpKeyDft;
int RightTableBumpKeyDft; int RightTableBumpKeyDft;
int BottomTableBumpKeyDft; int BottomTableBumpKeyDft;
int Resolution;
}; };
@ -38,6 +39,8 @@ public:
static void menu_check(UINT uIDCheckItem, int check); static void menu_check(UINT uIDCheckItem, int check);
static void menu_set(UINT uIDEnableItem, int enable); static void menu_set(UINT uIDEnableItem, int enable);
static void toggle(UINT uIDCheckItem); static void toggle(UINT uIDCheckItem);
static void update_resolution_menu();
static void init_resolution();
static void keyboard(); static void keyboard();
static INT_PTR _stdcall KeyMapDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR _stdcall KeyMapDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);

View file

@ -3,6 +3,7 @@
#include "control.h" #include "control.h"
#include "fullscrn.h"
#include "high_score.h" #include "high_score.h"
#include "memory.h" #include "memory.h"
#include "pinball.h" #include "pinball.h"
@ -28,6 +29,8 @@ datFileStruct* pb::record_table = nullptr;
int pb::time_ticks = 0, pb::demo_mode = 0, pb::cheat_mode = 0, pb::game_mode = 2, pb::mode_countdown_, pb::state; int pb::time_ticks = 0, pb::demo_mode = 0, pb::cheat_mode = 0, pb::game_mode = 2, pb::mode_countdown_, pb::state;
float pb::time_now, pb::time_next, pb::ball_speed_limit; float pb::time_now, pb::time_next, pb::ball_speed_limit;
high_score_struct pb::highscore_table[5]; high_score_struct pb::highscore_table[5];
bool pb::FullTiltMode = false;
int pb::init() int pb::init()
{ {
@ -37,9 +40,8 @@ int pb::init()
++memory::critical_allocation; ++memory::critical_allocation;
lstrcpyA(datFileName, winmain::DatFileName); lstrcpyA(datFileName, winmain::DatFileName);
//lstrcpyA(datFileName, "cadet.dat");
pinball::make_path_name(dataFilePath, datFileName, 300); pinball::make_path_name(dataFilePath, datFileName, 300);
record_table = partman::load_records(dataFilePath, 0, strstr(datFileName, "cadet")); record_table = partman::load_records(dataFilePath, fullscrn::GetResolution(), FullTiltMode);
auto useBmpFont = 0; auto useBmpFont = 0;
pinball::get_rc_int(158, &useBmpFont); pinball::get_rc_int(158, &useBmpFont);
@ -52,28 +54,27 @@ int pb::init()
auto plt = (PALETTEENTRY*)partman::field_labeled(record_table, "background", datFieldTypes::Palette); auto plt = (PALETTEENTRY*)partman::field_labeled(record_table, "background", datFieldTypes::Palette);
gdrv::display_palette(plt); gdrv::display_palette(plt);
auto tableSize = (__int16*)partman::field_labeled(record_table, "table_size", datFieldTypes::ShortArray);
auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit); auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit);
auto cameraInfo = (float*)partman::field_labeled(record_table, "camera_info", datFieldTypes::FloatArray); auto cameraInfoId = partman::record_labeled(record_table, "camera_info") + fullscrn::GetResolution();
auto cameraInfo = (float*)partman::field(record_table, cameraInfoId, datFieldTypes::FloatArray);
/*Full tilt hack - table size is hardcoded*/ /*Full tilt: table size depends on resolution*/
if (!tableSize) auto resInfo = &fullscrn::resolution_array[fullscrn::GetResolution()];
tableSize = new short[2]{600, 800};
if (cameraInfo) if (cameraInfo)
{ {
memcpy(&projMat, cameraInfo, sizeof(float) * 4 * 3); memcpy(&projMat, cameraInfo, sizeof(float) * 4 * 3);
cameraInfo += 12; cameraInfo += 12;
auto projCenterX = tableSize[0] * 0.5f; auto projCenterX = resInfo->TableWidth * 0.5f;
auto projCenterY = tableSize[1] * 0.5f; auto projCenterY = resInfo->TableHeight * 0.5f;
auto projD = cameraInfo[0]; auto projD = cameraInfo[0];
proj::init(projMat, projD, projCenterX, projCenterY); proj::init(projMat, projD, projCenterX, projCenterY);
zMin = cameraInfo[1]; zMin = cameraInfo[1];
zScaler = cameraInfo[2]; zScaler = cameraInfo[2];
} }
render::init(nullptr, zMin, zScaler, tableSize[0], tableSize[1]); render::init(nullptr, zMin, zScaler, resInfo->TableWidth, resInfo->TableHeight);
gdrv::copy_bitmap( gdrv::copy_bitmap(
&render::vscreen, &render::vscreen,
backgroundBmp->Width, backgroundBmp->Width,
@ -316,8 +317,8 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
void pb::window_size(int* width, int* height) void pb::window_size(int* width, int* height)
{ {
*width = 600; *width = fullscrn::resolution_array[fullscrn::GetResolution()].TableWidth;
*height = 416; *height = fullscrn::resolution_array[fullscrn::GetResolution()].TableHeight;
} }
void pb::pause_continue() void pb::pause_continue()

View file

@ -14,6 +14,7 @@ public:
static datFileStruct* record_table; static datFileStruct* record_table;
static TPinballTable* MainTable; static TPinballTable* MainTable;
static high_score_struct highscore_table[5]; static high_score_struct highscore_table[5];
static bool FullTiltMode;
static int init(); static int init();
static int uninit(); static int uninit();

View file

@ -224,10 +224,14 @@
#define Menu1_2Players 409 #define Menu1_2Players 409
#define Menu1_3Players 410 #define Menu1_3Players 410
#define Menu1_4Players 411 #define Menu1_4Players 411
#define Menu1_MaximumResolution 500
#define DLG_HIGHSCORES_Score1 501 #define DLG_HIGHSCORES_Score1 501
#define KEYMAPPER_Default 501 #define KEYMAPPER_Default 501
#define Menu1_640x480 501
#define DLG_HIGHSCORES_Score2 502 #define DLG_HIGHSCORES_Score2 502
#define Menu1_800x600 502
#define DLG_HIGHSCORES_Score3 503 #define DLG_HIGHSCORES_Score3 503
#define Menu1_1024x768 503
#define DLG_HIGHSCORES_Score4 504 #define DLG_HIGHSCORES_Score4 504
#define DLG_HIGHSCORES_Score5 505 #define DLG_HIGHSCORES_Score5 505
#define DLG_HIGHSCORES_EditName1 601 #define DLG_HIGHSCORES_EditName1 601
@ -243,6 +247,6 @@
#define _APS_NEXT_RESOURCE_VALUE 204 #define _APS_NEXT_RESOURCE_VALUE 204
#define _APS_NEXT_COMMAND_VALUE 40004 #define _APS_NEXT_COMMAND_VALUE 40004
#define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 102 #define _APS_NEXT_SYMED_VALUE 104
#endif #endif
#endif #endif

View file

@ -1,8 +1,11 @@
#include "pch.h" #include "pch.h"
#include "score.h" #include "score.h"
#include "fullscrn.h"
#include "loader.h" #include "loader.h"
#include "memory.h" #include "memory.h"
#include "partman.h" #include "partman.h"
#include "pb.h"
#include "render.h" #include "render.h"
#include "TDrain.h" #include "TDrain.h"
#include "winmain.h" #include "winmain.h"
@ -21,18 +24,21 @@ scoreStruct* score::create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp)
return nullptr; return nullptr;
score->Score = -9999; score->Score = -9999;
score->BackgroundBmp = renderBgBmp; score->BackgroundBmp = renderBgBmp;
auto shortArr = reinterpret_cast<__int16*>(partman::field_labeled(loader::loader_table, fieldName,
/*Full tilt: score box dimensions index is offset by resolution*/
auto dimensionsId = partman::record_labeled(pb::record_table, fieldName) + fullscrn::GetResolution();
auto dimensions = reinterpret_cast<__int16*>(partman::field(loader::loader_table, dimensionsId,
datFieldTypes::ShortArray)); datFieldTypes::ShortArray));
if (!shortArr) if (!dimensions)
{ {
memory::free(score); memory::free(score);
return nullptr; return nullptr;
} }
int groupIndex = *shortArr++; int groupIndex = *dimensions++;
score->OffsetX = *shortArr++; score->OffsetX = *dimensions++;
score->OffsetY = *shortArr++; score->OffsetY = *dimensions++;
score->Width = *shortArr++; score->Width = *dimensions++;
score->Height = *shortArr; score->Height = *dimensions;
for (int index = 0; index < 10; index++) for (int index = 0; index < 10; index++)
{ {
@ -52,6 +58,15 @@ scoreStruct* score::dup(scoreStruct* score, int scoreIndex)
} }
void score::load_msg_font(LPCSTR lpName) void score::load_msg_font(LPCSTR lpName)
{
/*3DPB stores font in resources, FT in dat. FT font has multiple resolutions*/
if (pb::FullTiltMode)
load_msg_font_FT(lpName);
else
load_msg_font_3DPB(lpName);
}
void score::load_msg_font_3DPB(LPCSTR lpName)
{ {
auto resHandle = FindResourceA(winmain::hinst, lpName, RT_RCDATA); auto resHandle = FindResourceA(winmain::hinst, lpName, RT_RCDATA);
if (!resHandle) if (!resHandle)
@ -136,10 +151,41 @@ void score::load_msg_font(LPCSTR lpName)
FreeResource(resGlobal); FreeResource(resGlobal);
} }
void score::load_msg_font_FT(LPCSTR lpName)
{
if (!pb::record_table)
return;
int groupIndex = partman::record_labeled(pb::record_table, lpName);
if (groupIndex < 0)
return;
msg_fontp = reinterpret_cast<score_msg_font_type*>(memory::allocate(sizeof(score_msg_font_type)));
if (!msg_fontp)
return;
memset(msg_fontp, 0, sizeof(score_msg_font_type));
auto gapArray = reinterpret_cast<__int16*>(partman::field(pb::record_table, groupIndex, datFieldTypes::ShortArray));
if (gapArray)
msg_fontp->GapWidth = gapArray[fullscrn::GetResolution()];
else
msg_fontp->GapWidth = 0;
for (auto charIndex = 32; charIndex < 128; charIndex++, ++groupIndex)
{
auto bmp = reinterpret_cast<gdrv_bitmap8*>(partman::field(pb::record_table, groupIndex,
datFieldTypes::Bitmap8bit));
if (!bmp)
break;
if (!msg_fontp->Height)
msg_fontp->Height = bmp->Height;
msg_fontp->Chars[charIndex] = bmp;
}
}
void score::unload_msg_font() void score::unload_msg_font()
{ {
if (msg_fontp) if (msg_fontp)
{ {
/*3DB creates bitmaps, FT just references them from partman*/
if (!pb::FullTiltMode)
for (int i = 0; i < 128; i++) for (int i = 0; i < 128; i++)
{ {
if (msg_fontp->Chars[i]) if (msg_fontp->Chars[i])

View file

@ -42,4 +42,7 @@ public:
static void set(scoreStruct* score, int value); static void set(scoreStruct* score, int value);
static void update(scoreStruct* score); static void update(scoreStruct* score);
static void string_format(int score, char* str); static void string_format(int score, char* str);
private :
static void load_msg_font_3DPB(LPCSTR lpName);
static void load_msg_font_FT(LPCSTR lpName);
}; };

View file

@ -30,6 +30,7 @@ int winmain::no_time_loss;
DWORD winmain::then; DWORD winmain::then;
DWORD winmain::now; DWORD winmain::now;
UINT winmain::iFrostUniqueMsg; UINT winmain::iFrostUniqueMsg;
bool winmain::restart = false;
gdrv_bitmap8 winmain::gfr_display{}; gdrv_bitmap8 winmain::gfr_display{};
char winmain::DatFileName[300]{}; char winmain::DatFileName[300]{};
@ -116,6 +117,18 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
hinst = hInstance; hinst = hInstance;
options::get_string(regSpaceCadet, "Pinball Data", DatFileName, pinball::get_rc_string(168, 0), 300); options::get_string(regSpaceCadet, "Pinball Data", DatFileName, pinball::get_rc_string(168, 0), 300);
/*Check for full tilt .dat file and switch to it automatically*/
char cadetFilePath[300]{};
pinball::make_path_name(cadetFilePath, "CADET.DAT", 300);
FILE* cadetDat;
fopen_s(&cadetDat, cadetFilePath, "r");
if (cadetDat)
{
fclose(cadetDat);
strcpy_s(DatFileName, "CADET.DAT");
pb::FullTiltMode = true;
}
iFrostUniqueMsg = RegisterWindowMessageA("PinballThemeSwitcherUniqueMsgString"); iFrostUniqueMsg = RegisterWindowMessageA("PinballThemeSwitcherUniqueMsgString");
auto windowClass = pinball::get_rc_string(167, 0); auto windowClass = pinball::get_rc_string(167, 0);
auto windowHandle = FindWindowA(windowClass, nullptr); auto windowHandle = FindWindowA(windowClass, nullptr);
@ -148,6 +161,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
RegisterClassA(&WndClass); RegisterClassA(&WndClass);
pinball::FindShiftKeys(); pinball::FindShiftKeys();
options::init_resolution();
char windowName[40]; char windowName[40];
lstrcpyA(windowName, pinball::get_rc_string(38, 0)); lstrcpyA(windowName, pinball::get_rc_string(38, 0));
@ -301,6 +315,24 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
DestroyWindow(hwnd_frame); DestroyWindow(hwnd_frame);
options::path_uninit(); options::path_uninit();
UnregisterClassA(windowClass, hinst); UnregisterClassA(windowClass, hinst);
if (restart)
{
char restartPath[300]{};
if (GetModuleFileNameA(nullptr, restartPath, 300))
{
STARTUPINFO si{};
PROCESS_INFORMATION pi{};
si.cb = sizeof si;
if (CreateProcess(restartPath, nullptr, nullptr, nullptr,
FALSE, 0, nullptr, nullptr, &si, &pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
}
return return_value; return return_value;
} }
@ -350,11 +382,6 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
RECT rect{}; RECT rect{};
++memory::critical_allocation; ++memory::critical_allocation;
GetWindowRect(GetDesktopWindow(), &rect);
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
pb::window_size(&width, &height);
auto prevCursor = SetCursor(LoadCursorA(nullptr, IDC_WAIT)); auto prevCursor = SetCursor(LoadCursorA(nullptr, IDC_WAIT));
gdrv::init(hinst, hWnd); gdrv::init(hinst, hWnd);
@ -371,6 +398,11 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
SetCursor(prevCursor); SetCursor(prevCursor);
auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1); auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1);
auto menuHandle = GetMenu(hWnd); auto menuHandle = GetMenu(hWnd);
GetWindowRect(GetDesktopWindow(), &rect);
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
pb::window_size(&width, &height);
fullscrn::init(width, height, options::Options.FullScreen, hWnd, menuHandle, fullscrn::init(width, height, options::Options.FullScreen, hWnd, menuHandle,
changeDisplayFg); changeDisplayFg);
@ -428,6 +460,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
fullscrn::getminmaxinfo((MINMAXINFO*)lParam); fullscrn::getminmaxinfo((MINMAXINFO*)lParam);
return DefWindowProcA(hWnd, Msg, wParam, lParam); return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_DISPLAYCHANGE: case WM_DISPLAYCHANGE:
options::update_resolution_menu();
if (fullscrn::displaychange()) if (fullscrn::displaychange())
{ {
options::Options.FullScreen = 0; options::Options.FullScreen = 0;
@ -558,6 +591,12 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
options::toggle(wParam); options::toggle(wParam);
new_game(); new_game();
break; break;
case Menu1_MaximumResolution:
case Menu1_640x480:
case Menu1_800x600:
case Menu1_1024x768:
options::toggle(wParam);
break;
case Menu1_Help_Topics: case Menu1_Help_Topics:
if (!single_step) if (!single_step)
pause(); pause();
@ -779,3 +818,9 @@ void winmain::help_introduction(HINSTANCE a1, HWND a2)
} }
} }
} }
void winmain::Restart()
{
restart = true;
PostMessageA(hwnd_frame, WM_QUIT, 0, 0);
}

View file

@ -20,6 +20,7 @@ public:
static void new_game(); static void new_game();
static void pause(); static void pause();
static void help_introduction(HINSTANCE a1, HWND a2); static void help_introduction(HINSTANCE a1, HWND a2);
static void Restart();
private: private:
static int return_value, bQuit, DispFrameRate, DispGRhistory, activated; static int return_value, bQuit, DispFrameRate, DispGRhistory, activated;
static int has_focus, mouse_down, last_mouse_x, last_mouse_y, no_time_loss; static int has_focus, mouse_down, last_mouse_x, last_mouse_y, no_time_loss;
@ -27,6 +28,7 @@ private:
static UINT iFrostUniqueMsg; static UINT iFrostUniqueMsg;
static gdrv_bitmap8 gfr_display; static gdrv_bitmap8 gfr_display;
static HCURSOR mouse_hsave; static HCURSOR mouse_hsave;
static bool restart;
static HDC _BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint); static HDC _BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
}; };