Index: code/menuui/credits.cpp
===================================================================
--- code/menuui/credits.cpp	(revision 9013)
+++ code/menuui/credits.cpp	(working copy)
@@ -210,7 +210,7 @@
 static float Credits_artwork_display_time	= 9.0f;
 static float Credits_artwork_fade_time		= 1.0f;
 
-static SCP_string Credit_text;
+static SCP_vector<SCP_string> Credit_text_parts;
 
 static bool Credits_parsed;
 
@@ -309,11 +309,11 @@
 		}
 	}
 
-	parse_optional_float("$Text scroll rate:", &Credits_scroll_rate, 15.0f, 0.0f);
+	parse_optional_float("$Text scroll rate:", &Credits_scroll_rate, 0.0f);
 
-	parse_optional_float("$Artworks display time:", &Credits_artwork_display_time, 9.0f, 0.0f);
+	parse_optional_float("$Artworks display time:", &Credits_artwork_display_time, 0.0f);
 
-	parse_optional_float("$Artworks fade time:", &Credits_artwork_fade_time, 1.0f, 0.0f);
+	parse_optional_float("$Artworks fade time:", &Credits_artwork_fade_time, 0.0f);
 
 	if (optional_string("$SCP Credits position:"))
 	{
@@ -331,6 +331,7 @@
 
 	ignore_white_space();
 	
+	SCP_string credits_text;
 	SCP_string line;
 
 	SCP_vector<int> charNum;
@@ -348,7 +349,7 @@
 		// Also don't append the default credits anymore when there was already a parsed table
 		if(first_run && !Credits_parsed && !line.compare(mod_check))
 		{
-			Credit_text.append(unmodified_credits);
+			credits_text.append(unmodified_credits);
 		}
 
 		first_run = false;
@@ -356,7 +357,7 @@
 		if (line.empty())
 		{
 			// If the line is empty then just append a newline, don't bother with splitting it first
-			Credit_text.append("\n");
+			credits_text.append("\n");
 		}
 		else
 		{
@@ -376,12 +377,14 @@
 			// Now add all splitted lines to the credit text and append a newline to the end
 			for (int i = 0; i < numLines; i++)
 			{
-				Credit_text.append(SCP_string(lines[i], charNum[i]));
-				Credit_text.append("\n");
+				credits_text.append(SCP_string(lines[i], charNum[i]));
+				credits_text.append("\n");
 			}
 		}
 	}
 
+	Credit_text_parts.push_back(credits_text);
+
 	Credits_parsed = true;
 }
 
