diff --git a/Descent3/credits.cpp b/Descent3/credits.cpp index 3536b0f49..759143728 100644 --- a/Descent3/credits.cpp +++ b/Descent3/credits.cpp @@ -78,6 +78,7 @@ */ #include +#include #include "bitmap.h" #include "crossplat.h" @@ -89,7 +90,6 @@ #include "grtext.h" #include "hlsoundlib.h" #include "log.h" -#include "mem.h" #include "pserror.h" #include "psrand.h" #include "renderer.h" @@ -102,6 +102,11 @@ // music regions for credits #define CREDITS1_MUSIC_REGION 0 +// Speed of scrolling +#define CREDIT_PIXELS_PER_SECOND 22 + +#define MAX_CREDIT_LEN 200 + // other stuff #define CLTYPE_HEADING 0 #define CLTYPE_TEXT 1 @@ -109,23 +114,19 @@ #define CLTYPE_BLANK 3 struct creditline { - ddgr_color color; - uint8_t type; - char *text; - creditline *next; - uint16_t startx, starty, endx, endy; - float displaytime; + ddgr_color color{}; + uint8_t type{}; + std::string text; + uint16_t startx{}; + uint16_t starty{}; + uint16_t endx{}; + uint16_t endy{}; + float displaytime{}; }; -static void Credits_Render(creditline *header, float pixels_in); -static creditline Creditlines; - -static ddgr_color CreditTextColor, CreditHeadingColor; -static int CreditStartX, CreditStartY, CreditEndX, CreditEndY; -static float CreditDisplayTime; static chunked_bitmap Credits_bm; -#define MAX_CREDIT_LEN 200 +void Credits_Render(std::vector::iterator credit, std::vector::iterator end, float pixels_in); static bool Credits_IsKeyPressed() { if (ddio_KeyInKey()) @@ -136,119 +137,17 @@ static bool Credits_IsKeyPressed() { // Parses a credit line // Returns 1 if new text was read, else 0 -static int Credits_ParseLine(char *line, creditline *credit) { - size_t line_len = strlen(line); - int new_text = 0; - - if (line_len < 1) { - ASSERT(credit->next == nullptr); - ASSERT(credit->text == nullptr); - - credit->text = nullptr; - - credit->type = CLTYPE_BLANK; - new_text = 1; - - } else if (line[0] == ';') { - // Comment - return 0; - } else if (line[0] == '*') { - // Movement data - int x1, x2, y1, y2; - float timedelay; - - int num_found = sscanf(line, "*%d %d %d %d %f", &x1, &y1, &x2, &y2, &timedelay); - if (num_found != 5) { - LOG_WARNING.printf("Bad movement data in credit text (%s)", line); - return 0; - } else { - CreditStartX = x1; - CreditStartY = y1; - CreditEndX = x2; - CreditEndY = y2; - CreditDisplayTime = timedelay; - } - - } else if (line[0] == '!') { - // Heading - ASSERT(credit->next == nullptr); - ASSERT(credit->text == nullptr); - - credit->text = (char *)mem_malloc(line_len + 1); - ASSERT(credit->text); - - strcpy(credit->text, &line[1]); - credit->startx = CreditStartX; - credit->starty = CreditStartY; - credit->endx = CreditEndX; - credit->endy = CreditEndY; - credit->displaytime = CreditDisplayTime; - LOG_DEBUG.printf("Read header %s", line); - - credit->color = CreditHeadingColor; - credit->type = CLTYPE_HEADING; - new_text = 1; - - } else if (line[0] == '$') { - // text color - int r, g, b; - int num_found = sscanf(line, "$%d %d %d", &r, &g, &b); - if (num_found != 3) { - LOG_WARNING.printf("Bad color in credit text (%s)", line); - return 0; - } else { - CreditTextColor = GR_RGB(r, g, b); - } - - } else if (line[0] == '^') { - // heading color - int r, g, b; - int num_found = sscanf(line, "^%d %d %d", &r, &g, &b); - if (num_found != 3) { - LOG_WARNING.printf("Bad color in credit text (%s)", line); - return 0; - } else { - CreditHeadingColor = GR_RGB(r, g, b); - } - } else { - ASSERT(credit->next == nullptr); - ASSERT(credit->text == nullptr); - - if (!strnicmp("Jason Leighton", line, 14) && (ps_rand() % 100) == 0) { - strcat(line, " (Hi mom!)"); - line_len += 10; - } - - credit->text = (char *)mem_malloc(line_len + 1); - ASSERT(credit->text); - - strcpy(credit->text, line); - credit->color = CreditTextColor; - credit->type = CLTYPE_TEXT; - new_text = 1; - } - - return new_text; -} - -// Given a filename, attempts to load that filename as credit text -static bool Credits_LoadCredits(const char *filename) { - CFILE *infile; +static bool Credits_LoadCredits(const char *filename, std::vector &credit_lines) { char curline[MAX_CREDIT_LEN]; // Reset our data - CreditTextColor = GR_RGB(0, 128, 255); - CreditHeadingColor = GR_RGB(255, 255, 255); - CreditStartX = CreditEndX = 320; - CreditStartY = CreditEndY = 50; - CreditDisplayTime = 10; + ddgr_color CreditTextColor = GR_RGB(0, 128, 255); + ddgr_color CreditHeadingColor = GR_RGB(255, 255, 255); - creditline *cur_credit = &Creditlines; - Creditlines.next = nullptr; - Creditlines.text = nullptr; + creditline cur_credit; // Open the file, bail on failure - infile = cfopen(filename, "rt"); + CFILE *infile = cfopen(filename, "rt"); if (!infile) { LOG_ERROR << "Couldn't open credit file to read credits!"; @@ -257,50 +156,97 @@ static bool Credits_LoadCredits(const char *filename) { for (int i = 0; i < 27; i++) { // Generate blank lines for the start - cur_credit->text = nullptr; - cur_credit->type = CLTYPE_BLANK; - cur_credit->next = mem_rmalloc(); - ASSERT(cur_credit->next); - cur_credit = cur_credit->next; - cur_credit->next = nullptr; - cur_credit->text = nullptr; + cur_credit.type = CLTYPE_BLANK; + credit_lines.push_back(cur_credit); } // Read in each line of the credit file, allocing memory and putting it into a correct category - int done = 0; - while (!done) { - if (cfeof(infile)) { - done = 1; - continue; + while (!cfeof(infile)) { + cf_ReadString(curline, MAX_CREDIT_LEN, infile); + if (strnicmp("END", curline, 3) == 0) { + // End of credits, don't parse file further. + break; } - // Read a line and parse it - cf_ReadString(curline, MAX_CREDIT_LEN, infile); - // mprintf(0,"Read string %s\n",curline); + size_t line_len = strlen(curline); - if (!strnicmp("END", curline, 3)) { - done = 1; - continue; - } + if (line_len < 1) { + cur_credit.type = CLTYPE_BLANK; + cur_credit.text = ""; + credit_lines.push_back(cur_credit); + } else { + int num_found; + int r, g, b; + switch (curline[0]) { + case ';': + // Comment + break; + case '*': + // Movement data + int x1, x2, y1, y2; + float timedelay; + + num_found = sscanf(curline, "*%d %d %d %d %f", &x1, &y1, &x2, &y2, &timedelay); + if (num_found != 5) { + LOG_WARNING.printf("Bad movement data in credit text (%s)", curline); + break; + } else { + cur_credit.startx = x1; + cur_credit.starty = y1; + cur_credit.endx = x2; + cur_credit.endy = y2; + cur_credit.displaytime = timedelay; + } + break; + case '!': + // Heading + cur_credit.text = &curline[1]; + LOG_DEBUG.printf("Read header %s", curline); + cur_credit.color = CreditHeadingColor; + cur_credit.type = CLTYPE_HEADING; + credit_lines.push_back(cur_credit); + break; + case '$': + // Text color + num_found = sscanf(curline, "$%d %d %d", &r, &g, &b); + if (num_found != 3) { + LOG_WARNING.printf("Bad color in credit text (%s)", curline); + break; + } else { + CreditTextColor = GR_RGB(r, g, b); + } + break; + case '^': + // Heading color + num_found = sscanf(curline, "^%d %d %d", &r, &g, &b); + if (num_found != 3) { + LOG_WARNING.printf("Bad color in credit text (%s)", curline); + break; + } else { + CreditHeadingColor = GR_RGB(r, g, b); + } + break; + default: + if (!strnicmp("Jason Leighton", curline, 14) && (ps_rand() % 100) == 0) { + strcat(curline, " (Hi mom!)"); + } - if (Credits_ParseLine(curline, cur_credit)) { - // Make a new line - cur_credit->next = mem_rmalloc(); - ASSERT(cur_credit->next); - cur_credit = cur_credit->next; - cur_credit->next = nullptr; - cur_credit->text = nullptr; + cur_credit.text = curline; + cur_credit.color = CreditTextColor; + cur_credit.type = CLTYPE_TEXT; + credit_lines.push_back(cur_credit); + } } } - - cur_credit->type = CLTYPE_END; + // End directive to be sure + cur_credit.type = CLTYPE_END; + cur_credit.text = ""; + credit_lines.push_back(cur_credit); cfclose(infile); return true; } -#define CREDIT_PIXELS_PER_SECOND 22 - void Credits_Display() { #ifdef DEMO // ShowStaticScreen("democredits1.ogf"); @@ -327,38 +273,23 @@ void Credits_Display() { LOG_INFO << "Chillin in credits"; + std::vector credit_lines; // Load our credits - if (!Credits_LoadCredits("GameCredits.txt")) { + if (!Credits_LoadCredits("GameCredits.txt", credit_lines)) { LOG_WARNING << "There was an error loading game credits!"; } else { - // First count how many headers there are so we know how many to allocate - int count = 0; - int done = 0; - creditline *credit = &Creditlines; - - while (!done) { - if (credit->type != CLTYPE_END) - count++; - credit = credit->next; - if (!credit || credit->type == CLTYPE_END) - done = 1; - } + auto credit = credit_lines.begin(); int font_height = grfont_GetHeight(BIG_BRIEFING_FONT); - int total_pixel_height = font_height * count; - int cur_line = 0; - float total_pixel_count = 0; float cur_pixel_count = 0; float last_time = timer_GetTime(); // Now show these guys - done = 0; - credit = &Creditlines; - while (cur_line < count) { + while (credit != credit_lines.end()) { StartFrame(0, 0, Game_window_w, Game_window_h); rend_DrawChunkedBitmap(&Credits_bm, 0, 0, 255); - Credits_Render(credit, cur_pixel_count); + Credits_Render(credit, credit_lines.end(), cur_pixel_count); EndFrame(); rend_Flip(); @@ -368,11 +299,9 @@ void Credits_Display() { cur_pixel_count += frametime * CREDIT_PIXELS_PER_SECOND; while (cur_pixel_count >= font_height) { - credit = credit->next; - cur_line++; - if (credit == nullptr || credit->type == CLTYPE_END) { + credit++; + if (credit == credit_lines.end() || credit->type == CLTYPE_END) { cur_pixel_count = -1; - cur_line = count; } else { cur_pixel_count -= font_height; } @@ -390,26 +319,11 @@ void Credits_Display() { // Check for keys Descent->defer(); if (Credits_IsKeyPressed()) { - cur_line = count; + break; } } } - // Free credit text memory - creditline *cur_credit = &Creditlines; - while (cur_credit) { - if (cur_credit->text) - mem_free(cur_credit->text); - - creditline *next_credit = cur_credit->next; - - if (cur_credit != &Creditlines) { - mem_free(cur_credit); - } - - cur_credit = next_credit; - } - // Free bitmaps bm_DestroyChunkedBitmap(&Credits_bm); @@ -419,9 +333,8 @@ void Credits_Display() { #endif } -void Credits_Render(creditline *header, float pixels_in) { +void Credits_Render(std::vector::iterator credit, std::vector::iterator end, float pixels_in) { bool done = false; - creditline *credit = header; grtext_Reset(); grtext_SetFont(BIG_BRIEFING_FONT); @@ -430,16 +343,15 @@ void Credits_Render(creditline *header, float pixels_in) { float pixels_this_frame = 0; int cur_pixel = -pixels_in; - int cur_line = 0; + while ((pixels_this_frame < 480 + text_height) && !done) { if (credit->type == CLTYPE_BLANK) { - credit = credit->next; - cur_line++; + credit++; pixels_this_frame += text_height; cur_pixel += text_height; - if ((credit == nullptr) || (credit->type == CLTYPE_END)) + if ((credit == end) || (credit->type == CLTYPE_END)) done = true; continue; @@ -456,17 +368,13 @@ void Credits_Render(creditline *header, float pixels_in) { } else grtext_SetAlpha(255); - // Figure out text placement - int texty = cur_pixel; - - grtext_CenteredPrintf(0, texty, "%s", credit->text); + grtext_CenteredPrintf(0, cur_pixel, "%s", credit->text.c_str()); - credit = credit->next; + credit++; - if ((credit == nullptr) || (credit->type == CLTYPE_END)) + if ((credit == end) || (credit->type == CLTYPE_END)) done = true; - cur_line++; pixels_this_frame += text_height; cur_pixel += text_height; } diff --git a/Descent3/credits.h b/Descent3/credits.h index cac5ab676..55c5fb6d1 100644 --- a/Descent3/credits.h +++ b/Descent3/credits.h @@ -32,4 +32,4 @@ * $NoKeywords: $ */ -void Credits_Display(void); +void Credits_Display();