Change shadow text rendering system to use a pre-generated shadow font sprite to improve text rendering speeds dramatically. Fix bug from commit cfd73ab036 where custom font colored shadow text kept creating new versionf of itself causing memory leaks. Release Build 10791.
This commit is contained in:
parent
00e22877c4
commit
d49e7ff6bb
@ -1994,7 +1994,7 @@ void AiL::RenderHud(){
|
|||||||
std::stringstream castTimeDisplay;
|
std::stringstream castTimeDisplay;
|
||||||
castTimeDisplay<<std::fixed<<std::setprecision(1)<<timer;
|
castTimeDisplay<<std::fixed<<std::setprecision(1)<<timer;
|
||||||
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2+90.f,ScreenHeight()-80.f}-vf2d{float(GetTextSizeProp(castTimeDisplay.str()).x),0},castTimeDisplay.str(),WHITE,BLACK);
|
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2+90.f,ScreenHeight()-80.f}-vf2d{float(GetTextSizeProp(castTimeDisplay.str()).x),0},castTimeDisplay.str(),WHITE,BLACK);
|
||||||
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2.f-GetTextSizeProp(castText).x*2/2,ScreenHeight()-64.f},castText,WHITE,BLACK,{2,3},std::numeric_limits<float>::max(),2.f);
|
DrawShadowStringPropDecal(vf2d{ScreenWidth()/2.f-GetTextSizeProp(castText).x*2/2,ScreenHeight()-64.f},castText,WHITE,BLACK,{2,3},{1.8f,2.6f},std::numeric_limits<float>::max());
|
||||||
};
|
};
|
||||||
|
|
||||||
if(GetPlayer()->GetCastInfo().castTimer>0){
|
if(GetPlayer()->GetCastInfo().castTimer>0){
|
||||||
@ -2020,8 +2020,8 @@ void AiL::RenderHud(){
|
|||||||
std::string text=player->GetHealth()>0?std::to_string(healthCounter.GetDisplayValue()):"X";
|
std::string text=player->GetHealth()>0?std::to_string(healthCounter.GetDisplayValue()):"X";
|
||||||
std::string text_mana=std::to_string(manaCounter.GetDisplayValue());
|
std::string text_mana=std::to_string(manaCounter.GetDisplayValue());
|
||||||
|
|
||||||
DrawShadowStringPropDecal({20,3},text,healthCounter.GetDisplayColor(),healthOutlineCol,{2,2},INFINITE);
|
DrawShadowStringPropDecal({20,3},text,healthCounter.GetDisplayColor(),healthOutlineCol,{2,2},{1.8f,1.8f},INFINITE);
|
||||||
DrawShadowStringPropDecal({24,23},text_mana,manaCounter.GetDisplayColor(),BLACK,{1.5f,1.5f},INFINITE);
|
DrawShadowStringPropDecal({24,23},text_mana,manaCounter.GetDisplayColor(),BLACK,{1.5f,1.5f},{1.45f,1.45f},INFINITE);
|
||||||
|
|
||||||
#pragma region Show Max Health/Max Mana
|
#pragma region Show Max Health/Max Mana
|
||||||
if(GameSettings::ShowMaxHealth()){
|
if(GameSettings::ShowMaxHealth()){
|
||||||
@ -2029,14 +2029,14 @@ void AiL::RenderHud(){
|
|||||||
|
|
||||||
std::string maxHealthText="/"+std::to_string(int(player->GetMaxHealth()));
|
std::string maxHealthText="/"+std::to_string(int(player->GetMaxHealth()));
|
||||||
float maxHealthTextHeight=GetTextSizeProp(maxHealthText).y;
|
float maxHealthTextHeight=GetTextSizeProp(maxHealthText).y;
|
||||||
DrawShadowStringPropDecal(vf2d{20,3}+healthTextSize+vf2d{1.f,-maxHealthTextHeight},maxHealthText,{200,200,200,255},healthOutlineCol,{1.f,1.f},INFINITE);
|
DrawShadowStringPropDecal(vf2d{20,3}+healthTextSize+vf2d{1.f,-maxHealthTextHeight},maxHealthText,{200,200,200,255},healthOutlineCol,{1.f,1.f},{1.f,1.f},INFINITE);
|
||||||
}
|
}
|
||||||
if(GameSettings::ShowMaxMana()){
|
if(GameSettings::ShowMaxMana()){
|
||||||
vf2d manaTextSize=GetTextSizeProp(text_mana)*vf2d{1.5f,1.5f};
|
vf2d manaTextSize=GetTextSizeProp(text_mana)*vf2d{1.5f,1.5f};
|
||||||
|
|
||||||
std::string maxManaText="/"+std::to_string(player->GetMaxMana());
|
std::string maxManaText="/"+std::to_string(player->GetMaxMana());
|
||||||
float maxManaTextHeight=GetTextSizeProp(maxManaText).y;
|
float maxManaTextHeight=GetTextSizeProp(maxManaText).y;
|
||||||
DrawShadowStringPropDecal(vf2d{24,23}+manaTextSize+vf2d{1.f,-maxManaTextHeight},maxManaText,{200,200,255,255},BLACK,{1.f,1.f},INFINITE);
|
DrawShadowStringPropDecal(vf2d{24,23}+manaTextSize+vf2d{1.f,-maxManaTextHeight},maxManaText,{200,200,255,255},BLACK,{1.f,1.f},{1.f,1.f},INFINITE);
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
@ -2108,7 +2108,7 @@ void AiL::RenderCooldowns(){
|
|||||||
}
|
}
|
||||||
std::stringstream cooldownTimeDisplay;
|
std::stringstream cooldownTimeDisplay;
|
||||||
cooldownTimeDisplay<<std::fixed<<std::setprecision(1)<<a.cooldown;
|
cooldownTimeDisplay<<std::fixed<<std::setprecision(1)<<a.cooldown;
|
||||||
DrawShadowStringPropDecal(pos+vf2d{12,12}-vf2d{float(GetTextSizeProp(cooldownTimeDisplay.str()).x*0.5),float(GetTextSizeProp(cooldownTimeDisplay.str()).y*1)}/2,cooldownTimeDisplay.str(),WHITE,BLACK,{0.5,1});
|
DrawShadowStringPropDecal(pos+vf2d{12,12}-vf2d{float(GetTextSizeProp(cooldownTimeDisplay.str()).x*0.5),float(GetTextSizeProp(cooldownTimeDisplay.str()).y*1)}/2,cooldownTimeDisplay.str(),WHITE,BLACK,{0.5,1},{0.5,1});
|
||||||
}else{
|
}else{
|
||||||
vf2d iconScale={1,1};
|
vf2d iconScale={1,1};
|
||||||
if(loadoutSlot!=-1)iconScale={0.7f,0.7f};
|
if(loadoutSlot!=-1)iconScale={0.7f,0.7f};
|
||||||
@ -2148,7 +2148,7 @@ void AiL::RenderCooldowns(){
|
|||||||
if(itemAmt>0){
|
if(itemAmt>0){
|
||||||
std::string amtString="x"+std::to_string(itemAmt);
|
std::string amtString="x"+std::to_string(itemAmt);
|
||||||
vf2d qtySize=vf2d{GetTextSize(amtString)}*vf2d{0.5f,0.75f};
|
vf2d qtySize=vf2d{GetTextSize(amtString)}*vf2d{0.5f,0.75f};
|
||||||
DrawShadowStringDecal(pos+vf2d{20,20}-qtySize/2,amtString,WHITE,BLACK,{0.5f,0.75f});
|
DrawShadowStringDecal(pos+vf2d{20,20}-qtySize/2,amtString,WHITE,BLACK,{0.5f,0.75f},{0.5f,0.75f});
|
||||||
}else{
|
}else{
|
||||||
DrawDecal(pos,GFX["square_skill_overlay_icon_empty.png"].Decal(),{1,1},DARK_RED);
|
DrawDecal(pos,GFX["square_skill_overlay_icon_empty.png"].Decal(),{1,1},DARK_RED);
|
||||||
shortNameCol=RED;
|
shortNameCol=RED;
|
||||||
@ -2160,11 +2160,11 @@ void AiL::RenderCooldowns(){
|
|||||||
|
|
||||||
if(a.manaCost>0){
|
if(a.manaCost>0){
|
||||||
vf2d manaCostSize=vf2d{GetTextSize(std::to_string(a.manaCost))}*vf2d{0.5f,0.75f};
|
vf2d manaCostSize=vf2d{GetTextSize(std::to_string(a.manaCost))}*vf2d{0.5f,0.75f};
|
||||||
DrawShadowStringDecal(pos+vf2d{20,4}-manaCostSize/2,std::to_string(a.manaCost),{192,192,255},manaCostShadowCol,{0.5f,0.75f});
|
DrawShadowStringDecal(pos+vf2d{20,4}-manaCostSize/2,std::to_string(a.manaCost),{192,192,255},manaCostShadowCol,{0.5f,0.75f},{0.5f,0.75f});
|
||||||
}
|
}
|
||||||
|
|
||||||
vf2d shortNameSize=vf2d{GetTextSize(a.shortName)}*vf2d{0.5f,0.75f};
|
vf2d shortNameSize=vf2d{GetTextSize(a.shortName)}*vf2d{0.5f,0.75f};
|
||||||
DrawShadowStringDecal(pos+vf2d{13,24}-shortNameSize/2,a.shortName,shortNameCol,{255,255,255,230},{0.5f,0.75f});
|
DrawShadowStringDecal(pos+vf2d{13,24}-shortNameSize/2,a.shortName,shortNameCol,{255,255,255,230},{0.5f,0.75f},{0.5f,0.75f});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3594,7 +3594,7 @@ void AiL::DisplayBossEncounterInfo(){
|
|||||||
}
|
}
|
||||||
vf2d textScale={3,5};
|
vf2d textScale={3,5};
|
||||||
textScale.x=std::min(3.f,float(ScreenWidth())/GetTextSizeProp(displayText).x);
|
textScale.x=std::min(3.f,float(ScreenWidth())/GetTextSizeProp(displayText).x);
|
||||||
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/2)}-vf2d{GetTextSizeProp(displayText)}*textScale/2,displayText,{252, 186, 3, alpha},{128,0,0,alpha},textScale,std::numeric_limits<float>::max(),2);
|
DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/2)}-vf2d{GetTextSizeProp(displayText)}*textScale/2,displayText,{252, 186, 3, alpha},{128,0,0,alpha},textScale,textScale*0.9f,std::numeric_limits<float>::max());
|
||||||
}
|
}
|
||||||
if(InBossEncounter()){
|
if(InBossEncounter()){
|
||||||
Pixel displayCol=totalBossEncounterMobs==0?Pixel{224, 133, 29}:WHITE;
|
Pixel displayCol=totalBossEncounterMobs==0?Pixel{224, 133, 29}:WHITE;
|
||||||
@ -3747,7 +3747,7 @@ void AiL::InitializeGraphics(){
|
|||||||
}
|
}
|
||||||
LOG(VisualNovel::graphicsToLoad.size()<<" images for visual novel engine have been loaded.");
|
LOG(VisualNovel::graphicsToLoad.size()<<" images for visual novel engine have been loaded.");
|
||||||
|
|
||||||
SetFontSprite("GFX_Prefix"_S+"font.png",&gamepack,"GENERATE_GAMEPACK"_B);
|
SetFontSprite("GFX_Prefix"_S+"font.png","GFX_Prefix"_S+"font_shadow.png",&gamepack,"GENERATE_GAMEPACK"_B);
|
||||||
LOG("Custom font loaded.");
|
LOG("Custom font loaded.");
|
||||||
|
|
||||||
Menu::themes.SetInitialized();
|
Menu::themes.SetInitialized();
|
||||||
@ -3842,7 +3842,7 @@ void AiL::RenderVersionInfo(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string versionStr("v" + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + "." + std::to_string(VERSION_BUILD));
|
std::string versionStr("v" + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + "." + std::to_string(VERSION_BUILD));
|
||||||
DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4f,versionStr,ADMIN_MODE?RED:WHITE,BLACK,{0.4f,0.4f},std::numeric_limits<float>::max(),0.4f);
|
DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4f,versionStr,ADMIN_MODE?RED:WHITE,BLACK,{0.4f,0.4f},{0.4f,0.4f},std::numeric_limits<float>::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
int AiL::GetCurrentChapter(){
|
int AiL::GetCurrentChapter(){
|
||||||
|
@ -68,8 +68,8 @@ protected:
|
|||||||
|
|
||||||
vi2d descriptionPos=iconPos+vi2d{int(rect.size.y)-2,9};
|
vi2d descriptionPos=iconPos+vi2d{int(rect.size.y)-2,9};
|
||||||
|
|
||||||
window.DrawShadowStringPropDecal(descriptionPos-vf2d{0,10},ability->name,{0xFF,0xAF,0x56},BLACK,{0.8f,1.f},int(rect.size.x-(descriptionPos.x-rect.pos.x))-4);
|
window.DrawShadowStringPropDecal(descriptionPos-vf2d{0,10},ability->name,{0xFF,0xAF,0x56},BLACK,{0.8f,1.f},{0.8f,1.f},int(rect.size.x-(descriptionPos.x-rect.pos.x))-4);
|
||||||
window.DrawShadowStringPropDecal(descriptionPos,ability->description,WHITE,BLACK,{0.8f,1.f},int(rect.size.x-(descriptionPos.x-rect.pos.x))-4);
|
window.DrawShadowStringPropDecal(descriptionPos,ability->description,WHITE,BLACK,{0.8f,1.f},{0.8f,1.f},int(rect.size.x-(descriptionPos.x-rect.pos.x))-4);
|
||||||
|
|
||||||
InputType controlType=KEY;
|
InputType controlType=KEY;
|
||||||
if(Input::UsingGamepad())controlType=CONTROLLER;
|
if(Input::UsingGamepad())controlType=CONTROLLER;
|
||||||
|
@ -80,7 +80,7 @@ protected:
|
|||||||
for(float yOffset=0;const auto&[attr,value]:itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()].stats){
|
for(float yOffset=0;const auto&[attr,value]:itemRef.lock()->GetEnhancementInfo()[itemRef.lock()->EnhancementLevel()].stats){
|
||||||
std::string attributeLabel=std::format("{}",attr.Name());
|
std::string attributeLabel=std::format("{}",attr.Name());
|
||||||
float attributeLabelWidth=game->GetTextSizeProp(attributeLabel).x;
|
float attributeLabelWidth=game->GetTextSizeProp(attributeLabel).x;
|
||||||
window.DrawShadowStringPropDecal(drawPos+vf2d{maxAttributeLabelSize/2+24,yOffset}-vf2d{attributeLabelWidth/2,0},attributeLabel,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
|
window.DrawShadowStringPropDecal(drawPos+vf2d{maxAttributeLabelSize/2+24,yOffset}-vf2d{attributeLabelWidth/2,0},attributeLabel,WHITE,BLACK,adjustedScale,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x);
|
||||||
uint8_t nextEnhanceLevel=itemRef.lock()->EnhancementLevel()+1;
|
uint8_t nextEnhanceLevel=itemRef.lock()->EnhancementLevel()+1;
|
||||||
float nextStageValue=0;
|
float nextStageValue=0;
|
||||||
if(itemRef.lock()->GetEnhancementInfo().size()>nextEnhanceLevel){
|
if(itemRef.lock()->GetEnhancementInfo().size()>nextEnhanceLevel){
|
||||||
@ -92,21 +92,21 @@ protected:
|
|||||||
if(Inventory::GetItemCount(itemRef.lock()->ActualName())==0){ //This item hasn't been created yet, so just show that we are developing the item first.
|
if(Inventory::GetItemCount(itemRef.lock()->ActualName())==0){ //This item hasn't been created yet, so just show that we are developing the item first.
|
||||||
window.DrawShadowStringDecal(drawPos+vf2d{maxAttributeLabelSize+4+24,yOffset},std::format("{:<5}",(
|
window.DrawShadowStringDecal(drawPos+vf2d{maxAttributeLabelSize+4+24,yOffset},std::format("{:<5}",(
|
||||||
(attr.ShowAsDecimal()?std::format("{:>4.2f}{}",value,percentageSign):std::format("{}{}",value,percentageSign)))),
|
(attr.ShowAsDecimal()?std::format("{:>4.2f}{}",value,percentageSign):std::format("{}{}",value,percentageSign)))),
|
||||||
WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
|
WHITE,BLACK,adjustedScale,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x);
|
||||||
}else{ //This item is getting enhanced to the next level.
|
}else{ //This item is getting enhanced to the next level.
|
||||||
window.DrawShadowStringDecal(drawPos+vf2d{maxAttributeLabelSize+4+24,yOffset},std::format("{:>5} ->#00AA00 {:<5}",
|
window.DrawShadowStringDecal(drawPos+vf2d{maxAttributeLabelSize+4+24,yOffset},std::format("{:>5} ->#00AA00 {:<5}",
|
||||||
attr.ShowAsDecimal()?std::format("{:>4.2f}{}",value,percentageSign):std::format("{}{}",value,percentageSign),
|
attr.ShowAsDecimal()?std::format("{:>4.2f}{}",value,percentageSign):std::format("{}{}",value,percentageSign),
|
||||||
(nextEnhanceLevel<="Item.Item Max Enhancement Level"_I&&itemRef.lock()->GetEnhancementInfo()[nextEnhanceLevel].chapterAvailable<=game->GetCurrentChapter())?
|
(nextEnhanceLevel<="Item.Item Max Enhancement Level"_I&&itemRef.lock()->GetEnhancementInfo()[nextEnhanceLevel].chapterAvailable<=game->GetCurrentChapter())?
|
||||||
attr.ShowAsDecimal()?std::format("{:<4.2f}{}",nextStageValue,percentageSign):std::format("{}{}",nextStageValue,percentageSign)
|
attr.ShowAsDecimal()?std::format("{:<4.2f}{}",nextStageValue,percentageSign):std::format("{}{}",nextStageValue,percentageSign)
|
||||||
:"MAX"),
|
:"MAX"),
|
||||||
WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
|
WHITE,BLACK,adjustedScale,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x);
|
||||||
}
|
}
|
||||||
yOffset+=16;
|
yOffset+=16;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
std::string text="Cannot be enhanced.";
|
std::string text="Cannot be enhanced.";
|
||||||
float textWidth=game->GetTextSizeProp(text).x;
|
float textWidth=game->GetTextSizeProp(text).x;
|
||||||
window.DrawShadowStringPropDecal(rect.middle()-vf2d{textWidth,0}/2,text,RED,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x,1.0f);
|
window.DrawShadowStringPropDecal(rect.middle()-vf2d{textWidth,0}/2,text,RED,BLACK,adjustedScale,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -160,7 +160,7 @@ protected:
|
|||||||
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale;
|
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale;
|
||||||
vf2d drawPos=rect.pos+rect.size-textSize;
|
vf2d drawPos=rect.pos+rect.size-textSize;
|
||||||
if(itemRef.lock()->Amt()!=INFINITE){
|
if(itemRef.lock()->Amt()!=INFINITE){
|
||||||
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale);
|
window.DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,15 +138,15 @@ protected:
|
|||||||
}else{
|
}else{
|
||||||
if(shadow){
|
if(shadow){
|
||||||
if(proportional){
|
if(proportional){
|
||||||
window.DrawShadowStringPropDecal(drawPos,finalLabel,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4,1.0f);
|
window.DrawShadowStringPropDecal(drawPos,finalLabel,WHITE,BLACK,adjustedScale,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4);
|
||||||
}else{
|
}else{
|
||||||
window.DrawShadowStringDecal(drawPos,finalLabel,WHITE,BLACK,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4,1.0f);
|
window.DrawShadowStringDecal(drawPos,finalLabel,WHITE,BLACK,adjustedScale,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(proportional){
|
if(proportional){
|
||||||
window.DrawStringPropDecal(drawPos,finalLabel,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4,1.0f);
|
window.DrawStringPropDecal(drawPos,finalLabel,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4);
|
||||||
}else{
|
}else{
|
||||||
window.DrawStringDecal(drawPos,finalLabel,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4,1.0f);
|
window.DrawStringDecal(drawPos,finalLabel,WHITE,adjustedScale,fitToLabel?std::numeric_limits<float>::max():rect.size.x-4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ protected:
|
|||||||
window.DrawStringPropDecal(rect.pos+rect.size/2-game->GetWrappedTextSizeProp(GetLabel(),int(rect.size.x-1),scale)/2,GetLabel(),WHITE,{1,1},int(rect.size.x-1));
|
window.DrawStringPropDecal(rect.pos+rect.size/2-game->GetWrappedTextSizeProp(GetLabel(),int(rect.size.x-1),scale)/2,GetLabel(),WHITE,{1,1},int(rect.size.x-1));
|
||||||
}
|
}
|
||||||
if(shadow){
|
if(shadow){
|
||||||
window.DrawShadowStringPropDecal(drawPos,GetLabel(),WHITE,BLACK,scale,int(rect.size.x-1));
|
window.DrawShadowStringPropDecal(drawPos,GetLabel(),WHITE,BLACK,scale,scale,int(rect.size.x-1));
|
||||||
}else{
|
}else{
|
||||||
window.DrawStringPropDecal(drawPos,GetLabel(),WHITE,scale,int(rect.size.x-1));
|
window.DrawStringPropDecal(drawPos,GetLabel(),WHITE,scale,int(rect.size.x-1));
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 2
|
||||||
#define VERSION_PATCH 3
|
#define VERSION_PATCH 3
|
||||||
#define VERSION_BUILD 10737
|
#define VERSION_BUILD 10791
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -84,6 +84,7 @@ Images
|
|||||||
GFX_Unlock = unlock.png
|
GFX_Unlock = unlock.png
|
||||||
GFX_SwordSlash = swordslash.png
|
GFX_SwordSlash = swordslash.png
|
||||||
GFX_CustomFont = font.png
|
GFX_CustomFont = font.png
|
||||||
|
GFX_CustomFontShadow = font_shadow.png
|
||||||
GFX_Vignette = vignette.png
|
GFX_Vignette = vignette.png
|
||||||
GFX_Checkmark = checkmark.png
|
GFX_Checkmark = checkmark.png
|
||||||
GFX_DaggerStab = dagger_stab.png
|
GFX_DaggerStab = dagger_stab.png
|
||||||
|
BIN
Adventures in Lestoria/assets/font_shadow.png
Normal file
BIN
Adventures in Lestoria/assets/font_shadow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
@ -182,8 +182,10 @@ namespace olc
|
|||||||
// Draws a multiline string as a decal, with tiniting and scaling
|
// Draws a multiline string as a decal, with tiniting and scaling
|
||||||
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max());
|
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max());
|
||||||
void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max());
|
void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max());
|
||||||
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const float shadowSizeFactor=1);
|
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const float shadowSizeFactor=1);
|
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale, const olc::vf2d& shadowScale,const float width=std::numeric_limits<float>::max());
|
||||||
|
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
|
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale, const olc::vf2d& shadowScale,const float width=std::numeric_limits<float>::max());
|
||||||
// Draws a single shaded filled rectangle as a decal
|
// Draws a single shaded filled rectangle as a decal
|
||||||
void FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE);
|
void FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE);
|
||||||
void DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE);
|
void DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE);
|
||||||
@ -644,12 +646,20 @@ namespace olc
|
|||||||
pge->DrawStringPropDecal(WorldToScreen(pos), sText, col, scale * m_vWorldScale * m_vRecipPixel,width);
|
pge->DrawStringPropDecal(WorldToScreen(pos), sText, col, scale * m_vWorldScale * m_vRecipPixel,width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransformedView::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor){
|
void TransformedView::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale){
|
||||||
pge->DrawShadowStringDecal(WorldToScreen(pos),sText,col,shadowCol,scale,width,shadowSizeFactor);
|
pge->DrawShadowStringDecal(WorldToScreen(pos),sText,col,shadowCol,scale,scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransformedView::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor){
|
void TransformedView::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale, const olc::vf2d& shadowScale,const float width){
|
||||||
pge->DrawShadowStringPropDecal(WorldToScreen(pos),sText,col,shadowCol,scale,width,shadowSizeFactor);
|
pge->DrawShadowStringDecal(WorldToScreen(pos),sText,col,shadowCol,scale,shadowScale,width);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale){
|
||||||
|
pge->DrawShadowStringPropDecal(WorldToScreen(pos),sText,col,shadowCol,scale,scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformedView::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale, const olc::vf2d& shadowScale,const float width){
|
||||||
|
pge->DrawShadowStringPropDecal(WorldToScreen(pos),sText,col,shadowCol,scale,shadowScale,width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransformedView::FillRectDecal(const olc::vf2d & pos, const olc::vf2d & size, const olc::Pixel col)
|
void TransformedView::FillRectDecal(const olc::vf2d & pos, const olc::vf2d & size, const olc::Pixel col)
|
||||||
|
@ -116,11 +116,13 @@ namespace olc {
|
|||||||
const vf2d &pos2,
|
const vf2d &pos2,
|
||||||
Pixel p = WHITE) const;
|
Pixel p = WHITE) const;
|
||||||
// Draws a multiline string as a decal, with tinting and scaling
|
// Draws a multiline string as a decal, with tinting and scaling
|
||||||
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const bool disableDynamicScaling=false);
|
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max());
|
||||||
void DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
void DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }, const float width=std::numeric_limits<float>::max(),const bool disableDynamicScaling=false);
|
void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }, const float width=std::numeric_limits<float>::max());
|
||||||
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const float shadowSizeFactor=1,const bool disableDynamicScaling=false);
|
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col=WHITE, const Pixel shadowCol=BLACK, const olc::vf2d& scale={1.f,1.f});
|
||||||
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const float shadowSizeFactor=1,const bool disableDynamicScaling=false);
|
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale, const olc::vf2d& shadowScale,const float width=std::numeric_limits<float>::max());
|
||||||
|
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col=WHITE, const Pixel shadowCol=BLACK, const olc::vf2d& scale={1.f,1.f});
|
||||||
|
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale, const olc::vf2d& shadowScale,const float width=std::numeric_limits<float>::max());
|
||||||
void DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
void DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||||
void DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f });
|
void DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
|
|
||||||
@ -634,36 +636,116 @@ float olc::ViewPort::directionFromLine(vf2d lineA, vf2d lineB, vf2d point) {
|
|||||||
- (point.x - lineA.x) * (lineB.y - lineA.y);
|
- (point.x - lineA.x) * (lineB.y - lineA.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale, const float width,const bool disableDynamicScaling){
|
void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale, const float width){
|
||||||
if(sText.length()==0)return;
|
Pixel textCol=col;
|
||||||
std::string originalKey{pge->stripCol(sText)};
|
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||||
std::string renderStr{pge->stripLeadingCol(sText)};
|
letters.clear();
|
||||||
std::string key{"DSD_"+originalKey};
|
bool wrappingOccurred=false;
|
||||||
key+=std::to_string(width);
|
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||||
if(!disableDynamicScaling){
|
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||||
key+=scale.str();
|
const auto hexToNumber=[](char c){
|
||||||
}
|
if(c<='9')return c-'0';
|
||||||
const bool RerenderRequired=pge->garbageCollector.count(key)&&pge->garbageCollector[key].originalStr!=renderStr;
|
return (c-'A')+10;
|
||||||
const bool ShadowRerenderRequired=pge->garbageCollector.count(key+"_SHADOW")&&pge->garbageCollector[key+"_SHADOW"].originalStr!=renderStr;
|
};
|
||||||
if(!pge->garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
for (int skip=0,index=-1;auto c : sText)
|
||||||
vf2d imageSize=pge->GetWrappedTextSize(originalKey,width,scale);
|
{
|
||||||
if(imageSize.x<1||imageSize.y<1)return;
|
index++;
|
||||||
Decal*newDecal=nullptr;
|
if(skip){
|
||||||
if(!RerenderRequired){
|
skip--;
|
||||||
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
|
continue;
|
||||||
pge->garbageCollector[key].decal=newDecal;
|
}
|
||||||
}else{
|
if(c==' '||c=='\t'||c=='\n'){
|
||||||
newDecal=pge->garbageCollector[key].decal;
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, pge->fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale,letter.col);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}
|
||||||
|
if(wrappingOccurred){
|
||||||
|
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}else{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, pge->fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
drawingMarker.x = 0; drawingMarker.y += 8.0f * scale.y;
|
||||||
|
}
|
||||||
|
else if (c == ' ')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
else if (c == '\t')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c>=-128&&c<-105)
|
||||||
|
{
|
||||||
|
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||||
|
}
|
||||||
|
else if (c==PixelGameEngine::Reset[0])
|
||||||
|
{
|
||||||
|
textCol=col;
|
||||||
|
}
|
||||||
|
else if (c=='#')
|
||||||
|
{
|
||||||
|
skip=6;
|
||||||
|
textCol=BLACK;
|
||||||
|
for(int i=1;i<7;i++){
|
||||||
|
if(i<3){
|
||||||
|
textCol.r*=16;
|
||||||
|
textCol.r+=hexToNumber(sText[index+i]);
|
||||||
|
}else
|
||||||
|
if(i<5){
|
||||||
|
textCol.g*=16;
|
||||||
|
textCol.g+=hexToNumber(sText[index+i]);
|
||||||
|
}else{
|
||||||
|
textCol.b*=16;
|
||||||
|
textCol.b+=hexToNumber(sText[index+i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(textCol==WHITE)textCol=col;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = (c - 32) % 16;
|
||||||
|
int32_t oy = (c - 32) / 16;
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
if(planningMarker.x>width){
|
||||||
|
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, pge->fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale,letter.col);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
}else{
|
||||||
|
drawingMarker.x-=pge->vFontSpacing[' '-32].y*scale.x; //Don't include the space in the sizing when wrapping.
|
||||||
|
}
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
drawingMarker=planningMarker;
|
||||||
|
wrappingOccurred=true;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
letters.emplace_back(c,vf2d{ float(ox) * 8.0f, float(oy) * 8.0f }, vf2d{ 8.0f, 8.0f },textCol);
|
||||||
}
|
}
|
||||||
pge->garbageCollector[key].originalStr=originalKey;
|
|
||||||
pge->SetDrawTarget(newDecal->sprite);
|
|
||||||
pge->Clear(BLANK);
|
|
||||||
pge->DrawString({0,0},renderStr,WHITE,1U,width/scale.x);
|
|
||||||
pge->SetDrawTarget(nullptr);
|
|
||||||
newDecal->Update();
|
|
||||||
}
|
}
|
||||||
pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f;
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
DrawDecal(pos,pge->garbageCollector[key].decal,scale,pge->GetFinalRenderColor(col,sText));
|
DrawPartialDecal(pos + drawingMarker, pge->fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale,letter.col);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void olc::ViewPort::DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const olc::vf2d& scale){
|
void olc::ViewPort::DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const olc::vf2d& scale){
|
||||||
@ -682,140 +764,306 @@ void olc::ViewPort::DrawStringDecal(Font&font, const olc::vf2d& pos, const std::
|
|||||||
DrawDecal(pos,pge->garbageCollector[key].decal,scale/4,pge->GetFinalRenderColor(col,sText));
|
DrawDecal(pos,pge->garbageCollector[key].decal,scale/4,pge->GetFinalRenderColor(col,sText));
|
||||||
}
|
}
|
||||||
|
|
||||||
void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale,const float width,const bool disableDynamicScaling){
|
void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale,const float width){
|
||||||
if(sText.length()==0)return;
|
Pixel textCol=col;
|
||||||
std::string originalKey{pge->stripCol(sText)};
|
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||||
std::string renderStr{pge->stripLeadingCol(sText)};
|
letters.clear();
|
||||||
std::string key{"DSPD"+originalKey};
|
bool wrappingOccurred=false;
|
||||||
key+=std::to_string(width);
|
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||||
if(!disableDynamicScaling){
|
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||||
key+=scale.str();
|
const auto hexToNumber=[](char c){
|
||||||
}
|
if(c<='9')return c-'0';
|
||||||
const bool RerenderRequired=pge->garbageCollector.count(key)&&pge->garbageCollector[key].originalStr!=renderStr;
|
return (c-'A')+10;
|
||||||
const bool ShadowRerenderRequired=pge->garbageCollector.count(key+"_SHADOW")&&pge->garbageCollector[key+"_SHADOW"].originalStr!=renderStr;
|
};
|
||||||
if(!pge->garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
for (int skip=0,index=-1;auto c : sText)
|
||||||
vf2d imageSize=pge->GetWrappedTextSizeProp(originalKey,width,scale);
|
{
|
||||||
if(imageSize.x<1||imageSize.y<1)return;
|
index++;
|
||||||
Decal*newDecal=nullptr;
|
if(skip){
|
||||||
if(!RerenderRequired){
|
skip--;
|
||||||
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
|
continue;
|
||||||
pge->garbageCollector[key].decal=newDecal;
|
|
||||||
}else{
|
|
||||||
newDecal=pge->garbageCollector[key].decal;
|
|
||||||
}
|
}
|
||||||
pge->garbageCollector[key].originalStr=originalKey;
|
if(c==' '||c=='\t'||c=='\n'){
|
||||||
pge->SetDrawTarget(newDecal->sprite);
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
pge->Clear(BLANK);
|
DrawPartialDecal(pos + drawingMarker, pge->fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||||
pge->DrawStringProp({0,0},renderStr,WHITE,1U,width/scale.x);
|
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
pge->SetDrawTarget(nullptr);
|
}
|
||||||
newDecal->Update();
|
letters.clear();
|
||||||
}
|
wrappingOccurred=false;
|
||||||
pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f;
|
|
||||||
DrawDecal(pos,pge->garbageCollector[key].decal,scale,pge->GetFinalRenderColor(col,sText));
|
|
||||||
}
|
|
||||||
|
|
||||||
void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor,const bool disableDynamicScaling){
|
|
||||||
if(sText.length()==0)return;
|
|
||||||
std::string originalKey{pge->stripCol(sText)};
|
|
||||||
std::string renderStr{pge->stripLeadingCol(sText)};
|
|
||||||
std::string key{"DSSD_"+originalKey};
|
|
||||||
key+=std::to_string(width);
|
|
||||||
if(!disableDynamicScaling){
|
|
||||||
key+=scale.str();
|
|
||||||
}
|
|
||||||
const bool RerenderRequired=pge->garbageCollector.count(key)&&pge->garbageCollector[key].originalStr!=renderStr;
|
|
||||||
const bool ShadowRerenderRequired=pge->garbageCollector.count(key+"_SHADOW")&&pge->garbageCollector[key+"_SHADOW"].originalStr!=renderStr;
|
|
||||||
if(!pge->garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
|
||||||
vf2d imageSize=pge->GetWrappedTextSize(originalKey,width,scale);
|
|
||||||
if(imageSize.x<1||imageSize.y<1)return;
|
|
||||||
Decal*newDecal=nullptr;
|
|
||||||
if(!RerenderRequired){
|
|
||||||
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
|
|
||||||
pge->garbageCollector[key].decal=newDecal;
|
|
||||||
}else{
|
|
||||||
newDecal=pge->garbageCollector[key].decal;
|
|
||||||
}
|
}
|
||||||
pge->garbageCollector[key].originalStr=originalKey;
|
if(wrappingOccurred){
|
||||||
pge->SetDrawTarget(newDecal->sprite);
|
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||||
pge->Clear(BLANK);
|
wrappingOccurred=false;
|
||||||
pge->DrawString({0,0},renderStr,WHITE,1U,width/scale.x);
|
}else{
|
||||||
newDecal->Update();
|
continue;
|
||||||
vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale;
|
|
||||||
Decal*newShadowDecal=nullptr;
|
|
||||||
if(!ShadowRerenderRequired){
|
|
||||||
newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.y/scale.y*4)+adjustedShadowSizeFactor.y*2));
|
|
||||||
pge->garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
|
|
||||||
}else{
|
|
||||||
newShadowDecal=pge->garbageCollector[key+"_SHADOW"].decal;
|
|
||||||
}
|
|
||||||
pge->SetDrawTarget(newShadowDecal->sprite);
|
|
||||||
pge->Clear(BLANK);
|
|
||||||
for(float y=-adjustedShadowSizeFactor.y;y<=adjustedShadowSizeFactor.y+0.1;y+=adjustedShadowSizeFactor.y/2){
|
|
||||||
for(float x=-adjustedShadowSizeFactor.x;x<=adjustedShadowSizeFactor.x+0.1;x+=adjustedShadowSizeFactor.x/2){
|
|
||||||
if(x!=0||y!=0){
|
|
||||||
pge->DrawString(vf2d{x,y}+adjustedShadowSizeFactor,renderStr,WHITE,4U,width/scale.x*4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pge->SetDrawTarget(nullptr);
|
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||||
newShadowDecal->Update();
|
if (c == '\n')
|
||||||
}
|
{
|
||||||
pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f;
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
pge->garbageCollector[key+"_SHADOW"].expireTime=pge->GetRunTime()+120.0f;
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},pge->garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol);
|
DrawPartialDecal(pos + drawingMarker, pge->fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||||
DrawDecal(pos,pge->garbageCollector[key].decal,scale,pge->GetFinalRenderColor(col,sText));
|
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
}
|
}
|
||||||
|
letters.clear();
|
||||||
void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor,const bool disableDynamicScaling){
|
drawingMarker.x = 0; drawingMarker.y += 8.0f * scale.y;
|
||||||
if(sText.length()==0)return;
|
|
||||||
std::string originalKey{pge->stripCol(sText)};
|
|
||||||
std::string renderStr{pge->stripLeadingCol(sText)};
|
|
||||||
std::string key{"DSSPD"+originalKey};
|
|
||||||
key+=std::to_string(width);
|
|
||||||
if(!disableDynamicScaling){
|
|
||||||
key+=scale.str();
|
|
||||||
}
|
|
||||||
const bool RerenderRequired=pge->garbageCollector.count(key)&&pge->garbageCollector[key].originalStr!=renderStr;
|
|
||||||
const bool ShadowRerenderRequired=pge->garbageCollector.count(key+"_SHADOW")&&pge->garbageCollector[key+"_SHADOW"].originalStr!=renderStr;
|
|
||||||
if(!pge->garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
|
||||||
vf2d imageSize=pge->GetWrappedTextSizeProp(originalKey,width,scale);
|
|
||||||
if(imageSize.x<1||imageSize.y<1)return;
|
|
||||||
Decal*newDecal=nullptr;
|
|
||||||
if(!RerenderRequired){
|
|
||||||
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
|
|
||||||
pge->garbageCollector[key].decal=newDecal;
|
|
||||||
}else{
|
|
||||||
newDecal=pge->garbageCollector[key].decal;
|
|
||||||
}
|
}
|
||||||
pge->garbageCollector[key].originalStr=originalKey;
|
else if (c == ' ')
|
||||||
pge->SetDrawTarget(newDecal->sprite);
|
{
|
||||||
pge->Clear(BLANK);
|
drawingMarker.x += float(pge->vFontSpacing[' ' - 32].y) * scale.x;
|
||||||
pge->DrawStringProp({0,0},renderStr,WHITE,1U,width/scale.x);
|
planningMarker.x += float(pge->vFontSpacing[' ' - 32].y) * scale.x;
|
||||||
newDecal->Update();
|
|
||||||
vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale;
|
|
||||||
Decal*newShadowDecal=nullptr;
|
|
||||||
if(!ShadowRerenderRequired){
|
|
||||||
newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.y/scale.y*4)+adjustedShadowSizeFactor.y*2));
|
|
||||||
pge->garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
|
|
||||||
}else{
|
|
||||||
newShadowDecal=pge->garbageCollector[key+"_SHADOW"].decal;
|
|
||||||
}
|
}
|
||||||
pge->SetDrawTarget(newShadowDecal->sprite);
|
else if (c == '\t')
|
||||||
pge->Clear(BLANK);
|
{
|
||||||
for(float y=-adjustedShadowSizeFactor.y;y<=adjustedShadowSizeFactor.y+0.1;y+=adjustedShadowSizeFactor.y/2){
|
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
for(float x=-adjustedShadowSizeFactor.x;x<=adjustedShadowSizeFactor.x+0.1;x+=adjustedShadowSizeFactor.x/2){
|
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
if(x!=0||y!=0){
|
}
|
||||||
pge->DrawStringProp(vf2d{x,y}+adjustedShadowSizeFactor,renderStr,WHITE,4U,width/scale.x*4);
|
else if (c>=-128&&c<-105)
|
||||||
|
{
|
||||||
|
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||||
|
}
|
||||||
|
else if (c==PixelGameEngine::Reset[0])
|
||||||
|
{
|
||||||
|
textCol=col;
|
||||||
|
}
|
||||||
|
else if (c=='#')
|
||||||
|
{
|
||||||
|
skip=6;
|
||||||
|
textCol=BLACK;
|
||||||
|
for(int i=1;i<7;i++){
|
||||||
|
if(i<3){
|
||||||
|
textCol.r*=16;
|
||||||
|
textCol.r+=hexToNumber(sText[index+i]);
|
||||||
|
}else
|
||||||
|
if(i<5){
|
||||||
|
textCol.g*=16;
|
||||||
|
textCol.g+=hexToNumber(sText[index+i]);
|
||||||
|
}else{
|
||||||
|
textCol.b*=16;
|
||||||
|
textCol.b+=hexToNumber(sText[index+i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(textCol==WHITE)textCol=col;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = (c - 32) % 16;
|
||||||
|
int32_t oy = (c - 32) / 16;
|
||||||
|
planningMarker.x += float(pge->vFontSpacing[c - 32].y) * scale.x;
|
||||||
|
if(planningMarker.x>width){
|
||||||
|
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, pge->fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale,letter.col);
|
||||||
|
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
}else{
|
||||||
|
drawingMarker.x-=float(pge->vFontSpacing[' '-32].y)*scale.x; //Don't include the space in the sizing when wrapping.
|
||||||
|
}
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
drawingMarker=planningMarker;
|
||||||
|
wrappingOccurred=true;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
planningMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
letters.emplace_back(c,vf2d{ float(ox) * 8.0f + float(pge->vFontSpacing[c - 32].x), float(oy) * 8.0f }, vf2d{ float(pge->vFontSpacing[c - 32].y), 8.0f },textCol);
|
||||||
}
|
}
|
||||||
pge->SetDrawTarget(nullptr);
|
|
||||||
newShadowDecal->Update();
|
|
||||||
}
|
}
|
||||||
pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f;
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
pge->garbageCollector[key+"_SHADOW"].expireTime=pge->GetRunTime()+120.0f;
|
DrawPartialDecal(pos + drawingMarker, pge->fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||||
DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},pge->garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol);
|
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
DrawDecal(pos,pge->garbageCollector[key].decal,scale,pge->GetFinalRenderColor(col,sText));
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale){
|
||||||
|
DrawShadowStringDecal(pos,sText,col,shadowCol,scale,scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const olc::vf2d& shadowScale,const float width){
|
||||||
|
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||||
|
letters.clear();
|
||||||
|
bool wrappingOccurred=false;
|
||||||
|
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||||
|
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||||
|
const auto hexToNumber=[](char c){
|
||||||
|
if(c<='9')return c-'0';
|
||||||
|
return (c-'A')+10;
|
||||||
|
};
|
||||||
|
for (int skip=0,index=-1;auto c : sText)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
if(skip){
|
||||||
|
skip--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c==' '||c=='\t'||c=='\n'){
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, pge->fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}
|
||||||
|
if(wrappingOccurred){
|
||||||
|
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}else{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, pge->fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
drawingMarker.x = 0; drawingMarker.y += 8.0f * scale.y;
|
||||||
|
}
|
||||||
|
else if (c == ' ')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
else if (c == '\t')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c>=-128&&c<-105){}
|
||||||
|
else if (c==PixelGameEngine::Reset[0]){}
|
||||||
|
else if (c=='#')
|
||||||
|
{
|
||||||
|
skip=6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = (c - 32) % 16;
|
||||||
|
int32_t oy = (c - 32) / 16;
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
if(planningMarker.x>width){
|
||||||
|
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, pge->fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
}else{
|
||||||
|
drawingMarker.x-=pge->vFontSpacing[' '-32].y*scale.x; //Don't include the space in the sizing when wrapping.
|
||||||
|
}
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
drawingMarker=planningMarker;
|
||||||
|
wrappingOccurred=true;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
letters.emplace_back(c,vf2d{ float(ox) * 10.0f, float(oy) * 10.0f }, vf2d{ 10.0f, 10.0f },shadowCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, pge->fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
DrawStringDecal(pos,sText,col,scale,width);
|
||||||
|
}
|
||||||
|
|
||||||
|
void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale){
|
||||||
|
DrawShadowStringPropDecal(pos,sText,col,shadowCol,scale,scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const olc::vf2d& shadowScale,const float width){
|
||||||
|
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||||
|
letters.clear();
|
||||||
|
bool wrappingOccurred=false;
|
||||||
|
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||||
|
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||||
|
const auto hexToNumber=[](char c){
|
||||||
|
if(c<='9')return c-'0';
|
||||||
|
return (c-'A')+10;
|
||||||
|
};
|
||||||
|
for (int skip=0,index=-1;auto c : sText)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
if(skip){
|
||||||
|
skip--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c==' '||c=='\t'||c=='\n'){
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, pge->fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}
|
||||||
|
if(wrappingOccurred){
|
||||||
|
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}else{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, pge->fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
drawingMarker.x = 0; drawingMarker.y += 8.0f * scale.y;
|
||||||
|
}
|
||||||
|
else if (c == ' ')
|
||||||
|
{
|
||||||
|
drawingMarker.x += float(pge->vFontSpacing[' ' - 32].y) * scale.x;
|
||||||
|
planningMarker.x += float(pge->vFontSpacing[' ' - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c == '\t')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c>=-128&&c<-105){}
|
||||||
|
else if (c==PixelGameEngine::Reset[0]){}
|
||||||
|
else if (c=='#')
|
||||||
|
{
|
||||||
|
skip=6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = (c - 32) % 16;
|
||||||
|
int32_t oy = (c - 32) / 16;
|
||||||
|
planningMarker.x += float(pge->vFontSpacing[c - 32].y) * scale.x;
|
||||||
|
if(planningMarker.x>width){
|
||||||
|
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, pge->fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
}else{
|
||||||
|
drawingMarker.x-=pge->vFontSpacing[' '-32].y*scale.x; //Don't include the space in the sizing when wrapping.
|
||||||
|
}
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
drawingMarker=planningMarker;
|
||||||
|
wrappingOccurred=true;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
planningMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
letters.emplace_back(c,vf2d{ float(ox) * 10.0f + float(pge->vFontSpacing[c - 32].x), float(oy) * 10.0f }, vf2d{ float(pge->vFontSpacing[c - 32].y)+2, 10.0f },shadowCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, pge->fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
DrawStringPropDecal(pos,sText,col,scale,width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void olc::ViewPort::DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
void olc::ViewPort::DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||||
@ -828,7 +1076,7 @@ void olc::ViewPort::DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const
|
|||||||
if(!pge->garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
if(!pge->garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||||
delete pge->garbageCollector[key].decal;
|
delete pge->garbageCollector[key].decal;
|
||||||
pge->garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
pge->garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
||||||
pge->garbageCollector[key].originalStr=std::string(originalKey.begin(),originalKey.end());
|
pge->garbageCollector[key].originalStr=std::string(renderStr.begin(),renderStr.end());
|
||||||
}
|
}
|
||||||
pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f;
|
pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f;
|
||||||
std::erase_if(pge->garbageCollector,[&](auto&key){
|
std::erase_if(pge->garbageCollector,[&](auto&key){
|
||||||
@ -858,7 +1106,7 @@ void olc::ViewPort::DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, c
|
|||||||
if(!pge->garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
if(!pge->garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||||
delete pge->garbageCollector[key].decal;
|
delete pge->garbageCollector[key].decal;
|
||||||
pge->garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
pge->garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
||||||
pge->garbageCollector[key].originalStr=std::string(originalKey.begin(),originalKey.end());
|
pge->garbageCollector[key].originalStr=std::string(renderStr.begin(),renderStr.end());
|
||||||
}
|
}
|
||||||
pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f;
|
pge->garbageCollector[key].expireTime=pge->GetRunTime()+120.0f;
|
||||||
DrawDecal(pos+vf2d{0,0.5f},pge->garbageCollector[key].decal,scale/4,shadowCol);
|
DrawDecal(pos+vf2d{0,0.5f},pge->garbageCollector[key].decal,scale/4,shadowCol);
|
||||||
|
@ -1148,12 +1148,14 @@ namespace olc
|
|||||||
void DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
|
void DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||||
void DrawPartialSquishedRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::vf2d& squishScale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
|
void DrawPartialSquishedRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::vf2d& squishScale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||||
// Draws a multiline string as a decal, with tiniting and scaling
|
// Draws a multiline string as a decal, with tiniting and scaling
|
||||||
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const bool disableDynamicScaling=false);
|
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max());
|
||||||
void DrawOGStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
void DrawOGStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
void DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
void DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }, const float width=std::numeric_limits<float>::max(),const bool disableDynamicScaling=false);
|
void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }, const float width=std::numeric_limits<float>::max());
|
||||||
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const float shadowSizeFactor=1,const bool disableDynamicScaling=false);
|
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col=WHITE, const Pixel shadowCol=BLACK, const olc::vf2d& scale={1.f,1.f});
|
||||||
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const float shadowSizeFactor=1,const bool disableDynamicScaling=false);
|
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const olc::vf2d&shadowScale,const float width=std::numeric_limits<float>::max());
|
||||||
|
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col=WHITE, const Pixel shadowCol=BLACK, const olc::vf2d& scale={1.f,1.f});
|
||||||
|
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const olc::vf2d&shadowScale,const float width=std::numeric_limits<float>::max());
|
||||||
void DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
void DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||||
void DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f });
|
void DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||||
// Draws a single shaded filled rectangle as a decal
|
// Draws a single shaded filled rectangle as a decal
|
||||||
@ -1182,7 +1184,7 @@ namespace olc
|
|||||||
olc::Sprite* GetFontSprite();
|
olc::Sprite* GetFontSprite();
|
||||||
// Returns the font image
|
// Returns the font image
|
||||||
olc::Decal* GetFontDecal();
|
olc::Decal* GetFontDecal();
|
||||||
void SetFontSprite(std::string_view filename,ResourcePack*pack,bool generateGamePack);
|
void SetFontSprite(std::string_view filename,std::string_view shadowFilename,ResourcePack*pack,bool generateGamePack);
|
||||||
|
|
||||||
// Clip a line segment to visible area
|
// Clip a line segment to visible area
|
||||||
bool ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2);
|
bool ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2);
|
||||||
@ -1311,7 +1313,7 @@ namespace olc
|
|||||||
float fLastElapsed = 0.0f;
|
float fLastElapsed = 0.0f;
|
||||||
int nFrameCount = 0;
|
int nFrameCount = 0;
|
||||||
bool bSuspendTextureTransfer = false;
|
bool bSuspendTextureTransfer = false;
|
||||||
Renderable fontRenderable;
|
Renderable fontRenderable,fontRenderableShadow;
|
||||||
std::vector<LayerDesc> vLayers;
|
std::vector<LayerDesc> vLayers;
|
||||||
uint8_t nTargetLayer = 0;
|
uint8_t nTargetLayer = 0;
|
||||||
uint32_t nLastFPS = 0;
|
uint32_t nLastFPS = 0;
|
||||||
@ -2474,16 +2476,20 @@ namespace olc
|
|||||||
{ return fontRenderable.Sprite(); }
|
{ return fontRenderable.Sprite(); }
|
||||||
olc::Decal* PixelGameEngine::GetFontDecal()
|
olc::Decal* PixelGameEngine::GetFontDecal()
|
||||||
{ return fontRenderable.Decal(); }
|
{ return fontRenderable.Decal(); }
|
||||||
void PixelGameEngine::SetFontSprite(std::string_view filename,ResourcePack*pack,bool generateGamePack)
|
void PixelGameEngine::SetFontSprite(std::string_view filename,std::string_view shadowFilename,ResourcePack*pack,bool generateGamePack)
|
||||||
{
|
{
|
||||||
if(pack->Loaded()){
|
if(pack->Loaded()){
|
||||||
fontRenderable.Load(std::string(filename),pack);
|
fontRenderable.Load(std::string(filename),pack);
|
||||||
|
fontRenderableShadow.Load(std::string(shadowFilename),pack);
|
||||||
}else{
|
}else{
|
||||||
fontRenderable.Load(std::string(filename),nullptr);
|
fontRenderable.Load(std::string(filename),nullptr);
|
||||||
|
fontRenderableShadow.Load(std::string(shadowFilename),nullptr);
|
||||||
if(generateGamePack){
|
if(generateGamePack){
|
||||||
pack->AddFile(std::string(filename));
|
pack->AddFile(std::string(filename));
|
||||||
|
pack->AddFile(std::string(shadowFilename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Generate shadow version.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelGameEngine::ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2)
|
bool PixelGameEngine::ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2)
|
||||||
@ -3483,120 +3489,325 @@ namespace olc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelGameEngine::DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale,const float width,const bool disableDynamicScaling)
|
void PixelGameEngine::DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale,const float width)
|
||||||
{
|
{
|
||||||
if(sText.length()==0)return;
|
Pixel textCol=col;
|
||||||
std::string originalKey{stripCol(sText)};
|
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||||
std::string renderStr{stripLeadingCol(sText)};
|
letters.clear();
|
||||||
std::string key{"DSD"+std::string(originalKey)};
|
bool wrappingOccurred=false;
|
||||||
key+=std::to_string(width);
|
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||||
if(!disableDynamicScaling){
|
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||||
key+=scale.str();
|
const auto hexToNumber=[](char c){
|
||||||
}
|
if(c<='9')return c-'0';
|
||||||
const bool RerenderRequired=garbageCollector.count(key)&&garbageCollector[key].originalStr!=renderStr;
|
return (c-'A')+10;
|
||||||
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
};
|
||||||
vf2d imageSize=GetWrappedTextSize(originalKey,width,scale);
|
for (int skip=0,index=-1;auto c : sText)
|
||||||
if(imageSize.x<1||imageSize.y<1)return;
|
{
|
||||||
Decal*newDecal=nullptr;
|
index++;
|
||||||
if(!RerenderRequired){
|
if(skip){
|
||||||
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
|
skip--;
|
||||||
garbageCollector[key].decal=newDecal;
|
continue;
|
||||||
}else{
|
|
||||||
newDecal=garbageCollector[key].decal;
|
|
||||||
}
|
}
|
||||||
garbageCollector[key].originalStr=originalKey;
|
if(c==' '||c=='\t'||c=='\n'){
|
||||||
SetDrawTarget(newDecal->sprite);
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
Clear(BLANK);
|
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale,letter.col);
|
||||||
DrawString({0,0},renderStr,WHITE,1U,width/scale.x);
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
SetDrawTarget(nullptr);
|
}
|
||||||
newDecal->Update();
|
letters.clear();
|
||||||
}
|
wrappingOccurred=false;
|
||||||
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
|
||||||
DrawDecal(pos,garbageCollector[key].decal,scale,GetFinalRenderColor(col,sText));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PixelGameEngine::DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale, const float width,const bool disableDynamicScaling)
|
|
||||||
{
|
|
||||||
if(sText.length()==0)return;
|
|
||||||
std::string originalKey{stripCol(sText)};
|
|
||||||
std::string renderStr{stripLeadingCol(sText)};
|
|
||||||
std::string key{"DSPD_"+std::string(originalKey)};
|
|
||||||
key+=std::to_string(width);
|
|
||||||
if(!disableDynamicScaling){
|
|
||||||
key+=scale.str();
|
|
||||||
}
|
|
||||||
const bool RerenderRequired=garbageCollector.count(key)&&garbageCollector[key].originalStr!=renderStr;
|
|
||||||
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
|
||||||
vf2d imageSize=GetWrappedTextSizeProp(originalKey,width,scale);
|
|
||||||
if(imageSize.x<1||imageSize.y<1)return;
|
|
||||||
Decal*newDecal=nullptr;
|
|
||||||
if(!RerenderRequired){
|
|
||||||
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
|
|
||||||
garbageCollector[key].decal=newDecal;
|
|
||||||
}else{
|
|
||||||
newDecal=garbageCollector[key].decal;
|
|
||||||
}
|
}
|
||||||
garbageCollector[key].originalStr=originalKey;
|
if(wrappingOccurred){
|
||||||
SetDrawTarget(newDecal->sprite);
|
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||||
Clear(BLANK);
|
wrappingOccurred=false;
|
||||||
DrawStringProp({0,0},renderStr,WHITE,1U,width/scale.x);
|
}else{
|
||||||
SetDrawTarget(nullptr);
|
continue;
|
||||||
newDecal->Update();
|
|
||||||
}
|
|
||||||
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
|
||||||
DrawDecal(pos,garbageCollector[key].decal,scale,GetFinalRenderColor(col,sText));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PixelGameEngine::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor,const bool disableDynamicScaling){
|
|
||||||
if(sText.length()==0)return;
|
|
||||||
std::string originalKey{stripCol(sText)};
|
|
||||||
std::string renderStr{stripLeadingCol(sText)};
|
|
||||||
std::string key{"DSSD_"+std::string(originalKey)};
|
|
||||||
key+=std::to_string(width);
|
|
||||||
if(!disableDynamicScaling){
|
|
||||||
key+=scale.str();
|
|
||||||
}
|
|
||||||
const bool RerenderRequired=garbageCollector.count(key)&&garbageCollector[key].originalStr!=renderStr;
|
|
||||||
const bool ShadowRerenderRequired=garbageCollector.count(key+"_SHADOW")&&garbageCollector[key+"_SHADOW"].originalStr!=renderStr;
|
|
||||||
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
|
||||||
vf2d imageSize=GetWrappedTextSize(originalKey,width,scale);
|
|
||||||
if(imageSize.x<1||imageSize.y<1)return;
|
|
||||||
Decal*newDecal=nullptr;
|
|
||||||
if(!RerenderRequired){
|
|
||||||
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
|
|
||||||
garbageCollector[key].decal=newDecal;
|
|
||||||
}else{
|
|
||||||
newDecal=garbageCollector[key].decal;
|
|
||||||
}
|
|
||||||
garbageCollector[key].originalStr=originalKey;
|
|
||||||
SetDrawTarget(newDecal->sprite);
|
|
||||||
Clear(BLANK);
|
|
||||||
DrawString({0,0},renderStr,WHITE,1U,width/scale.x);
|
|
||||||
newDecal->Update();
|
|
||||||
vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale;
|
|
||||||
Decal*newShadowDecal=nullptr;
|
|
||||||
if(!ShadowRerenderRequired){
|
|
||||||
newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.y/scale.y*4)+adjustedShadowSizeFactor.y*2));
|
|
||||||
garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
|
|
||||||
}else{
|
|
||||||
newShadowDecal=garbageCollector[key+"_SHADOW"].decal;
|
|
||||||
}
|
|
||||||
SetDrawTarget(newShadowDecal->sprite);
|
|
||||||
Clear(BLANK);
|
|
||||||
for(float y=-adjustedShadowSizeFactor.y;y<=adjustedShadowSizeFactor.y+0.1;y+=adjustedShadowSizeFactor.y/2){
|
|
||||||
for(float x=-adjustedShadowSizeFactor.x;x<=adjustedShadowSizeFactor.x+0.1;x+=adjustedShadowSizeFactor.x/2){
|
|
||||||
if(x!=0||y!=0){
|
|
||||||
DrawString(vf2d{x,y}+adjustedShadowSizeFactor,renderStr,WHITE,4U,width/scale.x*4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetDrawTarget(nullptr);
|
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||||
newShadowDecal->Update();
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
drawingMarker.x = 0; drawingMarker.y += 8.0f * scale.y;
|
||||||
|
}
|
||||||
|
else if (c == ' ')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
else if (c == '\t')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c>=-128&&c<-105)
|
||||||
|
{
|
||||||
|
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||||
|
}
|
||||||
|
else if (c==PixelGameEngine::Reset[0])
|
||||||
|
{
|
||||||
|
textCol=col;
|
||||||
|
}
|
||||||
|
else if (c=='#')
|
||||||
|
{
|
||||||
|
skip=6;
|
||||||
|
textCol=BLACK;
|
||||||
|
for(int i=1;i<7;i++){
|
||||||
|
if(i<3){
|
||||||
|
textCol.r*=16;
|
||||||
|
textCol.r+=hexToNumber(sText[index+i]);
|
||||||
|
}else
|
||||||
|
if(i<5){
|
||||||
|
textCol.g*=16;
|
||||||
|
textCol.g+=hexToNumber(sText[index+i]);
|
||||||
|
}else{
|
||||||
|
textCol.b*=16;
|
||||||
|
textCol.b+=hexToNumber(sText[index+i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(textCol==WHITE)textCol=col;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = (c - 32) % 16;
|
||||||
|
int32_t oy = (c - 32) / 16;
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
if(planningMarker.x>width){
|
||||||
|
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale,letter.col);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
}else{
|
||||||
|
drawingMarker.x-=float(vFontSpacing[' '-32].y)*scale.x; //Don't include the space in the sizing when wrapping.
|
||||||
|
}
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
drawingMarker=planningMarker;
|
||||||
|
wrappingOccurred=true;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
letters.emplace_back(c,vf2d{ float(ox) * 8.0f, float(oy) * 8.0f }, vf2d{ 8.0f, 8.0f },textCol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
garbageCollector[key+"_SHADOW"].expireTime=GetRunTime()+120.0f;
|
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale,letter.col);
|
||||||
DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol);
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
DrawDecal(pos,garbageCollector[key].decal,scale,GetFinalRenderColor(col,sText));
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixelGameEngine::DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale, const float width)
|
||||||
|
{
|
||||||
|
Pixel textCol=col;
|
||||||
|
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||||
|
letters.clear();
|
||||||
|
bool wrappingOccurred=false;
|
||||||
|
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||||
|
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||||
|
const auto hexToNumber=[](char c){
|
||||||
|
if(c<='9')return c-'0';
|
||||||
|
return (c-'A')+10;
|
||||||
|
};
|
||||||
|
for (int skip=0,index=-1;auto c : sText)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
if(skip){
|
||||||
|
skip--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c==' '||c=='\t'||c=='\n'){
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||||
|
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}
|
||||||
|
if(wrappingOccurred){
|
||||||
|
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}else{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||||
|
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
drawingMarker.x = 0; drawingMarker.y += 8.0f * scale.y;
|
||||||
|
}
|
||||||
|
else if (c == ' ')
|
||||||
|
{
|
||||||
|
drawingMarker.x += float(vFontSpacing[' ' - 32].y) * scale.x;
|
||||||
|
planningMarker.x += float(vFontSpacing[' ' - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c == '\t')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c>=-128&&c<-105)
|
||||||
|
{
|
||||||
|
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||||
|
}
|
||||||
|
else if (c==PixelGameEngine::Reset[0])
|
||||||
|
{
|
||||||
|
textCol=col;
|
||||||
|
}
|
||||||
|
else if (c=='#')
|
||||||
|
{
|
||||||
|
skip=6;
|
||||||
|
textCol=BLACK;
|
||||||
|
for(int i=1;i<7;i++){
|
||||||
|
if(i<3){
|
||||||
|
textCol.r*=16;
|
||||||
|
textCol.r+=hexToNumber(sText[index+i]);
|
||||||
|
}else
|
||||||
|
if(i<5){
|
||||||
|
textCol.g*=16;
|
||||||
|
textCol.g+=hexToNumber(sText[index+i]);
|
||||||
|
}else{
|
||||||
|
textCol.b*=16;
|
||||||
|
textCol.b+=hexToNumber(sText[index+i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(textCol==WHITE)textCol=col;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = (c - 32) % 16;
|
||||||
|
int32_t oy = (c - 32) / 16;
|
||||||
|
planningMarker.x += float(vFontSpacing[c - 32].y) * scale.x;
|
||||||
|
if(planningMarker.x>width){
|
||||||
|
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale,letter.col);
|
||||||
|
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
}else{
|
||||||
|
drawingMarker.x-=float(vFontSpacing[' '-32].y)*scale.x; //Don't include the space in the sizing when wrapping.
|
||||||
|
}
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
drawingMarker=planningMarker;
|
||||||
|
wrappingOccurred=true;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
planningMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
letters.emplace_back(c,vf2d{ float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, vf2d{ float(vFontSpacing[c - 32].y), 8.0f },textCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||||
|
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixelGameEngine::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale){
|
||||||
|
DrawShadowStringDecal(pos,sText,col,shadowCol,scale,scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixelGameEngine::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const olc::vf2d& shadowScale,const float width){
|
||||||
|
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||||
|
letters.clear();
|
||||||
|
bool wrappingOccurred=false;
|
||||||
|
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||||
|
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||||
|
const auto hexToNumber=[](char c){
|
||||||
|
if(c<='9')return c-'0';
|
||||||
|
return (c-'A')+10;
|
||||||
|
};
|
||||||
|
for (int skip=0,index=-1;auto c : sText)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
if(skip){
|
||||||
|
skip--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c==' '||c=='\t'||c=='\n'){
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}
|
||||||
|
if(wrappingOccurred){
|
||||||
|
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||||
|
wrappingOccurred=false;
|
||||||
|
}else{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
drawingMarker.x = 0; drawingMarker.y += 8.0f * scale.y;
|
||||||
|
}
|
||||||
|
else if (c == ' ')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
else if (c == '\t')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c>=-128&&c<-105){}
|
||||||
|
else if (c==PixelGameEngine::Reset[0]){}
|
||||||
|
else if (c=='#')
|
||||||
|
{
|
||||||
|
skip=6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = (c - 32) % 16;
|
||||||
|
int32_t oy = (c - 32) / 16;
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
if(planningMarker.x>width){
|
||||||
|
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
}else{
|
||||||
|
drawingMarker.x-=float(vFontSpacing[' '-32].y)*scale.x; //Don't include the space in the sizing when wrapping.
|
||||||
|
}
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
drawingMarker=planningMarker;
|
||||||
|
wrappingOccurred=true;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
planningMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
letters.emplace_back(c,vf2d{ float(ox) * 10.0f, float(oy) * 10.0f }, vf2d{ 10.0f, 10.0f },shadowCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += 8.0f * scale.x;
|
||||||
|
}
|
||||||
|
DrawStringDecal(pos,sText,col,scale,width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelGameEngine::DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const olc::vf2d& scale){
|
void PixelGameEngine::DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const olc::vf2d& scale){
|
||||||
@ -3609,7 +3820,7 @@ namespace olc
|
|||||||
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||||
delete garbageCollector[key].decal;
|
delete garbageCollector[key].decal;
|
||||||
garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
||||||
garbageCollector[key].originalStr=std::string(originalKey.begin(),originalKey.end());
|
garbageCollector[key].originalStr=std::string(renderStr.begin(),renderStr.end());
|
||||||
}
|
}
|
||||||
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
||||||
DrawDecal(pos,garbageCollector[key].decal,scale/4,GetFinalRenderColor(col,sText));
|
DrawDecal(pos,garbageCollector[key].decal,scale/4,GetFinalRenderColor(col,sText));
|
||||||
@ -3625,7 +3836,7 @@ namespace olc
|
|||||||
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||||
delete garbageCollector[key].decal;
|
delete garbageCollector[key].decal;
|
||||||
garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
||||||
garbageCollector[key].originalStr=std::string(originalKey.begin(),originalKey.end());
|
garbageCollector[key].originalStr=std::string(renderStr.begin(),renderStr.end());
|
||||||
}
|
}
|
||||||
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
||||||
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
||||||
@ -3648,7 +3859,7 @@ namespace olc
|
|||||||
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||||
delete garbageCollector[key].decal;
|
delete garbageCollector[key].decal;
|
||||||
garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
garbageCollector[key].decal=font.RenderStringToDecal(renderStr,WHITE);
|
||||||
garbageCollector[key].originalStr=std::string(originalKey.begin(),originalKey.end());
|
garbageCollector[key].originalStr=std::string(renderStr.begin(),renderStr.end());
|
||||||
}
|
}
|
||||||
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
||||||
DrawDecal(pos+vf2d{0,0.5f},garbageCollector[key].decal,scale/4,shadowCol);
|
DrawDecal(pos+vf2d{0,0.5f},garbageCollector[key].decal,scale/4,shadowCol);
|
||||||
@ -3657,56 +3868,99 @@ namespace olc
|
|||||||
DrawDecal(pos,garbageCollector[key].decal,scale/4,GetFinalRenderColor(col,sText));
|
DrawDecal(pos,garbageCollector[key].decal,scale/4,GetFinalRenderColor(col,sText));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelGameEngine::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor,const bool disableDynamicScaling){
|
void PixelGameEngine::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale){
|
||||||
if(sText.length()==0)return;
|
DrawShadowStringPropDecal(pos,sText,col,shadowCol,scale,scale);
|
||||||
std::string originalKey{stripCol(sText)};
|
}
|
||||||
std::string renderStr{stripLeadingCol(sText)};
|
|
||||||
std::string key{"DSSPD_"+originalKey};
|
void PixelGameEngine::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const olc::vf2d& shadowScale,const float width){
|
||||||
key+=std::to_string(width);
|
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||||
if(!disableDynamicScaling){
|
letters.clear();
|
||||||
key+=scale.str();
|
bool wrappingOccurred=false;
|
||||||
}
|
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||||
const bool RerenderRequired=garbageCollector.count(key)&&garbageCollector[key].originalStr!=renderStr;
|
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||||
const bool ShadowRerenderRequired=garbageCollector.count(key+"_SHADOW")&&garbageCollector[key+"_SHADOW"].originalStr!=renderStr;
|
const auto hexToNumber=[](char c){
|
||||||
if(!garbageCollector.count(key)||RerenderRequired){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
if(c<='9')return c-'0';
|
||||||
vf2d imageSize=GetWrappedTextSizeProp(originalKey,width,scale);
|
return (c-'A')+10;
|
||||||
if(imageSize.x<1||imageSize.y<1)return;
|
};
|
||||||
Decal*newDecal=nullptr;
|
for (int skip=0,index=-1;auto c : sText)
|
||||||
if(!RerenderRequired){
|
{
|
||||||
newDecal=new Decal(new Sprite(imageSize.x/scale.x,imageSize.y/scale.y));
|
index++;
|
||||||
garbageCollector[key].decal=newDecal;
|
if(skip){
|
||||||
}else{
|
skip--;
|
||||||
newDecal=garbageCollector[key].decal;
|
continue;
|
||||||
}
|
}
|
||||||
garbageCollector[key].originalStr=originalKey;
|
if(c==' '||c=='\t'||c=='\n'){
|
||||||
SetDrawTarget(newDecal->sprite);
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
Clear(BLANK);
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
DrawStringProp({0,0},renderStr,WHITE,1U,width/scale.x);
|
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
newDecal->Update();
|
}
|
||||||
vf2d adjustedShadowSizeFactor=vf2d{shadowSizeFactor,shadowSizeFactor}*4/scale;
|
letters.clear();
|
||||||
Decal*newShadowDecal=nullptr;
|
wrappingOccurred=false;
|
||||||
if(!ShadowRerenderRequired){
|
|
||||||
newShadowDecal=new Decal(new Sprite((imageSize.x/scale.x*4)+adjustedShadowSizeFactor.x*2,(imageSize.y/scale.y*4)+adjustedShadowSizeFactor.y*2));
|
|
||||||
garbageCollector[key+"_SHADOW"].decal=newShadowDecal;
|
|
||||||
}else{
|
|
||||||
newShadowDecal=garbageCollector[key+"_SHADOW"].decal;
|
|
||||||
}
|
}
|
||||||
SetDrawTarget(newShadowDecal->sprite);
|
if(wrappingOccurred){
|
||||||
Clear(BLANK);
|
if(c!=' '&&c!='\t'&&c!='\n'){
|
||||||
for(float y=-adjustedShadowSizeFactor.y;y<=adjustedShadowSizeFactor.y+0.1;y+=adjustedShadowSizeFactor.y/2){
|
wrappingOccurred=false;
|
||||||
for(float x=-adjustedShadowSizeFactor.x;x<=adjustedShadowSizeFactor.x+0.1;x+=adjustedShadowSizeFactor.x/2){
|
}else{
|
||||||
if(x!=0||y!=0){
|
continue;
|
||||||
DrawStringProp(vf2d{x,y}+adjustedShadowSizeFactor,renderStr,WHITE,4U,width/scale.x*4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetDrawTarget(nullptr);
|
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||||
newShadowDecal->Update();
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
drawingMarker.x = 0; drawingMarker.y += 8.0f * scale.y;
|
||||||
|
}
|
||||||
|
else if (c == ' ')
|
||||||
|
{
|
||||||
|
drawingMarker.x += float(vFontSpacing[' ' - 32].y) * scale.x;
|
||||||
|
planningMarker.x += float(vFontSpacing[' ' - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c == '\t')
|
||||||
|
{
|
||||||
|
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||||
|
}
|
||||||
|
else if (c>=-128&&c<-105){}
|
||||||
|
else if (c==PixelGameEngine::Reset[0]){}
|
||||||
|
else if (c=='#')
|
||||||
|
{
|
||||||
|
skip=6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t ox = (c - 32) % 16;
|
||||||
|
int32_t oy = (c - 32) / 16;
|
||||||
|
planningMarker.x += float(vFontSpacing[c - 32].y) * scale.x;
|
||||||
|
if(planningMarker.x>width){
|
||||||
|
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
|
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
letters.clear();
|
||||||
|
}else{
|
||||||
|
drawingMarker.x-=float(vFontSpacing[' '-32].y)*scale.x; //Don't include the space in the sizing when wrapping.
|
||||||
|
}
|
||||||
|
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||||
|
drawingMarker=planningMarker;
|
||||||
|
wrappingOccurred=true;
|
||||||
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
|
planningMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
letters.emplace_back(c,vf2d{ float(ox) * 10.0f + float(vFontSpacing[c - 32].x), float(oy) * 10.0f }, vf2d{ float(vFontSpacing[c - 32].y)+2, 10.0f },shadowCol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
garbageCollector[key].expireTime=GetRunTime()+120.0f;
|
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||||
garbageCollector[key+"_SHADOW"].expireTime=GetRunTime()+120.0f;
|
DrawPartialRotatedDecal(pos + drawingMarker+vf2d{5.f,5.f}*scale-shadowScale, fontRenderableShadow.Decal(),0.f,{5.f,5.f}, letter.sourcePos, letter.sourceSize,shadowScale,shadowCol);
|
||||||
DrawDecal(pos-vf2d{shadowSizeFactor,shadowSizeFactor},garbageCollector[key+"_SHADOW"].decal,scale/4,shadowCol);
|
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||||
DrawDecal(pos,garbageCollector[key].decal,scale,GetFinalRenderColor(col,sText));
|
}
|
||||||
|
DrawStringPropDecal(pos,sText,col,scale,width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelGameEngine::DrawShadowString(const olc::vi2d& pos, std::string_view sText, Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor){
|
void PixelGameEngine::DrawShadowString(const olc::vi2d& pos, std::string_view sText, Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor){
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user