mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-18 10:37:53 +01:00
Score: inject 3DPB msg font into dat struct.
Fixed double free in sound.
This commit is contained in:
parent
43593b168d
commit
69ecce88df
8 changed files with 117 additions and 141 deletions
|
@ -2,8 +2,11 @@
|
||||||
|
|
||||||
#include "GroupData.h"
|
#include "GroupData.h"
|
||||||
|
|
||||||
|
#include "EmbeddedData.h"
|
||||||
#include "fullscrn.h"
|
#include "fullscrn.h"
|
||||||
#include "gdrv.h"
|
#include "gdrv.h"
|
||||||
|
#include "pb.h"
|
||||||
|
#include "pinball.h"
|
||||||
#include "zdrv.h"
|
#include "zdrv.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,7 +108,7 @@ void GroupData::SplitSplicedBitmap(const gdrv_bitmap8& srcBmp, gdrv_bitmap8& bmp
|
||||||
bmp.XPosition = srcBmp.XPosition;
|
bmp.XPosition = srcBmp.XPosition;
|
||||||
bmp.YPosition = srcBmp.YPosition;
|
bmp.YPosition = srcBmp.YPosition;
|
||||||
bmp.Resolution = srcBmp.Resolution;
|
bmp.Resolution = srcBmp.Resolution;
|
||||||
|
|
||||||
zdrv::fill(&zMap, zMap.Width, zMap.Height, 0, 0, 0xFFFF);
|
zdrv::fill(&zMap, zMap.Width, zMap.Height, 0, 0, 0xFFFF);
|
||||||
zMap.Resolution = srcBmp.Resolution;
|
zMap.Resolution = srcBmp.Resolution;
|
||||||
|
|
||||||
|
@ -277,3 +280,79 @@ zmap_header_type* DatFile::GetZMap(int groupIndex)
|
||||||
auto group = Groups[groupIndex];
|
auto group = Groups[groupIndex];
|
||||||
return group->GetZMap(fullscrn::GetResolution());
|
return group->GetZMap(fullscrn::GetResolution());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatFile::Finalize()
|
||||||
|
{
|
||||||
|
if (!pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
int groupIndex = record_labeled("pbmsg_ft");
|
||||||
|
assertm(groupIndex < 0, "DatFile: pbmsg_ft is already in .dat");
|
||||||
|
|
||||||
|
// Load 3DPB font into dat to simplify pipeline
|
||||||
|
auto rcData = reinterpret_cast<MsgFont*>(ImFontAtlas::DecompressCompressedBase85Data(
|
||||||
|
EmbeddedData::PB_MSGFT_bin_compressed_data_base85));
|
||||||
|
AddMsgFont(rcData, "pbmsg_ft");
|
||||||
|
IM_FREE(rcData);
|
||||||
|
|
||||||
|
// PINBALL2.MID is an alternative font provided in 3DPB data
|
||||||
|
/*auto file = pinball::make_path_name("PINBALL2.MID");
|
||||||
|
auto fileHandle = fopen(file.c_str(), "rb");
|
||||||
|
fseek(fileHandle, 0, SEEK_END);
|
||||||
|
auto fileSize = static_cast<uint32_t>(ftell(fileHandle));
|
||||||
|
auto rcData = reinterpret_cast<MsgFont*>(new uint8_t[fileSize]);
|
||||||
|
fseek(fileHandle, 0, SEEK_SET);
|
||||||
|
fread(rcData, 1, fileSize, fileHandle);
|
||||||
|
fclose(fileHandle);
|
||||||
|
AddMsgFont(rcData, "pbmsg_ft");
|
||||||
|
delete[] rcData;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto group : Groups)
|
||||||
|
{
|
||||||
|
group->FinalizeGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatFile::AddMsgFont(MsgFont* font, const std::string& fontName)
|
||||||
|
{
|
||||||
|
auto groupId = Groups.back()->GroupId + 1;
|
||||||
|
auto ptrToData = reinterpret_cast<char*>(font->Data);
|
||||||
|
for (auto charInd = 32; charInd < 128; charInd++, groupId++)
|
||||||
|
{
|
||||||
|
auto curChar = reinterpret_cast<MsgFontChar*>(ptrToData);
|
||||||
|
assertm(curChar->Width == font->CharWidths[charInd], "Score: mismatched font width");
|
||||||
|
ptrToData += curChar->Width * font->Height + 1;
|
||||||
|
|
||||||
|
auto bmp = new gdrv_bitmap8(curChar->Width, font->Height, true);
|
||||||
|
auto srcPtr = curChar->Data;
|
||||||
|
auto dstPtr = &bmp->IndexedBmpPtr[bmp->Stride * (bmp->Height - 1)];
|
||||||
|
for (auto y = 0; y < font->Height; ++y)
|
||||||
|
{
|
||||||
|
memcpy(dstPtr, srcPtr, curChar->Width);
|
||||||
|
srcPtr += curChar->Width;
|
||||||
|
dstPtr -= bmp->Stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto group = new GroupData(groupId);
|
||||||
|
group->AddEntry(new EntryData(FieldTypes::Bitmap8bit, reinterpret_cast<char*>(bmp)));
|
||||||
|
if (charInd == 32)
|
||||||
|
{
|
||||||
|
// First font group holds font name and gap width
|
||||||
|
auto groupName = new char[fontName.length() + 1];
|
||||||
|
strcpy(groupName, fontName.c_str());
|
||||||
|
group->AddEntry(new EntryData(FieldTypes::GroupName, groupName));
|
||||||
|
|
||||||
|
auto gaps = new char[2];
|
||||||
|
*reinterpret_cast<int16_t*>(gaps) = font->GapWidth;
|
||||||
|
group->AddEntry(new EntryData(FieldTypes::ShortArray, gaps));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto groupName = new char[30];
|
||||||
|
sprintf(groupName, "char %d='%c'", charInd, charInd);
|
||||||
|
group->AddEntry(new EntryData(FieldTypes::GroupName, groupName));
|
||||||
|
}
|
||||||
|
|
||||||
|
Groups.push_back(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -55,6 +55,27 @@ struct EntryData
|
||||||
char* Buffer{};
|
char* Buffer{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct MsgFontChar
|
||||||
|
{
|
||||||
|
uint8_t Width;
|
||||||
|
char Data[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MsgFont
|
||||||
|
{
|
||||||
|
int16_t GapWidth;
|
||||||
|
int16_t Unknown1;
|
||||||
|
int16_t Height;
|
||||||
|
uint8_t CharWidths[128];
|
||||||
|
MsgFontChar Data[1];
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
static_assert(sizeof(MsgFont) == 136, "Wrong size of MsgFont");
|
||||||
|
|
||||||
|
|
||||||
class GroupData
|
class GroupData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -100,4 +121,8 @@ public:
|
||||||
char* field_labeled(LPCSTR lpString, FieldTypes fieldType);
|
char* field_labeled(LPCSTR lpString, FieldTypes fieldType);
|
||||||
gdrv_bitmap8* GetBitmap(int groupIndex);
|
gdrv_bitmap8* GetBitmap(int groupIndex);
|
||||||
zmap_header_type* GetZMap(int groupIndex);
|
zmap_header_type* GetZMap(int groupIndex);
|
||||||
|
void Finalize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AddMsgFont(MsgFont* font, const std::string& fontName);
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,7 @@ void Sound::Deactivate()
|
||||||
void Sound::Close()
|
void Sound::Close()
|
||||||
{
|
{
|
||||||
delete[] TimeStamps;
|
delete[] TimeStamps;
|
||||||
|
TimeStamps = nullptr;
|
||||||
Mix_CloseAudio();
|
Mix_CloseAudio();
|
||||||
Mix_Quit();
|
Mix_Quit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,6 @@ int gdrv::display_palette(ColorRgba* plt)
|
||||||
|
|
||||||
current_palette[255].Color = 0xffFFFFFF;
|
current_palette[255].Color = 0xffFFFFFF;
|
||||||
|
|
||||||
score::ApplyPalette();
|
|
||||||
for (const auto group : pb::record_table->Groups)
|
for (const auto group : pb::record_table->Groups)
|
||||||
{
|
{
|
||||||
for (int i = 0; i <= 2; i++)
|
for (int i = 0; i <= 2; i++)
|
||||||
|
|
|
@ -75,7 +75,7 @@ DatFile* partman::load_records(LPCSTR lpFileName, bool fullTiltMode)
|
||||||
assertm(bmpHeader.Resolution <= 2, "partman: bitmap resolution out of bounds");
|
assertm(bmpHeader.Resolution <= 2, "partman: bitmap resolution out of bounds");
|
||||||
|
|
||||||
auto bmp = new gdrv_bitmap8(bmpHeader);
|
auto bmp = new gdrv_bitmap8(bmpHeader);
|
||||||
entryData->Buffer = reinterpret_cast<char*>(bmp);
|
entryData->Buffer = reinterpret_cast<char*>(bmp);
|
||||||
fread(bmp->IndexedBmpPtr, 1, bmpHeader.Size, fileHandle);
|
fread(bmp->IndexedBmpPtr, 1, bmpHeader.Size, fileHandle);
|
||||||
}
|
}
|
||||||
else if (entryType == FieldTypes::Bitmap16bit)
|
else if (entryType == FieldTypes::Bitmap16bit)
|
||||||
|
@ -120,13 +120,15 @@ DatFile* partman::load_records(LPCSTR lpFileName, bool fullTiltMode)
|
||||||
groupData->AddEntry(entryData);
|
groupData->AddEntry(entryData);
|
||||||
}
|
}
|
||||||
|
|
||||||
groupData->FinalizeGroup();
|
|
||||||
datFile->Groups.push_back(groupData);
|
datFile->Groups.push_back(groupData);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fileHandle);
|
fclose(fileHandle);
|
||||||
if (datFile->Groups.size() == header.NumberOfGroups)
|
if (datFile->Groups.size() == header.NumberOfGroups)
|
||||||
|
{
|
||||||
|
datFile->Finalize();
|
||||||
return datFile;
|
return datFile;
|
||||||
|
}
|
||||||
delete datFile;
|
delete datFile;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -521,27 +521,6 @@ void render::SpriteViewer(bool* show)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3DPB font is not in dat file.
|
|
||||||
if (!pb::FullTiltMode)
|
|
||||||
{
|
|
||||||
int index = -1;
|
|
||||||
for (auto bmp : score::msg_fontp->Chars)
|
|
||||||
{
|
|
||||||
index++;
|
|
||||||
if (!bmp)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ImGui::Text("Char: %d, symbol:'%c'", index, index);
|
|
||||||
|
|
||||||
gdrv::CreatePreview(*bmp);
|
|
||||||
if (bmp->Texture)
|
|
||||||
{
|
|
||||||
ImGui::Image(bmp->Texture, ImVec2(bmp->Width * scale, bmp->Height * scale),
|
|
||||||
uv_min, uv_max, tint_col, border_col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,100 +53,23 @@ 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)
|
|
||||||
{
|
|
||||||
if (strcmp(lpName, "pbmsg_ft") != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto rcData = reinterpret_cast<int16_t*>(ImFontAtlas::DecompressCompressedBase85Data(
|
|
||||||
EmbeddedData::PB_MSGFT_bin_compressed_data_base85));
|
|
||||||
|
|
||||||
auto fontp = new score_msg_font_type();
|
|
||||||
msg_fontp = fontp;
|
|
||||||
if (!fontp)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memset(fontp->Chars, 0, sizeof fontp->Chars);
|
|
||||||
|
|
||||||
auto maxWidth = 0;
|
|
||||||
auto ptrToWidths = (char*)rcData + 6;
|
|
||||||
for (auto index = 128; index; index--)
|
|
||||||
{
|
|
||||||
if (*ptrToWidths > maxWidth)
|
|
||||||
maxWidth = *ptrToWidths;
|
|
||||||
++ptrToWidths;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto height = rcData[2];
|
|
||||||
auto tmpCharBur = new char[maxWidth * height + 4];
|
|
||||||
if (!tmpCharBur)
|
|
||||||
{
|
|
||||||
delete msg_fontp;
|
|
||||||
msg_fontp = nullptr;
|
|
||||||
IM_FREE(rcData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_fontp->GapWidth = rcData[0];
|
|
||||||
msg_fontp->Height = height;
|
|
||||||
|
|
||||||
auto ptrToData = (char*)(rcData + 67);
|
|
||||||
int charInd;
|
|
||||||
for (charInd = 0; charInd < 128; charInd++)
|
|
||||||
{
|
|
||||||
auto width = *((char*)rcData + 6 + charInd);
|
|
||||||
if (!width)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto bmp = new gdrv_bitmap8(width, height, true);
|
|
||||||
msg_fontp->Chars[charInd] = bmp;
|
|
||||||
|
|
||||||
auto sizeInBytes = height * width + 1;
|
|
||||||
memcpy(tmpCharBur + 3, ptrToData, sizeInBytes);
|
|
||||||
ptrToData += sizeInBytes;
|
|
||||||
|
|
||||||
auto srcPtr = tmpCharBur + 4;
|
|
||||||
auto dstPtr = &bmp->IndexedBmpPtr[bmp->Stride * (bmp->Height - 1)];
|
|
||||||
for (auto y = 0; y < height; ++y)
|
|
||||||
{
|
|
||||||
memcpy(dstPtr, srcPtr, width);
|
|
||||||
srcPtr += width;
|
|
||||||
dstPtr -= bmp->Stride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] tmpCharBur;
|
|
||||||
IM_FREE(rcData);
|
|
||||||
if (charInd != 128)
|
|
||||||
unload_msg_font();
|
|
||||||
}
|
|
||||||
|
|
||||||
void score::load_msg_font_FT(LPCSTR lpName)
|
|
||||||
{
|
{
|
||||||
if (!pb::record_table)
|
if (!pb::record_table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int groupIndex = pb::record_table->record_labeled(lpName);
|
int groupIndex = pb::record_table->record_labeled(lpName);
|
||||||
if (groupIndex < 0)
|
if (groupIndex < 0)
|
||||||
return;
|
return;
|
||||||
msg_fontp = new score_msg_font_type();
|
|
||||||
if (!msg_fontp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memset(msg_fontp, 0, sizeof(score_msg_font_type));
|
msg_fontp = new score_msg_font_type();
|
||||||
|
|
||||||
|
// FT font has multiple resolutions
|
||||||
auto gapArray = reinterpret_cast<int16_t*>(pb::record_table->field(groupIndex, FieldTypes::ShortArray));
|
auto gapArray = reinterpret_cast<int16_t*>(pb::record_table->field(groupIndex, FieldTypes::ShortArray));
|
||||||
if (gapArray)
|
if (gapArray)
|
||||||
msg_fontp->GapWidth = gapArray[fullscrn::GetResolution()];
|
msg_fontp->GapWidth = gapArray[fullscrn::GetResolution()];
|
||||||
else
|
else
|
||||||
msg_fontp->GapWidth = 0;
|
msg_fontp->GapWidth = 0;
|
||||||
|
|
||||||
for (auto charIndex = 32; charIndex < 128; charIndex++, ++groupIndex)
|
for (auto charIndex = 32; charIndex < 128; charIndex++, ++groupIndex)
|
||||||
{
|
{
|
||||||
auto bmp = pb::record_table->GetBitmap(groupIndex);
|
auto bmp = pb::record_table->GetBitmap(groupIndex);
|
||||||
|
@ -158,16 +81,11 @@ void score::load_msg_font_FT(LPCSTR lpName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void score::unload_msg_font()
|
void score::unload_msg_font()
|
||||||
{
|
{
|
||||||
if (msg_fontp)
|
if (msg_fontp)
|
||||||
{
|
{
|
||||||
/*3DBP creates bitmaps, FT just references them from partman*/
|
|
||||||
if (!pb::FullTiltMode)
|
|
||||||
for (auto& Char : msg_fontp->Chars)
|
|
||||||
{
|
|
||||||
delete Char;
|
|
||||||
}
|
|
||||||
delete msg_fontp;
|
delete msg_fontp;
|
||||||
msg_fontp = nullptr;
|
msg_fontp = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -267,18 +185,3 @@ void score::string_format(int score, char* str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void score::ApplyPalette()
|
|
||||||
{
|
|
||||||
if (!msg_fontp || pb::FullTiltMode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Only 3DPB font needs this, because it is not loaded by partman
|
|
||||||
for (auto& Char : msg_fontp->Chars)
|
|
||||||
{
|
|
||||||
if (Char)
|
|
||||||
{
|
|
||||||
gdrv::ApplyPalette(*Char);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,15 +17,7 @@ struct score_msg_font_type
|
||||||
{
|
{
|
||||||
int GapWidth;
|
int GapWidth;
|
||||||
int Height;
|
int Height;
|
||||||
gdrv_bitmap8* Chars[128];
|
gdrv_bitmap8* Chars[128]{};
|
||||||
};
|
|
||||||
|
|
||||||
struct score_font_rc
|
|
||||||
{
|
|
||||||
short Header0;
|
|
||||||
short Header1;
|
|
||||||
short Height;
|
|
||||||
char SomeLen[128];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,8 +34,4 @@ 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);
|
||||||
static void ApplyPalette();
|
|
||||||
private :
|
|
||||||
static void load_msg_font_3DPB(LPCSTR lpName);
|
|
||||||
static void load_msg_font_FT(LPCSTR lpName);
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue