aboutsummaryrefslogtreecommitdiff
path: root/saga/text.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'saga/text.cpp')
-rw-r--r--saga/text.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/saga/text.cpp b/saga/text.cpp
new file mode 100644
index 0000000000..80367169c9
--- /dev/null
+++ b/saga/text.cpp
@@ -0,0 +1,342 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+/*
+ Description:
+
+ Text / dialogue display management module
+
+ Notes:
+*/
+
+#include "reinherit.h"
+
+#include "yslib.h"
+
+/*
+ * Uses the following modules:
+\*--------------------------------------------------------------------------*/
+#include "font_mod.h"
+
+/*
+ * Begin module
+\*--------------------------------------------------------------------------*/
+#include "text_mod.h"
+#include "text.h"
+
+namespace Saga {
+
+int
+TEXT_Draw(int font_id,
+ R_SURFACE * ds,
+ const char *string,
+ int text_x, int text_y, int color, int effect_color, int flags)
+{
+
+ int string_w;
+ int string_len;
+
+ int fit_w;
+
+ const char *start_p;
+ const char *search_p;
+ const char *measure_p;
+ const char *found_p;
+ int len;
+ int w;
+ const char *end_p;
+ int h;
+ int wc;
+
+ int w_total;
+ int len_total;
+
+ string_len = strlen(string);
+
+ if (flags & FONT_CENTERED) {
+
+ /* Text is centered... format output */
+
+ /* Enforce minimum and maximum center points for centered text */
+ if (text_x < R_TEXT_CENTERLIMIT) {
+ text_x = R_TEXT_CENTERLIMIT;
+ }
+
+ if (text_x > ds->buf_w - R_TEXT_CENTERLIMIT) {
+ text_x = ds->buf_w - R_TEXT_CENTERLIMIT;
+ }
+
+ if (text_x < (R_TEXT_MARGIN * 2)) {
+ /* Text can't be centered if it's too close to the margin */
+ return R_FAILURE;
+ }
+
+ string_w =
+ FONT_GetStringWidth(font_id, string, string_len, flags);
+
+ if (text_x < (ds->buf_w / 2)) {
+ /* Fit to right side */
+ fit_w = (text_x - R_TEXT_MARGIN) * 2;
+ } else {
+ /* Fit to left side */
+ fit_w = ((ds->buf_w - R_TEXT_MARGIN) - text_x) * 2;
+ }
+
+ if (fit_w >= string_w) {
+
+ /* Entire string fits, draw it */
+ text_x = text_x - (string_w / 2);
+
+ FONT_Draw(font_id,
+ ds,
+ string,
+ string_len,
+ text_x, text_y, color, effect_color, flags);
+
+ return R_SUCCESS;
+ }
+
+ /* String won't fit on one line ... */
+
+ h = FONT_GetHeight(font_id);
+ w_total = 0;
+ len_total = 0;
+ wc = 0;
+
+ start_p = string;
+ measure_p = string;
+ search_p = string;
+ end_p = string + string_len;
+
+ for (;;) {
+
+ found_p = strchr(search_p, ' ');
+
+ if (found_p == NULL) {
+ /* Ran to the end of the buffer */
+ len = end_p - measure_p;
+ } else {
+ len = found_p - measure_p;
+ }
+
+ w = FONT_GetStringWidth(font_id, measure_p, len,
+ flags);
+ measure_p = found_p;
+
+ if ((w_total + w) > fit_w) {
+ /* This word won't fit */
+ if (wc == 0) {
+ /* The first word in the line didn't fit. abort */
+ return R_SUCCESS;
+ }
+
+ /* Wrap what we've got and restart */
+ FONT_Draw(font_id,
+ ds,
+ start_p,
+ len_total,
+ text_x - (w_total / 2),
+ text_y, color, effect_color, flags);
+
+ text_y += h + R_TEXT_LINESPACING;
+ w_total = 0;
+ len_total = 0;
+ wc = 0;
+ measure_p = search_p;
+ start_p = search_p;
+
+ } else {
+ /* Word will fit ok */
+ w_total += w;
+ len_total += len;
+ wc++;
+
+ if (found_p == NULL) {
+ /* Since word hit NULL but fit, we are done */
+ FONT_Draw(font_id,
+ ds,
+ start_p,
+ len_total,
+ text_x - (w_total / 2),
+ text_y,
+ color, effect_color, flags);
+
+ return R_SUCCESS;
+ }
+
+ search_p = measure_p + 1;
+ }
+ } /* End for (;;) */
+
+ } else {
+
+ /* Text is not centered; No formatting required */
+
+ FONT_Draw(font_id,
+ ds,
+ string,
+ string_len, text_x, text_y, color, effect_color, flags);
+
+ }
+
+ return R_SUCCESS;
+}
+
+R_TEXTLIST *TEXT_CreateList(void)
+{
+ R_TEXTLIST *new_textlist;
+
+ new_textlist = (R_TEXTLIST *)malloc(sizeof *new_textlist);
+
+ if (new_textlist == NULL) {
+ return NULL;
+ }
+
+ new_textlist->list = ys_dll_create();
+
+ if (new_textlist->list == NULL) {
+ free(new_textlist);
+ return NULL;
+ }
+
+ return new_textlist;
+}
+
+void TEXT_ClearList(R_TEXTLIST * tlist)
+{
+ if (tlist != NULL) {
+ ys_dll_delete_all(tlist->list);
+ }
+
+ return;
+}
+
+void TEXT_DestroyList(R_TEXTLIST * tlist)
+{
+ if (tlist != NULL) {
+ ys_dll_destroy(tlist->list);
+ }
+ free(tlist);
+
+ return;
+}
+
+int TEXT_DrawList(R_TEXTLIST * textlist, R_SURFACE * ds)
+{
+
+ R_TEXTLIST_ENTRY *entry_p;
+ YS_DL_NODE *walk_p;
+
+ assert((textlist != NULL) && (ds != NULL));
+
+ for (walk_p = ys_dll_head(textlist->list);
+ walk_p != NULL; walk_p = ys_dll_next(walk_p)) {
+
+ entry_p = (R_TEXTLIST_ENTRY *)ys_dll_get_data(walk_p);
+
+ if (entry_p->display != 0) {
+
+ TEXT_Draw(entry_p->font_id,
+ ds,
+ entry_p->string,
+ entry_p->text_x,
+ entry_p->text_y,
+ entry_p->color,
+ entry_p->effect_color, entry_p->flags);
+ }
+ }
+
+ return R_SUCCESS;
+}
+
+int TEXT_ProcessList(R_TEXTLIST * textlist, long ms)
+{
+ R_TEXTLIST_ENTRY *entry_p;
+ YS_DL_NODE *walk_p;
+ YS_DL_NODE *temp_p;
+
+ for (walk_p = ys_dll_head(textlist->list);
+ walk_p != NULL; walk_p = temp_p) {
+
+ temp_p = ys_dll_next(walk_p);
+
+ entry_p = (R_TEXTLIST_ENTRY *)ys_dll_get_data(walk_p);
+
+ if (entry_p->flags & TEXT_TIMEOUT) {
+
+ entry_p->time -= ms;
+ if (entry_p->time <= 0) {
+
+ ys_dll_delete(walk_p);
+ }
+ }
+ }
+
+ return R_SUCCESS;
+
+}
+
+R_TEXTLIST_ENTRY *TEXT_AddEntry(R_TEXTLIST * textlist,
+ R_TEXTLIST_ENTRY * entry)
+{
+ YS_DL_NODE *new_node = NULL;
+
+ if (entry != NULL) {
+ new_node =
+ ys_dll_add_tail(textlist->list, entry, sizeof *entry);
+ }
+
+ return (new_node != NULL) ? (R_TEXTLIST_ENTRY *)new_node->data : NULL;
+}
+
+int TEXT_SetDisplay(R_TEXTLIST_ENTRY * entry, int val)
+{
+ if (entry != NULL) {
+ entry->display = !!val;
+ return R_SUCCESS;
+ }
+
+ return R_FAILURE;
+}
+
+int TEXT_DeleteEntry(R_TEXTLIST * textlist, R_TEXTLIST_ENTRY * entry)
+{
+ YS_DL_NODE *walk_p;
+
+ if (entry == NULL) {
+ return R_FAILURE;
+ }
+
+ for (walk_p = ys_dll_head(textlist->list);
+ walk_p != NULL; walk_p = ys_dll_next(walk_p)) {
+
+ if (entry == ys_dll_get_data(walk_p)) {
+ ys_dll_delete(walk_p);
+ break;
+ }
+ }
+
+ return R_SUCCESS;
+}
+
+} // End of namespace Saga
+