diff --git a/Crawler/CharacterAbilityPreviewComponent.h b/Crawler/CharacterAbilityPreviewComponent.h index 1e5ae998..d10c5ad5 100644 --- a/Crawler/CharacterAbilityPreviewComponent.h +++ b/Crawler/CharacterAbilityPreviewComponent.h @@ -68,7 +68,7 @@ protected: vi2d descriptionPos=iconPos+vi2d{int(rect.size.y)-2,-1}; - window.DrawShadowStringPropDecal(descriptionPos,util::WrapText(game,ability->description,int(rect.size.x-(descriptionPos.x-rect.pos.x)),true,{0.8f,1.0f}),WHITE,BLACK,{0.8f,1.f}); + window.DrawShadowStringPropDecal(descriptionPos,ability->description,WHITE,BLACK,{0.8f,1.f},int(rect.size.x-(descriptionPos.x-rect.pos.x))-4); if(textWidth>boxWidth){ window.DrawShadowStringPropDecal(textPos,ability->input->GetDisplayName(),WHITE,BLACK,{boxWidth/textWidth*0.5f,0.5}); diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index b0577012..25fa564b 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -1321,7 +1321,7 @@ void Crawler::RenderCooldowns(){ } vf2d keyDisplaySize=vf2d{GetTextSize(a.input->GetDisplayName())}*vf2d{0.5f,0.5f}; - DrawShadowStringDecal(pos+vf2d{12,-2}-keyDisplaySize/2,a.input->GetDisplayName(),keyDisplayCol,BLACK,{0.5f,0.5f},1); + DrawShadowStringDecal(pos+vf2d{12,-2}-keyDisplaySize/2,a.input->GetDisplayName(),keyDisplayCol,BLACK,{0.5f,0.5f},std::numeric_limits::max(),1); vf2d shortNameSize=vf2d{GetTextSize(a.shortName)}*vf2d{0.5f,0.75f}; DrawShadowStringDecal(pos+vf2d{13,24}-shortNameSize/2,a.shortName,shortNameCol,{255,255,255,64},{0.5f,0.75f}); @@ -2195,7 +2195,7 @@ void Crawler::ValidateGameStatus(){ void Crawler::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)); - DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4f,versionStr,WHITE,BLACK,{0.4f,0.4f},0.4f); + DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4f,versionStr,WHITE,BLACK,{0.4f,0.4f},std::numeric_limits::max(),0.4f); } int Crawler::GetCurrentChapter(){ diff --git a/Crawler/State_GameRun.cpp b/Crawler/State_GameRun.cpp index 0662cfea..cbcd82cf 100644 --- a/Crawler/State_GameRun.cpp +++ b/Crawler/State_GameRun.cpp @@ -51,6 +51,21 @@ void State_GameRun::OnStateChange(GameState*prevState){ } game->GetPlayer()->SetState(State::NORMAL); port=ViewPort::rectViewPort({0,0},{240,240},{24,24}); + + if(r.Decal()==nullptr){ + r.Create(240,240); + game->SetDrawTarget(r.Sprite()); + game->Clear(BLANK); + game->DrawString({8,24*0},"#FF0000This is a #BFA6F9test of hex",WHITE,1,72); + game->DrawString({8,24*1},"#00FF00This is a #E9A6F9test of hex",WHITE,1,72); + game->DrawString({8,24*2},"#0000FFThis is a #F9E8A6test of hex",WHITE,1,72); + game->DrawShadowString({8,24*3},"#FFFFFFThis is a #000066test of hex",WHITE,BLACK,{1,1},72); + game->DrawShadowString({8,24*4},"#FF0000This is a #BFA6F9test of hex",WHITE,BLACK,{1,1},72); + game->DrawShadowStringProp({8,24*5},"#00FF00This is a #E9A6F9test of hex",WHITE,BLACK,{1,1},72); + game->DrawShadowStringProp({8,24*6},"#0000FFThis is a #F9E8A6test of hex",WHITE,BLACK,{1,1},72); + game->SetDrawTarget(nullptr); + r.Decal()->Update(); + } } void State_GameRun::OnUserUpdate(Crawler*game){ game->bossDisplayTimer=std::max(0.f,game->bossDisplayTimer-game->GetElapsedTime()); @@ -76,7 +91,8 @@ void State_GameRun::OnUserUpdate(Crawler*game){ } void State_GameRun::Draw(Crawler*game){ game->RenderHud(); - FontTest(); //Enable to test font coloring. + //FontTest(); //Enable to test font coloring. + FontSpriteTest(); //Enable to test font coloring. } void State_GameRun::FontTest(){ @@ -87,9 +103,13 @@ void State_GameRun::FontTest(){ port.DrawShadowStringDecal({8,24*4},"#FF0000This is a #BFA6F9test of hex",WHITE,BLACK,{1,1},72); port.DrawShadowStringPropDecal({8,24*5},"#00FF00This is a #E9A6F9test of hex",WHITE,BLACK,{1,1},72); port.DrawShadowStringPropDecal({8,24*6},"#0000FFThis is a #F9E8A6test of hex",WHITE,BLACK,{1,1},72); - /*port.DrawShadowStringDecal(VisualNovel::font,{8,24*7},U"#FFFFFFThis is a #000066test of hex",WHITE,BLACK,{1,1},72); - port.DrawShadowStringDecal(VisualNovel::font,{8,24*8},U"#FF0000This is a #BFA6F9test of hex",WHITE,BLACK,{1,1},72); - port.DrawShadowStringDecal(VisualNovel::font,{8,24*9},U"#00FF00This is a #E9A6F9test of hex",WHITE,BLACK,{1,1},72); - port.DrawShadowStringDecal(VisualNovel::font,{8,24*10},U"#0000FFThis is a #F9E8A6test of hex",WHITE,BLACK,{1,1},72);*/ + port.DrawShadowStringDecal(VisualNovel::font,{8,24*7},U"#FFFFFFThis is a #000066test of hex",WHITE,BLACK,{1,1}); + port.DrawShadowStringDecal(VisualNovel::font,{8,24*8},U"#FF0000This is a #BFA6F9test of hex",WHITE,BLACK,{1,1}); + port.DrawShadowStringDecal(VisualNovel::font,{8,24*9},U"#00FF00This is a #E9A6F9test of hex",WHITE,BLACK,{1,1}); + port.DrawShadowStringDecal(VisualNovel::font,{8,24*10},U"#0000FFThis is a #F9E8A6test of hex",WHITE,BLACK,{1,1}); port.drawEdges(); +} + +void State_GameRun::FontSpriteTest(){ + game->DrawDecal({24,24},r.Decal()); } \ No newline at end of file diff --git a/Crawler/State_GameRun.h b/Crawler/State_GameRun.h index 90c9bf13..0d78ed6e 100644 --- a/Crawler/State_GameRun.h +++ b/Crawler/State_GameRun.h @@ -41,8 +41,10 @@ All rights reserved. class State_GameRun:public GameState{ ViewPort port; + Renderable r; virtual void OnStateChange(GameState*prevState)override final; virtual void OnUserUpdate(Crawler*game)override final; virtual void Draw(Crawler*game)override final; void FontTest(); + void FontSpriteTest(); }; \ No newline at end of file diff --git a/Crawler/Version.h b/Crawler/Version.h index 70a8ef33..26651b89 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 4372 +#define VERSION_BUILD 4398 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/olcPixelGameEngine.h b/Crawler/olcPixelGameEngine.h index 340f42de..e9e34bff 100644 --- a/Crawler/olcPixelGameEngine.h +++ b/Crawler/olcPixelGameEngine.h @@ -1113,19 +1113,19 @@ namespace olc void DrawSprite(const olc::vi2d& pos, Sprite* sprite, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE, std::functioncolorFunc=[](Pixel&in){return in;}); // Draws an area of a sprite at location (x,y), where the // selected area is (ox,oy) to (ox+w,oy+h) - void DrawPartialSprite(int32_t x, int32_t y, Sprite* sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE); - void DrawPartialSprite(const olc::vi2d& pos, Sprite* sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE); + void DrawPartialSprite(int32_t x, int32_t y, Sprite* sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE,Pixel colorOverride=WHITE); + void DrawPartialSprite(const olc::vi2d& pos, Sprite* sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE,Pixel colorOverride=WHITE); // Draws a single line of text - traditional monospaced - void DrawStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); - void DrawShadowString(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1); - void DrawStringProp(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); - void DrawShadowStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1); + void DrawStringProp(const olc::vi2d& pos, std::string_view sText, Pixel col = olc::WHITE, uint32_t scale = 1,const float width=std::numeric_limits::max(),const bool colorOverride=false); + void DrawShadowString(const olc::vi2d& pos, std::string_view sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits::max(),const float shadowSizeFactor=1); + void DrawStringProp(int32_t x, int32_t y, std::string_view sText, Pixel col = olc::WHITE, uint32_t scale = 1,const float width=std::numeric_limits::max(),const bool colorOverride=false); + void DrawShadowStringProp(const olc::vi2d& pos, std::string_view sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits::max(),const float shadowSizeFactor=1); olc::vi2d GetTextSize(std::string_view s); olc::vi2d GetTextSizeProp(std::string_view s); olc::vi2d GetWrappedTextSize(std::string_view s,const float width=std::numeric_limits::max(),const float scale=1); olc::vi2d GetWrappedTextSizeProp(std::string_view s,const float width=std::numeric_limits::max(),const float scale=1); - void DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); - void DrawString(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); + void DrawString(const olc::vi2d& pos, std::string_view sText, Pixel col = olc::WHITE, uint32_t scale = 1,const float width=std::numeric_limits::max(),const bool colorOverride=false); + void DrawString(int32_t x, int32_t y, std::string_view sText, Pixel col = olc::WHITE, uint32_t scale = 1,const float width=std::numeric_limits::max(),const bool colorOverride=false); // Decal Quad functions void SetDecalMode(const olc::DecalMode& mode); @@ -1152,8 +1152,8 @@ namespace olc 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::max(),const bool colorOverride=false); 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::max(),const bool colorOverride=false); - void DrawShadowStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1); - void DrawShadowStringPropDecal(const olc::vf2d& pos, const std::string& 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(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::max(),const float shadowSizeFactor=1); + 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::max(),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 }); // Draws a single shaded filled rectangle as a decal @@ -2886,10 +2886,10 @@ namespace olc } } - void PixelGameEngine::DrawPartialSprite(const olc::vi2d& pos, Sprite* sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, uint32_t scale, uint8_t flip) - { DrawPartialSprite(pos.x, pos.y, sprite, sourcepos.x, sourcepos.y, size.x, size.y, scale, flip); } + void PixelGameEngine::DrawPartialSprite(const olc::vi2d& pos, Sprite* sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, uint32_t scale, uint8_t flip,Pixel colorOverride) + { DrawPartialSprite(pos.x, pos.y, sprite, sourcepos.x, sourcepos.y, size.x, size.y, scale, flip,colorOverride); } - void PixelGameEngine::DrawPartialSprite(int32_t x, int32_t y, Sprite* sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, uint32_t scale, uint8_t flip) + void PixelGameEngine::DrawPartialSprite(int32_t x, int32_t y, Sprite* sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, uint32_t scale, uint8_t flip,Pixel colorOverride) { if (sprite == nullptr) return; @@ -2908,7 +2908,7 @@ namespace olc for (int32_t j = 0; j < h; j++, fy += fym) for (uint32_t is = 0; is < scale; is++) for (uint32_t js = 0; js < scale; js++) - Draw(x + (i * scale) + is, y + (j * scale) + js, sprite->GetPixel(fx + ox, fy + oy)); + Draw(x + (i * scale) + is, y + (j * scale) + js, (colorOverride!=WHITE&&sprite->GetPixel(fx + ox, fy + oy).a!=0)?colorOverride:sprite->GetPixel(fx + ox, fy + oy)); } } else @@ -2918,7 +2918,7 @@ namespace olc { fy = fys; for (int32_t j = 0; j < h; j++, fy += fym) - Draw(x + i, y + j, sprite->GetPixel(fx + ox, fy + oy)); + Draw(x + i, y + j, (colorOverride!=WHITE&&sprite->GetPixel(fx + ox, fy + oy).a!=0)?colorOverride:sprite->GetPixel(fx + ox, fy + oy)); } } } @@ -3562,19 +3562,15 @@ namespace olc } } - void PixelGameEngine::DrawShadowStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){ - std::string strippedText=sText; - std::erase_if(strippedText,[](char chr){return chr<0;}); - int skip=0; - std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;}); + 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){ for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){ for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){ if(x!=0||y!=0){ - DrawStringDecal(pos+vf2d{x,y}, strippedText, shadowCol,scale); + DrawStringDecal(pos+vf2d{x,y}, sText, shadowCol,scale,width,true); } } } - DrawStringDecal(pos, sText, col,scale); + 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){ @@ -3653,49 +3649,37 @@ namespace olc DrawDecal(pos,garbageCollector[key].decal,scale/4,col); } - void PixelGameEngine::DrawShadowStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){ - std::string strippedText=sText; - std::erase_if(strippedText,[](char chr){return chr<0;}); - int skip=0; - std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;}); + 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){ for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){ for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){ if(x!=0||y!=0){ - DrawStringPropDecal(pos+vf2d{x,y}, strippedText, shadowCol,scale); + DrawStringPropDecal(pos+vf2d{x,y}, sText, shadowCol,scale,width,true); } } } - DrawStringPropDecal(pos, sText, col,scale); + DrawStringPropDecal(pos, sText, col,scale,width); } - void PixelGameEngine::DrawShadowString(const olc::vi2d& pos, const std::string& sText, Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){ - std::string strippedText=sText; - std::erase_if(strippedText,[](char chr){return chr<0;}); - int skip=0; - std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;}); + 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){ for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){ for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){ if(x!=0||y!=0){ - DrawString(int32_t(pos.x+x),int32_t(pos.y+y), strippedText, shadowCol,int(scale.x)); + DrawString(int32_t(pos.x+x),int32_t(pos.y+y), sText, shadowCol,int(scale.x),width,true); } } } - DrawString(pos.x,pos.y, sText, col,int(scale.x)); + DrawString(pos.x,pos.y, sText, col,int(scale.x),width); } - void PixelGameEngine::DrawShadowStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){ - std::string strippedText=sText; - std::erase_if(strippedText,[](char chr){return chr<0;}); - int skip=0; - std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;}); + void PixelGameEngine::DrawShadowStringProp(const olc::vi2d& pos, std::string_view sText, Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor){ for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){ for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){ if(x!=0||y!=0){ - DrawStringProp(int32_t(pos.x+x),int32_t(pos.y+y), strippedText, shadowCol,int(scale.x)); + DrawStringProp(int32_t(pos.x+x),int32_t(pos.y+y), sText, shadowCol,int(scale.x),width,true); } } } - DrawStringProp(pos.x,pos.y, sText, col,int(scale.x)); + DrawStringProp(pos.x,pos.y, sText, col,int(scale.x),width); } // Thanks Oso-Grande/Sopadeoso For these awesom and stupidly clever Text Rotation routines... duh XD @@ -3864,13 +3848,11 @@ namespace olc return size * 8; } - void PixelGameEngine::DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col, uint32_t scale) - { DrawString(pos.x, pos.y, sText, col, scale); } + void PixelGameEngine::DrawString(const olc::vi2d& pos, std::string_view sText, Pixel col, uint32_t scale,const float width,const bool colorOverride) + { DrawString(pos.x, pos.y, sText, col, scale,width,colorOverride); } - void PixelGameEngine::DrawString(int32_t x, int32_t y, const std::string& sText, Pixel col, uint32_t scale) + void PixelGameEngine::DrawString(int32_t x, int32_t y, std::string_view sText, Pixel col, uint32_t scale,const float width,const bool colorOverride) { - int32_t sx = 0; - int32_t sy = 0; Pixel::Mode m = nPixelMode; Pixel textCol=col; // Thanks @tucna, spotted bug with col.ALPHA :P @@ -3879,6 +3861,12 @@ namespace olc if (col.a != 255) SetPixelMode(Pixel::ALPHA); else SetPixelMode(Pixel::MASK); } + vf2d pos={float(x),float(y)}; + static std::vectorletters; + 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; @@ -3890,18 +3878,43 @@ namespace olc skip--; continue; } + if(c==' '||c=='\t'){ + for(PixelGameEngine::StringDecalData&letter:letters){ + DrawPartialSprite(vi2d(pos + drawingMarker), fontRenderable.Sprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale, Sprite::Flip::NONE,letter.col); + drawingMarker.x += 8.0f * scale; + } + letters.clear(); + wrappingOccurred=false; + } + if(wrappingOccurred){ + if(c!=' '&&c!='\t'){ + wrappingOccurred=false; + }else{ + continue; + } + } if(c=='\r')continue; //Ignore carriage returns. Stupid Linux. if (c == '\n') { - sx = 0; sy += 8 * scale; + planningMarker.x = 0; planningMarker.y += 8.0f * scale; + } + else if (c == ' ') + { + drawingMarker.x += 8.0f * scale; + planningMarker.x += 8.0f * scale; } else if (c == '\t') { - sx += 8 * nTabSizeInSpaces * scale; + drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale; + planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale; } else if (c>=-128&&c<-105) { - textCol={charToColor[c].r,charToColor[c].g,charToColor[c].b,col.a}; + 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=='#') { @@ -3922,34 +3935,33 @@ namespace olc } if(textCol==WHITE)textCol=col; } - else if (c==Reset[0]) - { - textCol=col; - } - else + else { int32_t ox = (c - 32) % 16; int32_t oy = (c - 32) / 16; - - if (scale > 1) - { - for (uint32_t i = 0; i < 8; i++) - for (uint32_t j = 0; j < 8; j++) - if (fontRenderable.Sprite()->GetPixel(i + ox * 8, j + oy * 8).r > 0) - for (uint32_t is = 0; is < scale; is++) - for (uint32_t js = 0; js < scale; js++) - Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, textCol); - } - else - { - for (uint32_t i = 0; i < 8; i++) - for (uint32_t j = 0; j < 8; j++) - if (fontRenderable.Sprite()->GetPixel(i + ox * 8, j + oy * 8).r > 0) - Draw(x + sx + i, y + sy + j, textCol); + planningMarker.x += 8.0f * scale; + 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){ + DrawPartialSprite(vi2d(pos + drawingMarker), fontRenderable.Sprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale, Sprite::Flip::NONE,letter.col); + drawingMarker.x += 8.0f * scale; + } + letters.clear(); + } + planningMarker.x = 0; planningMarker.y += 8.0f * scale; + drawingMarker=planningMarker; + wrappingOccurred=true; + for(PixelGameEngine::StringDecalData&letter:letters){ + planningMarker.x += 8.0f * scale; + } } - sx += 8 * scale; + letters.emplace_back(c,vf2d{ float(ox) * 8.0f, float(oy) * 8.0f }, vf2d{ 8.0f, 8.0f },colorOverride?col:textCol); } } + for(PixelGameEngine::StringDecalData&letter:letters){ + DrawPartialSprite(vi2d(pos + drawingMarker), fontRenderable.Sprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale, Sprite::Flip::NONE,letter.col); + drawingMarker.x += 8.0f * scale; + } SetPixelMode(m); } @@ -4054,24 +4066,29 @@ namespace olc return vi2d(vf2d{maxWidth,planningMarker.y+8}*scale); } - void PixelGameEngine::DrawStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col, uint32_t scale) - { DrawStringProp(pos.x, pos.y, sText, col, scale); } + void PixelGameEngine::DrawStringProp(const olc::vi2d& pos, std::string_view sText, Pixel col, uint32_t scale,const float width,const bool colorOverride) + { DrawStringProp(pos.x, pos.y, sText, col, scale,width,colorOverride); } - void PixelGameEngine::DrawStringProp(int32_t x, int32_t y, const std::string& sText, Pixel col, uint32_t scale) + void PixelGameEngine::DrawStringProp(int32_t x, int32_t y, std::string_view sText, Pixel col, uint32_t scale,const float width,const bool colorOverride) { - int32_t sx = 0; - int32_t sy = 0; Pixel::Mode m = nPixelMode; Pixel textCol=col; - const auto hexToNumber=[](char c){ - if(c<='9')return c-'0'; - return (c-'A')+10; - }; - if (m != Pixel::CUSTOM) + // Thanks @tucna, spotted bug with col.ALPHA :P + if (m != Pixel::CUSTOM) // Thanks @Megarev, required for "shaders" { if (col.a != 255) SetPixelMode(Pixel::ALPHA); else SetPixelMode(Pixel::MASK); } + static std::vectorletters; + letters.clear(); + bool wrappingOccurred=false; + olc::vf2d planningMarker = { 0.0f, 0.0f }; + olc::vf2d drawingMarker = { 0.0f, 0.0f }; + vf2d pos={float(x),float(y)}; + 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++; @@ -4079,20 +4096,41 @@ namespace olc skip--; continue; } + if(c==' '||c=='\t'){ + for(PixelGameEngine::StringDecalData&letter:letters){ + DrawPartialSprite(vi2d(pos + drawingMarker), GetFontSprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale,Sprite::Flip::NONE, letter.col); + drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale; + } + letters.clear(); + wrappingOccurred=false; + } + if(wrappingOccurred){ + if(c!=' '&&c!='\t'){ + wrappingOccurred=false; + }else{ + continue; + } + } if(c=='\r')continue; //Ignore carriage returns. Stupid Linux. if (c == '\n') { - sx = 0; sy += 8 * scale; + planningMarker.x = 0; planningMarker.y += 8.0f * scale; + } + else if (c == ' ') + { + drawingMarker.x += float(vFontSpacing[' ' - 32].y) * scale; + planningMarker.x += float(vFontSpacing[' ' - 32].y) * scale; } else if (c == '\t') { - sx += 8 * nTabSizeInSpaces * scale; + drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale; + planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale; } else if (c>=-128&&c<-105) { - textCol={charToColor[c].r,charToColor[c].g,charToColor[c].b,col.a}; + textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a}; } - else if (c==Reset[0]) + else if (c==PixelGameEngine::Reset[0]) { textCol=col; } @@ -4119,26 +4157,29 @@ namespace olc { int32_t ox = (c - 32) % 16; int32_t oy = (c - 32) / 16; - - if (scale > 1) - { - for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++) - for (int32_t j = 0; j < 8; j++) - if (fontRenderable.Sprite()->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0) - for (int32_t is = 0; is < int(scale); is++) - for (int32_t js = 0; js < int(scale); js++) - Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, textCol); - } - else - { - for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++) - for (int32_t j = 0; j < 8; j++) - if (fontRenderable.Sprite()->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0) - Draw(x + sx + i, y + sy + j, textCol); + planningMarker.x += float(vFontSpacing[c - 32].y) * scale; + 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){ + DrawPartialSprite(vi2d(pos + drawingMarker), GetFontSprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale, Sprite::Flip::NONE,letter.col); + drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale; + } + letters.clear(); + } + planningMarker.x = 0; planningMarker.y += 8.0f * scale; + drawingMarker=planningMarker; + wrappingOccurred=true; + for(PixelGameEngine::StringDecalData&letter:letters){ + planningMarker.x += float(vFontSpacing[letter.c - 32].y) * scale; + } } - sx += vFontSpacing[c - 32].y * scale; + 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 },colorOverride?col:textCol); } } + for(PixelGameEngine::StringDecalData&letter:letters){ + DrawPartialSprite(vi2d(pos + drawingMarker), GetFontSprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale, Sprite::Flip::NONE,letter.col); + drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale; + } SetPixelMode(m); }