@@ -402,7 +405,7 @@
 
 void credits_init()
 {
-	int i, w, h;
+	int i;
 	credits_screen_buttons *b;
 
 	int credits_spooled_music_index = event_music_get_spooled_music_index("Cinema");	
@@ -418,9 +421,7 @@
 
 	Credits_frametime = 0;
 	Credits_last_time = timer_get_milliseconds();
-
-	Credit_text = "";
-
+	
 	// this is moved up here so we can override it if desired
 	Credits_artwork_index = rand() % NUM_IMAGES;
 
@@ -429,17 +430,19 @@
 	credits_parse();
 
 	if (!Credits_parsed)
-		Credit_text.assign("No credits available.\n");
+	{
+		Credit_text_parts.push_back(SCP_string("No credits available.\n"));
+	}
 	else
 	{
 		switch (SCP_credits_position)
 		{
 			case START:
-				Credit_text.insert(0, fs2_open_credit_text);
+				Credit_text_parts.insert(Credit_text_parts.begin(), fs2_open_credit_text);
 				break;
 
 			case END:
-				Credit_text.append(fs2_open_credit_text);
+				Credit_text_parts.push_back(fs2_open_credit_text);
 				break;
 
 			default:
@@ -449,117 +452,128 @@
 	}
 
 	int ch;
-	for (SCP_string::iterator ii = Credit_text.begin(); ii != Credit_text.end(); ++ii)
+	for (SCP_vector<SCP_string>::iterator iter = Credit_text_parts.begin(); iter != Credit_text_parts.end(); ++iter)
 	{
-		ch = *ii;
-		switch (ch)
+		for (SCP_string::iterator ii = iter->begin(); ii != iter->end(); ++ii)
 		{
-			case -4:
-				ch = 129;
-				break;
+			ch = *ii;
+			switch (ch)
+			{
+				case -4:
+					ch = 129;
+					break;
 
-			case -28:
-				ch = 132;
-				break;
+				case -28:
+					ch = 132;
+					break;
 
-			case -10:
-				ch = 148;
-				break;
+				case -10:
+					ch = 148;
+					break;
 
-			case -23:
-				ch = 130;
-				break;
+				case -23:
+					ch = 130;
+					break;
 
-			case -30:
-				ch = 131;
-				break;
+				case -30:
+					ch = 131;
+					break;
 
-			case -25:
-				ch = 135;
-				break;
+				case -25:
+					ch = 135;
+					break;
 
-			case -21:
-				ch = 137;
-				break;
+				case -21:
+					ch = 137;
+					break;
 
-			case -24:
-				ch = 138;
-				break;
+				case -24:
+					ch = 138;
+					break;
 
-			case -17:
-				ch = 139;
-				break;
+				case -17:
+					ch = 139;
+					break;
 
-			case -18:
-				ch = 140;
-				break;
+				case -18:
+					ch = 140;
+					break;
 
-			case -60:
-				ch = 142;
-				break;
+				case -60:
+					ch = 142;
+					break;
 
-			case -55:
-				ch = 144;
-				break;
+				case -55:
+					ch = 144;
+					break;
 
-			case -12:
-				ch = 147;
-				break;
+				case -12:
+					ch = 147;
+					break;
 
-			case -14:
-				ch = 149;
-				break;
+				case -14:
+					ch = 149;
+					break;
 
-			case -5:
-				ch = 150;
-				break;
+				case -5:
+					ch = 150;
+					break;
 
-			case -7:
-				ch = 151;
-				break;
+				case -7:
+					ch = 151;
+					break;
 
-			case -42:
-				ch = 153;
-				break;
+				case -42:
+					ch = 153;
+					break;
 
-			case -36:
-				ch = 154;
-				break;
+				case -36:
+					ch = 154;
+					break;
 
-			case -31:
-				ch = 160;
-				break;
+				case -31:
+					ch = 160;
+					break;
 
-			case -19:
-				ch = 161;
-				break;
+				case -19:
+					ch = 161;
+					break;
 
-			case -13:
-				ch = 162;
-				break;
+				case -13:
+					ch = 162;
+					break;
 
-			case -6:
-				ch = 163;
-				break;
+				case -6:
+					ch = 163;
+					break;
 
-			case -32:
-				ch = 133;
-				break;
+				case -32:
+					ch = 133;
+					break;
 
-			case -22:
-				ch = 136;
-				break;
+				case -22:
+					ch = 136;
+					break;
 
-			case -20:
-				ch = 141;
-				break;
+				case -20:
+					ch = 141;
+					break;
+			}
+
+			*ii = (char) ch;
 		}
+	}
 
-		*ii = (char) ch;
+	int temp_h;
+	int h = 0;
+
+	for (SCP_vector<SCP_string>::iterator iter = Credit_text_parts.begin(); iter != Credit_text_parts.end(); ++iter)
+	{
+		gr_get_string_size(NULL, &temp_h, iter->c_str(), iter->length());
+
+		h = h + temp_h;
 	}
 
-	gr_get_string_size(&w, &h, Credit_text.c_str(), Credit_text.length());
-
 	Credit_start_pos = i2fl(Credits_text_coords[gr_screen.res][CREDITS_H_COORD]);
 	Credit_stop_pos = -i2fl(h);
 	Credit_position = Credit_start_pos;
@@ -611,7 +625,7 @@
 
 	credits_stop_music();
 
-	Credit_text = "";
+	Credit_text_parts.clear();
 
 	if (Background_bitmap){
 		bm_release(Background_bitmap);
@@ -738,16 +752,29 @@
 	gr_set_clip(Credits_text_coords[gr_screen.res][CREDITS_X_COORD], Credits_text_coords[gr_screen.res][CREDITS_Y_COORD], Credits_text_coords[gr_screen.res][CREDITS_W_COORD], Credits_text_coords[gr_screen.res][CREDITS_H_COORD]);
 	gr_set_font(FONT1);
 	gr_set_color_fast(&Color_normal);
-
-	int sy;
+	
+	int sy; // The current position of the first text part
 	if ( Credit_position > 0 ) {
 		sy = fl2i(Credit_position+0.5f);
 	} else {
 		sy = fl2i(Credit_position-0.5f);
 	}
 
-	gr_string(0x8000, sy, Credit_text.c_str());
+	for (SCP_vector<SCP_string>::iterator iter = Credit_text_parts.begin(); iter != Credit_text_parts.end(); ++iter)
+	{
+		int height;
 
+		gr_get_string_size(NULL, &height, iter->c_str(), iter->length());
+
+		// Check if the text part is actually visible
+		if (sy + height > 0)
+		{
+			gr_string(0x8000, sy, iter->c_str());
+		}
+
+		sy = sy + height;
+	}
+
 	int temp_time;
 	temp_time = timer_get_milliseconds();
 
Index: code/parse/parselo.cpp
===================================================================
--- code/parse/parselo.cpp	(revision 9013)
+++ code/parse/parselo.cpp	(working copy)
@@ -4055,7 +4055,7 @@
 	return num_files;
 }
 
-bool parse_optional_float(const char *tag, float *destination, float def, float min, float max)
+bool parse_optional_float(const char *tag, float *destination, float min, float max)
 {
 	Assert(tag != NULL);
 	Assert(destination != NULL);
@@ -4079,8 +4079,6 @@
 	}
 	else
 	{
-		*destination = def;
-
 		return false;
 	}
 }
Index: code/parse/parselo.h
===================================================================
--- code/parse/parselo.h	(revision 9013)
+++ code/parse/parselo.h	(working copy)
@@ -269,11 +269,10 @@
  *
  * @param tag The optional tag that should be checked
  * @param destination The destination float where the value should be stored
- * @param def The default value which should be used when the tag isn't present
  * @param min The minimum value which will be accepted. Optional parameter; defaults to @c FLT_MIN
  * @param max The maximum value which will be accepted. Optional parameter; defaults to @c FLT_MAX
  * @return
  */
-bool parse_optional_float(const char *tag, float *destination, float def, float min = FLT_MIN, float max = FLT_MAX);
+bool parse_optional_float(const char *tag, float *destination, float min = FLT_MIN, float max = FLT_MAX);
 
 #endif
