mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-04 21:39:54 +00:00
cellFont rendering functions
-Now, all the games using rendering text using cellFontRenderCharGlyphImage and all the related functions should work, or at least don't crash. -There are still issues with the character position on surface, and in some cases, it renders the text with a different font than the one the game specified. A lot of cellFont stuff is still missing or may be not properly implemented. -For games using system-embedded fontsets you have to find a *legal* way to copy the .TTF files from your PS3 into dev_flash/data/font.
This commit is contained in:
parent
ce88a4fc9a
commit
66a9acfb04
2
.gitignore
vendored
2
.gitignore
vendored
@ -45,6 +45,8 @@ rpcs3/git-version.h
|
||||
# Copyrighted files
|
||||
/bin/data/
|
||||
/bin/dev_flash/data/font
|
||||
/bin/dev_flash/sys
|
||||
/bin/dev_flash/vsh
|
||||
|
||||
# Ignore installed games except test homebrews
|
||||
!/bin/dev_hdd0/game/
|
||||
|
@ -2,8 +2,7 @@
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
#include "cellFont.h"
|
||||
|
||||
//#include "stblib/stb_truetype.h"
|
||||
#include "stblib/stb_truetype.h"
|
||||
|
||||
void cellFont_init();
|
||||
void cellFont_unload();
|
||||
@ -91,7 +90,16 @@ struct CellFontConfig
|
||||
|
||||
struct CellFontRenderer
|
||||
{
|
||||
u32 SystemReserved_addr; //void *systemReserved[64];
|
||||
void *systemReserved[64];
|
||||
};
|
||||
|
||||
//Custom enum to determine the origin of a CellFont object
|
||||
enum
|
||||
{
|
||||
CELL_FONT_OPEN_FONTSET,
|
||||
CELL_FONT_OPEN_FONT_FILE,
|
||||
CELL_FONT_OPEN_FONT_INSTANCE,
|
||||
CELL_FONT_OPEN_MEMORY,
|
||||
};
|
||||
|
||||
struct CellFont
|
||||
@ -101,7 +109,10 @@ struct CellFont
|
||||
be_t<float> scale_y;
|
||||
be_t<float> slant;
|
||||
be_t<u32> renderer_addr;
|
||||
//stbtt_fontinfo stbfont;
|
||||
|
||||
stbtt_fontinfo stbfont;
|
||||
be_t<u32> fontdata_addr;
|
||||
be_t<u32> origin;
|
||||
};
|
||||
|
||||
struct CellFontType
|
||||
@ -163,6 +174,16 @@ struct CellFontGlyphMetrics
|
||||
} Vertical;
|
||||
};
|
||||
|
||||
struct CellFontImageTransInfo
|
||||
{
|
||||
be_t<u32> Image_addr;
|
||||
be_t<u32> imageWidthByte;
|
||||
be_t<u32> imageWidth;
|
||||
be_t<u32> imageHeight;
|
||||
be_t<u32> Surface_addr;
|
||||
be_t<u32> surfWidthByte;
|
||||
};
|
||||
|
||||
struct CellFontRendererConfig
|
||||
{
|
||||
struct BufferingPolicy
|
||||
@ -276,10 +297,12 @@ int cellFontOpenFontMemory(mem_ptr_t<CellFontLibrary> library, u32 fontAddr, u32
|
||||
if (!Memory.IsGoodAddr(fontAddr))
|
||||
return CELL_FONT_ERROR_FONT_OPEN_FAILED;
|
||||
|
||||
//stbtt_InitFont(&(font->stbfont), (unsigned char*)Memory.VirtualToRealAddr(fontAddr), 0);
|
||||
font->renderer_addr = NULL;
|
||||
//TODO: Write data in font
|
||||
if (!stbtt_InitFont(&(font->stbfont), (unsigned char*)Memory.VirtualToRealAddr(fontAddr), 0))
|
||||
return CELL_FONT_ERROR_FONT_OPEN_FAILED;
|
||||
|
||||
font->renderer_addr = NULL;
|
||||
font->fontdata_addr = fontAddr;
|
||||
font->origin = CELL_FONT_OPEN_MEMORY;
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
@ -293,10 +316,11 @@ int cellFontOpenFontFile(mem_ptr_t<CellFontLibrary> library, mem8_ptr_t fontPath
|
||||
return CELL_FONT_ERROR_FONT_OPEN_FAILED;
|
||||
|
||||
u32 fileSize = f.GetSize();
|
||||
MemoryAllocator<u8> buffer(fileSize);
|
||||
f.Read(Memory.VirtualToRealAddr(buffer.GetAddr()), fileSize);
|
||||
cellFontOpenFontMemory(library.GetAddr(), buffer.GetAddr(), fileSize, subNum, uniqueId, font.GetAddr());
|
||||
return CELL_FONT_OK;
|
||||
u32 bufferAddr = Memory.Alloc(fileSize, 1); // Freed in cellFontCloseFont
|
||||
f.Read(Memory.VirtualToRealAddr(bufferAddr), fileSize);
|
||||
int ret = cellFontOpenFontMemory(library.GetAddr(), bufferAddr, fileSize, subNum, uniqueId, font.GetAddr());
|
||||
font->origin = CELL_FONT_OPEN_FONT_FILE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cellFontOpenFontset(mem_ptr_t<CellFontLibrary> library, mem_ptr_t<CellFontType> fontType, mem_ptr_t<CellFont> font)
|
||||
@ -379,7 +403,8 @@ int cellFontOpenFontset(mem_ptr_t<CellFontLibrary> library, mem_ptr_t<CellFontTy
|
||||
|
||||
u32 file_addr = Memory.Alloc(file.length()+1, 1);
|
||||
Memory.WriteString(file_addr, file);
|
||||
int ret = cellFontOpenFontFile(library.GetAddr(), file_addr, 0, 0, font.GetAddr()); //TODO: The values of subNum, uniqueId may be incorrect
|
||||
int ret = cellFontOpenFontFile(library.GetAddr(), file_addr, 0, 0, font.GetAddr()); //TODO: Find the correct values of subNum, uniqueId
|
||||
font->origin = CELL_FONT_OPEN_FONTSET;
|
||||
Memory.Free(file_addr);
|
||||
return ret;
|
||||
}
|
||||
@ -387,6 +412,17 @@ int cellFontOpenFontset(mem_ptr_t<CellFontLibrary> library, mem_ptr_t<CellFontTy
|
||||
int cellFontOpenFontInstance(mem_ptr_t<CellFont> openedFont, mem_ptr_t<CellFont> font)
|
||||
{
|
||||
cellFont.Warning("cellFontOpenFontInstance(openedFont=0x%x, font=0x%x)", openedFont.GetAddr(), font.GetAddr());
|
||||
|
||||
if (!openedFont.IsGood() || !font.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
|
||||
font->renderer_addr = openedFont->renderer_addr;
|
||||
font->scale_x = openedFont->scale_x;
|
||||
font->scale_y = openedFont->scale_y;
|
||||
font->slant = openedFont->slant;
|
||||
font->stbfont = openedFont->stbfont;
|
||||
font->origin = CELL_FONT_OPEN_FONT_INSTANCE;
|
||||
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
@ -437,8 +473,9 @@ void cellFontRenderSurfaceSetScissor(mem_ptr_t<CellFontRenderSurface> surface, s
|
||||
|
||||
int cellFontSetScalePixel(mem_ptr_t<CellFont> font, float w, float h)
|
||||
{
|
||||
h = GetCurrentPPUThread().FPR[1]; // TODO: Something is wrong with the float arguments
|
||||
cellFont.Warning("cellFontSetScalePixel(font_addr=0x%x, w=%f, h=%f)", font.GetAddr(), w, h);
|
||||
w = GetCurrentPPUThread().FPR[1]; // TODO: Something is wrong with the float arguments
|
||||
h = GetCurrentPPUThread().FPR[2]; // TODO: Something is wrong with the float arguments
|
||||
cellFont.Log("cellFontSetScalePixel(font_addr=0x%x, w=%f, h=%f)", font.GetAddr(), w, h);
|
||||
|
||||
if (!font.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
@ -450,16 +487,19 @@ int cellFontSetScalePixel(mem_ptr_t<CellFont> font, float w, float h)
|
||||
|
||||
int cellFontGetHorizontalLayout(mem_ptr_t<CellFont> font, mem_ptr_t<CellFontHorizontalLayout> layout)
|
||||
{
|
||||
cellFont.Warning("cellFontGetHorizontalLayout(font_addr=0x%x, layout_addr=0x%x)",
|
||||
cellFont.Log("cellFontGetHorizontalLayout(font_addr=0x%x, layout_addr=0x%x)",
|
||||
font.GetAddr(), layout.GetAddr());
|
||||
|
||||
if (!font.IsGood() || !layout.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
|
||||
//TODO: This values are (probably) wrong and just for testing purposes! Find the way of calculating them.
|
||||
layout->baseLineY = font->scale_y - 4;
|
||||
layout->lineHeight = font->scale_y;
|
||||
layout->effectHeight = 4;
|
||||
int ascent, descent, lineGap;
|
||||
float scale = stbtt_ScaleForPixelHeight(&(font->stbfont), font->scale_y);
|
||||
stbtt_GetFontVMetrics(&(font->stbfont), &ascent, &descent, &lineGap);
|
||||
|
||||
layout->baseLineY = ascent * scale;
|
||||
layout->lineHeight = (ascent-descent+lineGap) * scale;
|
||||
layout->effectHeight = lineGap * scale;
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
@ -496,15 +536,74 @@ int cellFontDestroyRenderer()
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
int cellFontSetupRenderScalePixel()
|
||||
int cellFontSetupRenderScalePixel(mem_ptr_t<CellFont> font, float w, float h)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
w = GetCurrentPPUThread().FPR[1]; // TODO: Something is wrong with the float arguments
|
||||
h = GetCurrentPPUThread().FPR[2]; // TODO: Something is wrong with the float arguments
|
||||
cellFont.Log("cellFontSetupRenderScalePixel(font_addr=0x%x, w=%f, h=%f)", font.GetAddr(), w, h);
|
||||
|
||||
if (!font.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
if (!font->renderer_addr)
|
||||
return CELL_FONT_ERROR_RENDERER_UNBIND;
|
||||
|
||||
// TODO: ?
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
int cellFontGetRenderCharGlyphMetrics()
|
||||
int cellFontGetRenderCharGlyphMetrics(mem_ptr_t<CellFont> font, u32 code, mem_ptr_t<CellFontGlyphMetrics> metrics)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
cellFont.Log("cellFontGetRenderCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x)",
|
||||
font.GetAddr(), code, metrics.GetAddr());
|
||||
|
||||
if (!font.IsGood() || !metrics.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
if (!font->renderer_addr)
|
||||
return CELL_FONT_ERROR_RENDERER_UNBIND;
|
||||
|
||||
// TODO: ?
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
int cellFontRenderCharGlyphImage(mem_ptr_t<CellFont> font, u32 code, mem_ptr_t<CellFontRenderSurface> surface, float x, float y, mem_ptr_t<CellFontGlyphMetrics> metrics, mem_ptr_t<CellFontImageTransInfo> transInfo)
|
||||
{
|
||||
x = GetCurrentPPUThread().FPR[1]; // TODO: Something is wrong with the float arguments
|
||||
y = GetCurrentPPUThread().FPR[2]; // TODO: Something is wrong with the float arguments
|
||||
cellFont.Log("cellFontRenderCharGlyphImage(font_addr=0x%x, code=0x%x, surface_addr=0x%x, x=%f, y=%f, metrics_addr=0x%x, trans_addr=0x%x)",
|
||||
font.GetAddr(), code, surface.GetAddr(), x, y, metrics.GetAddr(), transInfo.GetAddr());
|
||||
|
||||
if (!font.IsGood() || !surface.IsGood() || !metrics.IsGood() || !transInfo.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
if (!font->renderer_addr)
|
||||
return CELL_FONT_ERROR_RENDERER_UNBIND;
|
||||
|
||||
// Render the character
|
||||
int width, height, xoff, yoff;
|
||||
float scale = stbtt_ScaleForPixelHeight(&(font->stbfont), font->scale_y);
|
||||
unsigned char* box = stbtt_GetCodepointBitmap(&(font->stbfont), scale, scale, code, &width, &height, &xoff, &yoff);
|
||||
if (!box) return CELL_OK;
|
||||
|
||||
// Get the baseLineY value
|
||||
int baseLineY;
|
||||
int ascent, descent, lineGap;
|
||||
stbtt_GetFontVMetrics(&(font->stbfont), &ascent, &descent, &lineGap);
|
||||
baseLineY = ascent * scale;
|
||||
|
||||
// Move the rendered character to the surface
|
||||
unsigned char* buffer = (unsigned char*)Memory.VirtualToRealAddr(surface->buffer_addr);
|
||||
for (u32 ypos = 0; ypos < height; ypos++){
|
||||
if ((u32)y + ypos + yoff + baseLineY >= surface->height)
|
||||
break;
|
||||
|
||||
for (u32 xpos = 0; xpos < width; xpos++){
|
||||
if ((u32)x + xpos >= surface->width)
|
||||
break;
|
||||
|
||||
// TODO: There are some oddities in the position of the character in the final buffer
|
||||
buffer[((int)y + ypos + yoff + baseLineY)*surface->width + (int)x+xpos] = box[ypos*width + xpos];
|
||||
}
|
||||
}
|
||||
stbtt_FreeBitmap(box, 0);
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
@ -516,7 +615,8 @@ int cellFontEndLibrary()
|
||||
|
||||
int cellFontSetEffectSlant(mem_ptr_t<CellFont> font, float slantParam)
|
||||
{
|
||||
cellFont.Warning("cellFontSetEffectSlant(font_addr=0x%x, slantParam=%f)", font.GetAddr(), slantParam);
|
||||
slantParam = GetCurrentPPUThread().FPR[1]; // TODO: Something is wrong with the float arguments
|
||||
cellFont.Log("cellFontSetEffectSlant(font_addr=0x%x, slantParam=%f)", font.GetAddr(), slantParam);
|
||||
|
||||
if (!font.IsGood() || slantParam < -1.0 || slantParam > 1.0)
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
@ -532,47 +632,57 @@ int cellFontGetEffectSlant(mem_ptr_t<CellFont> font, mem32_t slantParam)
|
||||
if (!font.IsGood() || !slantParam.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
|
||||
slantParam = font->slant;
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
int cellFontRenderCharGlyphImage()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
slantParam = font->slant; //Does this conversion from be_t<float> to *mem32_t work?
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
int cellFontGetFontIdCode(mem_ptr_t<CellFont> font, u32 code, mem32_t fontId, mem32_t fontCode)
|
||||
{
|
||||
cellFont.Warning("cellFontGetFontIdCode(font_addr=0x%x, code=0x%x, fontId_addr=0x%x, fontCode_addr=0x%x",
|
||||
cellFont.Log("cellFontGetFontIdCode(font_addr=0x%x, code=0x%x, fontId_addr=0x%x, fontCode_addr=0x%x",
|
||||
font.GetAddr(), code, fontId.GetAddr(), fontCode.GetAddr());
|
||||
|
||||
if (!font.IsGood() || !fontId.IsGood()) //fontCode isn't used
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
|
||||
// TODO: ?
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
int cellFontCloseFont()
|
||||
int cellFontCloseFont(mem_ptr_t<CellFont> font)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
cellFont.Warning("cellFontCloseFont(font_addr=0x%x)", font.GetAddr());
|
||||
|
||||
if (!font.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (font->origin == CELL_FONT_OPEN_FONTSET ||
|
||||
font->origin == CELL_FONT_OPEN_FONT_FILE ||
|
||||
font->origin == CELL_FONT_OPEN_MEMORY)
|
||||
Memory.Free(font->fontdata_addr);
|
||||
|
||||
return CELL_FONT_OK;
|
||||
}
|
||||
|
||||
int cellFontGetCharGlyphMetrics(mem_ptr_t<CellFont> font, u32 code, mem_ptr_t<CellFontGlyphMetrics> metrics)
|
||||
{
|
||||
cellFont.Warning("cellFontGetCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x",
|
||||
cellFont.Log("cellFontGetCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x",
|
||||
font.GetAddr(), code, metrics.GetAddr());
|
||||
|
||||
if (!font.IsGood() || metrics.IsGood())
|
||||
return CELL_FONT_ERROR_INVALID_PARAMETER;
|
||||
|
||||
//TODO: This values are (probably) wrong and just for testing purposes! Find the way of calculating them.
|
||||
metrics->width = 0;
|
||||
metrics->height = 0;
|
||||
metrics->Horizontal.bearingX = 0;
|
||||
int x0, y0, x1, y1;
|
||||
int advanceWidth, leftSideBearing;
|
||||
float scale = stbtt_ScaleForPixelHeight(&(font->stbfont), font->scale_y);
|
||||
stbtt_GetCodepointBox(&(font->stbfont), code, &x0, &y0, &x1, &y1);
|
||||
stbtt_GetCodepointHMetrics(&(font->stbfont), code, &advanceWidth, &leftSideBearing);
|
||||
|
||||
// TODO: Add the rest of the information
|
||||
metrics->width = (x1-x0) * scale;
|
||||
metrics->height = (y1-y0) * scale;
|
||||
metrics->Horizontal.bearingX = (float)leftSideBearing * scale;
|
||||
metrics->Horizontal.bearingY = 0;
|
||||
metrics->Horizontal.advance = 0;
|
||||
metrics->Horizontal.advance = (float)advanceWidth * scale;
|
||||
metrics->Vertical.bearingX = 0;
|
||||
metrics->Vertical.bearingY = 0;
|
||||
metrics->Vertical.advance = 0;
|
||||
|
2066
stblib/stb_truetype.h
Normal file
2066
stblib/stb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user