Index: src/simutrans/descriptor/reader/roadsign_reader.cc
===================================================================
--- src/simutrans/descriptor/reader/roadsign_reader.cc	(revisión: 12130)
+++ src/simutrans/descriptor/reader/roadsign_reader.cc	(copia de trabajo)
@@ -107,6 +107,10 @@
 		dbg->fatal( "roadsign_reader_t::read_node()", "Cannot handle too new node version %i", version );
 	}
 
+	// the diagonal images are an additional node behind the cursor,
+	// so a fifth child means they are there
+	desc->has_diagonal = node.nchildren > 4;
+
 	if(  version<=3  &&  (  desc->is_choose_sign() ||  desc->is_private_way()  )  &&  desc->get_waytype() == road_wt  ) {
 		// do not shift these signs to the left for compatibility
 		desc->offset_left = 0;
Index: src/simutrans/descriptor/roadsign_desc.h
===================================================================
--- src/simutrans/descriptor/roadsign_desc.h	(revisión: 12130)
+++ src/simutrans/descriptor/roadsign_desc.h	(copia de trabajo)
@@ -22,6 +22,8 @@
  *  0   Name
  *  1   Copyright
  *  2   Image list
+ *  3   Cursor and icon
+ *  4   Diagonal image list (optional)
  */
 class roadsign_desc_t : public obj_desc_transport_infrastructure_t {
 	friend class roadsign_reader_t;
@@ -33,6 +35,10 @@
 
 	uint16 min_speed; // 0 = no min speed
 
+	// set from the number of children when loading, so it is not part of the
+	// node data and does not change the checksum of signs already published
+	bool has_diagonal = false;
+
 public:
 	enum types {
 		NONE                  = 0,
@@ -53,6 +59,25 @@
 		return image != NULL ? image->get_id() : IMG_EMPTY;
 	}
 
+	// the diagonal list is parallel to the normal one, so both take the same index
+	image_id get_image_id(ribi_t::dir dir, bool diagonal) const
+	{
+		if(  !diagonal  ||  !has_diagonal  ) {
+			return get_image_id(dir);
+		}
+		image_t const* const image = get_child<image_list_t>(4)->get_image(dir);
+		if(  image == NULL  ||  image->get_id() == IMG_EMPTY  ) {
+			// falling back keeps the sign visible, and keeps its front/back order
+			// and its offsets exactly as they are without diagonals
+			return get_image_id(dir);
+		}
+		return image->get_id();
+	}
+
+	bool has_diagonal_image() const { return has_diagonal; }
+
+	// only the normal list: this count decides whether a sign is a traffic light
+	// and whether it has electrified images, so the diagonals must stay out of it
 	uint16 get_count() const { return get_child<image_list_t>(2)->get_count(); }
 
 	skin_desc_t const* get_cursor() const { return get_child<skin_desc_t>(3); }
Index: src/simutrans/descriptor/writer/roadsign_writer.cc
===================================================================
--- src/simutrans/descriptor/writer/roadsign_writer.cc	(revisión: 12130)
+++ src/simutrans/descriptor/writer/roadsign_writer.cc	(copia de trabajo)
@@ -19,8 +19,8 @@
 static const char* traffic_light_directions[] = {"n", "s", "w", "e", "nw", "se", "sw", "ne"};
 static const char* general_sign_directions[] = {"n", "s", "w", "e"};
 
-// parse "image[direction][state]" syntax
-void parse_images_2d(slist_tpl<std::string>& keys, tabfileobj_t& obj, roadsign_desc_t::types flags)
+// parse "<name>[direction][state]" syntax
+void parse_images_2d(slist_tpl<std::string>& keys, tabfileobj_t& obj, roadsign_desc_t::types flags, const char* name, bool optional)
 {
 	const char** directions;
 	uint8 dir_cnt; // how many directions are there?
@@ -42,9 +42,13 @@
 	for(  uint8 state=0;  state<8;  state++  ) {
 		for(  uint8 idx = 0;  idx < dir_cnt;  idx++  ) {
 			char buf[64];
-			sprintf(buf, "image[%s][%i]", directions[idx], state);
+			sprintf(buf, "%s[%s][%i]", name, directions[idx], state);
 			const char* img = obj.get(buf);
 			if(  !*img  ){
+				if(  optional  &&  state==0  &&  idx==0  ) {
+					// the whole list is not defined, which is the normal case
+					return;
+				}
 				if(  state>(dir_cnt==2)  &&  idx==0  ) {
 					// Assume all further state numbers are invalid.
 					return;
@@ -59,17 +63,17 @@
 }
 
 
-// parse "image[number]" syntax
-void parse_images_numbered(slist_tpl<std::string>& keys, tabfileobj_t& obj)
+// parse "<name>[number]" syntax
+void parse_images_numbered(slist_tpl<std::string>& keys, tabfileobj_t& obj, const char* name)
 {
 	for (int i = 0; i < 32; i++) {
 		char buf[40];
-		sprintf(buf, "image[%i]", i);
+		sprintf(buf, "%s[%i]", name, i);
 		const char *str = obj.get(buf);
 		// make sure, there are always 4, 8, 12, ... images (for all directions)
 		if(  !*str  ) {
 			if(  i % 4  ) {
-				dbg->fatal("roadsign_writer", "image count is %d but must be multiple of 4!", i);
+				dbg->fatal("roadsign_writer", "%s count is %d but must be multiple of 4!", name, i);
 			}
 			break;
 		}
@@ -135,17 +139,25 @@
 
 	// add the images
 	slist_tpl<std::string> keys;
+	slist_tpl<std::string> diagonal_keys;
 
 	if(  *obj.get("image[0]")  ) {
 		// image[0] is defined.
 		// assume that images are defined in image[number] syntax.
-		parse_images_numbered(keys, obj);
+		parse_images_numbered(keys, obj, "image");
+		parse_images_numbered(diagonal_keys, obj, "diagonal");
 	}
 	else {
 		// image[0] is not defined.
 		// assume that images are defined in image[direction][state] syntax.
-		parse_images_2d(keys, obj, flags);
+		parse_images_2d(keys, obj, flags, "image", false);
+		parse_images_2d(diagonal_keys, obj, flags, "diagonal", true);
 	}
+	// both lists are addressed with the same index, so a diagonal list of a different
+	// length would silently shift the images instead of failing here
+	if(  !diagonal_keys.empty()  &&  diagonal_keys.get_count()!=keys.get_count()  ) {
+		dbg->fatal("roadsign_writer", "%i diagonal images given, but the sign has %i images!", diagonal_keys.get_count(), keys.get_count());
+	}
 	imagelist_writer_t::instance()->write_obj(fp, node, keys);
 
 	// probably add some icons, if defined
@@ -154,9 +166,16 @@
 	const char *c = obj.get("cursor"), *i=obj.get("icon");
 	cursorkeys.append(c);
 	cursorkeys.append(i);
-	if (*c || *i) {
+	if (*c || *i || !diagonal_keys.empty()) {
+		// when diagonals follow, this node has to be written even if it is empty:
+		// the diagonal list is found by its position, and would take this one otherwise
 		cursorskin_writer_t::instance()->write_obj(fp, node, obj, cursorkeys);
 	}
 
+	// last child, so that older versions of Simutrans just ignore it
+	if(  !diagonal_keys.empty()  ) {
+		imagelist_writer_t::instance()->write_obj(fp, node, diagonal_keys);
+	}
+
 	node.check_and_write_header(fp);
 }
Index: src/simutrans/obj/roadsign.cc
===================================================================
--- src/simutrans/obj/roadsign.cc	(revisión: 12130)
+++ src/simutrans/obj/roadsign.cc	(copia de trabajo)
@@ -47,6 +47,7 @@
 {
 	image = foreground_image = IMG_EMPTY;
 	preview = false;
+	diagonal = false;
 	rdwr(file);
 	if(desc) {
 		/* if more than one state, we will switch direction and phase for traffic lights
@@ -74,6 +75,7 @@
 	this->dir = dir;
 	this->preview = preview;
 	image = foreground_image = IMG_EMPTY;
+	diagonal = false;
 	state = 0;
 	ticks_ns = ticks_ow = 16;
 	ticks_offset = 0;
@@ -247,6 +249,10 @@
 		return;
 	}
 
+	// signs on a bend use the diagonal images, if the sign has any
+	const weg_t *w = gr->get_weg(desc->get_wtyp()!=tram_wt ? desc->get_wtyp() : track_wt);
+	diagonal = w != NULL  &&  w->is_diagonal();
+
 	after_xoffset = 0;
 	after_yoffset = 0;
 	sint8 xoff = 0, yoff = 0;
@@ -267,7 +273,7 @@
 			// gate open
 			image += 2;
 		}
-		set_image( desc->get_image_id(image) );
+		set_image( desc->get_image_id(image, diagonal) );
 		set_yoff( 0 );
 		if(  hang_diff  ) {
 				set_yoff( -(TILE_HEIGHT_STEP*hang_diff)/2 );
@@ -321,7 +327,7 @@
 			const sint16 YOFF = desc->get_offset_left();
 
 			if(temp_dir&ribi_t::east) {
-				tmp_image = desc->get_image_id(3);
+				tmp_image = desc->get_image_id(3, diagonal);
 				xoff += XOFF;
 				yoff += -YOFF;
 			}
@@ -328,12 +334,12 @@
 
 			if(temp_dir&ribi_t::north) {
 				if(tmp_image!=IMG_EMPTY) {
-					foreground_image = desc->get_image_id(0);
+					foreground_image = desc->get_image_id(0, diagonal);
 					after_xoffset += -XOFF;
 					after_yoffset += -YOFF;
 				}
 				else {
-					tmp_image = desc->get_image_id(0);
+					tmp_image = desc->get_image_id(0, diagonal);
 					xoff += -XOFF;
 					yoff += -YOFF;
 				}
@@ -340,7 +346,7 @@
 			}
 
 			if(temp_dir&ribi_t::west) {
-				foreground_image = desc->get_image_id(2);
+				foreground_image = desc->get_image_id(2, diagonal);
 				after_xoffset += -XOFF;
 				after_yoffset += YOFF;
 			}
@@ -347,12 +353,12 @@
 
 			if(temp_dir&ribi_t::south) {
 				if(foreground_image!=IMG_EMPTY) {
-					tmp_image = desc->get_image_id(1);
+					tmp_image = desc->get_image_id(1, diagonal);
 					xoff += XOFF;
 					yoff += YOFF;
 				}
 				else {
-					foreground_image = desc->get_image_id(1);
+					foreground_image = desc->get_image_id(1, diagonal);
 					after_xoffset += XOFF;
 					after_yoffset += YOFF;
 				}
@@ -361,28 +367,28 @@
 		else {
 
 			if(temp_dir&ribi_t::east) {
-				foreground_image = desc->get_image_id(3);
+				foreground_image = desc->get_image_id(3, diagonal);
 			}
 
 			if(temp_dir&ribi_t::north) {
 				if(foreground_image!=IMG_EMPTY) {
-					tmp_image = desc->get_image_id(0);
+					tmp_image = desc->get_image_id(0, diagonal);
 				}
 				else {
-					foreground_image = desc->get_image_id(0);
+					foreground_image = desc->get_image_id(0, diagonal);
 				}
 			}
 
 			if(temp_dir&ribi_t::west) {
-				tmp_image = desc->get_image_id(2);
+				tmp_image = desc->get_image_id(2, diagonal);
 			}
 
 			if(temp_dir&ribi_t::south) {
 				if(tmp_image!=IMG_EMPTY) {
-					foreground_image = desc->get_image_id(1);
+					foreground_image = desc->get_image_id(1, diagonal);
 				}
 				else {
-					tmp_image = desc->get_image_id(1);
+					tmp_image = desc->get_image_id(1, diagonal);
 				}
 			}
 		}
@@ -409,18 +415,18 @@
 
 				if(weg_dir&ribi_t::north) {
 					if(weg_dir&ribi_t::east) {
-						foreground_image = desc->get_image_id(6+direction*8);
+						foreground_image = desc->get_image_id(6+direction*8, diagonal);
 						after_xoffset += 0;
 						after_yoffset += 0;
 					}
 					else {
-						foreground_image = desc->get_image_id(1+direction*8);
+						foreground_image = desc->get_image_id(1+direction*8, diagonal);
 						after_xoffset += XOFF;
 						after_yoffset += YOFF;
 					}
 				}
 				else if(weg_dir&ribi_t::east) {
-					foreground_image = desc->get_image_id(2+direction*8);
+					foreground_image = desc->get_image_id(2+direction*8, diagonal);
 					after_xoffset += -XOFF;
 					after_yoffset += YOFF;
 				}
@@ -427,18 +433,18 @@
 
 				if(weg_dir&ribi_t::west) {
 					if(weg_dir&ribi_t::south) {
-						tmp_image = desc->get_image_id(7+direction*8);
+						tmp_image = desc->get_image_id(7+direction*8, diagonal);
 						xoff += 0;
 						yoff += 0;
 					}
 					else {
-						tmp_image = desc->get_image_id(3+direction*8);
+						tmp_image = desc->get_image_id(3+direction*8, diagonal);
 						xoff += XOFF;
 						yoff += -YOFF;
 					}
 				}
 				else if(weg_dir&ribi_t::south) {
-					tmp_image = desc->get_image_id(0+direction*8);
+					tmp_image = desc->get_image_id(0+direction*8, diagonal);
 					xoff += -XOFF;
 					yoff += -YOFF;
 				}
@@ -447,26 +453,26 @@
 				// drive right ...
 				if(weg_dir&ribi_t::south) {
 					if(weg_dir&ribi_t::east) {
-						foreground_image = desc->get_image_id(4+direction*8);
+						foreground_image = desc->get_image_id(4+direction*8, diagonal);
 					}
 					else {
-						foreground_image = desc->get_image_id(0+direction*8);
+						foreground_image = desc->get_image_id(0+direction*8, diagonal);
 					}
 				}
 				else if(weg_dir&ribi_t::east) {
-					foreground_image = desc->get_image_id(2+direction*8);
+					foreground_image = desc->get_image_id(2+direction*8, diagonal);
 				}
 
 				if(weg_dir&ribi_t::west) {
 					if(weg_dir&ribi_t::north) {
-						tmp_image = desc->get_image_id(5+direction*8);
+						tmp_image = desc->get_image_id(5+direction*8, diagonal);
 					}
 					else {
-						tmp_image = desc->get_image_id(3+direction*8);
+						tmp_image = desc->get_image_id(3+direction*8, diagonal);
 					}
 				}
 				else if(weg_dir&ribi_t::north) {
-					tmp_image = desc->get_image_id(1+direction*8);
+					tmp_image = desc->get_image_id(1+direction*8, diagonal);
 				}
 			}
 
@@ -495,7 +501,7 @@
 			// force redraw
 			mark_image_dirty(get_image(),0);
 		}
-		set_image( desc->get_image_id(image) );
+		set_image( desc->get_image_id(image, diagonal) );
 	}
 	else {
 		if (grund_t* gr = welt->lookup(get_pos())) {
Index: src/simutrans/obj/roadsign.h
===================================================================
--- src/simutrans/obj/roadsign.h	(revisión: 12130)
+++ src/simutrans/obj/roadsign.h	(copia de trabajo)
@@ -38,6 +38,9 @@
 
 	uint8 automatic:1;
 	uint8 preview:1;
+	// whether the way below bends here, so the diagonal images are the ones to use.
+	// Kept here because private way signs redraw from sync_step, which never calls calc_image
+	uint8 diagonal:1;
 
 	/*
 	 * Many things go in these...
Index: src/simutrans/obj/signal.cc
===================================================================
--- src/simutrans/obj/signal.cc	(revisión: 12130)
+++ src/simutrans/obj/signal.cc	(copia de trabajo)
@@ -47,6 +47,7 @@
 {
 	foreground_image = IMG_EMPTY;
 	image_id image = IMG_EMPTY;
+	diagonal = false;
 
 	after_xoffset = 0;
 	after_yoffset = 0;
@@ -65,6 +66,8 @@
 		weg_t *sch = gr->get_weg(desc->get_wtyp()!=tram_wt ? desc->get_wtyp() : track_wt);
 		if(sch) {
 			uint16 offset=0;
+			// signals on a bend use the diagonal images, if the signal has any
+			diagonal = sch->is_diagonal();
 			ribi_t::ribi dir = sch->get_ribi_unmasked() & (~calc_mask());
 			if(sch->is_electrified()  &&  (desc->get_count()/8)>1) {
 				offset = (desc->is_pre_signal()  ||  desc->is_priority_signal()) ? 12 : 8;
@@ -108,7 +111,7 @@
 				const sint16 YOFF = desc->get_offset_left();
 
 				if(temp_dir&ribi_t::east) {
-					image = desc->get_image_id(3+state*4+offset);
+					image = desc->get_image_id(3+state*4+offset, diagonal);
 					xoff += XOFF;
 					yoff += -YOFF;
 				}
@@ -115,12 +118,12 @@
 
 				if(temp_dir&ribi_t::north) {
 					if(image!=IMG_EMPTY) {
-						foreground_image = desc->get_image_id(0+state*4+offset);
+						foreground_image = desc->get_image_id(0+state*4+offset, diagonal);
 						after_xoffset += -XOFF;
 						after_yoffset += -YOFF;
 					}
 					else {
-						image = desc->get_image_id(0+state*4+offset);
+						image = desc->get_image_id(0+state*4+offset, diagonal);
 						xoff += -XOFF;
 						yoff += -YOFF;
 					}
@@ -127,7 +130,7 @@
 				}
 
 				if(temp_dir&ribi_t::west) {
-					foreground_image = desc->get_image_id(2+state*4+offset);
+					foreground_image = desc->get_image_id(2+state*4+offset, diagonal);
 					after_xoffset += -XOFF;
 					after_yoffset += YOFF;
 				}
@@ -134,12 +137,12 @@
 
 				if(temp_dir&ribi_t::south) {
 					if(foreground_image!=IMG_EMPTY) {
-						image = desc->get_image_id(1+state*4+offset);
+						image = desc->get_image_id(1+state*4+offset, diagonal);
 						xoff += XOFF;
 						yoff += YOFF;
 					}
 					else {
-						foreground_image = desc->get_image_id(1+state*4+offset);
+						foreground_image = desc->get_image_id(1+state*4+offset, diagonal);
 						after_xoffset += XOFF;
 						after_yoffset += YOFF;
 					}
@@ -147,28 +150,28 @@
 			}
 			else {
 				if(temp_dir&ribi_t::east) {
-					foreground_image = desc->get_image_id(3+state*4+offset);
+					foreground_image = desc->get_image_id(3+state*4+offset, diagonal);
 				}
 
 				if(temp_dir&ribi_t::north) {
 					if(foreground_image==IMG_EMPTY) {
-						foreground_image = desc->get_image_id(0+state*4+offset);
+						foreground_image = desc->get_image_id(0+state*4+offset, diagonal);
 					}
 					else {
-						image = desc->get_image_id(0+state*4+offset);
+						image = desc->get_image_id(0+state*4+offset, diagonal);
 					}
 				}
 
 				if(temp_dir&ribi_t::west) {
-					image = desc->get_image_id(2+state*4+offset);
+					image = desc->get_image_id(2+state*4+offset, diagonal);
 				}
 
 				if(temp_dir&ribi_t::south) {
 					if(image==IMG_EMPTY) {
-						image = desc->get_image_id(1+state*4+offset);
+						image = desc->get_image_id(1+state*4+offset, diagonal);
 					}
 					else {
-						foreground_image = desc->get_image_id(1+state*4+offset);
+						foreground_image = desc->get_image_id(1+state*4+offset, diagonal);
 					}
 				}
 			}
