mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 13:50:13 +00:00
AGS: Configurable font init mode, for backward compatibility
From upstream 9a11a1d4334aef99b8b516a13d5a5bcc0284fde7
This commit is contained in:
parent
7f3ea3074f
commit
ca4c91031b
@ -258,10 +258,10 @@ HError InitAndRegisterGameEntities() {
|
|||||||
return HError::None();
|
return HError::None();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadFonts(GameDataVersion data_ver) {
|
void LoadFonts(GameSetupStruct &game, GameDataVersion data_ver) {
|
||||||
for (int i = 0; i < _GP(game).numfonts; ++i) {
|
for (int i = 0; i < _GP(game).numfonts; ++i) {
|
||||||
FontInfo &finfo = _GP(game).fonts[i];
|
FontInfo &finfo = _GP(game).fonts[i];
|
||||||
if (!wloadfont_size(i, finfo))
|
if (!load_font_size(i, finfo, game.options[OPT_FONTLOADLOGIC]))
|
||||||
quitprintf("Unable to load font %d, no renderer could load a matching file", i);
|
quitprintf("Unable to load font %d, no renderer could load a matching file", i);
|
||||||
|
|
||||||
const bool is_wfn = is_bitmap_font(i);
|
const bool is_wfn = is_bitmap_font(i);
|
||||||
@ -299,14 +299,12 @@ void LoadFonts(GameDataVersion data_ver) {
|
|||||||
if (finfo.LineSpacing == 0) {
|
if (finfo.LineSpacing == 0) {
|
||||||
set_font_linespacing(i, height + 2 * finfo.AutoOutlineThickness);
|
set_font_linespacing(i, height + 2 * finfo.AutoOutlineThickness);
|
||||||
|
|
||||||
// WORKAROUND: For qfg2vga at least, fInfo.SizePt == 0, which causes below
|
// Backward compatibility: if the real font's height != formal height
|
||||||
// to screw up line spacing. Since by the current upstream HEAD this has all
|
// and there's no custom linespacing, then set linespacing = formal height.
|
||||||
// been replaced anyway, for now I'm adding an explicit 0 check
|
if ((game.options[OPT_FONTLOADLOGIC] & FONT_LOAD_REPORTREALHEIGHT) == 0) {
|
||||||
if (finfo.SizePt != 0) {
|
|
||||||
// Backward compatibility: if the real font's height != formal height
|
|
||||||
// and there's no custom linespacing, then set linespacing = formal height.
|
|
||||||
const int compat_height = finfo.SizePt * finfo.SizeMultiplier;
|
const int compat_height = finfo.SizePt * finfo.SizeMultiplier;
|
||||||
if (height != compat_height) {
|
// WORKAROUND: Don't replace if no height
|
||||||
|
if (compat_height != 0 && height != compat_height) {
|
||||||
set_font_linespacing(i, compat_height + 2 * finfo.AutoOutlineThickness);
|
set_font_linespacing(i, compat_height + 2 * finfo.AutoOutlineThickness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,8 +353,9 @@ void AllocScriptModules() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion data_ver) {
|
HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion data_ver) {
|
||||||
const ScriptAPIVersion base_api = (ScriptAPIVersion)_GP(game).options[OPT_BASESCRIPTAPI];
|
GameSetupStruct &game = ents.Game;
|
||||||
const ScriptAPIVersion compat_api = (ScriptAPIVersion)_GP(game).options[OPT_SCRIPTCOMPATLEV];
|
const ScriptAPIVersion base_api = (ScriptAPIVersion)game.options[OPT_BASESCRIPTAPI];
|
||||||
|
const ScriptAPIVersion compat_api = (ScriptAPIVersion)game.options[OPT_SCRIPTCOMPATLEV];
|
||||||
if (data_ver >= kGameVersion_341) {
|
if (data_ver >= kGameVersion_341) {
|
||||||
const char *base_api_name = GetScriptAPIName(base_api);
|
const char *base_api_name = GetScriptAPIName(base_api);
|
||||||
const char *compat_api_name = GetScriptAPIName(compat_api);
|
const char *compat_api_name = GetScriptAPIName(compat_api);
|
||||||
@ -366,42 +365,43 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat
|
|||||||
}
|
}
|
||||||
// If the game was compiled using unsupported version of the script API,
|
// If the game was compiled using unsupported version of the script API,
|
||||||
// we warn about potential incompatibilities but proceed further.
|
// we warn about potential incompatibilities but proceed further.
|
||||||
if (_GP(game).options[OPT_BASESCRIPTAPI] > kScriptAPI_Current)
|
if (game.options[OPT_BASESCRIPTAPI] > kScriptAPI_Current)
|
||||||
_G(platform)->DisplayAlert("Warning: this game requests a higher version of AGS script API, it may not run correctly or run at all.");
|
_G(platform)->DisplayAlert("Warning: this game requests a higher version of AGS script API, it may not run correctly or run at all.");
|
||||||
|
|
||||||
//
|
//
|
||||||
// 1. Check that the loaded data is valid and compatible with the current
|
// 1. Check that the loaded data is valid and compatible with the current
|
||||||
// engine capabilities.
|
// engine capabilities.
|
||||||
//
|
//
|
||||||
if (_GP(game).numfonts == 0)
|
if (game.numfonts == 0)
|
||||||
return new GameInitError(kGameInitErr_NoFonts);
|
return new GameInitError(kGameInitErr_NoFonts);
|
||||||
if (_GP(game).audioClipTypes.size() > MAX_AUDIO_TYPES)
|
if (game.audioClipTypes.size() > MAX_AUDIO_TYPES)
|
||||||
return new GameInitError(kGameInitErr_TooManyAudioTypes,
|
return new GameInitError(kGameInitErr_TooManyAudioTypes,
|
||||||
String::FromFormat("Required: %zu, max: %zu", _GP(game).audioClipTypes.size(), MAX_AUDIO_TYPES));
|
String::FromFormat("Required: %zu, max: %zu", game.audioClipTypes.size(), MAX_AUDIO_TYPES));
|
||||||
|
|
||||||
//
|
//
|
||||||
// 3. Allocate and init game objects
|
// 3. Allocate and init game objects
|
||||||
//
|
//
|
||||||
_G(charextra) = (CharacterExtras *)calloc(_GP(game).numcharacters, sizeof(CharacterExtras));
|
_G(charextra) = (CharacterExtras *)calloc(game.numcharacters, sizeof(CharacterExtras));
|
||||||
_G(charcache) = (CharacterCache *)calloc(1, sizeof(CharacterCache) * _GP(game).numcharacters + 5);
|
_G(charcache) = (CharacterCache *)calloc(1, sizeof(CharacterCache) * game.numcharacters + 5);
|
||||||
_G(mls) = (MoveList *)calloc(_GP(game).numcharacters + MAX_ROOM_OBJECTS + 1, sizeof(MoveList));
|
_G(mls) = (MoveList *)calloc(game.numcharacters + MAX_ROOM_OBJECTS + 1, sizeof(MoveList));
|
||||||
init_game_drawdata();
|
init_game_drawdata();
|
||||||
_GP(views) = std::move(ents.Views);
|
_GP(views) = std::move(ents.Views);
|
||||||
|
|
||||||
_GP(play).charProps.resize(_GP(game).numcharacters);
|
_GP(play).charProps.resize(game.numcharacters);
|
||||||
_G(old_dialog_scripts) = ents.OldDialogScripts;
|
_G(old_dialog_scripts) = ents.OldDialogScripts;
|
||||||
_G(old_speech_lines) = ents.OldSpeechLines;
|
_G(old_speech_lines) = ents.OldSpeechLines;
|
||||||
|
|
||||||
// Set number of game channels corresponding to the loaded game version
|
// Set number of game channels corresponding to the loaded game version
|
||||||
if (_G(loaded_game_file_version) < kGameVersion_360)
|
if (_G(loaded_game_file_version) < kGameVersion_360)
|
||||||
_GP(game).numGameChannels = MAX_GAME_CHANNELS_v320;
|
game.numGameChannels = MAX_GAME_CHANNELS_v320;
|
||||||
else
|
else
|
||||||
_GP(game).numGameChannels = MAX_GAME_CHANNELS;
|
game.numGameChannels = MAX_GAME_CHANNELS;
|
||||||
|
|
||||||
HError err = InitAndRegisterGameEntities();
|
HError err = InitAndRegisterGameEntities();
|
||||||
if (!err)
|
if (!err)
|
||||||
return new GameInitError(kGameInitErr_EntityInitFail, err);
|
return new GameInitError(kGameInitErr_EntityInitFail, err);
|
||||||
LoadFonts(data_ver);
|
LoadFonts(game, data_ver);
|
||||||
|
LoadLipsyncData();
|
||||||
|
|
||||||
//
|
//
|
||||||
// 4. Initialize certain runtime variables
|
// 4. Initialize certain runtime variables
|
||||||
@ -410,12 +410,12 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat
|
|||||||
_G(ifacepopped) = -1;
|
_G(ifacepopped) = -1;
|
||||||
|
|
||||||
String svg_suffix;
|
String svg_suffix;
|
||||||
if (_GP(game).saveGameFileExtension[0] != 0)
|
if (game.saveGameFileExtension[0] != 0)
|
||||||
svg_suffix.Format(".%s", _GP(game).saveGameFileExtension);
|
svg_suffix.Format(".%s", game.saveGameFileExtension);
|
||||||
set_save_game_suffix(svg_suffix);
|
set_save_game_suffix(svg_suffix);
|
||||||
|
|
||||||
_GP(play).score_sound = _GP(game).scoreClipID;
|
_GP(play).score_sound = game.scoreClipID;
|
||||||
_GP(play).fade_effect = _GP(game).options[OPT_FADETYPE];
|
_GP(play).fade_effect = game.options[OPT_FADETYPE];
|
||||||
|
|
||||||
//
|
//
|
||||||
// 5. Initialize runtime state of certain game objects
|
// 5. Initialize runtime state of certain game objects
|
||||||
@ -424,7 +424,7 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat
|
|||||||
// labels are not clickable by default
|
// labels are not clickable by default
|
||||||
_GP(guilabels)[i].SetClickable(false);
|
_GP(guilabels)[i].SetClickable(false);
|
||||||
}
|
}
|
||||||
_GP(play).gui_draw_order = (int32_t *)calloc(_GP(game).numgui * sizeof(int), 1);
|
_GP(play).gui_draw_order = (int32_t *)calloc(game.numgui * sizeof(int), 1);
|
||||||
update_gui_zorder();
|
update_gui_zorder();
|
||||||
calculate_reserved_channel_count();
|
calculate_reserved_channel_count();
|
||||||
|
|
||||||
|
@ -744,7 +744,7 @@ void IAGSEngine::BreakIntoDebugger() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IAGSFontRenderer *IAGSEngine::ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer) {
|
IAGSFontRenderer *IAGSEngine::ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer) {
|
||||||
auto *old_render = font_replace_renderer(fontNumber, newRenderer);
|
auto *old_render = font_replace_renderer(fontNumber, newRenderer, _GP(game).options[OPT_FONTLOADLOGIC]);
|
||||||
GUI::MarkForFontUpdate(fontNumber);
|
GUI::MarkForFontUpdate(fontNumber);
|
||||||
return old_render;
|
return old_render;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,7 @@ namespace AGS3 {
|
|||||||
#define OPT_RENDERATSCREENRES 45 // scale sprites at the (final) screen resolution
|
#define OPT_RENDERATSCREENRES 45 // scale sprites at the (final) screen resolution
|
||||||
#define OPT_RELATIVEASSETRES 46 // relative asset resolution mode (where sprites are resized to match game type)
|
#define OPT_RELATIVEASSETRES 46 // relative asset resolution mode (where sprites are resized to match game type)
|
||||||
#define OPT_WALKSPEEDABSOLUTE 47 // if movement speeds are independent of walkable mask resolution
|
#define OPT_WALKSPEEDABSOLUTE 47 // if movement speeds are independent of walkable mask resolution
|
||||||
|
#define OPT_FONTLOADLOGIC 48 // fonts load/init logic, see FONT_LOAD_xxx flags
|
||||||
#define OPT_HIGHESTOPTION OPT_WALKSPEEDABSOLUTE
|
#define OPT_HIGHESTOPTION OPT_WALKSPEEDABSOLUTE
|
||||||
#define OPT_NOMODMUSIC 98
|
#define OPT_NOMODMUSIC 98
|
||||||
#define OPT_LIPSYNCTEXT 99
|
#define OPT_LIPSYNCTEXT 99
|
||||||
|
@ -73,7 +73,7 @@ bool is_font_loaded(size_t fontNumber) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finish font's initialization
|
// Finish font's initialization
|
||||||
static void post_init_font(size_t fontNumber) {
|
static void post_init_font(size_t fontNumber, int load_mode) {
|
||||||
Font &font = _GP(fonts)[fontNumber];
|
Font &font = _GP(fonts)[fontNumber];
|
||||||
if (font.Metrics.Height == 0) {
|
if (font.Metrics.Height == 0) {
|
||||||
// There is no explicit method for getting maximal possible height of any
|
// There is no explicit method for getting maximal possible height of any
|
||||||
@ -85,19 +85,20 @@ static void post_init_font(size_t fontNumber) {
|
|||||||
font.Metrics.Height = height;
|
font.Metrics.Height = height;
|
||||||
font.Metrics.RealHeight = height;
|
font.Metrics.RealHeight = height;
|
||||||
}
|
}
|
||||||
font.Metrics.CompatHeight = font.Metrics.Height;
|
font.Metrics.CompatHeight = (load_mode & FONT_LOAD_REPORTREALHEIGHT) == 0 ?
|
||||||
|
font.Metrics.Height : font.Metrics.RealHeight;
|
||||||
if (font.Info.Outline != FONT_OUTLINE_AUTO) {
|
if (font.Info.Outline != FONT_OUTLINE_AUTO) {
|
||||||
font.Info.AutoOutlineThickness = 0;
|
font.Info.AutoOutlineThickness = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer) {
|
IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer, int load_mode) {
|
||||||
if (fontNumber >= _GP(fonts).size())
|
if (fontNumber >= _GP(fonts).size())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
IAGSFontRenderer *oldRender = _GP(fonts)[fontNumber].Renderer;
|
IAGSFontRenderer *oldRender = _GP(fonts)[fontNumber].Renderer;
|
||||||
_GP(fonts)[fontNumber].Renderer = renderer;
|
_GP(fonts)[fontNumber].Renderer = renderer;
|
||||||
_GP(fonts)[fontNumber].Renderer2 = nullptr;
|
_GP(fonts)[fontNumber].Renderer2 = nullptr;
|
||||||
post_init_font(fontNumber);
|
post_init_font(fontNumber, load_mode);
|
||||||
return oldRender;
|
return oldRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +351,7 @@ FontInfo get_fontinfo(size_t font_number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loads a font from disk
|
// Loads a font from disk
|
||||||
bool wloadfont_size(size_t fontNumber, const FontInfo &font_info) {
|
bool load_font_size(size_t fontNumber, const FontInfo &font_info, int load_mode) {
|
||||||
if (_GP(fonts).size() <= fontNumber)
|
if (_GP(fonts).size() <= fontNumber)
|
||||||
_GP(fonts).resize(fontNumber + 1);
|
_GP(fonts).resize(fontNumber + 1);
|
||||||
else
|
else
|
||||||
@ -372,7 +373,7 @@ bool wloadfont_size(size_t fontNumber, const FontInfo &font_info) {
|
|||||||
|
|
||||||
_GP(fonts)[fontNumber].Info = font_info;
|
_GP(fonts)[fontNumber].Info = font_info;
|
||||||
_GP(fonts)[fontNumber].Metrics = metrics;
|
_GP(fonts)[fontNumber].Metrics = metrics;
|
||||||
post_init_font(fontNumber);
|
post_init_font(fontNumber, load_mode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
|
|
||||||
namespace AGS3 {
|
namespace AGS3 {
|
||||||
|
|
||||||
|
// Font load flags, primarily for backward compatibility
|
||||||
|
// REPORTREALHEIGHT: get_font_height should return real font's height,
|
||||||
|
// otherwise returns formal height, equal to "font size" parameter
|
||||||
|
#define FONT_LOAD_REPORTREALHEIGHT 0x01
|
||||||
|
|
||||||
class IAGSFontRenderer;
|
class IAGSFontRenderer;
|
||||||
class IAGSFontRenderer2;
|
class IAGSFontRenderer2;
|
||||||
struct FontInfo;
|
struct FontInfo;
|
||||||
@ -66,7 +71,7 @@ struct FontRenderParams;
|
|||||||
void init_font_renderer();
|
void init_font_renderer();
|
||||||
void shutdown_font_renderer();
|
void shutdown_font_renderer();
|
||||||
void adjust_y_coordinate_for_text(int *ypos, size_t fontnum);
|
void adjust_y_coordinate_for_text(int *ypos, size_t fontnum);
|
||||||
IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer);
|
IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer, int load_mode);
|
||||||
bool font_first_renderer_loaded();
|
bool font_first_renderer_loaded();
|
||||||
bool is_font_loaded(size_t fontNumber);
|
bool is_font_loaded(size_t fontNumber);
|
||||||
bool is_bitmap_font(size_t fontNumber);
|
bool is_bitmap_font(size_t fontNumber);
|
||||||
@ -115,7 +120,7 @@ void set_fontinfo(size_t fontNumber, const FontInfo &finfo);
|
|||||||
// Gets full information about the font
|
// Gets full information about the font
|
||||||
FontInfo get_fontinfo(size_t font_number);
|
FontInfo get_fontinfo(size_t font_number);
|
||||||
// Loads a font from disk
|
// Loads a font from disk
|
||||||
bool wloadfont_size(size_t fontNumber, const FontInfo &font_info);
|
bool load_font_size(size_t fontNumber, const FontInfo &font_info, int load_mode);
|
||||||
void wgtprintf(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...);
|
void wgtprintf(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...);
|
||||||
// Allocates two outline stencil buffers, or returns previously creates ones;
|
// Allocates two outline stencil buffers, or returns previously creates ones;
|
||||||
// these buffers are owned by the font, they should not be deleted by the caller.
|
// these buffers are owned by the font, they should not be deleted by the caller.
|
||||||
|
Loading…
Reference in New Issue
Block a user