From ffd3e7687851c48b57622647fefc23cd6b9386fb Mon Sep 17 00:00:00 2001 From: tpu Date: Mon, 25 Feb 2013 23:00:04 +0800 Subject: [PATCH 1/6] add basic PGF font code. --- Common/Common.vcxproj | 4 +- Core/Core.vcxproj | 3 +- Core/Core.vcxproj.filters | 2 + Core/HLE/sceFont.cpp | 304 ++++++++++++++++++++++++++++++++++++ Core/HLE/sceFont.h | 129 +++++++++++++++ GPU/GPU.vcxproj | 2 + Windows/PPSSPP.vcxproj | 4 +- ext/libkirk/libkirk.vcxproj | 1 + ext/zlib/zlib.vcxproj | 4 +- headless/Headless.vcxproj | 4 +- unittest/UnitTests.vcxproj | 4 +- 11 files changed, 450 insertions(+), 11 deletions(-) diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 060207d0b..421bbcc8b 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -66,7 +66,7 @@ Use Level3 Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS stdafx.h MultiThreadedDebugDLL @@ -102,7 +102,7 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS stdafx.h false StreamingSIMDExtensions2 diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 50c55c3a0..ddcc0190f 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -67,7 +67,7 @@ Level3 Disabled ../common;..;../native;../native/ext/glew;../ext/zlib - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS StreamingSIMDExtensions2 Fast @@ -98,6 +98,7 @@ false StreamingSIMDExtensions2 Fast + _MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index aeafbe3ad..aa18c230f 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -375,6 +375,7 @@ MIPS\ARM + @@ -695,6 +696,7 @@ MIPS\ARM + diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 867d7ea66..bcc624657 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -6,6 +6,310 @@ #include "../MIPS/MIPS.h" #include "ChunkFile.h" + +/******************************************************************************/ + +static int get_value(int bpe, u8 *buf, int *pos) +{ + int i, v; + + v = 0; + for(i=0; i> ((*pos)%8) ) &1 ) << i; + (*pos)++; + } + + return v; +} + +static int read_table(u8 *buf, int *table, int num, int bpe) +{ + int i, p, len; + + len = ((num*bpe+31)/32)*4; + + p = 0; + for(i=0; ibuf; + n_charmap = ph->charmap_len; + + for(i=0; icharmap[i]==ptr){ + return i+ph->charmap_min; + } + } + + return 0xffff; +} + +static int have_shadow(PGF_FONT *pgft, u32 ucs) +{ + PGF_HEADER *ph; + int i, n_shadowmap; + + ph = (PGF_HEADER*)pgft->buf; + n_shadowmap = ph->shadowmap_len; + + for(i=0; ishadowmap[i]==ucs){ + return 1; + } + } + + return 0; +} + +static void get_bitmap(PGF_GLYPH *glyph) +{ + int i, j, p, nb, data, len; + u8 *bmp, temp_buf[64*64]; + + i = 0; + p = 0; + len = glyph->width * glyph->height; + if((glyph->flag&3)==2){ + bmp = temp_buf; + }else{ + bmp = glyph->bmp; + } + + while(idata, &p); + if(nb<8){ + data = get_value(4, glyph->data, &p); + for(j=0; jdata, &p); + bmp[i] = data; + i++; + } + } + } + + if((glyph->flag&3)==2){ + int h, v; + + i = 0; + for(h=0; hwidth; h++){ + for(v=0; vheight; v++){ + glyph->bmp[v*glyph->width+h] = bmp[i]; + i++; + } + } + } + +} + +static void load_shadow_glyph(u8 *ptr, PGF_GLYPH *glyph) +{ + int pos; + + pos = 0; + + glyph->size = get_value(14, ptr, &pos); + glyph->width = get_value(7, ptr, &pos); + glyph->height = get_value(7, ptr, &pos); + glyph->left = get_value(7, ptr, &pos); + glyph->top = get_value(7, ptr, &pos); + glyph->flag = get_value(6, ptr, &pos); + + if(glyph->left>63) glyph->left |= 0xffffff80; + if(glyph->top >63) glyph->top |= 0xffffff80; + + glyph->data = ptr+(pos/8); + glyph->bmp = (u8*)malloc(glyph->width*glyph->height); + get_bitmap(glyph); +} + +static void load_char_glyph(PGF_FONT *pgft, int index, PGF_GLYPH *glyph) +{ + int id, pos; + u8 *ptr; + + ptr = pgft->glyphdata + pgft->charptr[index]; + pos = 0; + + glyph->index = index; + glyph->have_shadow = have_shadow(pgft, glyph->ucs); + + glyph->size = get_value(14, ptr, &pos); + glyph->width = get_value( 7, ptr, &pos); + glyph->height = get_value( 7, ptr, &pos); + glyph->left = get_value( 7, ptr, &pos); + glyph->top = get_value( 7, ptr, &pos); + glyph->flag = get_value( 6, ptr, &pos); + + if(glyph->left>63) glyph->left |= 0xffffff80; + if(glyph->top >63) glyph->top |= 0xffffff80; + + /* read extension info */ + glyph->shadow_flag = get_value(7, ptr, &pos); + glyph->shadow_id = get_value(9, ptr, &pos); + if(glyph->flag&0x04){ + id = get_value(8, ptr, &pos); + glyph->dimension.h = pgft->dimension[id].h; + glyph->dimension.v = pgft->dimension[id].v; + }else{ + glyph->dimension.h = get_value(32, ptr, &pos); + glyph->dimension.v = get_value(32, ptr, &pos); + } + if(glyph->flag&0x08){ + id = get_value(8, ptr, &pos); + glyph->bearingX.h = pgft->bearingX[id].h; + glyph->bearingX.v = pgft->bearingX[id].v; + }else{ + glyph->bearingX.h = get_value(32, ptr, &pos); + glyph->bearingX.v = get_value(32, ptr, &pos); + } + if(glyph->flag&0x10){ + id = get_value(8, ptr, &pos); + glyph->bearingY.h = pgft->bearingY[id].h; + glyph->bearingY.v = pgft->bearingY[id].v; + }else{ + glyph->bearingY.h = get_value(32, ptr, &pos); + glyph->bearingY.v = get_value(32, ptr, &pos); + } + if(glyph->flag&0x20){ + id = get_value(8, ptr, &pos); + glyph->advance.h = pgft->advance[id].h; + glyph->advance.v = pgft->advance[id].v; + }else{ + glyph->advance.h = get_value(32, ptr, &pos); + glyph->advance.v = get_value(32, ptr, &pos); + } + + glyph->data = ptr+(pos/8); + glyph->bmp = (u8*)malloc(glyph->width*glyph->height); + get_bitmap(glyph); + + if(glyph->have_shadow){ + id = glyph->shadow_id; + pgft->shadow_glyph[id] = (PGF_GLYPH*)malloc(sizeof(PGF_GLYPH)); + memset(pgft->shadow_glyph[id], 0, sizeof(PGF_GLYPH)); + load_shadow_glyph(ptr+glyph->size, pgft->shadow_glyph[id]); + } + +} + + +int load_all_glyph(PGF_FONT *pgft) +{ + PGF_GLYPH *glyph; + PGF_HEADER *ph; + int i, n_chars, ucs; + + ph = (PGF_HEADER*)pgft->buf; + n_chars = ph->charptr_len; + + for(i=0; iucs = ucs; + pgft->char_glyph[ucs] = glyph; + load_char_glyph(pgft, i, glyph); + } + + return 0; +} + + +PGF_FONT *load_pgf_from_buf(u8 *buf, int length) +{ + PGF_FONT *pgft; + PGF_HEADER *ph; + int i; + + pgft = (PGF_FONT*)malloc(sizeof(PGF_FONT)); + memset(pgft, 0, sizeof(PGF_FONT)); + + pgft->buf = buf; + + /* pgf header */ + ph = (PGF_HEADER*)buf; + buf += ph->header_len; + + /* dimension table */ + pgft->dimension = (F26_PAIRS*)buf; + buf += (ph->dimension_len*8); + + /* left bearing table */ + pgft->bearingX = (F26_PAIRS*)buf; + buf += (ph->bearingX_len*8); + + /* top bearing table */ + pgft->bearingY = (F26_PAIRS*)buf; + buf += (ph->bearingY_len*8); + + /* advance table */ + pgft->advance = (F26_PAIRS*)buf; + buf += (ph->advance_len*8); + + /* read shadowmap table */ + if(ph->shadowmap_len){ + pgft->shadowmap = (int*)malloc(ph->shadowmap_len*4); + buf += read_table(buf, pgft->shadowmap, ph->shadowmap_len, ph->shadowmap_bpe); + } + + /* read charmap table */ + pgft->charmap = (int*)malloc(ph->charmap_len*4); + buf += read_table(buf, pgft->charmap, ph->charmap_len, ph->charmap_bpe); + + /* read charptr table */ + pgft->charptr = (int*)malloc(ph->charptr_len*4); + buf += read_table(buf, pgft->charptr, ph->charptr_len, ph->charptr_bpe); + for(i=0; icharptr_len; i++){ + pgft->charptr[i] *= ph->charptr_scale; + } + + /* font glyph data */ + pgft->glyphdata = buf; + + load_all_glyph(pgft); + + return pgft; +} + +PGF_GLYPH *get_glyph(PGF_FONT *pgft, int ucs) +{ + return pgft->char_glyph[ucs]; +} + +void free_glyph(PGF_FONT *pgft, PGF_GLYPH *glyph) +{ + int ucs; + + ucs = glyph->ucs; + free(glyph->bmp); + free(glyph); + pgft->char_glyph[ucs] = 0; +} + +void free_pgf_font(PGF_FONT *pgft) +{ + + +} + + + +/******************************************************************************/ + typedef u32 FontLibraryHandle; typedef u32 FontHandle; diff --git a/Core/HLE/sceFont.h b/Core/HLE/sceFont.h index 81d095c5b..c1802a908 100644 --- a/Core/HLE/sceFont.h +++ b/Core/HLE/sceFont.h @@ -6,3 +6,132 @@ void Register_sceFont(); void __FontInit(); void __FontDoState(PointerWrap &p); + + +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; + +typedef struct f26_pairs { + int h; + int v; +} F26_PAIRS; + +typedef struct pgf_header_t { + /* 0x0000 */ + u16 header_start; + u16 header_len; + u8 pgf_id[4]; + u32 revision; + u32 version; + + /* 0x0010 */ + int charmap_len; + int charptr_len; + int charmap_bpe; + int charptr_bpe; + + /* 0x0020 */ + u8 unk_20[2]; /* 04 04 */ + u8 bpp; /* 04 */ + u8 unk_23; /* 00 */ + + u32 h_size; + u32 v_size; + u32 h_res; + u32 v_res; + + u8 unk_34; /* 00 */ + u8 font_name[64]; /* "FTT-NewRodin Pro DB" */ + u8 font_type[64]; /* "Regular" */ + u8 unk_B5; /* 00 */ + + u16 charmap_min; + u16 charmap_max; + + /* 0x00BA */ + u16 unk_BA; /* 0x0000 */ + u32 unk_BC; /* 0x00010000 */ + u32 unk_C0; /* 0x00000000 */ + u32 unk_C4; /* 0x00000000 */ + u32 unk_C8; /* 0x00010000 */ + u32 unk_CC; /* 0x00000000 */ + u32 unk_D0; /* 0x00000000 */ + + int ascender; + int descender; + int max_h_bearingX; + int max_h_bearingY; + int min_v_bearingX; + int max_v_bearingY; + int max_h_advance; + int max_v_advance; + int max_h_dimension; + int max_v_dimension; + u16 max_glyph_w; + u16 max_glyph_h; + + /* 0x0100 */ + u16 charptr_scale; /* 0004 */ + u8 dimension_len; + u8 bearingX_len; + u8 bearingY_len; + u8 advance_len; + u8 unk_106[102]; /* 00 00 ... ... 00 */ + + u32 shadowmap_len; + u32 shadowmap_bpe; + u32 unk_174; + u32 shadowscale_x; + u32 shadowscale_y; + u32 unk_180; + u32 unk_184; +} PGF_HEADER; + +typedef struct glyph_t { + int index; + int ucs; + int have_shadow; + + int size; /* 14bits */ + int width; /* 7bits */ + int height; /* 7bits */ + int left; /* 7bits signed */ + int top; /* 7bits signed */ + int flag; /* 6bits: 2+1+1+1+1 */ + + int shadow_flag;/* 7bits: 2+2+3 */ + int shadow_id; /* 9bits */ + + F26_PAIRS dimension; + F26_PAIRS bearingX; + F26_PAIRS bearingY; + F26_PAIRS advance; + + u8 *data; + u8 *bmp; +} PGF_GLYPH; + +typedef struct pgf_font_t { + u8 *buf; + + PGF_HEADER *ph; + + struct f26_pairs *dimension; + struct f26_pairs *bearingX; + struct f26_pairs *bearingY; + struct f26_pairs *advance; + + int *charmap; + int *charptr; + int *shadowmap; + + u8 *glyphdata; + PGF_GLYPH *char_glyph[65536]; + PGF_GLYPH *shadow_glyph[512]; + +} PGF_FONT; + + + + diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 4a6262b41..445739ea5 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -69,6 +69,7 @@ Level3 Disabled ../common;..;../native;../native/ext/glew; + _MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true @@ -94,6 +95,7 @@ false StreamingSIMDExtensions2 Fast + _MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 019fde5bc..cd964dba6 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -96,7 +96,7 @@ Disabled - WIN32;_DEBUG;%(PreprocessorDefinitions) + WIN32;_DEBUG;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true Sync Use @@ -151,7 +151,7 @@ true Speed true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true Sync MultiThreadedDLL diff --git a/ext/libkirk/libkirk.vcxproj b/ext/libkirk/libkirk.vcxproj index 20cba7c8c..e4e5f463b 100644 --- a/ext/libkirk/libkirk.vcxproj +++ b/ext/libkirk/libkirk.vcxproj @@ -95,6 +95,7 @@ false StreamingSIMDExtensions2 Fast + _MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true diff --git a/ext/zlib/zlib.vcxproj b/ext/zlib/zlib.vcxproj index be9c34926..e7ec0a542 100644 --- a/ext/zlib/zlib.vcxproj +++ b/ext/zlib/zlib.vcxproj @@ -99,7 +99,7 @@ Level3 Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS Windows @@ -127,7 +127,7 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS StreamingSIMDExtensions2 false Fast diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index ecfadbd1a..ef0e4a994 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -80,7 +80,7 @@ NotUsing Level3 Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS ../Common;..;../Core;../native/ext/glew;../native Default @@ -111,7 +111,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS ../Common;..;../Core;../native/ext/glew;../native false StreamingSIMDExtensions2 diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index ca9cb9312..757c39ee6 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -85,7 +85,7 @@ Level3 Disabled - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS ../common;..;../native;../native/ext/glew;../ext/zlib @@ -117,7 +117,7 @@ MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS ../common;..;../native;../native/ext/glew;../ext/zlib From 11dd7c57acc10d0559047375e850b799451ce12b Mon Sep 17 00:00:00 2001 From: tpu Date: Wed, 27 Feb 2013 23:49:57 +0800 Subject: [PATCH 2/6] PGF font works! Please put font file from flash0:/font/ to Flash/font/ --- Core/HLE/sceFont.cpp | 562 +++++++++++++++++++++++++------------------ Core/HLE/sceFont.h | 133 +++++++++- 2 files changed, 456 insertions(+), 239 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index bcc624657..9351699f0 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1,11 +1,20 @@ -#include "sceFont.h" + #include "base/timeutil.h" +#include "../Config.h" +#include "../Host.h" +#include "../SaveState.h" #include "HLE.h" #include "../MIPS/MIPS.h" -#include "ChunkFile.h" +#include "../FileSystems/FileSystem.h" +#include "../FileSystems/MetaFileSystem.h" +#include "../System.h" + + + +#include "sceFont.h" /******************************************************************************/ @@ -249,7 +258,7 @@ PGF_FONT *load_pgf_from_buf(u8 *buf, int length) buf += (ph->dimension_len*8); /* left bearing table */ - pgft->bearingX = (F26_PAIRS*)buf; + pgft->bearingX = (F26_PAIRS*)buf; buf += (ph->bearingX_len*8); /* top bearing table */ @@ -306,142 +315,55 @@ void free_pgf_font(PGF_FONT *pgft) } +/******************************************************************************/ +static const char *font_list[16] = { + "flash0:/font/jpn0.pgf", + "flash0:/font/ltn0.pgf", + "flash0:/font/ltn2.pgf", + "flash0:/font/ltn3.pgf", + "flash0:/font/ltn4.pgf", + "flash0:/font/ltn5.pgf", + "flash0:/font/ltn6.pgf", + "flash0:/font/ltn7.pgf", + "flash0:/font/ltn8.pgf", + "flash0:/font/ltn9.pgf", + "flash0:/font/ltn10.pgf", + "flash0:/font/ltn11.pgf", + "flash0:/font/ltn12.pgf", + "flash0:/font/ltn13.pgf", + "flash0:/font/ltn14.pgf", + "flash0:/font/ltn15.pgf", +}; +static int font_num = 16; + +static PGF_FONT *font_slot[8] = {NULL, }; + +static int get_font_slot(void) +{ + int i; + + for(i=0; i<8; i++){ + if(font_slot[i]==NULL) + return i; + } + + return -1; +} + +static float f26_float(int value) +{ + float f, t; + + f = (float)(value>>6); + t = (float)(value&0x3f); + f += t/64; + + return f; +} /******************************************************************************/ -typedef u32 FontLibraryHandle; -typedef u32 FontHandle; - -struct FontNewLibParams { - u32 userDataAddr; - u32 numFonts; - u32 cacheDataAddr; - - // Driver callbacks. - u32 allocFuncAddr; - u32 freeFuncAddr; - u32 openFuncAddr; - u32 closeFuncAddr; - u32 readFuncAddr; - u32 seekFuncAddr; - u32 errorFuncAddr; - u32 ioFinishFuncAddr; -}; - -typedef enum Family { - FONT_FAMILY_SANS_SERIF = 1, - FONT_FAMILY_SERIF = 2, -}; - -typedef enum Style { - FONT_STYLE_REGULAR = 1, - FONT_STYLE_ITALIC = 2, - FONT_STYLE_BOLD = 5, - FONT_STYLE_BOLD_ITALIC = 6, - FONT_STYLE_DB = 103, // Demi-Bold / semi-bold -}; - -typedef enum Language { - FONT_LANGUAGE_JAPANESE = 1, - FONT_LANGUAGE_LATIN = 2, - FONT_LANGUAGE_KOREAN = 3, -}; - -struct FontStyle { - float fontH; - float fontV; - float fontHRes; - float fontVRes; - float fontWeight; - u16 fontFamily; - u16 fontStyle; - // Check. - u16 fontStyleSub; - u16 fontLanguage; - u16 fontRegion; - u16 fontCountry; - char fontName[64]; - char fontFileName[64]; - u32 fontAttributes; - u32 fontExpire; -}; - -struct FontInfo { - // Glyph metrics (in 26.6 signed fixed-point). - u32 maxGlyphWidthI; - u32 maxGlyphHeightI; - u32 maxGlyphAscenderI; - u32 maxGlyphDescenderI; - u32 maxGlyphLeftXI; - u32 maxGlyphBaseYI; - u32 minGlyphCenterXI; - u32 maxGlyphTopYI; - u32 maxGlyphAdvanceXI; - u32 maxGlyphAdvanceYI; - - // Glyph metrics (replicated as float). - float maxGlyphWidthF; - float maxGlyphHeightF; - float maxGlyphAscenderF; - float maxGlyphDescenderF; - float maxGlyphLeftXF; - float maxGlyphBaseYF; - float minGlyphCenterXF; - float maxGlyphTopYF; - float maxGlyphAdvanceXF; - float maxGlyphAdvanceYF; - - // Bitmap dimensions. - short maxGlyphWidth; - short maxGlyphHeight; - u32 charMapLength; // Number of elements in the font's charmap. - u32 shadowMapLength; // Number of elements in the font's shadow charmap. - - // Font style (used by font comparison functions). - FontStyle fontStyle; - - u8 BPP; // Font's BPP. - u8 pad[3]; -}; - -struct CharInfo { - u32 bitmapWidth; - u32 bitmapHeight; - u32 bitmapLeft; - u32 bitmapTop; - // Glyph metrics (in 26.6 signed fixed-point). - u32 spf26Width; - u32 spf26Height; - s32 spf26Ascender; - s32 spf26Descender; - s32 spf26BearingHX; - s32 spf26BearingHY; - s32 spf26BearingVX; - s32 spf26BearingVY; - s32 spf26AdvanceH; - s32 spf26AdvanceV; - u8 pad[4]; -}; - -enum FontPixelFormat { - PSP_FONT_PIXELFORMAT_4 = 0, - PSP_FONT_PIXELFORMAT_4_REV = 1, - PSP_FONT_PIXELFORMAT_8 = 2, - PSP_FONT_PIXELFORMAT_24 = 3, - PSP_FONT_PIXELFORMAT_32 = 4 -}; - -struct GlyphImage { - FontPixelFormat pixelFormat; - s32 xPos64; - s32 yPos64; - u16 bufWidth; - u16 bufHeight; - u16 bytesPerLine; - u16 pad; - u32 bufferPtr; -}; FontNewLibParams fontLib; @@ -458,7 +380,7 @@ void __FontDoState(PointerWrap &p) u32 sceFontNewLib(u32 FontNewLibParamsPtr, u32 errorCodePtr) { - ERROR_LOG(HLE, "sceFontNewLib %x, %x", FontNewLibParamsPtr, errorCodePtr); + DEBUG_LOG(HLE, "sceFontNewLib %x, %x", FontNewLibParamsPtr, errorCodePtr); if (Memory::IsValidAddress(FontNewLibParamsPtr)&&Memory::IsValidAddress(errorCodePtr)) { @@ -469,55 +391,142 @@ u32 sceFontNewLib(u32 FontNewLibParamsPtr, u32 errorCodePtr) return 1; } - int sceFontDoneLib(u32 FontLibraryHandlePtr) { - ERROR_LOG(HLE, "sceFontDoneLib %x", FontLibraryHandlePtr); + DEBUG_LOG(HLE, "sceFontDoneLib %x", FontLibraryHandlePtr); return 0; } u32 sceFontOpen(u32 libHandle, u32 index, u32 mode, u32 errorCodePtr) { - ERROR_LOG(HLE, "sceFontDoneLib %x, %x, %x, %x", libHandle, index, mode, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - { - Memory::Write_U32(0, errorCodePtr); + int retv, slot; + u8 *buf; + + DEBUG_LOG(HLE, "sceFontDoneLib %x, %x, %x, %x", libHandle, index, mode, errorCodePtr); + + retv = 0; + slot = get_font_slot(); + if(slot==-1){ + retv = -1; + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(-1, errorCodePtr); + return 0; } - return 1; + + index -= 1; + u32 h = pspFileSystem.OpenFile(font_list[index], FILEACCESS_READ); + if (h == 0){ + ERROR_LOG(HLE, "sceFontOpen: %s not found", font_list[index]); + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(-1, errorCodePtr); + return 0; + } + + PSPFileInfo info = pspFileSystem.GetFileInfo(font_list[index]); + buf = (u8*)malloc((size_t)info.size); + pspFileSystem.ReadFile(h, buf, info.size); + pspFileSystem.CloseFile(h); + + font_slot[slot] = load_pgf_from_buf(buf, (int)info.size); + + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(0, errorCodePtr); + + return slot+1; } u32 sceFontOpenUserMemory(u32 libHandle, u32 memoryFontAddrPtr, u32 memoryFontLength, u32 errorCodePtr) { - ERROR_LOG(HLE, "sceFontOpenUserMemory %x, %x, %x, %x", libHandle, memoryFontAddrPtr, memoryFontLength, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - { - Memory::Write_U32(0, errorCodePtr); + int retv, slot; + u8 *buf; + + DEBUG_LOG(HLE, "sceFontOpenUserMemory %x, %x, %x, %x", libHandle, memoryFontAddrPtr, memoryFontLength, errorCodePtr); + + retv = 0; + slot = get_font_slot(); + if(slot==-1){ + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(-1, errorCodePtr); + return 0; } - return 1; + + if (!Memory::IsValidAddress(memoryFontAddrPtr)){ + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(-1, errorCodePtr); + return 0; + } + buf = (u8*) Memory::GetPointer(memoryFontAddrPtr); + + font_slot[slot] = load_pgf_from_buf(buf, memoryFontLength); + + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(0, errorCodePtr); + + return slot+1; } u32 sceFontOpenUserFile(u32 libHandle, u32 fileNamePtr, u32 mode, u32 errorCodePtr) { - ERROR_LOG(HLE, "sceFontOpenUserFile %x, %x, %x, %x", libHandle, fileNamePtr, mode, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - { - Memory::Write_U32(0, errorCodePtr); + int retv, slot; + u8 *buf; + char *filename; + + DEBUG_LOG(HLE, "sceFontOpenUserFile %x, %x, %x, %x", libHandle, fileNamePtr, mode, errorCodePtr); + + retv = 0; + slot = get_font_slot(); + if(slot==-1){ + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(-1, errorCodePtr); + return 0; } - return 1; + + if (!Memory::IsValidAddress(fileNamePtr)){ + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(-1, errorCodePtr); + return 0; + } + filename = (char*) Memory::GetPointer(fileNamePtr); + + u32 h = pspFileSystem.OpenFile(filename, FILEACCESS_READ); + if (h == 0){ + ERROR_LOG(HLE, "sceFontOpenUserFIle: %s not found", filename); + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(-1, errorCodePtr); + return 0; + } + + PSPFileInfo info = pspFileSystem.GetFileInfo(filename); + buf = (u8*)malloc((size_t)info.size); + pspFileSystem.ReadFile(h, buf, info.size); + pspFileSystem.CloseFile(h); + + font_slot[slot] = load_pgf_from_buf(buf, (int)info.size); + + if (Memory::IsValidAddress(errorCodePtr)) + Memory::Write_U32(0, errorCodePtr); + + return slot+1; } int sceFontClose(u32 fontHandle) { - ERROR_LOG(HLE, "sceFontClose %x", fontHandle); + int slot; + + DEBUG_LOG(HLE, "sceFontClose %x", fontHandle); + + slot = fontHandle-1; + free_pgf_font(font_slot[slot]); + font_slot[slot] = NULL; + return 0; } int sceFontFindOptimumFont(u32 libHandlePtr, u32 fontStylePtr, u32 errorCodePtr) { - ERROR_LOG(HLE, "sceFontFindOptimumFont %x, %x, %x", libHandlePtr, fontStylePtr, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - { + DEBUG_LOG(HLE, "sceFontFindOptimumFont %x, %x, %x", libHandlePtr, fontStylePtr, errorCodePtr); + if (Memory::IsValidAddress(errorCodePtr)){ Memory::Write_U32(0, errorCodePtr); } return 1; @@ -525,84 +534,125 @@ int sceFontFindOptimumFont(u32 libHandlePtr, u32 fontStylePtr, u32 errorCodePtr) int sceFontFindFont(u32 libHandlePtr, u32 fontStylePtr, u32 errorCodePtr) { - ERROR_LOG(HLE, "sceFontFindFont %x, %x, %x", libHandlePtr, fontStylePtr, errorCodePtr); + DEBUG_LOG(HLE, "sceFontFindFont %x, %x, %x", libHandlePtr, fontStylePtr, errorCodePtr); + if (Memory::IsValidAddress(errorCodePtr)){ + Memory::Write_U32(0, errorCodePtr); + } return 1; } int sceFontGetFontInfo(u32 fontHandle, u32 fontInfoPtr) { - ERROR_LOG(HLE, "sceFontGetFontInfo %x, %x", fontHandle, fontInfoPtr); + PGF_FONT *pgft; + PGF_HEADER *ph; + int slot; + + DEBUG_LOG(HLE, "sceFontGetFontInfo %x, %x", fontHandle, fontInfoPtr); + + slot = fontHandle-1; + pgft = font_slot[slot]; + ph = (PGF_HEADER*)pgft->buf; FontInfo fi; memset (&fi, 0, sizeof(fi)); if (Memory::IsValidAddress(fontInfoPtr)) { fi.BPP = 4; - fi.charMapLength = 255; - fi.maxGlyphAdvanceXF = 2.0; - fi.maxGlyphAdvanceXI = 2; - fi.maxGlyphAdvanceYF = 2.0; - fi.maxGlyphAdvanceYI = 32 << 6; - fi.maxGlyphAscenderF = 32 << 6; - fi.maxGlyphAscenderI = 32 << 6; - fi.maxGlyphBaseYF = 0.0; - fi.maxGlyphBaseYI = 0; - fi.maxGlyphDescenderF = 0; - fi.maxGlyphDescenderI = 0; - fi.maxGlyphHeight = 32; - fi.maxGlyphHeightF = 32; - fi.maxGlyphHeightI = 32; - fi.maxGlyphLeftXF = 0; - fi.maxGlyphLeftXI = 0; - fi.maxGlyphTopYF = 0; - fi.maxGlyphTopYI = 0; - fi.maxGlyphWidth = 32; - fi.maxGlyphWidthF = 32; - fi.maxGlyphWidthI = 32; - fi.minGlyphCenterXF = 16; - fi.minGlyphCenterXI = 16; - fi.shadowMapLength = 0; - fi.fontStyle.fontAttributes=1; - fi.fontStyle.fontCountry= 1; - fi.fontStyle.fontExpire= 1; - fi.fontStyle.fontFamily= 1; - strcpy(fi.fontStyle.fontFileName, "asd"); - fi.fontStyle.fontH=32; - fi.fontStyle.fontHRes=32; - fi.fontStyle.fontLanguage=1; - strcpy(fi.fontStyle.fontName, "ppsspp"); - fi.fontStyle.fontRegion=9; - fi.fontStyle.fontV=32; - fi.fontStyle.fontVRes=32; - fi.fontStyle.fontWeight= 32; + fi.charMapLength = ph->charmap_len; + fi.shadowMapLength = ph->shadowmap_len; + + fi.maxInfoI.width = ph->max_glyph_w<<6; + fi.maxInfoI.height = ph->max_glyph_h<<6; + fi.maxInfoI.ascender = ph->ascender; + fi.maxInfoI.descender = ph->descender; + fi.maxInfoI.h_bearingX = ph->max_h_bearingX; + fi.maxInfoI.h_bearingY = ph->max_h_bearingY; + fi.maxInfoI.v_bearingX = ph->min_v_bearingX; + fi.maxInfoI.v_bearingY = ph->max_v_bearingY; + fi.maxInfoI.h_advance = ph->max_h_advance; + fi.maxInfoI.v_advance = ph->max_v_advance; + + fi.maxInfoF.width = (float)(ph->max_glyph_w); + fi.maxInfoF.height = (float)(ph->max_glyph_h); + fi.maxInfoF.ascender = f26_float(ph->ascender); + fi.maxInfoF.descender = f26_float(ph->descender); + fi.maxInfoF.h_bearingX = f26_float(ph->max_h_bearingX); + fi.maxInfoF.h_bearingY = f26_float(ph->max_h_bearingY); + fi.maxInfoF.v_bearingX = f26_float(ph->min_v_bearingX); + fi.maxInfoF.v_bearingY = f26_float(ph->max_v_bearingY); + fi.maxInfoF.h_advance = f26_float(ph->max_h_advance); + fi.maxInfoF.v_advance = f26_float(ph->max_v_advance); + + fi.maxGlyphHeight = ph->max_glyph_h; + fi.maxGlyphWidth = ph->max_glyph_w; + + fi.fontStyle.fontAttributes = 1; + fi.fontStyle.fontCountry = 1; + fi.fontStyle.fontExpire = 1; + fi.fontStyle.fontFamily = 1; + fi.fontStyle.fontH = f26_float(ph->h_size); + fi.fontStyle.fontHRes = f26_float(ph->h_res); + fi.fontStyle.fontLanguage = 1; + fi.fontStyle.fontRegion = 9; + fi.fontStyle.fontV = f26_float(ph->v_size); + fi.fontStyle.fontVRes = f26_float(ph->v_res); + fi.fontStyle.fontWeight = 32; + strcpy(fi.fontStyle.fontFileName, font_list[slot]); + strcpy(fi.fontStyle.fontName, (const char*)ph->font_name); + Memory::WriteStruct(fontInfoPtr, &fi); } return 0; } -int sceFontGetFontInfoByIndexNumber(u32 libHandle, u32 fontInfoPtr, u32 unknown, u32 fontIndex) +int sceFontGetFontInfoByIndexNumber(u32 libHandle, u32 fontInfoPtr, u32 fontIndex) { - ERROR_LOG(HLE, "HACK sceFontGetFontInfoByIndexNumber %x, %x, %x, %x", libHandle, fontInfoPtr, unknown, fontIndex); + ERROR_LOG(HLE, "HACK sceFontGetFontInfoByIndexNumber %x, %x, %x", libHandle, fontInfoPtr, fontIndex); // clearly wrong.. - return sceFontGetFontInfo(libHandle, fontInfoPtr); + return -1; } int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) { - ERROR_LOG(HLE, "HACK sceFontGetCharInfo %x, %x, %x", fontHandle, charCode, charInfoPtr); - if (Memory::IsValidAddress(charInfoPtr)) - { - CharInfo pspCharInfo; - memset(&pspCharInfo, 0, sizeof(pspCharInfo)); - pspCharInfo.bitmapWidth = 16; - pspCharInfo.bitmapHeight = 16; + PGF_FONT *pgft; + PGF_HEADER *ph; + PGF_GLYPH *gh; + int slot; + + DEBUG_LOG(HLE, "HACK sceFontGetCharInfo %x, %x, %x", fontHandle, charCode, charInfoPtr); + + slot = fontHandle-1; + pgft = font_slot[slot]; + if(pgft==NULL) + return -1; + + ph = (PGF_HEADER*)pgft->buf; + gh = pgft->char_glyph[charCode]; + if(gh==NULL) + return -2; + + if (Memory::IsValidAddress(charInfoPtr)) { + CharInfo pspCharInfo; + memset(&pspCharInfo, 0, sizeof(pspCharInfo)); + + pspCharInfo.bitmapWidth = gh->width; + pspCharInfo.bitmapHeight = gh->height; + pspCharInfo.bitmapLeft = gh->left; + pspCharInfo.bitmapTop = gh->top; + + pspCharInfo.info.width = gh->dimension.h; + pspCharInfo.info.height = gh->dimension.v; + pspCharInfo.info.ascender = ph->ascender; + pspCharInfo.info.descender = ph->descender; + pspCharInfo.info.h_bearingX = gh->bearingX.h; + pspCharInfo.info.h_bearingY = gh->bearingY.h; + pspCharInfo.info.v_bearingX = gh->bearingX.v; + pspCharInfo.info.v_bearingY = gh->bearingY.v; + pspCharInfo.info.h_advance = gh->advance.h; + pspCharInfo.info.v_advance = gh->advance.v; - pspCharInfo.spf26Width = pspCharInfo.bitmapWidth << 6; - pspCharInfo.spf26Height = pspCharInfo.bitmapHeight << 6; - pspCharInfo.spf26AdvanceH = pspCharInfo.bitmapWidth << 6; - pspCharInfo.spf26AdvanceV = pspCharInfo.bitmapHeight << 6; Memory::WriteStruct(charInfoPtr, &pspCharInfo); } return 0; @@ -610,36 +660,77 @@ int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) int sceFontGetCharImageRect(u32 fontHandle, u32 charCode, u32 charRectPtr) { - ERROR_LOG(HLE, "HACK sceFontGetCharImageRect %x, %x (%c)", fontHandle, charRectPtr, charCode); + PGF_FONT *pgft; + PGF_GLYPH *gh; + int slot; + + DEBUG_LOG(HLE, "HACK sceFontGetCharImageRect %x, %x (%c)", fontHandle, charRectPtr, charCode); + + slot = fontHandle-1; + pgft = font_slot[slot]; + if(pgft==NULL) + return -1; + + gh = pgft->char_glyph[charCode]; + if(gh==NULL) + return -2; + if (Memory::IsValidAddress(charRectPtr)) { - Memory::Write_U16(16, charRectPtr); // character bitmap width in pixels - Memory::Write_U16(16, charRectPtr + 2); // character bitmap height in pixels + Memory::Write_U16(gh->width, charRectPtr); // character bitmap width in pixels + Memory::Write_U16(gh->width, charRectPtr+2); // character bitmap height in pixels } + return 0; } int sceFontGetCharGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) { - ERROR_LOG(HLE, "HACK sceFontGetCharGlyphImage %x, %x, %x (%c)", fontHandle, charCode, glyphImagePtr, charCode); + PGF_FONT *pgft; + PGF_GLYPH *gh; + int slot; + u8 line_buf[512]; - int pixelFormat = Memory::Read_U32(glyphImagePtr); - int xPos64 = Memory::Read_U32(glyphImagePtr+4); - int yPos64 = Memory::Read_U32(glyphImagePtr+8); - int bufWidth = Memory::Read_U16(glyphImagePtr+12); - int bufHeight = Memory::Read_U16(glyphImagePtr+14); + DEBUG_LOG(HLE, "HACK sceFontGetCharGlyphImage %x, %x, %x (%c)", fontHandle, charCode, glyphImagePtr, charCode); + + slot = fontHandle-1; + pgft = font_slot[slot]; + if(pgft==NULL) + return -1; + + gh = pgft->char_glyph[charCode]; + if(gh==NULL) + return -2; + + int pixelFormat = Memory::Read_U32(glyphImagePtr); + int xPos64 = Memory::Read_U32(glyphImagePtr+4); + int yPos64 = Memory::Read_U32(glyphImagePtr+8); + int bufWidth = Memory::Read_U16(glyphImagePtr+12); + int bufHeight = Memory::Read_U16(glyphImagePtr+14); int bytesPerLine = Memory::Read_U16(glyphImagePtr+16); - int buffer = Memory::Read_U32(glyphImagePtr+20); + int buffer = Memory::Read_U32(glyphImagePtr+20); - // Small chessboard. Does not respect pixelformat currently... + xPos64 = (xPos64+32)>>6; + yPos64 = (yPos64+32)>>6; - // Actually should be really easy to substitute in a proper font here... - // could even grab pixel data from the PPGe one. - for (int y = 0; y < bufHeight; y++) - { - for (int x = 0; x < bytesPerLine; x++) - { - Memory::Write_U8((((x >> 1) ^ (y >> 1)) & 1) ? 0xff : 0x00, buffer + (y * bytesPerLine + x)); + int line = buffer + yPos64*bytesPerLine; + u8 *src = gh->bmp; + + for (int y=0; yheight; y++) { + Memory::Memcpy(line_buf, line, bytesPerLine); + int xp = xPos64; + for (int x=0; xwidth; x++) { + if(xp&1){ + line_buf[xp/2] &= 0x0f; + line_buf[xp/2] |= (*src)<<4; + }else{ + line_buf[xp/2] &= 0xf0; + line_buf[xp/2] |= (*src); + } + xp += 1; + src += 1; } + Memory::Memcpy(line, line_buf, bytesPerLine); + line += bytesPerLine; } return 0; @@ -647,14 +738,13 @@ int sceFontGetCharGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) int sceFontGetCharGlyphImage_Clip(u32 libHandler, u32 charCode, u32 glyphImagePtr, int clipXPos, int clipYPos, int clipWidth, int clipHeight) { - ERROR_LOG(HLE, "sceFontGetCharGlyphImage_Clip %x, %x, %x (%c)", libHandler, charCode, glyphImagePtr, charCode); - //sceFontGetCharGlyphImage(libHandler, charCode, glyphImagePtr); - return 0; + DEBUG_LOG(HLE, "sceFontGetCharGlyphImage_Clip %x, %x, %x (%c)", libHandler, charCode, glyphImagePtr, charCode); + return sceFontGetCharGlyphImage(libHandler, charCode, glyphImagePtr); } int sceFontSetAltCharacterCode(u32 libHandle, u32 charCode) { - ERROR_LOG(HLE, "sceFontSetAltCharacterCode %x (%c)", libHandle, charCode); + DEBUG_LOG(HLE, "sceFontSetAltCharacterCode %x (%c)", libHandle, charCode); return 0; } @@ -666,7 +756,7 @@ int sceFontFlush(u32 fontHandle) int sceFontGetFontList(u32 fontLibHandle, u32 fontStylePtr, u32 numFonts) { - ERROR_LOG(HLE, "sceFontGetFontList %x, %x, %x", fontLibHandle, fontStylePtr, numFonts); + DEBUG_LOG(HLE, "sceFontGetFontList %x, %x, %x", fontLibHandle, fontStylePtr, numFonts); FontStyle style; memset(&style, 0, sizeof (style)); @@ -687,12 +777,12 @@ int sceFontGetFontList(u32 fontLibHandle, u32 fontStylePtr, u32 numFonts) int sceFontGetNumFontList(u32 libHandle, u32 errorCodePtr) { - ERROR_LOG(HLE, "UNIMPL sceFontGetNumFontList %x, %x", libHandle, errorCodePtr); + DEBUG_LOG(HLE, "UNIMPL sceFontGetNumFontList %x, %x", libHandle, errorCodePtr); if (Memory::IsValidAddress(errorCodePtr)) { Memory::Write_U32(0, errorCodePtr); } - return 1; + return font_num; } int sceFontSetResolution(u32 fontLibHandle, float hRes, float vRes) @@ -718,7 +808,7 @@ const HLEFunction sceLibFont[] = {0x099ef33c, WrapI_UUU, "sceFontFindOptimumFont"}, {0x681e61a7, WrapI_UUU, "sceFontFindFont"}, {0x2f67356a, WrapI_V, "sceFontCalcMemorySize"}, - {0x5333322d, WrapI_UUUU, "sceFontGetFontInfoByIndexNumber"}, + {0x5333322d, WrapI_UUU, "sceFontGetFontInfoByIndexNumber"}, {0xa834319d, WrapU_UUUU, "sceFontOpen"}, {0x57fcb733, WrapU_UUUU, "sceFontOpenUserFile"}, {0xbb8e7fe6, WrapU_UUUU, "sceFontOpenUserMemory"}, diff --git a/Core/HLE/sceFont.h b/Core/HLE/sceFont.h index c1802a908..a29bb89fd 100644 --- a/Core/HLE/sceFont.h +++ b/Core/HLE/sceFont.h @@ -7,10 +7,137 @@ void Register_sceFont(); void __FontInit(); void __FontDoState(PointerWrap &p); +typedef u32 FontLibraryHandle; +typedef u32 FontHandle; + +struct FontNewLibParams { + u32 userDataAddr; + u32 numFonts; + u32 cacheDataAddr; + + // Driver callbacks. + u32 allocFuncAddr; + u32 freeFuncAddr; + u32 openFuncAddr; + u32 closeFuncAddr; + u32 readFuncAddr; + u32 seekFuncAddr; + u32 errorFuncAddr; + u32 ioFinishFuncAddr; +}; + +typedef enum Family { + FONT_FAMILY_SANS_SERIF = 1, + FONT_FAMILY_SERIF = 2, +}; + +typedef enum Style { + FONT_STYLE_REGULAR = 1, + FONT_STYLE_ITALIC = 2, + FONT_STYLE_BOLD = 5, + FONT_STYLE_BOLD_ITALIC = 6, + FONT_STYLE_DB = 103, // Demi-Bold / semi-bold +}; + +typedef enum Language { + FONT_LANGUAGE_JAPANESE = 1, + FONT_LANGUAGE_LATIN = 2, + FONT_LANGUAGE_KOREAN = 3, +}; + +struct FontStyle { + float fontH; + float fontV; + float fontHRes; + float fontVRes; + float fontWeight; + u16 fontFamily; + u16 fontStyle; + // Check. + u16 fontStyleSub; + u16 fontLanguage; + u16 fontRegion; + u16 fontCountry; + char fontName[64]; + char fontFileName[64]; + u32 fontAttributes; + u32 fontExpire; +}; + +struct iMerticsInfo{ + // Glyph metrics (in 26.6 signed fixed-point). + u32 width; + u32 height; + u32 ascender; + u32 descender; + u32 h_bearingX; + u32 h_bearingY; + u32 v_bearingX; + u32 v_bearingY; + u32 h_advance; + u32 v_advance; +}; + +struct fMerticsInfo{ + // Glyph metrics (in 26.6 signed fixed-point). + float width; + float height; + float ascender; + float descender; + float h_bearingX; + float h_bearingY; + float v_bearingX; + float v_bearingY; + float h_advance; + float v_advance; +}; + +struct FontInfo { + struct iMerticsInfo maxInfoI; + struct fMerticsInfo maxInfoF; + + // Bitmap dimensions. + short maxGlyphWidth; + short maxGlyphHeight; + u32 charMapLength; // Number of elements in the font's charmap. + u32 shadowMapLength; // Number of elements in the font's shadow charmap. + + // Font style (used by font comparison functions). + FontStyle fontStyle; + + u8 BPP; // Font's BPP. + u8 pad[3]; +}; + +struct CharInfo { + u32 bitmapWidth; + u32 bitmapHeight; + u32 bitmapLeft; + u32 bitmapTop; + // Glyph metrics (in 26.6 signed fixed-point). + struct iMerticsInfo info; + u8 pad[4]; +}; + +enum FontPixelFormat { + PSP_FONT_PIXELFORMAT_4 = 0, + PSP_FONT_PIXELFORMAT_4_REV = 1, + PSP_FONT_PIXELFORMAT_8 = 2, + PSP_FONT_PIXELFORMAT_24 = 3, + PSP_FONT_PIXELFORMAT_32 = 4 +}; + +struct GlyphImage { + FontPixelFormat pixelFormat; + s32 xPos64; + s32 yPos64; + u16 bufWidth; + u16 bufHeight; + u16 bytesPerLine; + u16 pad; + u32 bufferPtr; +}; -typedef unsigned int u32; -typedef unsigned short u16; -typedef unsigned char u8; typedef struct f26_pairs { int h; From 8161a2cfd0b1e203d40fe99d588352a957a16530 Mon Sep 17 00:00:00 2001 From: tpu Date: Fri, 15 Mar 2013 22:45:08 +0800 Subject: [PATCH 3/6] sceFont: remove load_all_glyph(). Load glyph runtime. add sceFontFindOptimumFont. sceIo: PGD handle bug fix. --- Core/HLE/sceFont.cpp | 248 +++++++++++++++++++++++++++--------- Core/HLE/sceGe.cpp | 4 +- Core/HLE/sceIo.cpp | 22 +++- Core/HLE/sceKernelMutex.cpp | 4 +- Core/MemMap.h | 2 +- 5 files changed, 213 insertions(+), 67 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 9351699f0..5c247cb76 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -62,6 +62,18 @@ static u32 ptr2ucs(PGF_FONT *pgft, int ptr) return 0xffff; } +static u32 ucs2ptr(PGF_FONT *pgft, int ucs) +{ + PGF_HEADER *ph; + int ptr; + + ph = (PGF_HEADER*)pgft->buf; + ucs -= ph->charmap_min; + ptr = pgft->charmap[ucs]; + + return ptr; +} + static int have_shadow(PGF_FONT *pgft, u32 ucs) { PGF_HEADER *ph; @@ -238,6 +250,7 @@ int load_all_glyph(PGF_FONT *pgft) } + PGF_FONT *load_pgf_from_buf(u8 *buf, int length) { PGF_FONT *pgft; @@ -289,14 +302,51 @@ PGF_FONT *load_pgf_from_buf(u8 *buf, int length) /* font glyph data */ pgft->glyphdata = buf; - load_all_glyph(pgft); + //load_all_glyph(pgft); return pgft; } -PGF_GLYPH *get_glyph(PGF_FONT *pgft, int ucs) +PGF_FONT *load_pgf_from_file(const char *filename) { - return pgft->char_glyph[ucs]; + u32 h = pspFileSystem.OpenFile(filename, FILEACCESS_READ); + if (h == 0){ + ERROR_LOG(HLE, "load_pgf_from_file: %s not found", filename); + return NULL; + } + + PSPFileInfo info = pspFileSystem.GetFileInfo(filename); + u8 *buf = (u8*)malloc((size_t)info.size); + pspFileSystem.ReadFile(h, buf, info.size); + pspFileSystem.CloseFile(h); + + PGF_FONT *pgft = load_pgf_from_buf(buf, (int)info.size); + + return pgft; +} + +PGF_GLYPH *get_glyph(PGF_FONT *pgft, u32 ucs) +{ + PGF_GLYPH *gh; + PGF_HEADER *ph; + int ptr; + + ph = (PGF_HEADER*)pgft->buf; + + gh = pgft->char_glyph[ucs]; + if(gh==NULL){ + ptr = ucs2ptr(pgft, ucs); + if(ptr>ph->charptr_len) + ptr = ucs2ptr(pgft, '?'); + + gh = (PGF_GLYPH*)malloc(sizeof(PGF_GLYPH)); + memset(gh, 0, sizeof(PGF_GLYPH)); + gh->ucs = ucs; + pgft->char_glyph[ucs] = gh; + load_char_glyph(pgft, ptr, gh); + } + + return gh; } void free_glyph(PGF_FONT *pgft, PGF_GLYPH *glyph) @@ -311,15 +361,79 @@ void free_glyph(PGF_FONT *pgft, PGF_GLYPH *glyph) void free_pgf_font(PGF_FONT *pgft) { + PGF_HEADER *ph; + int i; + ph = (PGF_HEADER*)pgft->buf; + for(i=0; i<65536; i++){ + if(pgft->char_glyph[i]) + free_glyph(pgft, pgft->char_glyph[i]); + } + + for(i=0; i<512; i++){ + if(pgft->shadow_glyph[i]){ + free(pgft->shadow_glyph[i]->bmp); + free(pgft->shadow_glyph[i]); + } + } + + if(ph->shadowmap_len){ + free(pgft->shadowmap); + } + free(pgft->charmap); + free(pgft->charptr); + + free(pgft->buf); + free(pgft); } /******************************************************************************/ -static const char *font_list[16] = { +struct FontRegistryEntry { + int hSize; + int vSize; + int hResolution; + int vResolution; + int extraAttributes; + int weight; + int familyCode; + int style; + int styleSub; + int languageCode; + int regionCode; + int countryCode; + const char *fileName; + const char *fontName; + int expireDate; + int shadow_option; +}; + +static const FontRegistryEntry fontRegistry[] = { + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_JAPANESE, 0, 1, "jpn0.pgf", "FTT-NewRodin Pro DB", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn0.pgf", "FTT-NewRodin Pro Latin", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn1.pgf", "FTT-Matisse Pro Latin", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn2.pgf", "FTT-NewRodin Pro Latin", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn3.pgf", "FTT-Matisse Pro Latin", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn4.pgf", "FTT-NewRodin Pro Latin", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn5.pgf", "FTT-Matisse Pro Latin", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn6.pgf", "FTT-NewRodin Pro Latin", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn7.pgf", "FTT-Matisse Pro Latin", 0, 0}, + {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn8.pgf", "FTT-NewRodin Pro Latin", 0, 0}, + {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn9.pgf", "FTT-Matisse Pro Latin", 0, 0}, + {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn10.pgf", "FTT-NewRodin Pro Latin", 0, 0}, + {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn11.pgf", "FTT-Matisse Pro Latin", 0, 0}, + {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn12.pgf", "FTT-NewRodin Pro Latin", 0, 0}, + {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn13.pgf", "FTT-Matisse Pro Latin", 0, 0}, + {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn14.pgf", "FTT-NewRodin Pro Latin", 0, 0}, + {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn15.pgf", "FTT-Matisse Pro Latin", 0, 0}, + {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_KOREAN, 0, 3, "kr0.pgf", "AsiaNHH(512Johab)", 0, 0}, +}; + +static const char *font_list[18] = { "flash0:/font/jpn0.pgf", "flash0:/font/ltn0.pgf", + "flash0:/font/ltn1.pgf", "flash0:/font/ltn2.pgf", "flash0:/font/ltn3.pgf", "flash0:/font/ltn4.pgf", @@ -334,8 +448,9 @@ static const char *font_list[16] = { "flash0:/font/ltn13.pgf", "flash0:/font/ltn14.pgf", "flash0:/font/ltn15.pgf", + "flash0:/font/kr0.pgf", }; -static int font_num = 16; +static int font_num = 18; static PGF_FONT *font_slot[8] = {NULL, }; @@ -362,6 +477,41 @@ static float f26_float(int value) return f; } +void show_style_info(struct FontStyle *s) +{ + INFO_LOG(HLE, "FontStyle: H=%f V=%f Hres=%f Vres=%f Weight=%f", s->fontH, s->fontV, s->fontHRes, s->fontVRes, s->fontWeight); + INFO_LOG(HLE, "FontStyle: family=%d style=%d substyle=%d", s->fontFamily, s->fontStyle, s->fontStyleSub); + INFO_LOG(HLE, "FontStyle: language=%d region=%d country=%d", s->fontLanguage, s->fontRegion, s->fontCountry); + INFO_LOG(HLE, "FontStyle: fontname=%s filename=%s", s->fontName, s->fontFileName); +} + +int match_font(struct FontStyle *s) +{ + int i; + int score, max_score, font_index; + + max_score = -1; + for(i=0; ifontLanguage) + score += 0x01000000; + if(fontRegistry[i].familyCode==s->fontFamily) + score += 0x00100000; + if(fontRegistry[i].style==s->fontStyle) + score += 0x00010000; + if(fontRegistry[i].hSize==s->fontH) + score += 0x00001000; + + if(score>max_score){ + max_score = score; + font_index = i; + } + } + + return font_index; +} + /******************************************************************************/ @@ -399,37 +549,26 @@ int sceFontDoneLib(u32 FontLibraryHandlePtr) u32 sceFontOpen(u32 libHandle, u32 index, u32 mode, u32 errorCodePtr) -{ - int retv, slot; - u8 *buf; + { + int slot; - DEBUG_LOG(HLE, "sceFontDoneLib %x, %x, %x, %x", libHandle, index, mode, errorCodePtr); + INFO_LOG(HLE, "sceFontOpen %x, %x, %x, %x", libHandle, index, mode, errorCodePtr); - retv = 0; slot = get_font_slot(); if(slot==-1){ - retv = -1; if (Memory::IsValidAddress(errorCodePtr)) Memory::Write_U32(-1, errorCodePtr); return 0; } index -= 1; - u32 h = pspFileSystem.OpenFile(font_list[index], FILEACCESS_READ); - if (h == 0){ - ERROR_LOG(HLE, "sceFontOpen: %s not found", font_list[index]); + + font_slot[slot] = load_pgf_from_file(font_list[index]); + if(font_slot[slot]==NULL){ if (Memory::IsValidAddress(errorCodePtr)) Memory::Write_U32(-1, errorCodePtr); - return 0; } - PSPFileInfo info = pspFileSystem.GetFileInfo(font_list[index]); - buf = (u8*)malloc((size_t)info.size); - pspFileSystem.ReadFile(h, buf, info.size); - pspFileSystem.CloseFile(h); - - font_slot[slot] = load_pgf_from_buf(buf, (int)info.size); - if (Memory::IsValidAddress(errorCodePtr)) Memory::Write_U32(0, errorCodePtr); @@ -441,7 +580,7 @@ u32 sceFontOpenUserMemory(u32 libHandle, u32 memoryFontAddrPtr, u32 memoryFontLe int retv, slot; u8 *buf; - DEBUG_LOG(HLE, "sceFontOpenUserMemory %x, %x, %x, %x", libHandle, memoryFontAddrPtr, memoryFontLength, errorCodePtr); + INFO_LOG(HLE, "sceFontOpenUserMemory %x, %x, %x, %x", libHandle, memoryFontAddrPtr, memoryFontLength, errorCodePtr); retv = 0; slot = get_font_slot(); @@ -468,13 +607,11 @@ u32 sceFontOpenUserMemory(u32 libHandle, u32 memoryFontAddrPtr, u32 memoryFontLe u32 sceFontOpenUserFile(u32 libHandle, u32 fileNamePtr, u32 mode, u32 errorCodePtr) { - int retv, slot; - u8 *buf; + int slot; char *filename; - DEBUG_LOG(HLE, "sceFontOpenUserFile %x, %x, %x, %x", libHandle, fileNamePtr, mode, errorCodePtr); + INFO_LOG(HLE, "sceFontOpenUserFile %x, %x, %x, %x", libHandle, fileNamePtr, mode, errorCodePtr); - retv = 0; slot = get_font_slot(); if(slot==-1){ if (Memory::IsValidAddress(errorCodePtr)) @@ -489,21 +626,12 @@ u32 sceFontOpenUserFile(u32 libHandle, u32 fileNamePtr, u32 mode, u32 errorCodeP } filename = (char*) Memory::GetPointer(fileNamePtr); - u32 h = pspFileSystem.OpenFile(filename, FILEACCESS_READ); - if (h == 0){ - ERROR_LOG(HLE, "sceFontOpenUserFIle: %s not found", filename); + font_slot[slot] = load_pgf_from_file(filename); + if(font_slot[slot]==NULL){ if (Memory::IsValidAddress(errorCodePtr)) Memory::Write_U32(-1, errorCodePtr); - return 0; } - PSPFileInfo info = pspFileSystem.GetFileInfo(filename); - buf = (u8*)malloc((size_t)info.size); - pspFileSystem.ReadFile(h, buf, info.size); - pspFileSystem.CloseFile(h); - - font_slot[slot] = load_pgf_from_buf(buf, (int)info.size); - if (Memory::IsValidAddress(errorCodePtr)) Memory::Write_U32(0, errorCodePtr); @@ -514,7 +642,7 @@ int sceFontClose(u32 fontHandle) { int slot; - DEBUG_LOG(HLE, "sceFontClose %x", fontHandle); + INFO_LOG(HLE, "sceFontClose %x", fontHandle); slot = fontHandle-1; free_pgf_font(font_slot[slot]); @@ -525,16 +653,28 @@ int sceFontClose(u32 fontHandle) int sceFontFindOptimumFont(u32 libHandlePtr, u32 fontStylePtr, u32 errorCodePtr) { - DEBUG_LOG(HLE, "sceFontFindOptimumFont %x, %x, %x", libHandlePtr, fontStylePtr, errorCodePtr); + int font_index; + + INFO_LOG(HLE, "sceFontFindOptimumFont %x, %x, %x", libHandlePtr, fontStylePtr, errorCodePtr); + + FontStyle s; + + Memory::ReadStruct(fontStylePtr, &s); + show_style_info(&s); + + font_index = match_font(&s); + INFO_LOG(HLE, "sceFontFindOptimumFont: match %s", font_list[font_index]); + if (Memory::IsValidAddress(errorCodePtr)){ Memory::Write_U32(0, errorCodePtr); } - return 1; + + return font_index+1; } int sceFontFindFont(u32 libHandlePtr, u32 fontStylePtr, u32 errorCodePtr) { - DEBUG_LOG(HLE, "sceFontFindFont %x, %x, %x", libHandlePtr, fontStylePtr, errorCodePtr); + INFO_LOG(HLE, "sceFontFindFont %x, %x, %x", libHandlePtr, fontStylePtr, errorCodePtr); if (Memory::IsValidAddress(errorCodePtr)){ Memory::Write_U32(0, errorCodePtr); } @@ -547,7 +687,7 @@ int sceFontGetFontInfo(u32 fontHandle, u32 fontInfoPtr) PGF_HEADER *ph; int slot; - DEBUG_LOG(HLE, "sceFontGetFontInfo %x, %x", fontHandle, fontInfoPtr); + INFO_LOG(HLE, "sceFontGetFontInfo %x, %x", fontHandle, fontInfoPtr); slot = fontHandle-1; pgft = font_slot[slot]; @@ -621,7 +761,7 @@ int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) PGF_GLYPH *gh; int slot; - DEBUG_LOG(HLE, "HACK sceFontGetCharInfo %x, %x, %x", fontHandle, charCode, charInfoPtr); + INFO_LOG(HLE, "HACK sceFontGetCharInfo %x, %x, %x", fontHandle, charCode, charInfoPtr); slot = fontHandle-1; pgft = font_slot[slot]; @@ -629,9 +769,7 @@ int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) return -1; ph = (PGF_HEADER*)pgft->buf; - gh = pgft->char_glyph[charCode]; - if(gh==NULL) - return -2; + gh = get_glyph(pgft, charCode); if (Memory::IsValidAddress(charInfoPtr)) { CharInfo pspCharInfo; @@ -664,16 +802,14 @@ int sceFontGetCharImageRect(u32 fontHandle, u32 charCode, u32 charRectPtr) PGF_GLYPH *gh; int slot; - DEBUG_LOG(HLE, "HACK sceFontGetCharImageRect %x, %x (%c)", fontHandle, charRectPtr, charCode); + INFO_LOG(HLE, "HACK sceFontGetCharImageRect %x, %x (%c)", fontHandle, charRectPtr, charCode); slot = fontHandle-1; pgft = font_slot[slot]; if(pgft==NULL) return -1; - gh = pgft->char_glyph[charCode]; - if(gh==NULL) - return -2; + gh = get_glyph(pgft, charCode); if (Memory::IsValidAddress(charRectPtr)) { Memory::Write_U16(gh->width, charRectPtr); // character bitmap width in pixels @@ -690,16 +826,14 @@ int sceFontGetCharGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) int slot; u8 line_buf[512]; - DEBUG_LOG(HLE, "HACK sceFontGetCharGlyphImage %x, %x, %x (%c)", fontHandle, charCode, glyphImagePtr, charCode); + INFO_LOG(HLE, "HACK sceFontGetCharGlyphImage %x, %x, %x (%c)", fontHandle, charCode, glyphImagePtr, charCode); slot = fontHandle-1; pgft = font_slot[slot]; if(pgft==NULL) return -1; - gh = pgft->char_glyph[charCode]; - if(gh==NULL) - return -2; + gh = get_glyph(pgft, charCode); int pixelFormat = Memory::Read_U32(glyphImagePtr); int xPos64 = Memory::Read_U32(glyphImagePtr+4); @@ -738,7 +872,7 @@ int sceFontGetCharGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) int sceFontGetCharGlyphImage_Clip(u32 libHandler, u32 charCode, u32 glyphImagePtr, int clipXPos, int clipYPos, int clipWidth, int clipHeight) { - DEBUG_LOG(HLE, "sceFontGetCharGlyphImage_Clip %x, %x, %x (%c)", libHandler, charCode, glyphImagePtr, charCode); + INFO_LOG(HLE, "sceFontGetCharGlyphImage_Clip %x, %x, %x (%c)", libHandler, charCode, glyphImagePtr, charCode); return sceFontGetCharGlyphImage(libHandler, charCode, glyphImagePtr); } @@ -750,7 +884,7 @@ int sceFontSetAltCharacterCode(u32 libHandle, u32 charCode) int sceFontFlush(u32 fontHandle) { - DEBUG_LOG(HLE, "sceFontFlush(%i)", fontHandle); + INFO_LOG(HLE, "sceFontFlush(%i)", fontHandle); return 0; } diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 11ea18c71..9056c6b0e 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -220,7 +220,7 @@ u32 sceGeDrawSync(u32 mode) int sceGeContinue() { - ERROR_LOG(HLE, "UNIMPL sceGeContinue"); + //ERROR_LOG(HLE, "UNIMPL sceGeContinue"); // no arguments return 0; } @@ -228,7 +228,7 @@ int sceGeContinue() int sceGeBreak(u32 mode) { //mode => 0 : current dlist 1: all drawing - ERROR_LOG(HLE, "UNIMPL sceGeBreak(mode=%d)", mode); + //ERROR_LOG(HLE, "UNIMPL sceGeBreak(mode=%d)", mode); return 0; } diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index d1787ea56..ceaac0b6a 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -376,14 +376,14 @@ u32 npdrmRead(FileNode *f, u8 *data, int size) { if(offset+remain_size>pgd->block_size){ copy_size = pgd->block_size-offset; + memcpy(data, pgd->block_buf+offset, copy_size); block += 1; offset = 0; }else{ copy_size = remain_size; + memcpy(data, pgd->block_buf+offset, copy_size); } - memcpy(data, pgd->block_buf+offset, copy_size); - data += copy_size; remain_size -= copy_size; pgd->file_offset += copy_size; @@ -516,6 +516,8 @@ u32 npdrmLseek(FileNode *f, s32 where, FileMove whence) } f->pgdInfo->file_offset = newPos; + pspFileSystem.SeekFile(f->handle, (s32)f->pgdInfo->data_offset+newPos, whence); + return newPos; } @@ -602,8 +604,6 @@ u32 sceIoOpen(const char* filename, int flags, int mode) { access |= FILEACCESS_APPEND; if (flags & O_CREAT) access |= FILEACCESS_CREATE; - if (flags & O_NPDRM) - PSPFileInfo info = pspFileSystem.GetFileInfo(filename); u32 h = pspFileSystem.OpenFile(filename, (FileAccess) access); @@ -1184,15 +1184,27 @@ u32 sceIoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 ou if (Memory::IsValidAddress(indataPtr) && inlen == 16) { u8 keybuf[16]; u8 pgd_header[0x90]; + u8 pgd_magic[4] = {0x00, 0x50, 0x47, 0x44}; memcpy(keybuf, Memory::GetPointer(indataPtr), 16); pspFileSystem.ReadFile(f->handle, pgd_header, 0x90); + f->pgdInfo = pgd_open(pgd_header, 2, keybuf); if(f->pgdInfo==NULL){ DEBUG_LOG(HLE, "Not a valid PGD file. Open as normal file."); f->npdrm = false; pspFileSystem.SeekFile(f->handle, (s32)0, FILEMOVE_BEGIN); + if(memcmp(pgd_header, pgd_magic, 4)==0){ + // File is PGD file, but key mismatch + f->asyncResult = 0x80510204; + }else{ + // File is decrypted. + f->asyncResult = 0; + } + }else{ + // Everthing OK. + f->npdrm = true; + f->asyncResult = 0; } - f->asyncResult = 0; } break; diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index cd87a8f19..e652adfea 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -839,7 +839,7 @@ int sceKernelTryLockLwMutex_600(u32 workareaPtr, int count) int sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr) { - DEBUG_LOG(HLE, "sceKernelLockLwMutex(%08x, %i, %08x)", workareaPtr, count, timeoutPtr); + //DEBUG_LOG(HLE, "sceKernelLockLwMutex(%08x, %i, %08x)", workareaPtr, count, timeoutPtr); NativeLwMutexWorkarea workarea; Memory::ReadStruct(workareaPtr, &workarea); @@ -910,7 +910,7 @@ int sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr) int sceKernelUnlockLwMutex(u32 workareaPtr, int count) { - DEBUG_LOG(HLE, "sceKernelUnlockLwMutex(%08x, %i)", workareaPtr, count); + //DEBUG_LOG(HLE, "sceKernelUnlockLwMutex(%08x, %i)", workareaPtr, count); NativeLwMutexWorkarea workarea; Memory::ReadStruct(workareaPtr, &workarea); diff --git a/Core/MemMap.h b/Core/MemMap.h index a7731d839..ba588d980 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -66,7 +66,7 @@ inline u32 PSP_GetKernelMemoryEnd() { return 0x08400000;} inline u32 PSP_GetUserMemoryBase() { return 0x08800000;} inline u32 PSP_GetUserMemoryEnd() { return 0x0A000000;} -inline u32 PSP_GetDefaultLoadAddress() { return 0x08800000;} +inline u32 PSP_GetDefaultLoadAddress() { return 0x08804000;} //inline u32 PSP_GetDefaultLoadAddress() { return 0x0898dab0;} inline u32 PSP_GetVidMemBase() { return 0x04000000;} From 9790e1e9040a1916d58a672cdf8f7b82332dbc7f Mon Sep 17 00:00:00 2001 From: tpu Date: Sat, 16 Mar 2013 12:29:20 +0800 Subject: [PATCH 4/6] remove defines --- Core/HLE/sceFont.h | 258 +-------------------------------------------- 1 file changed, 1 insertion(+), 257 deletions(-) diff --git a/Core/HLE/sceFont.h b/Core/HLE/sceFont.h index 84158df41..5b0765ead 100644 --- a/Core/HLE/sceFont.h +++ b/Core/HLE/sceFont.h @@ -6,260 +6,4 @@ void Register_sceFont(); void __FontInit(); void __FontShutdown(); -void __FontDoState(PointerWrap &p); - -typedef u32 FontLibraryHandle; -typedef u32 FontHandle; - -struct FontNewLibParams { - u32 userDataAddr; - u32 numFonts; - u32 cacheDataAddr; - - // Driver callbacks. - u32 allocFuncAddr; - u32 freeFuncAddr; - u32 openFuncAddr; - u32 closeFuncAddr; - u32 readFuncAddr; - u32 seekFuncAddr; - u32 errorFuncAddr; - u32 ioFinishFuncAddr; -}; - -typedef enum Family { - FONT_FAMILY_SANS_SERIF = 1, - FONT_FAMILY_SERIF = 2, -}; - -typedef enum Style { - FONT_STYLE_REGULAR = 1, - FONT_STYLE_ITALIC = 2, - FONT_STYLE_BOLD = 5, - FONT_STYLE_BOLD_ITALIC = 6, - FONT_STYLE_DB = 103, // Demi-Bold / semi-bold -}; - -typedef enum Language { - FONT_LANGUAGE_JAPANESE = 1, - FONT_LANGUAGE_LATIN = 2, - FONT_LANGUAGE_KOREAN = 3, -}; - -struct FontStyle { - float fontH; - float fontV; - float fontHRes; - float fontVRes; - float fontWeight; - u16 fontFamily; - u16 fontStyle; - // Check. - u16 fontStyleSub; - u16 fontLanguage; - u16 fontRegion; - u16 fontCountry; - char fontName[64]; - char fontFileName[64]; - u32 fontAttributes; - u32 fontExpire; -}; - -struct iMerticsInfo{ - // Glyph metrics (in 26.6 signed fixed-point). - u32 width; - u32 height; - u32 ascender; - u32 descender; - u32 h_bearingX; - u32 h_bearingY; - u32 v_bearingX; - u32 v_bearingY; - u32 h_advance; - u32 v_advance; -}; - -struct fMerticsInfo{ - // Glyph metrics (in 26.6 signed fixed-point). - float width; - float height; - float ascender; - float descender; - float h_bearingX; - float h_bearingY; - float v_bearingX; - float v_bearingY; - float h_advance; - float v_advance; -}; - -struct FontInfo { - struct iMerticsInfo maxInfoI; - struct fMerticsInfo maxInfoF; - - // Bitmap dimensions. - short maxGlyphWidth; - short maxGlyphHeight; - u32 charMapLength; // Number of elements in the font's charmap. - u32 shadowMapLength; // Number of elements in the font's shadow charmap. - - // Font style (used by font comparison functions). - FontStyle fontStyle; - - u8 BPP; // Font's BPP. - u8 pad[3]; -}; - -struct CharInfo { - u32 bitmapWidth; - u32 bitmapHeight; - u32 bitmapLeft; - u32 bitmapTop; - // Glyph metrics (in 26.6 signed fixed-point). - struct iMerticsInfo info; - u8 pad[4]; -}; - -enum FontPixelFormat { - PSP_FONT_PIXELFORMAT_4 = 0, - PSP_FONT_PIXELFORMAT_4_REV = 1, - PSP_FONT_PIXELFORMAT_8 = 2, - PSP_FONT_PIXELFORMAT_24 = 3, - PSP_FONT_PIXELFORMAT_32 = 4 -}; - -struct GlyphImage { - FontPixelFormat pixelFormat; - s32 xPos64; - s32 yPos64; - u16 bufWidth; - u16 bufHeight; - u16 bytesPerLine; - u16 pad; - u32 bufferPtr; -}; - - -typedef struct f26_pairs { - int h; - int v; -} F26_PAIRS; - -typedef struct pgf_header_t { - /* 0x0000 */ - u16 header_start; - u16 header_len; - u8 pgf_id[4]; - u32 revision; - u32 version; - - /* 0x0010 */ - int charmap_len; - int charptr_len; - int charmap_bpe; - int charptr_bpe; - - /* 0x0020 */ - u8 unk_20[2]; /* 04 04 */ - u8 bpp; /* 04 */ - u8 unk_23; /* 00 */ - - u32 h_size; - u32 v_size; - u32 h_res; - u32 v_res; - - u8 unk_34; /* 00 */ - u8 font_name[64]; /* "FTT-NewRodin Pro DB" */ - u8 font_type[64]; /* "Regular" */ - u8 unk_B5; /* 00 */ - - u16 charmap_min; - u16 charmap_max; - - /* 0x00BA */ - u16 unk_BA; /* 0x0000 */ - u32 unk_BC; /* 0x00010000 */ - u32 unk_C0; /* 0x00000000 */ - u32 unk_C4; /* 0x00000000 */ - u32 unk_C8; /* 0x00010000 */ - u32 unk_CC; /* 0x00000000 */ - u32 unk_D0; /* 0x00000000 */ - - int ascender; - int descender; - int max_h_bearingX; - int max_h_bearingY; - int min_v_bearingX; - int max_v_bearingY; - int max_h_advance; - int max_v_advance; - int max_h_dimension; - int max_v_dimension; - u16 max_glyph_w; - u16 max_glyph_h; - - /* 0x0100 */ - u16 charptr_scale; /* 0004 */ - u8 dimension_len; - u8 bearingX_len; - u8 bearingY_len; - u8 advance_len; - u8 unk_106[102]; /* 00 00 ... ... 00 */ - - u32 shadowmap_len; - u32 shadowmap_bpe; - u32 unk_174; - u32 shadowscale_x; - u32 shadowscale_y; - u32 unk_180; - u32 unk_184; -} PGF_HEADER; - -typedef struct glyph_t { - int index; - int ucs; - int have_shadow; - - int size; /* 14bits */ - int width; /* 7bits */ - int height; /* 7bits */ - int left; /* 7bits signed */ - int top; /* 7bits signed */ - int flag; /* 6bits: 2+1+1+1+1 */ - - int shadow_flag;/* 7bits: 2+2+3 */ - int shadow_id; /* 9bits */ - - F26_PAIRS dimension; - F26_PAIRS bearingX; - F26_PAIRS bearingY; - F26_PAIRS advance; - - u8 *data; - u8 *bmp; -} PGF_GLYPH; - -typedef struct pgf_font_t { - u8 *buf; - - PGF_HEADER *ph; - - struct f26_pairs *dimension; - struct f26_pairs *bearingX; - struct f26_pairs *bearingY; - struct f26_pairs *advance; - - int *charmap; - int *charptr; - int *shadowmap; - - u8 *glyphdata; - PGF_GLYPH *char_glyph[65536]; - PGF_GLYPH *shadow_glyph[512]; - -} PGF_FONT; - - - - +void __FontDoState(PointerWrap &p); \ No newline at end of file From 8fe3294818bee157303d184b073c709bd63d40ea Mon Sep 17 00:00:00 2001 From: tpu Date: Sat, 16 Mar 2013 12:30:03 +0800 Subject: [PATCH 5/6] change return method --- Core/HLE/sceIo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 2bb1ea52b..1cf41a564 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1357,15 +1357,15 @@ int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 out pspFileSystem.SeekFile(f->handle, (s32)0, FILEMOVE_BEGIN); if(memcmp(pgd_header, pgd_magic, 4)==0){ // File is PGD file, but key mismatch - f->asyncResult = 0x80510204; + return 0x80510204; }else{ // File is decrypted. - f->asyncResult = 0; + return 0; } }else{ // Everthing OK. f->npdrm = true; - f->asyncResult = 0; + return 0; } } break; From 641b78ab6765c223cf3ea96c2f46572cf0687b64 Mon Sep 17 00:00:00 2001 From: tpu Date: Sat, 20 Apr 2013 13:51:40 +0800 Subject: [PATCH 6/6] add DLC support --- Core/HLE/sceIo.cpp | 65 ++++++++++++++++++++++++----------- Core/HLE/scePspNpDrm_user.cpp | 21 ++++++----- ext/libkirk/amctrl.c | 40 ++++++++++++++++++--- ext/libkirk/amctrl.h | 1 + 4 files changed, 94 insertions(+), 33 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index b8d6952cc..c1a4c0063 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -186,6 +186,7 @@ public: u32 openMode; u32 npdrm; + u32 pgd_offset; PGD_DESC *pgdInfo; }; @@ -735,6 +736,7 @@ FileNode *__IoOpen(const char* filename, int flags, int mode) { f->openMode = access; f->npdrm = (flags & O_NPDRM)? true: false; + f->pgd_offset = 0; return f; } @@ -1365,33 +1367,54 @@ int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 out switch (cmd) { // Define decryption key (amctrl.prx DRM) - case 0x04100001: + case 0x04100001: { + u8 keybuf[16]; + u8 *key_ptr; + u8 pgd_header[0x90]; + u8 pgd_magic[4] = {0x00, 0x50, 0x47, 0x44}; + if (Memory::IsValidAddress(indataPtr) && inlen == 16) { - u8 keybuf[16]; - u8 pgd_header[0x90]; - u8 pgd_magic[4] = {0x00, 0x50, 0x47, 0x44}; - INFO_LOG(HLE, "Decrypting PGD DRM files"); memcpy(keybuf, Memory::GetPointer(indataPtr), 16); - pspFileSystem.ReadFile(f->handle, pgd_header, 0x90); - f->pgdInfo = pgd_open(pgd_header, 2, keybuf); - if(f->pgdInfo==NULL){ - ERROR_LOG(HLE, "Not a valid PGD file. Open as normal file."); - f->npdrm = false; - pspFileSystem.SeekFile(f->handle, (s32)0, FILEMOVE_BEGIN); - if(memcmp(pgd_header, pgd_magic, 4)==0){ - // File is PGD file, but key mismatch - return ERROR_PGD_INVALID_HEADER; - }else{ - // File is decrypted. - return 0; - } + key_ptr = keybuf; + }else{ + key_ptr = NULL; + } + + INFO_LOG(HLE, "Decrypting PGD DRM files"); + pspFileSystem.SeekFile(f->handle, (s32)f->pgd_offset, FILEMOVE_BEGIN); + pspFileSystem.ReadFile(f->handle, pgd_header, 0x90); + f->pgdInfo = pgd_open(pgd_header, 2, key_ptr); + if(f->pgdInfo==NULL){ + ERROR_LOG(HLE, "Not a valid PGD file. Open as normal file."); + f->npdrm = false; + pspFileSystem.SeekFile(f->handle, (s32)0, FILEMOVE_BEGIN); + if(memcmp(pgd_header, pgd_magic, 4)==0){ + // File is PGD file, but key mismatch + return ERROR_PGD_INVALID_HEADER; }else{ - // Everthing OK. - f->npdrm = true; + // File is decrypted. return 0; } + }else{ + // Everthing OK. + f->npdrm = true; + f->pgdInfo->data_offset += f->pgd_offset; + return 0; } break; + } + // Set PGD offset. Called from sceNpDrmEdataSetupKey + case 0x04100002: + f->pgd_offset = indataPtr; + break; + + // Get PGD data size. Called from sceNpDrmEdataGetDataSize + case 0x04100010: + if(f->pgdInfo) + return f->pgdInfo->data_size; + else + return (int)f->info.size; + break; // Get UMD sector size case 0x01020003: @@ -1443,7 +1466,7 @@ u32 sceIoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 ou { int result = __IoIoctl(id, cmd, indataPtr, inlen, outdataPtr, outlen); // Just a low estimate on timing. - return hleDelayResult(0, "io ctrl command", 100); + return hleDelayResult(result, "io ctrl command", 100); } u32 sceIoIoctlAsync(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen) diff --git a/Core/HLE/scePspNpDrm_user.cpp b/Core/HLE/scePspNpDrm_user.cpp index 384cefc2e..4941df2ef 100644 --- a/Core/HLE/scePspNpDrm_user.cpp +++ b/Core/HLE/scePspNpDrm_user.cpp @@ -2,34 +2,39 @@ #include "HLE.h" +u32 sceIoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen); + int sceNpDrmSetLicenseeKey(u32 npDrmKeyAddr) { - ERROR_LOG(HLE, "UNIMPL sceNpDrmSetLicenseeKey(%08x)", npDrmKeyAddr); + INFO_LOG(HLE, "call sceNpDrmSetLicenseeKey(%08x)", npDrmKeyAddr); return 0; } int sceNpDrmClearLicenseeKey() { - ERROR_LOG(HLE, "UNIMPL sceNpDrmClearLicenseeKey()"); + INFO_LOG(HLE, "call sceNpDrmClearLicenseeKey()"); return 0; } int sceNpDrmRenameCheck(const char *filename) { - ERROR_LOG(HLE, "UNIMPL sceNpDrmRenameCheck(%s)", filename); + INFO_LOG(HLE, "call sceNpDrmRenameCheck(%s)", filename); return 0; } int sceNpDrmEdataSetupKey(u32 edataFd) { - ERROR_LOG(HLE, "UNIMPL sceNpDrmEdataSetupKey %x", edataFd); - return 0; + INFO_LOG(HLE, "call sceNpDrmEdataSetupKey %x", edataFd); + /* set PGD offset */ + sceIoIoctl(edataFd, 0x04100002, 0x90, 0, 0, 0); + /* call PGD open */ + return sceIoIoctl(edataFd, 0x04100001, 0, 0, 0, 0); } int sceNpDrmEdataGetDataSize(u32 edataFd) { - ERROR_LOG(HLE, "UNIMPL sceNpDrmEdataGetDataSize %x", edataFd); - return 0; + INFO_LOG(HLE, "call sceNpDrmEdataGetDataSize %x", edataFd); + return sceIoIoctl(edataFd, 0x04100010, 0, 0, 0, 0); } int sceNpDrmOpen() @@ -67,4 +72,4 @@ void Register_sceNpDrm() RegisterModule("sceNpDrm", ARRAY_SIZE(sceNpDrm), sceNpDrm); RegisterModule("scePspNpDrm_user", ARRAY_SIZE(sceNpDrm), sceNpDrm); } - \ No newline at end of file + diff --git a/ext/libkirk/amctrl.c b/ext/libkirk/amctrl.c index c499e7cff..189a3f0d3 100644 --- a/ext/libkirk/amctrl.c +++ b/ext/libkirk/amctrl.c @@ -334,6 +334,40 @@ int sceDrmBBMacFinal2(MAC_KEY *mkey, u8 *out, u8 *vkey) return retv; } +// get key from bbmac +int bbmac_getkey(MAC_KEY *mkey, u8 *bbmac, u8 *vkey) +{ + int i, retv, type, code; + u8 *kbuf, tmp[16], tmp1[16]; + + type = mkey->type; + retv = sceDrmBBMacFinal(mkey, tmp, NULL); + if(retv) + return retv; + + kbuf = kirk_buf+0x14; + + // decrypt bbmac + if(type==3){ + memcpy(kbuf, bbmac, 0x10); + kirk7(kirk_buf, 0x10, 0x63); + }else{ + memcpy(kirk_buf, bbmac, 0x10); + } + + memcpy(tmp1, kirk_buf, 16); + memcpy(kbuf, tmp1, 16); + + code = (type==2)? 0x3A : 0x38; + kirk7(kirk_buf, 0x10, code); + + for(i=0; i<0x10; i++){ + vkey[i] = tmp[i] ^ kirk_buf[i]; + } + + return 0; +} + /*************************************************************/ static int sub_1F8(u8 *buf, int size, u8 *key, int key_type) @@ -625,12 +659,10 @@ PGD_DESC *pgd_open(u8 *pgd_buf, int pgd_flag, u8 *pgd_vkey) memcpy(pgd->vkey, pgd_vkey, 16); } }else{ - //ERROR_LOG(HLE, "pgd_open: need key!\n"); - free(pgd); - return NULL; + // get vkey from MAC_70 + bbmac_getkey(&mkey, pgd_buf+0x70, pgd->vkey); } - // decrypt PGD_DESC sceDrmBBCipherInit(&ckey, pgd->cipher_type, 2, pgd_buf+0x10, pgd->vkey, 0); sceDrmBBCipherUpdate(&ckey, pgd_buf+0x30, 0x30); diff --git a/ext/libkirk/amctrl.h b/ext/libkirk/amctrl.h index 9a22ac956..e4c9d04aa 100644 --- a/ext/libkirk/amctrl.h +++ b/ext/libkirk/amctrl.h @@ -45,6 +45,7 @@ int sceDrmBBMacInit(MAC_KEY *mkey, int type); int sceDrmBBMacUpdate(MAC_KEY *mkey, u8 *buf, int size); int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey); int sceDrmBBMacFinal2(MAC_KEY *mkey, u8 *out, u8 *vkey); +int bbmac_getkey(MAC_KEY *mkey, u8 *bbmac, u8 *vkey); // type: 1 use fixed key // 2 use fuse id