diff options
Diffstat (limited to 'src/renderer.cpp')
-rw-r--r-- | src/renderer.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/renderer.cpp b/src/renderer.cpp index 2be36ae..c8c1746 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
@@ -1,4 +1,5 @@ | |||
1 | #include "renderer.h" | 1 | #include "renderer.h" |
2 | #include <iostream> | ||
2 | #include "game.h" | 3 | #include "game.h" |
3 | 4 | ||
4 | Renderer::Renderer() | 5 | Renderer::Renderer() |
@@ -113,6 +114,11 @@ Renderer::Renderer() | |||
113 | 114 | ||
114 | loadTextureFromFile("../res/title0.png", titles_[0]); | 115 | loadTextureFromFile("../res/title0.png", titles_[0]); |
115 | SDL_QueryTexture(titles_[0].get(), nullptr, nullptr, &titleWidths_[0], &titleHeights_[0]); | 116 | SDL_QueryTexture(titles_[0].get(), nullptr, nullptr, &titleWidths_[0], &titleHeights_[0]); |
117 | |||
118 | font_ = font_ptr(TTF_OpenFont("../res/softsquare.ttf", 45)); | ||
119 | if (!font_) { | ||
120 | throw ttf_error(); | ||
121 | } | ||
116 | } | 122 | } |
117 | 123 | ||
118 | void Renderer::renderGame( | 124 | void Renderer::renderGame( |
@@ -389,6 +395,55 @@ void Renderer::renderGame( | |||
389 | SDL_RenderCopy(ren_.get(), readInstruction_.get(), nullptr, nullptr); | 395 | SDL_RenderCopy(ren_.get(), readInstruction_.get(), nullptr, nullptr); |
390 | } | 396 | } |
391 | 397 | ||
398 | if (game.sign.signDisplayState != SignInstructionState::Hidden) { | ||
399 | int opacity = 255; | ||
400 | if (game.sign.signDisplayState == SignInstructionState::FadingIn) { | ||
401 | opacity = game.sign.signDisplayFade.getProgress(0, 255); | ||
402 | } else if (game.sign.signDisplayState == SignInstructionState::FadingOut) { | ||
403 | opacity = game.sign.signDisplayFade.getProgress(255, 0); | ||
404 | } | ||
405 | |||
406 | SDL_Rect signRect { | ||
407 | 0, | ||
408 | GAME_HEIGHT / 2 - (45 * 2 + 1 + MESSAGE_MARGIN * 2) / 2, | ||
409 | GAME_WIDTH, | ||
410 | 45 * 2 + 1 + MESSAGE_MARGIN * 2 | ||
411 | }; | ||
412 | |||
413 | SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_BLEND); | ||
414 | SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, opacity); | ||
415 | SDL_RenderFillRect(ren_.get(), &signRect); | ||
416 | |||
417 | if (game.sign.signDisplayState == SignInstructionState::Visible) { | ||
418 | int lineIndex = 0; | ||
419 | for (const SignLine& line : game.sign.linesToShow) { | ||
420 | if (messageLines_[lineIndex].line != line.text) { | ||
421 | renderMessageLine(messageLines_[lineIndex], line.text, game); | ||
422 | } | ||
423 | |||
424 | if (line.charsRevealed > 0) { | ||
425 | { | ||
426 | SDL_Rect srcRect { | ||
427 | 0, 0, messageLines_[lineIndex].charIndexToWidth[line.charsRevealed], | ||
428 | TTF_FontHeight(font_.get()) | ||
429 | }; | ||
430 | SDL_Rect destRect { | ||
431 | MESSAGE_MARGIN, | ||
432 | GAME_HEIGHT / 2 - (45 * 2 + 1 + MESSAGE_MARGIN * 2) / 2 + MESSAGE_MARGIN + (45 + 1) * lineIndex, | ||
433 | srcRect.w, | ||
434 | srcRect.h }; | ||
435 | |||
436 | SDL_SetRenderTarget(ren_.get(), nullptr); | ||
437 | SDL_RenderCopy(ren_.get(), messageLines_[lineIndex].renderedTex.get(), &srcRect, &destRect); | ||
438 | //std::cout << line.charsRevealed << " (" << messageLines_[lineIndex].charIndexToWidth[line.charsRevealed] << "): " << messageLines_[lineIndex].line.substr(0,line.charsRevealed) << std::endl; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | lineIndex++; | ||
443 | } | ||
444 | } | ||
445 | } | ||
446 | |||
392 | SDL_RenderPresent(ren_.get()); | 447 | SDL_RenderPresent(ren_.get()); |
393 | } | 448 | } |
394 | 449 | ||
@@ -443,3 +498,44 @@ void Renderer::loadTextureFromFile(std::string_view path, texture_ptr& texture) | |||
443 | texture = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), pfs.get())); | 498 | texture = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), pfs.get())); |
444 | SDL_SetTextureBlendMode(texture.get(), SDL_BLENDMODE_BLEND); | 499 | SDL_SetTextureBlendMode(texture.get(), SDL_BLENDMODE_BLEND); |
445 | } | 500 | } |
501 | |||
502 | void Renderer::renderMessageLine(MessageCache& line, const std::string& text, const Game& game) { | ||
503 | line.line = text; | ||
504 | |||
505 | line.renderedTex.reset( | ||
506 | SDL_CreateTexture( | ||
507 | ren_.get(), | ||
508 | SDL_PIXELFORMAT_RGBA8888, | ||
509 | SDL_TEXTUREACCESS_TARGET, | ||
510 | MESSAGE_TEXT_WIDTH, | ||
511 | TTF_FontHeight(font_.get()))); | ||
512 | |||
513 | SDL_SetTextureBlendMode(line.renderedTex.get(), SDL_BLENDMODE_BLEND); | ||
514 | |||
515 | SDL_SetRenderTarget(ren_.get(), line.renderedTex.get()); | ||
516 | SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_BLEND); | ||
517 | SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); | ||
518 | SDL_RenderClear(ren_.get()); | ||
519 | |||
520 | line.charIndexToWidth.clear(); | ||
521 | line.charIndexToWidth.push_back(0); | ||
522 | |||
523 | for (int i=0; i<line.line.size(); i++) { | ||
524 | if (line.line[i] != ' ') { | ||
525 | int width = 0; | ||
526 | std::string substr = line.line.substr(0, i+1); | ||
527 | TTF_SizeText(font_.get(), substr.c_str(), &width, nullptr); | ||
528 | line.charIndexToWidth.push_back(width); | ||
529 | } else { | ||
530 | line.charIndexToWidth.push_back(line.charIndexToWidth.back()); | ||
531 | } | ||
532 | } | ||
533 | |||
534 | SDL_Color fgColor {.r = 255, .g = 255, .b = 255, .a = 255}; | ||
535 | SDL_Color bgColor {.r = 0, .g = 0, .b = 0, .a = 255}; | ||
536 | SDL_Rect rect {0, 0, line.charIndexToWidth.back(), TTF_FontHeight(font_.get())}; | ||
537 | surface_ptr lineSurf = surface_ptr(TTF_RenderText_Shaded(font_.get(), line.line.c_str(), fgColor, bgColor)); | ||
538 | texture_ptr lineTex = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), lineSurf.get())); | ||
539 | SDL_RenderCopy(ren_.get(), lineTex.get(), nullptr, &rect); | ||
540 | } | ||
541 | |||