[Scummvm-cvs-logs] SF.net SVN: scummvm:[41833] scummvm/trunk/engines/sci

waltervn at users.sourceforge.net waltervn at users.sourceforge.net
Wed Jun 24 21:12:47 CEST 2009


Revision: 41833
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41833&view=rev
Author:   waltervn
Date:     2009-06-24 19:12:45 +0000 (Wed, 24 Jun 2009)

Log Message:
-----------
SCI: Partial support for dual-language games.

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kgraphics.cpp
    scummvm/trunk/engines/sci/engine/script.cpp
    scummvm/trunk/engines/sci/engine/state.cpp
    scummvm/trunk/engines/sci/engine/state.h
    scummvm/trunk/engines/sci/engine/vm.h
    scummvm/trunk/engines/sci/gfx/gfx_gui.cpp
    scummvm/trunk/engines/sci/gfx/gfx_gui.h

Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-06-24 18:28:18 UTC (rev 41832)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-06-24 19:12:45 UTC (rev 41833)
@@ -621,10 +621,14 @@
 reg_t kTextSize(EngineState *s, int funct_nr, int argc, reg_t *argv) {
 	int width, height;
 	char *text = argv[1].segment ? (char *) kernel_dereference_bulk_pointer(s, argv[1], 0) : NULL;
+	const char *sep = NULL; 
 	reg_t *dest = kernel_dereference_reg_pointer(s, argv[0], 4);
 	int maxwidth = (argc > 3) ? argv[3].toUint16() : 0;
 	int font_nr = argv[2].toUint16();
 
+	if ((argc > 4) && (argv[4].segment))
+		sep = (const char *)kernel_dereference_bulk_pointer(s, argv[4], 0);	
+
 	if (maxwidth < 0)
 		maxwidth = 0;
 
@@ -636,7 +640,7 @@
 		return s->r_acc;
 	}
 
-	GFX_ASSERT(gfxop_get_text_params(s->gfx_state, font_nr, text, maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE,
+	GFX_ASSERT(gfxop_get_text_params(s->gfx_state, font_nr, s->strSplit(text, sep).c_str(), maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE,
 	                                 &width, &height, 0, NULL, NULL, NULL));
 	debugC(2, kDebugLevelStrings, "GetTextSize '%s' -> %dx%d\n", text, width, height);
 
@@ -1570,7 +1574,7 @@
 
 	int font_nr = GET_SEL32V(obj, font);
 	reg_t text_pos = GET_SEL32(obj, text);
-	char *text = text_pos.isNull() ? NULL : (char *)s->seg_manager->dereference(text_pos, NULL);
+	const char *text = text_pos.isNull() ? NULL : (char *)s->seg_manager->dereference(text_pos, NULL);
 	int view = GET_SEL32V(obj, view);
 	int cel = sign_extend_byte(GET_SEL32V(obj, cel));
 	int loop = sign_extend_byte(GET_SEL32V(obj, loop));
@@ -1584,7 +1588,7 @@
 	switch (type) {
 	case K_CONTROL_BUTTON:
 		debugC(2, kDebugLevelGraphics, "drawing button %04x:%04x to %d,%d\n", PRINT_REG(obj), x, y);
-		ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(s->port, obj, area, text, font_nr,
+		ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(s->port, obj, area, s->strSplit(text, NULL).c_str(), font_nr,
 		                          (int8)(state & kControlStateFramed), (int8)inverse, (int8)(state & kControlStateDisabled)));
 		break;
 
@@ -1593,7 +1597,7 @@
 
 		debugC(2, kDebugLevelGraphics, "drawing text %04x:%04x to %d,%d, mode=%d\n", PRINT_REG(obj), x, y, mode);
 
-		ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(s->port, obj, area, text, font_nr, mode,
+		ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(s->port, obj, area, s->strSplit(text).c_str(), font_nr, mode,
 									(int8)(!!(state & kControlStateDitherFramed)), (int8)inverse));
 		break;
 
@@ -1620,8 +1624,8 @@
 
 	case K_CONTROL_CONTROL:
 	case K_CONTROL_CONTROL_ALIAS: {
-		char **entries_list = NULL;
-		char *seeker;
+		const char **entries_list = NULL;
+		const char *seeker;
 		int entries_nr;
 		int lsTop = GET_SEL32V(obj, lsTop) - text_pos.offset;
 		int list_top = 0;
@@ -1641,7 +1645,7 @@
 
 		if (entries_nr) { // determine list_top, selection, and the entries_list
 			seeker = text;
-			entries_list = (char**)malloc(sizeof(char *) * entries_nr);
+			entries_list = (const char**)malloc(sizeof(char *) * entries_nr);
 			for (i = 0; i < entries_nr; i++) {
 				entries_list[i] = seeker;
 				seeker += entry_size	;
@@ -2524,10 +2528,10 @@
 	lWhite.alpha = 0;
 	lWhite.priority = -1;
 	lWhite.control = -1;
+	const char *title = argv[4 + argextra].segment ? kernel_dereference_char_pointer(s, argv[4 + argextra], 0) : NULL;
 
 	window = sciw_new_window(s, gfx_rect(x, y, xl, yl), s->titlebar_port->_font, fgcolor, bgcolor,
-							s->titlebar_port->_font, lWhite, black, argv[4 + argextra].segment ?
-							kernel_dereference_char_pointer(s, argv[4 + argextra], 0) : NULL, flags);
+							s->titlebar_port->_font, lWhite, black, title ? s->strSplit(title, NULL).c_str() : NULL, flags);
 
 	// PQ3 and SCI1.1 games have the interpreter store underBits implicitly
 	if (argextra)
@@ -3287,7 +3291,7 @@
 
 	assert_primary_widget_lists(s);
 
-	text_handle = gfxw_new_text(s->gfx_state, area, font_nr, text, halign, ALIGN_TOP, color0, *color1, bg_color, 0);
+	text_handle = gfxw_new_text(s->gfx_state, area, font_nr, s->strSplit(text).c_str(), halign, ALIGN_TOP, color0, *color1, bg_color, 0);
 
 	if (!text_handle) {
 		error("Display: Failed to create text widget");

Modified: scummvm/trunk/engines/sci/engine/script.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/script.cpp	2009-06-24 18:28:18 UTC (rev 41832)
+++ scummvm/trunk/engines/sci/engine/script.cpp	2009-06-24 19:12:45 UTC (rev 41833)
@@ -200,6 +200,9 @@
 	FIND_SELECTOR(points);
 	FIND_SELECTOR(syncCue);
 	FIND_SELECTOR(syncTime);
+	FIND_SELECTOR(printLang);
+	FIND_SELECTOR(subtitleLang);
+	FIND_SELECTOR(parseLang);
 }
 
 void Kernel::dumpScriptObject(char *data, int seeker, int objsize) {

Modified: scummvm/trunk/engines/sci/engine/state.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/state.cpp	2009-06-24 18:28:18 UTC (rev 41832)
+++ scummvm/trunk/engines/sci/engine/state.cpp	2009-06-24 19:12:45 UTC (rev 41833)
@@ -126,4 +126,69 @@
 	return script_000->locals_block->_locals[13].toUint16();
 }
 
+kLanguage EngineState::charToLanguage(const char c) const {
+	switch (c) {
+	case 'F':
+		return K_LANG_FRENCH;
+	case 'S':
+		return K_LANG_SPANISH;
+	case 'I':
+		return K_LANG_ITALIAN;
+	case 'G':
+		return K_LANG_GERMAN;
+	case 'J':
+	case 'j':
+		return K_LANG_JAPANESE;
+	case 'P':
+		return K_LANG_PORTUGUESE;
+	default:
+		return K_LANG_NONE;
+	}
+}
+
+Common::String EngineState::getLanguageString(const char *str, kLanguage lang) const {
+	kLanguage secondLang = K_LANG_NONE;
+
+	const char *seeker = str;
+	while (*seeker) {
+		if ((*seeker == '%') || (*seeker == '#')) {
+			secondLang = charToLanguage(*(seeker + 1));
+
+			if (secondLang != K_LANG_NONE)
+				break;
+		}
+
+		seeker++;
+	}
+
+	if ((secondLang == K_LANG_JAPANESE) && (*(seeker + 1) == 'J')) {
+		// FIXME: Add Kanji support
+		lang = K_LANG_ENGLISH;
+	}
+
+	if (secondLang == lang)
+		return Common::String(seeker + 2);
+
+	if (seeker)
+		return Common::String(str, seeker - str);
+	else
+		return Common::String(str);
+}
+
+Common::String EngineState::strSplit(const char *str, const char *sep) {
+	EngineState *s = this;
+
+	kLanguage lang = (kLanguage)GET_SEL32V(s->game_obj, printLang);
+	kLanguage subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
+
+	Common::String retval = getLanguageString(str, lang);
+
+	if ((subLang != K_LANG_NONE) && (sep != NULL)) {
+		retval += sep;
+		retval += getLanguageString(str, subLang);
+	}
+
+	return retval;
+}
+
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/engine/state.h
===================================================================
--- scummvm/trunk/engines/sci/engine/state.h	2009-06-24 18:28:18 UTC (rev 41832)
+++ scummvm/trunk/engines/sci/engine/state.h	2009-06-24 19:12:45 UTC (rev 41833)
@@ -88,6 +88,18 @@
 	SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE = 4
 };
 
+/** Supported languages */
+enum kLanguage {
+	K_LANG_NONE = 0,
+	K_LANG_ENGLISH = 1,
+	K_LANG_FRENCH = 33,
+	K_LANG_SPANISH = 34,
+	K_LANG_ITALIAN = 39,
+	K_LANG_GERMAN = 49,
+	K_LANG_JAPANESE = 81,
+	K_LANG_PORTUGUESE = 351
+};
+
 struct drawn_pic_t {
 	int nr;
 	int palette;
@@ -209,6 +221,16 @@
 
 	uint16 currentRoomNumber() const;
 
+	/**
+	 * Processes a multilanguage string based on the current language settings and
+	 * returns a string that is ready to be displayed.
+	 * @param str		the multilanguage string
+	 * @param sep		optional seperator between main language and subtitle language,
+	 *					if NULL is passed no subtitle will be added to the returned string
+	 * @return processed string
+	 */
+	Common::String strSplit(const char *str, const char *sep = "\r----------\r");
+
 	/* Debugger data: */
 	Breakpoint *bp_list;   /**< List of breakpoints */
 	int have_bp;  /**< Bit mask specifying which types of breakpoints are used in bp_list */
@@ -239,6 +261,10 @@
 	Kernel *_kernel;
 
 	EngineState *successor; /**< Successor of this state: Used for restoring */
+
+private:
+	kLanguage charToLanguage(const char c) const;
+	Common::String getLanguageString(const char *str, kLanguage lang) const;
 };
 
 /**

Modified: scummvm/trunk/engines/sci/engine/vm.h
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.h	2009-06-24 18:28:18 UTC (rev 41832)
+++ scummvm/trunk/engines/sci/engine/vm.h	2009-06-24 19:12:45 UTC (rev 41833)
@@ -198,7 +198,11 @@
 	Selector points; /**< Used by AvoidPath() */
 
 	Selector syncCue; /**< Used by DoSync() */
-	Selector syncTime; /**< Used by DoSync() */
+	Selector syncTime;
+
+	Selector printLang; /**< Used for i18n */
+	Selector subtitleLang;
+	Selector parseLang;
 };
 
 // A reference to an object's variable.

Modified: scummvm/trunk/engines/sci/gfx/gfx_gui.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_gui.cpp	2009-06-24 18:28:18 UTC (rev 41832)
+++ scummvm/trunk/engines/sci/gfx/gfx_gui.cpp	2009-06-24 19:12:45 UTC (rev 41833)
@@ -266,7 +266,7 @@
 	return gfx_rect(rect.x + point.x, rect.y + point.y, rect.width + 1, rect.height + yplus);
 }
 
-GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, char *text,
+GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, const char *text,
 	int font, gfx_alignment_t align, char framed, char inverse, int flags, char gray_text) {
 	gfx_color_t *color1, *color2, *bgcolor;
 
@@ -294,7 +294,7 @@
 	return list;
 }
 
-GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, char selected, char inverse, char grayed_out) {
+GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, char selected, char inverse, char grayed_out) {
 	gfx_color_t *frame_col = (inverse) ? &(port->_bgcolor) : &(port->_color);
 	GfxList *list;
 
@@ -332,7 +332,7 @@
 	return list;
 }
 
-GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font,
+GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font,
 								   gfx_alignment_t align, char framed, char inverse) {
 	GfxList *list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 2), 0);
 
@@ -344,7 +344,7 @@
 	return _sciw_add_text_to_list(list, port, zone, text, font, align, framed, inverse, 0, port->gray_text);
 }
 
-GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, unsigned int cursor,
+GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, unsigned int cursor,
 								   char inverse) {
 	GfxText *text_handle;
 
@@ -440,7 +440,7 @@
 	return list;
 }
 
-GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, char **entries_list,
+GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, const char **entries_list,
 	int entries_nr, int list_top, int selection, char inverse) {
 	GfxList *list;
 

Modified: scummvm/trunk/engines/sci/gfx/gfx_gui.h
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_gui.h	2009-06-24 18:28:18 UTC (rev 41832)
+++ scummvm/trunk/engines/sci/gfx/gfx_gui.h	2009-06-24 19:12:45 UTC (rev 41833)
@@ -113,7 +113,7 @@
  * @return				The button
  */
 GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone,
-		char *text, int font, char selected, char inverse, char gray);
+		const char *text, int font, char selected, char inverse, char gray);
 
 /**
  * Creates a new text control list.
@@ -129,7 +129,7 @@
  * @return				The text control widget list
  */
 GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone,
-		char *text, int font, gfx_alignment_t align, char frame,
+		const char *text, int font, gfx_alignment_t align, char frame,
 		char inverse);
 
 /**
@@ -145,7 +145,7 @@
  * @return				An appropriate widget list
  */
 GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone,
-		char *text, int font, unsigned int cursor, char inverse);
+		const char *text, int font, unsigned int cursor, char inverse);
 
 /**
  * Creates a new icon control list.
@@ -178,8 +178,8 @@
  * @return					An appropriate widget list
  */
 GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone,
-		int font_nr, char **entries_list, int entries_nr, int list_top,
-		int selection, char inverse);
+		int font_nr, const char **entries_list, int entries_nr,
+		int list_top, int selection, char inverse);
 /** @} */
 
 /** @name Menubar widgets */


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list