mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-17 15:20:17 +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 "EmbeddedData.h"
|
||||
#include "fullscrn.h"
|
||||
#include "gdrv.h"
|
||||
#include "pb.h"
|
||||
#include "pinball.h"
|
||||
#include "zdrv.h"
|
||||
|
||||
|
||||
|
@ -105,7 +108,7 @@ void GroupData::SplitSplicedBitmap(const gdrv_bitmap8& srcBmp, gdrv_bitmap8& bmp
|
|||
bmp.XPosition = srcBmp.XPosition;
|
||||
bmp.YPosition = srcBmp.YPosition;
|
||||
bmp.Resolution = srcBmp.Resolution;
|
||||
|
||||
|
||||
zdrv::fill(&zMap, zMap.Width, zMap.Height, 0, 0, 0xFFFF);
|
||||
zMap.Resolution = srcBmp.Resolution;
|
||||
|
||||
|
@ -277,3 +280,79 @@ zmap_header_type* DatFile::GetZMap(int groupIndex)
|
|||
auto group = Groups[groupIndex];
|
||||
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{};
|
||||
};
|
||||
|
||||
|
||||
#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
|
||||
{
|
||||
public:
|
||||
|
@ -100,4 +121,8 @@ public:
|
|||
char* field_labeled(LPCSTR lpString, FieldTypes fieldType);
|
||||
gdrv_bitmap8* GetBitmap(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()
|
||||
{
|
||||
delete[] TimeStamps;
|
||||
TimeStamps = nullptr;
|
||||
Mix_CloseAudio();
|
||||
Mix_Quit();
|
||||
}
|
||||
|
|
|
@ -119,7 +119,6 @@ int gdrv::display_palette(ColorRgba* plt)
|
|||
|
||||
current_palette[255].Color = 0xffFFFFFF;
|
||||
|
||||
score::ApplyPalette();
|
||||
for (const auto group : pb::record_table->Groups)
|
||||
{
|
||||
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");
|
||||
|
||||
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);
|
||||
}
|
||||
else if (entryType == FieldTypes::Bitmap16bit)
|
||||
|
@ -120,13 +120,15 @@ DatFile* partman::load_records(LPCSTR lpFileName, bool fullTiltMode)
|
|||
groupData->AddEntry(entryData);
|
||||
}
|
||||
|
||||
groupData->FinalizeGroup();
|
||||
datFile->Groups.push_back(groupData);
|
||||
}
|
||||
|
||||
fclose(fileHandle);
|
||||
if (datFile->Groups.size() == header.NumberOfGroups)
|
||||
{
|
||||
datFile->Finalize();
|
||||
return datFile;
|
||||
}
|
||||
delete datFile;
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -53,100 +53,23 @@ scoreStruct* score::dup(scoreStruct* score, int scoreIndex)
|
|||
}
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
int groupIndex = pb::record_table->record_labeled(lpName);
|
||||
if (groupIndex < 0)
|
||||
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));
|
||||
if (gapArray)
|
||||
msg_fontp->GapWidth = gapArray[fullscrn::GetResolution()];
|
||||
else
|
||||
msg_fontp->GapWidth = 0;
|
||||
|
||||
for (auto charIndex = 32; charIndex < 128; charIndex++, ++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()
|
||||
{
|
||||
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;
|
||||
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 Height;
|
||||
gdrv_bitmap8* Chars[128];
|
||||
};
|
||||
|
||||
struct score_font_rc
|
||||
{
|
||||
short Header0;
|
||||
short Header1;
|
||||
short Height;
|
||||
char SomeLen[128];
|
||||
gdrv_bitmap8* Chars[128]{};
|
||||
};
|
||||
|
||||
|
||||
|
@ -42,8 +34,4 @@ public:
|
|||
static void set(scoreStruct* score, int value);
|
||||
static void update(scoreStruct* score);
|
||||
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